make it possible to easily have variants of glsl programs
Now it's possible to add a preamble to the compiled program, so there can be just one program with #ifdef's inside and the small variants can be selected using #define in the preamble instead of having several almost identical programs. Change-Id: I6c5112313b91b6269ebdecdfc896e0f96209ea2b
This commit is contained in:
@@ -161,8 +161,6 @@ struct GLWindow
|
||||
~GLWindow();
|
||||
};
|
||||
|
||||
typedef std::pair<OUString, OUString> ProgramKey;
|
||||
|
||||
class VCLOPENGL_DLLPUBLIC OpenGLContext
|
||||
{
|
||||
public:
|
||||
@@ -203,8 +201,8 @@ public:
|
||||
void ReleaseFramebuffers();
|
||||
|
||||
// retrieve a program from the cache or compile/link it
|
||||
OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
|
||||
OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
|
||||
OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
|
||||
OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
|
||||
|
||||
bool isCurrent();
|
||||
static void clearCurrent();
|
||||
@@ -266,6 +264,14 @@ private:
|
||||
OpenGLFramebuffer* mpFirstFramebuffer;
|
||||
OpenGLFramebuffer* mpLastFramebuffer;
|
||||
|
||||
struct ProgramKey
|
||||
{
|
||||
ProgramKey( const OUString& vertexShader, const OUString& fragmentShader, const OString& preamble );
|
||||
bool operator< ( const ProgramKey& other ) const;
|
||||
OUString vertexShader;
|
||||
OUString fragmentShader;
|
||||
OString preamble;
|
||||
};
|
||||
boost::ptr_map<ProgramKey, OpenGLProgram> maPrograms;
|
||||
OpenGLProgram* mpCurrentProgram;
|
||||
#ifdef DBG_UTIL
|
||||
|
@@ -25,7 +25,7 @@
|
||||
class VCLOPENGL_DLLPUBLIC OpenGLHelper
|
||||
{
|
||||
public:
|
||||
static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName);
|
||||
static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName, const OString& preamble = "" );
|
||||
|
||||
/**
|
||||
* The caller is responsible for allocate the memory for the RGBA buffer, before call
|
||||
|
@@ -43,7 +43,7 @@ public:
|
||||
OpenGLProgram();
|
||||
~OpenGLProgram();
|
||||
|
||||
bool Load( const OUString& rVertexShader, const OUString& rFragmentShader );
|
||||
bool Load( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
|
||||
bool Use();
|
||||
bool Clean();
|
||||
|
||||
|
@@ -73,7 +73,7 @@ protected:
|
||||
bool CheckOffscreenTexture();
|
||||
|
||||
public:
|
||||
bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
|
||||
bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
|
||||
bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
|
||||
bool UseSolid( SalColor nColor, double fTransparency );
|
||||
bool UseSolid( SalColor nColor );
|
||||
|
@@ -373,11 +373,11 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
|
||||
bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
|
||||
{
|
||||
if( mpProgram != NULL )
|
||||
mpProgram->Clean();
|
||||
mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader );
|
||||
mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader, preamble );
|
||||
#ifdef DBG_UTIL
|
||||
mProgramIsSolidColor = false; // UseSolid() will set to true if needed
|
||||
#endif
|
||||
|
@@ -31,9 +31,9 @@ OpenGLProgram::~OpenGLProgram()
|
||||
glDeleteProgram( mnId );
|
||||
}
|
||||
|
||||
bool OpenGLProgram::Load( const OUString& rVertexShader, const OUString& rFragmentShader )
|
||||
bool OpenGLProgram::Load( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
|
||||
{
|
||||
mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader );
|
||||
mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader, preamble );
|
||||
return ( mnId != 0 );
|
||||
}
|
||||
|
||||
|
@@ -1582,9 +1582,9 @@ void OpenGLContext::ReleaseFramebuffers()
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
|
||||
OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
|
||||
{
|
||||
ProgramKey aKey( rVertexShader, rFragmentShader );
|
||||
ProgramKey aKey( rVertexShader, rFragmentShader, preamble );
|
||||
|
||||
boost::ptr_map<ProgramKey, OpenGLProgram>::iterator
|
||||
it = maPrograms.find( aKey );
|
||||
@@ -1592,7 +1592,7 @@ OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const O
|
||||
return it->second;
|
||||
|
||||
OpenGLProgram* pProgram = new OpenGLProgram;
|
||||
if( !pProgram->Load( rVertexShader, rFragmentShader ) )
|
||||
if( !pProgram->Load( rVertexShader, rFragmentShader, preamble ) )
|
||||
{
|
||||
delete pProgram;
|
||||
return NULL;
|
||||
@@ -1602,9 +1602,9 @@ OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const O
|
||||
return pProgram;
|
||||
}
|
||||
|
||||
OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
|
||||
OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble )
|
||||
{
|
||||
OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader );
|
||||
OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
|
||||
|
||||
if( pProgram == mpCurrentProgram )
|
||||
return pProgram;
|
||||
@@ -1615,4 +1615,20 @@ OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const O
|
||||
return mpCurrentProgram;
|
||||
}
|
||||
|
||||
inline
|
||||
OpenGLContext::ProgramKey::ProgramKey( const OUString& v, const OUString& f, const OString& p )
|
||||
: vertexShader( v ), fragmentShader( f ), preamble( p )
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
bool OpenGLContext::ProgramKey::operator< ( const ProgramKey& other ) const
|
||||
{
|
||||
if( vertexShader != other.vertexShader )
|
||||
return vertexShader < other.vertexShader;
|
||||
if( fragmentShader != other.fragmentShader )
|
||||
return fragmentShader < other.fragmentShader;
|
||||
return preamble < other.preamble;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
@@ -97,7 +97,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName)
|
||||
GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString& rFragmentShaderName, const OString& preamble)
|
||||
{
|
||||
// Create the shaders
|
||||
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
@@ -107,6 +107,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
|
||||
|
||||
// Compile Vertex Shader
|
||||
OString aVertexShaderSource = loadShader(rVertexShaderName);
|
||||
if( !preamble.isEmpty())
|
||||
aVertexShaderSource = preamble + "\n" + aVertexShaderSource;
|
||||
char const * VertexSourcePointer = aVertexShaderSource.getStr();
|
||||
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
|
||||
glCompileShader(VertexShaderID);
|
||||
@@ -119,6 +121,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
|
||||
|
||||
// Compile Fragment Shader
|
||||
OString aFragmentShaderSource = loadShader(rFragmentShaderName);
|
||||
if( !preamble.isEmpty())
|
||||
aFragmentShaderSource = preamble + "\n" + aFragmentShaderSource;
|
||||
char const * FragmentSourcePointer = aFragmentShaderSource.getStr();
|
||||
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
|
||||
glCompileShader(FragmentShaderID);
|
||||
|
Reference in New Issue
Block a user