>From 9a6322e5b6fd2bdee3522ff0d728524d4e7042ba Mon Sep 17 00:00:00 2001
From: Frederic Plourde <[email protected]>
Date: Tue, 20 Sep 2011 14:41:35 -0400
Subject: [PATCH 2/3] Add GLUniform per-plugin mechanism
Currently, the openGL plugin binds the active program in GLWindow::
glDrawTexture (). Since this is the last plugin-hookable function
before hitting priv->vertexBuffer->render (), plugins are currently
unable to set GL uniforms within their respective ::glDrawTexture
callback because the main shaders are not yet compiled and bound.
This patch adds "addUniform{...}" facilities to the GLVertexBuffer
class. Since vertexBuffer is the only way for plugins to draw
things, it seems reasonable to hook the uniform list directly in
GLVertexBuffer.
---
plugins/opengl/include/opengl/vertexbuffer.h | 13 ++++
plugins/opengl/src/privatevertexbuffer.h | 65 ++++++++++++++++++
plugins/opengl/src/vertexbuffer.cpp | 93
++++++++++++++++++++++++++
3 files changed, 171 insertions(+), 0 deletions(-)
diff --git a/plugins/opengl/include/opengl/vertexbuffer.h
b/plugins/opengl/include/opengl/vertexbuffer.h
index f819685..57ad79d 100644
--- a/plugins/opengl/include/opengl/vertexbuffer.h
+++ b/plugins/opengl/include/opengl/vertexbuffer.h
@@ -21,6 +21,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Travis Watkins <[email protected]>
+ * Frederic Plourde <[email protected]>
*/
#ifndef _COMPIZ_GLVERTEXBUFFER_H
@@ -64,6 +65,18 @@ class GLVertexBuffer
GLuint nTexcoords,
GLfloat *texcoords);
+ void addUniform (const char *name, GLfloat value);
+ void addUniform (const char *name, GLint value);
+ bool addUniform (const char *name, const GLMatrix &value);
+ void addUniform2f (const char *name, GLfloat x, GLfloat y);
+ void addUniform3f (const char *name, GLfloat x, GLfloat y, GLfloat z);
+ void addUniform4f (const char *name, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w);
+ void addUniform2i (const char *name, GLint x, GLint y);
+ void addUniform3i (const char *name, GLint x, GLint y, GLint z);
+ void addUniform4i (const char *name, GLint x, GLint y,
+ GLint z, GLint w);
+
void setProgram (GLProgram *program);
int render (const GLMatrix &modelview);
diff --git a/plugins/opengl/src/privatevertexbuffer.h
b/plugins/opengl/src/privatevertexbuffer.h
index bcab776..b91253a 100644
--- a/plugins/opengl/src/privatevertexbuffer.h
+++ b/plugins/opengl/src/privatevertexbuffer.h
@@ -21,6 +21,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Travis Watkins <[email protected]>
+ * Frederic Plourde <[email protected]>
*/
#ifndef _VERTEXBUFFER_PRIVATE_H
@@ -33,6 +34,69 @@
#endif
#include <opengl/program.h>
+#include <typeinfo>
+
+class GLVertexBuffer;
+
+class AbstractUniform
+{
+ public:
+ void virtual set(GLProgram* program) = 0;
+};
+
+template < typename T, int C >
+class Uniform: public AbstractUniform
+{
+ public:
+ Uniform(const char *_name, ... );
+ void set(GLProgram* program);
+
+ public:
+ T a[C];
+ std::string name;
+};
+
+template < typename T, int C >
+Uniform< T, C >::Uniform(const char *_name, ... )
+{
+ va_list arg_list;
+ va_start( arg_list, _name );
+ name = _name;
+ for( int i = 0; i < C; i++ )
+ a[i] = va_arg( arg_list, T );
+ va_end( arg_list );
+}
+
+template < typename T, int C >
+void Uniform< T, C >::set(GLProgram* prog)
+{
+ const char* n = name.c_str();
+
+ // This will only get called from privateVertexBuffer::render
+ // so we know we've got a valid, bound program here
+ if (typeid(a[0]) == typeid(double))
+ {
+ switch ( (sizeof( a )) / (sizeof( double )) )
+ {
+ case 1: prog->setUniform (n, (GLfloat) a[0]); break;
+ case 2: prog->setUniform2f (n, a[0], a[1]); break;
+ case 3: prog->setUniform3f (n, a[0], a[1], a[2]); break;
+ case 4: prog->setUniform4f (n, a[0], a[1], a[2], a[3]); break;
+ }
+ } else if (typeid(a[0]) == typeid(int))
+ {
+ switch ( (sizeof( a )) / (sizeof( int )) )
+ {
+ case 1: prog->setUniform (n, (GLint) a[0]); break;
+ case 2: prog->setUniform2i (n, a[0], a[1]); break;
+ case 3: prog->setUniform3i (n, a[0], a[1], a[2]); break;
+ case 4: prog->setUniform4i (n, a[0], a[1], a[2], a[3]); break;
+ }
+ } else
+ {
+ printf ("Error !! unknown uniform type !\n");
+ }
+}
class GLVertexBuffer;
@@ -65,6 +129,7 @@ class PrivateVertexBuffer
GLuint normalBuffer;
GLuint colorBuffer;
GLuint textureBuffers[4];
+ std::vector<AbstractUniform*> uniforms;
};
#endif //_VERTEXBUFFER_PRIVATE_H
diff --git a/plugins/opengl/src/vertexbuffer.cpp
b/plugins/opengl/src/vertexbuffer.cpp
index b99b44f..c7bb38b 100644
--- a/plugins/opengl/src/vertexbuffer.cpp
+++ b/plugins/opengl/src/vertexbuffer.cpp
@@ -21,6 +21,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: Travis Watkins <[email protected]>
+ * Frederic Plourde <[email protected]>
*/
#include <vector>
@@ -72,6 +73,7 @@ void GLVertexBuffer::begin (GLenum primitiveType)
priv->normalData.clear ();
priv->colorData.clear ();
priv->textureData.clear ();
+ priv->uniforms.clear ();
}
void GLVertexBuffer::begin ()
@@ -177,6 +179,91 @@ void GLVertexBuffer::addTexCoords (GLuint texture,
}
}
+void GLVertexBuffer::addUniform (const char *name, GLfloat value)
+{
+ // we're casting to double here to make our template va_arg happy
+ Uniform<double, 1>* uniform = new Uniform<double, 1>(name,
(double)value);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform (const char *name, GLint value)
+{
+ Uniform<GLint, 1>* uniform = new Uniform<GLint, 1>(name, value);
+ priv->uniforms.push_back (uniform);
+}
+
+bool GLVertexBuffer::addUniform (const char *name, const GLMatrix &value)
+{
+ #warning Add 'addUniform' support to GLMatrix type !
+ return true;
+}
+
+void GLVertexBuffer::addUniform2f (const char *name,
+ GLfloat x,
+ GLfloat y)
+{
+ // we're casting to double here to make our template va_arg happy
+ Uniform<double, 2>* uniform = new Uniform<double, 2>(name,
+ (double)x,
+ (double)y);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform3f (const char *name,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ // we're casting to double here to make our template va_arg happy
+ Uniform<double, 3>* uniform = new Uniform<double, 3>(name,
+ (double)x,
+ (double)y,
+ (double)z);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform4f (const char *name,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w)
+{
+ // we're casting to double here to make our template va_arg happy
+ Uniform<double, 4>* uniform = new Uniform<double, 4>(name,
+ (double)x,
+ (double)y,
+ (double)z,
+ (double)w);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform2i (const char *name,
+ GLint x,
+ GLint y)
+{
+ Uniform<GLint, 2>* uniform = new Uniform<GLint, 2>(name, x, y);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform3i (const char *name,
+ GLint x,
+ GLint y,
+ GLint z)
+{
+ Uniform<GLint, 3>* uniform = new Uniform<GLint, 3>(name, x, y, z);
+ priv->uniforms.push_back (uniform);
+}
+
+void GLVertexBuffer::addUniform4i (const char *name,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w)
+{
+ Uniform<GLint, 4>* uniform = new Uniform<GLint, 4>(name, x, y, z, w);
+ priv->uniforms.push_back (uniform);
+}
+
void GLVertexBuffer::setProgram (GLProgram *program)
{
priv->program = program;
@@ -322,6 +409,12 @@ int PrivateVertexBuffer::render (const
GLMatrix &projection,
program->setUniform (name, i);
}
+ // set per-plugin uniforms
+ for (int i = 0; i < uniforms.size (); i++)
+ {
+ uniforms[i]->set (program);
+ }
+
//convert paint attribs to 0-1 range
attribs[0] = attrib.opacity / 65535.0f;
attribs[1] = attrib.brightness / 65535.0f;
--
1.7.4.1
_______________________________________________
dev mailing list
[email protected]
http://lists.compiz.org/mailman/listinfo/dev