glshader.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:8k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // glshader.cpp
  2. //
  3. // Copyright (C) 2001-2006, Chris Laurel <claurel@shatters.net>
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <iostream>
  10. #include "glshader.h"
  11. #include "gl.h"
  12. #include "glext.h"
  13. using namespace std;
  14. static const string GetInfoLog(GLhandleARB obj);
  15. ostream* g_shaderLogFile = NULL;
  16. GLShader::GLShader(GLhandleARB _id) :
  17.     id(_id)
  18. {
  19. }
  20. GLhandleARB
  21. GLShader::getID() const
  22. {
  23.     return id;
  24. }
  25. GLShaderStatus
  26. GLShader::compile(const vector<string>& source)
  27. {
  28.     if (source.empty())
  29.         return ShaderStatus_EmptyProgram;
  30.     
  31.     // Convert vector of shader source strings to an array for OpenGL
  32.     const char** sourceStrings = new const char*[source.size()];
  33.     for (unsigned int i = 0; i < source.size(); i++)
  34.         sourceStrings[i] = source[i].c_str();
  35.     // Copy shader source to OpenGL
  36.     glx::glShaderSourceARB(id, source.size(), sourceStrings, NULL);
  37.     delete[] sourceStrings;
  38.     // Actually compile the shader
  39.     glx::glCompileShaderARB(id);
  40.     
  41.     GLint compileSuccess;
  42.     glx::glGetObjectParameterivARB(id, GL_OBJECT_COMPILE_STATUS_ARB,
  43.                                    &compileSuccess);
  44.     if (compileSuccess == GL_FALSE)
  45.         return ShaderStatus_CompileError;
  46.     return ShaderStatus_OK;
  47. }
  48. GLShader::~GLShader()
  49. {
  50.     glx::glDeleteObjectARB(id);
  51. }
  52. //************* GLxxxProperty **********
  53. FloatShaderParameter::FloatShaderParameter() :
  54.     slot(-1)
  55. {
  56. }
  57. FloatShaderParameter::FloatShaderParameter(GLhandleARB obj, const char* name)
  58. {
  59.     slot = glx::glGetUniformLocationARB(obj, name);
  60. }
  61. FloatShaderParameter&
  62. FloatShaderParameter::operator=(float f)
  63. {
  64.     if (slot != -1)
  65.         glx::glUniform1fARB(slot, f);
  66.     return *this;
  67. }
  68. Vec3ShaderParameter::Vec3ShaderParameter() :
  69.     slot(-1)
  70. {
  71. }
  72. Vec3ShaderParameter::Vec3ShaderParameter(GLhandleARB obj, const char* name)
  73. {
  74.     slot = glx::glGetUniformLocationARB(obj, name);
  75. }
  76. Vec3ShaderParameter&
  77. Vec3ShaderParameter::operator=(const Vec3f& v)
  78. {
  79.     if (slot != -1)
  80.         glx::glUniform3fARB(slot, v.x, v.y, v.z);
  81.     return *this;
  82. }
  83. Vec3ShaderParameter&
  84. Vec3ShaderParameter::operator=(const Point3f& p)
  85. {
  86.     if (slot != -1)
  87.         glx::glUniform3fARB(slot, p.x, p.y, p.z);
  88.     return *this;
  89. }
  90. Vec4ShaderParameter::Vec4ShaderParameter() :
  91.     slot(-1)
  92. {
  93. }
  94. Vec4ShaderParameter::Vec4ShaderParameter(GLhandleARB obj, const char* name)
  95. {
  96.     slot = glx::glGetUniformLocationARB(obj, name);
  97. }
  98. Vec4ShaderParameter&
  99. Vec4ShaderParameter::operator=(const Vec4f& v)
  100. {
  101.     if (slot != -1)
  102.         glx::glUniform4fARB(slot, v.x, v.y, v.z, v.w);
  103.     return *this;
  104. }
  105. //************* GLProgram **************
  106. GLProgram::GLProgram(GLhandleARB _id) :
  107.     id(_id)
  108. {
  109. }
  110. GLProgram::~GLProgram()
  111. {
  112.     glx::glDeleteObjectARB(id);
  113. }
  114. void
  115. GLProgram::use() const
  116. {
  117.     glx::glUseProgramObjectARB(id);
  118. }
  119. void
  120. GLProgram::attach(const GLShader& shader)
  121. {
  122.     glx::glAttachObjectARB(id, shader.getID());
  123. }
  124. GLShaderStatus
  125. GLProgram::link()
  126. {
  127.     glx::glLinkProgramARB(id);
  128.     GLint linkSuccess;
  129.     glx::glGetObjectParameterivARB(id, GL_OBJECT_LINK_STATUS_ARB,
  130.                                    &linkSuccess);
  131.     if (linkSuccess == GL_FALSE)
  132.     {
  133.         if (g_shaderLogFile != NULL)
  134.         {
  135.             *g_shaderLogFile << "Error linking shader program:n";
  136.             *g_shaderLogFile << GetInfoLog(getID());
  137.         }
  138.         return ShaderStatus_LinkError;
  139.     }
  140.     return ShaderStatus_OK;
  141. }
  142. //************* GLShaderLoader ************
  143. GLShaderStatus
  144. GLShaderLoader::CreateVertexShader(const vector<string>& source,
  145.                                    GLVertexShader** vs)
  146. {
  147.     GLhandleARB vsid = glx::glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
  148.     GLVertexShader* shader = new GLVertexShader(vsid);
  149.     if (!shader)
  150.         return ShaderStatus_OutOfMemory;
  151.     GLShaderStatus status = shader->compile(source);
  152.     if (status != ShaderStatus_OK)
  153.     {
  154.         if (g_shaderLogFile != NULL)
  155.         {
  156.             *g_shaderLogFile << "Error compiling vertex shader:n";
  157.             *g_shaderLogFile << GetInfoLog(shader->getID());
  158.         }
  159.         return status;
  160.     }
  161.     *vs = shader;
  162.     return ShaderStatus_OK;
  163. }
  164. GLShaderStatus
  165. GLShaderLoader::CreateFragmentShader(const vector<string>& source,
  166.                                      GLFragmentShader** fs)
  167. {
  168.     GLhandleARB fsid = glx::glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
  169.     GLFragmentShader* shader = new GLFragmentShader(fsid);
  170.     if (!shader)
  171.         return ShaderStatus_OutOfMemory;
  172.     GLShaderStatus status = shader->compile(source);
  173.     if (status != ShaderStatus_OK)
  174.     {
  175.         if (g_shaderLogFile != NULL)
  176.         {
  177.             *g_shaderLogFile << "Error compiling fragment shader:n";
  178.             *g_shaderLogFile << GetInfoLog(shader->getID());
  179.         }
  180.         return status;
  181.     }
  182.     *fs = shader;
  183.     return ShaderStatus_OK;
  184. }
  185. GLShaderStatus
  186. GLShaderLoader::CreateVertexShader(const string& source,
  187.                                    GLVertexShader** vs)
  188.                                         
  189. {
  190.     vector<string> v;
  191.     v.push_back(source);
  192.     return CreateVertexShader(v, vs);
  193. }
  194. GLShaderStatus
  195. GLShaderLoader::CreateFragmentShader(const string& source,
  196.                                      GLFragmentShader** fs)
  197. {
  198.     vector<string> v;
  199.     v.push_back(source);
  200.     return CreateFragmentShader(v, fs);
  201. }
  202. GLShaderStatus
  203. GLShaderLoader::CreateProgram(const GLVertexShader& vs,
  204.                               const GLFragmentShader& fs,
  205.                               GLProgram** progOut)
  206. {
  207.     GLhandleARB progid = glx::glCreateProgramObjectARB();
  208.     GLProgram* prog = new GLProgram(progid);
  209.     if (!prog)
  210.         return ShaderStatus_OutOfMemory;
  211.     prog->attach(vs);
  212.     prog->attach(fs);
  213.     *progOut = prog;
  214.     return ShaderStatus_OK;
  215. }
  216. GLShaderStatus
  217. GLShaderLoader::CreateProgram(const vector<string>& vsSource,
  218.                               const vector<string>& fsSource,
  219.                               GLProgram** progOut)
  220. {
  221.     GLVertexShader* vs = NULL;
  222.     GLShaderStatus status = CreateVertexShader(vsSource, &vs);
  223.     if (status != ShaderStatus_OK)
  224.         return status;
  225.     GLFragmentShader* fs = NULL;
  226.     status = CreateFragmentShader(fsSource, &fs);
  227.     if (status != ShaderStatus_OK)
  228.     {
  229.         delete vs;
  230.         return status;
  231.     }
  232.     GLProgram* prog = NULL;
  233.     status = CreateProgram(*vs, *fs, &prog);
  234.     if (status != ShaderStatus_OK)
  235.     {
  236.         delete vs;
  237.         delete fs;
  238.         return status;
  239.     }
  240.     *progOut = prog;
  241.     // No need to keep these around--the program doesn't reference them
  242.     delete vs;
  243.     delete fs;
  244.     return ShaderStatus_OK;
  245. }
  246. GLShaderStatus
  247. GLShaderLoader::CreateProgram(const string& vsSource,
  248.                               const string& fsSource,
  249.                               GLProgram** progOut)
  250. {
  251.     vector<string> vsSourceVec;
  252.     vsSourceVec.push_back(vsSource);
  253.     vector<string> fsSourceVec;
  254.     fsSourceVec.push_back(fsSource);
  255.     return CreateProgram(vsSourceVec, fsSourceVec, progOut);
  256. }
  257. const string
  258. GetInfoLog(GLhandleARB obj)
  259. {
  260.     GLint logLength = 0;
  261.     GLsizei charsWritten = 0;
  262.     glx::glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
  263.                                    &logLength);
  264.     if (logLength <= 0)
  265.         return string();
  266.     char* log = new char[logLength];
  267.     if (log == NULL)
  268.         return string();
  269.     
  270.     glx::glGetInfoLogARB(obj, logLength, &charsWritten, log);
  271.     
  272.     string s(log, charsWritten);
  273.     delete[] log;
  274.     
  275.     return s;
  276. }