diff options
Diffstat (limited to 'linden/indra/llrender/llimagegl.cpp')
-rw-r--r-- | linden/indra/llrender/llimagegl.cpp | 266 |
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 |
128 | void 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 | ||
144 | void 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) | ||
165 | void LLImageGL::unbindTexture(S32 stage) | ||
166 | { | ||
167 | unbindTexture(stage, GL_TEXTURE_2D); | ||
168 | } | ||
169 | |||
170 | // static | ||
171 | void LLImageGL::updateStats(F32 current_time) | 128 | void 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 | ||
326 | void LLImageGL::cleanup() | 288 | void LLImageGL::cleanup() |
@@ -421,41 +383,14 @@ void LLImageGL::dump() | |||
421 | 383 | ||
422 | //---------------------------------------------------------------------------- | 384 | //---------------------------------------------------------------------------- |
423 | 385 | ||
424 | BOOL LLImageGL::bindTextureInternal(const S32 stage) const | 386 | void 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 |
487 | BOOL LLImageGL::bind(const S32 stage) const | 405 | bool 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); | 411 | bool LLImageGL::bindDefaultImage(const S32 stage) const |
494 | //llassert(res); | 412 | { |
495 | return res; | 413 | return false; |
496 | } | 414 | } |
497 | 415 | ||
416 | |||
498 | void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) | 417 | void 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 | ||
718 | BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) | 650 | BOOL 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 |
818 | BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height) | 749 | BOOL 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 | ||
1149 | void LLImageGL::destroyGLTexture() | 1081 | void 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 | ||
1262 | BOOL LLImageGL::getIsResident(BOOL test_now) | 1193 | BOOL 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 | ||
1340 | void LLImageGL::setTarget(const LLGLenum target, const LLGLenum bind_target) | 1271 | void 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 | ||
1277 | void 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 | |||
1325 | BOOL 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); |