Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/shader.cc @ 9701

Last change on this file since 9701 was 9685, checked in by bensch, 18 years ago

adapted many classes to the new ClassID System, now comes the hard part… Scripting… then Network… wow this will be so bad :/

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