123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- /**
- * @file llgl.h
- * @brief LLGL definition
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #ifndef LL_LLGL_H
- #define LL_LLGL_H
- // This file contains various stuff for handling gl extensions and other GL
- // related stuff.
- #include <list>
- #include "llcolor4.h"
- #include "hbfastmap.h"
- #include "llglheaders.h"
- #include "llinstancetracker.h"
- #include "llmatrix4a.h"
- #include "llplane.h"
- #include "llstring.h"
- extern bool gDebugGL;
- // Global flag for dual-renderer support (EE/WL and PBR). HB
- extern bool gUsePBRShaders;
- class LLSD;
- // Manage GL extensions...
- class LLGLManager
- {
- protected:
- LOG_CLASS(LLGLManager);
- public:
- LLGLManager();
- bool initGL();
- void shutdownGL();
- #if LL_WINDOWS
- void initWGL(HDC dc); // Initializes stupid WGL extensions
- #endif
- std::string getRawGLString(); // For sending to simulator
- void getPixelFormat(); // Get the best pixel format
- void printGLInfoString();
- void getGLInfo(LLSD& info);
- void asLLSD(LLSD& info);
- private:
- void initExtensions();
- void initGLStates();
- void initGLImages();
- public:
- S32 mDriverVersionMajor;
- S32 mDriverVersionMinor;
- S32 mDriverVersionRelease;
- F32 mGLVersion; // E.g = 3.2
- S32 mGLSLVersionMajor;
- S32 mGLSLVersionMinor;
- S32 mVRAM; // Total VRAM in MB
- S32 mTexVRAM; // VRAM reserved for textures in MB
- S32 mGLMaxVertexRange;
- S32 mGLMaxIndexRange;
- S32 mGLMaxTextureSize;
- std::string mDriverVersionVendorString;
- std::string mGLVersionString;
- // In ALL CAPS
- std::string mGLVendor;
- std::string mGLVendorShort;
- // In ALL CAPS
- std::string mGLRenderer;
- // Limits
- S32 mMaxSamples;
- S32 mNumTextureImageUnits;
- S32 mMaxUniformBlockSize;
- F32 mMaxAnisotropy;
- // Extensions
- #if LL_WINDOWS
- bool mHasAMDAssociations;
- #endif
- bool mHasATIMemInfo;
- bool mHasNVXMemInfo;
- bool mHasVertexArrayObject;
- bool mHasSync;
- bool mHasOcclusionQuery2;
- bool mHasTimerQuery;
- bool mHasDepthClamp;
- bool mUseDepthClamp;
- bool mHasAnisotropic;
- bool mHasCubeMapArray;
- bool mHasDebugOutput;
- bool mHasTextureSwizzle;
- bool mHasGpuShader4;
- bool mHasGpuShader5;
- // GPU vendor flags
- bool mIsAMD;
- bool mIsNVIDIA;
- bool mIsIntel;
- // Whether this version of GL is good enough for SL to use
- bool mHasRequirements;
- // Misc extensions
- bool mHasVertexAttribIPointer;
- bool mInited;
- bool mIsDisabled;
- };
- extern LLGLManager gGLManager;
- class LLQuaternion;
- class LLMatrix4;
- LL_NO_INLINE void log_glerror(const char* file, U32 line, bool crash = false);
- #if LL_DEBUG
- # define stop_glerror() if (LL_UNLIKELY(gDebugGL)) log_glerror(__FILE__, __LINE__, true)
- #else
- # define stop_glerror() if (LL_UNLIKELY(gDebugGL)) log_glerror(__FILE__, __LINE__)
- #endif
- void clear_glerror();
- // This is a class for GL state management
- /*
- GL STATE MANAGEMENT DESCRIPTION
- LLGLState and its two subclasses, LLGLEnable and LLGLDisable, manage the
- current enable/disable states of the GL to prevent redundant setting of
- state within a render path or the accidental corruption of what state the
- next path expects.
- Essentially, wherever you would call glEnable set a state and then
- subsequently reset it by calling glDisable (or vice versa), make an
- instance of LLGLEnable with the state you want to set, and assume it will
- be restored to its original state when that instance of LLGLEnable is
- destroyed. It is good practice to exploit stack frame controls for optimal
- setting/unsetting and readability of code. There are a collection of helper
- classes below that define groups of enables/disables and that can cause
- multiple states to be set with the creation of one instance.
- Sample usage:
- // Disable lighting for rendering hud objects:
- // INCORRECT USAGE
- LLGLEnable blend(GL_BLEND);
- renderHUD();
- LLGLDisable blend(GL_BLEND);
- // CORRECT USAGE
- {
- LLGLEnable blend(GL_BLEND);
- renderHUD();
- }
- If a state is to be set on a conditional, the following mechanism
- is useful:
- {
- LLGLEnable blend(blend_hud ? GL_BLEND : 0);
- renderHUD();
- }
- A LLGLState initialized with a parameter of 0 does nothing.
- LLGLState works by maintaining a map of the current GL states, and ignoring
- redundant enables/disables. If a redundant call is attempted, it becomes a
- noop, otherwise, it is set in the constructor and reset in the destructor.
- For debugging GL state corruption, running with debug enabled will trigger
- asserts if the existing GL state does not match the expected GL state.
- */
- class LLGLState
- {
- protected:
- LOG_CLASS(LLGLState);
- public:
- static void initClass();
- static void restoreGL();
- static void dumpStates();
-
- static void checkStates(const std::string& msg = LLStringUtil::null,
- S32 line = -1);
- #if 0 // Not used, but kept in source, just in case... HB
- // Really should not be needed.
- static void resetTextureStates();
- #endif
- protected:
- typedef fast_hmap<U32, GLboolean> state_map_t;
- static state_map_t sStateMap;
- public:
- enum { CURRENT_STATE = -2 };
- LLGLState(U32 state, S32 enabled = CURRENT_STATE);
- virtual ~LLGLState();
- void setEnabled(S32 enabled);
- LL_INLINE void enable() { setEnabled(GL_TRUE); }
- LL_INLINE void disable() { setEnabled(GL_FALSE); }
- protected:
- U32 mState;
- S32 mWasEnabled;
- S32 mIsEnabled;
- };
- // Helper define, to log the filename and line number of the checkStates()
- // call, whenever an error is detected. Unless you got a specific message to
- // pass on error, use this macro instead of LLGLState::checkStates(). HB
- #define LL_GL_CHECK_STATES LLGLState::checkStates(__FILE__, __LINE__)
- class LLGLEnable : public LLGLState
- {
- public:
- LL_INLINE LLGLEnable(U32 state)
- : LLGLState(state, GL_TRUE)
- {
- }
- };
- class LLGLDisable : public LLGLState
- {
- public:
- LL_INLINE LLGLDisable(U32 state)
- : LLGLState(state, GL_FALSE)
- {
- }
- };
- /*
- Store and modify projection matrix to create an oblique projection that clips
- to the specified plane. Oblique projections alter values in the depth buffer,
- so this class should not be used mid-renderpass.
- Restores projection matrix on destruction.
- GL_MODELVIEW_MATRIX is active whenever program execution leaves this class.
- Does not stack.
- */
- class alignas(16) LLGLUserClipPlane
- {
- public:
- LLGLUserClipPlane(const LLPlane& plane, const LLMatrix4a& modelview,
- const LLMatrix4a& projection, bool apply = true);
- ~LLGLUserClipPlane();
- void disable();
- void setPlane(F32 a, F32 b, F32 c, F32 d);
- private:
- LLMatrix4a mProjection;
- LLMatrix4a mModelview;
- bool mApply;
- };
- /*
- Modify and load projection matrix to push depth values to far clip plane.
- Restores projection matrix on destruction.
- Saves/restores matrix mode around projection manipulation.
- Does not stack.
- */
- class LLGLSquashToFarClip
- {
- public:
- LLGLSquashToFarClip(U32 layer = 0);
- ~LLGLSquashToFarClip();
- };
- /*
- Interface for objects that need periodic GL updates applied to them.
- Used to synchronize GL updates with GL thread.
- */
- class LLGLUpdate
- {
- public:
- LLGLUpdate()
- : mInQ(false)
- {
- }
- virtual ~LLGLUpdate()
- {
- if (mInQ)
- {
- std::list<LLGLUpdate*>::iterator end = sGLQ.end();
- std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(),
- end,
- this);
- if (iter != end)
- {
- sGLQ.erase(iter);
- }
- }
- }
- virtual void updateGL() = 0;
- public:
- static std::list<LLGLUpdate*> sGLQ;
- bool mInQ;
- };
- ///////////////////////////////////////////////////////////////////////////////
- // Formerly in llglstates.h, but since that header was #included by this one...
- ///////////////////////////////////////////////////////////////////////////////
- class LLGLDepthTest
- {
- protected:
- LOG_CLASS(LLGLDepthTest);
- public:
- // Enabled by default
- // Note: the new 'ignored' allows (when 'true' to make this class a no-
- // operation, so to simplify the dual renderer code. HB
- LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE,
- U32 depth_func = GL_LEQUAL, bool ignored = false);
- ~LLGLDepthTest();
- void checkState();
- public:
- U32 mPrevDepthFunc;
- GLboolean mPrevDepthEnabled;
- GLboolean mPrevWriteEnabled;
- private:
- bool mIgnored;
- static U32 sDepthFunc; // defaults to GL_LESS
- static GLboolean sDepthEnabled; // defaults to GL_FALSE
- static GLboolean sWriteEnabled; // defaults to GL_TRUE
- };
- class LLGLSDefault
- {
- public:
- LLGLSDefault()
- : // Disable
- mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE)
- {
- }
- protected:
- LLGLDisable mBlend;
- LLGLDisable mCullFace;
- };
- class LLGLSObjectSelect
- {
- public:
- LLGLSObjectSelect()
- : mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE)
- {
- }
- protected:
- LLGLDisable mBlend;
- LLGLEnable mCullFace;
- };
- class LLGLSUIDefault
- {
- public:
- LLGLSUIDefault()
- : mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE),
- mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL),
- mMSAA(GL_MULTISAMPLE)
- {
- }
- protected:
- LLGLEnable mBlend;
- LLGLDisable mCullFace;
- LLGLDepthTest mDepthTest;
- LLGLDisable mMSAA;
- };
- class LLGLSPipeline
- {
- public:
- LLGLSPipeline()
- : mCullFace(GL_CULL_FACE),
- mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL)
- {
- }
- protected:
- LLGLEnable mCullFace;
- LLGLDepthTest mDepthTest;
- };
- class LLGLSPipelineAlpha // : public LLGLSPipeline
- {
- public:
- LLGLSPipelineAlpha()
- : mBlend(GL_BLEND)
- {
- }
- protected:
- LLGLEnable mBlend;
- };
- class LLGLSPipelineSelection
- {
- public:
- LLGLSPipelineSelection()
- : mCullFace(GL_CULL_FACE)
- {
- }
- protected:
- LLGLDisable mCullFace;
- };
- class LLGLSPipelineSkyBox
- {
- public:
- LLGLSPipelineSkyBox();
- virtual ~LLGLSPipelineSkyBox() = default;
- protected:
- LLGLDisable mCullFace;
- LLGLSquashToFarClip mSquashClip;
- };
- class LLGLSPipelineDepthTestSkyBox : public LLGLSPipelineSkyBox
- {
- public:
- LLGLSPipelineDepthTestSkyBox(GLboolean depth_test, GLboolean depth_write);
- public:
- LLGLDepthTest mDepth;
- };
- class LLGLSPipelineBlendSkyBox : public LLGLSPipelineDepthTestSkyBox
- {
- public:
- LLGLSPipelineBlendSkyBox(GLboolean depth_test, GLboolean depth_write);
- public:
- LLGLEnable mBlend;
- };
- class LLGLSTracker
- {
- public:
- LLGLSTracker()
- : mCullFace(GL_CULL_FACE),
- mBlend(GL_BLEND)
- {
- }
- protected:
- LLGLEnable mCullFace;
- LLGLEnable mBlend;
- };
- class LLGLSSpecular
- {
- public:
- LLGLSSpecular(const LLColor4& color, F32 shininess)
- {
- mShininess = shininess;
- if (mShininess > 0.f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV);
- S32 shiny = (S32)(shininess * 128.f);
- shiny = llclamp(shiny, 0, 128);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny);
- }
- }
- ~LLGLSSpecular()
- {
- if (mShininess > 0.f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
- LLColor4::transparent.mV);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
- }
- }
- public:
- F32 mShininess;
- };
- ///////////////////////////////////////////////////////////////////////////////
- const std::string getGLErrorString(U32 error);
- #endif // LL_LLGL_H
|