>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

Reply via email to