diff options
Diffstat (limited to 'linden/indra/llrender/llrender.cpp')
-rw-r--r-- | linden/indra/llrender/llrender.cpp | 362 |
1 files changed, 309 insertions, 53 deletions
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp index 7be06af..ff0a2db 100644 --- a/linden/indra/llrender/llrender.cpp +++ b/linden/indra/llrender/llrender.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2001-2008, Linden Research, Inc. | 7 | * Copyright (c) 2001-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -32,7 +32,11 @@ | |||
32 | #include "linden_common.h" | 32 | #include "linden_common.h" |
33 | 33 | ||
34 | #include "llrender.h" | 34 | #include "llrender.h" |
35 | |||
35 | #include "llvertexbuffer.h" | 36 | #include "llvertexbuffer.h" |
37 | #include "llcubemap.h" | ||
38 | #include "llimagegl.h" | ||
39 | #include "llrendertarget.h" | ||
36 | 40 | ||
37 | LLRender gGL; | 41 | LLRender gGL; |
38 | 42 | ||
@@ -44,6 +48,20 @@ S32 gGLViewport[4]; | |||
44 | 48 | ||
45 | static const U32 LL_NUM_TEXTURE_LAYERS = 8; | 49 | static const U32 LL_NUM_TEXTURE_LAYERS = 8; |
46 | 50 | ||
51 | static GLenum sGLTextureType[] = | ||
52 | { | ||
53 | GL_TEXTURE_2D, | ||
54 | GL_TEXTURE_RECTANGLE_ARB, | ||
55 | GL_TEXTURE_CUBE_MAP_ARB | ||
56 | }; | ||
57 | |||
58 | static GLint sGLAddressMode[] = | ||
59 | { | ||
60 | GL_REPEAT, | ||
61 | GL_MIRRORED_REPEAT, | ||
62 | GL_CLAMP_TO_EDGE | ||
63 | }; | ||
64 | |||
47 | static GLenum sGLCompareFunc[] = | 65 | static GLenum sGLCompareFunc[] = |
48 | { | 66 | { |
49 | GL_NEVER, | 67 | GL_NEVER, |
@@ -72,82 +90,213 @@ static GLenum sGLBlendFactor[] = | |||
72 | GL_ONE_MINUS_SRC_ALPHA | 90 | GL_ONE_MINUS_SRC_ALPHA |
73 | }; | 91 | }; |
74 | 92 | ||
75 | LLTexUnit::LLTexUnit(U32 index) | 93 | LLTexUnit::LLTexUnit(S32 index) |
76 | : mIsEnabled(false), mCurrBlendType(TB_MULT), | 94 | : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT), |
77 | mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), | 95 | mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), |
78 | mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), | 96 | mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), |
79 | mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), | 97 | mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), |
80 | mCurrColorScale(1), mCurrAlphaScale(1) | 98 | mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0) |
81 | { | 99 | { |
82 | llassert_always(index < LL_NUM_TEXTURE_LAYERS); | 100 | llassert_always(index < LL_NUM_TEXTURE_LAYERS); |
83 | mIndex = index; | 101 | mIndex = index; |
84 | } | 102 | } |
85 | 103 | ||
86 | U32 LLTexUnit::getIndex(void) | 104 | //static |
105 | U32 LLTexUnit::getInternalType(eTextureType type) | ||
106 | { | ||
107 | return sGLTextureType[type]; | ||
108 | } | ||
109 | |||
110 | void LLTexUnit::refreshState(void) | ||
111 | { | ||
112 | // We set dirty to true so that the tex unit knows to ignore caching | ||
113 | // and we reset the cached tex unit state | ||
114 | |||
115 | glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); | ||
116 | if (mCurrTexType != TT_NONE) | ||
117 | { | ||
118 | glEnable(sGLTextureType[mCurrTexType]); | ||
119 | glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | glDisable(GL_TEXTURE_2D); | ||
124 | glBindTexture(GL_TEXTURE_2D, 0); | ||
125 | } | ||
126 | |||
127 | if (mCurrBlendType != TB_COMBINE) | ||
128 | { | ||
129 | setTextureBlendType(mCurrBlendType); | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false); | ||
134 | setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | void LLTexUnit::activate(void) | ||
87 | { | 139 | { |
88 | return mIndex; | 140 | if (mIndex < 0) return; |
141 | |||
142 | if (gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) | ||
143 | { | ||
144 | glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); | ||
145 | gGL.mCurrTextureUnitIndex = mIndex; | ||
146 | } | ||
89 | } | 147 | } |
90 | 148 | ||
91 | void LLTexUnit::enable(void) | 149 | void LLTexUnit::enable(eTextureType type) |
92 | { | 150 | { |
93 | if (!mIsEnabled) | 151 | if (mIndex < 0) return; |
152 | |||
153 | if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) ) | ||
94 | { | 154 | { |
95 | activate(); | 155 | activate(); |
96 | glEnable(GL_TEXTURE_2D); | 156 | if (mCurrTexType != TT_NONE && !gGL.mDirty) |
97 | mIsEnabled = true; | 157 | { |
158 | disable(); // Force a disable of a previous texture type if it's enabled. | ||
159 | } | ||
160 | mCurrTexType = type; | ||
161 | glEnable(sGLTextureType[type]); | ||
98 | } | 162 | } |
99 | } | 163 | } |
100 | 164 | ||
101 | void LLTexUnit::disable(void) | 165 | void LLTexUnit::disable(void) |
102 | { | 166 | { |
103 | if (mIsEnabled) | 167 | if (mIndex < 0) return; |
168 | |||
169 | if (mCurrTexType != TT_NONE) | ||
104 | { | 170 | { |
105 | activate(); | 171 | activate(); |
106 | glDisable(GL_TEXTURE_2D); | 172 | unbind(mCurrTexType); |
107 | mIsEnabled = false; | 173 | glDisable(sGLTextureType[mCurrTexType]); |
174 | mCurrTexType = TT_NONE; | ||
108 | } | 175 | } |
109 | } | 176 | } |
110 | 177 | ||
111 | void LLTexUnit::activate(void) | 178 | bool LLTexUnit::bind(const LLImageGL* texture, bool forceBind) |
112 | { | 179 | { |
113 | //if (gGL.mCurrTextureUnitIndex != mIndex) | 180 | if (mIndex < 0) return false; |
181 | |||
182 | gGL.flush(); | ||
183 | |||
184 | if (texture == NULL) | ||
114 | { | 185 | { |
115 | glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); | 186 | llwarns << "NULL LLTexUnit::bind texture" << llendl; |
116 | gGL.mCurrTextureUnitIndex = mIndex; | 187 | return false; |
188 | } | ||
189 | |||
190 | if (!texture->getTexName()) //if texture does not exist | ||
191 | { | ||
192 | return texture->bindDefaultImage(mIndex); | ||
117 | } | 193 | } |
194 | // Disabled caching of binding state. | ||
195 | activate(); | ||
196 | enable(texture->getTarget()); | ||
197 | mCurrTexture = texture->getTexName(); | ||
198 | glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); | ||
199 | texture->updateBindStats(); | ||
200 | return true; | ||
118 | } | 201 | } |
119 | 202 | ||
120 | // Useful for debugging that you've manually assigned a texture operation to the correct | 203 | bool LLTexUnit::bind(LLCubeMap* cubeMap) |
121 | // texture unit based on the currently set active texture in opengl. | ||
122 | void LLTexUnit::debugTextureUnit(void) | ||
123 | { | 204 | { |
124 | GLint activeTexture; | 205 | if (mIndex < 0) return false; |
125 | glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture); | 206 | |
126 | if ((GL_TEXTURE0_ARB + mIndex) != activeTexture) | 207 | gGL.flush(); |
208 | |||
209 | // Disabled caching of binding state. | ||
210 | if (cubeMap != NULL) | ||
127 | { | 211 | { |
128 | llerrs << "Incorrect Texture Unit! Expected: " << (activeTexture - GL_TEXTURE0_ARB) << " Actual: " << mIndex << llendl; | 212 | if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) |
213 | { | ||
214 | activate(); | ||
215 | enable(LLTexUnit::TT_CUBE_MAP); | ||
216 | mCurrTexture = cubeMap->mImages[0]->getTexName(); | ||
217 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); | ||
218 | cubeMap->mImages[0]->updateBindStats(); | ||
219 | cubeMap->mImages[0]->setMipFilterNearest (FALSE, FALSE); | ||
220 | return true; | ||
221 | } | ||
222 | else | ||
223 | { | ||
224 | llwarns << "Using cube map without extension!" << llendl | ||
225 | } | ||
129 | } | 226 | } |
227 | return false; | ||
130 | } | 228 | } |
131 | 229 | ||
132 | void LLTexUnit::bindTexture(const LLImageGL* texture) | 230 | bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) |
133 | { | 231 | { |
134 | if (texture != NULL) | 232 | if (mIndex < 0) return false; |
233 | |||
234 | gGL.flush(); | ||
235 | |||
236 | if (bindDepth) | ||
135 | { | 237 | { |
136 | activate(); | 238 | bindManual(renderTarget->getUsage(), renderTarget->getDepth()); |
137 | texture->bind(mIndex); | ||
138 | } | 239 | } |
240 | else | ||
241 | { | ||
242 | bindManual(renderTarget->getUsage(), renderTarget->getTexture()); | ||
243 | } | ||
244 | |||
245 | return true; | ||
139 | } | 246 | } |
140 | 247 | ||
141 | void LLTexUnit::unbindTexture(void) | 248 | bool LLTexUnit::bindManual(eTextureType type, U32 texture) |
142 | { | 249 | { |
250 | if (mIndex < 0) return false; | ||
251 | |||
252 | // Disabled caching of binding state. | ||
253 | gGL.flush(); | ||
254 | |||
143 | activate(); | 255 | activate(); |
144 | glBindTexture(GL_TEXTURE_2D, 0); | 256 | enable(type); |
257 | mCurrTexture = texture; | ||
258 | glBindTexture(sGLTextureType[type], texture); | ||
259 | return true; | ||
260 | } | ||
261 | |||
262 | void LLTexUnit::unbind(eTextureType type) | ||
263 | { | ||
264 | if (mIndex < 0) return; | ||
265 | |||
266 | // Disabled caching of binding state. | ||
267 | if (mCurrTexType == type) | ||
268 | { | ||
269 | gGL.flush(); | ||
270 | |||
271 | activate(); | ||
272 | mCurrTexture = 0; | ||
273 | glBindTexture(sGLTextureType[type], 0); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) | ||
278 | { | ||
279 | if (mIndex < 0) return; | ||
280 | |||
281 | if (true) | ||
282 | { | ||
283 | activate(); | ||
284 | |||
285 | glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); | ||
286 | glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); | ||
287 | if (mCurrTexType == TT_CUBE_MAP) | ||
288 | { | ||
289 | glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); | ||
290 | } | ||
291 | } | ||
145 | } | 292 | } |
146 | 293 | ||
147 | void LLTexUnit::setTextureBlendType(eTextureBlendType type) | 294 | void LLTexUnit::setTextureBlendType(eTextureBlendType type) |
148 | { | 295 | { |
296 | if (mIndex < 0) return; | ||
297 | |||
149 | // Do nothing if it's already correctly set. | 298 | // Do nothing if it's already correctly set. |
150 | if (mCurrBlendType == type) | 299 | if (mCurrBlendType == type && !gGL.mDirty) |
151 | { | 300 | { |
152 | return; | 301 | return; |
153 | } | 302 | } |
@@ -262,16 +411,18 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) | |||
262 | 411 | ||
263 | void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) | 412 | void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) |
264 | { | 413 | { |
414 | if (mIndex < 0) return; | ||
415 | |||
265 | activate(); | 416 | activate(); |
266 | if (mCurrBlendType != TB_COMBINE) | 417 | if (mCurrBlendType != TB_COMBINE || gGL.mDirty) |
267 | { | 418 | { |
268 | mCurrBlendType = TB_COMBINE; | 419 | mCurrBlendType = TB_COMBINE; |
269 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | 420 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
270 | } | 421 | } |
271 | 422 | ||
272 | // We want an early out, because this function does a LOT of stuff. | 423 | // We want an early out, because this function does a LOT of stuff. |
273 | if ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2) ) | 424 | if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2)) |
274 | || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2) )) | 425 | || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty) |
275 | { | 426 | { |
276 | return; | 427 | return; |
277 | } | 428 | } |
@@ -304,7 +455,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT | |||
304 | } | 455 | } |
305 | else | 456 | else |
306 | { | 457 | { |
307 | // Set enums to ALPHA ones | 458 | // Set enums to RGB ones |
308 | comb_enum = GL_COMBINE_RGB_ARB; | 459 | comb_enum = GL_COMBINE_RGB_ARB; |
309 | src0_enum = GL_SOURCE0_RGB_ARB; | 460 | src0_enum = GL_SOURCE0_RGB_ARB; |
310 | src1_enum = GL_SOURCE1_RGB_ARB; | 461 | src1_enum = GL_SOURCE1_RGB_ARB; |
@@ -405,7 +556,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT | |||
405 | 556 | ||
406 | void LLTexUnit::setColorScale(S32 scale) | 557 | void LLTexUnit::setColorScale(S32 scale) |
407 | { | 558 | { |
408 | if (mCurrColorScale != scale) | 559 | if (mCurrColorScale != scale || gGL.mDirty) |
409 | { | 560 | { |
410 | mCurrColorScale = scale; | 561 | mCurrColorScale = scale; |
411 | glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); | 562 | glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); |
@@ -414,27 +565,52 @@ void LLTexUnit::setColorScale(S32 scale) | |||
414 | 565 | ||
415 | void LLTexUnit::setAlphaScale(S32 scale) | 566 | void LLTexUnit::setAlphaScale(S32 scale) |
416 | { | 567 | { |
417 | if (mCurrAlphaScale != scale) | 568 | if (mCurrAlphaScale != scale || gGL.mDirty) |
418 | { | 569 | { |
419 | mCurrAlphaScale = scale; | 570 | mCurrAlphaScale = scale; |
420 | glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); | 571 | glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); |
421 | } | 572 | } |
422 | } | 573 | } |
423 | 574 | ||
575 | // Useful for debugging that you've manually assigned a texture operation to the correct | ||
576 | // texture unit based on the currently set active texture in opengl. | ||
577 | void LLTexUnit::debugTextureUnit(void) | ||
578 | { | ||
579 | if (mIndex < 0) return; | ||
580 | |||
581 | GLint activeTexture; | ||
582 | glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture); | ||
583 | if ((GL_TEXTURE0_ARB + mIndex) != activeTexture) | ||
584 | { | ||
585 | U32 set_unit = (activeTexture - GL_TEXTURE0_ARB); | ||
586 | llwarns << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << llendl; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | |||
424 | LLRender::LLRender() | 591 | LLRender::LLRender() |
592 | : mDirty(false), mCount(0), mMode(LLRender::TRIANGLES) | ||
425 | { | 593 | { |
426 | mCount = 0; | ||
427 | mMode = LLVertexBuffer::TRIANGLES; | ||
428 | mBuffer = new LLVertexBuffer(immediate_mask, 0); | 594 | mBuffer = new LLVertexBuffer(immediate_mask, 0); |
429 | mBuffer->allocateBuffer(4096, 0, TRUE); | 595 | mBuffer->allocateBuffer(4096, 0, TRUE); |
430 | mBuffer->getVertexStrider(mVerticesp); | 596 | mBuffer->getVertexStrider(mVerticesp); |
431 | mBuffer->getTexCoordStrider(mTexcoordsp); | 597 | mBuffer->getTexCoordStrider(mTexcoordsp); |
432 | mBuffer->getColorStrider(mColorsp); | 598 | mBuffer->getColorStrider(mColorsp); |
433 | 599 | ||
434 | for (unsigned int i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) | 600 | mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); |
601 | for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) | ||
435 | { | 602 | { |
436 | mTexUnits.push_back(new LLTexUnit(i)); | 603 | mTexUnits.push_back(new LLTexUnit(i)); |
437 | } | 604 | } |
605 | mDummyTexUnit = new LLTexUnit(-1); | ||
606 | |||
607 | for (U32 i = 0; i < 4; i++) | ||
608 | { | ||
609 | mCurrColorMask[i] = true; | ||
610 | } | ||
611 | |||
612 | mCurrAlphaFunc = CF_DEFAULT; | ||
613 | mCurrAlphaFuncVal = 0.01f; | ||
438 | } | 614 | } |
439 | 615 | ||
440 | LLRender::~LLRender() | 616 | LLRender::~LLRender() |
@@ -449,6 +625,28 @@ void LLRender::shutdown() | |||
449 | delete mTexUnits[i]; | 625 | delete mTexUnits[i]; |
450 | } | 626 | } |
451 | mTexUnits.clear(); | 627 | mTexUnits.clear(); |
628 | delete mDummyTexUnit; | ||
629 | mDummyTexUnit = NULL; | ||
630 | } | ||
631 | |||
632 | void LLRender::refreshState(void) | ||
633 | { | ||
634 | mDirty = true; | ||
635 | |||
636 | U32 active_unit = mCurrTextureUnitIndex; | ||
637 | |||
638 | for (U32 i = 0; i < mTexUnits.size(); i++) | ||
639 | { | ||
640 | mTexUnits[i]->refreshState(); | ||
641 | } | ||
642 | |||
643 | mTexUnits[active_unit]->activate(); | ||
644 | |||
645 | setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]); | ||
646 | |||
647 | setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal); | ||
648 | |||
649 | mDirty = false; | ||
452 | } | 650 | } |
453 | 651 | ||
454 | void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) | 652 | void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) |
@@ -483,6 +681,12 @@ void LLRender::setColorMask(bool writeColor, bool writeAlpha) | |||
483 | void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) | 681 | void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) |
484 | { | 682 | { |
485 | flush(); | 683 | flush(); |
684 | |||
685 | mCurrColorMask[0] = writeColorR; | ||
686 | mCurrColorMask[1] = writeColorG; | ||
687 | mCurrColorMask[2] = writeColorB; | ||
688 | mCurrColorMask[3] = writeAlpha; | ||
689 | |||
486 | glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); | 690 | glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); |
487 | } | 691 | } |
488 | 692 | ||
@@ -518,6 +722,9 @@ void LLRender::setSceneBlendType(eBlendType type) | |||
518 | void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) | 722 | void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) |
519 | { | 723 | { |
520 | flush(); | 724 | flush(); |
725 | |||
726 | mCurrAlphaFunc = func; | ||
727 | mCurrAlphaFuncVal = value; | ||
521 | if (func == CF_DEFAULT) | 728 | if (func == CF_DEFAULT) |
522 | { | 729 | { |
523 | glAlphaFunc(GL_GREATER, 0.01f); | 730 | glAlphaFunc(GL_GREATER, 0.01f); |
@@ -536,22 +743,38 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) | |||
536 | 743 | ||
537 | LLTexUnit* LLRender::getTexUnit(U32 index) | 744 | LLTexUnit* LLRender::getTexUnit(U32 index) |
538 | { | 745 | { |
539 | if (index < mTexUnits.size()) | 746 | if ((index >= 0) && (index < mTexUnits.size())) |
540 | { | 747 | { |
541 | return mTexUnits[index]; | 748 | return mTexUnits[index]; |
542 | } | 749 | } |
543 | llerrs << "Non-existing texture unit layer requested: " << index << llendl; | 750 | else |
544 | return NULL; | 751 | { |
752 | lldebugs << "Non-existing texture unit layer requested: " << index << llendl; | ||
753 | return mDummyTexUnit; | ||
754 | } | ||
755 | } | ||
756 | |||
757 | bool LLRender::verifyTexUnitActive(U32 unitToVerify) | ||
758 | { | ||
759 | if (mCurrTextureUnitIndex == unitToVerify) | ||
760 | { | ||
761 | return true; | ||
762 | } | ||
763 | else | ||
764 | { | ||
765 | llwarns << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << llendl; | ||
766 | return false; | ||
767 | } | ||
545 | } | 768 | } |
546 | 769 | ||
547 | void LLRender::begin(const GLuint& mode) | 770 | void LLRender::begin(const GLuint& mode) |
548 | { | 771 | { |
549 | if (mode != mMode) | 772 | if (mode != mMode) |
550 | { | 773 | { |
551 | if (mMode == LLVertexBuffer::QUADS || | 774 | if (mMode == LLRender::QUADS || |
552 | mMode == LLVertexBuffer::LINES || | 775 | mMode == LLRender::LINES || |
553 | mMode == LLVertexBuffer::TRIANGLES || | 776 | mMode == LLRender::TRIANGLES || |
554 | mMode == LLVertexBuffer::POINTS) | 777 | mMode == LLRender::POINTS) |
555 | { | 778 | { |
556 | flush(); | 779 | flush(); |
557 | } | 780 | } |
@@ -572,10 +795,10 @@ void LLRender::end() | |||
572 | //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; | 795 | //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; |
573 | } | 796 | } |
574 | 797 | ||
575 | if ((mMode != LLVertexBuffer::QUADS && | 798 | if ((mMode != LLRender::QUADS && |
576 | mMode != LLVertexBuffer::LINES && | 799 | mMode != LLRender::LINES && |
577 | mMode != LLVertexBuffer::TRIANGLES && | 800 | mMode != LLRender::TRIANGLES && |
578 | mMode != LLVertexBuffer::POINTS) || | 801 | mMode != LLRender::POINTS) || |
579 | mCount > 2048) | 802 | mCount > 2048) |
580 | { | 803 | { |
581 | flush(); | 804 | flush(); |
@@ -638,7 +861,8 @@ void LLRender::flush() | |||
638 | } | 861 | } |
639 | void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) | 862 | void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) |
640 | { | 863 | { |
641 | if (mCount >= 4096) | 864 | //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095] |
865 | if (mCount > 4094) | ||
642 | { | 866 | { |
643 | // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; | 867 | // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; |
644 | return; | 868 | return; |
@@ -720,3 +944,35 @@ void LLRender::color3fv(const GLfloat* c) | |||
720 | color4f(c[0],c[1],c[2],1); | 944 | color4f(c[0],c[1],c[2],1); |
721 | } | 945 | } |
722 | 946 | ||
947 | void LLRender::debugTexUnits(void) | ||
948 | { | ||
949 | LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL; | ||
950 | std::string active_enabled = "false"; | ||
951 | for (U32 i = 0; i < mTexUnits.size(); i++) | ||
952 | { | ||
953 | if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE) | ||
954 | { | ||
955 | if (i == mCurrTextureUnitIndex) active_enabled = "true"; | ||
956 | LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL; | ||
957 | LL_INFOS("TextureUnit") << "Enabled As: " ; | ||
958 | switch (getTexUnit(i)->mCurrTexType) | ||
959 | { | ||
960 | case LLTexUnit::TT_TEXTURE: | ||
961 | LL_CONT << "Texture 2D"; | ||
962 | break; | ||
963 | case LLTexUnit::TT_RECT_TEXTURE: | ||
964 | LL_CONT << "Texture Rectangle"; | ||
965 | break; | ||
966 | case LLTexUnit::TT_CUBE_MAP: | ||
967 | LL_CONT << "Cube Map"; | ||
968 | break; | ||
969 | default: | ||
970 | LL_CONT << "ARGH!!! NONE!"; | ||
971 | break; | ||
972 | } | ||
973 | LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL; | ||
974 | } | ||
975 | } | ||
976 | LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL; | ||
977 | } | ||
978 | |||