diff options
author | Gediminas Liktaras <gliktaras@gmail.com> | 2011-12-08 13:34:09 (GMT) |
---|---|---|
committer | Paul Tagliamonte <paultag@fluxbox.org> | 2011-12-10 16:13:19 (GMT) |
commit | cd339169d1961eb508ea89cee2609ec6d0fc0c15 (patch) | |
tree | 01acd158a03fb17a72e067ff0b36701da75e49dc /util/fbcompose/OpenGLShaders.cc | |
parent | 85ac5c4b2c6a526992f483a6e91867dc2f82a19e (diff) | |
download | fluxbox_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.cc | 234 |
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 | |||
32 | using namespace FbCompositor; | ||
33 | |||
34 | |||
35 | //--- CONSTANTS ---------------------------------------------------------------- | ||
36 | |||
37 | /** Size of the info log buffer. */ | ||
38 | const int INFO_LOG_BUFFER_SIZE = 256; | ||
39 | |||
40 | |||
41 | //--- VERTEX SHADER SOURCE ----------------------------------------------------- | ||
42 | |||
43 | /** Head of the vertex shader source code. */ | ||
44 | const 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. */ | ||
56 | const 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. */ | ||
64 | const GLchar VERTEX_SHADER_TAIL[] = "\ | ||
65 | } \n\ | ||
66 | "; | ||
67 | |||
68 | |||
69 | //--- FRAGMENT SHADER SOURCE --------------------------------------------------- | ||
70 | |||
71 | /** Head of the fragment shader source code. */ | ||
72 | const 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. */ | ||
84 | const 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. */ | ||
92 | const GLchar FRAGMENT_SHADER_TAIL[] = "\ | ||
93 | } \n\ | ||
94 | "; | ||
95 | |||
96 | |||
97 | //--- CONSTRUCTORS AND DESTRUCTORS --------------------------------------------- | ||
98 | |||
99 | // Constructor. | ||
100 | OpenGLShaderProgram::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. | ||
148 | OpenGLShaderProgram::~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. | ||
161 | GLuint 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. | ||
204 | GLuint 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 | } | ||