Changeset 9869 in orxonox.OLD for trunk/src/lib/graphics/shader.cc
- Timestamp:
- Oct 3, 2006, 12:19:30 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/shader.cc
r9406 r9869 18 18 #include "shader.h" 19 19 20 #include "stdlibincl.h"21 20 #include "compiler.h" 22 21 //#include <stdio.h> … … 25 24 #include "debug.h" 26 25 27 #include "util/loading/resource_manager.h"28 26 29 27 … … 33 31 34 32 33 ObjectListDefinition(Shader); 35 34 35 void Shader::Uniform::setV(unsigned int count, float* vv) const 36 { 37 switch (count) 38 { 39 case 1: 40 glUniform1fv(this->uniform, 1, vv); 41 break; 42 case 2: 43 glUniform2fv(this->uniform, 2, vv); 44 break; 45 case 3: 46 glUniform3fv(this->uniform, 3, vv); 47 break; 48 case 4: 49 glUniform4fv(this->uniform, 4, vv); 50 break; 51 } 52 } 53 void Shader::Uniform::setV(unsigned int count, int* vv) const 54 { 55 switch (count) 56 { 57 case 1: 58 glUniform1iv(this->uniform, 1, vv); 59 break; 60 case 2: 61 glUniform2iv(this->uniform, 2, vv); 62 break; 63 case 3: 64 glUniform3iv(this->uniform, 3, vv); 65 break; 66 case 4: 67 glUniform4iv(this->uniform, 4, vv); 68 break; 69 } 70 } 71 72 73 74 Shader::Shader() 75 : data(new ShaderData) 76 { 77 78 } 36 79 37 80 /** … … 39 82 */ 40 83 Shader::Shader (const std::string& vertexShaderFile, const std::string& fragmentShaderFile) 84 : data(new ShaderData) 41 85 { 42 this->setClassID(CL_SHADER, "Shader"); 86 if (!Shader::checkShaderAbility()) 87 PRINTF(2)("Your system does not support shaders\n"); 88 this->load(vertexShaderFile, fragmentShaderFile); 43 89 44 this->shaderProgram = 0;45 this->vertexShader = 0;46 this->fragmentShader = 0;47 48 if (GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100)49 {50 this->shaderProgram = glCreateProgramObjectARB();51 52 if (!vertexShaderFile.empty())53 this->loadShaderProgramm(Shader::Vertex, vertexShaderFile);54 if (!fragmentShaderFile.empty())55 this->loadShaderProgramm(Shader::Fragment, fragmentShaderFile);56 57 this->linkShaderProgram();58 59 }60 else61 {62 PRINTF(2)("Shaders are not supported on your hardware\n");63 }64 90 } 65 91 92 const Shader* Shader::storedShader = NULL; 66 93 67 /** 68 * standard deconstructor 69 */ 70 Shader::~Shader () 94 void Shader::activateShader() const 71 95 { 72 if (this->shaderProgram == glGetHandleARB(GL_PROGRAM_OBJECT_ARB)) 73 Shader::deactivateShader(); 74 75 // delete what has to be deleted here 76 this->deleteProgram(Shader::Vertex); 77 this->deleteProgram(Shader::Fragment); 78 79 if (this->fragmentShader != 0) 96 if (likely (this->getProgram() != 0)) 80 97 { 81 glDetachObjectARB(this->shaderProgram, this->fragmentShader); 82 glDeleteObjectARB(this->fragmentShader); 83 } 84 if (this->vertexShader != 0) 85 { 86 glDetachObjectARB(this->shaderProgram, this->vertexShader); 87 glDeleteObjectARB(this->vertexShader); 88 } 89 if (this->shaderProgram != 0) 90 { 91 GLint status = 0; 92 //glLinkProgramARB(this->shaderProgram); 93 glDeleteObjectARB(this->shaderProgram); 94 // link error checking 95 glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_DELETE_STATUS_ARB, &status); 96 if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION) 97 this->printError(this->shaderProgram); 98 } 99 } 100 101 Shader* Shader::getShader(const std::string& vertexShaderFile, const std::string& fragmentShaderFile) 102 { 103 return (Shader*)ResourceManager::getInstance()->load(vertexShaderFile, SHADER, RP_LEVEL, fragmentShaderFile); 104 } 105 106 bool Shader::unload(Shader* shader) 107 { 108 return ResourceManager::getInstance()->unload(shader); 109 } 110 111 Shader* Shader::storedShader = NULL; 112 113 114 bool Shader::loadShaderProgramm(Shader::Type type, const std::string& fileName) 115 { 116 GLhandleARB shader = 0; 117 118 if (type != Shader::Vertex && type != Shader::Fragment) 119 return false; 120 this->deleteProgram(type); 121 122 123 std::string program; 124 if (!readShader(fileName, program)) 125 return false; 126 127 if (type == Shader::Vertex && GLEW_ARB_vertex_shader) 128 { 129 this->vertexShaderFile = fileName; 130 131 shader = this->vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); 132 } 133 134 if (type == Shader::Fragment && GLEW_ARB_fragment_shader) 135 { 136 this->fragmentShaderFile = fileName; 137 138 shader = this->fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); 139 } 140 141 if (shader != 0) 142 { 143 GLint status = 0; 144 const char* prog = program.c_str(); 145 146 glShaderSourceARB(shader, 1, &prog, NULL); 147 glCompileShaderARB(shader); 148 // checking on error. 149 glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); 150 if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION) 151 this->printError(shader); 152 else 153 glAttachObjectARB(this->shaderProgram, shader); 154 } 155 return true; 156 } 157 158 159 void Shader::linkShaderProgram() 160 { 161 GLint status = 0; 162 163 glLinkProgramARB(this->shaderProgram); 164 // link error checking 165 glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &status); 166 if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION) 167 this->printError(this->shaderProgram); 168 } 169 170 171 bool Shader::readShader(const std::string& fileName, std::string& output) 172 { 173 char lineBuffer[PARSELINELENGTH]; 174 175 std::ifstream shader; 176 shader.open(fileName.c_str()); 177 if (!shader.is_open()) 178 return false; 179 180 181 while (!shader.eof()) 182 { 183 shader.getline(lineBuffer, PARSELINELENGTH); 184 output += lineBuffer; 185 output += "\n"; 186 } 187 188 189 shader.close(); 190 return true; 191 } 192 193 194 195 void Shader::activateShader() 196 { 197 if (likely (this->shaderProgram != 0)) 198 { 199 glUseProgramObjectARB(this->shaderProgram); 98 glUseProgramObjectARB(this->getProgram()); 200 99 Shader::storedShader = this; 201 100 } 202 101 } 203 204 void Shader::bindShader(const char* name, const float* value, size_t size)205 {206 if (likely (this->shaderProgram != 0)) {207 glUseProgramObjectARB(this->shaderProgram);208 209 unsigned int location = glGetUniformLocationARB(this->shaderProgram, name);210 /* This is EXPENSIVE and should be avoided. */211 212 if (size == 1) glUniform1fvARB(location, 1, value);213 else if (size == 2) glUniform2fvARB(location, 1, value);214 else if (size == 3) glUniform3fvARB(location, 1, value);215 else if (size == 4) glUniform4fvARB(location, 1, value);216 else if (size == 9) glUniformMatrix3fvARB(location, 1, false, value);217 else if (size == 16) glUniformMatrix4fvARB(location, 1, false, value);218 219 }220 }221 222 102 void Shader::deactivateShader() 223 103 { 224 if (storedShader != NULL) 225 glUseProgramObjectARB(0); 226 Shader::storedShader = NULL; 227 } 228 229 230 void Shader::deleteProgram(Shader::Type type) 231 { 232 GLint status = 0; 233 if (type == Shader::Vertex && this->vertexShader != 0) 234 { 235 this->vertexShaderFile = ""; 236 glDetachObjectARB(this->shaderProgram, this->vertexShader); 237 glDeleteObjectARB(this->vertexShader); 238 glGetObjectParameterivARB(this->vertexShader, GL_OBJECT_DELETE_STATUS_ARB, &status); 239 if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION) 240 Shader::printError(this->vertexShader); 241 this->vertexShader = 0; 242 } 243 else if (type == Shader::Fragment && this->fragmentShader != 0) 244 { 245 this->fragmentShaderFile = ""; 246 glDetachObjectARB(this->shaderProgram, this->fragmentShader); 247 glDeleteObjectARB(this->fragmentShader); 248 glGetObjectParameterivARB(this->fragmentShader, GL_OBJECT_DELETE_STATUS_ARB, &status); 249 if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION) 250 Shader::printError(this->fragmentShader); 251 this->fragmentShader = 0; 252 } 253 else 254 return; 255 } 256 257 258 void Shader::printError(GLhandleARB program) 259 { 260 if (program == 0) 261 return; 262 263 int infologLength = 0; 264 int charsWritten = 0; 265 char *infoLog; 266 267 glGetObjectParameterivARB(program, GL_OBJECT_INFO_LOG_LENGTH_ARB, 268 &infologLength); 269 270 if (infologLength > 0) 271 { 272 infoLog = new char[infologLength+1]; 273 glGetInfoLogARB(program, infologLength, &charsWritten, infoLog); 274 printf("%s\n", infoLog); 275 delete[] infoLog; 276 } 104 if (storedShader != NULL) 105 glUseProgramObjectARB(0); 106 Shader::storedShader = NULL; 277 107 } 278 108 … … 288 118 } 289 119 290 void Shader::debug() const291 {292 PRINT(3)("Shader info: (SHADER: %d)\n", this->shaderProgram);293 if (this->vertexShader != 0)294 {295 /* PRINT(3)("VertexShaderProgramm: number=%d, file='%s'\n", this->vertexShader, this->vertexShaderFile);296 if (this->vertexShaderSource != NULL)297 for (unsigned int i = 0; i < this->vertexShaderSource->getCount(); i++)298 PRINT(3)("%d: %s\n", i, this->vertexShaderSource->getEntry(i));299 }300 if (this->fragmentShader != 0)301 {302 PRINT(3)("FragmentShaderProgramm: number=%d, file='%s'\n", this->fragmentShader, this->fragmentShaderFile);303 if (this->fragmentShaderSource != NULL)304 for (unsigned int i = 0; i < this->fragmentShaderSource->getCount(); i++)305 PRINT(3)("%d: %s\n", i, this->fragmentShaderSource->getEntry(i));*/306 }307 }308 120
Note: See TracChangeset
for help on using the changeset viewer.