aboutsummaryrefslogtreecommitdiff
path: root/util/fbcompose/OpenGLShaders.cc
diff options
context:
space:
mode:
authorGediminas Liktaras <gliktaras@gmail.com>2011-12-08 13:34:09 (GMT)
committerPaul Tagliamonte <paultag@fluxbox.org>2011-12-10 16:13:19 (GMT)
commitcd339169d1961eb508ea89cee2609ec6d0fc0c15 (patch)
tree01acd158a03fb17a72e067ff0b36701da75e49dc /util/fbcompose/OpenGLShaders.cc
parent85ac5c4b2c6a526992f483a6e91867dc2f82a19e (diff)
downloadfluxbox_paul-cd339169d1961eb508ea89cee2609ec6d0fc0c15.zip
fluxbox_paul-cd339169d1961eb508ea89cee2609ec6d0fc0c15.tar.bz2
fbcompose - A compositing addon for fluxbox window manager.
fbcompose(1) is an optional compositing addon for fluxbox window manager. It augments fluxbox with a number of graphical features. Most notably, fbcompose allows fluxbox to properly display applications that require compositing (docky, for example), adds support for true window transparency (as opposed to fluxbox's pseudo transparency) and provides a plugin framework to extend the compositor's functionality. As this is still a beta version of the compositor, the bugs are likely.
Diffstat (limited to 'util/fbcompose/OpenGLShaders.cc')
-rw-r--r--util/fbcompose/OpenGLShaders.cc234
1 files changed, 234 insertions, 0 deletions
diff --git a/util/fbcompose/OpenGLShaders.cc b/util/fbcompose/OpenGLShaders.cc
new file mode 100644
index 0000000..35fed1b
--- /dev/null
+++ b/util/fbcompose/OpenGLShaders.cc
@@ -0,0 +1,234 @@
1/** OpenGLShaders.cc file for the fluxbox compositor. */
2
3// Copyright (c) 2011 Gediminas Liktaras (gliktaras at gmail dot com)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21// THE SOFTWARE.
22
23
24#include "OpenGLShaders.hh"
25
26#include "Exceptions.hh"
27#include "Logging.hh"
28#include "OpenGLPlugin.hh"
29
30#include <sstream>
31
32using namespace FbCompositor;
33
34
35//--- CONSTANTS ----------------------------------------------------------------
36
37/** Size of the info log buffer. */
38const int INFO_LOG_BUFFER_SIZE = 256;
39
40
41//--- VERTEX SHADER SOURCE -----------------------------------------------------
42
43/** Head of the vertex shader source code. */
44const GLchar VERTEX_SHADER_HEAD[] = "\
45 #version 120 \n\
46 \n\
47 attribute vec2 fb_InitMainTexCoord; \n\
48 attribute vec2 fb_InitPrimPos; \n\
49 attribute vec2 fb_InitShapeTexCoord; \n\
50 \n\
51 varying vec2 fb_MainTexCoord; \n\
52 varying vec2 fb_ShapeTexCoord; \n\
53";
54
55/** Middle of the vertex shader source code. */
56const GLchar VERTEX_SHADER_MIDDLE[] = "\
57 void main() { \n\
58 gl_Position = vec4(fb_InitPrimPos, 0.0, 1.0); \n\
59 fb_MainTexCoord = fb_InitMainTexCoord; \n\
60 fb_ShapeTexCoord = fb_InitShapeTexCoord; \n\
61";
62
63/** Tail of the vertex shader source code. */
64const GLchar VERTEX_SHADER_TAIL[] = "\
65 } \n\
66";
67
68
69//--- FRAGMENT SHADER SOURCE ---------------------------------------------------
70
71/** Head of the fragment shader source code. */
72const GLchar FRAGMENT_SHADER_HEAD[] = "\
73 #version 120 \n\
74 \n\
75 uniform float fb_Alpha; \n\
76 uniform sampler2D fb_MainTexture; \n\
77 uniform sampler2D fb_ShapeTexture; \n\
78 \n\
79 varying vec2 fb_MainTexCoord; \n\
80 varying vec2 fb_ShapeTexCoord; \n\
81";
82
83/** Middle of the fragment shader source code. */
84const GLchar FRAGMENT_SHADER_MIDDLE[] = "\
85 void main() { \n\
86 gl_FragColor = texture2D(fb_MainTexture, fb_MainTexCoord) \n\
87 * texture2D(fb_ShapeTexture, fb_ShapeTexCoord) \n\
88 * vec4(1.0, 1.0, 1.0, fb_Alpha); \n\
89";
90
91/** Tail of the fragment shader source code. */
92const GLchar FRAGMENT_SHADER_TAIL[] = "\
93 } \n\
94";
95
96
97//--- CONSTRUCTORS AND DESTRUCTORS ---------------------------------------------
98
99// Constructor.
100OpenGLShaderProgram::OpenGLShaderProgram(const std::vector<BasePlugin*> &plugins) {
101 std::stringstream ss;
102
103 // Assemble vertex shader.
104 ss.str("");
105 ss << VERTEX_SHADER_HEAD;
106 for (size_t i = 0; i < plugins.size(); i++) {
107 ss << (dynamic_cast<OpenGLPlugin*>(plugins[i]))->vertexShader() << "\n";
108 }
109 ss << VERTEX_SHADER_MIDDLE;
110 for (size_t i = 0; i < plugins.size(); i++) {
111 ss << (dynamic_cast<OpenGLPlugin*>(plugins[i]))->pluginName() << "();\n";
112 }
113 ss << VERTEX_SHADER_TAIL;
114 m_vertex_shader = createShader(GL_VERTEX_SHADER, ss.str().length(), ss.str().c_str());
115
116 fbLog_debug << "Vertex shader source code:" << std::endl << ss.str() << std::endl;
117
118 // Assemble fragment shader.
119 ss.str("");
120 ss << FRAGMENT_SHADER_HEAD;
121 for (size_t i = 0; i < plugins.size(); i++) {
122 ss << (dynamic_cast<OpenGLPlugin*>(plugins[i]))->fragmentShader() << "\n";
123 }
124 ss << FRAGMENT_SHADER_MIDDLE;
125 for (size_t i = 0; i < plugins.size(); i++) {
126 ss << (dynamic_cast<OpenGLPlugin*>(plugins[i]))->pluginName() << "();\n";
127 }
128 ss << FRAGMENT_SHADER_TAIL;
129 m_fragment_shader = createShader(GL_FRAGMENT_SHADER, ss.str().length(), ss.str().c_str());
130
131 fbLog_debug << "Fragment shader source code:" << std::endl << ss.str() << std::endl;
132
133 // Create shader program.
134 m_shader_program = createShaderProgram(m_vertex_shader, m_fragment_shader);
135
136 // Initialize attribute locations.
137 m_main_tex_coord_attrib = getAttributeLocation("fb_InitMainTexCoord");
138 m_prim_pos_attrib = getAttributeLocation("fb_InitPrimPos");
139 m_shape_tex_coord_attrib = getAttributeLocation("fb_InitShapeTexCoord");
140
141 // Initialize uniform locations.
142 m_alpha_uniform = getUniformLocation("fb_Alpha");
143 m_main_tex_uniform = getUniformLocation("fb_MainTexture");
144 m_shape_tex_uniform = getUniformLocation("fb_ShapeTexture");
145}
146
147// Destructor.
148OpenGLShaderProgram::~OpenGLShaderProgram() {
149 glDetachShader(m_shader_program, m_vertex_shader);
150 glDetachShader(m_shader_program, m_fragment_shader);
151
152 glDeleteProgram(m_shader_program);
153 glDeleteShader(m_vertex_shader);
154 glDeleteShader(m_fragment_shader);
155}
156
157
158//--- INITIALIZATION FUNCTIONS -------------------------------------------------
159
160// Creates a shader.
161GLuint OpenGLShaderProgram::createShader(GLenum shader_type, GLint source_length, const GLchar *source) {
162 // Determine shader type.
163 FbTk::FbString shaderName;
164 if (shader_type == GL_VERTEX_SHADER) {
165 shaderName = "vertex";
166 } else if (shader_type == GL_GEOMETRY_SHADER) { // For completeness.
167 shaderName = "geometry";
168 } else if (shader_type == GL_FRAGMENT_SHADER) {
169 shaderName = "fragment";
170 } else {
171 throw InitException("createShader() was given an invalid shader type.");
172 }
173
174 // Create and compile.
175 GLuint shader = glCreateShader(shader_type);
176 if (!shader) {
177 std::stringstream ss;
178 ss << "Could not create " << shaderName << " shader.";
179 throw InitException(ss.str());
180 }
181
182 glShaderSource(shader, 1, &source, &source_length);
183 glCompileShader(shader);
184
185 // Check for errors.
186 GLint compile_status;
187 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
188
189 if (!compile_status) {
190 GLsizei info_log_size;
191 GLchar info_log[INFO_LOG_BUFFER_SIZE];
192 glGetShaderInfoLog(shader, INFO_LOG_BUFFER_SIZE, &info_log_size, info_log);
193
194 std::stringstream ss;
195 ss << "Error in compilation of the " << shaderName << " shader: "
196 << std::endl << (const char*)(info_log);
197 throw InitException(ss.str());
198 }
199
200 return shader;
201}
202
203// Creates a shader program.
204GLuint OpenGLShaderProgram::createShaderProgram(GLuint vertex_shader, GLuint fragment_shader) {
205 GLuint program = glCreateProgram();
206 if (!program) {
207 throw InitException("Cannot create a shader program.");
208 }
209
210 // Link program.
211 if (vertex_shader) {
212 glAttachShader(program, vertex_shader);
213 }
214 if (fragment_shader) {
215 glAttachShader(program, fragment_shader);
216 }
217 glLinkProgram(program);
218
219 // Check for errors.
220 GLint linkStatus;
221 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
222
223 if (!linkStatus) {
224 GLsizei info_log_size;
225 GLchar info_log[INFO_LOG_BUFFER_SIZE];
226 glGetProgramInfoLog(program, INFO_LOG_BUFFER_SIZE, &info_log_size, info_log);
227
228 std::stringstream ss;
229 ss << "Error in linking of the shader program: " << std::endl << (const char*)(info_log);
230 throw InitException(ss.str());
231 }
232
233 return program;
234}