aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender
diff options
context:
space:
mode:
authorJacek Antonelli2008-12-01 17:39:58 -0600
committerJacek Antonelli2008-12-01 17:40:06 -0600
commit7abecb48babe6a6f09bf6692ba55076546cfced9 (patch)
tree8d18a88513fb97adf32c10aae78f4be1984942db /linden/indra/llrender
parentSecond Life viewer sources 1.21.6 (diff)
downloadmeta-impy-7abecb48babe6a6f09bf6692ba55076546cfced9.zip
meta-impy-7abecb48babe6a6f09bf6692ba55076546cfced9.tar.gz
meta-impy-7abecb48babe6a6f09bf6692ba55076546cfced9.tar.bz2
meta-impy-7abecb48babe6a6f09bf6692ba55076546cfced9.tar.xz
Second Life viewer sources 1.22.0-RC
Diffstat (limited to 'linden/indra/llrender')
-rw-r--r--linden/indra/llrender/llcubemap.cpp54
-rw-r--r--linden/indra/llrender/llcubemap.h2
-rw-r--r--linden/indra/llrender/llfont.cpp31
-rw-r--r--linden/indra/llrender/llfont.h1
-rw-r--r--linden/indra/llrender/llfontgl.cpp20
-rw-r--r--linden/indra/llrender/llgl.cpp64
-rw-r--r--linden/indra/llrender/llgl.h6
-rw-r--r--linden/indra/llrender/llglimmediate.h4
-rw-r--r--linden/indra/llrender/llglslshader.cpp8
-rw-r--r--linden/indra/llrender/llglslshader.h5
-rw-r--r--linden/indra/llrender/llglstates.h22
-rw-r--r--linden/indra/llrender/llimagegl.cpp266
-rw-r--r--linden/indra/llrender/llimagegl.h26
-rw-r--r--linden/indra/llrender/llpostprocess.cpp18
-rw-r--r--linden/indra/llrender/llrender.cpp364
-rw-r--r--linden/indra/llrender/llrender.h124
-rw-r--r--linden/indra/llrender/llrendertarget.cpp56
-rw-r--r--linden/indra/llrender/llrendertarget.h15
-rw-r--r--linden/indra/llrender/llshadermgr.cpp2
-rw-r--r--linden/indra/llrender/llvertexbuffer.cpp8
-rw-r--r--linden/indra/llrender/llvertexbuffer.h16
21 files changed, 679 insertions, 433 deletions
diff --git a/linden/indra/llrender/llcubemap.cpp b/linden/indra/llrender/llcubemap.cpp
index 563d616..878ae17 100644
--- a/linden/indra/llrender/llcubemap.cpp
+++ b/linden/indra/llrender/llcubemap.cpp
@@ -92,11 +92,11 @@ void LLCubeMap::initGL()
92 for (int i = 0; i < 6; i++) 92 for (int i = 0; i < 6; i++)
93 { 93 {
94 mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE)); 94 mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
95 mImages[i]->setTarget(mTargets[i], GL_TEXTURE_CUBE_MAP_ARB); 95 mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
96 mRawImages[i] = new LLImageRaw(64, 64, 4); 96 mRawImages[i] = new LLImageRaw(64, 64, 4);
97 mImages[i]->createGLTexture(0, mRawImages[i], texname); 97 mImages[i]->createGLTexture(0, mRawImages[i], texname);
98 98
99 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texname); 99 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
100 mImages[i]->setClampCubemap (TRUE, TRUE, TRUE); 100 mImages[i]->setClampCubemap (TRUE, TRUE, TRUE);
101 stop_glerror(); 101 stop_glerror();
102 } 102 }
@@ -180,26 +180,7 @@ GLuint LLCubeMap::getGLName()
180 180
181void LLCubeMap::bind() 181void LLCubeMap::bind()
182{ 182{
183 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) 183 gGL.getTexUnit(mTextureStage)->bind(this);
184 {
185 // We assume that if they have cube mapping, they have multitexturing.
186 if (mTextureStage > 0)
187 {
188 gGL.getTexUnit(mTextureStage)->activate();
189 }
190 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
191 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mImages[0]->getTexName());
192
193 mImages[0]->setMipFilterNearest (FALSE, FALSE);
194 if (mTextureStage > 0)
195 {
196 gGL.getTexUnit(0)->activate();
197 }
198 }
199 else
200 {
201 llwarns << "Using cube map without extension!" << llendl
202 }
203} 184}
204 185
205void LLCubeMap::enable(S32 stage) 186void LLCubeMap::enable(S32 stage)
@@ -213,17 +194,7 @@ void LLCubeMap::enableTexture(S32 stage)
213 mTextureStage = stage; 194 mTextureStage = stage;
214 if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) 195 if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
215 { 196 {
216 if (stage > 0) 197 gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
217 {
218 gGL.getTexUnit(stage)->activate();
219 }
220
221 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
222
223 if (stage > 0)
224 {
225 gGL.getTexUnit(0)->activate();
226 }
227 } 198 }
228} 199}
229 200
@@ -262,15 +233,10 @@ void LLCubeMap::disableTexture(void)
262{ 233{
263 if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) 234 if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
264 { 235 {
265 if (mTextureStage > 0) 236 gGL.getTexUnit(mTextureStage)->disable();
237 if (mTextureStage == 0)
266 { 238 {
267 gGL.getTexUnit(mTextureStage)->activate(); 239 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
268 }
269 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
270 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
271 if (mTextureStage > 0)
272 {
273 gGL.getTexUnit(0)->activate();
274 } 240 }
275 } 241 }
276} 242}
@@ -297,6 +263,8 @@ void LLCubeMap::setMatrix(S32 stage)
297{ 263{
298 mMatrixStage = stage; 264 mMatrixStage = stage;
299 265
266 if (mMatrixStage < 0) return;
267
300 if (stage > 0) 268 if (stage > 0)
301 { 269 {
302 gGL.getTexUnit(stage)->activate(); 270 gGL.getTexUnit(stage)->activate();
@@ -324,6 +292,8 @@ void LLCubeMap::setMatrix(S32 stage)
324 292
325void LLCubeMap::restoreMatrix() 293void LLCubeMap::restoreMatrix()
326{ 294{
295 if (mMatrixStage < 0) return;
296
327 if (mMatrixStage > 0) 297 if (mMatrixStage > 0)
328 { 298 {
329 gGL.getTexUnit(mMatrixStage)->activate(); 299 gGL.getTexUnit(mMatrixStage)->activate();
@@ -340,7 +310,7 @@ void LLCubeMap::restoreMatrix()
340 310
341void LLCubeMap::setReflection (void) 311void LLCubeMap::setReflection (void)
342{ 312{
343 glBindTexture (GL_TEXTURE_CUBE_MAP_ARB, getGLName()); 313 gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
344 mImages[0]->setMipFilterNearest (FALSE, FALSE); 314 mImages[0]->setMipFilterNearest (FALSE, FALSE);
345 mImages[0]->setClampCubemap (TRUE, TRUE); 315 mImages[0]->setClampCubemap (TRUE, TRUE);
346} 316}
diff --git a/linden/indra/llrender/llcubemap.h b/linden/indra/llrender/llcubemap.h
index 45bfa16..15ca7db 100644
--- a/linden/indra/llrender/llcubemap.h
+++ b/linden/indra/llrender/llcubemap.h
@@ -53,6 +53,7 @@ public:
53 53
54 void enableTexture(S32 stage); 54 void enableTexture(S32 stage);
55 void enableTextureCoords(S32 stage); 55 void enableTextureCoords(S32 stage);
56 S32 getStage(void) { return mTextureStage; }
56 57
57 void disable(void); 58 void disable(void);
58 void disableTexture(void); 59 void disableTexture(void);
@@ -77,6 +78,7 @@ public:
77 static bool sUseCubeMaps; 78 static bool sUseCubeMaps;
78 79
79protected: 80protected:
81 friend class LLTexUnit;
80 ~LLCubeMap(); 82 ~LLCubeMap();
81 LLGLenum mTargets[6]; 83 LLGLenum mTargets[6];
82 LLPointer<LLImageGL> mImages[6]; 84 LLPointer<LLImageGL> mImages[6];
diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp
index 4b5ee64..bcd0aca 100644
--- a/linden/indra/llrender/llfont.cpp
+++ b/linden/indra/llrender/llfont.cpp
@@ -92,18 +92,18 @@ LLFontManager::~LLFontManager()
92 92
93 93
94LLFontGlyphInfo::LLFontGlyphInfo(U32 index) 94LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
95{ 95: mGlyphIndex(index),
96 mGlyphIndex = index; 96 mXBitmapOffset(0), // Offset to the origin in the bitmap
97 mXBitmapOffset = 0; // Offset to the origin in the bitmap 97 mYBitmapOffset(0), // Offset to the origin in the bitmap
98 mYBitmapOffset = 0; // Offset to the origin in the bitmap 98 mXBearing(0), // Distance from baseline to left in pixels
99 mXBearing = 0; // Distance from baseline to left in pixels 99 mYBearing(0), // Distance from baseline to top in pixels
100 mYBearing = 0; // Distance from baseline to top in pixels 100 mWidth(0), // In pixels
101 mWidth = 0; // In pixels 101 mHeight(0), // In pixels
102 mHeight = 0; // In pixels 102 mXAdvance(0.f), // In pixels
103 mXAdvance = 0.f; // In pixels 103 mYAdvance(0.f), // In pixels
104 mYAdvance = 0.f; // In pixels 104 mIsRendered(FALSE),
105 mIsRendered = FALSE; 105 mMetricsValid(FALSE)
106} 106{}
107 107
108LLFontList::LLFontList() 108LLFontList::LLFontList()
109{ 109{
@@ -303,6 +303,9 @@ void LLFont::resetBitmap()
303 iter != mCharGlyphInfoMap.end(); ++iter) 303 iter != mCharGlyphInfoMap.end(); ++iter)
304 { 304 {
305 iter->second->mIsRendered = FALSE; 305 iter->second->mIsRendered = FALSE;
306 //FIXME: this is only strictly necessary when resetting the entire font,
307 //not just flushing the bitmap
308 iter->second->mMetricsValid = FALSE;
306 } 309 }
307 mRawImagep->clear(255, 0); 310 mRawImagep->clear(255, 0);
308 mCurrentOffsetX = 1; 311 mCurrentOffsetX = 1;
@@ -439,6 +442,7 @@ BOOL LLFont::addGlyphFromFont(LLFont *fontp, const llwchar wch, const U32 glyph_
439 gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; 442 gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
440 gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; 443 gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
441 gi->mIsRendered = TRUE; 444 gi->mIsRendered = TRUE;
445 gi->mMetricsValid = TRUE;
442 446
443 insertGlyphInfo(wch, gi); 447 insertGlyphInfo(wch, gi);
444 448
@@ -528,7 +532,7 @@ F32 LLFont::getXAdvance(const llwchar wch) const
528 532
529 // Return existing info only if it is current 533 // Return existing info only if it is current
530 LLFontGlyphInfo* gi = getGlyphInfo(wch); 534 LLFontGlyphInfo* gi = getGlyphInfo(wch);
531 if (gi && gi->mIsRendered) 535 if (gi && gi->mMetricsValid)
532 { 536 {
533 return gi->mXAdvance; 537 return gi->mXAdvance;
534 } 538 }
@@ -573,6 +577,7 @@ F32 LLFont::getXAdvance(const llwchar wch) const
573 // Convert these from 26.6 units to float pixels. 577 // Convert these from 26.6 units to float pixels.
574 gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; 578 gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
575 gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; 579 gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
580 gi->mMetricsValid = TRUE;
576 return gi->mXAdvance; 581 return gi->mXAdvance;
577 } 582 }
578 else 583 else
diff --git a/linden/indra/llrender/llfont.h b/linden/indra/llrender/llfont.h
index d937dfd..2054832 100644
--- a/linden/indra/llrender/llfont.h
+++ b/linden/indra/llrender/llfont.h
@@ -72,6 +72,7 @@ public:
72 S32 mHeight; // In pixels 72 S32 mHeight; // In pixels
73 F32 mXAdvance; // In pixels 73 F32 mXAdvance; // In pixels
74 F32 mYAdvance; // In pixels 74 F32 mYAdvance; // In pixels
75 BOOL mMetricsValid; // We have up-to-date metrics for this glyph
75 76
76 // Information for actually rendering 77 // Information for actually rendering
77 BOOL mIsRendered; // We actually have rendered this glyph 78 BOOL mIsRendered; // We actually have rendered this glyph
diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp
index a328196..2705516 100644
--- a/linden/indra/llrender/llfontgl.cpp
+++ b/linden/indra/llrender/llfontgl.cpp
@@ -148,7 +148,7 @@ void LLFontGL::init()
148 { 148 {
149 mImageGLp = new LLImageGL(FALSE); 149 mImageGLp = new LLImageGL(FALSE);
150 //RN: use nearest mipmap filtering to obviate the need to do pixel-accurate positioning 150 //RN: use nearest mipmap filtering to obviate the need to do pixel-accurate positioning
151 mImageGLp->bind(); 151 gGL.getTexUnit(0)->bind(mImageGLp);
152 // we allow bilinear filtering to get sub-pixel positioning for drop shadows 152 // we allow bilinear filtering to get sub-pixel positioning for drop shadows
153 //mImageGLp->setMipFilterNearest(TRUE, TRUE); 153 //mImageGLp->setMipFilterNearest(TRUE, TRUE);
154 } 154 }
@@ -533,7 +533,7 @@ BOOL LLFontGL::loadFace(const std::string& filename,
533 return FALSE; 533 return FALSE;
534 } 534 }
535 mImageGLp->createGLTexture(0, mRawImageGLp); 535 mImageGLp->createGLTexture(0, mRawImageGLp);
536 mImageGLp->bind(); 536 gGL.getTexUnit(0)->bind(mImageGLp);
537 mImageGLp->setMipFilterNearest(TRUE, TRUE); 537 mImageGLp->setMipFilterNearest(TRUE, TRUE);
538 return TRUE; 538 return TRUE;
539} 539}
@@ -547,7 +547,7 @@ BOOL LLFontGL::addChar(const llwchar wch)
547 547
548 stop_glerror(); 548 stop_glerror();
549 mImageGLp->setSubImage(mRawImageGLp, 0, 0, mImageGLp->getWidth(), mImageGLp->getHeight()); 549 mImageGLp->setSubImage(mRawImageGLp, 0, 0, mImageGLp->getWidth(), mImageGLp->getHeight());
550 mImageGLp->bind(); 550 gGL.getTexUnit(0)->bind(mImageGLp);
551 mImageGLp->setMipFilterNearest(TRUE, TRUE); 551 mImageGLp->setMipFilterNearest(TRUE, TRUE);
552 stop_glerror(); 552 stop_glerror();
553 return TRUE; 553 return TRUE;
@@ -583,7 +583,7 @@ S32 LLFontGL::render(const LLWString &wstr,
583 return wstr.length() ; 583 return wstr.length() ;
584 } 584 }
585 585
586 LLGLEnable tex(GL_TEXTURE_2D); 586 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
587 587
588 if (wstr.empty()) 588 if (wstr.empty())
589 { 589 {
@@ -663,7 +663,7 @@ S32 LLFontGL::render(const LLWString &wstr,
663 663
664 // Bind the font texture 664 // Bind the font texture
665 665
666 mImageGLp->bind(0); 666 gGL.getTexUnit(0)->bind(mImageGLp);
667 667
668 // Not guaranteed to be set correctly 668 // Not guaranteed to be set correctly
669 gGL.setSceneBlendType(LLRender::BT_ALPHA); 669 gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -761,7 +761,7 @@ S32 LLFontGL::render(const LLWString &wstr,
761 break; 761 break;
762 } 762 }
763 763
764 ext_image->bind(); 764 gGL.getTexUnit(0)->bind(ext_image);
765 const F32 ext_x = cur_render_x + (EXT_X_BEARING * sScaleX); 765 const F32 ext_x = cur_render_x + (EXT_X_BEARING * sScaleX);
766 const F32 ext_y = cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight); 766 const F32 ext_y = cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight);
767 767
@@ -795,7 +795,7 @@ S32 LLFontGL::render(const LLWString &wstr,
795 cur_render_x = cur_x; 795 cur_render_x = cur_x;
796 796
797 // Bind the font texture 797 // Bind the font texture
798 mImageGLp->bind(); 798 gGL.getTexUnit(0)->bind(mImageGLp);
799 } 799 }
800 else 800 else
801 { 801 {
@@ -863,8 +863,8 @@ S32 LLFontGL::render(const LLWString &wstr,
863 863
864 if (style & UNDERLINE) 864 if (style & UNDERLINE)
865 { 865 {
866 LLGLSNoTexture no_texture; 866 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
867 gGL.begin(LLVertexBuffer::LINES); 867 gGL.begin(LLRender::LINES);
868 gGL.vertex2f(start_x, cur_y - (mDescender)); 868 gGL.vertex2f(start_x, cur_y - (mDescender));
869 gGL.vertex2f(cur_x, cur_y - (mDescender)); 869 gGL.vertex2f(cur_x, cur_y - (mDescender));
870 gGL.end(); 870 gGL.end();
@@ -1359,7 +1359,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
1359 F32 slant_offset; 1359 F32 slant_offset;
1360 slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f); 1360 slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
1361 1361
1362 gGL.begin(LLVertexBuffer::QUADS); 1362 gGL.begin(LLRender::QUADS);
1363 { 1363 {
1364 //FIXME: bold and drop shadow are mutually exclusive only for convenience 1364 //FIXME: bold and drop shadow are mutually exclusive only for convenience
1365 //Allow both when we need them. 1365 //Allow both when we need them.
diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp
index 843bc79..67d258e 100644
--- a/linden/indra/llrender/llgl.cpp
+++ b/linden/indra/llrender/llgl.cpp
@@ -263,7 +263,6 @@ LLGLManager::LLGLManager() :
263 mHasMultitexture(FALSE), 263 mHasMultitexture(FALSE),
264 mNumTextureUnits(1), 264 mNumTextureUnits(1),
265 mHasMipMapGeneration(FALSE), 265 mHasMipMapGeneration(FALSE),
266 mHasPalettedTextures(FALSE),
267 mHasCompressedTextures(FALSE), 266 mHasCompressedTextures(FALSE),
268 mHasFramebufferObject(FALSE), 267 mHasFramebufferObject(FALSE),
269 268
@@ -566,7 +565,6 @@ void LLGLManager::initExtensions()
566 mHasFramebufferObject = FALSE; 565 mHasFramebufferObject = FALSE;
567# endif 566# endif
568 mHasMipMapGeneration = FALSE; 567 mHasMipMapGeneration = FALSE;
569 mHasPalettedTextures = FALSE;
570 mHasSeparateSpecularColor = FALSE; 568 mHasSeparateSpecularColor = FALSE;
571 mHasAnisotropic = FALSE; 569 mHasAnisotropic = FALSE;
572 mHasCubeMap = FALSE; 570 mHasCubeMap = FALSE;
@@ -578,7 +576,6 @@ void LLGLManager::initExtensions()
578#else // LL_MESA_HEADLESS 576#else // LL_MESA_HEADLESS
579 mHasMultitexture = glh_init_extensions("GL_ARB_multitexture"); 577 mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
580 mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap"); 578 mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
581 mHasPalettedTextures = glh_init_extension("GL_EXT_paletted_texture");
582 mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color"); 579 mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
583 mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic"); 580 mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
584 glh_init_extensions("GL_ARB_texture_cube_map"); 581 glh_init_extensions("GL_ARB_texture_cube_map");
@@ -610,7 +607,6 @@ void LLGLManager::initExtensions()
610 mHasVertexBufferObject = FALSE; 607 mHasVertexBufferObject = FALSE;
611 mHasFramebufferObject = FALSE; 608 mHasFramebufferObject = FALSE;
612 mHasMipMapGeneration = FALSE; 609 mHasMipMapGeneration = FALSE;
613 mHasPalettedTextures = FALSE;
614 mHasSeparateSpecularColor = FALSE; 610 mHasSeparateSpecularColor = FALSE;
615 mHasAnisotropic = FALSE; 611 mHasAnisotropic = FALSE;
616 mHasCubeMap = FALSE; 612 mHasCubeMap = FALSE;
@@ -628,7 +624,6 @@ void LLGLManager::initExtensions()
628 // bug reports. This should be the default until we get a 624 // bug reports. This should be the default until we get a
629 // proper blacklist/whitelist on Linux. 625 // proper blacklist/whitelist on Linux.
630 mHasMipMapGeneration = FALSE; 626 mHasMipMapGeneration = FALSE;
631 mHasPalettedTextures = FALSE;
632 mHasAnisotropic = FALSE; 627 mHasAnisotropic = FALSE;
633 //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar 628 //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
634 //mHasOcclusionQuery = FALSE; // source of many ATI system hangs 629 //mHasOcclusionQuery = FALSE; // source of many ATI system hangs
@@ -648,7 +643,6 @@ void LLGLManager::initExtensions()
648 if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE; 643 if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE;
649 if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE; 644 if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE;
650 if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S 645 if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
651 if (strchr(blacklist,'e')) mHasPalettedTextures = FALSE;//S
652// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S 646// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
653// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S 647// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
654 if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE; 648 if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
@@ -663,13 +657,6 @@ void LLGLManager::initExtensions()
663 if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S 657 if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
664 } 658 }
665#endif // LL_LINUX 659#endif // LL_LINUX
666
667#if LL_DARWIN || LL_LINUX
668 // MBW -- 12/4/2003 -- Using paletted textures causes a bunch of avatar rendering problems on the Mac.
669 // Not sure if this is due to driver problems or incorrect use of the extension, but I'm disabling it for now.
670 // Tofu - 2006-10-03 -- Same problem on Linux.
671 mHasPalettedTextures = false;
672#endif
673 660
674 if (!mHasMultitexture) 661 if (!mHasMultitexture)
675 { 662 {
@@ -683,10 +670,6 @@ void LLGLManager::initExtensions()
683 { 670 {
684 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL; 671 LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL;
685 } 672 }
686 if (!mHasPalettedTextures)
687 {
688 LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_paletted_texture" << LL_ENDL;
689 }
690 if (!mHasSeparateSpecularColor) 673 if (!mHasSeparateSpecularColor)
691 { 674 {
692 LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL; 675 LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL;
@@ -788,13 +771,7 @@ void LLGLManager::initExtensions()
788 mGLMaxIndexRange = 0; 771 mGLMaxIndexRange = 0;
789 } 772 }
790#endif // !LL_LINUX 773#endif // !LL_LINUX
791#if LL_LINUX 774
792 // On Linux we need to get glColorTableEXT dynamically.
793 if (mHasPalettedTextures)
794 {
795 glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glColorTableEXT");
796 }
797#endif // LL_LINUX
798 if (mHasOcclusionQuery) 775 if (mHasOcclusionQuery)
799 { 776 {
800 glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB"); 777 glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
@@ -960,7 +937,8 @@ void assert_glerror()
960 GLubyte const * gl_error_msg = gluErrorString(error); 937 GLubyte const * gl_error_msg = gluErrorString(error);
961 if (NULL != gl_error_msg) 938 if (NULL != gl_error_msg)
962 { 939 {
963 LL_WARNS("RenderState") << "GL Error:" << gl_error_msg << LL_ENDL; 940 LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
941 LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
964 } 942 }
965 else 943 else
966 { 944 {
@@ -1001,7 +979,7 @@ GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
1001void LLGLState::initClass() 979void LLGLState::initClass()
1002{ 980{
1003 sStateMap[GL_DITHER] = GL_TRUE; 981 sStateMap[GL_DITHER] = GL_TRUE;
1004 sStateMap[GL_TEXTURE_2D] = GL_TRUE; 982 // sStateMap[GL_TEXTURE_2D] = GL_TRUE;
1005 983
1006 //make sure multisample defaults to disabled 984 //make sure multisample defaults to disabled
1007 sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE; 985 sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
@@ -1030,7 +1008,7 @@ void LLGLState::resetTextureStates()
1030 { 1008 {
1031 gGL.getTexUnit(j)->activate(); 1009 gGL.getTexUnit(j)->activate();
1032 glClientActiveTextureARB(GL_TEXTURE0_ARB+j); 1010 glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
1033 j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D); 1011 j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
1034 } 1012 }
1035} 1013}
1036 1014
@@ -1053,14 +1031,6 @@ void LLGLState::checkStates(const std::string& msg)
1053 1031
1054 stop_glerror(); 1032 stop_glerror();
1055 1033
1056 GLint activeTexture;
1057 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
1058
1059 if (activeTexture != GL_TEXTURE0_ARB)
1060 {
1061 LL_GL_ERRS << "Texture channel corrupted. " << LL_ENDL;
1062 }
1063
1064 GLint src; 1034 GLint src;
1065 GLint dst; 1035 GLint dst;
1066 glGetIntegerv(GL_BLEND_SRC, &src); 1036 glGetIntegerv(GL_BLEND_SRC, &src);
@@ -1099,17 +1069,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
1099 1069
1100 BOOL error = FALSE; 1070 BOOL error = FALSE;
1101 1071
1102 if (activeTexture != GL_TEXTURE0_ARB) 1072 if (activeTexture == GL_TEXTURE0_ARB)
1103 {
1104 error = TRUE;
1105 LL_WARNS("RenderState") << "Active texture channel corrupted. " << LL_ENDL;
1106 }
1107 else if (!glIsEnabled(GL_TEXTURE_2D))
1108 {
1109 error = TRUE;
1110 LL_WARNS("RenderState") << "GL_TEXTURE_2D not enabled on texture channel 0." << LL_ENDL;
1111 }
1112 else
1113 { 1073 {
1114 GLint tex_env_mode = 0; 1074 GLint tex_env_mode = 0;
1115 1075
@@ -1152,7 +1112,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
1152 LLMatrix4 identity; 1112 LLMatrix4 identity;
1153 LLMatrix4 matrix; 1113 LLMatrix4 matrix;
1154 1114
1155 for (GLint i = 0; i < maxTextureUnits; i++) 1115 for (GLint i = 1; i < maxTextureUnits; i++)
1156 { 1116 {
1157 gGL.getTexUnit(i)->activate(); 1117 gGL.getTexUnit(i)->activate();
1158 glClientActiveTextureARB(GL_TEXTURE0_ARB+i); 1118 glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
@@ -1459,16 +1419,6 @@ void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
1459#endif 1419#endif
1460} 1420}
1461 1421
1462
1463void set_palette(U8 *palette_data)
1464{
1465 if (gGLManager.mHasPalettedTextures)
1466 {
1467 glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, palette_data);
1468 }
1469}
1470
1471
1472void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific ) 1422void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
1473{ 1423{
1474 // GL_VERSION returns a null-terminated string with the format: 1424 // GL_VERSION returns a null-terminated string with the format:
diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h
index cb368d7..8433348 100644
--- a/linden/indra/llrender/llgl.h
+++ b/linden/indra/llrender/llgl.h
@@ -74,7 +74,6 @@ public:
74 BOOL mHasMultitexture; 74 BOOL mHasMultitexture;
75 S32 mNumTextureUnits; 75 S32 mNumTextureUnits;
76 BOOL mHasMipMapGeneration; 76 BOOL mHasMipMapGeneration;
77 BOOL mHasPalettedTextures;
78 BOOL mHasCompressedTextures; 77 BOOL mHasCompressedTextures;
79 BOOL mHasFramebufferObject; 78 BOOL mHasFramebufferObject;
80 79
@@ -318,11 +317,11 @@ public:
318class LLGLNamePool 317class LLGLNamePool
319{ 318{
320public: 319public:
321 typedef struct 320 struct NameEntry
322 { 321 {
323 GLuint name; 322 GLuint name;
324 BOOL used; 323 BOOL used;
325 } NameEntry; 324 };
326 325
327 struct CompareUsed 326 struct CompareUsed
328 { 327 {
@@ -370,7 +369,6 @@ void disable_cloth_weights(const S32 index);
370void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights); 369void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights);
371void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights); 370void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights);
372void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals); 371void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals);
373void set_palette(U8* palette_data);
374void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific ); 372void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
375 373
376extern BOOL gClothRipple; 374extern BOOL gClothRipple;
diff --git a/linden/indra/llrender/llglimmediate.h b/linden/indra/llrender/llglimmediate.h
index 2d7d768..cd2af8b 100644
--- a/linden/indra/llrender/llglimmediate.h
+++ b/linden/indra/llrender/llglimmediate.h
@@ -76,12 +76,12 @@ public:
76 void color3fv(const GLfloat* c); 76 void color3fv(const GLfloat* c);
77 void color4ubv(const GLubyte* c); 77 void color4ubv(const GLubyte* c);
78 78
79 typedef struct Vertex 79 typedef struct
80 { 80 {
81 GLfloat v[3]; 81 GLfloat v[3];
82 GLubyte c[4]; 82 GLubyte c[4];
83 GLfloat uv[2]; 83 GLfloat uv[2];
84 }; 84 } Vertex;
85 85
86private: 86private:
87 U32 mCount; 87 U32 mCount;
diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp
index 26984e1..5d7375c 100644
--- a/linden/indra/llrender/llglslshader.cpp
+++ b/linden/indra/llrender/llglslshader.cpp
@@ -365,7 +365,7 @@ void LLGLSLShader::bindNoShader(void)
365 glUseProgramObjectARB(0); 365 glUseProgramObjectARB(0);
366} 366}
367 367
368S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode) 368S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
369{ 369{
370 if (uniform < 0 || uniform >= (S32)mTexture.size()) 370 if (uniform < 0 || uniform >= (S32)mTexture.size())
371 { 371 {
@@ -376,12 +376,12 @@ S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
376 if (index != -1) 376 if (index != -1)
377 { 377 {
378 gGL.getTexUnit(index)->activate(); 378 gGL.getTexUnit(index)->activate();
379 glEnable(mode); 379 gGL.getTexUnit(index)->enable(mode);
380 } 380 }
381 return index; 381 return index;
382} 382}
383 383
384S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode) 384S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
385{ 385{
386 if (uniform < 0 || uniform >= (S32)mTexture.size()) 386 if (uniform < 0 || uniform >= (S32)mTexture.size())
387 { 387 {
@@ -392,7 +392,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
392 if (index != -1) 392 if (index != -1)
393 { 393 {
394 gGL.getTexUnit(index)->activate(); 394 gGL.getTexUnit(index)->activate();
395 glDisable(mode); 395 gGL.getTexUnit(index)->disable();
396 } 396 }
397 return index; 397 return index;
398} 398}
diff --git a/linden/indra/llrender/llglslshader.h b/linden/indra/llrender/llglslshader.h
index 0fa8e41..cd787cc 100644
--- a/linden/indra/llrender/llglslshader.h
+++ b/linden/indra/llrender/llglslshader.h
@@ -33,6 +33,7 @@
33#define LL_LLGLSLSHADER_H 33#define LL_LLGLSLSHADER_H
34 34
35#include "llgl.h" 35#include "llgl.h"
36#include "llrender.h"
36 37
37class LLShaderFeatures 38class LLShaderFeatures
38{ 39{
@@ -111,8 +112,8 @@ public:
111 //if given texture uniform is active in the shader, 112 //if given texture uniform is active in the shader,
112 //the corresponding channel will be active upon return 113 //the corresponding channel will be active upon return
113 //returns channel texture is enabled in from [0-MAX) 114 //returns channel texture is enabled in from [0-MAX)
114 S32 enableTexture(S32 uniform, S32 mode = GL_TEXTURE_2D); 115 S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
115 S32 disableTexture(S32 uniform, S32 mode = GL_TEXTURE_2D); 116 S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
116 117
117 BOOL link(BOOL suppress_errors = FALSE); 118 BOOL link(BOOL suppress_errors = FALSE);
118 void bind(); 119 void bind();
diff --git a/linden/indra/llrender/llglstates.h b/linden/indra/llrender/llglstates.h
index e53640c..bb8b8df 100644
--- a/linden/indra/llrender/llglstates.h
+++ b/linden/indra/llrender/llglstates.h
@@ -87,13 +87,6 @@ public:
87 { } 87 { }
88}; 88};
89 89
90class LLGLSNoTexture
91{
92public:
93 LLGLSNoTexture()
94 { LLImageGL::unbindTexture(0); }
95};
96
97class LLGLSObjectSelect 90class LLGLSObjectSelect
98{ 91{
99protected: 92protected:
@@ -104,7 +97,7 @@ public:
104 : mBlend(GL_BLEND), mFog(GL_FOG), 97 : mBlend(GL_BLEND), mFog(GL_FOG),
105 mAlphaTest(GL_ALPHA_TEST), 98 mAlphaTest(GL_ALPHA_TEST),
106 mCullFace(GL_CULL_FACE) 99 mCullFace(GL_CULL_FACE)
107 { LLImageGL::unbindTexture(0); } 100 { }
108}; 101};
109 102
110class LLGLSObjectSelectAlpha 103class LLGLSObjectSelectAlpha
@@ -143,17 +136,6 @@ public:
143 {} 136 {}
144}; 137};
145 138
146class LLGLSNoTextureNoAlphaTest // : public LLGLSUIDefault
147{
148protected:
149 LLGLDisable mAlphaTest;
150public:
151 LLGLSNoTextureNoAlphaTest()
152 : mAlphaTest(GL_ALPHA_TEST)
153
154 { LLImageGL::unbindTexture(0); }
155};
156
157//---------------------------------------------------------------------------- 139//----------------------------------------------------------------------------
158 140
159class LLGLSFog 141class LLGLSFog
@@ -251,7 +233,7 @@ public:
251 mBlend(GL_BLEND), 233 mBlend(GL_BLEND),
252 mAlphaTest(GL_ALPHA_TEST) 234 mAlphaTest(GL_ALPHA_TEST)
253 235
254 { LLImageGL::unbindTexture(0); } 236 { }
255}; 237};
256 238
257//---------------------------------------------------------------------------- 239//----------------------------------------------------------------------------
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index a871758..d9b22c5 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -125,49 +125,6 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
125//---------------------------------------------------------------------------- 125//----------------------------------------------------------------------------
126 126
127// static 127// static
128void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_target )
129{
130 gGL.flush();
131 if (stage > 0)
132 {
133 gGL.getTexUnit(stage)->activate();
134 }
135 glBindTexture(bind_target, gl_name);
136 sCurrentBoundTextures[stage] = gl_name;
137 if (stage > 0)
138 {
139 gGL.getTexUnit(0)->activate();
140 }
141}
142
143// static
144void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target)
145{
146 // LLGLSLShader can return -1
147 if (stage >= 0)
148 {
149 gGL.flush();
150 if (stage > 0)
151 {
152 gGL.getTexUnit(stage)->activate();
153 glBindTexture(GL_TEXTURE_2D, 0);
154 gGL.getTexUnit(0)->activate();
155 }
156 else
157 {
158 glBindTexture(GL_TEXTURE_2D, 0);
159 }
160 sCurrentBoundTextures[stage] = 0;
161 }
162}
163
164// static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency)
165void LLImageGL::unbindTexture(S32 stage)
166{
167 unbindTexture(stage, GL_TEXTURE_2D);
168}
169
170// static
171void LLImageGL::updateStats(F32 current_time) 128void LLImageGL::updateStats(F32 current_time)
172{ 129{
173 sLastFrameTime = current_time; 130 sLastFrameTime = current_time;
@@ -189,7 +146,7 @@ void LLImageGL::destroyGL(BOOL save_state)
189{ 146{
190 for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) 147 for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++)
191 { 148 {
192 LLImageGL::unbindTexture(stage, GL_TEXTURE_2D); 149 gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
193 } 150 }
194 for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); 151 for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
195 iter != sImageList.end(); iter++) 152 iter != sImageList.end(); iter++)
@@ -284,6 +241,8 @@ LLImageGL::~LLImageGL()
284{ 241{
285 LLImageGL::cleanup(); 242 LLImageGL::cleanup();
286 sImageList.erase(this); 243 sImageList.erase(this);
244 delete [] mPickMask;
245 mPickMask = NULL;
287 sCount--; 246 sCount--;
288} 247}
289 248
@@ -293,11 +252,12 @@ void LLImageGL::init(BOOL usemipmaps)
293 mMissed = FALSE; 252 mMissed = FALSE;
294#endif 253#endif
295 254
255 mPickMask = NULL;
296 mTextureMemory = 0; 256 mTextureMemory = 0;
297 mLastBindTime = 0.f; 257 mLastBindTime = 0.f;
298 258
299 mTarget = GL_TEXTURE_2D; 259 mTarget = GL_TEXTURE_2D;
300 mBindTarget = GL_TEXTURE_2D; 260 mBindTarget = LLTexUnit::TT_TEXTURE;
301 mUseMipMaps = usemipmaps; 261 mUseMipMaps = usemipmaps;
302 mHasMipMaps = FALSE; 262 mHasMipMaps = FALSE;
303 mAutoGenMips = FALSE; 263 mAutoGenMips = FALSE;
@@ -321,6 +281,8 @@ void LLImageGL::init(BOOL usemipmaps)
321 mFormatType = GL_UNSIGNED_BYTE; 281 mFormatType = GL_UNSIGNED_BYTE;
322 mFormatSwapBytes = FALSE; 282 mFormatSwapBytes = FALSE;
323 mHasExplicitFormat = FALSE; 283 mHasExplicitFormat = FALSE;
284
285 mInitialized = true;
324} 286}
325 287
326void LLImageGL::cleanup() 288void LLImageGL::cleanup()
@@ -421,41 +383,14 @@ void LLImageGL::dump()
421 383
422//---------------------------------------------------------------------------- 384//----------------------------------------------------------------------------
423 385
424BOOL LLImageGL::bindTextureInternal(const S32 stage) const 386void LLImageGL::updateBindStats(void) const
425{ 387{
426 if (gGLManager.mIsDisabled)
427 {
428 llwarns << "Trying to bind a texture while GL is disabled!" << llendl;
429 }
430
431
432 if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName)
433 {
434 // already set!
435 return TRUE;
436 }
437
438 if (mTexName != 0) 388 if (mTexName != 0)
439 { 389 {
440#ifdef DEBUG_MISS 390#ifdef DEBUG_MISS
441 mMissed = ! getIsResident(TRUE); 391 mMissed = ! getIsResident(TRUE);
442#endif 392#endif
443
444 gGL.flush();
445 if (stage > 0)
446 {
447 gGL.getTexUnit(stage)->activate();
448 }
449
450 glBindTexture(mBindTarget, mTexName);
451 sCurrentBoundTextures[stage] = mTexName;
452 sBindCount++; 393 sBindCount++;
453
454 if (stage > 0)
455 {
456 gGL.getTexUnit(0)->activate();
457 }
458
459 if (mLastBindTime != sLastFrameTime) 394 if (mLastBindTime != sLastFrameTime)
460 { 395 {
461 // we haven't accounted for this texture yet this frame 396 // we haven't accounted for this texture yet this frame
@@ -463,38 +398,22 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
463 updateBoundTexMem(mTextureMemory); 398 updateBoundTexMem(mTextureMemory);
464 mLastBindTime = sLastFrameTime; 399 mLastBindTime = sLastFrameTime;
465 } 400 }
466
467 return TRUE;
468 }
469 else
470 {
471 gGL.flush();
472 if (stage > 0)
473 {
474 gGL.getTexUnit(stage)->activate();
475 }
476 glBindTexture(mBindTarget, 0);
477 if (stage > 0)
478 {
479 gGL.getTexUnit(0)->activate();
480 }
481 sCurrentBoundTextures[stage] = 0;
482 return FALSE;
483 } 401 }
484} 402}
485 403
486//virtual 404//virtual
487BOOL LLImageGL::bind(const S32 stage) const 405bool LLImageGL::bindError(const S32 stage) const
488{ 406{
489 if (stage == -1) 407 return false;
490 { 408}
491 return FALSE; 409
492 } 410//virtual
493 BOOL res = bindTextureInternal(stage); 411bool LLImageGL::bindDefaultImage(const S32 stage) const
494 //llassert(res); 412{
495 return res; 413 return false;
496} 414}
497 415
416
498void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) 417void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
499{ 418{
500 // Note: must be called before createTexture() 419 // Note: must be called before createTexture()
@@ -532,7 +451,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
532 451
533 { 452 {
534// LLFastTimer t2(LLFastTimer::FTM_TEMP2); 453// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
535 llverify(bindTextureInternal(0)); 454 llverify(gGL.getTexUnit(0)->bind(this));
536 } 455 }
537 456
538 if (mUseMipMaps) 457 if (mUseMipMaps)
@@ -569,7 +488,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
569 } 488 }
570 489
571 glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); 490 glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
572 491 updatePickMask(w, h, data_in);
492
573 if(mFormatSwapBytes) 493 if(mFormatSwapBytes)
574 { 494 {
575 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); 495 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
@@ -585,7 +505,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
585 { 505 {
586 if (mAutoGenMips) 506 if (mAutoGenMips)
587 { 507 {
588 glTexParameteri(mBindTarget, GL_GENERATE_MIPMAP_SGIS, TRUE); 508 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
589 stop_glerror(); 509 stop_glerror();
590 { 510 {
591// LLFastTimer t2(LLFastTimer::FTM_TEMP4); 511// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
@@ -596,12 +516,17 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
596 stop_glerror(); 516 stop_glerror();
597 } 517 }
598 518
519 S32 w = getWidth(mCurrentDiscardLevel);
520 S32 h = getHeight(mCurrentDiscardLevel);
521
599 glTexImage2D(mTarget, 0, mFormatInternal, 522 glTexImage2D(mTarget, 0, mFormatInternal,
600 getWidth(mCurrentDiscardLevel), getHeight(mCurrentDiscardLevel), 0, 523 w, h, 0,
601 mFormatPrimary, mFormatType, 524 mFormatPrimary, mFormatType,
602 data_in); 525 data_in);
603 stop_glerror(); 526 stop_glerror();
604 527
528 updatePickMask(w, h, data_in);
529
605 if(mFormatSwapBytes) 530 if(mFormatSwapBytes)
606 { 531 {
607 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); 532 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
@@ -651,6 +576,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
651 576
652 glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); 577 glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data);
653 stop_glerror(); 578 stop_glerror();
579 if (m == 0)
580 {
581 updatePickMask(w, h, cur_mip_data);
582 }
654 583
655 if(mFormatSwapBytes) 584 if(mFormatSwapBytes)
656 { 585 {
@@ -701,6 +630,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
701 630
702 glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0, 631 glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0,
703 mFormatPrimary, mFormatType, (GLvoid *)data_in); 632 mFormatPrimary, mFormatType, (GLvoid *)data_in);
633 updatePickMask(w, h, data_in);
634
704 stop_glerror(); 635 stop_glerror();
705 636
706 if(mFormatSwapBytes) 637 if(mFormatSwapBytes)
@@ -713,6 +644,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
713 mHasMipMaps = FALSE; 644 mHasMipMaps = FALSE;
714 } 645 }
715 stop_glerror(); 646 stop_glerror();
647 mInitialized = true;
716} 648}
717 649
718BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) 650BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
@@ -786,12 +718,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
786 718
787 datap += (y_pos * data_width + x_pos) * getComponents(); 719 datap += (y_pos * data_width + x_pos) * getComponents();
788 // Update the GL texture 720 // Update the GL texture
789 BOOL res = bindTextureInternal(0); 721 BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
790 if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; 722 if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
791 stop_glerror(); 723 stop_glerror();
792 724
793 LLGLEnable tex( GL_TEXTURE_2D );
794
795 glTexSubImage2D(mTarget, 0, x_pos, y_pos, 725 glTexSubImage2D(mTarget, 0, x_pos, y_pos,
796 width, height, mFormatPrimary, mFormatType, datap); 726 width, height, mFormatPrimary, mFormatType, datap);
797 stop_glerror(); 727 stop_glerror();
@@ -804,6 +734,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
804 734
805 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 735 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
806 stop_glerror(); 736 stop_glerror();
737 mInitialized = true;
807 } 738 }
808 739
809 return TRUE; 740 return TRUE;
@@ -817,9 +748,10 @@ BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S3
817// Copy sub image from frame buffer 748// Copy sub image from frame buffer
818BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height) 749BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
819{ 750{
820 if (bindTextureInternal(0)) 751 if (gGL.getTexUnit(0)->bind(this))
821 { 752 {
822 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); 753 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
754 mInitialized = true;
823 stop_glerror(); 755 stop_glerror();
824 return TRUE; 756 return TRUE;
825 } 757 }
@@ -919,9 +851,9 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
919 stop_glerror(); 851 stop_glerror();
920 { 852 {
921// LLFastTimer t1(LLFastTimer::FTM_TEMP6); 853// LLFastTimer t1(LLFastTimer::FTM_TEMP6);
922 llverify(bindTextureInternal(0)); 854 llverify(gGL.getTexUnit(0)->bind(this));
923 glTexParameteri(mBindTarget, GL_TEXTURE_BASE_LEVEL, 0); 855 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
924 glTexParameteri(mBindTarget, GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level); 856 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
925 } 857 }
926 } 858 }
927 if (!mTexName) 859 if (!mTexName)
@@ -949,7 +881,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
949 setMipFilterNearest(mMagFilterNearest); 881 setMipFilterNearest(mMagFilterNearest);
950 882
951 // things will break if we don't unbind after creation 883 // things will break if we don't unbind after creation
952 unbindTexture(0, mBindTarget); 884 gGL.getTexUnit(0)->unbind(mBindTarget);
953 stop_glerror(); 885 stop_glerror();
954 886
955 if (old_name != 0) 887 if (old_name != 0)
@@ -1050,8 +982,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1050 S32 gl_discard = discard_level - mCurrentDiscardLevel; 982 S32 gl_discard = discard_level - mCurrentDiscardLevel;
1051 983
1052 //explicitly unbind texture 984 //explicitly unbind texture
1053 LLImageGL::unbindTexture(0, mTarget); 985 gGL.getTexUnit(0)->unbind(mBindTarget);
1054 llverify(bindTextureInternal(0)); 986 llverify(gGL.getTexUnit(0)->bind(this));
1055 987
1056 if (gDebugGL) 988 if (gDebugGL)
1057 { 989 {
@@ -1148,15 +1080,15 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1148 1080
1149void LLImageGL::destroyGLTexture() 1081void LLImageGL::destroyGLTexture()
1150{ 1082{
1151 stop_glerror();
1152
1153 if (mTexName != 0) 1083 if (mTexName != 0)
1154 { 1084 {
1085 stop_glerror();
1086
1155 for (int i = 0; i < gGLManager.mNumTextureUnits; i++) 1087 for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
1156 { 1088 {
1157 if (sCurrentBoundTextures[i] == mTexName) 1089 if (sCurrentBoundTextures[i] == mTexName)
1158 { 1090 {
1159 unbindTexture(i, GL_TEXTURE_2D); 1091 gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
1160 stop_glerror(); 1092 stop_glerror();
1161 } 1093 }
1162 } 1094 }
@@ -1184,8 +1116,8 @@ void LLImageGL::glClamp (BOOL clamps, BOOL clampt)
1184{ 1116{
1185 if (mTexName != 0) 1117 if (mTexName != 0)
1186 { 1118 {
1187 glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1119 glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1188 glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1120 glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1189 } 1121 }
1190} 1122}
1191 1123
@@ -1223,23 +1155,23 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
1223 { 1155 {
1224 if (mMinFilterNearest) 1156 if (mMinFilterNearest)
1225 { 1157 {
1226 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1158 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1227 } 1159 }
1228 else if (mHasMipMaps) 1160 else if (mHasMipMaps)
1229 { 1161 {
1230 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 1162 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1231 } 1163 }
1232 else 1164 else
1233 { 1165 {
1234 glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1166 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1235 } 1167 }
1236 if (mMagFilterNearest) 1168 if (mMagFilterNearest)
1237 { 1169 {
1238 glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1170 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1239 } 1171 }
1240 else 1172 else
1241 { 1173 {
1242 glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1174 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1243 } 1175 }
1244 if (gGLManager.mHasAnisotropic) 1176 if (gGLManager.mHasAnisotropic)
1245 { 1177 {
@@ -1247,16 +1179,15 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
1247 { 1179 {
1248 F32 largest_anisotropy; 1180 F32 largest_anisotropy;
1249 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy); 1181 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy);
1250 glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy); 1182 glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy);
1251 } 1183 }
1252 else 1184 else
1253 { 1185 {
1254 glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); 1186 glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
1255 } 1187 }
1256 } 1188 }
1257 } 1189 stop_glerror();
1258 1190 }
1259 stop_glerror();
1260} 1191}
1261 1192
1262BOOL LLImageGL::getIsResident(BOOL test_now) 1193BOOL LLImageGL::getIsResident(BOOL test_now)
@@ -1337,14 +1268,93 @@ BOOL LLImageGL::getBoundRecently() const
1337 return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); 1268 return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
1338} 1269}
1339 1270
1340void LLImageGL::setTarget(const LLGLenum target, const LLGLenum bind_target) 1271void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
1341{ 1272{
1342 mTarget = target; 1273 mTarget = target;
1343 mBindTarget = bind_target; 1274 mBindTarget = bind_target;
1344} 1275}
1345 1276
1277void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
1278{
1279 if (mFormatType != GL_UNSIGNED_BYTE ||
1280 mFormatPrimary != GL_RGBA)
1281 {
1282 //cannot generate a pick mask for this texture
1283 delete [] mPickMask;
1284 mPickMask = NULL;
1285 return;
1286 }
1287
1288 U32 pick_width = width/2;
1289 U32 pick_height = height/2;
1290
1291 U32 size = llmax(pick_width, (U32) 1) * llmax(pick_height, (U32) 1);
1292
1293 size = size/8 + 1;
1294
1295 delete[] mPickMask;
1296 mPickMask = new U8[size];
1297
1298 memset(mPickMask, 0, sizeof(U8) * size);
1299
1300 U32 pick_bit = 0;
1301
1302 for (S32 y = 0; y < height; y += 2)
1303 {
1304 for (S32 x = 0; x < width; x += 2)
1305 {
1306 U8 alpha = data_in[(y*width+x)*4+3];
1307
1308 if (alpha > 32)
1309 {
1310 U32 pick_idx = pick_bit/8;
1311 U32 pick_offset = pick_bit%8;
1312 if (pick_idx >= size)
1313 {
1314 llerrs << "WTF?" << llendl;
1315 }
1316
1317 mPickMask[pick_idx] |= 1 << pick_offset;
1318 }
1319
1320 ++pick_bit;
1321 }
1322 }
1323}
1324
1325BOOL LLImageGL::getMask(const LLVector2 &tc)
1326{
1327 BOOL res = TRUE;
1328
1329 if (mPickMask)
1330 {
1331 S32 width = getWidth()/2;
1332 S32 height = getHeight()/2;
1333
1334 F32 u = tc.mV[0] - floorf(tc.mV[0]);
1335 F32 v = tc.mV[1] - floorf(tc.mV[1]);
1336
1337 if (u < 0.f || u > 1.f ||
1338 v < 0.f || v > 1.f)
1339 {
1340 llerrs << "WTF?" << llendl;
1341 }
1342
1343 S32 x = (S32)(u * width);
1344 S32 y = (S32)(v * height);
1345
1346 S32 idx = y*width+x;
1347 S32 offset = idx%8;
1348
1349 res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
1350 }
1351
1352 return res;
1353}
1354
1346//---------------------------------------------------------------------------- 1355//----------------------------------------------------------------------------
1347 1356
1357
1348// Manual Mip Generation 1358// Manual Mip Generation
1349/* 1359/*
1350 S32 width = getWidth(discard_level); 1360 S32 width = getWidth(discard_level);
diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h
index 3f231ee..dbe11da 100644
--- a/linden/indra/llrender/llimagegl.h
+++ b/linden/indra/llrender/llimagegl.h
@@ -37,6 +37,9 @@
37 37
38#include "llgltypes.h" 38#include "llgltypes.h"
39#include "llmemory.h" 39#include "llmemory.h"
40#include "v2math.h"
41
42#include "llrender.h"
40 43
41//============================================================================ 44//============================================================================
42 45
@@ -48,11 +51,7 @@ public:
48 static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); 51 static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
49 static S32 dataFormatComponents(S32 dataformat); 52 static S32 dataFormatComponents(S32 dataformat);
50 53
51 // Wrapper for glBindTexture that keeps LLImageGL in sync. 54 void updateBindStats(void) const;
52 // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D
53 static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target);
54 static void unbindTexture(S32 stage, LLGLenum target);
55 static void unbindTexture(S32 stage); // Uses GL_TEXTURE_2D (not a default arg to avoid gl.h dependency)
56 55
57 // needs to be called every frame 56 // needs to be called every frame
58 static void updateStats(F32 current_time); 57 static void updateStats(F32 current_time);
@@ -79,7 +78,6 @@ public:
79 78
80protected: 79protected:
81 virtual ~LLImageGL(); 80 virtual ~LLImageGL();
82 BOOL bindTextureInternal(const S32 stage = 0) const;
83 81
84private: 82private:
85 void glClamp (BOOL clamps, BOOL clampt); 83 void glClamp (BOOL clamps, BOOL clampt);
@@ -87,7 +85,8 @@ private:
87 85
88public: 86public:
89 virtual void dump(); // debugging info to llinfos 87 virtual void dump(); // debugging info to llinfos
90 virtual BOOL bind(const S32 stage = 0) const; 88 virtual bool bindError(const S32 stage = 0) const;
89 virtual bool bindDefaultImage(const S32 stage = 0) const;
91 90
92 void setSize(S32 width, S32 height, S32 ncomponents); 91 void setSize(S32 width, S32 height, S32 ncomponents);
93 92
@@ -132,7 +131,11 @@ public:
132 131
133 BOOL getIsResident(BOOL test_now = FALSE); // not const 132 BOOL getIsResident(BOOL test_now = FALSE); // not const
134 133
135 void setTarget(const LLGLenum target, const LLGLenum bind_target); 134 void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
135
136 LLTexUnit::eTextureType getTarget(void) const { return mBindTarget; }
137 bool isInitialized(void) const { return mInitialized; }
138 void setInitialized (bool initialized) { mInitialized = initialized; }
136 139
137 BOOL getUseMipMaps() const { return mUseMipMaps; } 140 BOOL getUseMipMaps() const { return mUseMipMaps; }
138 void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } 141 void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
@@ -141,6 +144,9 @@ public:
141 144
142 BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; 145 BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
143 146
147 void updatePickMask(S32 width, S32 height, const U8* data_in);
148 BOOL getMask(const LLVector2 &tc);
149
144protected: 150protected:
145 void init(BOOL usemipmaps); 151 void init(BOOL usemipmaps);
146 virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors 152 virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
@@ -152,6 +158,7 @@ public:
152 158
153private: 159private:
154 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL 160 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
161 U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
155 S8 mUseMipMaps; 162 S8 mUseMipMaps;
156 S8 mHasMipMaps; 163 S8 mHasMipMaps;
157 S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents) 164 S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
@@ -159,7 +166,8 @@ private:
159 166
160protected: 167protected:
161 LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps) 168 LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
162 LLGLenum mBindTarget; // NOrmally GL_TEXTURE2D, sometimes something else (ex. cube maps) 169 LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
170 bool mInitialized;
163 171
164 LLGLuint mTexName; 172 LLGLuint mTexName;
165 173
diff --git a/linden/indra/llrender/llpostprocess.cpp b/linden/indra/llrender/llpostprocess.cpp
index c884951..0f1ad5c 100644
--- a/linden/indra/llrender/llpostprocess.cpp
+++ b/linden/indra/llrender/llpostprocess.cpp
@@ -220,9 +220,9 @@ void LLPostProcess::applyColorFilterShader(void)
220 gPostColorFilterProgram.bind(); 220 gPostColorFilterProgram.bind();
221 221
222 gGL.getTexUnit(0)->activate(); 222 gGL.getTexUnit(0)->activate();
223 glEnable(GL_TEXTURE_RECTANGLE_ARB); 223 gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
224 224
225 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); 225 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
226 226
227 getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); 227 getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject);
228 glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); 228 glUniform1iARB(colorFilterUniforms["RenderTexture"], 0);
@@ -264,16 +264,16 @@ void LLPostProcess::applyNightVisionShader(void)
264 gPostNightVisionProgram.bind(); 264 gPostNightVisionProgram.bind();
265 265
266 gGL.getTexUnit(0)->activate(); 266 gGL.getTexUnit(0)->activate();
267 glEnable(GL_TEXTURE_RECTANGLE_ARB); 267 gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
268 268
269 getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); 269 getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject);
270 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); 270 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
271 glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); 271 glUniform1iARB(nightVisionUniforms["RenderTexture"], 0);
272 272
273 gGL.getTexUnit(1)->activate(); 273 gGL.getTexUnit(1)->activate();
274 glEnable(GL_TEXTURE_2D); 274 gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
275 275
276 glBindTexture(GL_TEXTURE_2D, noiseTexture); 276 gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture);
277 glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); 277 glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1);
278 278
279 279
@@ -373,7 +373,7 @@ void LLPostProcess::doEffects(void)
373 373
374void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height) 374void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height)
375{ 375{
376 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); 376 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
377 glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); 377 glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0);
378} 378}
379 379
@@ -487,7 +487,7 @@ void LLPostProcess::createTexture(GLuint & texture, unsigned int width, unsigned
487 std::vector<GLubyte> data(width * height * 4, 0); 487 std::vector<GLubyte> data(width * height * 4, 0);
488 488
489 glGenTextures(1, &texture); 489 glGenTextures(1, &texture);
490 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); 490 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
491 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, 491 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0,
492 GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); 492 GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
493 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 493 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
@@ -509,7 +509,7 @@ void LLPostProcess::createNoiseTexture(GLuint & texture)
509 buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); 509 buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
510 } 510 }
511 } 511 }
512 glBindTexture(GL_TEXTURE_2D, texture); 512 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture);
513 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); 513 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
514 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); 514 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
515 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); 515 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp
index 7be06af..80fed06 100644
--- a/linden/indra/llrender/llrender.cpp
+++ b/linden/indra/llrender/llrender.cpp
@@ -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
37LLRender gGL; 41LLRender gGL;
38 42
@@ -44,6 +48,20 @@ S32 gGLViewport[4];
44 48
45static const U32 LL_NUM_TEXTURE_LAYERS = 8; 49static const U32 LL_NUM_TEXTURE_LAYERS = 8;
46 50
51static GLenum sGLTextureType[] =
52{
53 GL_TEXTURE_2D,
54 GL_TEXTURE_RECTANGLE_ARB,
55 GL_TEXTURE_CUBE_MAP_ARB
56};
57
58static GLint sGLAddressMode[] =
59{
60 GL_REPEAT,
61 GL_MIRRORED_REPEAT,
62 GL_CLAMP_TO_EDGE
63};
64
47static GLenum sGLCompareFunc[] = 65static GLenum sGLCompareFunc[] =
48{ 66{
49 GL_NEVER, 67 GL_NEVER,
@@ -72,82 +90,217 @@ static GLenum sGLBlendFactor[] =
72 GL_ONE_MINUS_SRC_ALPHA 90 GL_ONE_MINUS_SRC_ALPHA
73}; 91};
74 92
75LLTexUnit::LLTexUnit(U32 index) 93LLTexUnit::LLTexUnit(S32 index)
76: mIsEnabled(false), mCurrBlendType(TB_MULT), 94: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
77mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), 95mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
78mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), 96mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
79mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), 97mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
80mCurrColorScale(1), mCurrAlphaScale(1) 98mCurrColorScale(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
86U32 LLTexUnit::getIndex(void) 104//static
105U32 LLTexUnit::getInternalType(eTextureType type)
87{ 106{
88 return mIndex; 107 return sGLTextureType[type];
89} 108}
90 109
91void LLTexUnit::enable(void) 110void LLTexUnit::refreshState(void)
92{ 111{
93 if (!mIsEnabled) 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)
94 { 117 {
95 activate(); 118 glEnable(sGLTextureType[mCurrTexType]);
96 glEnable(GL_TEXTURE_2D); 119 glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
97 mIsEnabled = true;
98 } 120 }
99} 121 else
100
101void LLTexUnit::disable(void)
102{
103 if (mIsEnabled)
104 { 122 {
105 activate();
106 glDisable(GL_TEXTURE_2D); 123 glDisable(GL_TEXTURE_2D);
107 mIsEnabled = false; 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);
108 } 135 }
109} 136}
110 137
111void LLTexUnit::activate(void) 138void LLTexUnit::activate(void)
112{ 139{
113 //if (gGL.mCurrTextureUnitIndex != mIndex) 140 if (mIndex < 0) return;
141
142 if (gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
114 { 143 {
115 glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); 144 glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
116 gGL.mCurrTextureUnitIndex = mIndex; 145 gGL.mCurrTextureUnitIndex = mIndex;
117 } 146 }
118} 147}
119 148
120// Useful for debugging that you've manually assigned a texture operation to the correct 149void LLTexUnit::enable(eTextureType type)
121// texture unit based on the currently set active texture in opengl.
122void LLTexUnit::debugTextureUnit(void)
123{ 150{
124 GLint activeTexture; 151 if (mIndex < 0) return;
125 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture); 152
126 if ((GL_TEXTURE0_ARB + mIndex) != activeTexture) 153 if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
154 {
155 activate();
156 if (mCurrTexType != TT_NONE && !gGL.mDirty)
157 {
158 disable(); // Force a disable of a previous texture type if it's enabled.
159 }
160 mCurrTexType = type;
161 glEnable(sGLTextureType[type]);
162 }
163}
164
165void LLTexUnit::disable(void)
166{
167 if (mIndex < 0) return;
168
169 if (mCurrTexType != TT_NONE)
127 { 170 {
128 llerrs << "Incorrect Texture Unit! Expected: " << (activeTexture - GL_TEXTURE0_ARB) << " Actual: " << mIndex << llendl; 171 activate();
172 unbind(mCurrTexType);
173 glDisable(sGLTextureType[mCurrTexType]);
174 mCurrTexType = TT_NONE;
129 } 175 }
130} 176}
131 177
132void LLTexUnit::bindTexture(const LLImageGL* texture) 178bool LLTexUnit::bind(const LLImageGL* texture)
133{ 179{
180 if (mIndex < 0) return false;
181
182 gGL.flush();
183
184 if (texture == NULL)
185 {
186 return texture->bindError(mIndex);
187 }
188
189 if (!texture->isInitialized())
190 {
191 return texture->bindDefaultImage(mIndex);
192 }
193
194 // Disabled caching of binding state.
134 if (texture != NULL) 195 if (texture != NULL)
135 { 196 {
136 activate(); 197 activate();
137 texture->bind(mIndex); 198 enable(texture->getTarget());
199 mCurrTexture = texture->getTexName();
200 glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
201 texture->updateBindStats();
202 return true;
138 } 203 }
204 return false;
139} 205}
140 206
141void LLTexUnit::unbindTexture(void) 207bool LLTexUnit::bind(LLCubeMap* cubeMap)
142{ 208{
209 if (mIndex < 0) return false;
210
211 gGL.flush();
212
213 // Disabled caching of binding state.
214 if (cubeMap != NULL)
215 {
216 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
217 {
218 activate();
219 enable(LLTexUnit::TT_CUBE_MAP);
220 mCurrTexture = cubeMap->mImages[0]->getTexName();
221 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
222 cubeMap->mImages[0]->updateBindStats();
223 cubeMap->mImages[0]->setMipFilterNearest (FALSE, FALSE);
224 return true;
225 }
226 else
227 {
228 llwarns << "Using cube map without extension!" << llendl
229 }
230 }
231 return false;
232}
233
234bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
235{
236 if (mIndex < 0) return false;
237
238 gGL.flush();
239
240 if (bindDepth)
241 {
242 bindManual(renderTarget->getUsage(), renderTarget->getDepth());
243 }
244 else
245 {
246 bindManual(renderTarget->getUsage(), renderTarget->getTexture());
247 }
248
249 return true;
250}
251
252bool LLTexUnit::bindManual(eTextureType type, U32 texture)
253{
254 if (mIndex < 0) return false;
255
256 // Disabled caching of binding state.
257 gGL.flush();
258
143 activate(); 259 activate();
144 glBindTexture(GL_TEXTURE_2D, 0); 260 enable(type);
261 mCurrTexture = texture;
262 glBindTexture(sGLTextureType[type], texture);
263 return true;
264}
265
266void LLTexUnit::unbind(eTextureType type)
267{
268 if (mIndex < 0) return;
269
270 // Disabled caching of binding state.
271 if (mCurrTexType == type)
272 {
273 gGL.flush();
274
275 activate();
276 mCurrTexture = 0;
277 glBindTexture(sGLTextureType[type], 0);
278 }
279}
280
281void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
282{
283 if (mIndex < 0) return;
284
285 if (true)
286 {
287 activate();
288
289 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
290 glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
291 if (mCurrTexType == TT_CUBE_MAP)
292 {
293 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
294 }
295 }
145} 296}
146 297
147void LLTexUnit::setTextureBlendType(eTextureBlendType type) 298void LLTexUnit::setTextureBlendType(eTextureBlendType type)
148{ 299{
300 if (mIndex < 0) return;
301
149 // Do nothing if it's already correctly set. 302 // Do nothing if it's already correctly set.
150 if (mCurrBlendType == type) 303 if (mCurrBlendType == type && !gGL.mDirty)
151 { 304 {
152 return; 305 return;
153 } 306 }
@@ -262,16 +415,18 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
262 415
263void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) 416void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
264{ 417{
418 if (mIndex < 0) return;
419
265 activate(); 420 activate();
266 if (mCurrBlendType != TB_COMBINE) 421 if (mCurrBlendType != TB_COMBINE || gGL.mDirty)
267 { 422 {
268 mCurrBlendType = TB_COMBINE; 423 mCurrBlendType = TB_COMBINE;
269 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 424 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
270 } 425 }
271 426
272 // We want an early out, because this function does a LOT of stuff. 427 // We want an early out, because this function does a LOT of stuff.
273 if ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2) ) 428 if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
274 || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2) )) 429 || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
275 { 430 {
276 return; 431 return;
277 } 432 }
@@ -304,7 +459,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
304 } 459 }
305 else 460 else
306 { 461 {
307 // Set enums to ALPHA ones 462 // Set enums to RGB ones
308 comb_enum = GL_COMBINE_RGB_ARB; 463 comb_enum = GL_COMBINE_RGB_ARB;
309 src0_enum = GL_SOURCE0_RGB_ARB; 464 src0_enum = GL_SOURCE0_RGB_ARB;
310 src1_enum = GL_SOURCE1_RGB_ARB; 465 src1_enum = GL_SOURCE1_RGB_ARB;
@@ -405,7 +560,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
405 560
406void LLTexUnit::setColorScale(S32 scale) 561void LLTexUnit::setColorScale(S32 scale)
407{ 562{
408 if (mCurrColorScale != scale) 563 if (mCurrColorScale != scale || gGL.mDirty)
409 { 564 {
410 mCurrColorScale = scale; 565 mCurrColorScale = scale;
411 glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); 566 glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
@@ -414,27 +569,52 @@ void LLTexUnit::setColorScale(S32 scale)
414 569
415void LLTexUnit::setAlphaScale(S32 scale) 570void LLTexUnit::setAlphaScale(S32 scale)
416{ 571{
417 if (mCurrAlphaScale != scale) 572 if (mCurrAlphaScale != scale || gGL.mDirty)
418 { 573 {
419 mCurrAlphaScale = scale; 574 mCurrAlphaScale = scale;
420 glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); 575 glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
421 } 576 }
422} 577}
423 578
579// Useful for debugging that you've manually assigned a texture operation to the correct
580// texture unit based on the currently set active texture in opengl.
581void LLTexUnit::debugTextureUnit(void)
582{
583 if (mIndex < 0) return;
584
585 GLint activeTexture;
586 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
587 if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
588 {
589 U32 set_unit = (activeTexture - GL_TEXTURE0_ARB);
590 llwarns << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << llendl;
591 }
592}
593
594
424LLRender::LLRender() 595LLRender::LLRender()
596: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES)
425{ 597{
426 mCount = 0;
427 mMode = LLVertexBuffer::TRIANGLES;
428 mBuffer = new LLVertexBuffer(immediate_mask, 0); 598 mBuffer = new LLVertexBuffer(immediate_mask, 0);
429 mBuffer->allocateBuffer(4096, 0, TRUE); 599 mBuffer->allocateBuffer(4096, 0, TRUE);
430 mBuffer->getVertexStrider(mVerticesp); 600 mBuffer->getVertexStrider(mVerticesp);
431 mBuffer->getTexCoordStrider(mTexcoordsp); 601 mBuffer->getTexCoordStrider(mTexcoordsp);
432 mBuffer->getColorStrider(mColorsp); 602 mBuffer->getColorStrider(mColorsp);
433 603
434 for (unsigned int i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) 604 mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
605 for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
435 { 606 {
436 mTexUnits.push_back(new LLTexUnit(i)); 607 mTexUnits.push_back(new LLTexUnit(i));
437 } 608 }
609 mDummyTexUnit = new LLTexUnit(-1);
610
611 for (U32 i = 0; i < 4; i++)
612 {
613 mCurrColorMask[i] = true;
614 }
615
616 mCurrAlphaFunc = CF_DEFAULT;
617 mCurrAlphaFuncVal = 0.01f;
438} 618}
439 619
440LLRender::~LLRender() 620LLRender::~LLRender()
@@ -449,6 +629,28 @@ void LLRender::shutdown()
449 delete mTexUnits[i]; 629 delete mTexUnits[i];
450 } 630 }
451 mTexUnits.clear(); 631 mTexUnits.clear();
632 delete mDummyTexUnit;
633 mDummyTexUnit = NULL;
634}
635
636void LLRender::refreshState(void)
637{
638 mDirty = true;
639
640 U32 active_unit = mCurrTextureUnitIndex;
641
642 for (U32 i = 0; i < mTexUnits.size(); i++)
643 {
644 mTexUnits[i]->refreshState();
645 }
646
647 mTexUnits[active_unit]->activate();
648
649 setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
650
651 setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
652
653 mDirty = false;
452} 654}
453 655
454void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) 656void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -483,6 +685,12 @@ void LLRender::setColorMask(bool writeColor, bool writeAlpha)
483void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) 685void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
484{ 686{
485 flush(); 687 flush();
688
689 mCurrColorMask[0] = writeColorR;
690 mCurrColorMask[1] = writeColorG;
691 mCurrColorMask[2] = writeColorB;
692 mCurrColorMask[3] = writeAlpha;
693
486 glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); 694 glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha);
487} 695}
488 696
@@ -518,6 +726,9 @@ void LLRender::setSceneBlendType(eBlendType type)
518void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) 726void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
519{ 727{
520 flush(); 728 flush();
729
730 mCurrAlphaFunc = func;
731 mCurrAlphaFuncVal = value;
521 if (func == CF_DEFAULT) 732 if (func == CF_DEFAULT)
522 { 733 {
523 glAlphaFunc(GL_GREATER, 0.01f); 734 glAlphaFunc(GL_GREATER, 0.01f);
@@ -536,22 +747,38 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
536 747
537LLTexUnit* LLRender::getTexUnit(U32 index) 748LLTexUnit* LLRender::getTexUnit(U32 index)
538{ 749{
539 if (index < mTexUnits.size()) 750 if ((index >= 0) && (index < mTexUnits.size()))
540 { 751 {
541 return mTexUnits[index]; 752 return mTexUnits[index];
542 } 753 }
543 llerrs << "Non-existing texture unit layer requested: " << index << llendl; 754 else
544 return NULL; 755 {
756 lldebugs << "Non-existing texture unit layer requested: " << index << llendl;
757 return mDummyTexUnit;
758 }
759}
760
761bool LLRender::verifyTexUnitActive(U32 unitToVerify)
762{
763 if (mCurrTextureUnitIndex == unitToVerify)
764 {
765 return true;
766 }
767 else
768 {
769 llwarns << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << llendl;
770 return false;
771 }
545} 772}
546 773
547void LLRender::begin(const GLuint& mode) 774void LLRender::begin(const GLuint& mode)
548{ 775{
549 if (mode != mMode) 776 if (mode != mMode)
550 { 777 {
551 if (mMode == LLVertexBuffer::QUADS || 778 if (mMode == LLRender::QUADS ||
552 mMode == LLVertexBuffer::LINES || 779 mMode == LLRender::LINES ||
553 mMode == LLVertexBuffer::TRIANGLES || 780 mMode == LLRender::TRIANGLES ||
554 mMode == LLVertexBuffer::POINTS) 781 mMode == LLRender::POINTS)
555 { 782 {
556 flush(); 783 flush();
557 } 784 }
@@ -572,10 +799,10 @@ void LLRender::end()
572 //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; 799 //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl;
573 } 800 }
574 801
575 if ((mMode != LLVertexBuffer::QUADS && 802 if ((mMode != LLRender::QUADS &&
576 mMode != LLVertexBuffer::LINES && 803 mMode != LLRender::LINES &&
577 mMode != LLVertexBuffer::TRIANGLES && 804 mMode != LLRender::TRIANGLES &&
578 mMode != LLVertexBuffer::POINTS) || 805 mMode != LLRender::POINTS) ||
579 mCount > 2048) 806 mCount > 2048)
580 { 807 {
581 flush(); 808 flush();
@@ -638,7 +865,8 @@ void LLRender::flush()
638} 865}
639void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) 866void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
640{ 867{
641 if (mCount >= 4096) 868 //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
869 if (mCount > 4094)
642 { 870 {
643 // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; 871 // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
644 return; 872 return;
@@ -720,3 +948,35 @@ void LLRender::color3fv(const GLfloat* c)
720 color4f(c[0],c[1],c[2],1); 948 color4f(c[0],c[1],c[2],1);
721} 949}
722 950
951void LLRender::debugTexUnits(void)
952{
953 LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
954 std::string active_enabled = "false";
955 for (U32 i = 0; i < mTexUnits.size(); i++)
956 {
957 if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
958 {
959 if (i == mCurrTextureUnitIndex) active_enabled = "true";
960 LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
961 LL_INFOS("TextureUnit") << "Enabled As: " ;
962 switch (getTexUnit(i)->mCurrTexType)
963 {
964 case LLTexUnit::TT_TEXTURE:
965 LL_CONT << "Texture 2D";
966 break;
967 case LLTexUnit::TT_RECT_TEXTURE:
968 LL_CONT << "Texture Rectangle";
969 break;
970 case LLTexUnit::TT_CUBE_MAP:
971 LL_CONT << "Cube Map";
972 break;
973 default:
974 LL_CONT << "ARGH!!! NONE!";
975 break;
976 }
977 LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
978 }
979 }
980 LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
981}
982
diff --git a/linden/indra/llrender/llrender.h b/linden/indra/llrender/llrender.h
index 15360a3..8c648f3 100644
--- a/linden/indra/llrender/llrender.h
+++ b/linden/indra/llrender/llrender.h
@@ -37,14 +37,39 @@
37#ifndef LL_LLGLRENDER_H 37#ifndef LL_LLGLRENDER_H
38#define LL_LLGLRENDER_H 38#define LL_LLGLRENDER_H
39 39
40#include "stdtypes.h" 40//#include "linden_common.h"
41#include "llgltypes.h" 41
42#include "v2math.h"
43#include "v3math.h"
44#include "v4coloru.h"
45#include "llstrider.h"
46#include "llmemory.h"
42#include "llglheaders.h" 47#include "llglheaders.h"
43#include "llvertexbuffer.h" 48
49class LLVertexBuffer;
50class LLCubeMap;
51class LLImageGL;
52class LLRenderTarget;
44 53
45class LLTexUnit 54class LLTexUnit
46{ 55{
56 friend class LLRender;
47public: 57public:
58 typedef enum
59 {
60 TT_TEXTURE = 0, // Standard 2D Texture
61 TT_RECT_TEXTURE, // Non power of 2 texture
62 TT_CUBE_MAP, // 6-sided cube map texture
63 TT_NONE // No texture type is currently enabled
64 } eTextureType;
65
66 typedef enum
67 {
68 TAM_WRAP = 0, // Standard 2D Texture
69 TAM_MIRROR, // Non power of 2 texture
70 TAM_CLAMP // No texture type is currently enabled
71 } eTextureAddressMode;
72
48 typedef enum 73 typedef enum
49 { 74 {
50 TB_REPLACE = 0, 75 TB_REPLACE = 0,
@@ -93,15 +118,36 @@ public:
93 TBS_ONE_MINUS_CONST_ALPHA 118 TBS_ONE_MINUS_CONST_ALPHA
94 } eTextureBlendSrc; 119 } eTextureBlendSrc;
95 120
96 LLTexUnit(U32 index); 121 LLTexUnit(S32 index);
97 U32 getIndex(void); 122
123 // Refreshes renderer state of the texture unit to the cached values
124 // Needed when the render context has changed and invalidated the current state
125 void refreshState(void);
126
127 // returns the index of this texture unit
128 S32 getIndex(void) const { return mIndex; }
98 129
99 void enable(void); 130 // Sets this tex unit to be the currently active one
100 void disable(void); 131 void activate(void);
101 void activate(void); 132
133 // Enables this texture unit for the given texture type (automatically disables any previously enabled texture type)
134 void enable(eTextureType type);
135 // Disables the current texture unit
136 void disable(void);
137
138 // Binds the LLImageGL to this texture unit (automatically enables the unit for the LLImageGL's texture type)
139 bool bind(const LLImageGL* texture);
140 // Binds a cubemap to this texture unit (automatically enables the texture unit for cubemaps)
141 bool bind(LLCubeMap* cubeMap);
142 // Binds a render target to this texture unit (automatically enables the texture unit for the RT's texture type)
143 bool bind(LLRenderTarget * renderTarget, bool bindDepth = false);
144 // Manually binds a texture to the texture unit (automatically enables the tex unit for the given texture type)
145 bool bindManual(eTextureType type, U32 texture);
146
147 // Unbinds the currently bound texture of the given type (only if there's a texture of the given type currently bound)
148 void unbind(eTextureType type);
102 149
103 void bindTexture(const LLImageGL* texture); 150 void setTextureAddressMode(eTextureAddressMode mode);
104 void unbindTexture(void);
105 151
106 void setTextureBlendType(eTextureBlendType type); 152 void setTextureBlendType(eTextureBlendType type);
107 153
@@ -110,11 +156,14 @@ public:
110 156
111 // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead. 157 // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead.
112 inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA) 158 inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA)
113 { setTextureCombiner(op, src1, src2, true); } 159 { setTextureCombiner(op, src1, src2, true); }
114 160
115private: 161 static U32 getInternalType(eTextureType type);
116 U32 mIndex; 162
117 bool mIsEnabled; 163protected:
164 S32 mIndex;
165 U32 mCurrTexture;
166 eTextureType mCurrTexType;
118 eTextureBlendType mCurrBlendType; 167 eTextureBlendType mCurrBlendType;
119 eTextureBlendOp mCurrColorOp; 168 eTextureBlendOp mCurrColorOp;
120 eTextureBlendSrc mCurrColorSrc1; 169 eTextureBlendSrc mCurrColorSrc1;
@@ -137,6 +186,19 @@ class LLRender
137{ 186{
138 friend class LLTexUnit; 187 friend class LLTexUnit;
139public: 188public:
189
190 typedef enum {
191 TRIANGLES = 0,
192 TRIANGLE_STRIP,
193 TRIANGLE_FAN,
194 POINTS,
195 LINES,
196 LINE_STRIP,
197 QUADS,
198 LINE_LOOP,
199 NUM_MODES
200 } eGeomModes;
201
140 typedef enum 202 typedef enum
141 { 203 {
142 CF_NEVER = 0, 204 CF_NEVER = 0,
@@ -178,6 +240,10 @@ public:
178 ~LLRender(); 240 ~LLRender();
179 void shutdown(); 241 void shutdown();
180 242
243 // Refreshes renderer state to the cached values
244 // Needed when the render context has changed and invalidated the current state
245 void refreshState(void);
246
181 void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); 247 void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
182 void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z); 248 void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
183 void pushMatrix(); 249 void pushMatrix();
@@ -214,7 +280,13 @@ public:
214 280
215 LLTexUnit* getTexUnit(U32 index); 281 LLTexUnit* getTexUnit(U32 index);
216 282
217 typedef struct Vertex 283 U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
284
285 bool verifyTexUnitActive(U32 unitToVerify);
286
287 void debugTexUnits(void);
288
289 struct Vertex
218 { 290 {
219 GLfloat v[3]; 291 GLfloat v[3];
220 GLubyte c[4]; 292 GLubyte c[4];
@@ -224,14 +296,20 @@ public:
224public: 296public:
225 297
226private: 298private:
227 U32 mCount; 299 bool mDirty;
228 U32 mMode; 300 U32 mCount;
229 U32 mCurrTextureUnitIndex; 301 U32 mMode;
230 LLPointer<LLVertexBuffer> mBuffer; 302 U32 mCurrTextureUnitIndex;
231 LLStrider<LLVector3> mVerticesp; 303 bool mCurrColorMask[4];
232 LLStrider<LLVector2> mTexcoordsp; 304 eCompareFunc mCurrAlphaFunc;
233 LLStrider<LLColor4U> mColorsp; 305 F32 mCurrAlphaFuncVal;
234 std::vector<LLTexUnit*> mTexUnits; 306
307 LLPointer<LLVertexBuffer> mBuffer;
308 LLStrider<LLVector3> mVerticesp;
309 LLStrider<LLVector2> mTexcoordsp;
310 LLStrider<LLColor4U> mColorsp;
311 std::vector<LLTexUnit*> mTexUnits;
312 LLTexUnit* mDummyTexUnit;
235}; 313};
236 314
237extern F64 gGLModelView[16]; 315extern F64 gGLModelView[16];
diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp
index e18ec56..9d693a7 100644
--- a/linden/indra/llrender/llrendertarget.cpp
+++ b/linden/indra/llrender/llrendertarget.cpp
@@ -47,7 +47,7 @@ LLRenderTarget::LLRenderTarget() :
47 mStencil(0), 47 mStencil(0),
48 mUseDepth(FALSE), 48 mUseDepth(FALSE),
49 mRenderDepth(FALSE), 49 mRenderDepth(FALSE),
50 mUsage(GL_TEXTURE_2D) 50 mUsage(LLTexUnit::TT_TEXTURE)
51{ 51{
52} 52}
53 53
@@ -56,7 +56,7 @@ LLRenderTarget::~LLRenderTarget()
56 release(); 56 release();
57} 57}
58 58
59void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL use_fbo) 59void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage, BOOL use_fbo)
60{ 60{
61 stop_glerror(); 61 stop_glerror();
62 mResX = resx; 62 mResX = resx;
@@ -67,22 +67,22 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
67 release(); 67 release();
68 68
69 glGenTextures(1, (GLuint *) &mTex); 69 glGenTextures(1, (GLuint *) &mTex);
70 glBindTexture(mUsage, mTex); 70 gGL.getTexUnit(0)->bindManual(mUsage, mTex);
71 glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL); 71 glTexImage2D(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL);
72 72
73 glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 73 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
74 glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 74 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
75 75
76 if (mUsage != GL_TEXTURE_RECTANGLE_ARB) 76 if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
77 { 77 {
78 glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); 78 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
79 glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); 79 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
80 } 80 }
81 else 81 else
82 { 82 {
83 // ATI doesn't support mirrored repeat for rectangular textures. 83 // ATI doesn't support mirrored repeat for rectangular textures.
84 glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 84 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
85 glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 85 glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
86 } 86 }
87 87
88 stop_glerror(); 88 stop_glerror();
@@ -107,14 +107,14 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
107 107
108 if (mDepth) 108 if (mDepth)
109 { 109 {
110 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0); 110 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
111 stop_glerror(); 111 stop_glerror();
112 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0); 112 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
113 stop_glerror(); 113 stop_glerror();
114 } 114 }
115 115
116 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 116 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
117 mUsage, mTex, 0); 117 LLTexUnit::getInternalType(mUsage), mTex, 0);
118 stop_glerror(); 118 stop_glerror();
119 119
120 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 120 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@@ -125,10 +125,11 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
125void LLRenderTarget::allocateDepth() 125void LLRenderTarget::allocateDepth()
126{ 126{
127 glGenTextures(1, (GLuint *) &mDepth); 127 glGenTextures(1, (GLuint *) &mDepth);
128 glBindTexture(mUsage, mDepth); 128 gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
129 glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 129 U32 internal_type = LLTexUnit::getInternalType(mUsage);
130 glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 130 glTexParameteri(internal_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
131 glTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); 131 glTexParameteri(internal_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
132 glTexImage2D(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
132} 133}
133 134
134void LLRenderTarget::release() 135void LLRenderTarget::release()
@@ -191,24 +192,13 @@ void LLRenderTarget::clear()
191 } 192 }
192} 193}
193 194
194void LLRenderTarget::bindTexture()
195{
196 glBindTexture(mUsage, mTex);
197}
198
199void LLRenderTarget::bindDepth()
200{
201 glBindTexture(mUsage, mDepth);
202}
203
204
205void LLRenderTarget::flush(BOOL fetch_depth) 195void LLRenderTarget::flush(BOOL fetch_depth)
206{ 196{
207 gGL.flush(); 197 gGL.flush();
208 if (!mFBO) 198 if (!mFBO)
209 { 199 {
210 bindTexture(); 200 gGL.getTexUnit(0)->bind(this);
211 glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY); 201 glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY);
212 202
213 if (fetch_depth) 203 if (fetch_depth)
214 { 204 {
@@ -217,8 +207,8 @@ void LLRenderTarget::flush(BOOL fetch_depth)
217 allocateDepth(); 207 allocateDepth();
218 } 208 }
219 209
220 bindDepth(); 210 gGL.getTexUnit(0)->bind(this, true);
221 glCopyTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0); 211 glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0);
222 } 212 }
223 } 213 }
224 else 214 else
diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h
index 5e3c4d9..65bab8b 100644
--- a/linden/indra/llrender/llrendertarget.h
+++ b/linden/indra/llrender/llrendertarget.h
@@ -33,6 +33,7 @@
33#define LL_LLRENDERTARGET_H 33#define LL_LLRENDERTARGET_H
34 34
35#include "llgl.h" 35#include "llgl.h"
36#include "llrender.h"
36 37
37/* 38/*
38 SAMPLE USAGE: 39 SAMPLE USAGE:
@@ -53,7 +54,7 @@
53 ... 54 ...
54 55
55 //use target as a texture 56 //use target as a texture
56 target.bindTexture(); 57 gGL.getTexUnit(INDEX)->bind(&target);
57 ... <issue drawing commands> ... 58 ... <issue drawing commands> ...
58 59
59*/ 60*/
@@ -71,7 +72,7 @@ public:
71 //allocate resources for rendering 72 //allocate resources for rendering
72 //must be called before use 73 //must be called before use
73 //multiple calls will release previously allocated resources 74 //multiple calls will release previously allocated resources
74 void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = FALSE); 75 void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE);
75 76
76 //allocate a depth texture 77 //allocate a depth texture
77 void allocateDepth(); 78 void allocateDepth();
@@ -100,11 +101,11 @@ public:
100 //get Y resolution 101 //get Y resolution
101 U32 getHeight() const { return mResY; } 102 U32 getHeight() const { return mResY; }
102 103
103 //bind results of render for sampling 104 LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
104 void bindTexture();
105 105
106 //bind results of render for sampling depth buffer 106 U32 getTexture(void) const { return mTex; }
107 void bindDepth(); 107
108 U32 getDepth(void) const { return mDepth; }
108 109
109 //flush rendering operations 110 //flush rendering operations
110 //must be called when rendering is complete 111 //must be called when rendering is complete
@@ -128,7 +129,7 @@ private:
128 U32 mStencil; 129 U32 mStencil;
129 BOOL mUseDepth; 130 BOOL mUseDepth;
130 BOOL mRenderDepth; 131 BOOL mRenderDepth;
131 U32 mUsage; 132 LLTexUnit::eTextureType mUsage;
132 133
133}; 134};
134 135
diff --git a/linden/indra/llrender/llshadermgr.cpp b/linden/indra/llrender/llshadermgr.cpp
index 4416775..d884c15 100644
--- a/linden/indra/llrender/llshadermgr.cpp
+++ b/linden/indra/llrender/llshadermgr.cpp
@@ -307,7 +307,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
307 { 307 {
308 LL_DEBUGS("ShaderLoading") << log << LL_ENDL; 308 LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
309 } 309 }
310} 310 }
311} 311}
312 312
313GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type) 313GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type)
diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp
index 547663b..465c4ca 100644
--- a/linden/indra/llrender/llvertexbuffer.cpp
+++ b/linden/indra/llrender/llvertexbuffer.cpp
@@ -76,7 +76,7 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
76 sizeof(LLVector4), // TYPE_CLOTHWEIGHT, 76 sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
77}; 77};
78 78
79U32 LLVertexBuffer::sGLMode[LLVertexBuffer::NUM_MODES] = 79U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
80{ 80{
81 GL_TRIANGLES, 81 GL_TRIANGLES,
82 GL_TRIANGLE_STRIP, 82 GL_TRIANGLE_STRIP,
@@ -187,7 +187,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
187 llerrs << "Wrong vertex buffer bound." << llendl; 187 llerrs << "Wrong vertex buffer bound." << llendl;
188 } 188 }
189 189
190 if (mode > NUM_MODES) 190 if (mode > LLRender::NUM_MODES)
191 { 191 {
192 llerrs << "Invalid draw mode: " << mode << llendl; 192 llerrs << "Invalid draw mode: " << mode << llendl;
193 return; 193 return;
@@ -216,7 +216,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
216 llerrs << "Wrong vertex buffer bound." << llendl; 216 llerrs << "Wrong vertex buffer bound." << llendl;
217 } 217 }
218 218
219 if (mode > NUM_MODES) 219 if (mode > LLRender::NUM_MODES)
220 { 220 {
221 llerrs << "Invalid draw mode: " << mode << llendl; 221 llerrs << "Invalid draw mode: " << mode << llendl;
222 return; 222 return;
@@ -240,7 +240,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
240 llerrs << "Wrong vertex buffer bound." << llendl; 240 llerrs << "Wrong vertex buffer bound." << llendl;
241 } 241 }
242 242
243 if (mode > NUM_MODES) 243 if (mode > LLRender::NUM_MODES)
244 { 244 {
245 llerrs << "Invalid draw mode: " << mode << llendl; 245 llerrs << "Invalid draw mode: " << mode << llendl;
246 return; 246 return;
diff --git a/linden/indra/llrender/llvertexbuffer.h b/linden/indra/llrender/llvertexbuffer.h
index 8edcf69..a97c74e 100644
--- a/linden/indra/llrender/llvertexbuffer.h
+++ b/linden/indra/llrender/llvertexbuffer.h
@@ -39,6 +39,7 @@
39#include "v4coloru.h" 39#include "v4coloru.h"
40#include "llstrider.h" 40#include "llstrider.h"
41#include "llmemory.h" 41#include "llmemory.h"
42#include "llrender.h"
42#include <set> 43#include <set>
43#include <vector> 44#include <vector>
44#include <list> 45#include <list>
@@ -123,19 +124,8 @@ public:
123 MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped 124 MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
124 }; 125 };
125 126
126 enum {
127 TRIANGLES = 0,
128 TRIANGLE_STRIP,
129 TRIANGLE_FAN,
130 POINTS,
131 LINES,
132 LINE_STRIP,
133 QUADS,
134 LINE_LOOP,
135 NUM_MODES
136 };
137protected: 127protected:
138 friend class LLGLImmediate; 128 friend class LLRender;
139 129
140 virtual ~LLVertexBuffer(); // use unref() 130 virtual ~LLVertexBuffer(); // use unref()
141 131
@@ -255,7 +245,7 @@ public:
255 245
256 static BOOL sEnableVBOs; 246 static BOOL sEnableVBOs;
257 static S32 sTypeOffsets[TYPE_MAX]; 247 static S32 sTypeOffsets[TYPE_MAX];
258 static U32 sGLMode[NUM_MODES]; 248 static U32 sGLMode[LLRender::NUM_MODES];
259 static U32 sGLRenderBuffer; 249 static U32 sGLRenderBuffer;
260 static U32 sGLRenderIndices; 250 static U32 sGLRenderIndices;
261 static BOOL sVBOActive; 251 static BOOL sVBOActive;