aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llimagegl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llrender/llimagegl.cpp')
-rw-r--r--linden/indra/llrender/llimagegl.cpp266
1 files changed, 138 insertions, 128 deletions
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);