1 /****************************************************************************
2 * Render Radiance Scaling *
3 * Meshlab's plugin *
4 * *
5 * Copyright(C) 2010 *
6 * Vergne Romain, Dumas Olivier *
7 * INRIA - Institut Nationnal de Recherche en Informatique et Automatique *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 #ifndef GPUPROGRAM_H
24 #define GPUPROGRAM_H
25
26 #include <GL/glew.h>
27 #include <iostream>
28 #include "gpuShader.h"
29 #include <string>
30 #include <vector>
31 #include <map>
32
33 class GPUProgram {
34
35 public:
36 GPUProgram(GPUShader *vs=NULL,GPUShader *fs=NULL,GPUShader *geom=NULL,
37 int inputGeometry=0,int outputGeometry=0,int outVertices=0);
38
39 GPUProgram(const std::string &vsFile="",
40 const std::string &fsFile="",
41 const std::string &gsFile="",
42 int inputGeometry=0,
43 int outputGeometry=0,
44 int outVertices=0);
45
46 ~GPUProgram();
47
48 void addUniform(const std::string &uniformName);
49 void addAttribute(const std::string &attributeName);
50 void reload();
51
52 inline GLuint id() const;
53 bool haveShaderOfType(SHADER_TYPE type);
54 std::string filename(SHADER_TYPE type);
55
56 inline void enable();
57 inline void disable();
58
59 inline GLint getUniformLocation(const std::string &uniformName);
60 inline GLint getAttributeLocation(const std::string &attributeName);
61
62 inline void setUniform1f(const std::string &uniformName,GLfloat v);
63 inline void setUniform2f(const std::string &uniformName,GLfloat v1,GLfloat v2);
64 inline void setUniform3f(const std::string &uniformName,GLfloat v1,GLfloat v2,GLfloat v3);
65 inline void setUniform4f(const std::string &uniformName,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4);
66 inline void setUniform1f(GLint loc,GLfloat v);
67 inline void setUniform2f(GLint loc,GLfloat v1,GLfloat v2);
68 inline void setUniform3f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3);
69 inline void setUniform4f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4);
70
71 inline void setUniform1i(const std::string &uniformName,GLint v);
72 inline void setUniform2i(const std::string &uniformName,GLint v1,GLint v2);
73 inline void setUniform3i(const std::string &uniformName,GLint v1,GLint v2,GLint v3);
74 inline void setUniform4i(const std::string &uniformName,GLint v1,GLint v2,GLint v3,GLint v4);
75 inline void setUniform1i(GLint loc,GLint v);
76 inline void setUniform2i(GLint loc,GLint v1,GLint v2);
77 inline void setUniform3i(GLint loc,GLint v1,GLint v2,GLint v3);
78 inline void setUniform4i(GLint loc,GLint v1,GLint v2,GLint v3,GLint v4);
79
80 inline void setUniform1fv(const std::string &uniformName,GLfloat *v,GLsizei count=1);
81 inline void setUniform2fv(const std::string &uniformName,GLfloat *v,GLsizei count=1);
82 inline void setUniform3fv(const std::string &uniformName,GLfloat *v,GLsizei count=1);
83 inline void setUniform4fv(const std::string &uniformName,GLfloat *v,GLsizei count=1);
84 inline void setUniform1fv(GLint loc,GLfloat *v,GLsizei count=1);
85 inline void setUniform2fv(GLint loc,GLfloat *v,GLsizei count=1);
86 inline void setUniform3fv(GLint loc,GLfloat *v,GLsizei count=1);
87 inline void setUniform4fv(GLint loc,GLfloat *v,GLsizei count=1);
88
89 inline void setUniform1iv(const std::string &uniformName,GLint *v,GLsizei count=1);
90 inline void setUniform2iv(const std::string &uniformName,GLint *v,GLsizei count=1);
91 inline void setUniform3iv(const std::string &uniformName,GLint *v,GLsizei count=1);
92 inline void setUniform4iv(const std::string &uniformName,GLint *v,GLsizei count=1);
93 inline void setUniform1iv(GLint loc,GLint *v,GLsizei count=1);
94 inline void setUniform2iv(GLint loc,GLint *v,GLsizei count=1);
95 inline void setUniform3iv(GLint loc,GLint *v,GLsizei count=1);
96 inline void setUniform4iv(GLint loc,GLint *v,GLsizei count=1);
97
98 inline void setUniformMatrix2fv(const std::string &uniformName,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
99 inline void setUniformMatrix3fv(const std::string &uniformName,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
100 inline void setUniformMatrix4fv(const std::string &uniformName,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
101 inline void setUniformMatrix2fv(GLint loc,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
102 inline void setUniformMatrix3fv(GLint loc,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
103 inline void setUniformMatrix4fv(GLint loc,GLfloat *v,GLsizei count=1,GLboolean transpose=false);
104
105 inline void setUniformTexture(const std::string &uniformName,GLint num,GLenum type,GLuint textureName);
106 inline void setUniformTexture(GLint loc,GLint num,GLenum type,GLuint textureName);
107
108 inline void setUniformBuffer(const std::string &uniformName,GLuint buffer);
109 inline void setUniformBuffer(GLint loc,GLuint buffer);
110 inline GLint getUniformBufferSize(const std::string &uniformName);
111 inline GLint getUniformBufferSize(GLint loc);
112
113 protected:
114 void attach();
115 bool link();
116 bool attachAndLink();
117 void detach();
118 void setGeometryParameters(int inputGeometry,int outputGeometry,int outVertices);
119
120 private:
121
122 GPUShader* _vs;
123 GPUShader* _fs;
124 GPUShader* _gs;
125 GLuint _programId;
126
127 std::map<std::string,GLint> _uniformLocations;
128 std::map<std::string,GLint> _attributeLocations;
129 std::map<GLuint,std::pair<GLenum,GLenum> > _textures;
130
131 int _inputGeometry;
132 int _outputGeometry;
133 int _outVertices;
134 };
135
enable()136 inline void GPUProgram::enable() {
137 glUseProgramObjectARB(_programId);
138
139 for(std::map<GLuint,std::pair<GLenum,GLenum> >::iterator i=_textures.begin();i!=_textures.end();++i) {
140 glActiveTexture((*i).second.first);
141 glBindTexture((*i).second.second,(*i).first);
142 glEnable((*i).second.second);
143 }
144
145 }
146
disable()147 inline void GPUProgram::disable() {
148 for(std::map<GLuint,std::pair<GLenum,GLenum> >::reverse_iterator i=_textures.rbegin();i!=_textures.rend();++i) {
149 glActiveTexture((*i).second.first);
150 glDisable((*i).second.second);
151 }
152
153 glUseProgramObjectARB(0);
154 }
155
id()156 inline GLuint GPUProgram::id() const {
157 return _programId;
158 }
159
setUniform1f(const std::string & uniformName,GLfloat v)160 inline void GPUProgram::setUniform1f(const std::string &uniformName,GLfloat v) {
161 glUniform1f(_uniformLocations[uniformName],v);
162 }
163
setUniform2f(const std::string & uniformName,GLfloat v1,GLfloat v2)164 inline void GPUProgram::setUniform2f(const std::string &uniformName,GLfloat v1,GLfloat v2) {
165 glUniform2f(_uniformLocations[uniformName],v1,v2);
166 }
167
setUniform3f(const std::string & uniformName,GLfloat v1,GLfloat v2,GLfloat v3)168 inline void GPUProgram::setUniform3f(const std::string &uniformName,GLfloat v1,GLfloat v2,GLfloat v3) {
169 glUniform3f(_uniformLocations[uniformName],v1,v2,v3);
170 }
171
setUniform4f(const std::string & uniformName,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4)172 inline void GPUProgram::setUniform4f(const std::string &uniformName,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4) {
173 glUniform4f(_uniformLocations[uniformName],v1,v2,v3,v4);
174 }
175
setUniform1i(const std::string & uniformName,GLint v)176 inline void GPUProgram::setUniform1i(const std::string &uniformName,GLint v) {
177 glUniform1i(_uniformLocations[uniformName],v);
178 }
179
setUniform2i(const std::string & uniformName,GLint v1,GLint v2)180 inline void GPUProgram::setUniform2i(const std::string &uniformName,GLint v1,GLint v2) {
181 glUniform2i(_uniformLocations[uniformName],v1,v2);
182 }
183
setUniform3i(const std::string & uniformName,GLint v1,GLint v2,GLint v3)184 inline void GPUProgram::setUniform3i(const std::string &uniformName,GLint v1,GLint v2,GLint v3) {
185 glUniform3i(_uniformLocations[uniformName],v1,v2,v3);
186 }
187
setUniform4i(const std::string & uniformName,GLint v1,GLint v2,GLint v3,GLint v4)188 inline void GPUProgram::setUniform4i(const std::string &uniformName,GLint v1,GLint v2,GLint v3,GLint v4) {
189 glUniform4i(_uniformLocations[uniformName],v1,v2,v3,v4);
190 }
191
setUniform1fv(const std::string & uniformName,GLfloat * v,GLsizei count)192 inline void GPUProgram::setUniform1fv(const std::string &uniformName,GLfloat *v,GLsizei count) {
193 glUniform1fv(_uniformLocations[uniformName],count,v);
194 }
195
setUniform2fv(const std::string & uniformName,GLfloat * v,GLsizei count)196 inline void GPUProgram::setUniform2fv(const std::string &uniformName,GLfloat *v,GLsizei count) {
197 glUniform2fv(_uniformLocations[uniformName],count,v);
198 }
199
setUniform3fv(const std::string & uniformName,GLfloat * v,GLsizei count)200 inline void GPUProgram::setUniform3fv(const std::string &uniformName,GLfloat *v,GLsizei count) {
201 glUniform3fv(_uniformLocations[uniformName],count,v);
202 }
203
setUniform4fv(const std::string & uniformName,GLfloat * v,GLsizei count)204 inline void GPUProgram::setUniform4fv(const std::string &uniformName,GLfloat *v,GLsizei count) {
205 glUniform4fv(_uniformLocations[uniformName],count,v);
206 }
207
setUniform1iv(const std::string & uniformName,GLint * v,GLsizei count)208 inline void GPUProgram::setUniform1iv(const std::string &uniformName,GLint *v,GLsizei count) {
209 glUniform1iv(_uniformLocations[uniformName],count,v);
210 }
211
setUniform2iv(const std::string & uniformName,GLint * v,GLsizei count)212 inline void GPUProgram::setUniform2iv(const std::string &uniformName,GLint *v,GLsizei count) {
213 glUniform2iv(_uniformLocations[uniformName],count,v);
214 }
215
setUniform3iv(const std::string & uniformName,GLint * v,GLsizei count)216 inline void GPUProgram::setUniform3iv(const std::string &uniformName,GLint *v,GLsizei count) {
217 glUniform3iv(_uniformLocations[uniformName],count,v);
218 }
219
setUniform4iv(const std::string & uniformName,GLint * v,GLsizei count)220 inline void GPUProgram::setUniform4iv(const std::string &uniformName,GLint *v,GLsizei count) {
221 glUniform4iv(_uniformLocations[uniformName],count,v);
222 }
223
setUniformMatrix2fv(const std::string & uniformName,GLfloat * v,GLsizei count,GLboolean transpose)224 inline void GPUProgram::setUniformMatrix2fv(const std::string &uniformName,GLfloat *v,GLsizei count,GLboolean transpose) {
225 glUniformMatrix2fv(_uniformLocations[uniformName],count,transpose,v);
226 }
227
setUniformMatrix3fv(const std::string & uniformName,GLfloat * v,GLsizei count,GLboolean transpose)228 inline void GPUProgram::setUniformMatrix3fv(const std::string &uniformName,GLfloat *v,GLsizei count,GLboolean transpose) {
229 glUniformMatrix3fv(_uniformLocations[uniformName],count,transpose,v);
230 }
231
setUniformMatrix4fv(const std::string & uniformName,GLfloat * v,GLsizei count,GLboolean transpose)232 inline void GPUProgram::setUniformMatrix4fv(const std::string &uniformName,GLfloat *v,GLsizei count,GLboolean transpose) {
233 glUniformMatrix4fv(_uniformLocations[uniformName],count,transpose,v);
234 }
235
setUniformTexture(const std::string & uniformName,GLint num,GLenum type,GLuint textureName)236 inline void GPUProgram::setUniformTexture(const std::string &uniformName,GLint num,GLenum type,GLuint textureName) {
237 GLenum textureNum;
238
239 const std::map<GLuint,std::pair<GLenum,GLenum> >::iterator it = _textures.find(textureName);
240
241 if(it==_textures.end()) {
242 textureNum = GL_TEXTURE0+_textures.size();
243 } else {
244 textureNum = (*it).second.first;
245 }
246
247 glPushAttrib(GL_TEXTURE_BIT);
248 glActiveTexture(textureNum);
249 glBindTexture(type,textureName);
250 glEnable(type);
251
252 glUniform1i(_uniformLocations[uniformName],num);
253 _textures[textureName] = std::pair<GLenum,GLenum>(textureNum,type);
254
255 glDisable(type);
256 glPopAttrib();
257 }
258
setUniform1f(GLint loc,GLfloat v)259 inline void GPUProgram::setUniform1f(GLint loc,GLfloat v) {
260 glUniform1f(loc,v);
261 }
262
setUniform2f(GLint loc,GLfloat v1,GLfloat v2)263 inline void GPUProgram::setUniform2f(GLint loc,GLfloat v1,GLfloat v2) {
264 glUniform2f(loc,v1,v2);
265 }
266
setUniform3f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3)267 inline void GPUProgram::setUniform3f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3) {
268 glUniform3f(loc,v1,v2,v3);
269 }
270
setUniform4f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4)271 inline void GPUProgram::setUniform4f(GLint loc,GLfloat v1,GLfloat v2,GLfloat v3,GLfloat v4) {
272 glUniform4f(loc,v1,v2,v3,v4);
273 }
274
setUniform1i(GLint loc,GLint v)275 inline void GPUProgram::setUniform1i(GLint loc,GLint v) {
276 glUniform1i(loc,v);
277 }
278
setUniform2i(GLint loc,GLint v1,GLint v2)279 inline void GPUProgram::setUniform2i(GLint loc,GLint v1,GLint v2) {
280 glUniform2i(loc,v1,v2);
281 }
282
setUniform3i(GLint loc,GLint v1,GLint v2,GLint v3)283 inline void GPUProgram::setUniform3i(GLint loc,GLint v1,GLint v2,GLint v3) {
284 glUniform3i(loc,v1,v2,v3);
285 }
286
setUniform4i(GLint loc,GLint v1,GLint v2,GLint v3,GLint v4)287 inline void GPUProgram::setUniform4i(GLint loc,GLint v1,GLint v2,GLint v3,GLint v4) {
288 glUniform4i(loc,v1,v2,v3,v4);
289 }
290
setUniform1fv(GLint loc,GLfloat * v,GLsizei count)291 inline void GPUProgram::setUniform1fv(GLint loc,GLfloat *v,GLsizei count) {
292 glUniform1fv(loc,count,v);
293 }
294
setUniform2fv(GLint loc,GLfloat * v,GLsizei count)295 inline void GPUProgram::setUniform2fv(GLint loc,GLfloat *v,GLsizei count) {
296 glUniform2fv(loc,count,v);
297 }
298
setUniform3fv(GLint loc,GLfloat * v,GLsizei count)299 inline void GPUProgram::setUniform3fv(GLint loc,GLfloat *v,GLsizei count) {
300 glUniform3fv(loc,count,v);
301 }
302
setUniform4fv(GLint loc,GLfloat * v,GLsizei count)303 inline void GPUProgram::setUniform4fv(GLint loc,GLfloat *v,GLsizei count) {
304 glUniform4fv(loc,count,v);
305 }
306
setUniform1iv(GLint loc,GLint * v,GLsizei count)307 inline void GPUProgram::setUniform1iv(GLint loc,GLint *v,GLsizei count) {
308 glUniform1iv(loc,count,v);
309 }
310
setUniform2iv(GLint loc,GLint * v,GLsizei count)311 inline void GPUProgram::setUniform2iv(GLint loc,GLint *v,GLsizei count) {
312 glUniform2iv(loc,count,v);
313 }
314
setUniform3iv(GLint loc,GLint * v,GLsizei count)315 inline void GPUProgram::setUniform3iv(GLint loc,GLint *v,GLsizei count) {
316 glUniform3iv(loc,count,v);
317 }
318
setUniform4iv(GLint loc,GLint * v,GLsizei count)319 inline void GPUProgram::setUniform4iv(GLint loc,GLint *v,GLsizei count) {
320 glUniform4iv(loc,count,v);
321 }
322
setUniformMatrix2fv(GLint loc,GLfloat * v,GLsizei count,GLboolean transpose)323 inline void GPUProgram::setUniformMatrix2fv(GLint loc,GLfloat *v,GLsizei count,GLboolean transpose) {
324 glUniformMatrix2fv(loc,count,transpose,v);
325 }
326
setUniformMatrix3fv(GLint loc,GLfloat * v,GLsizei count,GLboolean transpose)327 inline void GPUProgram::setUniformMatrix3fv(GLint loc,GLfloat *v,GLsizei count,GLboolean transpose) {
328 glUniformMatrix3fv(loc,count,transpose,v);
329 }
330
setUniformMatrix4fv(GLint loc,GLfloat * v,GLsizei count,GLboolean transpose)331 inline void GPUProgram::setUniformMatrix4fv(GLint loc,GLfloat *v,GLsizei count,GLboolean transpose) {
332 glUniformMatrix4fv(loc,count,transpose,v);
333 }
334
setUniformTexture(GLint loc,GLint num,GLenum type,GLuint textureName)335 inline void GPUProgram::setUniformTexture(GLint loc,GLint num,GLenum type,GLuint textureName) {
336 GLenum textureNum;
337
338 const std::map<GLuint,std::pair<GLenum,GLenum> >::iterator it = _textures.find(textureName);
339
340 if(it==_textures.end()) {
341 textureNum = GL_TEXTURE0+_textures.size();
342 } else {
343 textureNum = (*it).second.first;
344 }
345
346 glPushAttrib(GL_TEXTURE_BIT);
347 glActiveTexture(textureNum);
348 glBindTexture(type,textureName);
349 glEnable(type);
350
351 glUniform1i(loc,num);
352 _textures[textureName] = std::pair<GLenum,GLenum>(textureNum,type);
353
354 glDisable(type);
355 glPopAttrib();
356 }
357
getUniformLocation(const std::string & uniformName)358 inline GLint GPUProgram::getUniformLocation(const std::string &uniformName) {
359 return _uniformLocations[uniformName];
360 }
361
getAttributeLocation(const std::string & attributeName)362 inline GLint GPUProgram::getAttributeLocation(const std::string &attributeName) {
363 return _attributeLocations[attributeName];
364 }
365
setUniformBuffer(const std::string & uniformName,GLuint buffer)366 inline void GPUProgram::setUniformBuffer(const std::string &uniformName,GLuint buffer) {
367 glUniformBufferEXT(_programId,_uniformLocations[uniformName],buffer);
368 }
369
setUniformBuffer(GLint loc,GLuint buffer)370 inline void GPUProgram::setUniformBuffer(GLint loc,GLuint buffer) {
371 glUniformBufferEXT(_programId,loc,buffer);
372 }
373
getUniformBufferSize(const std::string & uniformName)374 inline GLint GPUProgram::getUniformBufferSize(const std::string &uniformName) {
375 return glGetUniformBufferSizeEXT(_programId,_uniformLocations[uniformName]);
376 }
377
getUniformBufferSize(GLint loc)378 inline GLint GPUProgram::getUniformBufferSize(GLint loc) {
379 return glGetUniformBufferSizeEXT(_programId,loc);
380 }
381
382 static inline
383 void CheckErrorsGL(const char* location=NULL,std::ostream& ostr = std::cerr) {
384
385 GLuint errnum;
386 const char *errstr;
387 while((errnum=glGetError())) {
388 ostr << " **************************************************** " << std::endl;
389 ostr << " Checking OpenGL Error " << std::endl;
390
391 std::cout << " **************************************************** " << std::endl;
392 std::cout << " Checking OpenGL Error " << std::endl;
393
394 errstr = reinterpret_cast<const char *>(gluErrorString(errnum));
395 ostr << errstr;
396
397 if(location) ostr << " at " << location;
398 ostr << std::endl;
399 std::cout << " **************************************************** " << std::endl;
400 ostr << " **************************************************** " << std::endl;
401 }
402 }
403
404 #endif // GPUPROGRAM_H
405