diff options
author | Jacek Antonelli | 2009-04-30 13:04:20 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-04-30 13:07:16 -0500 |
commit | ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch) | |
tree | 8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/llrender/llimagegl.cpp | |
parent | Second Life viewer sources 1.22.11 (diff) | |
download | meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2 meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz |
Second Life viewer sources 1.23.0-RC
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llrender/llimagegl.cpp | 315 |
1 files changed, 210 insertions, 105 deletions
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 6a142a7..cdf626e 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -62,7 +63,6 @@ BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; | |||
62 | F32 LLImageGL::sLastFrameTime = 0.f; | 63 | F32 LLImageGL::sLastFrameTime = 0.f; |
63 | 64 | ||
64 | std::set<LLImageGL*> LLImageGL::sImageList; | 65 | std::set<LLImageGL*> LLImageGL::sImageList; |
65 | |||
66 | //************************************************************************************** | 66 | //************************************************************************************** |
67 | //below are functions for debug use | 67 | //below are functions for debug use |
68 | //do not delete them even though they are not currently being used. | 68 | //do not delete them even though they are not currently being used. |
@@ -308,21 +308,21 @@ void LLImageGL::init(BOOL usemipmaps) | |||
308 | #endif | 308 | #endif |
309 | 309 | ||
310 | mPickMask = NULL; | 310 | mPickMask = NULL; |
311 | mTextureState = NO_DELETE ; | ||
311 | mTextureMemory = 0; | 312 | mTextureMemory = 0; |
312 | mLastBindTime = 0.f; | 313 | mLastBindTime = 0.f; |
313 | 314 | ||
314 | mTarget = GL_TEXTURE_2D; | 315 | mTarget = GL_TEXTURE_2D; |
315 | mBindTarget = LLTexUnit::TT_TEXTURE; | 316 | mBindTarget = LLTexUnit::TT_TEXTURE; |
316 | mUseMipMaps = usemipmaps; | 317 | mUseMipMaps = usemipmaps; |
317 | mHasMipMaps = FALSE; | 318 | mHasMipMaps = false; |
318 | mAutoGenMips = FALSE; | 319 | mAutoGenMips = FALSE; |
319 | mTexName = 0; | 320 | mTexName = 0; |
320 | mIsResident = 0; | 321 | mIsResident = 0; |
321 | mClampS = FALSE; | 322 | |
322 | mClampT = FALSE; | 323 | mTexOptionsDirty = true; |
323 | mClampR = FALSE; | 324 | mAddressMode = LLTexUnit::TAM_WRAP; |
324 | mMagFilterNearest = FALSE; | 325 | mFilterOption = LLTexUnit::TFO_ANISOTROPIC; |
325 | mMinFilterNearest = FALSE; | ||
326 | mWidth = 0; | 326 | mWidth = 0; |
327 | mHeight = 0; | 327 | mHeight = 0; |
328 | mComponents = 0; | 328 | mComponents = 0; |
@@ -338,6 +338,7 @@ void LLImageGL::init(BOOL usemipmaps) | |||
338 | mHasExplicitFormat = FALSE; | 338 | mHasExplicitFormat = FALSE; |
339 | 339 | ||
340 | mGLTextureCreated = FALSE ; | 340 | mGLTextureCreated = FALSE ; |
341 | mIsMask = FALSE; | ||
341 | } | 342 | } |
342 | 343 | ||
343 | void LLImageGL::cleanup() | 344 | void LLImageGL::cleanup() |
@@ -468,6 +469,11 @@ bool LLImageGL::bindDefaultImage(const S32 stage) const | |||
468 | return false; | 469 | return false; |
469 | } | 470 | } |
470 | 471 | ||
472 | //virtual | ||
473 | void LLImageGL::forceImmediateUpdate() | ||
474 | { | ||
475 | return ; | ||
476 | } | ||
471 | 477 | ||
472 | void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) | 478 | void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) |
473 | { | 479 | { |
@@ -497,17 +503,15 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) | |||
497 | void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | 503 | void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) |
498 | { | 504 | { |
499 | // LLFastTimer t1(LLFastTimer::FTM_TEMP1); | 505 | // LLFastTimer t1(LLFastTimer::FTM_TEMP1); |
500 | 506 | llpushcallstacks ; | |
501 | bool is_compressed = false; | 507 | bool is_compressed = false; |
502 | if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) | 508 | if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) |
503 | { | 509 | { |
504 | is_compressed = true; | 510 | is_compressed = true; |
505 | } | 511 | } |
506 | 512 | ||
507 | { | ||
508 | // LLFastTimer t2(LLFastTimer::FTM_TEMP2); | 513 | // LLFastTimer t2(LLFastTimer::FTM_TEMP2); |
509 | llverify(gGL.getTexUnit(0)->bind(this)); | 514 | gGL.getTexUnit(0)->bind(this); |
510 | } | ||
511 | 515 | ||
512 | if (mUseMipMaps) | 516 | if (mUseMipMaps) |
513 | { | 517 | { |
@@ -518,6 +522,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
518 | // are stored BEFORE the largest image | 522 | // are stored BEFORE the largest image |
519 | for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++) | 523 | for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++) |
520 | { | 524 | { |
525 | |||
521 | S32 w = getWidth(d); | 526 | S32 w = getWidth(d); |
522 | S32 h = getHeight(d); | 527 | S32 h = getHeight(d); |
523 | S32 gl_level = d-mCurrentDiscardLevel; | 528 | S32 gl_level = d-mCurrentDiscardLevel; |
@@ -528,7 +533,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
528 | if (is_compressed) | 533 | if (is_compressed) |
529 | { | 534 | { |
530 | // LLFastTimer t2(LLFastTimer::FTM_TEMP4); | 535 | // LLFastTimer t2(LLFastTimer::FTM_TEMP4); |
531 | S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); | 536 | S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); |
532 | glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); | 537 | glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); |
533 | stop_glerror(); | 538 | stop_glerror(); |
534 | } | 539 | } |
@@ -542,7 +547,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
542 | stop_glerror(); | 547 | stop_glerror(); |
543 | } | 548 | } |
544 | 549 | ||
545 | glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); | 550 | LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); |
551 | if (gl_level == 0) | ||
552 | { | ||
553 | analyzeAlpha(data_in, w, h); | ||
554 | } | ||
546 | updatePickMask(w, h, data_in); | 555 | updatePickMask(w, h, data_in); |
547 | 556 | ||
548 | if(mFormatSwapBytes) | 557 | if(mFormatSwapBytes) |
@@ -574,10 +583,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
574 | S32 w = getWidth(mCurrentDiscardLevel); | 583 | S32 w = getWidth(mCurrentDiscardLevel); |
575 | S32 h = getHeight(mCurrentDiscardLevel); | 584 | S32 h = getHeight(mCurrentDiscardLevel); |
576 | 585 | ||
577 | glTexImage2D(mTarget, 0, mFormatInternal, | 586 | LLImageGL::setManualImage(mTarget, 0, mFormatInternal, |
578 | w, h, 0, | 587 | w, h, |
579 | mFormatPrimary, mFormatType, | 588 | mFormatPrimary, mFormatType, |
580 | data_in); | 589 | data_in); |
590 | analyzeAlpha(data_in, w, h); | ||
581 | stop_glerror(); | 591 | stop_glerror(); |
582 | 592 | ||
583 | updatePickMask(w, h, data_in); | 593 | updatePickMask(w, h, data_in); |
@@ -629,7 +639,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
629 | stop_glerror(); | 639 | stop_glerror(); |
630 | } | 640 | } |
631 | 641 | ||
632 | glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); | 642 | LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data); |
643 | if (m == 0) | ||
644 | { | ||
645 | analyzeAlpha(data_in, w, h); | ||
646 | } | ||
633 | stop_glerror(); | 647 | stop_glerror(); |
634 | if (m == 0) | 648 | if (m == 0) |
635 | { | 649 | { |
@@ -662,7 +676,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
662 | { | 676 | { |
663 | llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; | 677 | llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; |
664 | } | 678 | } |
665 | mHasMipMaps = TRUE; | 679 | mHasMipMaps = true; |
666 | } | 680 | } |
667 | else | 681 | else |
668 | { | 682 | { |
@@ -683,8 +697,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
683 | stop_glerror(); | 697 | stop_glerror(); |
684 | } | 698 | } |
685 | 699 | ||
686 | glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0, | 700 | LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, |
687 | mFormatPrimary, mFormatType, (GLvoid *)data_in); | 701 | mFormatPrimary, mFormatType, (GLvoid *)data_in); |
702 | analyzeAlpha(data_in, w, h); | ||
703 | |||
688 | updatePickMask(w, h, data_in); | 704 | updatePickMask(w, h, data_in); |
689 | 705 | ||
690 | stop_glerror(); | 706 | stop_glerror(); |
@@ -696,14 +712,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) | |||
696 | } | 712 | } |
697 | 713 | ||
698 | } | 714 | } |
699 | mHasMipMaps = FALSE; | 715 | mHasMipMaps = false; |
700 | } | 716 | } |
701 | stop_glerror(); | 717 | stop_glerror(); |
702 | mGLTextureCreated = true; | 718 | mGLTextureCreated = true; |
719 | llpushcallstacks ; | ||
703 | } | 720 | } |
704 | 721 | ||
705 | BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) | 722 | BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) |
706 | { | 723 | { |
724 | llpushcallstacks ; | ||
707 | if (!width || !height) | 725 | if (!width || !height) |
708 | { | 726 | { |
709 | return TRUE; | 727 | return TRUE; |
@@ -779,6 +797,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
779 | 797 | ||
780 | glTexSubImage2D(mTarget, 0, x_pos, y_pos, | 798 | glTexSubImage2D(mTarget, 0, x_pos, y_pos, |
781 | width, height, mFormatPrimary, mFormatType, datap); | 799 | width, height, mFormatPrimary, mFormatType, datap); |
800 | gGL.getTexUnit(0)->disable(); | ||
782 | stop_glerror(); | 801 | stop_glerror(); |
783 | 802 | ||
784 | if(mFormatSwapBytes) | 803 | if(mFormatSwapBytes) |
@@ -791,6 +810,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 | |||
791 | stop_glerror(); | 810 | stop_glerror(); |
792 | mGLTextureCreated = true; | 811 | mGLTextureCreated = true; |
793 | } | 812 | } |
813 | llpushcallstacks ; | ||
794 | return TRUE; | 814 | return TRUE; |
795 | } | 815 | } |
796 | 816 | ||
@@ -815,6 +835,24 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ | |||
815 | } | 835 | } |
816 | } | 836 | } |
817 | 837 | ||
838 | // static | ||
839 | void LLImageGL::generateTextures(S32 numTextures, U32 *textures) | ||
840 | { | ||
841 | glGenTextures(numTextures, (GLuint*)textures); | ||
842 | } | ||
843 | |||
844 | // static | ||
845 | void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) | ||
846 | { | ||
847 | glDeleteTextures(numTextures, (GLuint*)textures); | ||
848 | } | ||
849 | |||
850 | // static | ||
851 | void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) | ||
852 | { | ||
853 | glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); | ||
854 | } | ||
855 | |||
818 | //create an empty GL texture: just create a texture name | 856 | //create an empty GL texture: just create a texture name |
819 | //the texture is assiciate with some image by calling glTexImage outside LLImageGL | 857 | //the texture is assiciate with some image by calling glTexImage outside LLImageGL |
820 | BOOL LLImageGL::createGLTexture() | 858 | BOOL LLImageGL::createGLTexture() |
@@ -847,6 +885,7 @@ BOOL LLImageGL::createGLTexture() | |||
847 | 885 | ||
848 | BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) | 886 | BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) |
849 | { | 887 | { |
888 | llpushcallstacks ; | ||
850 | if (gGLManager.mIsDisabled) | 889 | if (gGLManager.mIsDisabled) |
851 | { | 890 | { |
852 | llwarns << "Trying to create a texture while GL is disabled!" << llendl; | 891 | llwarns << "Trying to create a texture while GL is disabled!" << llendl; |
@@ -907,6 +946,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S | |||
907 | 946 | ||
908 | BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) | 947 | BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) |
909 | { | 948 | { |
949 | llpushcallstacks ; | ||
910 | llassert(data_in); | 950 | llassert(data_in); |
911 | 951 | ||
912 | if (discard_level < 0) | 952 | if (discard_level < 0) |
@@ -923,7 +963,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ | |||
923 | return TRUE; | 963 | return TRUE; |
924 | } | 964 | } |
925 | 965 | ||
926 | GLuint old_name = mTexName; | 966 | U32 old_name = mTexName; |
927 | // S32 old_discard = mCurrentDiscardLevel; | 967 | // S32 old_discard = mCurrentDiscardLevel; |
928 | 968 | ||
929 | if (usename != 0) | 969 | if (usename != 0) |
@@ -932,7 +972,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ | |||
932 | } | 972 | } |
933 | else | 973 | else |
934 | { | 974 | { |
935 | glGenTextures(1, (GLuint*)&mTexName); | 975 | LLImageGL::generateTextures(1, &mTexName); |
936 | stop_glerror(); | 976 | stop_glerror(); |
937 | { | 977 | { |
938 | // LLFastTimer t1(LLFastTimer::FTM_TEMP6); | 978 | // LLFastTimer t1(LLFastTimer::FTM_TEMP6); |
@@ -962,9 +1002,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ | |||
962 | 1002 | ||
963 | setImage(data_in, data_hasmips); | 1003 | setImage(data_in, data_hasmips); |
964 | 1004 | ||
965 | setClamp(mClampS, mClampT); | 1005 | // Set texture options to our defaults. |
966 | setMipFilterNearest(mMagFilterNearest); | 1006 | gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); |
967 | 1007 | gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); | |
1008 | gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); | ||
1009 | |||
968 | // things will break if we don't unbind after creation | 1010 | // things will break if we don't unbind after creation |
969 | gGL.getTexUnit(0)->unbind(mBindTarget); | 1011 | gGL.getTexUnit(0)->unbind(mBindTarget); |
970 | stop_glerror(); | 1012 | stop_glerror(); |
@@ -972,16 +1014,18 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ | |||
972 | if (old_name != 0) | 1014 | if (old_name != 0) |
973 | { | 1015 | { |
974 | sGlobalTextureMemory -= mTextureMemory; | 1016 | sGlobalTextureMemory -= mTextureMemory; |
975 | glDeleteTextures(1, &old_name); | 1017 | LLImageGL::deleteTextures(1, &old_name); |
976 | stop_glerror(); | 1018 | stop_glerror(); |
977 | } | 1019 | } |
978 | 1020 | ||
979 | mTextureMemory = getMipBytes(discard_level); | 1021 | mTextureMemory = getMipBytes(discard_level); |
980 | sGlobalTextureMemory += mTextureMemory; | 1022 | sGlobalTextureMemory += mTextureMemory; |
981 | 1023 | setActive() ; | |
1024 | |||
982 | // mark this as bound at this point, so we don't throw it out immediately | 1025 | // mark this as bound at this point, so we don't throw it out immediately |
983 | mLastBindTime = sLastFrameTime; | 1026 | mLastBindTime = sLastFrameTime; |
984 | 1027 | ||
1028 | llpushcallstacks ; | ||
985 | return TRUE; | 1029 | return TRUE; |
986 | } | 1030 | } |
987 | 1031 | ||
@@ -1054,6 +1098,7 @@ BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_h | |||
1054 | 1098 | ||
1055 | BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) | 1099 | BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) |
1056 | { | 1100 | { |
1101 | llpushcallstacks ; | ||
1057 | if (discard_level < 0) | 1102 | if (discard_level < 0) |
1058 | { | 1103 | { |
1059 | discard_level = mCurrentDiscardLevel; | 1104 | discard_level = mCurrentDiscardLevel; |
@@ -1068,7 +1113,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre | |||
1068 | 1113 | ||
1069 | //explicitly unbind texture | 1114 | //explicitly unbind texture |
1070 | gGL.getTexUnit(0)->unbind(mBindTarget); | 1115 | gGL.getTexUnit(0)->unbind(mBindTarget); |
1071 | llverify(gGL.getTexUnit(0)->bind(this)); | 1116 | llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName)); |
1072 | 1117 | ||
1073 | //debug code, leave it there commented. | 1118 | //debug code, leave it there commented. |
1074 | //checkTexSize() ; | 1119 | //checkTexSize() ; |
@@ -1156,7 +1201,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre | |||
1156 | return FALSE ; | 1201 | return FALSE ; |
1157 | } | 1202 | } |
1158 | //----------------------------------------------------------------------------------------------- | 1203 | //----------------------------------------------------------------------------------------------- |
1159 | 1204 | llpushcallstacks ; | |
1160 | return TRUE ; | 1205 | return TRUE ; |
1161 | } | 1206 | } |
1162 | 1207 | ||
@@ -1178,8 +1223,10 @@ void LLImageGL::destroyGLTexture() | |||
1178 | sGlobalTextureMemory -= mTextureMemory; | 1223 | sGlobalTextureMemory -= mTextureMemory; |
1179 | mTextureMemory = 0; | 1224 | mTextureMemory = 0; |
1180 | 1225 | ||
1181 | glDeleteTextures(1, (GLuint*)&mTexName); | 1226 | LLImageGL::deleteTextures(1, &mTexName); |
1227 | mTextureState = DELETED ; | ||
1182 | mTexName = 0; | 1228 | mTexName = 0; |
1229 | mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. | ||
1183 | mGLTextureCreated = FALSE ; | 1230 | mGLTextureCreated = FALSE ; |
1184 | stop_glerror(); | 1231 | stop_glerror(); |
1185 | } | 1232 | } |
@@ -1187,89 +1234,35 @@ void LLImageGL::destroyGLTexture() | |||
1187 | 1234 | ||
1188 | //---------------------------------------------------------------------------- | 1235 | //---------------------------------------------------------------------------- |
1189 | 1236 | ||
1190 | void LLImageGL::glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr) | 1237 | void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode) |
1191 | { | 1238 | { |
1192 | glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); | 1239 | if (mAddressMode != mode) |
1193 | glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); | ||
1194 | glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); | ||
1195 | } | ||
1196 | |||
1197 | void LLImageGL::glClamp (BOOL clamps, BOOL clampt) | ||
1198 | { | ||
1199 | if (mTexName != 0) | ||
1200 | { | 1240 | { |
1201 | glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); | 1241 | mTexOptionsDirty = true; |
1202 | glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); | 1242 | mAddressMode = mode; |
1203 | } | 1243 | } |
1204 | } | ||
1205 | |||
1206 | void LLImageGL::setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr) | ||
1207 | { | ||
1208 | mClampS = clamps; | ||
1209 | mClampT = clampt; | ||
1210 | mClampR = clampr; | ||
1211 | glClampCubemap (clamps, clampt, clampr); | ||
1212 | } | ||
1213 | 1244 | ||
1214 | void LLImageGL::setClamp(BOOL clamps, BOOL clampt) | 1245 | if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) |
1215 | { | 1246 | { |
1216 | mClampS = clamps; | 1247 | gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode); |
1217 | mClampT = clampt; | 1248 | mTexOptionsDirty = false; |
1218 | glClamp (clamps, clampt); | 1249 | } |
1219 | } | ||
1220 | |||
1221 | void LLImageGL::overrideClamp (BOOL clamps, BOOL clampt) | ||
1222 | { | ||
1223 | glClamp (clamps, clampt); | ||
1224 | } | ||
1225 | |||
1226 | void LLImageGL::restoreClamp (void) | ||
1227 | { | ||
1228 | glClamp (mClampS, mClampT); | ||
1229 | } | 1250 | } |
1230 | 1251 | ||
1231 | void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest) | 1252 | void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option) |
1232 | { | 1253 | { |
1233 | mMagFilterNearest = mag_nearest; | 1254 | if (mFilterOption != option) |
1234 | mMinFilterNearest = min_nearest; | 1255 | { |
1256 | mTexOptionsDirty = true; | ||
1257 | mFilterOption = option; | ||
1258 | } | ||
1235 | 1259 | ||
1236 | if (mTexName != 0) | 1260 | if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) |
1237 | { | 1261 | { |
1238 | if (mMinFilterNearest) | 1262 | gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option); |
1239 | { | 1263 | mTexOptionsDirty = false; |
1240 | glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 1264 | } |
1241 | } | 1265 | stop_glerror(); |
1242 | else if (mHasMipMaps) | ||
1243 | { | ||
1244 | glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); | ||
1245 | } | ||
1246 | else | ||
1247 | { | ||
1248 | glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
1249 | } | ||
1250 | if (mMagFilterNearest) | ||
1251 | { | ||
1252 | glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
1253 | } | ||
1254 | else | ||
1255 | { | ||
1256 | glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
1257 | } | ||
1258 | if (gGLManager.mHasAnisotropic) | ||
1259 | { | ||
1260 | if (sGlobalUseAnisotropic && !mMagFilterNearest) | ||
1261 | { | ||
1262 | F32 largest_anisotropy; | ||
1263 | glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy); | ||
1264 | glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy); | ||
1265 | } | ||
1266 | else | ||
1267 | { | ||
1268 | glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); | ||
1269 | } | ||
1270 | } | ||
1271 | stop_glerror(); | ||
1272 | } | ||
1273 | } | 1266 | } |
1274 | 1267 | ||
1275 | BOOL LLImageGL::getIsResident(BOOL test_now) | 1268 | BOOL LLImageGL::getIsResident(BOOL test_now) |
@@ -1356,6 +1349,118 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b | |||
1356 | mBindTarget = bind_target; | 1349 | mBindTarget = bind_target; |
1357 | } | 1350 | } |
1358 | 1351 | ||
1352 | void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) | ||
1353 | { | ||
1354 | if (mFormatType != GL_UNSIGNED_BYTE) | ||
1355 | { | ||
1356 | llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; | ||
1357 | } | ||
1358 | |||
1359 | U32 stride = 0; | ||
1360 | switch (mFormatPrimary) | ||
1361 | { | ||
1362 | case GL_LUMINANCE: | ||
1363 | case GL_ALPHA: | ||
1364 | stride = 1; | ||
1365 | break; | ||
1366 | case GL_LUMINANCE_ALPHA: | ||
1367 | stride = 2; | ||
1368 | break; | ||
1369 | case GL_RGB: | ||
1370 | //no alpha | ||
1371 | mIsMask = FALSE; | ||
1372 | return; | ||
1373 | case GL_RGBA: | ||
1374 | stride = 4; | ||
1375 | break; | ||
1376 | case GL_BGRA_EXT: | ||
1377 | stride = 4; | ||
1378 | break; | ||
1379 | default: | ||
1380 | llwarns << "Cannot analyze alpha of image with primary format " << std::hex << mFormatPrimary << std::dec << llendl; | ||
1381 | return; | ||
1382 | } | ||
1383 | |||
1384 | U32 length = w * h; | ||
1385 | const GLubyte* current = ((const GLubyte*) data_in)+stride-1; | ||
1386 | |||
1387 | S32 sample[16]; | ||
1388 | memset(sample, 0, sizeof(S32)*16); | ||
1389 | |||
1390 | for (U32 i = 0; i < length; i++) | ||
1391 | { | ||
1392 | ++sample[*current/16]; | ||
1393 | current += stride; | ||
1394 | } | ||
1395 | |||
1396 | U32 total = 0; | ||
1397 | for (U32 i = 4; i < 11; i++) | ||
1398 | { | ||
1399 | total += sample[i]; | ||
1400 | } | ||
1401 | |||
1402 | if (total > length/16) | ||
1403 | { | ||
1404 | mIsMask = FALSE; | ||
1405 | } | ||
1406 | else | ||
1407 | { | ||
1408 | mIsMask = TRUE; | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1412 | BOOL LLImageGL::isDeleted() | ||
1413 | { | ||
1414 | return mTextureState == DELETED ; | ||
1415 | } | ||
1416 | |||
1417 | BOOL LLImageGL::isInactive() | ||
1418 | { | ||
1419 | return mTextureState == INACTIVE ; | ||
1420 | } | ||
1421 | |||
1422 | BOOL LLImageGL::isDeletionCandidate() | ||
1423 | { | ||
1424 | return mTextureState == DELETION_CANDIDATE ; | ||
1425 | } | ||
1426 | |||
1427 | void LLImageGL::setDeletionCandidate() | ||
1428 | { | ||
1429 | if(mTexName && (mTextureState == INACTIVE)) | ||
1430 | { | ||
1431 | mTextureState = DELETION_CANDIDATE ; | ||
1432 | } | ||
1433 | } | ||
1434 | |||
1435 | void LLImageGL::forceActive() | ||
1436 | { | ||
1437 | mTextureState = ACTIVE ; | ||
1438 | } | ||
1439 | |||
1440 | void LLImageGL::setActive() | ||
1441 | { | ||
1442 | if(mTextureState != NO_DELETE) | ||
1443 | { | ||
1444 | mTextureState = ACTIVE ; | ||
1445 | } | ||
1446 | } | ||
1447 | |||
1448 | //set the texture inactive | ||
1449 | void LLImageGL::setInactive() | ||
1450 | { | ||
1451 | if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently()) | ||
1452 | { | ||
1453 | mTextureState = INACTIVE ; | ||
1454 | } | ||
1455 | } | ||
1456 | |||
1457 | //set the texture to stay in memory | ||
1458 | void LLImageGL::setNoDelete() | ||
1459 | { | ||
1460 | mTextureState = NO_DELETE ; | ||
1461 | } | ||
1462 | |||
1463 | //---------------------------------------------------------------------------- | ||
1359 | void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) | 1464 | void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) |
1360 | { | 1465 | { |
1361 | if (mFormatType != GL_UNSIGNED_BYTE || | 1466 | if (mFormatType != GL_UNSIGNED_BYTE || |
@@ -1468,7 +1573,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) | |||
1468 | llassert(w > 0 && h > 0 && cur_mip_data); | 1573 | llassert(w > 0 && h > 0 && cur_mip_data); |
1469 | U8 test = cur_mip_data[w*h*mComponents-1]; | 1574 | U8 test = cur_mip_data[w*h*mComponents-1]; |
1470 | { | 1575 | { |
1471 | glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); | 1576 | LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data); |
1472 | stop_glerror(); | 1577 | stop_glerror(); |
1473 | } | 1578 | } |
1474 | if (prev_mip_data && prev_mip_data != rawdata) | 1579 | if (prev_mip_data && prev_mip_data != rawdata) |