From 6fcf38217e8772b2f90c7a8e7ce6b60071f6d20c Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Tue, 25 Mar 2008 22:50:26 +0000 Subject: merge release@82858 maint-render-2-merge@83010 -> release QAR-389 --- indra/llcommon/llfile.cpp | 8 +- indra/llcommon/llfile.h | 6 +- indra/llimagej2coj/llimagej2coj.cpp | 12 + indra/llrender/llfontgl.cpp | 6 + indra/llrender/llfontgl.h | 5 +- indra/llrender/llrendertarget.cpp | 64 ++- indra/llrender/llrendertarget.h | 27 +- indra/llwindow/llwindow.cpp | 9 +- indra/llwindow/llwindow.h | 5 +- indra/llwindow/llwindowheadless.h | 2 + indra/llwindow/llwindowmacosx.cpp | 26 +- indra/llwindow/llwindowmacosx.h | 11 +- indra/llwindow/llwindowmesaheadless.h | 2 + indra/llwindow/llwindowsdl.cpp | 40 +- indra/llwindow/llwindowsdl.h | 5 +- indra/llwindow/llwindowwin32.cpp | 456 ++++----------------- indra/llwindow/llwindowwin32.h | 5 +- indra/newview/app_settings/settings.xml | 57 ++- .../shaders/class1/deferred/diffuseF.glsl | 16 + .../shaders/class1/deferred/diffuseV.glsl | 22 + .../shaders/class1/environment/waterF.glsl | 2 +- .../shaders/class1/environment/waterFogF.glsl | 4 +- .../shaders/class1/environment/waterV.glsl | 5 +- .../shaders/class1/lighting/lightF.glsl | 2 +- .../shaders/class1/lighting/lightShinyF.glsl | 2 +- .../shaders/class1/lighting/lightShinyWaterF.glsl | 2 +- indra/newview/featuretable.txt | 1 + indra/newview/featuretable_linux.txt | 1 + indra/newview/featuretable_mac.txt | 59 +-- indra/newview/featuretable_solaris.txt | 1 + indra/newview/linux_tools/wrapper.sh | 3 +- indra/newview/llappviewer.cpp | 21 - indra/newview/lldrawpoolwater.cpp | 3 + indra/newview/lldrawpoolwater.h | 1 + indra/newview/llfasttimerview.cpp | 8 +- indra/newview/llfloaterhardwaresettings.cpp | 23 +- indra/newview/llfloaterhardwaresettings.h | 1 + indra/newview/llfloatersnapshot.cpp | 417 ++++++++++++++----- indra/newview/llfloatersnapshot.h | 10 +- indra/newview/llhudtext.cpp | 3 +- indra/newview/llhudtext.h | 2 + indra/newview/lloverlaybar.cpp | 2 + indra/newview/llselectmgr.cpp | 30 ++ indra/newview/llselectmgr.h | 1 + indra/newview/lltexturefetch.cpp | 12 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewerdisplay.cpp | 37 +- indra/newview/llviewermenu.cpp | 3 + indra/newview/llviewerpartsource.cpp | 7 +- indra/newview/llviewerwindow.cpp | 202 +++++++-- indra/newview/llviewerwindow.h | 1 + indra/newview/llvoavatar.cpp | 192 ++++++++- indra/newview/llvoavatar.h | 7 +- indra/newview/pipeline.cpp | 160 +++++--- indra/newview/pipeline.h | 4 + 55 files changed, 1291 insertions(+), 723 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index c44650009d..3c590a0d49 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -266,6 +266,7 @@ void llofstream::open(const char* _Filename, /* Flawfinder: ignore */ } llassert(_Filebuffer==NULL); _Filebuffer = new _Myfb(filep); + _ShouldClose = true; _Myios::init(_Filebuffer); } @@ -281,7 +282,7 @@ void llofstream::close() llofstream::llofstream(const char *_Filename, std::ios_base::openmode _Mode, int _Prot) - : std::basic_ostream >(NULL,true),_Filebuffer(NULL) + : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) { // construct with named file and specified mode open(_Filename, _Mode , _Prot); /* Flawfinder: ignore */ } @@ -289,7 +290,10 @@ llofstream::llofstream(const char *_Filename, llofstream::~llofstream() { // destroy the object - close(); + if (_ShouldClose) + { + close(); + } delete _Filebuffer; } diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 7a1542a6fa..da1ad6a34e 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -127,7 +127,7 @@ public: typedef std::basic_ios > _Myios; llofstream() - : std::basic_ostream >(NULL,true),_Filebuffer(NULL) + : std::basic_ostream >(NULL,true),_Filebuffer(NULL),_ShouldClose(false) { // construct unopened } @@ -138,7 +138,8 @@ public: explicit llofstream(_Filet *_File) : std::basic_ostream >(NULL,true), - _Filebuffer(new _Myfb(_File))//_File) + _Filebuffer(new _Myfb(_File)),//_File) + _ShouldClose(false) { // construct with specified C stream } @@ -157,6 +158,7 @@ public: private: _Myfb *_Filebuffer; // the file buffer + bool _ShouldClose; }; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index d7be118875..dfc5d4520b 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -158,6 +158,18 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod return TRUE; // done } + // sometimes we get bad data out of the cache - check to see if the decode succeeded + for (S32 i = 0; i < image->numcomps; i++) + { + if (image->comps[i].factor != base.getRawDiscardLevel()) + { + // if we didn't get the discard level we're expecting, fail + opj_image_destroy(image); + base.mDecoding = FALSE; + return TRUE; + } + } + // Copy image data into our raw image format (instead of the separate channel format S32 img_components = image->numcomps; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 2e767ebb9c..df9dca3af5 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -47,6 +47,7 @@ F32 LLFontGL::sVertDPI = 96.f; F32 LLFontGL::sHorizDPI = 96.f; F32 LLFontGL::sScaleX = 1.f; F32 LLFontGL::sScaleY = 1.f; +BOOL LLFontGL::sDisplayFont = TRUE ; LLString LLFontGL::sAppDir; LLFontGL* LLFontGL::sMonospace = NULL; @@ -557,6 +558,11 @@ S32 LLFontGL::render(const LLWString &wstr, BOOL use_embedded, BOOL use_ellipses) const { + if(!sDisplayFont) //do not display texts + { + return wstr.length() ; + } + LLGLEnable tex(GL_TEXTURE_2D); if (wstr.empty()) diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 393d26c685..b5f018e8f7 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -202,6 +202,8 @@ public: static LLString nameFromVAlign(LLFontGL::VAlign align); static LLFontGL::VAlign vAlignFromName(const LLString& name); + static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; } + protected: struct embedded_data_t { @@ -220,6 +222,7 @@ public: static F32 sHorizDPI; static F32 sScaleX; static F32 sScaleY; + static BOOL sDisplayFont ; static LLString sAppDir; // For loading fonts static LLFontGL* sMonospace; // medium @@ -244,7 +247,7 @@ public: protected: /*virtual*/ BOOL addChar(const llwchar wch); static LLString getFontPathLocal(); - static LLString getFontPathSystem(); + static LLString getFontPathSystem(); protected: LLPointer mRawImageGLp; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index c082b93164..593a5a18e5 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -49,8 +49,9 @@ LLRenderTarget::~LLRenderTarget() release(); } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL force_fbo) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL use_fbo) { + stop_glerror(); mResX = resx; mResY = resy; @@ -79,32 +80,44 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 stop_glerror(); - if (sUseFBO || force_fbo) + if (depth) { - if (depth) - { - glGenRenderbuffersEXT(1, (GLuint *) &mDepth); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,mResX,mResY); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - } + stop_glerror(); + allocateDepth(); + stop_glerror(); + } + if ((sUseFBO && use_fbo) && gGLManager.mHasFramebufferObject) + { glGenFramebuffersEXT(1, (GLuint *) &mFBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); if (mDepth) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, mDepth); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0); + stop_glerror(); } + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, mUsage, mTex, 0); - + stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + stop_glerror(); } } +void LLRenderTarget::allocateDepth() +{ + glGenTextures(1, (GLuint *) &mDepth); + glBindTexture(mUsage, mDepth); + glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); +} + void LLRenderTarget::release() { if (mFBO) @@ -121,7 +134,7 @@ void LLRenderTarget::release() if (mDepth) { - glDeleteRenderbuffersEXT(1, (GLuint *) &mDepth); + glDeleteTextures(1, (GLuint *) &mDepth); mDepth = 0; } } @@ -141,7 +154,7 @@ void LLRenderTarget::clear() U32 mask = GL_COLOR_BUFFER_BIT; if (mUseDepth) { - mask |= GL_DEPTH_BUFFER_BIT; + mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; } if (mFBO) { @@ -160,13 +173,34 @@ void LLRenderTarget::bindTexture() glBindTexture(mUsage, mTex); } -void LLRenderTarget::flush() +void LLRenderTarget::bindDepth() +{ + glBindTexture(mUsage, mDepth); +} + + +void LLRenderTarget::flush(BOOL fetch_depth) { gGL.flush(); if (!mFBO) { bindTexture(); glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY); + + if (fetch_depth) + { + if (!mDepth) + { + allocateDepth(); + } + + bindDepth(); + glCopyTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0); + } + } + else + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 0c0eab2b10..7f9c611c69 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -37,7 +37,7 @@ /* SAMPLE USAGE: - LLFBOTarget target; + LLRenderTarget target; ... @@ -46,7 +46,7 @@ //render to contents of offscreen buffer target.bindTarget(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + target.clear(); ... ... target.flush(); @@ -71,7 +71,10 @@ public: //allocate resources for rendering //must be called before use //multiple calls will release previously allocated resources - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL force_fbo = FALSE); + void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = TRUE); + + //allocate a depth texture + void allocateDepth(); //free any allocated resources //safe to call redundantly @@ -80,7 +83,7 @@ public: //bind target for rendering //applies appropriate viewport void bindTarget(); - + //clear render targer, clears depth buffer if present, //uses scissor rect if in copy-to-texture mode void clear(); @@ -88,14 +91,25 @@ public: //get applied viewport void getViewport(S32* viewport); + //get X resolution + U32 getWidth() const { return mResX; } + + //get Y resolution + U32 getHeight() const { return mResY; } + //bind results of render for sampling void bindTexture(); + //bind results of render for sampling depth buffer + void bindDepth(); + //flush rendering operations //must be called when rendering is complete //should be used 1:1 with bindTarget // call bindTarget once, do all your rendering, call flush once - void flush(); + // if fetch_depth is TRUE, every effort will be made to copy the depth buffer into + // the current depth texture. A depth texture will be allocated if needed. + void flush(BOOL fetch_depth = FALSE); //Returns TRUE if target is ready to be rendered into. //That is, if the target has been allocated with at least @@ -108,8 +122,11 @@ private: U32 mTex; U32 mFBO; U32 mDepth; + U32 mStencil; BOOL mUseDepth; + BOOL mRenderDepth; U32 mUsage; + }; #endif diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 43f3081321..37f089e8be 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -440,7 +440,8 @@ LLWindow* LLWindowManager::createWindow( BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth) + BOOL ignore_pixel_depth, + U32 fsaa_samples) { LLWindow* new_window; @@ -453,15 +454,15 @@ LLWindow* LLWindowManager::createWindow( #elif LL_SDL new_window = new LLWindowSDL( title, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32( title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_DARWIN new_window = new LLWindowMacOSX( title, name, x, y, width, height, flags, - fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth); + fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_LINUX new_window = new LLWindowLinux( title, name, x, y, width, height, flags, diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index bc444ae811..b2e9c5b51d 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -184,6 +184,8 @@ public: virtual void flashIcon(F32 seconds) = 0; virtual F32 getGamma() = 0; virtual BOOL setGamma(const F32 gamma) = 0; // Set the gamma + virtual void setFSAASamples(const U32 fsaa_samples) = 0; //set number of FSAA samples + virtual U32 getFSAASamples() = 0; virtual BOOL restoreGamma() = 0; // Restore original gamma table (before updating gamma) virtual ESwapMethod getSwapMethod() { return mSwapMethod; } virtual void gatherInput() = 0; @@ -340,7 +342,8 @@ public: BOOL clearBg = FALSE, BOOL disable_vsync = TRUE, BOOL use_gl = TRUE, - BOOL ignore_pixel_depth = FALSE); + BOOL ignore_pixel_depth = FALSE, + U32 fsaa_samples = 0); static BOOL destroyWindow(LLWindow* window); static BOOL isWindowValid(LLWindow *window); }; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 4962cf7bf7..b7e6644674 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -69,6 +69,8 @@ public: /*virtual*/ void flashIcon(F32 seconds) {}; /*virtual*/ F32 getGamma() {return 1.0f; }; /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma + /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { } + /*virtual*/ U32 getFSAASamples() { return 0; } /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index a1d97429e1..aa4c2c86f7 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -246,7 +246,8 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth) + BOOL ignore_pixel_depth, + U32 fsaa_samples) : LLWindow(fullscreen, flags) { // Voodoo for calling cocoa from carbon (see llwindowmacosx-objc.mm). @@ -277,6 +278,8 @@ LLWindowMacOSX::LLWindowMacOSX(char *title, char *name, S32 x, S32 y, S32 width, mTSMScriptCode = 0; mTSMLangCode = 0; mPreeditor = NULL; + mFSAASamples = fsaa_samples; + mForceRebuild = FALSE; // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state. // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state. @@ -558,6 +561,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits AGL_RGBA, AGL_FULLSCREEN, // AGL_NO_RECOVERY, // MBW -- XXX -- Not sure if we want this attribute + AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0, + AGL_SAMPLES_ARB, mFSAASamples, AGL_DOUBLEBUFFER, AGL_CLOSEST_POLICY, AGL_ACCELERATED, @@ -586,6 +591,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits AGL_DOUBLEBUFFER, AGL_CLOSEST_POLICY, AGL_ACCELERATED, + AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0, + AGL_SAMPLES_ARB, mFSAASamples, AGL_RED_SIZE, 8, AGL_GREEN_SIZE, 8, AGL_BLUE_SIZE, 8, @@ -819,6 +826,9 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } } + //make sure multisample starts off disabled + glDisable(GL_MULTISAMPLE_ARB); + // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return TRUE; } @@ -897,8 +907,9 @@ BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL dis } stop_glerror(); - if(needsRebuild) + if(needsRebuild || mForceRebuild) { + mForceRebuild = FALSE; destroyContext(); result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync); if (result) @@ -1318,6 +1329,17 @@ F32 LLWindowMacOSX::getGamma() return result; } +U32 LLWindowMacOSX::getFSAASamples() +{ + return mFSAASamples; +} + +void LLWindowMacOSX::setFSAASamples(const U32 samples) +{ + mFSAASamples = samples; + mForceRebuild = TRUE; +} + BOOL LLWindowMacOSX::restoreGamma() { CGDisplayRestoreColorSyncSettings(); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 2fdf80ee82..86b88daa3c 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -78,6 +78,8 @@ public: /*virtual*/ void flashIcon(F32 seconds); /*virtual*/ F32 getGamma(); /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma + /*virtual*/ U32 getFSAASamples(); + /*virtual*/ void setFSAASamples(const U32 fsaa_samples); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -119,7 +121,8 @@ protected: LLWindowMacOSX( char *title, char *name, int x, int y, int width, int height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth); + BOOL ignore_pixel_depth, + U32 fsaa_samples); ~LLWindowMacOSX(); void initCursors(); @@ -185,7 +188,9 @@ protected: LLCoordScreen mNeedsResizeSize; F32 mOverrideAspectRatio; BOOL mMinimized; - + U32 mFSAASamples; + BOOL mForceRebuild; + F32 mBounceTime; NMRec mBounceRec; LLTimer mBounceTimer; @@ -196,7 +201,7 @@ protected: ScriptCode mTSMScriptCode; LangCode mTSMLangCode; LLPreeditor* mPreeditor; - + friend class LLWindowManager; }; diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index fe91a2d2a0..8de92bbe0e 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -74,6 +74,8 @@ public: /*virtual*/ F32 getGamma() {return 1.0f; }; /*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma /*virtual*/ BOOL restoreGamma() {return FALSE; }; // Restore original gamma table (before updating gamma) + /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } + /*virtual*/ U32 getFSAASamples() { return 0; } //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput() {}; /*virtual*/ void delayInputProcessing() {}; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 686be3385e..122b57a497 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -81,7 +81,7 @@ static BOOL was_fullscreen = FALSE; void maybe_lock_display(void) { - if (gWindowImplementation) { + if (gWindowImplementation && gWindowImplementation->Lock_Display) { gWindowImplementation->Lock_Display(); } } @@ -89,7 +89,7 @@ void maybe_lock_display(void) void maybe_unlock_display(void) { - if (gWindowImplementation) { + if (gWindowImplementation && gWindowImplementation->Unlock_Display) { gWindowImplementation->Unlock_Display(); } } @@ -217,7 +217,7 @@ LLWindowSDL::LLWindowSDL(char *title, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth) + BOOL ignore_pixel_depth, U32 fsaa_samples) : LLWindow(fullscreen, flags), mGamma(1.0f) { // Initialize the keyboard @@ -236,6 +236,7 @@ LLWindowSDL::LLWindowSDL(char *title, S32 x, S32 y, S32 width, mReallyCapturedCount = 0; mHaveInputFocus = -1; mIsMinimized = -1; + mFSAASamples = fsaa_samples; #if LL_X11 mSDL_XWindowID = None; @@ -260,7 +261,7 @@ LLWindowSDL::LLWindowSDL(char *title, S32 x, S32 y, S32 width, mWindowTitle = new char[strlen(title) + 1]; /* Flawfinder: ignore */ if(mWindowTitle == NULL) { - llerrs << "Memory allocation failure" << llendl; + llwarns << "Memory allocation failure" << llendl; return; } @@ -535,6 +536,12 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (mFSAASamples > 0) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); + } + mSDLFlags = sdlflags; if (mFullscreen) @@ -796,7 +803,6 @@ void LLWindowSDL::destroyContext() gGLManager.shutdownGL(); llinfos << "SDL_QuitSS/VID begins" << llendl; SDL_QuitSubSystem(SDL_INIT_VIDEO); // *FIX: this might be risky... - //unload_all_glsyms(); mWindow = NULL; } @@ -922,10 +928,10 @@ BOOL LLWindowSDL::getSize(LLCoordScreen *size) { size->mX = mWindow->w; size->mY = mWindow->h; - return (TRUE); + return (TRUE); } - llerrs << "LLWindowSDL::getPosition(): no window and not fullscreen!" << llendl; + llwarns << "LLWindowSDL::getPosition(): no window and not fullscreen!" << llendl; return (FALSE); } @@ -935,10 +941,10 @@ BOOL LLWindowSDL::getSize(LLCoordWindow *size) { size->mX = mWindow->w; size->mY = mWindow->h; - return (TRUE); + return (TRUE); } - llerrs << "LLWindowSDL::getPosition(): no window and not fullscreen!" << llendl; + llwarns << "LLWindowSDL::getPosition(): no window and not fullscreen!" << llendl; return (FALSE); } @@ -970,6 +976,16 @@ void LLWindowSDL::swapBuffers() SDL_GL_SwapBuffers(); } +U32 LLWindowSDL::getFSAASamples() +{ + return mFSAASamples; +} + +void LLWindowSDL::setFSAASamples(const U32 samples) +{ + mFSAASamples = samples; +} + F32 LLWindowSDL::getGamma() { return 1/mGamma; @@ -1116,8 +1132,10 @@ F32 LLWindowSDL::getPixelAspectRatio() if (getFullscreen()) { LLCoordScreen screen_size; - getSize(&screen_size); - pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; + if (getSize(&screen_size)) + { + pixel_aspect = getNativeAspectRatio() * (F32)screen_size.mY / (F32)screen_size.mX; + } } return pixel_aspect; diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 2c411e03fd..4d4d36e30a 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -85,6 +85,8 @@ public: /*virtual*/ void flashIcon(F32 seconds); /*virtual*/ F32 getGamma(); /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma + /*virtual*/ U32 getFSAASamples(); + /*virtual*/ void setFSAASamples(const U32 samples); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -132,7 +134,7 @@ protected: LLWindowSDL( char *title, int x, int y, int width, int height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth); + BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowSDL(); void initCursors(); @@ -183,6 +185,7 @@ protected: LLCoordScreen mNeedsResizeSize; F32 mOverrideAspectRatio; F32 mGamma; + U32 mFSAASamples; int mSDLFlags; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index a5367aac8a..bcbd2d9cc3 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -371,10 +371,11 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, S32 height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth) + BOOL ignore_pixel_depth, + U32 fsaa_samples) : LLWindow(fullscreen, flags) { - S32 i = 0; + mFSAASamples = fsaa_samples; mIconResource = gIconResource; mOverrideAspectRatio = 0.f; mNativeAspectRatio = 0.f; @@ -389,7 +390,6 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, // based on the system's (user's) default settings. allowLanguageTextInput(mPreeditor, FALSE); - GLuint pixel_format; WNDCLASS wc; DWORD dw_ex_style; DWORD dw_style; @@ -651,366 +651,13 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, //----------------------------------------------------------------------- // Create GL drawing context //----------------------------------------------------------------------- - PIXELFORMATDESCRIPTOR pfd = + if (!switchContext(mFullscreen, LLCoordScreen(window_rect.right - window_rect.left, // width + window_rect.bottom - window_rect.top), // height + TRUE)) { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - pfdflags, - PFD_TYPE_RGBA, - BITS_PER_PIXEL, - 0, 0, 0, 0, 0, 0, // RGB bits and shift, unused - 8, // alpha bits - 0, // alpha shift - 0, // accum bits - 0, 0, 0, 0, // accum RGBA - 24, // depth bits - 8, // stencil bits, avi added for stencil test - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - if (!(mhDC = GetDC(mWindowHandle))) - { - close(); - OSMessageBox("Can't make GL device context", "Error", OSMB_OK); - return; - } - - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) - { - close(); - OSMessageBox("Can't find suitable pixel format", "Error", OSMB_OK); - return; - } - - // Verify what pixel format we actually received. - if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - close(); - OSMessageBox("Can't get pixel format description", "Error", OSMB_OK); return; } - - // sanity check pfd returned by Windows - if (!ignore_pixel_depth && (pfd.cColorBits < 32)) - { - close(); - OSMessageBox( - "Second Life requires True Color (32-bit) to run in a window.\n" - "Please go to Control Panels -> Display -> Settings and\n" - "set the screen to 32-bit color.\n" - "Alternately, if you choose to run fullscreen, Second Life\n" - "will automatically adjust the screen each time it runs.", - "Error", - OSMB_OK); - return; - } - - if (!ignore_pixel_depth && (pfd.cAlphaBits < 8)) - { - close(); - OSMessageBox( - "Second Life is unable to run because it can't get an 8 bit alpha\n" - "channel. Usually this is due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "Also be sure your monitor is set to True Color (32-bit) in\n" - "Control Panels -> Display -> Settings.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return; - } - - if (!SetPixelFormat(mhDC, pixel_format, &pfd)) - { - close(); - OSMessageBox("Can't set pixel format", "Error", OSMB_OK); - return; - } - - if (use_gl) - { - if (!(mhRC = wglCreateContext(mhDC))) - { - close(); - OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK); - return; - } - - if (!wglMakeCurrent(mhDC, mhRC)) - { - close(); - OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK); - return; - } - - gGLManager.initWGL(); - - if (gGLManager.mHasWGLARBPixelFormat && (wglChoosePixelFormatARB != NULL)) - { - // OK, at this point, use the ARB wglChoosePixelFormatsARB function to see if we - // can get exactly what we want. - GLint attrib_list[256]; - S32 cur_attrib = 0; - - attrib_list[cur_attrib++] = WGL_DEPTH_BITS_ARB; - attrib_list[cur_attrib++] = 24; - - attrib_list[cur_attrib++] = WGL_STENCIL_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_DRAW_TO_WINDOW_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_ACCELERATION_ARB; - attrib_list[cur_attrib++] = WGL_FULL_ACCELERATION_ARB; - - attrib_list[cur_attrib++] = WGL_SUPPORT_OPENGL_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_DOUBLE_BUFFER_ARB; - attrib_list[cur_attrib++] = GL_TRUE; - - attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; - attrib_list[cur_attrib++] = 32; - - attrib_list[cur_attrib++] = WGL_RED_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - // End the list - attrib_list[cur_attrib++] = 0; - - GLint pixel_formats[256]; - U32 num_formats = 0; - - // First we try and get a 32 bit depth pixel format - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit"); - return; - } - - if (!num_formats) - { - llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl; - // Try 24-bit format - attrib_list[1] = 24; - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); - return; - } - - if (!num_formats) - { - llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl; - attrib_list[1] = 16; - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result || !num_formats) - { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); - return; - } - } - - llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl; - - pixel_format = pixel_formats[0]; - } - - DestroyWindow(mWindowHandle); - - mWindowHandle = CreateWindowEx(dw_ex_style, - mWindowClassName, - mWindowTitle, - WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dw_style, - x, // x pos - y, // y pos - window_rect.right - window_rect.left, // width - window_rect.bottom - window_rect.top, // height - NULL, - NULL, - mhInstance, - NULL); - - if (!(mhDC = GetDC(mWindowHandle))) - { - close(); - OSMessageBox("Can't make GL device context", "Error", OSMB_OK); - return; - } - - if (!SetPixelFormat(mhDC, pixel_format, &pfd)) - { - close(); - OSMessageBox("Can't set pixel format", "Error", OSMB_OK); - return; - } - - int swap_method = 0; - GLint swap_query = WGL_SWAP_METHOD_ARB; - - if (wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method)) - { - switch (swap_method) - { - case WGL_SWAP_EXCHANGE_ARB: - mSwapMethod = SWAP_METHOD_EXCHANGE; - llinfos << "Swap Method: Exchange" << llendl; - break; - case WGL_SWAP_COPY_ARB: - mSwapMethod = SWAP_METHOD_COPY; - llinfos << "Swap Method: Copy" << llendl; - break; - case WGL_SWAP_UNDEFINED_ARB: - mSwapMethod = SWAP_METHOD_UNDEFINED; - llinfos << "Swap Method: Undefined" << llendl; - break; - default: - mSwapMethod = SWAP_METHOD_UNDEFINED; - llinfos << "Swap Method: Unknown" << llendl; - break; - } - } - } - else - { - llwarns << "No wgl_ARB_pixel_format extension, using default ChoosePixelFormat!" << llendl; - } - - // Verify what pixel format we actually received. - if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - close(); - OSMessageBox("Can't get pixel format description", "Error", OSMB_OK); - return; - } - llinfos << "GL buffer: Color Bits " << S32(pfd.cColorBits) - << " Alpha Bits " << S32(pfd.cAlphaBits) - << " Depth Bits " << S32(pfd.cDepthBits) - << llendl; - - if (pfd.cColorBits < 32) - { - close(); - OSMessageBox( - "Second Life requires True Color (32-bit) to run in a window.\n" - "Please go to Control Panels -> Display -> Settings and\n" - "set the screen to 32-bit color.\n" - "Alternately, if you choose to run fullscreen, Second Life\n" - "will automatically adjust the screen each time it runs.", - "Error", - OSMB_OK); - return; - } - - if (pfd.cAlphaBits < 8) - { - close(); - OSMessageBox( - "Second Life is unable to run because it can't get an 8 bit alpha\n" - "channel. Usually this is due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "Also be sure your monitor is set to True Color (32-bit) in\n" - "Control Panels -> Display -> Settings.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return; - } - - if (!(mhRC = wglCreateContext(mhDC))) - { - close(); - OSMessageBox("Can't create GL rendering context", "Error", OSMB_OK); - return; - } - - if (!wglMakeCurrent(mhDC, mhRC)) - { - close(); - OSMessageBox("Can't activate GL rendering context", "Error", OSMB_OK); - return; - } - - if (!gGLManager.initGL()) - { - close(); - OSMessageBox( - "Second Life is unable to run because your video card drivers\n" - "are out of date or unsupported. Please make sure you have\n" - "the latest video card drivers installed.\n\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return; - } - - // Disable vertical sync for swap - if (disable_vsync && wglSwapIntervalEXT) - { - llinfos << "Disabling vertical sync" << llendl; - wglSwapIntervalEXT(0); - } - else - { - llinfos << "Keeping vertical sync" << llendl; - } - - - // OK, let's get the current gamma information and store it off. - mCurrentGamma = 0.f; // Not set, default; - if (!GetDeviceGammaRamp(mhDC, mPrevGammaRamp)) - { - llwarns << "Unable to get device gamma ramp" << llendl; - } - - // Calculate what the current gamma is. From a posting by Garrett T. Bass, Get/SetDeviceGammaRamp Demystified - // http://apollo.iwt.uni-bielefeld.de/~ml_robot/OpenGL-04-2000/0058.html - - // We're going to assume that gamma's the same for all 3 channels, because I don't feel like doing it otherwise. - // Using the red channel. - - F32 Csum = 0.0; - S32 Ccount = 0; - for (i = 0; i < 256; i++) - { - if (i != 0 && mPrevGammaRamp[i] != 0 && mPrevGammaRamp[i] != 65536) - { - F64 B = (i % 256) / 256.0; - F64 A = mPrevGammaRamp[i] / 65536.0; - F32 C = (F32) ( log(A) / log(B) ); - Csum += C; - Ccount++; - } - } - mCurrentGamma = Csum / Ccount; - - llinfos << "Previous gamma: " << mCurrentGamma << llendl; - } - - - //store this pointer for wndProc callback - SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this); - + //start with arrow cursor initCursors(); setCursor( UI_CURSOR_ARROW ); @@ -1018,8 +665,6 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, // Initialize (boot strap) the Language text input management, // based on the system's (or user's) default settings. allowLanguageTextInput(NULL, FALSE); - - initInputDevices(); } void LLWindowWin32::initInputDevices() @@ -1558,17 +1203,19 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; attrib_list[cur_attrib++] = 24; - attrib_list[cur_attrib++] = WGL_RED_BITS_ARB; - attrib_list[cur_attrib++] = 8; - - attrib_list[cur_attrib++] = WGL_GREEN_BITS_ARB; + attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; attrib_list[cur_attrib++] = 8; - attrib_list[cur_attrib++] = WGL_BLUE_BITS_ARB; - attrib_list[cur_attrib++] = 8; + U32 end_attrib = 0; + if (mFSAASamples > 0) + { + end_attrib = cur_attrib; + attrib_list[cur_attrib++] = WGL_SAMPLE_BUFFERS_ARB; + attrib_list[cur_attrib++] = GL_TRUE; - attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; - attrib_list[cur_attrib++] = 8; + attrib_list[cur_attrib++] = WGL_SAMPLES_ARB; + attrib_list[cur_attrib++] = mFSAASamples; + } // End the list attrib_list[cur_attrib++] = 0; @@ -1587,36 +1234,67 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa if (!num_formats) { - llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl; - // Try 24-bit format - attrib_list[1] = 24; - BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result) + if (end_attrib > 0) { - close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); - return FALSE; + llinfos << "No valid pixel format for " << mFSAASamples << "x anti-aliasing." << llendl; + attrib_list[end_attrib] = 0; + + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + if (!result) + { + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 32-bit no AA"); + return FALSE; + } } if (!num_formats) { - llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl; - attrib_list[1] = 16; + llinfos << "No 32 bit z-buffer, trying 24 bits instead" << llendl; + // Try 24-bit format + attrib_list[1] = 24; BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); - if (!result || !num_formats) + if (!result) { close(); - show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); + show_window_creation_error("Error after wglChoosePixelFormatARB 24-bit"); return FALSE; } + + if (!num_formats) + { + llwarns << "Couldn't get 24 bit z-buffer,trying 16 bits instead!" << llendl; + attrib_list[1] = 16; + BOOL result = wglChoosePixelFormatARB(mhDC, attrib_list, NULL, 256, pixel_formats, &num_formats); + if (!result || !num_formats) + { + close(); + show_window_creation_error("Error after wglChoosePixelFormatARB 16-bit"); + return FALSE; + } + } } llinfos << "Choosing pixel formats: " << num_formats << " pixel formats returned" << llendl; + } + + pixel_format = pixel_formats[0]; + + if (mhDC != 0) // Does The Window Have A Device Context? + { + wglMakeCurrent(mhDC, 0); // Set The Current Active Rendering Context To Zero + if (mhRC != 0) // Does The Window Have A Rendering Context? + { + wglDeleteContext (mhRC); // Release The Rendering Context + mhRC = 0; // Zero The Rendering Context - pixel_format = pixel_formats[0]; + } + ReleaseDC (mWindowHandle, mhDC); // Release The Device Context + mhDC = 0; // Zero The Device Context } + DestroyWindow (mWindowHandle); // Destroy The Window + - DestroyWindow(mWindowHandle); mWindowHandle = CreateWindowEx(dw_ex_style, mWindowClassName, mWindowTitle, @@ -2985,6 +2663,16 @@ BOOL LLWindowWin32::setGamma(const F32 gamma) return SetDeviceGammaRamp ( mhDC, mCurrentGammaRamp ); } +void LLWindowWin32::setFSAASamples(const U32 fsaa_samples) +{ + mFSAASamples = fsaa_samples; +} + +U32 LLWindowWin32::getFSAASamples() +{ + return mFSAASamples; +} + LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions) { if (!mSupportedResolutions) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index b21df8981e..e8eed55aee 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -78,6 +78,8 @@ public: /*virtual*/ void flashIcon(F32 seconds); /*virtual*/ F32 getGamma(); /*virtual*/ BOOL setGamma(const F32 gamma); // Set the gamma + /*virtual*/ void setFSAASamples(const U32 fsaa_samples); + /*virtual*/ U32 getFSAASamples(); /*virtual*/ BOOL restoreGamma(); // Restore original gamma table (before updating gamma) /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } /*virtual*/ void gatherInput(); @@ -118,7 +120,7 @@ protected: LLWindowWin32( char *title, char *name, int x, int y, int width, int height, U32 flags, BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl, - BOOL ignore_pixel_depth); + BOOL ignore_pixel_depth, U32 fsaa_samples); ~LLWindowWin32(); void initCursors(); @@ -184,6 +186,7 @@ protected: static BOOL sIsClassRegistered; // has the window class been registered? F32 mCurrentGamma; + U32 mFSAASamples; WORD mPrevGammaRamp[256*3]; WORD mCurrentGammaRamp[256*3]; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9cc61b4827..16b278c01c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5632,7 +5632,7 @@ Type Boolean Value - 0 + 1 RenderUseFarClip @@ -9600,5 +9600,60 @@ Value 1 + RenderDeferred + + Comment + Use deferred rendering pipeline. + Persist + 1 + Type + Boolean + Value + 0 + + RenderFSAASamples + + Comment + Number of samples to use for FSAA (0 = no AA). + Persist + 1 + Type + U32 + Value + 0 + + RenderTextureMemoryMultiple + + Comment + Multiple of texture memory value to use (should fit: 0 < value <= 1.0) + Persist + 1 + Type + F32 + Value + 1.0 + + Disregard128DefaultDrawDistance + + Comment + Whether to use the auto default to 128 draw distance + Persist + 1 + Type + Boolean + Value + 1 + + Disregard96DefaultDrawDistance + + Comment + Whether to use the auto default to 96 draw distance + Persist + 1 + Type + Boolean + Value + 1 + diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl new file mode 100644 index 0000000000..14e6361f83 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -0,0 +1,16 @@ +/** + * @file diffuseF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + gl_FragColor = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragColor.rgb = vary_normal*0.5+0.5; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl new file mode 100644 index 0000000000..8e9069368a --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -0,0 +1,22 @@ +/** + * @file diffuseV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_normal; +varying vec3 vary_position; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vary_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + + vary_normal = normalize(gl_NormalMatrix * gl_Normal); + + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 1c14381df9..7b9e4ff828 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -86,7 +86,7 @@ void main() color.rgb = mix(mix(fogCol.rgb, fb.rgb, fogCol.a), refcol.rgb, df); color.rgb += spec * specular; - color.rgb = atmosTransport(color.rgb); + color.rgb = applyWaterFog(color);//atmosTransport(color.rgb); color.rgb = scaleSoftClip(color.rgb); color.a = spec * sunAngle2; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 59e44fa871..7ee41998e2 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -8,11 +8,11 @@ vec4 applyWaterFog(vec4 color) { // GL_EXP2 Fog - float fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord); + //float fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord); // GL_EXP Fog // float fog = exp(-gl_Fog.density * gl_FogFragCoord); // GL_LINEAR Fog - // float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; + float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; fog = clamp(fog, 0.0, 1.0); color.rgb = mix(gl_Fog.color.rgb, color.rgb, fog); return color; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index d332798103..48ac87ef07 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -63,9 +63,8 @@ void main() //pass wave parameters to pixel shader vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; //get two normal map (detail map) texture coordinates - littleWave.xy = (v.xy) * vec2(0.6, 1.2) + d2 * time * 0.05; - // littleWave.zw = (v.xy) * vec2(0.07, 0.15) - d1 * time * 0.043; - littleWave.zw = (v.xy) * vec2(0.3, 0.6) + d1 * time * 0.1; + littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13; + littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; view.w = bigWave.y; refCoord.w = bigWave.x; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index 9ab986be6d..071489bca8 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -9,7 +9,7 @@ uniform sampler2D diffuseMap; void default_lighting() { - color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragColor = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index c6f7f8b81b..89785c45cb 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -11,7 +11,7 @@ uniform samplerCube environmentMap; void shiny_lighting() { - color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragColor = color; } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index 75f61ccdf1..7ac3c359bf 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -11,7 +11,7 @@ uniform samplerCube environmentMap; void shiny_lighting_water() { - color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragColor = color; } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 898751d3f1..2fcec67c0e 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -51,6 +51,7 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 +RenderTextureMemoryMultiple 1 1.0 // // Low Graphics Settings diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index d7921ffb59..40aa05d0c6 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -51,6 +51,7 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 +RenderTextureMemoryMultiple 1 1.0 // // Low Graphics Settings diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 9645ff8abf..c17ca7fcad 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -23,33 +23,36 @@ version 15 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 0 -RenderAvatarCloth 0 0 -RenderAvatarLODFactor 1 1.0 -RenderAvatarVP 1 0 -RenderCubeMap 1 1 -RenderFarClip 1 256 -RenderFlexTimeFactor 1 1.0 -RenderFogRatio 1 4.0 -RenderGamma 1 0 -RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 -RenderMaxPartCount 1 8192 -RenderNightBrightness 1 1.0 -RenderObjectBump 1 1 -RenderReflectionDetail 1 3 -RenderTerrainDetail 1 1 -RenderTerrainLODFactor 1 2.0 -RenderTreeLODFactor 1 1.0 -RenderUseImpostors 1 1 -RenderVBOEnable 1 1 -RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 -UseOcclusion 1 1 -VertexShaderEnable 1 1 -WindLightUseAtmosShaders 1 1 -WLSkyDetail 1 128 -RenderUseCleverUI 1 1 +RenderAnisotropic 1 0 +RenderAvatarCloth 0 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 0 +RenderCubeMap 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderFogRatio 1 4.0 +RenderGamma 1 0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderNightBrightness 1 1.0 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVBOEnable 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +UseOcclusion 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 +RenderUseCleverUI 1 1 +Disregard128DefaultDrawDistance 1 1 +Disregard96DefaultDrawDistance 1 1 +RenderTextureMemoryMultiple 1 0.5 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 @@ -337,6 +340,8 @@ VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_8600 +RenderTextureMemoryMultiple 1 0.375 /// tweaked ATI to 96 Draw distance diff --git a/indra/newview/featuretable_solaris.txt b/indra/newview/featuretable_solaris.txt index 7dd7c22cdf..2a514eaab1 100644 --- a/indra/newview/featuretable_solaris.txt +++ b/indra/newview/featuretable_solaris.txt @@ -34,6 +34,7 @@ RenderParticleCount 1 4096 RenderRippleWater 1 1 RenderTerrainDetail 1 2 VertexShaderEnable 1 1 +RenderTextureMemoryMultiple 1 1.0 // // Class 0 Hardware (Unknown or just old) diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 070d45a5bb..1b7d6b809e 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -17,8 +17,7 @@ ## on some hardware. Disabling this option may cause BETTER PERFORMANCE but ## may also cause CRASHES and hangs on some unstable combinations of drivers ## and hardware. -## NOTE: This is 'off' for WindLight to help testing. Hopefully it's not -## really needed any more anyway. +## NOTE: This is now disabled by default. #export LL_GL_BASICEXT=x ## - Avoids *all* optional OpenGL extensions. This is the safest and least- diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0e2d28400d..0a611c9bfa 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3169,27 +3169,6 @@ void LLAppViewer::idle() } stop_glerror(); - ////////////////////////////////////// - // - // Update images, using the image stats generated during object update/culling - // - // Can put objects onto the retextured list. - // - gFrameStats.start(LLFrameStats::IMAGE_UPDATE); - - { - LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); - - LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(), - gCamera->getAngularVelocityStat()->getMean()); - - gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. - - const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) - gImageList.updateImages(max_image_decode_time); - stop_glerror(); - } - ////////////////////////////////////// // // Sort and cull in the new renderer are moved to pipeline.cpp diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index ca2f5ebb86..4dfe725731 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -59,6 +59,7 @@ static float sTime; BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; +BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); LLVector3 LLDrawPoolWater::sLightDir; @@ -546,6 +547,7 @@ void LLDrawPoolWater::shade() if (water->getUseTexture()) { + sNeedsDistortionUpdate = TRUE; face->renderIndexed(); } else @@ -557,6 +559,7 @@ void LLDrawPoolWater::shade() } else { + sNeedsDistortionUpdate = TRUE; face->renderIndexed(); } } diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index d9b91db85c..a1b09a5e49 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -50,6 +50,7 @@ protected: public: static BOOL sSkipScreenCopy; static BOOL sNeedsReflectionUpdate; + static BOOL sNeedsDistortionUpdate; static LLVector3 sLightDir; static LLColor4 sWaterFogColor; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index c1194fa99e..f0ac46b7d6 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -113,10 +113,6 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_PIPELINE, " Pipeline", &LLColor4::magenta4, 0 }, { LLFastTimer::FTM_CLEANUP, " Cleanup", &LLColor4::cyan3, 0 }, { LLFastTimer::FTM_AUDIO_UPDATE, " Audio Update", &LLColor4::yellow3, 0 }, - { LLFastTimer::FTM_IMAGE_UPDATE, " Image Update", &LLColor4::yellow4, 1 }, - { LLFastTimer::FTM_IMAGE_CREATE, " Image CreateGL",&LLColor4::yellow5, 0 }, - { LLFastTimer::FTM_IMAGE_DECODE, " Image Decode", &LLColor4::yellow6, 0 }, - { LLFastTimer::FTM_IMAGE_MARK_DIRTY, " Dirty Textures",&LLColor4::red1, 0 }, { LLFastTimer::FTM_VFILE_WAIT, " VFile Wait", &LLColor4::cyan6, 0 }, // { LLFastTimer::FTM_IDLE_CB, " Callbacks", &LLColor4::pink1, 0 }, { LLFastTimer::FTM_RENDER, " Render", &green0, 1 }, @@ -146,6 +142,10 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 }, { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 }, { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 }, + { LLFastTimer::FTM_IMAGE_UPDATE, " Image Update", &LLColor4::yellow4, 1 }, + { LLFastTimer::FTM_IMAGE_CREATE, " Image CreateGL",&LLColor4::yellow5, 0 }, + { LLFastTimer::FTM_IMAGE_DECODE, " Image Decode", &LLColor4::yellow6, 0 }, + { LLFastTimer::FTM_IMAGE_MARK_DIRTY, " Dirty Textures",&LLColor4::red1, 0 }, { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 }, { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 }, { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 }, diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 00dcf67453..a3c3acd3bb 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -77,11 +77,13 @@ void LLFloaterHardwareSettings::refresh() mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic"); + mFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); mGamma = gSavedSettings.getF32("RenderGamma"); mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); + childSetValue("fsaa", (LLSD::Integer) mFSAASamples); refreshEnabledState(); } @@ -175,9 +177,25 @@ void LLFloaterHardwareSettings::apply() // Anisotropic rendering BOOL old_anisotropic = LLImageGL::sGlobalUseAnisotropic; LLImageGL::sGlobalUseAnisotropic = childGetValue("ani"); - if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic) + + U32 fsaa = (U32) childGetValue("fsaa").asInteger(); + U32 old_fsaa = gSavedSettings.getU32("RenderFSAASamples"); + + BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); + + if (old_fsaa != fsaa) + { + gSavedSettings.setU32("RenderFSAASamples", fsaa); + LLWindow* window = gViewerWindow->getWindow(); + LLCoordScreen size; + window->getSize(&size); + gViewerWindow->changeDisplaySettings(window->getFullscreen(), + size, + gSavedSettings.getBOOL("DisableVerticalSync"), + logged_in); + } + else if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic) { - BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); gViewerWindow->restartDisplay(logged_in); } @@ -189,6 +207,7 @@ void LLFloaterHardwareSettings::cancel() { gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); + gSavedSettings.setU32("RenderFSAASamples", mFSAASamples); gSavedSettings.setF32("RenderGamma", mGamma); gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h index 0f5f2fee05..2012a0aa2f 100644 --- a/indra/newview/llfloaterhardwaresettings.h +++ b/indra/newview/llfloaterhardwaresettings.h @@ -88,6 +88,7 @@ protected: BOOL mUseVBO; BOOL mUseAniso; + U32 mFSAASamples; F32 mGamma; S32 mVideoCardMem; F32 mFogRatio; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index d9694a7b3f..1af6683218 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -75,10 +75,14 @@ ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- +S32 LLFloaterSnapshot::sUIWinHeightLong = 526 ; +S32 LLFloaterSnapshot::sUIWinHeightShort = LLFloaterSnapshot::sUIWinHeightLong - 230 ; +S32 LLFloaterSnapshot::sUIWinWidth = 215 ; LLSnapshotFloaterView* gSnapshotFloaterView = NULL; LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL; + const F32 SNAPSHOT_TIME_DELAY = 1.f; F32 SHINE_TIME = 0.5f; @@ -88,7 +92,7 @@ F32 FALL_TIME = 0.6f; S32 BORDER_WIDTH = 6; const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte -#define MAX_TEXTURE_SIZE 512 //max upload texture size 512 * 512 +const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512 ///---------------------------------------------------------------------------- /// Class LLSnapshotLivePreview ///---------------------------------------------------------------------------- @@ -120,19 +124,30 @@ public: ESnapshotType getSnapshotType() const { return mSnapshotType; } BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } BOOL isSnapshotActive() { return mSnapshotActive; } + LLImageGL* getThumbnailImage() const { return mThumbnailImage ; } + S32 getThumbnailWidth() const { return mThumbnailWidth ; } + S32 getThumbnailHeight() const { return mThumbnailHeight ; } + BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; } + BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;} LLImageGL* getCurrentImage(); F32 getImageAspect(); + F32 getAspect() ; LLRect getImageRect(); BOOL isImageScaled(); void setSnapshotType(ESnapshotType type) { mSnapshotType = type; } void setSnapshotQuality(S32 quality); void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; } - void updateSnapshot(BOOL new_snapshot); + void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE); LLFloaterPostcard* savePostcard(); void saveTexture(); BOOL saveLocal(); + BOOL setThumbnailImageSize() ; + void generateThumbnailImage(BOOL force_update = FALSE) ; + void resetThumbnailImage() { mThumbnailImage = NULL ; } + void drawPreviewRect(S32 offset_x, S32 offset_y) ; + static void onIdle( void* snapshot_preview ); protected: @@ -144,6 +159,14 @@ protected: BOOL mImageScaled[2]; S32 mMaxImageSize ; + //thumbnail image + LLPointer mThumbnailImage ; + S32 mThumbnailWidth ; + S32 mThumbnailHeight ; + LLRect mPreviewRect ; + BOOL mThumbnailUpdateLock ; + BOOL mThumbnailUpToDate ; + S32 mCurImageIndex; LLPointer mRawImage; LLPointer mRawImageEncoded; @@ -170,12 +193,12 @@ public: }; std::set LLSnapshotLivePreview::sList; - LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : LLView("snapshot_live_preview", rect, FALSE), mColor(1.f, 0.f, 0.f, 0.5f), mCurImageIndex(0), mRawImage(NULL), + mThumbnailImage(NULL) , mRawImageEncoded(NULL), mJPEGImage(NULL), mShineCountdown(0), @@ -204,6 +227,8 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : mMaxImageSize = MAX_IMAGE_SIZE ; mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; + mThumbnailUpdateLock = FALSE ; + mThumbnailUpToDate = FALSE ; } LLSnapshotLivePreview::~LLSnapshotLivePreview() @@ -234,13 +259,8 @@ LLImageGL* LLSnapshotLivePreview::getCurrentImage() return mViewerImage[mCurImageIndex]; } -F32 LLSnapshotLivePreview::getImageAspect() +F32 LLSnapshotLivePreview::getAspect() { - if (!mViewerImage[mCurImageIndex]) - { - return 0.f; - } - F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); @@ -254,6 +274,16 @@ F32 LLSnapshotLivePreview::getImageAspect() } } +F32 LLSnapshotLivePreview::getImageAspect() +{ + if (!mViewerImage[mCurImageIndex]) + { + return 0.f; + } + + return getAspect() ; +} + LLRect LLSnapshotLivePreview::getImageRect() { return mImageRect[mCurImageIndex]; @@ -264,7 +294,7 @@ BOOL LLSnapshotLivePreview::isImageScaled() return mImageScaled[mCurImageIndex]; } -void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot) +void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail) { if (mSnapshotUpToDate) { @@ -272,15 +302,9 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot) mCurImageIndex = (mCurImageIndex + 1) % 2; mWidth[mCurImageIndex] = mWidth[old_image_index]; mHeight[mCurImageIndex] = mHeight[old_image_index]; - mFallAnimTimer.start(); - } - mSnapshotUpToDate = FALSE; - mShineAnimTimer.stop(); - if (new_snapshot) - { - mSnapshotDelayTimer.start(); - mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY); + mFallAnimTimer.start(); } + mSnapshotUpToDate = FALSE; LLRect& rect = mImageRect[mCurImageIndex]; rect.set(0, getRect().getHeight(), getRect().getWidth(), 0); @@ -305,6 +329,21 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot) rect.mRight -= (getRect().getWidth() - new_width) / 2; } } + + mShineAnimTimer.stop(); + if (new_snapshot) + { + mSnapshotDelayTimer.start(); + mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY); + } + else if(new_thumbnail) + { + mThumbnailUpToDate = FALSE ; + } + else + { + setThumbnailImageSize() ; + } } void LLSnapshotLivePreview::setSnapshotQuality(S32 quality) @@ -326,6 +365,45 @@ LLString LLSnapshotLivePreview::getWidgetTag() const return LL_SNAPSHOT_LIVE_PREVIEW_TAG; } +void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) +{ + F32 line_width ; + glGetFloatv(GL_LINE_WIDTH, &line_width) ; + glLineWidth(2.0f * line_width) ; + LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ; + gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y, + mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ; + glLineWidth(line_width) ; + + //draw four alpha rectangles to cover areas outside of the snapshot image + if(!mKeepAspectRatio) + { + LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; + S32 dwl = 0, dwr = 0 ; + if(mThumbnailWidth > mPreviewRect.getWidth()) + { + dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ; + dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ; + + gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y, + mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; + gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y, + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ; + } + + if(mThumbnailHeight > mPreviewRect.getHeight()) + { + S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ; + gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y , + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ; + + dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ; + gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh, + mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ; + } + } +} + void LLSnapshotLivePreview::draw() { if(getVisible()) @@ -519,14 +597,137 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare LLView::reshape(width, height, called_from_parent); if (old_rect.getWidth() != width || old_rect.getHeight() != height) { - updateSnapshot(getSnapshotUpToDate()); + updateSnapshot(FALSE, TRUE); + } +} + +BOOL LLSnapshotLivePreview::setThumbnailImageSize() +{ + if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + { + return FALSE ; + } + S32 window_width = gViewerWindow->getWindowDisplayWidth() ; + S32 window_height = gViewerWindow->getWindowDisplayHeight() ; + + F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height); + + // UI size for thumbnail + S32 max_width = LLFloaterSnapshot::getUIWinWidth() - 20; + S32 max_height = 90; + + if (window_aspect_ratio > (F32)max_width / max_height) + { + // image too wide, shrink to width + mThumbnailWidth = max_width; + mThumbnailHeight = llround((F32)max_width / window_aspect_ratio); + } + else + { + // image too tall, shrink to height + mThumbnailHeight = max_height; + mThumbnailWidth = llround((F32)max_height * window_aspect_ratio); + } + + if(mThumbnailWidth > window_width || mThumbnailHeight > window_height) + { + return FALSE ;//if the window is too small, ignore thumbnail updating. + } + + S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ; + if(!mKeepAspectRatio) + { + F32 ratio_x = (F32)mWidth[mCurImageIndex] / window_width ; + F32 ratio_y = (F32)mHeight[mCurImageIndex] / window_height ; + + //if(mWidth[mCurImageIndex] > window_width || + // mHeight[mCurImageIndex] > window_height ) + { + if(ratio_x > ratio_y) + { + top = (S32)(top * ratio_y / ratio_x) ; + } + else + { + right = (S32)(right * ratio_x / ratio_y) ; + } + } + //else + //{ + // right = (S32)(right * ratio_x) ; + // top = (S32)(top * ratio_y) ; + //} + left = (S32)((mThumbnailWidth - right) * 0.5f) ; + bottom = (S32)((mThumbnailHeight - top) * 0.5f) ; + top += bottom ; + right += left ; + } + mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ; + + return TRUE ; +} + +void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) +{ + if(mThumbnailUpdateLock) //in the process of updating + { + return ; + } + if(mThumbnailUpToDate && !force_update)//already updated + { + return ; + } + if(mWidth[mCurImageIndex] < 10 || mHeight[mCurImageIndex] < 10) + { + return ; + } + + ////lock updating + mThumbnailUpdateLock = TRUE ; + + if(!setThumbnailImageSize()) + { + mThumbnailUpdateLock = FALSE ; + mThumbnailUpToDate = TRUE ; + return ; + } + + if(mThumbnailImage) + { + resetThumbnailImage() ; + } + + LLPointer raw = NULL ; + S32 w , h ; + w = get_nearest_power_two(mThumbnailWidth, 512) * 2 ; + h = get_nearest_power_two(mThumbnailHeight, 512) * 2 ; + + { + raw = new LLImageRaw ; + if(!gViewerWindow->thumbnailSnapshot(raw, + w, h, + gSavedSettings.getBOOL("RenderUIInSnapshot"), + FALSE, + mSnapshotBufferType) ) + { + raw = NULL ; + } + } + + if(raw) + { + mThumbnailImage = new LLImageGL(raw, FALSE); + mThumbnailUpToDate = TRUE ; } + + //unlock updating + mThumbnailUpdateLock = FALSE ; } //static void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) { - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview; + LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview; LLVector3 new_camera_pos = gCamera->getOrigin(); LLQuaternion new_camera_rot = gCamera->getQuaternion(); @@ -637,6 +838,7 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE); previewp->mSnapshotUpToDate = TRUE; + previewp->generateThumbnailImage(TRUE) ; previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame @@ -647,6 +849,10 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->mSnapshotDelayTimer.stop(); previewp->mSnapshotActive = FALSE; } + if(!previewp->getThumbnailUpToDate()) + { + previewp->generateThumbnailImage() ; + } } void LLSnapshotLivePreview::setSize(S32 w, S32 h) @@ -759,7 +965,8 @@ public: static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); - static void checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); + static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ; + static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); @@ -773,7 +980,7 @@ private: static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); - static void checkAutoSnapshot(LLSnapshotLivePreview* floater); + static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ; public: @@ -840,7 +1047,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) { LLSnapshotLivePreview* previewp = getPreviewView(floaterp); - S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : -230 ; + S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ; LLComboBox* combo; if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution @@ -869,7 +1076,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) floaterp->getParent()->setMouseOpaque(TRUE); // shrink to smaller layout - floaterp->reshape(floaterp->getRect().getWidth(), 526 + delta_height); + floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); // can see and interact with fullscreen preview now if (previewp) @@ -902,7 +1109,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) else // turning off freeze frame mode { floaterp->getParent()->setMouseOpaque(FALSE); - floaterp->reshape(floaterp->getRect().getWidth(), 526 + delta_height); + floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getUIWinHeightLong() + delta_height); if (previewp) { previewp->setVisible(FALSE); @@ -1051,11 +1258,11 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) } // static -void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp) +void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail) { if (previewp) { - previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); + previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"), update_thumbnail); } } @@ -1143,16 +1350,13 @@ void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) void LLFloaterSnapshot::Impl::onClickMore(void* data) { - //floater->childSetVisible("more_btn", FALSE); - //floater->childSetVisible("less_btn", TRUE); - gSavedSettings.setBOOL( "AdvanceSnapshot", TRUE ); LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - view->translate( 0, -230 ); - view->reshape(view->getRect().getWidth(), 526); + view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() ); + view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong()); updateControls(view) ; updateLayout(view) ; @@ -1160,40 +1364,24 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data) } void LLFloaterSnapshot::Impl::onClickLess(void* data) { - //floater->childSetVisible("less_btn", FALSE); - //floater->childSetVisible("more_btn", TRUE); - gSavedSettings.setBOOL( "AdvanceSnapshot", FALSE ); LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - view->translate( 0, 230 ); - view->reshape(view->getRect().getWidth(), 294); + view->translate( 0, view->getUIWinHeightLong() - view->getUIWinHeightShort() ); + view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort()); updateControls(view) ; updateLayout(view) ; + + if(getPreviewView(view)) + { + getPreviewView(view)->setThumbnailImageSize() ; + } } } -//void LLFloaterSnapshot::Impl::onClickAdvanceSnap(LLUICtrl *ctrl, void* data) -//{ -// LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; -// gSavedSettings.setBOOL( "AdvanceSnapshot", check->get() ); -// -// LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; -// if (view) -// { -// S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : -230 ; -// -// view->translate( 0, delta_height ? 230 : -230 ); -// view->reshape(view->getRect().getWidth(), 526 + delta_height); -// -// updateControls(view) ; -// updateLayout(view) ; -// } -//} - // static void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) { @@ -1203,7 +1391,7 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view)); + checkAutoSnapshot(getPreviewView(view), TRUE); } } @@ -1216,7 +1404,7 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view)); + checkAutoSnapshot(getPreviewView(view), TRUE); } } @@ -1244,23 +1432,14 @@ void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) S32 w, h ; previewp->getSize(w, h) ; - checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize()) ; - previewp->setSize(w, h) ; - - //update textbox - LLSpinCtrl *sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_width") ; - if(sctrl) + if(checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize())) { - sctrl->setValue(w) ; + resetSnapshotSizeOnUI(view, w, h) ; } - sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_height") ; - if(sctrl) - { - sctrl->setValue(h) ; - } + previewp->setSize(w, h) ; - checkAutoSnapshot(previewp); + checkAutoSnapshot(previewp, TRUE); } } } @@ -1276,7 +1455,7 @@ void LLFloaterSnapshot::Impl::onCommitQuality(LLUICtrl* ctrl, void* data) { previewp->setSnapshotQuality(quality_val); } - checkAutoSnapshot(previewp); + checkAutoSnapshot(previewp, TRUE); } // static @@ -1300,6 +1479,12 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde { LLSnapshotLivePreview *previewp = getPreviewView(view) ; + if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getTypeIndex(view)) + { + previewp->mKeepAspectRatio = FALSE ; + return ; + } + if(!index) //current window size { sAspectRatioCheckOff = TRUE ; @@ -1385,13 +1570,17 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data) checkAspectRatio(view, width) ; previewp->getSize(width, height); - checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize()) ; + + if(checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize())) + { + resetSnapshotSizeOnUI(view, width, height) ; + } previewp->setSize(width, height); view->childSetValue("snapshot_width", width); view->childSetValue("snapshot_height", height); // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp); + checkAutoSnapshot(previewp, FALSE); } } @@ -1409,7 +1598,7 @@ void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) { previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex()); } - checkAutoSnapshot(previewp); + checkAutoSnapshot(previewp, TRUE); } } @@ -1440,8 +1629,11 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s //static -void LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) +BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) { + S32 w = width ; + S32 h = height ; + //if texture, ignore aspect ratio setting, round image size to power of 2. if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) { @@ -1457,15 +1649,12 @@ void LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3 //round to nearest power of 2 width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ; height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ; - - return ; } - - if(previewp && previewp->mKeepAspectRatio) + else if(previewp && previewp->mKeepAspectRatio) { if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1) { - return ; + return FALSE ; } //aspect ratio of the current window @@ -1499,7 +1688,27 @@ void LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3 else { } - return ; + + return (w != width || h != height) ; +} + +//static +void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) +{ + LLSpinCtrl *sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_width") ; + if(sctrl) + { + sctrl->setValue(width) ; + } + + sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_height") ; + if(sctrl) + { + sctrl->setValue(height) ; + } + + gSavedSettings.setS32("LastSnapshotWidth", width); + gSavedSettings.setS32("LastSnapshotHeight", height); } //static @@ -1522,35 +1731,14 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat if (w != curw || h != curh) { - S32 width = w ; - S32 height = h ; - previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ; - checkImageSize(previewp, width, height, width != curw, previewp->getMaxImageSize()) ; - - if(width != w || height != h) + if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize())) { - LLSpinCtrl *sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_width") ; - if(sctrl) - { - sctrl->setValue(width) ; - } - - sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_height") ; - if(sctrl) - { - sctrl->setValue(height) ; - } - - w = width ; - h = height ; - - gSavedSettings.setS32("LastSnapshotWidth", w); - gSavedSettings.setS32("LastSnapshotHeight", h); + resetSnapshotSizeOnUI(view, w, h) ; } previewp->setSize(w,h); - checkAutoSnapshot(previewp); + checkAutoSnapshot(previewp, FALSE); comboSetCustom(view, "postcard_size_combo"); comboSetCustom(view, "texture_size_combo"); comboSetCustom(view, "local_size_combo"); @@ -1664,7 +1852,7 @@ void LLFloaterSnapshot::draw() { LLSnapshotLivePreview* previewp = impl.getPreviewView(this); - if (previewp && previewp->isSnapshotActive()) + if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) { // don't render snapshot window in snapshot, even if "show ui" is turned on return; @@ -1720,7 +1908,7 @@ void LLFloaterSnapshot::draw() LLFloater::draw(); // draw snapshot thumbnail if not in fullscreen preview mode - if (/*!gSavedSettings.getBOOL("UseFreezeFrame") &&*/ previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) + /*if (previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) { F32 aspect = previewp->getImageAspect(); // UI size for thumbnail @@ -1757,6 +1945,21 @@ void LLFloaterSnapshot::draw() glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); + }*/ + if (previewp) + { + if(previewp->getThumbnailImage()) + { + S32 offset_x = (getRect().getWidth() - previewp->getThumbnailWidth()) / 2 ; + S32 offset_y = getRect().getHeight() - 205 + (90 - previewp->getThumbnailHeight()) / 2 ; + + glMatrixMode(GL_MODELVIEW); + gl_draw_scaled_image(offset_x, offset_y, + previewp->getThumbnailWidth(), previewp->getThumbnailHeight(), + previewp->getThumbnailImage(), LLColor4::white); + + previewp->drawPreviewRect(offset_x, offset_y) ; + } } } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index cf1e6bd8f8..fecc3f0fd5 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -50,14 +50,20 @@ public: static void show(void*); static void hide(void*); - static void update(); - + + static S32 getUIWinHeightLong() {return sUIWinHeightLong ;} + static S32 getUIWinHeightShort() {return sUIWinHeightShort ;} + static S32 getUIWinWidth() {return sUIWinWidth ;} + private: class Impl; Impl& impl; static LLFloaterSnapshot* sInstance; + static S32 sUIWinHeightLong ; + static S32 sUIWinHeightShort ; + static S32 sUIWinWidth ; }; class LLSnapshotFloaterView : public LLFloaterView diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 0468ae5a1a..e04a62167c 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -76,6 +76,7 @@ const F32 LOD_2_SCREEN_COVERAGE = 0.40f; std::set > LLHUDText::sTextObjects; std::vector > LLHUDText::sVisibleTextObjects; std::vector > LLHUDText::sVisibleHUDTextObjects; +BOOL LLHUDText::sDisplayText = TRUE ; bool lltextobject_further_away::operator()(const LLPointer& lhs, const LLPointer& rhs) const { @@ -120,7 +121,7 @@ LLHUDText::~LLHUDText() void LLHUDText::render() { - if (!mOnHUDAttachment) + if (!mOnHUDAttachment && sDisplayText) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); renderText(FALSE); diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index 75dc43cd6a..bb96c356bb 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -124,6 +124,7 @@ public: static void renderAllHUD(); static void addPickable(std::set &pick_list); static void reshape(); + static void setDisplayText(BOOL flag) { sDisplayText = flag ; } protected: LLHUDText(const U8 type); @@ -170,6 +171,7 @@ private: S32 mLOD; BOOL mHidden; + static BOOL sDisplayText ; static std::set > sTextObjects; static std::vector > sVisibleTextObjects; static std::vector > sVisibleHUDTextObjects; diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 237826cb7a..89f2e6239a 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -61,6 +61,7 @@ #include "llvoavatar.h" #include "llvoiceremotectrl.h" #include "llwebbrowserctrl.h" +#include "llselectmgr.h" // // Globals @@ -325,6 +326,7 @@ void LLOverlayBar::onClickMouselook(void*) //static void LLOverlayBar::onClickStandUp(void*) { + gSelectMgr->deselectAllForStandingUp(); gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f6556ffbd5..f468ce97ac 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3343,6 +3343,36 @@ void LLSelectMgr::deselectAll() updatePointAt(); } +void LLSelectMgr::deselectAllForStandingUp() +{ + /* + This function is similar deselectAll() except for the first if statement + which was removed. This is needed as a workaround for DEV-2854 + */ + + // Zap the angular velocity, as the sim will set it to zero + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) + { + LLViewerObject *objectp = (*iter)->getObject(); + objectp->setAngularVelocity( 0,0,0 ); + objectp->setVelocity( 0,0,0 ); + } + + sendListToRegions( + "ObjectDeselect", + packAgentAndSessionID, + packObjectLocalID, + NULL, + SEND_INDIVIDUALS); + + removeAll(); + + mLastSentSelectionCenterGlobal.clearVec(); + + updatePointAt(); +} + void LLSelectMgr::deselectUnused() { // no more outstanding references to this selection diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 68c1d4d9f8..570bcef79a 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -419,6 +419,7 @@ public: // Send deselect messages to simulator, then clear the list void deselectAll(); + void deselectAllForStandingUp(); // deselect only if nothing else currently referencing the selection void deselectUnused(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 008eaccdc4..acd64220d9 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -474,7 +474,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) mDesiredDiscard = discard; mDesiredSize = size; } - else if (size > mDesiredSize) + else if (size > mDesiredSize || size == 0) { mDesiredSize = size; prioritize = true; @@ -571,7 +571,8 @@ bool LLTextureFetchWorker::doWork(S32 param) U32 cache_priority = mWorkPriority; S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; S32 size = mDesiredSize - offset; - if (size <= 0) + + if(mDesiredSize != 0 && size <= 0) { mState = CACHE_POST; return false; @@ -1304,6 +1305,13 @@ bool LLTextureFetch::createRequest(const LLUUID& id, const LLHost& host, F32 pri // we really do get it.) desired_size = worker->mFileSize; } + else if ((discard == 0) && worker == NULL) + { + // if we want the entire image, but we don't know its size, then send + // a sentinel value of zero to request the entire contents of the cache. + // patch supplied by resident Sheet Spotter for VWR-2404 + desired_size = 0; + } else if (w*h*c > 0) { // If the requester knows the dimentions of the image, diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 7733ef5ae1..0df04fccfa 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -470,6 +470,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _1)); gSavedSettings.getControl("RenderUseCleverUI")->getSignal()->connect(boost::bind(&handleRenderUseCleverUIChanged, _1)); gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _1)); + gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("AvatarCompositeLimit")->getSignal()->connect(boost::bind(&handleCompositeLimitChanged, _1)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _1)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _1)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a75544d528..41a936ca49 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -75,6 +75,7 @@ #include "llcubemap.h" #include "llviewerregion.h" #include "lldrawpoolwater.h" +#include "lldrawpoolbump.h" #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llpostprocess.h" @@ -82,6 +83,7 @@ extern LLPointer gStartImageGL; extern BOOL gDisplaySwapBuffers; + LLPointer gDisconnectedImagep = NULL; // used to toggle renderer back on after teleport @@ -509,7 +511,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; - if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT) > 1) + if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT) > 1) && + gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)) { if (gCamera->cameraUnderWater()) { @@ -571,7 +574,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) glh::matrix4f proj = glh_get_current_projection(); glh::matrix4f mod = glh_get_current_modelview(); - glViewport(0,0,128,256); + glViewport(0,0,512,512); + LLVOAvatar::updateFreezeCounter() ; LLVOAvatar::updateImpostors(); glh_set_current_projection(proj); glh_set_current_modelview(mod); @@ -590,6 +594,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.generateWaterReflection(*gCamera); } + ////////////////////////////////////// + // + // Update images, using the image stats generated during object update/culling + // + // Can put objects onto the retextured list. + // + // Doing this here gives hardware occlusion queries extra time to complete + gFrameStats.start(LLFrameStats::IMAGE_UPDATE); + + { + LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); + + LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(), + gCamera->getAngularVelocityStat()->getMean()); + + gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. + + const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) + gImageList.updateImages(max_image_decode_time); + stop_glerror(); + } + /////////////////////////////////// // // StateSort @@ -692,8 +718,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } stop_glerror(); } - - render_hud_attachments(); if (to_texture) { @@ -764,13 +788,13 @@ void render_hud_attachments() gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLOW); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.stateSort(hud_cam, result); gPipeline.renderGeom(hud_cam); + render_hud_elements(); //restore type mask gPipeline.setRenderTypeMask(mask); if (has_ui) @@ -874,6 +898,9 @@ void render_ui_and_swap() { gPipeline.renderBloom(gSnapshot); } + + render_hud_elements(); + render_hud_attachments(); } LLGLSDefault gls_default; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ac52b8d05f..77cfd63847 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1359,6 +1359,9 @@ void init_debug_rendering_menu(LLMenuGL* menu) sub_menu->append(new LLMenuItemCheckGL("Texture Priority", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)); + sub_menu->append(new LLMenuItemCheckGL("Avatar Rendering Cost", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_SHAME)); sub_menu->append(new LLMenuItemCheckGL("Texture Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_TEXTURE_AREA)); diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index d81b688abf..db356064d4 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -84,7 +84,10 @@ LLUUID LLViewerPartSource::getImageUUID() const } void LLViewerPartSource::setStart() { - mDelay = 99 ; + //cancel delaying to start a new added particle source, because some particle source just emits for a short time. + //however, canceling this might cause overall particle emmitting fluctuate for a while because the new added source jumps to + //the current particle emmitting settings instantly. -->bao + mDelay = 0 ; //99 } LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) : @@ -263,7 +266,7 @@ void LLViewerPartSourceScript::update(const F32 dt) } if(mDelay) - { + { limited_rate = llmax(limited_rate, 0.01f * mDelay--) ; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 900fd6fc8b..d48e3cc4f3 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1522,7 +1522,8 @@ LLViewerWindow::LLViewerWindow( gNoRender, gSavedSettings.getBOOL("DisableVerticalSync"), !gNoRender, - ignore_pixel_depth); + ignore_pixel_depth, + gSavedSettings.getU32("RenderFSAASamples")); #if LL_WINDOWS if (!LLWinDebug::setupExceptionHandler()) { @@ -4242,14 +4243,145 @@ void LLViewerWindow::playSnapshotAnimAndSound() send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f); } +BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) +{ + if ((!gWorldPointer) || (!raw) || preview_width < 10 || preview_height < 10) + { + return FALSE; + } + + if(gResizeScreenTexture) //the window is resizing + { + return FALSE ; + } + + setCursor(UI_CURSOR_WAIT); + + // Hide all the UI widgets first and draw a frame + BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); + + if ( prev_draw_ui != show_ui) + { + LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + + BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = FALSE; + } + + S32 render_name = gSavedSettings.getS32("RenderName"); + gSavedSettings.setS32("RenderName", 0); + LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame + + S32 w = preview_width ; + S32 h = preview_height ; + LLVector2 display_scale = mDisplayScale ; + mDisplayScale.setVec((F32)w / mWindowRect.getWidth(), (F32)h / mWindowRect.getHeight()) ; + LLRect window_rect = mWindowRect; + mWindowRect.set(0, h, w, 0); + + gDisplaySwapBuffers = FALSE; + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + setup3DRender(); + setupViewport(); + + LLFontGL::setFontDisplay(FALSE) ; + LLHUDText::setDisplayText(FALSE) ; + if (type == SNAPSHOT_TYPE_OBJECT_ID) + { + gPickTransparent = FALSE; + gObjectList.renderObjectsForSelect(*gCamera, FALSE, FALSE); + } + else + { + display(do_rebuild, 1.0f, 0, TRUE); + render_ui_and_swap(); + } + + S32 glformat, gltype, glpixel_length ; + if(SNAPSHOT_TYPE_DEPTH == type) + { + glpixel_length = 4 ; + glformat = GL_DEPTH_COMPONENT ; + gltype = GL_FLOAT ; + } + else + { + glpixel_length = 3 ; + glformat = GL_RGB ; + gltype = GL_UNSIGNED_BYTE ; + } + + raw->resize(w, h, glpixel_length); + glReadPixels(0, 0, w, h, glformat, gltype, raw->getData()); + + if(SNAPSHOT_TYPE_DEPTH == type) + { + F32 depth_conversion_factor_1 = (gCamera->getFar() + gCamera->getNear()) / (2.f * gCamera->getFar() * gCamera->getNear()); + F32 depth_conversion_factor_2 = (gCamera->getFar() - gCamera->getNear()) / (2.f * gCamera->getFar() * gCamera->getNear()); + + //calculate the depth + for (S32 y = 0 ; y < h ; y++) + { + for(S32 x = 0 ; x < w ; x++) + { + S32 i = (w * y + x) << 2 ; + + F32 depth_float_i = *(F32*)(raw->getData() + i); + + F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2)); + U8 depth_byte = F32_to_U8(linear_depth_float, gCamera->getNear(), gCamera->getFar()); + *(raw->getData() + i + 0) = depth_byte; + *(raw->getData() + i + 1) = depth_byte; + *(raw->getData() + i + 2) = depth_byte; + *(raw->getData() + i + 3) = 255; + } + } + } + + LLFontGL::setFontDisplay(TRUE) ; + LLHUDText::setDisplayText(TRUE) ; + mDisplayScale.setVec(display_scale) ; + mWindowRect = window_rect; + setup3DRender(); + setupViewport(); + gDisplaySwapBuffers = FALSE; + + // POST SNAPSHOT + if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); + } + + if (hide_hud) + { + LLPipeline::sShowHUDAttachments = TRUE; + } + + setCursor(UI_CURSOR_ARROW); + + if (do_rebuild) + { + // If we had to do a rebuild, that means that the lists of drawables to be rendered + // was empty before we started. + // Need to reset these, otherwise we call state sort on it again when render gets called the next time + // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of + // objects on them. + gPipeline.resetDrawOrders(); + } + + gSavedSettings.setS32("RenderName", render_name); + + return TRUE; +} // Saves the image from the screen to the specified filename and path. BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size) { - //F32 image_aspect_ratio = ((F32)image_width) / ((F32)image_height); - //F32 window_aspect_ratio = ((F32)getWindowWidth()) / ((F32)getWindowHeight()); - if ((!gWorldPointer) || (!raw)) { @@ -4282,43 +4414,30 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // from window S32 snapshot_width = mWindowRect.getWidth(); S32 snapshot_height = mWindowRect.getHeight(); + // SNAPSHOT + S32 window_width = mWindowRect.getWidth(); + S32 window_height = mWindowRect.getHeight(); + LLRect window_rect = mWindowRect; + BOOL use_fbo = FALSE; + F32 scale_factor = 1.0f ; - if (keep_window_aspect || is_texture) //map the entire window to snapshot - { - } - else //scale or crop + if(!keep_window_aspect) //image cropping { - if(snapshot_width > image_width) //crop - { - snapshot_width = image_width ; - } - if(snapshot_height > image_height)//crop - { - snapshot_height = image_height ; - } - - //if (image_aspect_ratio > window_aspect_ratio) + //if(snapshot_width > image_width && snapshot_height > image_height) //crop //{ - // snapshot_height = llround((F32)snapshot_width / image_aspect_ratio); - //} - //else if (image_aspect_ratio < window_aspect_ratio) - //{ - // snapshot_width = llround((F32)snapshot_height * image_aspect_ratio); + // snapshot_width = image_width ; + // snapshot_height = image_height ; //} + //else //crop and enlarge + { + F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; + snapshot_width = (S32)(ratio * image_width) ; + snapshot_height = (S32)(ratio * image_height) ; + scale_factor = llmax(1.0f, 1.0f / ratio) ; + } } LLRenderTarget target; - - scale_factor = llmax(1.f, (F32)image_width / snapshot_width, (F32)image_height / snapshot_height); - - // SNAPSHOT - S32 window_width = mWindowRect.getWidth(); - S32 window_height = mWindowRect.getHeight(); - - LLRect window_rect = mWindowRect; - - BOOL use_fbo = FALSE; - if (gGLManager.mHasFramebufferObject && (image_width > window_width || image_height > window_height) && @@ -4339,9 +4458,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei window_height = snapshot_height; scale_factor = 1.f; mWindowRect.set(0, 0, snapshot_width, snapshot_height); - target.bindTarget(); - - + target.bindTarget(); } } @@ -4954,6 +5071,8 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, return TRUE; // a lie..., because we'll get to it later } + U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); + U32 old_fsaa = mWindow->getFSAASamples(); // going from windowed to windowed if (!old_fullscreen && !fullscreen) { @@ -4962,7 +5081,11 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, { mWindow->setSize(size); } - return TRUE; + + if (fsaa == old_fsaa) + { + return TRUE; + } } // Close floaters that don't handle settings change @@ -4988,10 +5111,13 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, gSavedSettings.setS32("WindowY", old_pos.mY); } + mWindow->setFSAASamples(fsaa); + result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync); if (!result_first_try) { // try to switch back + mWindow->setFSAASamples(old_fsaa); result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync); if (!result_second_try) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 09ad3fc270..ef3b5146e2 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -219,6 +219,7 @@ public: BOOL saveSnapshot(const LLString& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR); BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_IMAGE_SIZE ); + BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ; BOOL saveImageNumbered(LLImageRaw *raw, const LLString& extension = LLString()); void playSnapshotAnimAndSound(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 575f9c424c..68c5eec9a4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -138,6 +138,7 @@ LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL; LLVOAvatarInfo* LLVOAvatar::sAvatarInfo = NULL; BOOL gDebugAvatarRotation = FALSE; +S32 LLVOAvatar::sFreezeCounter = 0 ; //extern BOOL gVelocityInterpolate; @@ -2378,7 +2379,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLMemType mt(LLMemType::MTYPE_AVATAR); LLFastTimer t(LLFastTimer::FTM_AVATAR_UPDATE); - + if (isDead()) { llinfos << "Warning! Idle on dead avatar" << llendl; @@ -2606,7 +2607,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) F32 old_angle = mImpostorAngle.mV[i]; F32 angle_diff = fabsf(cur_angle-old_angle); - if (angle_diff > 3.14159f/16.f) + if (angle_diff > 3.14159f/512.f*distance) { mNeedsImpostorUpdate = TRUE; } @@ -3069,6 +3070,8 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) sNumVisibleChatBubbles--; } + shame(); + //-------------------------------------------------------------------- // draw tractor beam when editing objects //-------------------------------------------------------------------- @@ -3166,6 +3169,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLMemType mt(LLMemType::MTYPE_AVATAR); // update screen joint size + if (mScreenp) { F32 aspect = gCamera->getAspect(); @@ -3235,10 +3239,15 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // the rest should only be done occasionally for far away avatars //-------------------------------------------------------------------- - if (!mIsSelf && sUseImpostors && !mNeedsAnimUpdate) + if (!mIsSelf && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); - if (visible && mPixelArea <= impostor_area) + if (gMuteListp && gMuteListp->isMuted(getID())) + { + mUpdatePeriod = 16; + visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE; + } + else if (visible && mPixelArea <= impostor_area) { mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mPixelArea), 2, 8); @@ -3897,7 +3906,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) { mEyeLashLOD.updateGeometry(); mHeadLOD.updateGeometry(); - mHairLOD.updateGeometry(); + mHairLOD.updateGeometry(); } mNeedsSkin = FALSE; @@ -4119,8 +4128,13 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color) } LLVector3 pos(getRenderPosition()+mImpostorOffset); - LLVector3 left = gCamera->getLeftAxis()*mImpostorDim.mV[0]; - LLVector3 up = gCamera->getUpAxis()*mImpostorDim.mV[1]; + LLVector3 at = (pos-gCamera->getOrigin()); + at.normVec(); + LLVector3 left = gCamera->getUpAxis() % at; + LLVector3 up = at%left; + + left *= mImpostorDim.mV[0]; + up *= mImpostorDim.mV[1]; LLGLEnable test(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.f); @@ -5650,6 +5664,8 @@ BOOL LLVOAvatar::updateJointLODs() F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE)); F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f); F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor); + F32 area_scale = 0.16f; + { if (mIsSelf) { @@ -5659,7 +5675,7 @@ BOOL LLVOAvatar::updateJointLODs() } else { - mAdjustedPixelArea = mPixelArea; + mAdjustedPixelArea = mPixelArea*area_scale; } } else if (mIsDummy) @@ -5669,7 +5685,7 @@ BOOL LLVOAvatar::updateJointLODs() else { // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars - mAdjustedPixelArea = (F32)mPixelArea * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; + mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; } // now select meshes to render based on adjusted pixel area @@ -9440,6 +9456,23 @@ LLHost LLVOAvatar::getObjectHost() const } } +//static +void LLVOAvatar::updateFreezeCounter(S32 counter) +{ + if(counter) + { + sFreezeCounter = counter ; + } + else if(sFreezeCounter > 0) + { + sFreezeCounter-- ; + } + else + { + sFreezeCounter = 0 ; + } +} + BOOL LLVOAvatar::updateLOD() { BOOL res = updateJointLODs(); @@ -9493,7 +9526,7 @@ BOOL LLVOAvatar::isImpostor() const BOOL LLVOAvatar::needsImpostorUpdate() const { - return mNeedsImpostorUpdate; + return mNeedsImpostorUpdate ; } const LLVector3& LLVOAvatar::getImpostorOffset() const @@ -9524,8 +9557,141 @@ void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& di LLVector3 at = gCamera->getOrigin()-(getRenderPosition()+mImpostorOffset); distance = at.normVec(); - angle.mV[0] = acosf(at.mV[0]); - angle.mV[1] = acosf(at.mV[1]); - angle.mV[2] = acosf(at.mV[2]); + F32 da = 1.f - (at*gCamera->getAtAxis()); + angle.mV[0] = gCamera->getYaw()*da; + angle.mV[1] = gCamera->getPitch()*da; + angle.mV[2] = da; +} + +U32 calc_shame(LLVOVolume* volume, std::set &textures) +{ + if (!volume) + { + return 0; + } + + U32 shame = 0; + + U32 invisi = 0; + U32 shiny = 0; + U32 glow = 0; + U32 alpha = 0; + U32 flexi = 0; + U32 animtex = 0; + U32 particles = 0; + U32 scale = 0; + U32 bump = 0; + U32 planar = 0; + + if (volume->isFlexible()) + { + flexi = 1; + } + if (volume->isParticleSource()) + { + particles = 1; + } + + const LLVector3& sc = volume->getScale(); + scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2]; + + LLDrawable* drawablep = volume->mDrawable; + + if (volume->isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *) volume->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID sculpt_id = sculpt_params->getSculptTexture(); + textures.insert(sculpt_id); + } + + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + const LLTextureEntry* te = face->getTextureEntry(); + LLViewerImage* img = face->getTexture(); + + textures.insert(img->getID()); + + if (face->getPoolType() == LLDrawPool::POOL_ALPHA) + { + alpha++; + } + else if (img->getPrimaryFormat() == GL_ALPHA) + { + invisi = 1; + } + + if (te->getBumpmap()) + { + bump = 1; + } + if (te->getShiny()) + { + shiny = 1; + } + if (te->getGlow() > 0.f) + { + glow = 1; + } + if (face->mTextureMatrix != NULL) + { + animtex++; + } + if (te->getTexGen()) + { + planar++; + } + } + + shame += invisi + shiny + glow + alpha*4 + flexi*8 + animtex*4 + particles*16+bump*4+scale+planar; + + for (U32 i = 0; i < drawablep->getChildCount(); ++i) + { + shame += calc_shame(drawablep->getChild(i)->getVOVolume(), textures); + } + + return shame; } +void LLVOAvatar::shame() +{ + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) + { + return; + } + + U32 shame = 1; + + std::set textures; + + attachment_map_t::const_iterator iter; + for (iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + LLViewerObject* object = attachment->getObject(); + if (object && !object->isHUDAttachment()) + { + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + shame += 10; + LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + shame += calc_shame(volume, textures); + } + } + } + } + + shame += textures.size() * 5; + + setDebugText(llformat("%d", shame)); + F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f); + F32 red = llmin((F32) shame/1024.f, 1.f); + mText->setColor(LLColor4(red,green,0,1)); +} + + diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ae0656f3ea..a6731c3e31 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -984,6 +984,7 @@ protected: LLHost getObjectHost() const; S32 getLocalDiscardLevel( S32 index); + void shame(); //generate shame metric //Ventrella //----------------------------------------------------------------------------------------------- // the Voice Visualizer is responsible for detecting the user's voice signal, and when the @@ -993,7 +994,11 @@ protected: LLVoiceVisualizer * mVoiceVisualizer; int mCurrentGesticulationLevel; //End Ventrella - + +private: + static S32 sFreezeCounter ; +public: + static void updateFreezeCounter(S32 counter = 0 ) ; }; #endif // LL_VO_AVATAR_H diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f42ec51b5d..448bda1857 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -99,7 +99,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llspatialpartition.h" - +#include "llmutelist.h" #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -1252,6 +1252,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.flush(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } + else if (LLPipeline::sUseOcclusion > 1) + { + glFlush(); + } } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -1339,6 +1343,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) } glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glFlush(); } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) @@ -2124,8 +2129,6 @@ void render_hud_elements() LLFastTimer t(LLFastTimer::FTM_RENDER_UI); gPipeline.disableLights(); - gPipeline.renderDebug(); - LLGLDisable fog(GL_FOG); LLGLSUIDefault gls_ui; @@ -2289,15 +2292,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::startRender(); - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } - //by bao //fake vertex buffer updating //to guaranttee at least updating one VBO buffer every frame @@ -2314,7 +2308,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glMatrixMode(GL_MODELVIEW); LLGLSPipeline gls_pipeline; - + LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); // Toggle backface culling for debugging @@ -2346,8 +2341,22 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { gObjectList.renderObjectsForSelect(camera); } + else if (gSavedSettings.getBOOL("RenderDeferred")) + { + renderGeomDeferred(); + } else { + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } + } + + LLFastTimer t(LLFastTimer::FTM_POOLS); calcNearbyLights(camera); setupHWLights(NULL); @@ -2456,7 +2465,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) // have touch-handlers. mHighlightFaces.clear(); - render_hud_elements(); + renderDebug(); LLVertexBuffer::stopRender(); LLVertexBuffer::unbind(); @@ -2479,6 +2488,19 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) #endif } +void LLPipeline::renderGeomDeferred() +{ + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + gDeferredDiffuseProgram.bind(); + gPipeline.renderObjects(LLRenderPass::PASS_SIMPLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL, TRUE); + gDeferredDiffuseProgram.unbind(); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + void LLPipeline::addTrianglesDrawn(S32 count) { assertInitialized(); @@ -4814,6 +4836,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot) mScreen.bindTexture(); + LLGLEnable multisample(GL_MULTISAMPLE_ARB); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisable(GL_TEXTURE_RECTANGLE_ARB); @@ -4948,13 +4971,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) mRenderTypeMask = tmp; } - if (LLDrawPoolWater::sNeedsReflectionUpdate) + if (LLDrawPoolWater::sNeedsDistortionUpdate) { mRenderTypeMask &= ~((1<setupViewport(); mRenderTypeMask = type_mask; LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; + LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; gCamera->setUserClipPlane(LLPlane(-pnorm, -pd)); LLPipeline::sUseOcclusion = occlusion; } @@ -5075,10 +5098,6 @@ LLCubeMap* LLPipeline::findReflectionMap(const LLVector3& location) void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) { -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -5105,22 +5124,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - if (!avatar->mImpostor.isComplete()) + U32 mask; + BOOL muted = gMuteListp && gMuteListp->isMuted(avatar->getID()); + + if (muted) { - avatar->mImpostor.allocate(128,256,GL_RGBA,TRUE); - avatar->mImpostor.bindTexture(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; } - - U32 mask = (1<mImpostor.bindTarget(); - avatar->mImpostor.getViewport(gGLViewport); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } - - LLGLEnable stencil(GL_STENCIL_TEST); - - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); @@ -5190,9 +5192,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glMatrixMode(GL_PROJECTION); glPushMatrix(); - glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); - glh_set_current_projection(ortho); - glLoadMatrixf(ortho.m); + //glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); + F32 distance = (pos-camera.getOrigin()).magVec(); + F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; + F32 aspect = tdim.mV[0]/tdim.mV[1]; //128.f/256.f; + glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); + glh_set_current_projection(persp); + glLoadMatrixf(persp.m); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -5204,24 +5210,68 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glLoadMatrixf(mat.m); glh_set_current_modelview(mat); + glClearColor(0.0f,0.0f,0.0f,0.0f); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glStencilMask(0xFFFFFFFF); + glClearStencil(0); + + // get the number of pixels per angle + F32 pa = gViewerWindow->getWindowDisplayHeight()/(RAD_TO_DEG*gCamera->getView()); + + //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing) + U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512); + U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); + + if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || + resY != avatar->mImpostor.getHeight()) + { + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE); + avatar->mImpostor.bindTexture(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + } + + { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, resX, resY); + avatar->mImpostor.bindTarget(); + avatar->mImpostor.getViewport(gGLViewport); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + LLGLEnable stencil(GL_STENCIL_TEST); + + glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + renderGeom(camera); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; - LLGLEnable blend(GL_BLEND); + LLGLEnable blend(muted ? 0 : GL_BLEND); + + if (muted) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + else + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + } + gGL.blendFunc(GL_ONE, GL_ONE); LLImageGL::unbindTexture(0, GL_TEXTURE_2D); LLGLDepthTest depth(GL_FALSE, GL_FALSE); gGL.start(); - gGL.color4ub(0,0,0,1); + gGL.color4ub(64,64,64,1); gGL.begin(GL_QUADS); gGL.vertex3fv((pos+left-up).mV); gGL.vertex3fv((pos-left-up).mV); @@ -5230,9 +5280,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.end(); gGL.stop(); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + avatar->mImpostor.flush(); avatar->setImpostorDim(tdim); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 2054492b72..9c64ccdbe3 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -72,6 +72,7 @@ void glh_set_current_modelview(glh::matrix4f& mat); glh::matrix4f glh_get_current_projection(); void glh_set_current_projection(glh::matrix4f& mat); glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); +glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); class LLPipeline { @@ -179,6 +180,8 @@ public: void grabReferences(LLCullResult& result); void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); + void renderGeomDeferred(); + void processImagery(LLCamera& camera); void generateWaterReflection(LLCamera& camera); void renderHighlights(); @@ -328,6 +331,7 @@ public: RENDER_DEBUG_TEXTURE_ANIM = 0x080000, RENDER_DEBUG_LIGHTS = 0x100000, RENDER_DEBUG_BATCH_SIZE = 0x200000, + RENDER_DEBUG_SHAME = 0x400000, }; LLPointer mAlphaSizzleImagep; -- cgit v1.2.3