Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/shader_data.cc @ 9818

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

Switching to new Shader layout, with Shader and ShaderData. Shaders do not render for the time being

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