summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lang <langal@cip.ifi.lmu.de>2010-08-26 06:10:59 +0200
committerAlexander Lang <langal@cip.ifi.lmu.de>2010-08-26 06:10:59 +0200
commit7ae12de602eccb92bde874fae9c08139c00509a9 (patch)
tree8abdab3e355b14c3b0f45c11fc9df1969b4c786a
parent12c67914c6173e3af7381d916b2927bc2584cc48 (diff)
downloadglsl-7ae12de602eccb92bde874fae9c08139c00509a9.tar.gz
glsl-7ae12de602eccb92bde874fae9c08139c00509a9.tar.bz2
A simple Plugin that loads GLSLshaders and displays a GLSL-shaded quad
-rw-r--r--CompizShader/CMakeLists.txt5
-rw-r--r--CompizShader/shader.xml.in14
-rw-r--r--CompizShader/shader_fragment_simple4
-rwxr-xr-xCompizShader/shader_vertex4
-rw-r--r--CompizShader/src/shader.cpp302
-rw-r--r--CompizShader/src/shader.h64
6 files changed, 393 insertions, 0 deletions
diff --git a/CompizShader/CMakeLists.txt b/CompizShader/CMakeLists.txt
new file mode 100644
index 0000000..2ddf69d
--- /dev/null
+++ b/CompizShader/CMakeLists.txt
@@ -0,0 +1,5 @@
+find_package (Compiz REQUIRED)
+
+include (CompizPlugin)
+
+compiz_plugin (shader PLUGINDEPS composite opengl LIBRARIES ${OPENGL_gl_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR})
diff --git a/CompizShader/shader.xml.in b/CompizShader/shader.xml.in
new file mode 100644
index 0000000..a6288be
--- /dev/null
+++ b/CompizShader/shader.xml.in
@@ -0,0 +1,14 @@
+<compiz>
+ <plugin name="shader" useBcop="true">
+ <_short>Shader plugin</_short>
+ <_long>Draws a shaded quad on top of all windows</_long>
+ <category>Effects</category>
+ <deps>
+ <requirement>
+ <plugin>composite</plugin>
+ <plugin>opengl</plugin>
+ </requirement>
+ </deps>
+ </plugin>
+</compiz>
+
diff --git a/CompizShader/shader_fragment_simple b/CompizShader/shader_fragment_simple
new file mode 100644
index 0000000..5dba13d
--- /dev/null
+++ b/CompizShader/shader_fragment_simple
@@ -0,0 +1,4 @@
+void main()
+{
+ gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
+}
diff --git a/CompizShader/shader_vertex b/CompizShader/shader_vertex
new file mode 100755
index 0000000..00ea36f
--- /dev/null
+++ b/CompizShader/shader_vertex
@@ -0,0 +1,4 @@
+void main()
+{
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+} \ No newline at end of file
diff --git a/CompizShader/src/shader.cpp b/CompizShader/src/shader.cpp
new file mode 100644
index 0000000..063c7c0
--- /dev/null
+++ b/CompizShader/src/shader.cpp
@@ -0,0 +1,302 @@
+
+#include "shader.h"
+#include <GL/glext.h>
+#include <iostream>
+#include <fstream>
+
+COMPIZ_PLUGIN_20090315 (shader, ShaderPluginVTable);
+
+PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
+PFNGLUSEPROGRAMPROC glUseProgram = NULL;
+PFNGLCREATESHADERPROC glCreateShader = NULL;
+PFNGLSHADERSOURCEPROC glShaderSource = NULL;
+PFNGLCOMPILESHADERPROC glCompileShader = NULL;
+PFNGLATTACHSHADERPROC glAttachShader = NULL;
+PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
+PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
+PFNGLUNIFORM1IPROC glUniform1i = NULL;
+PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
+PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
+PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
+PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
+PFNGLDELETESHADERPROC glDeleteShader = NULL;
+PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL;
+
+bool
+ShaderScreen::queryForShader()
+{
+ glCreateProgram = (PFNGLCREATEPROGRAMPROC) gScreen->getProcAddress ("glCreateProgram");
+ glUseProgram = (PFNGLUSEPROGRAMPROC) gScreen->getProcAddress ("glUseProgram");
+ glCreateShader = (PFNGLCREATESHADERPROC) gScreen->getProcAddress ("glCreateShader");
+ glShaderSource = (PFNGLSHADERSOURCEPROC) gScreen->getProcAddress ("glShaderSource");
+ glCompileShader = (PFNGLCOMPILESHADERPROC) gScreen->getProcAddress ("glCompileShader");
+ glAttachShader = (PFNGLATTACHSHADERPROC) gScreen->getProcAddress ("glAttachShader");
+ glLinkProgram = (PFNGLLINKPROGRAMPROC) gScreen->getProcAddress ("glLinkProgram");
+ glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) gScreen->getProcAddress ("glGetUniformLocation");
+ glUniform1i = (PFNGLUNIFORM1IPROC) gScreen->getProcAddress ("glUniform1i");
+ glGetShaderiv = (PFNGLGETSHADERIVPROC) gScreen->getProcAddress ("glGetShaderiv");
+ glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) gScreen->getProcAddress ("glGetShaderInfoLog");
+ glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) gScreen->getProcAddress ("glGetProgramInfoLog");
+ glGetProgramiv = (PFNGLGETPROGRAMIVPROC) gScreen->getProcAddress ("glGetProgramiv");
+ glDeleteShader = (PFNGLDELETESHADERPROC) gScreen->getProcAddress ("glDeleteShader");
+ glDeleteProgram = (PFNGLDELETEPROGRAMPROC) gScreen->getProcAddress ("glDeleteProgram");
+
+ if (!(glUseProgram &&
+ glCreateShader &&
+ glShaderSource &&
+ glCompileShader &&
+ glGetShaderiv &&
+ glGetShaderInfoLog &&
+ glDeleteShader &&
+ glDeleteProgram &&
+ glCreateProgram &&
+ glAttachShader &&
+ glLinkProgram &&
+ glGetProgramiv &&
+ glGetProgramInfoLog &&
+ glGetUniformLocation &&
+ glUniform1i))
+ {
+ return false;
+ }
+ return true;
+}
+
+GLuint
+ShaderScreen::loadShader(std::string& fileName, GLuint type)
+{
+ std::string strData;
+ std::ifstream fileStream;
+ fileStream.open(fileName.c_str());
+
+ if(!fileStream)
+ {
+ std::cerr << "File " << fileName.c_str() << " could not be opened\n";
+ return 0;
+ }
+ getline(fileStream, strData, fileStream.widen('\255'));
+ fileStream.close();
+
+ GLuint shader;
+ shader = glCreateShader(type);
+ if (shader == 0) //works with nVidia, fails with fglrx
+ {
+ std::cerr << "Shader is: " << shader << std::endl;
+ return 0;
+ }
+
+ GLenum error = glGetError();
+ while (error != GL_NO_ERROR)
+ {
+ std::cout << "Error: " << error << std::endl;
+ if (error == GL_INVALID_ENUM)
+ std::cout << "GL_INVALID_ENUM" << std::endl;
+ if (error == GL_INVALID_OPERATION)
+ std::cout << "GL_INVALID_OPERATION" << std::endl;
+ error = glGetError();
+ }
+ const char* src = strData.c_str();
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader(shader);
+
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+
+// GLsizei length_;
+// glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length_);
+// GLchar* log_ = new GLchar[length_];
+// glGetShaderInfoLog(shader,length,&length_,log);
+// std::cerr << "Shader Info : " << log_ << "\n";
+ if(!compiled)
+ {
+ GLsizei length;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+ GLchar* log = new GLchar[length];
+ glGetShaderInfoLog(shader,length,&length,log);
+ std::cerr << "Shader Compile Error : " << log << "\n";
+ delete log;
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ return shader;
+}
+
+void
+ShaderScreen::clearShader()
+{
+ if (vertexShader != 0)
+ glDeleteShader(vertexShader);
+ if (fragmentShader != 0)
+ glDeleteShader(fragmentShader);
+ if (shaderProgram != 0)
+ glDeleteProgram(shaderProgram);
+ shaderProgram = 0;
+ vertexShader = 0;
+ fragmentShader = 0;
+}
+
+void
+ShaderScreen::loadProgram(std::string& vertexShaderPath, std::string& fragmentShaderPath)
+{
+ clearShader();
+
+ vertexShader = loadShader(vertexShaderPath, GL_VERTEX_SHADER);
+ fragmentShader = loadShader(fragmentShaderPath, GL_FRAGMENT_SHADER);
+
+ if (vertexShader == 0 || fragmentShader == 0)
+ {
+ std::cerr << "Cannot create shader" << std::endl;
+ return;
+ }
+ GLuint program = 0;
+ program = glCreateProgram();
+
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+
+ GLint linked;
+ glGetProgramiv(program, GL_LINK_STATUS, &linked);
+
+ if(!linked)
+ {
+ GLsizei length;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
+ char* log = new char[length];
+ glGetProgramInfoLog(program, length, &length, log);
+ std::cerr << "Program Link Error : " << log << "\n";
+ delete log;
+ glDeleteProgram(program);
+ program = 0;
+ }
+ shaderProgram = program;
+}
+
+void
+ShaderScreen::bindShader()
+{
+ if (shaderProgram != 0)
+ {
+ glUseProgram(shaderProgram);
+ }
+
+}
+
+void
+ShaderScreen::shaderInit()
+{
+ if (!queryForShader()) {
+ std::cout << "ERROR: Shader not supported" << std::endl;
+ return;
+ }
+ char* homedir = getenv("HOME");
+ if (!homedir)
+ {
+ std::cerr << "Error: Cannot find HOME" << std::endl;
+ return;
+ }
+ std::string fragmentPath(homedir);
+ fragmentPath += "/";
+ std::string vertexPath(fragmentPath);
+ vertexPath += "shader_vertex";
+ fragmentPath += "shader_fragment_simple";
+ loadProgram(vertexPath, fragmentPath);
+ initialized = true;
+}
+
+
+void
+ShaderScreen::unbindShader()
+{
+ glUseProgram(0);
+}
+
+bool
+ShaderScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask )
+{
+ int rectWidth = 200;
+ int rectHeight = 100;
+
+ bool ret;
+ ret = gScreen->glPaintOutput (attrib, transform, region, output, mask);
+
+ GLMatrix sTransform(transform);
+ sTransform.toScreenSpace(output, -DEFAULT_Z_CAMERA);
+ glPushMatrix;
+ glLoadMatrixf(sTransform.getMatrix());
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ glColor3f(1,0,0);
+
+ glBegin(GL_TRIANGLES);
+ glVertex2i(0,0);
+ glVertex2i(0, 10);
+ glVertex2i(10, 0);
+ glEnd();
+
+ glColor4usv(defaultColor);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_TEXTURE_2D);
+
+ if (!initialized)
+ shaderInit();
+ bindShader();
+ glBegin(GL_QUADS);
+ glTexCoord2f(0,1);
+ glVertex2i(output->centerX() - rectWidth/2.0f, output->centerY() - rectHeight/2.0f);
+ glTexCoord2f(0,0);
+ glVertex2i(output->centerX() - rectWidth/2.0f, output->centerY() + rectHeight/2.0f);
+ glTexCoord2f(1,0);
+ glVertex2i(output->centerX() + rectWidth/2.0f, output->centerY() + rectHeight/2.0f);
+ glTexCoord2f(1,1);
+ glVertex2i(output->centerX() + rectWidth/2.0f, output->centerY() - rectHeight/2.0f);
+ glEnd();
+ unbindShader();
+
+ glPopMatrix();
+ return ret;
+}
+
+void
+ShaderScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask )
+{
+ gScreen->glPaintTransformedOutput (attrib, transform, region, output, mask);
+}
+
+ShaderScreen::ShaderScreen (CompScreen *screen) :
+ PluginClassHandler <ShaderScreen, CompScreen> (screen),
+ screen (screen),
+ cScreen (CompositeScreen::get (screen)),
+ gScreen (GLScreen::get (screen)),
+ initialized(false)
+{
+ ScreenInterface::setHandler (screen, true);
+ CompositeScreenInterface::setHandler (cScreen, true);
+ GLScreenInterface::setHandler (gScreen, true);
+}
+
+ShaderScreen::~ShaderScreen ()
+{
+}
+
+bool
+ShaderPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
+ return false;
+ if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
+ return false;
+ if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false;
+
+ return true;
+}
diff --git a/CompizShader/src/shader.h b/CompizShader/src/shader.h
new file mode 100644
index 0000000..113f27d
--- /dev/null
+++ b/CompizShader/src/shader.h
@@ -0,0 +1,64 @@
+/**
+ * author: Alexander Lang
+ */
+#include <compiz/core/core.h>
+#include <core/pluginclasshandler.h>
+#include <compiz/composite/composite.h>
+#include <compiz/opengl/opengl.h>
+#include "shader_options.h"
+
+class ShaderScreen :
+ public ScreenInterface,
+ public CompositeScreenInterface,
+ public GLScreenInterface,
+ public PluginClassHandler <ShaderScreen, CompScreen>,
+ public ShaderOptions
+{
+ public:
+
+ ShaderScreen (CompScreen *s);
+ ~ShaderScreen ();
+
+ CompScreen *screen;
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+
+ bool initialized;
+ GLuint shaderProgram;
+ GLuint vertexShader;
+ GLuint fragmentShader;
+
+ bool
+ queryForShader();
+ void
+ bindShader();
+ void
+ unbindShader();
+ void
+ loadProgram(std::string& vertexShaderPath, std::string& fragmentShaderPath);
+ void
+ clearShader();
+ GLuint
+ loadShader(std::string& fileName, GLuint type);
+ void
+ shaderInit();
+
+ bool
+ glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &, const CompRegion &,
+ CompOutput *, unsigned int);
+
+ void
+ glPaintTransformedOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &, const CompRegion &,
+ CompOutput *, unsigned int);
+
+};
+
+class ShaderPluginVTable :
+ public CompPlugin::VTableForScreen<ShaderScreen>
+{
+ public:
+
+ bool init ();
+};