477 lines
11 KiB
C++
477 lines
11 KiB
C++
/**
|
|
* @file llgl.h
|
|
* @brief LLGL definition
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#ifndef LL_LLGL_H
|
|
#define LL_LLGL_H
|
|
|
|
// This file contains various stuff for handling gl extensions and other gl related stuff.
|
|
|
|
#include <string>
|
|
#include <boost/unordered_map.hpp>
|
|
#include <list>
|
|
|
|
#include "llerror.h"
|
|
#include "v4color.h"
|
|
#include "llstring.h"
|
|
#include "stdtypes.h"
|
|
#include "v4math.h"
|
|
#include "llplane.h"
|
|
#include "llgltypes.h"
|
|
#include "llinstancetracker.h"
|
|
|
|
#include "llglheaders.h"
|
|
#include "glh/glh_linear.h"
|
|
|
|
extern BOOL gDebugGL;
|
|
extern BOOL gDebugSession;
|
|
extern BOOL gDebugGLSession;
|
|
extern llofstream gFailLog;
|
|
|
|
#define LL_GL_ERRS LL_ERRS("RenderState")
|
|
|
|
void ll_init_fail_log(std::string filename);
|
|
|
|
void ll_fail(std::string msg);
|
|
|
|
void ll_close_fail_log();
|
|
|
|
class LLSD;
|
|
|
|
// Manage GL extensions...
|
|
class LLGLManager
|
|
{
|
|
public:
|
|
LLGLManager();
|
|
|
|
bool initGL();
|
|
void shutdownGL();
|
|
|
|
void initWGL(); // Initializes stupid WGL extensions
|
|
|
|
std::string getRawGLString(); // For sending to simulator
|
|
|
|
BOOL mInited;
|
|
BOOL mIsDisabled;
|
|
|
|
// OpenGL limits
|
|
S32 mMaxSamples;
|
|
S32 mNumTextureImageUnits;
|
|
S32 mMaxSampleMaskWords;
|
|
S32 mMaxColorTextureSamples;
|
|
S32 mMaxDepthTextureSamples;
|
|
S32 mMaxIntegerSamples;
|
|
S32 mGLMaxVertexRange;
|
|
S32 mGLMaxIndexRange;
|
|
S32 mGLMaxTextureSize;
|
|
F32 mMaxAnisotropy = 0.f;
|
|
|
|
// GL 4.x capabilities
|
|
bool mHasCubeMapArray = false;
|
|
bool mHasDebugOutput = false;
|
|
bool mHasTransformFeedback = false;
|
|
bool mHasAnisotropic = false;
|
|
|
|
// Vendor-specific extensions
|
|
bool mHasAMDAssociations = false;
|
|
|
|
BOOL mIsAMD;
|
|
BOOL mIsNVIDIA;
|
|
BOOL mIsIntel;
|
|
|
|
#if LL_DARWIN
|
|
// Needed to distinguish problem cards on older Macs that break with Materials
|
|
BOOL mIsMobileGF;
|
|
#endif
|
|
|
|
// Whether this version of GL is good enough for SL to use
|
|
BOOL mHasRequirements;
|
|
|
|
S32 mDriverVersionMajor;
|
|
S32 mDriverVersionMinor;
|
|
S32 mDriverVersionRelease;
|
|
F32 mGLVersion; // e.g = 1.4
|
|
S32 mGLSLVersionMajor;
|
|
S32 mGLSLVersionMinor;
|
|
std::string mDriverVersionVendorString;
|
|
std::string mGLVersionString;
|
|
|
|
S32 mVRAM; // VRAM in MB
|
|
|
|
void getPixelFormat(); // Get the best pixel format
|
|
|
|
std::string getGLInfoString();
|
|
void printGLInfoString();
|
|
void getGLInfo(LLSD& info);
|
|
|
|
void asLLSD(LLSD& info);
|
|
|
|
// In ALL CAPS
|
|
std::string mGLVendor;
|
|
std::string mGLVendorShort;
|
|
|
|
// In ALL CAPS
|
|
std::string mGLRenderer;
|
|
|
|
private:
|
|
void initExtensions();
|
|
void initGLStates();
|
|
void initGLImages();
|
|
};
|
|
|
|
extern LLGLManager gGLManager;
|
|
|
|
class LLQuaternion;
|
|
class LLMatrix4;
|
|
|
|
void rotate_quat(LLQuaternion& rotation);
|
|
|
|
void flush_glerror(); // Flush GL errors when we know we're handling them correctly.
|
|
|
|
void log_glerror();
|
|
void assert_glerror();
|
|
|
|
void clear_glerror();
|
|
|
|
//#if LL_DEBUG
|
|
# define stop_glerror() assert_glerror()
|
|
# define llglassertok() assert_glerror()
|
|
//#else
|
|
//# define stop_glerror()
|
|
//# define llglassertok()
|
|
//#endif
|
|
|
|
#define llglassertok_always() assert_glerror()
|
|
|
|
////////////////////////
|
|
//
|
|
// Note: U32's are GLEnum's...
|
|
//
|
|
|
|
// 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. In llglstates.h, there are a collection of helper classes that define groups
|
|
of enables/disables 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 lighting(GL_LIGHTING);
|
|
renderHUD();
|
|
LLGLDisable lighting(GL_LIGHTING);
|
|
|
|
//CORRECT USAGE
|
|
{
|
|
LLGLEnable lighting(GL_LIGHTING);
|
|
renderHUD();
|
|
}
|
|
|
|
If a state is to be set on a conditional, the following mechanism
|
|
is useful:
|
|
|
|
{
|
|
LLGLEnable lighting(light_hud ? GL_LIGHTING : 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.
|
|
|
|
*/
|
|
|
|
#include "boost/function.hpp"
|
|
|
|
class LLGLState
|
|
{
|
|
public:
|
|
static void initClass();
|
|
static void restoreGL();
|
|
|
|
static void resetTextureStates();
|
|
static void dumpStates();
|
|
|
|
// make sure GL blend function, GL states, and GL color mask match
|
|
// what we expect
|
|
// writeAlpha - whether or not writing to alpha channel is expected
|
|
static void checkStates(GLboolean writeAlpha = GL_TRUE);
|
|
|
|
protected:
|
|
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
|
|
|
|
public:
|
|
enum { CURRENT_STATE = -2 };
|
|
LLGLState(LLGLenum state, S32 enabled = CURRENT_STATE);
|
|
~LLGLState();
|
|
void setEnabled(S32 enabled);
|
|
void enable() { setEnabled(TRUE); }
|
|
void disable() { setEnabled(FALSE); }
|
|
protected:
|
|
LLGLenum mState;
|
|
BOOL mWasEnabled;
|
|
BOOL mIsEnabled;
|
|
};
|
|
|
|
// New LLGLState class wrappers that don't depend on actual GL flags.
|
|
class LLGLEnableBlending : public LLGLState
|
|
{
|
|
public:
|
|
LLGLEnableBlending(bool enable);
|
|
};
|
|
|
|
class LLGLEnableAlphaReject : public LLGLState
|
|
{
|
|
public:
|
|
LLGLEnableAlphaReject(bool enable);
|
|
};
|
|
|
|
// Enable with functor
|
|
class LLGLEnableFunc : LLGLState
|
|
{
|
|
public:
|
|
LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
|
|
: LLGLState(state, enable)
|
|
{
|
|
if (enable)
|
|
{
|
|
func();
|
|
}
|
|
}
|
|
};
|
|
|
|
/// TODO: Being deprecated.
|
|
class LLGLEnable : public LLGLState
|
|
{
|
|
public:
|
|
LLGLEnable(LLGLenum state) : LLGLState(state, TRUE) {}
|
|
};
|
|
|
|
/// TODO: Being deprecated.
|
|
class LLGLDisable : public LLGLState
|
|
{
|
|
public:
|
|
LLGLDisable(LLGLenum state) : LLGLState(state, 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.
|
|
Caches inverse of projection matrix used in gGLObliqueProjectionInverse
|
|
*/
|
|
class LLGLUserClipPlane
|
|
{
|
|
public:
|
|
|
|
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true);
|
|
~LLGLUserClipPlane();
|
|
|
|
void setPlane(F32 a, F32 b, F32 c, F32 d);
|
|
void disable();
|
|
|
|
private:
|
|
bool mApply;
|
|
|
|
glh::matrix4f mProjection;
|
|
glh::matrix4f mModelview;
|
|
};
|
|
|
|
/*
|
|
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();
|
|
LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
|
|
|
|
void setProjectionMatrix(glh::matrix4f& projection, U32 layer);
|
|
|
|
~LLGLSquashToFarClip();
|
|
};
|
|
|
|
/*
|
|
Interface for objects that need periodic GL updates applied to them.
|
|
Used to synchronize GL updates with GL thread.
|
|
*/
|
|
class LLGLUpdate
|
|
{
|
|
public:
|
|
|
|
static std::list<LLGLUpdate*> sGLQ;
|
|
|
|
BOOL mInQ;
|
|
LLGLUpdate()
|
|
: mInQ(FALSE)
|
|
{
|
|
}
|
|
virtual ~LLGLUpdate()
|
|
{
|
|
if (mInQ)
|
|
{
|
|
std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
|
|
if (iter != sGLQ.end())
|
|
{
|
|
sGLQ.erase(iter);
|
|
}
|
|
}
|
|
}
|
|
virtual void updateGL() = 0;
|
|
};
|
|
|
|
const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms
|
|
|
|
class LLGLFence
|
|
{
|
|
public:
|
|
virtual ~LLGLFence()
|
|
{
|
|
}
|
|
|
|
virtual void placeFence() = 0;
|
|
virtual bool isCompleted() = 0;
|
|
virtual void wait() = 0;
|
|
};
|
|
|
|
class LLGLSyncFence : public LLGLFence
|
|
{
|
|
public:
|
|
GLsync mSync;
|
|
|
|
LLGLSyncFence();
|
|
virtual ~LLGLSyncFence();
|
|
|
|
void placeFence();
|
|
bool isCompleted();
|
|
void wait();
|
|
};
|
|
|
|
extern LLMatrix4 gGLObliqueProjectionInverse;
|
|
|
|
#include "llglstates.h"
|
|
|
|
void init_glstates();
|
|
|
|
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
|
|
|
|
extern BOOL gClothRipple;
|
|
extern BOOL gHeadlessClient;
|
|
extern BOOL gNonInteractive;
|
|
extern BOOL gGLActive;
|
|
|
|
// Deal with changing glext.h definitions for newer SDK versions, specifically
|
|
// with MAC OSX 10.5 -> 10.6
|
|
|
|
|
|
#ifndef GL_DEPTH_ATTACHMENT
|
|
#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
|
|
#endif
|
|
|
|
#ifndef GL_STENCIL_ATTACHMENT
|
|
#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
|
#endif
|
|
|
|
#ifndef GL_FRAMEBUFFER
|
|
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
|
#define GL_DRAW_FRAMEBUFFER GL_DRAW_FRAMEBUFFER_EXT
|
|
#define GL_READ_FRAMEBUFFER GL_READ_FRAMEBUFFER_EXT
|
|
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
|
#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
|
|
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
|
|
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
|
|
#define glGenFramebuffers glGenFramebuffersEXT
|
|
#define glBindFramebuffer glBindFramebufferEXT
|
|
#define glCheckFramebufferStatus glCheckFramebufferStatusEXT
|
|
#define glBlitFramebuffer glBlitFramebufferEXT
|
|
#define glDeleteFramebuffers glDeleteFramebuffersEXT
|
|
#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT
|
|
#define glFramebufferTexture2D glFramebufferTexture2DEXT
|
|
#endif
|
|
|
|
#ifndef GL_RENDERBUFFER
|
|
#define GL_RENDERBUFFER GL_RENDERBUFFER_EXT
|
|
#define glGenRenderbuffers glGenRenderbuffersEXT
|
|
#define glBindRenderbuffer glBindRenderbufferEXT
|
|
#define glRenderbufferStorage glRenderbufferStorageEXT
|
|
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
|
|
#define glDeleteRenderbuffers glDeleteRenderbuffersEXT
|
|
#endif
|
|
|
|
#ifndef GL_COLOR_ATTACHMENT
|
|
#define GL_COLOR_ATTACHMENT GL_COLOR_ATTACHMENT_EXT
|
|
#endif
|
|
|
|
#ifndef GL_COLOR_ATTACHMENT0
|
|
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
|
#endif
|
|
|
|
#ifndef GL_COLOR_ATTACHMENT1
|
|
#define GL_COLOR_ATTACHMENT1 GL_COLOR_ATTACHMENT1_EXT
|
|
#endif
|
|
|
|
#ifndef GL_COLOR_ATTACHMENT2
|
|
#define GL_COLOR_ATTACHMENT2 GL_COLOR_ATTACHMENT2_EXT
|
|
#endif
|
|
|
|
#ifndef GL_COLOR_ATTACHMENT3
|
|
#define GL_COLOR_ATTACHMENT3 GL_COLOR_ATTACHMENT3_EXT
|
|
#endif
|
|
|
|
|
|
#ifndef GL_DEPTH24_STENCIL8
|
|
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
|
#endif
|
|
|
|
#endif // LL_LLGL_H
|