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 #include "gpuProgram.h"
24 #include <iostream>
25
26 using namespace std;
27
28
GPUProgram(GPUShader * vs,GPUShader * fs,GPUShader * gs,int inputGeometry,int outputGeometry,int outVertices)29 GPUProgram::GPUProgram(GPUShader* vs,GPUShader* fs,GPUShader *gs,
30 int inputGeometry,int outputGeometry,int outVertices)
31 : _vs(vs),
32 _fs(fs),
33 _gs(gs),
34 _inputGeometry(inputGeometry),
35 _outputGeometry(outputGeometry),
36 _outVertices(outVertices) {
37
38 _programId = glCreateProgram();
39 setGeometryParameters(_inputGeometry,_outputGeometry,_outVertices);
40 attachAndLink();
41 }
42
GPUProgram(const string & vsFile,const string & fsFile,const string & gsFile,int inputGeometry,int outputGeometry,int outVertices)43 GPUProgram::GPUProgram(const string &vsFile,
44 const string &fsFile,
45 const string &gsFile,
46 int inputGeometry,
47 int outputGeometry,
48 int outVertices)
49 :_inputGeometry(inputGeometry),
50 _outputGeometry(outputGeometry),
51 _outVertices(outVertices) {
52
53 _vs = _fs = _gs = NULL;
54
55 if(vsFile!="")
56 _vs = new GPUShader(VERT,vsFile);
57
58 if(fsFile!="")
59 _fs = new GPUShader(FRAG,fsFile);
60
61 if(gsFile!="")
62 _gs = new GPUShader(GEOM,gsFile);
63
64 _programId = glCreateProgram();
65 setGeometryParameters(_inputGeometry,_outputGeometry,_outVertices);
66 attachAndLink();
67 }
68
~GPUProgram()69 GPUProgram::~GPUProgram() {
70
71 detach();
72
73 if(_vs!=NULL) {
74 delete _vs;
75 }
76
77 if(_fs!=NULL) {
78 delete _fs;
79 }
80
81 if(_gs!=NULL) {
82 delete _gs;
83 }
84
85 glDeleteProgram(_programId);
86 }
87
setGeometryParameters(int inputGeometry,int outputGeometry,int outVertices)88 void GPUProgram::setGeometryParameters(int inputGeometry,int outputGeometry,int outVertices) {
89 #ifdef GL_EXT_geometry_shader4
90 if(GL_EXT_geometry_shader4 && _gs!=NULL && _gs->id()!=0) {
91 glProgramParameteriEXT(_programId,GL_GEOMETRY_INPUT_TYPE_EXT,inputGeometry);
92 glProgramParameteriEXT(_programId,GL_GEOMETRY_OUTPUT_TYPE_EXT,outputGeometry);
93 glProgramParameteriEXT(_programId,GL_GEOMETRY_VERTICES_OUT_EXT,outVertices);
94 }
95 #endif
96 }
97
attach()98 void GPUProgram::attach() {
99 if(_vs!=NULL) {
100 glAttachShader(_programId,_vs->id());
101 }
102
103 if(_fs!=NULL) {
104 glAttachShader(_programId,_fs->id());
105 }
106
107 if(_gs!=NULL) {
108 glAttachShader(_programId,_gs->id());
109 }
110 }
111
detach()112 void GPUProgram::detach() {
113
114 if(_vs!=NULL) {
115 glDetachShader(_programId,_vs->id());
116 }
117
118 if(_fs!=NULL) {
119 glDetachShader(_programId,_fs->id());
120 }
121
122 if(_gs!=NULL) {
123 glDetachShader(_programId,_gs->id());
124 }
125 }
126
link()127 bool GPUProgram::link() {
128 int linked = 1;
129
130 glLinkProgram(_programId);
131
132 glGetObjectParameterivARB(_programId,GL_OBJECT_LINK_STATUS_ARB,&linked);
133
134 if(linked)
135 return true;
136
137 return false;
138 }
139
attachAndLink()140 bool GPUProgram::attachAndLink() {
141 attach();
142 return link();
143 }
144
reload()145 void GPUProgram::reload() {
146
147 detach();
148
149 bool allOk = true;
150 if(_vs!=NULL) {
151 allOk = allOk && _vs->loadAndCompile();
152 }
153
154 if(_fs!=NULL) {
155 allOk = allOk && _fs->loadAndCompile();
156 }
157
158 if(_gs!=NULL) {
159 allOk = allOk && _gs->loadAndCompile();
160 }
161
162 if(!allOk){
163 std::cout << "reload fail, maybe missing file" << std::endl;
164 }
165 setGeometryParameters(_inputGeometry,_outputGeometry,_outVertices);
166 attachAndLink();
167
168 // reload uniforms
169 for(map<string,GLint>::iterator i=_uniformLocations.begin();i!=_uniformLocations.end();i++) {
170 _uniformLocations[(*i).first] = glGetUniformLocation(_programId,(*i).first.c_str());
171 }
172
173 // reload attributes
174 for(map<string,GLint>::iterator i=_attributeLocations.begin();i!=_attributeLocations.end();i++) {
175 _uniformLocations[(*i).first] = glGetAttribLocation(_programId,(*i).first.c_str());
176 }
177
178 // free textures
179 _textures.clear();
180 }
181
addUniform(const string & uniformName)182 void GPUProgram::addUniform(const string &uniformName) {
183 GLint location = glGetUniformLocation(_programId,uniformName.c_str());
184
185 _uniformLocations[uniformName] = location;
186 }
187
addAttribute(const string & attributeName)188 void GPUProgram::addAttribute(const string &attributeName) {
189 GLint location = glGetAttribLocation(_programId,attributeName.c_str());
190
191 _attributeLocations[attributeName] = location;
192 }
193
haveShaderOfType(SHADER_TYPE type)194 bool GPUProgram::haveShaderOfType(SHADER_TYPE type) {
195
196 if(type==VERT)
197 return _vs!=NULL;
198
199 if(type==FRAG)
200 return _fs!=NULL;
201
202 if(type==GEOM)
203 return _gs!=NULL;
204
205 cout << "Warning : unknown type !" << endl;
206
207 return false;
208 }
209
filename(SHADER_TYPE type)210 string GPUProgram::filename(SHADER_TYPE type) {
211
212 if(type==VERT && _vs!=NULL)
213 return _vs->filename();
214
215 if(type==FRAG && _fs!=NULL)
216 return _fs->filename();
217
218 if(type==GEOM && _gs!=NULL)
219 return _gs->filename();
220
221 cout << "Warning : unknown type !" << endl;
222
223 return "";
224 }
225