aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llrender.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llrender/llrender.cpp145
1 files changed, 116 insertions, 29 deletions
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp
index ff0a2db..ba95a19 100644
--- a/linden/indra/llrender/llrender.cpp
+++ b/linden/indra/llrender/llrender.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -74,7 +75,7 @@ static GLenum sGLCompareFunc[] =
74 GL_GREATER 75 GL_GREATER
75}; 76};
76 77
77const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD; 78const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
78 79
79static GLenum sGLBlendFactor[] = 80static GLenum sGLBlendFactor[] =
80{ 81{
@@ -95,7 +96,8 @@ LLTexUnit::LLTexUnit(S32 index)
95mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), 96mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
96mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), 97mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
97mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), 98mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
98mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0) 99mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
100mHasMipMaps(false)
99{ 101{
100 llassert_always(index < LL_NUM_TEXTURE_LAYERS); 102 llassert_always(index < LL_NUM_TEXTURE_LAYERS);
101 mIndex = index; 103 mIndex = index;
@@ -175,8 +177,9 @@ void LLTexUnit::disable(void)
175 } 177 }
176} 178}
177 179
178bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind) 180bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
179{ 181{
182 stop_glerror();
180 if (mIndex < 0) return false; 183 if (mIndex < 0) return false;
181 184
182 gGL.flush(); 185 gGL.flush();
@@ -189,14 +192,28 @@ bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind)
189 192
190 if (!texture->getTexName()) //if texture does not exist 193 if (!texture->getTexName()) //if texture does not exist
191 { 194 {
195 //if deleted, will re-generate it immediately
196 texture->forceImmediateUpdate() ;
197
192 return texture->bindDefaultImage(mIndex); 198 return texture->bindDefaultImage(mIndex);
193 } 199 }
194 // Disabled caching of binding state. 200
195 activate(); 201 if ((mCurrTexture != texture->getTexName()) || forceBind)
196 enable(texture->getTarget()); 202 {
197 mCurrTexture = texture->getTexName(); 203 activate();
198 glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); 204 enable(texture->getTarget());
199 texture->updateBindStats(); 205 mCurrTexture = texture->getTexName();
206 glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
207 texture->updateBindStats();
208 texture->setActive() ;
209 mHasMipMaps = texture->mHasMipMaps;
210 if (texture->mTexOptionsDirty)
211 {
212 texture->mTexOptionsDirty = false;
213 setTextureAddressMode(texture->mAddressMode);
214 setTextureFilteringOption(texture->mFilterOption);
215 }
216 }
200 return true; 217 return true;
201} 218}
202 219
@@ -206,8 +223,13 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
206 223
207 gGL.flush(); 224 gGL.flush();
208 225
209 // Disabled caching of binding state. 226 if (cubeMap == NULL)
210 if (cubeMap != NULL) 227 {
228 llwarns << "NULL LLTexUnit::bind cubemap" << llendl;
229 return false;
230 }
231
232 if (mCurrTexture != cubeMap->mImages[0]->getTexName())
211 { 233 {
212 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) 234 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
213 { 235 {
@@ -215,18 +237,27 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
215 enable(LLTexUnit::TT_CUBE_MAP); 237 enable(LLTexUnit::TT_CUBE_MAP);
216 mCurrTexture = cubeMap->mImages[0]->getTexName(); 238 mCurrTexture = cubeMap->mImages[0]->getTexName();
217 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); 239 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
240 mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
218 cubeMap->mImages[0]->updateBindStats(); 241 cubeMap->mImages[0]->updateBindStats();
219 cubeMap->mImages[0]->setMipFilterNearest (FALSE, FALSE); 242 if (cubeMap->mImages[0]->mTexOptionsDirty)
243 {
244 cubeMap->mImages[0]->mTexOptionsDirty = false;
245 setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
246 setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
247 }
220 return true; 248 return true;
221 } 249 }
222 else 250 else
223 { 251 {
224 llwarns << "Using cube map without extension!" << llendl 252 llwarns << "Using cube map without extension!" << llendl;
253 return false;
225 } 254 }
226 } 255 }
227 return false; 256 return true;
228} 257}
229 258
259// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
260#if !LL_MESA_HEADLESS
230bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) 261bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
231{ 262{
232 if (mIndex < 0) return false; 263 if (mIndex < 0) return false;
@@ -244,23 +275,26 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
244 275
245 return true; 276 return true;
246} 277}
278#endif // LL_MESA_HEADLESS
247 279
248bool LLTexUnit::bindManual(eTextureType type, U32 texture) 280bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
249{ 281{
250 if (mIndex < 0) return false; 282 if (mIndex < 0 || mCurrTexture == texture) return false;
251 283
252 // Disabled caching of binding state.
253 gGL.flush(); 284 gGL.flush();
254 285
255 activate(); 286 activate();
256 enable(type); 287 enable(type);
257 mCurrTexture = texture; 288 mCurrTexture = texture;
258 glBindTexture(sGLTextureType[type], texture); 289 glBindTexture(sGLTextureType[type], texture);
290 mHasMipMaps = hasMips;
259 return true; 291 return true;
260} 292}
261 293
262void LLTexUnit::unbind(eTextureType type) 294void LLTexUnit::unbind(eTextureType type)
263{ 295{
296 stop_glerror();
297
264 if (mIndex < 0) return; 298 if (mIndex < 0) return;
265 299
266 // Disabled caching of binding state. 300 // Disabled caching of binding state.
@@ -276,17 +310,57 @@ void LLTexUnit::unbind(eTextureType type)
276 310
277void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) 311void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
278{ 312{
279 if (mIndex < 0) return; 313 if (mIndex < 0 || mCurrTexture == 0) return;
280 314
281 if (true) 315 activate();
316
317 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
318 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
319 if (mCurrTexType == TT_CUBE_MAP)
282 { 320 {
283 activate(); 321 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
322 }
323}
324
325void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
326{
327 if (mIndex < 0 || mCurrTexture == 0) return;
284 328
285 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); 329 if (option == TFO_POINT)
286 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); 330 {
287 if (mCurrTexType == TT_CUBE_MAP) 331 glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
332 }
333 else
334 {
335 glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
336 }
337
338 if (option >= TFO_TRILINEAR && mHasMipMaps)
339 {
340 glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
341 }
342 else if (option >= TFO_BILINEAR)
343 {
344 glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
345 }
346 else
347 {
348 glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 }
350
351 if (gGLManager.mHasAnisotropic)
352 {
353 if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
288 { 354 {
289 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); 355 if (gGL.mMaxAnisotropy < 1.f)
356 {
357 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
358 }
359 glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
360 }
361 else
362 {
363 glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
290 } 364 }
291 } 365 }
292} 366}
@@ -589,12 +663,13 @@ void LLTexUnit::debugTextureUnit(void)
589 663
590 664
591LLRender::LLRender() 665LLRender::LLRender()
592: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES) 666: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES),
667 mMaxAnisotropy(0.f)
593{ 668{
594 mBuffer = new LLVertexBuffer(immediate_mask, 0); 669 mBuffer = new LLVertexBuffer(immediate_mask, 0);
595 mBuffer->allocateBuffer(4096, 0, TRUE); 670 mBuffer->allocateBuffer(4096, 0, TRUE);
596 mBuffer->getVertexStrider(mVerticesp); 671 mBuffer->getVertexStrider(mVerticesp);
597 mBuffer->getTexCoordStrider(mTexcoordsp); 672 mBuffer->getTexCoord0Strider(mTexcoordsp);
598 mBuffer->getColorStrider(mColorsp); 673 mBuffer->getColorStrider(mColorsp);
599 674
600 mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); 675 mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
@@ -687,7 +762,10 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB
687 mCurrColorMask[2] = writeColorB; 762 mCurrColorMask[2] = writeColorB;
688 mCurrColorMask[3] = writeAlpha; 763 mCurrColorMask[3] = writeAlpha;
689 764
690 glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); 765 glColorMask(writeColorR ? GL_TRUE : GL_FALSE,
766 writeColorG ? GL_TRUE : GL_FALSE,
767 writeColorB ? GL_TRUE : GL_FALSE,
768 writeAlpha ? GL_TRUE : GL_FALSE);
691} 769}
692 770
693void LLRender::setSceneBlendType(eBlendType type) 771void LLRender::setSceneBlendType(eBlendType type)
@@ -767,6 +845,14 @@ bool LLRender::verifyTexUnitActive(U32 unitToVerify)
767 } 845 }
768} 846}
769 847
848void LLRender::clearErrors()
849{
850 while (glGetError())
851 {
852 //loop until no more error flags left
853 }
854}
855
770void LLRender::begin(const GLuint& mode) 856void LLRender::begin(const GLuint& mode)
771{ 857{
772 if (mode != mMode) 858 if (mode != mMode)
@@ -852,13 +938,14 @@ void LLRender::flush()
852 938
853 mBuffer->setBuffer(immediate_mask); 939 mBuffer->setBuffer(immediate_mask);
854 mBuffer->drawArrays(mMode, 0, mCount); 940 mBuffer->drawArrays(mMode, 0, mCount);
855 941
856 mVerticesp[0] = mVerticesp[mCount]; 942 mVerticesp[0] = mVerticesp[mCount];
857 mTexcoordsp[0] = mTexcoordsp[mCount]; 943 mTexcoordsp[0] = mTexcoordsp[mCount];
858 mColorsp[0] = mColorsp[mCount]; 944 mColorsp[0] = mColorsp[mCount];
859 mCount = 0; 945 mCount = 0;
860 } 946 }
861} 947}
948
862void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) 949void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
863{ 950{
864 //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095] 951 //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]