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