diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llrender/llrender.cpp | 145 |
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 | ||
77 | const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD; | 78 | const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; |
78 | 79 | ||
79 | static GLenum sGLBlendFactor[] = | 80 | static GLenum sGLBlendFactor[] = |
80 | { | 81 | { |
@@ -95,7 +96,8 @@ LLTexUnit::LLTexUnit(S32 index) | |||
95 | mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), | 96 | mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), |
96 | mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), | 97 | mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), |
97 | mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), | 98 | mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), |
98 | mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0) | 99 | mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), |
100 | mHasMipMaps(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 | ||
178 | bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind) | 180 | bool 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 | ||
230 | bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) | 261 | bool 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 | ||
248 | bool LLTexUnit::bindManual(eTextureType type, U32 texture) | 280 | bool 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 | ||
262 | void LLTexUnit::unbind(eTextureType type) | 294 | void 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 | ||
277 | void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) | 311 | void 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 | |||
325 | void 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 | ||
591 | LLRender::LLRender() | 665 | LLRender::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 | ||
693 | void LLRender::setSceneBlendType(eBlendType type) | 771 | void LLRender::setSceneBlendType(eBlendType type) |
@@ -767,6 +845,14 @@ bool LLRender::verifyTexUnitActive(U32 unitToVerify) | |||
767 | } | 845 | } |
768 | } | 846 | } |
769 | 847 | ||
848 | void LLRender::clearErrors() | ||
849 | { | ||
850 | while (glGetError()) | ||
851 | { | ||
852 | //loop until no more error flags left | ||
853 | } | ||
854 | } | ||
855 | |||
770 | void LLRender::begin(const GLuint& mode) | 856 | void 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 | |||
862 | void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) | 949 | void 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] |