Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6987 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
RevLine 
[4744]1/*
[1853]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.
[1855]10
11   ### File Specific:
[5261]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[5261]18#include "shader.h"
[1853]19
[5262]20#include "stdlibincl.h"
[5273]21#include "compiler.h"
[5262]22#include <stdio.h>
23#include "debug.h"
[5318]24#include "array.h"
[5262]25
[5323]26#include "resource_manager.h"
[5262]27
[5323]28
[5262]29#ifndef PARSELINELENGHT
30#define PARSELINELENGHT     512       //!< how many chars to read at once
31#endif
32
[1856]33using namespace std;
[1853]34
[1856]35
[3245]36/**
[4838]37 * standard constructor
[3245]38*/
[5262]39Shader::Shader (const char* vertexShaderFile, const char* fragmentShaderFile)
[3365]40{
[5261]41   this->setClassID(CL_SHADER, "Shader");
[4320]42
[5261]43   this->fragmentShaderFile = NULL;
44   this->vertexShaderFile = NULL;
45   this->shaderProgram = 0;
46   this->vertexShader = 0;
47   this->fragmentShader = 0;
[5262]48
[5263]49   if (GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100)
[5273]50     {
[5320]51       GLint status = 0;
52
[5273]53       this->shaderProgram = glCreateProgramObjectARB();
[5263]54
[5273]55       if (vertexShaderFile != NULL)
[5285]56         this->loadShaderProgramm(SHADER_VERTEX, vertexShaderFile);
[5273]57       if (fragmentShaderFile != NULL)
[5285]58         this->loadShaderProgramm(SHADER_FRAGMENT, fragmentShaderFile);
[5320]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    }
[5273]65   else
66     {
67       PRINTF(2)("Shaders are not supported on your hardware\n");
68     }
[3365]69}
[1853]70
71
[3245]72/**
[4838]73 * standard deconstructor
[5318]74 */
[5261]75Shader::~Shader ()
[3543]76{
[5322]77  if (this->shaderProgram == glGetHandleARB(GL_PROGRAM_OBJECT_ARB))
[5318]78    Shader::deactivateShader();
79
[3543]80  // delete what has to be deleted here
[5262]81  this->deleteProgram(SHADER_VERTEX);
82  this->deleteProgram(SHADER_FRAGMENT);
[5263]83
[5273]84  if (this->fragmentShader != 0)
[5322]85  {
86    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
[5273]87    glDeleteObjectARB(this->fragmentShader);
[5322]88  }
[5273]89  if (this->vertexShader != 0)
[5322]90  {
91    glDetachObjectARB(this->shaderProgram, this->vertexShader);
[5273]92    glDeleteObjectARB(this->vertexShader);
[5322]93  }
[5273]94  if (this->shaderProgram != 0)
[5321]95  {
96    GLint status = 0;
[5322]97    //glLinkProgramARB(this->shaderProgram);
[5273]98    glDeleteObjectARB(this->shaderProgram);
[5321]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  }
[3543]104}
[5261]105
[5323]106Shader* Shader::getShader(const char* vertexShaderFile, const char* fragmentShaderFile)
107{
[6645]108  return (Shader*)ResourceManager::getInstance()->load(vertexShaderFile, SHADER,  RP_LEVEL, fragmentShaderFile);
[5323]109}
110
111bool Shader::unload(Shader* shader)
112{
113  return ResourceManager::getInstance()->unload(shader);
114}
115
[5317]116Shader* Shader::storedShader = NULL;
[5261]117
[5317]118
[5261]119bool Shader::loadShaderProgramm(SHADER_TYPE type, const char* fileName)
120{
[5319]121  GLhandleARB shader = 0;
[5285]122
[5262]123  if (type != SHADER_VERTEX && type != SHADER_FRAGMENT)
[5261]124    return false;
[5262]125  this->deleteProgram(type);
[5261]126
127
[5390]128  tArray<char*>* program = fileReadArray(fileName);
[5271]129  if (program == NULL)
130    return false;
[5318]131
[5266]132  if (type == SHADER_VERTEX && GLEW_ARB_vertex_shader)
[5262]133  {
134    this->vertexShaderFile = new char[strlen(fileName)+1];
135    strcpy(this->vertexShaderFile, fileName);
136
[5269]137    shader = this->vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
[5263]138  }
[5262]139
[5263]140  if (type == SHADER_FRAGMENT && GLEW_ARB_fragment_shader)
141  {
[5266]142    this->fragmentShaderFile = new char[strlen(fileName)+1];
143    strcpy(this->fragmentShaderFile, fileName);
144
[5269]145    shader = this->fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
[5263]146  }
[5273]147
148  if (shader != 0)
[5319]149  {
[5320]150    GLint status = 0;
[5321]151    glShaderSourceARB(shader, program->getCount(), (const char**)program->getArray(), NULL);
[5320]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);
[5319]159  }
160  for (unsigned int i=0; i< program->getCount(); i++)
161    delete[] program->getArray()[i];
162  delete program;
[5261]163}
164
[5266]165char* Shader::fileRead(const char* fileName)
[5261]166{
[5266]167  FILE* fileHandle;
168  char* content = NULL;
169
170  int count = 0;
171
[5271]172  if (fileName == NULL)
173    return NULL;
[5266]174
[5271]175  fileHandle = fopen(fileName, "rt");
[5266]176
[5271]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;
[5266]189}
190
[5318]191
[5390]192tArray<char*>* Shader::fileReadArray(const char* fileName)
[5318]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  }
[5390]201  tArray<char*>* file = new tArray<char*>;
[5318]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
[5266]218void Shader::activateShader()
219{
[5273]220  if (likely (this->shaderProgram != 0))
[5317]221  {
[5273]222    glUseProgramObjectARB(this->shaderProgram);
[5317]223    Shader::storedShader = this;
224  }
[5261]225}
[5262]226
[5266]227void Shader::deactivateShader()
228{
[5364]229 if (storedShader != NULL)
230   glUseProgramObjectARB(0);
231 Shader::storedShader = NULL;
[5266]232}
[5262]233
[5266]234
[5262]235void Shader::deleteProgram(SHADER_TYPE type)
236{
[5335]237  GLint status = 0;
[5273]238  if (type == SHADER_VERTEX && this->vertexShader != 0)
[5262]239  {
240    delete[] this->vertexShaderFile;
241    this->vertexShaderFile = NULL;
[5321]242    glDetachObjectARB(this->shaderProgram, this->vertexShader);
[5263]243    glDeleteObjectARB(this->vertexShader);
[5320]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);
[5263]247    this->vertexShader = 0;
[5262]248  }
[5273]249  else if (type == SHADER_FRAGMENT && this->fragmentShader != 0)
[5262]250  {
251    delete[] this->fragmentShaderFile;
252    this->fragmentShaderFile = NULL;
[5321]253    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
[5263]254    glDeleteObjectARB(this->fragmentShader);
[5320]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);
[5263]258    this->fragmentShader = 0;
[5262]259  }
260  else
261    return;
262}
263
[5264]264
[5319]265void Shader::printError(GLhandleARB program)
[5264]266{
[5273]267  if (program == 0)
268    return;
269
[5267]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  {
[5283]279    infoLog = new char[infologLength+1];
[5267]280    glGetInfoLogARB(program, infologLength, &charsWritten, infoLog);
[5269]281    printf("%s\n", infoLog);
[5283]282    delete[] infoLog;
[5267]283  }
[5264]284}
285
[5333]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}
[5264]296
[5262]297void Shader::debug() const
298{
299  PRINT(3)("Shader info: (SHADER: %d)\n", this->shaderProgram);
300  if (this->vertexShader != 0)
301  {
[5266]302/*    PRINT(3)("VertexShaderProgramm: number=%d, file='%s'\n", this->vertexShader, this->vertexShaderFile);
[5262]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++)
[5266]312        PRINT(3)("%d: %s\n", i, this->fragmentShaderSource->getEntry(i));*/
[5262]313  }
314}
315
Note: See TracBrowser for help on using the repository browser.