Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/shader.cc @ 6774

Last change on this file since 6774 was 6645, checked in by bensch, 19 years ago

orxonox/trunk: totally remastered the ResourceManager.
Now it takes MultiTypes instead of (void*) as parameters

  1. This is TypeSafe
  2. This is easier to use
  3. This makes much more sense, and is objectOriented

also made some minor adjustments to the MultiType, some comparisons

also fixed the loading in all the Other classes like material md2 and so on

File size: 8.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shader.h"
19
20#include "stdlibincl.h"
21#include "compiler.h"
22#include <stdio.h>
23#include "debug.h"
24#include "array.h"
25
26#include "resource_manager.h"
27
28
29#ifndef PARSELINELENGHT
30#define PARSELINELENGHT     512       //!< how many chars to read at once
31#endif
32
33using namespace std;
34
35
36/**
37 * standard constructor
38*/
39Shader::Shader (const char* vertexShaderFile, const char* fragmentShaderFile)
40{
41   this->setClassID(CL_SHADER, "Shader");
42
43   this->fragmentShaderFile = NULL;
44   this->vertexShaderFile = NULL;
45   this->shaderProgram = 0;
46   this->vertexShader = 0;
47   this->fragmentShader = 0;
48
49   if (GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100)
50     {
51       GLint status = 0;
52
53       this->shaderProgram = glCreateProgramObjectARB();
54
55       if (vertexShaderFile != NULL)
56         this->loadShaderProgramm(SHADER_VERTEX, vertexShaderFile);
57       if (fragmentShaderFile != NULL)
58         this->loadShaderProgramm(SHADER_FRAGMENT, fragmentShaderFile);
59       glLinkProgramARB(this->shaderProgram);
60       // link error checking
61       glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &status);
62       if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
63         this->printError(this->shaderProgram);
64    }
65   else
66     {
67       PRINTF(2)("Shaders are not supported on your hardware\n");
68     }
69}
70
71
72/**
73 * standard deconstructor
74 */
75Shader::~Shader ()
76{
77  if (this->shaderProgram == glGetHandleARB(GL_PROGRAM_OBJECT_ARB))
78    Shader::deactivateShader();
79
80  // delete what has to be deleted here
81  this->deleteProgram(SHADER_VERTEX);
82  this->deleteProgram(SHADER_FRAGMENT);
83
84  if (this->fragmentShader != 0)
85  {
86    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
87    glDeleteObjectARB(this->fragmentShader);
88  }
89  if (this->vertexShader != 0)
90  {
91    glDetachObjectARB(this->shaderProgram, this->vertexShader);
92    glDeleteObjectARB(this->vertexShader);
93  }
94  if (this->shaderProgram != 0)
95  {
96    GLint status = 0;
97    //glLinkProgramARB(this->shaderProgram);
98    glDeleteObjectARB(this->shaderProgram);
99       // link error checking
100    glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_DELETE_STATUS_ARB, &status);
101    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
102      this->printError(this->shaderProgram);
103  }
104}
105
106Shader* Shader::getShader(const char* vertexShaderFile, const char* fragmentShaderFile)
107{
108  return (Shader*)ResourceManager::getInstance()->load(vertexShaderFile, SHADER,  RP_LEVEL, fragmentShaderFile);
109}
110
111bool Shader::unload(Shader* shader)
112{
113  return ResourceManager::getInstance()->unload(shader);
114}
115
116Shader* Shader::storedShader = NULL;
117
118
119bool Shader::loadShaderProgramm(SHADER_TYPE type, const char* fileName)
120{
121  GLhandleARB shader = 0;
122
123  if (type != SHADER_VERTEX && type != SHADER_FRAGMENT)
124    return false;
125  this->deleteProgram(type);
126
127
128  tArray<char*>* program = fileReadArray(fileName);
129  if (program == NULL)
130    return false;
131
132  if (type == SHADER_VERTEX && GLEW_ARB_vertex_shader)
133  {
134    this->vertexShaderFile = new char[strlen(fileName)+1];
135    strcpy(this->vertexShaderFile, fileName);
136
137    shader = this->vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
138  }
139
140  if (type == SHADER_FRAGMENT && GLEW_ARB_fragment_shader)
141  {
142    this->fragmentShaderFile = new char[strlen(fileName)+1];
143    strcpy(this->fragmentShaderFile, fileName);
144
145    shader = this->fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
146  }
147
148  if (shader != 0)
149  {
150    GLint status = 0;
151    glShaderSourceARB(shader, program->getCount(), (const char**)program->getArray(), NULL);
152    glCompileShaderARB(shader);
153    // checking on error.
154    glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
155    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
156      this->printError(shader);
157    else
158      glAttachObjectARB(this->shaderProgram, shader);
159  }
160  for (unsigned int i=0; i< program->getCount(); i++)
161    delete[] program->getArray()[i];
162  delete program;
163}
164
165char* Shader::fileRead(const char* fileName)
166{
167  FILE* fileHandle;
168  char* content = NULL;
169
170  int count = 0;
171
172  if (fileName == NULL)
173    return NULL;
174
175  fileHandle = fopen(fileName, "rt");
176
177  if (fileHandle == NULL)
178    return NULL;
179  fseek(fileHandle, 0, SEEK_END);
180  count = ftell(fileHandle);
181  rewind(fileHandle);
182  if (count > 0) {
183     content = new char[count+1];
184     count = fread(content, sizeof(char), count, fileHandle);
185     content[count] = '\0';
186   }
187   fclose(fileHandle);
188 return content;
189}
190
191
192tArray<char*>* Shader::fileReadArray(const char* fileName)
193{
194  FILE*    stream;           //< The stream we use to read the file.
195
196  if( (stream = fopen (fileName, "rt")) == NULL)
197  {
198    PRINTF(1)("Shader could not open %s\n", fileName);
199    return NULL;
200  }
201  tArray<char*>* file = new tArray<char*>;
202
203  char lineBuffer[PARSELINELENGHT];
204  char* addString;
205  while(fgets (lineBuffer, PARSELINELENGHT, stream) != NULL)
206  {
207    addString = new char[strlen(lineBuffer)+1];
208    strcpy(addString, lineBuffer);
209    file->addEntry(addString);
210  }
211  fclose(stream);
212  file->finalizeArray();
213  return file;
214}
215
216
217
218void Shader::activateShader()
219{
220  if (likely (this->shaderProgram != 0))
221  {
222    glUseProgramObjectARB(this->shaderProgram);
223    Shader::storedShader = this;
224  }
225}
226
227void Shader::deactivateShader()
228{
229 if (storedShader != NULL)
230   glUseProgramObjectARB(0);
231 Shader::storedShader = NULL;
232}
233
234
235void Shader::deleteProgram(SHADER_TYPE type)
236{
237  GLint status = 0;
238  if (type == SHADER_VERTEX && this->vertexShader != 0)
239  {
240    delete[] this->vertexShaderFile;
241    this->vertexShaderFile = NULL;
242    glDetachObjectARB(this->shaderProgram, this->vertexShader);
243    glDeleteObjectARB(this->vertexShader);
244    glGetObjectParameterivARB(this->vertexShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
245    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
246      Shader::printError(this->vertexShader);
247    this->vertexShader = 0;
248  }
249  else if (type == SHADER_FRAGMENT && this->fragmentShader != 0)
250  {
251    delete[] this->fragmentShaderFile;
252    this->fragmentShaderFile = NULL;
253    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
254    glDeleteObjectARB(this->fragmentShader);
255    glGetObjectParameterivARB(this->fragmentShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
256    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
257      Shader::printError(this->fragmentShader);
258    this->fragmentShader = 0;
259  }
260  else
261    return;
262}
263
264
265void Shader::printError(GLhandleARB program)
266{
267  if (program == 0)
268    return;
269
270  int infologLength = 0;
271  int charsWritten  = 0;
272  char *infoLog;
273
274  glGetObjectParameterivARB(program, GL_OBJECT_INFO_LOG_LENGTH_ARB,
275                            &infologLength);
276
277  if (infologLength > 0)
278  {
279    infoLog = new char[infologLength+1];
280    glGetInfoLogARB(program, infologLength, &charsWritten, infoLog);
281    printf("%s\n", infoLog);
282    delete[] infoLog;
283  }
284}
285
286bool Shader::checkShaderAbility()
287{
288  if (GLEW_ARB_shader_objects &&
289      GLEW_ARB_shading_language_100 &&
290      GLEW_ARB_vertex_shader &&
291      GLEW_ARB_fragment_shader)
292    return true;
293  else
294    return false;
295}
296
297void Shader::debug() const
298{
299  PRINT(3)("Shader info: (SHADER: %d)\n", this->shaderProgram);
300  if (this->vertexShader != 0)
301  {
302/*    PRINT(3)("VertexShaderProgramm: number=%d, file='%s'\n", this->vertexShader, this->vertexShaderFile);
303    if (this->vertexShaderSource != NULL)
304      for (unsigned int i = 0; i < this->vertexShaderSource->getCount(); i++)
305        PRINT(3)("%d: %s\n", i, this->vertexShaderSource->getEntry(i));
306  }
307  if (this->fragmentShader != 0)
308  {
309    PRINT(3)("FragmentShaderProgramm: number=%d, file='%s'\n", this->fragmentShader, this->fragmentShaderFile);
310    if (this->fragmentShaderSource != NULL)
311      for (unsigned int i = 0; i < this->fragmentShaderSource->getCount(); i++)
312        PRINT(3)("%d: %s\n", i, this->fragmentShaderSource->getEntry(i));*/
313  }
314}
315
Note: See TracBrowser for help on using the repository browser.