Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 167 vs 168 for /trunk/Source Code/Hardware/Video/OpenGL/Shaders/glShaderProgram.cpp

Diff revisions: vs.
  @@ -15,6 +15,7 @@
15 15 _validationQueued(false),
16 16 _shaderProgramIdTemp(0)
17 17 {
18 + _shaderProgramId = Divide::GL::_invalidObjectID;
18 19 //3 buffers: Matrices, Materials and Lights
19 20 _UBOLocation.resize(UBO_PLACEHOLDER,-1);
20 21 _uniformBufferObjects.resize(UBO_PLACEHOLDER, NULL);
  @@ -26,7 +27,7 @@
26 27
27 28 glShaderProgram::~glShaderProgram()
28 29 {
29 - if(_shaderProgramId > 0 && _shaderProgramId != _invalidShaderProgramId){
30 + if(_shaderProgramId > 0 && _shaderProgramId != Divide::GL::_invalidObjectID){
30 31 for_each(ShaderIdMap::value_type& it, _shaderIdMap){
31 32 it.second->removeParentProgram(this);
32 33 GLCheck(glDetachShader(_shaderProgramId, it.second->getShaderId()));
  @@ -48,27 +49,36 @@
48 49 return ShaderProgram::tick(deltaTime);
49 50 }
50 51
51 - void glShaderProgram::validateInternal() {
52 - std::string validationBuffer;
53 52
54 - GLCheck(glValidateProgram(_shaderProgramId));
53 + std::string glShaderProgram::getLog() const {
55 54
56 - GLint length = 0, status = 0;
57 - GLCheck(glGetProgramiv(_shaderProgramId, GL_VALIDATE_STATUS, &status));
58 - GLCheck(glGetProgramiv(_shaderProgramId, GL_INFO_LOG_LENGTH, &length));
59 - if(length > 0){
55 + std::string validationBuffer("[OK]");
56 + GLint length = 0;
57 +
58 + GLCheck(glGetProgramiv(_threadedLoadComplete ? _shaderProgramId : _shaderProgramIdTemp, GL_INFO_LOG_LENGTH, &length));
59 +
60 + if(length > 1){
60 61 validationBuffer = "\n -- ";
61 62 std::vector<char> shaderProgramLog(length);
62 - GLCheck(glGetProgramInfoLog(_shaderProgramId, length, NULL, &shaderProgramLog[0]));
63 - shaderProgramLog.push_back('\n');
63 + GLCheck(glGetProgramInfoLog(_threadedLoadComplete ? _shaderProgramId : _shaderProgramIdTemp, length, NULL, &shaderProgramLog[0]));
64 64 validationBuffer.append(&shaderProgramLog[0]);
65 -
66 65 }
66 +
67 + return validationBuffer;
68 + }
69 +
70 + void glShaderProgram::validateInternal() {
67 71
72 +
73 + GLCheck(glValidateProgram(_shaderProgramId));
74 +
75 + GLint status = 0;
76 + GLCheck(glGetProgramiv(_shaderProgramId, GL_VALIDATE_STATUS, &status));
77 +
68 78 if (status == GL_FALSE){
69 - ERROR_FN(Locale::get("GLSL_VALIDATING_PROGRAM"), getName().c_str(), validationBuffer.c_str());
79 + ERROR_FN(Locale::get("GLSL_VALIDATING_PROGRAM"), getName().c_str(), getLog().c_str());
70 80 }else{
71 - D_PRINT_FN(Locale::get("GLSL_VALIDATING_PROGRAM"), getName().c_str(), validationBuffer.c_str());
81 + D_PRINT_FN(Locale::get("GLSL_VALIDATING_PROGRAM"), getName().c_str(), getLog().c_str());
72 82 }
73 83
74 84 _validationQueued = false;
  @@ -140,8 +150,16 @@
140 150 }
141 151
142 152 void glShaderProgram::link(){
153 + GLint linkStatus = 0;
143 154 D_PRINT_FN(Locale::get("GLSL_LINK_PROGRAM"),getName().c_str(), _shaderProgramIdTemp);
144 155 GLCheck(glLinkProgram(_shaderProgramIdTemp));
156 + GLCheck(glGetProgramiv(_shaderProgramIdTemp, GL_LINK_STATUS, &linkStatus));
157 +
158 + if(linkStatus == GL_FALSE){
159 + ERROR_FN(Locale::get("GLSL_LINK_PROGRAM_LOG"), getName().c_str(), getLog().c_str());
160 + }else{
161 + D_PRINT_FN(Locale::get("GLSL_LINK_PROGRAM_LOG"), getName().c_str(), getLog().c_str());
162 + }
145 163 _compiled = true;
146 164 }
147 165
  @@ -174,13 +192,13 @@
174 192 //Use the specified shader path
175 193 glswSetPath(std::string(getResourceLocation()+"GLSL/").c_str(), ".glsl");
176 194 //Mirror initial shader defines to match line count
177 - GLint lineCountOffset = 9;
178 - if(GFX_DEVICE.getGPUVendor() == GPU_VENDOR_NVIDIA || GFX_DEVICE.getGPUVendor() == GPU_VENDOR_AMD){
179 - lineCountOffset++;
180 - if(GFX_DEVICE.getGPUVendor() == GPU_VENDOR_NVIDIA){ //nVidia specific
181 - lineCountOffset += 5;
182 - }else{//AMD specific
183 - }
195 + GLint lineCountOffset = 11;
196 + GLint lineCountOffsetFrag = 2; //< for the EXT_texture_array define
197 + GLint lineCountOffsetVert = 0;
198 + if(GFX_DEVICE.getGPUVendor() == GPU_VENDOR_NVIDIA){ //nVidia specific
199 + lineCountOffset += 5;
200 + }else if(GFX_DEVICE.getGPUVendor() == GPU_VENDOR_AMD){//AMD specific
201 + lineCountOffset += 1;
184 202 }
185 203
186 204 std::string shaderSourceHeader;
  @@ -192,6 +210,22 @@
192 210 lineCountOffset++;
193 211 }
194 212
213 + std::string shaderSourceVertUniforms;
214 + //get all of the preprocessor defines
215 + for(U8 i = 0; i < _vertUniforms.size(); i++){
216 + shaderSourceVertUniforms.append("uniform ");
217 + shaderSourceVertUniforms.append(_vertUniforms[i]);
218 + shaderSourceVertUniforms.append(";\n");
219 + lineCountOffsetVert++;
220 + }
221 + std::string shaderSourceFragUniforms;
222 + //get all of the preprocessor defines
223 + for(U8 i = 0; i < _vertUniforms.size(); i++){
224 + shaderSourceFragUniforms.append("uniform ");
225 + shaderSourceFragUniforms.append(_fragUniforms[i]);
226 + shaderSourceFragUniforms.append(";\n");
227 + lineCountOffsetFrag++;
228 + }
195 229 lineCountOffset += 1;//the last new line
196 230
197 231 //Split the shader name to get the effect file name and the effect properties
  @@ -235,13 +269,14 @@
235 269 //If it doesn't
236 270 if(!vertexShader){
237 271 //Use glsw to read the vertex part of the effect
238 - const char* vs = glswGetShader(vertexShaderName.c_str(),lineCountOffset,_refreshVert);
272 + const char* vs = glswGetShader(vertexShaderName.c_str(),lineCountOffset + lineCountOffsetVert,_refreshVert);
239 273 if(!vs) ERROR_FN("[GLSL] %s",glswGetError());
240 274 assert(vs != NULL);
241 275
242 276 //If reading was succesfull
243 277 std::string vsString(vs);
244 - Util::replaceStringInPlace(vsString, "__CUSTOM_DEFINES__", shaderSourceHeader);
278 + Util::replaceStringInPlace(vsString, "//__CUSTOM_DEFINES__", shaderSourceHeader);
279 + //Util::replaceStringInPlace(vsString, "//__CUSTOM_VERTEX_UNIFORMS__",shaderSourceVertUniforms);
245 280 //Load our shader and save it in the manager in case a new Shader Program needs it
246 281 vertexShader = ShaderManager::getInstance().loadShader(vertexShaderName,vsString,VERTEX_SHADER,_refreshVert);
247 282 }
  @@ -267,13 +302,14 @@
267 302
268 303 if(!fragmentShader){
269 304 //Get our shader source
270 - const char* fs = glswGetShader(fragmentShaderName.c_str(),lineCountOffset,_refreshFrag);
305 + const char* fs = glswGetShader(fragmentShaderName.c_str(),lineCountOffset + lineCountOffsetFrag, _refreshFrag);
271 306 if(!fs) ERROR_FN("[GLSL] %s",glswGetError());
272 307 assert(fs != NULL);
273 308
274 309 std::string fsString(fs);
275 310 //Insert our custom defines in the special define slot
276 - Util::replaceStringInPlace(fsString, "__CUSTOM_DEFINES__", shaderSourceHeader);
311 + Util::replaceStringInPlace(fsString, "//__CUSTOM_DEFINES__", shaderSourceHeader);
312 + Util::replaceStringInPlace(fsString, "//__CUSTOM_FRAGMENT_UNIFORMS__",shaderSourceFragUniforms);
277 313 //Load and compile the shader
278 314 fragmentShader = ShaderManager::getInstance().loadShader(fragmentShaderName,fsString,FRAGMENT_SHADER,_refreshFrag);
279 315 }
  @@ -299,7 +335,7 @@
299 335 const char* gs = glswGetShader(geometryShaderName.c_str(),lineCountOffset,_refreshGeom);
300 336 if(gs != NULL){
301 337 std::string gsString(gs);
302 - Util::replaceStringInPlace(gsString, "__CUSTOM_DEFINES__", shaderSourceHeader);
338 + Util::replaceStringInPlace(gsString, "//__CUSTOM_DEFINES__", shaderSourceHeader);
303 339 geometryShader = ShaderManager::getInstance().loadShader(geometryShaderName,gsString,GEOMETRY_SHADER,_refreshGeom);
304 340 }else{
305 341 //Use debug output for geometry and tessellation shaders as they are not vital for the application as of yet
  @@ -329,7 +365,7 @@
329 365 const char* ts = glswGetShader(tessellationShaderName.c_str(),lineCountOffset,_refreshTess);
330 366 if(ts != NULL){
331 367 std::string tsString(ts);
332 - Util::replaceStringInPlace(tsString, "__CUSTOM_DEFINES__", shaderSourceHeader);
368 + Util::replaceStringInPlace(tsString, "//__CUSTOM_DEFINES__", shaderSourceHeader);
333 369 tessellationShader = ShaderManager::getInstance().loadShader(tessellationShaderName,tsString,TESSELATION_SHADER,_refreshTess);
334 370 }else{
335 371 //Use debug output for geometry and tessellation shaders as they are not vital for the application as of yet
  @@ -377,7 +413,7 @@
377 413 void glShaderProgram::bind() {
378 414 //If we did not create the hardware resource, do not try and bind it, as it is invalid
379 415 while(!isHWInitComplete()){}
380 - assert(_shaderProgramId != _invalidShaderProgramId);
416 + assert(_shaderProgramId != Divide::GL::_invalidObjectID);
381 417
382 418 GL_API::setActiveProgram(this);
383 419
  @@ -520,6 +556,33 @@
520 556
521 557 }
522 558
559 + void glShaderProgram::Uniform(const std::string& ext, const vectorImpl<vec2<GLfloat> >& values) {
560 + if(values.empty()) return;
561 + GLint location = cachedLoc(ext);
562 + if(location == -1) return;
563 +
564 + if(!_bound) GLCheck(glProgramUniform2fvEXT(_shaderProgramId, location, values.size(), values.front()));
565 + else GLCheck(glUniform2fv(location, values.size(), values.front()));
566 + }
567 +
568 + void glShaderProgram::Uniform(const std::string& ext, const vectorImpl<vec3<GLfloat> >& values) {
569 + if(values.empty()) return;
570 + GLint location = cachedLoc(ext);
571 + if(location == -1) return;
572 +
573 + if(!_bound) GLCheck(glProgramUniform3fvEXT(_shaderProgramId, location, values.size(), values.front()));
574 + else GLCheck(glUniform3fv(location, values.size(), values.front()));
575 + }
576 +
577 + void glShaderProgram::Uniform(const std::string& ext, const vectorImpl<vec4<GLfloat> >& values) {
578 + if(values.empty()) return;
579 + GLint location = cachedLoc(ext);
580 + if(location == -1) return;
581 +
582 + if(!_bound) GLCheck(glProgramUniform4fvEXT(_shaderProgramId, location, values.size(), values.front()));
583 + else GLCheck(glUniform4fv(location, values.size(), values.front()));
584 + }
585 +
523 586 void glShaderProgram::Uniform(const std::string& ext, const vectorImpl<mat4<GLfloat> >& values, bool rowMajor){
524 587 if(values.empty()) return;
525 588 GLint location = cachedLoc(ext);