GLSLProgram.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <GLSL/GLSLProgram.h>
00022 #include <GLEXT/GLStateExtension.h>
00023 #include <common/Logger.h>
00024 #include <common/Defines.h>
00025 
00026 const GLSLProgram* GLSLProgram::used_program_(0);
00027 
00028 GLSLProgram::GLSLProgram() : 
00029         id_(0), linked_(false)
00030 {
00031         DIALOG_ASSERT(GLStateExtension::hasShaders());
00032 
00033         id_ = glCreateProgram();
00034 
00035         DIALOG_ASSERT(id_);// ("can't create glsl program");
00036 }
00037 
00038 GLSLProgram::~GLSLProgram()
00039 {
00040         if (used_program_ == this) 
00041         {
00042                 // rather use some kind of "bug!"-exception here
00043                 Logger::log("warning: deleting bound glsl program!");
00044                 use_fixed();
00045         }
00046         // if shaders are still attached, it is rather a bug...
00047         std::list<GLSLShader*>::iterator it;
00048         for (it = attached_shaders_.begin(); 
00049                 it != attached_shaders_.end(); 
00050                 it++)
00051         {
00052                 glDetachShader(id_, (*it)->getId());
00053         }
00054 
00055         glDeleteProgram(id_);
00056 }
00057 
00058 void GLSLProgram::attach(GLSLShader &s)
00059 {
00060         glAttachShader(id_, s.getId());
00061         attached_shaders_.push_front(&s);
00062         linked_ = false;
00063 }
00064 
00065 void GLSLProgram::detach(GLSLShader &s)
00066 {
00067         glDetachShader(id_, s.getId());
00068 
00069         std::list<GLSLShader*>::iterator it;
00070         for (it = attached_shaders_.begin(); 
00071                 it != attached_shaders_.end(); )
00072         {
00073                 if (*it == &s) 
00074                 {
00075                         glDetachShader(id_, (*it)->getId());
00076                         it = attached_shaders_.erase(it);
00077                 } else 
00078                 {
00079                         it++;
00080                 }
00081         }
00082         linked_ = false;
00083 }
00084 
00085 void GLSLProgram::link()
00086 {
00087         glLinkProgram(id_);
00088         GLint waslinked = GL_FALSE;
00089         glGetProgramiv(id_, GL_LINK_STATUS, &waslinked);
00090 
00091         if (!waslinked) 
00092         {
00093                 GLint maxlength = 0;
00094                 glGetProgramiv(id_, GL_INFO_LOG_LENGTH, &maxlength);
00095                 std::string log(maxlength+1, ' ');
00096                 GLsizei length = 0;
00097                 glGetProgramInfoLog(id_, maxlength, &length, &log[0]);
00098                 S3D::dialogExit("GLSLProgram", 
00099                         S3D::formatStringBuffer("linking of program failed : %s", log.c_str()));
00100         }
00101 
00102         linked_ = true;
00103 }
00104 
00105 void GLSLProgram::use() const
00106 {
00107         DIALOG_ASSERT(linked_);
00108         glUseProgram(id_);
00109         used_program_ = this;
00110 }
00111 
00112 void GLSLProgram::set_gl_texture(GLTexture &tex, const char *texname, unsigned texunit) const
00113 {
00114         DIALOG_ASSERT(used_program_ == this);
00115 
00116         GLint uniloc = glGetUniformLocation(id_, texname);
00117         glActiveTexture(GL_TEXTURE0 + texunit);
00118         tex.draw(true);
00119         glUniform1i(uniloc, texunit);
00120 }
00121 
00122 void GLSLProgram::set_gl_texture(GLShadowFrameBuffer &tex, const char *texname, unsigned texunit) const
00123 {
00124         DIALOG_ASSERT(used_program_ == this);
00125 
00126         GLint uniloc = glGetUniformLocation(id_, texname);
00127         glActiveTexture(GL_TEXTURE0 + texunit);
00128         tex.bindDepthTexture();
00129         glUniform1i(uniloc, texunit);
00130 }
00131 
00132 void GLSLProgram::set_gl_texture_unit(const char *texname, unsigned texunit) const
00133 {
00134         DIALOG_ASSERT(used_program_ == this);
00135 
00136         GLint uniloc = glGetUniformLocation(id_, texname);
00137         glActiveTexture(GL_TEXTURE0 + texunit);
00138         glUniform1i(uniloc, texunit);
00139 }
00140 
00141 void GLSLProgram::set_uniform(const char *name, const Vector& value) const
00142 {
00143         DIALOG_ASSERT(used_program_ == this);
00144 
00145         GLint loc = glGetUniformLocation(id_, name);
00146         glUniform3f(loc, value[0], value[1], value[2]);
00147 }
00148 
00149 void GLSLProgram::set_uniform(const char *name, const float value) const
00150 {
00151         DIALOG_ASSERT(used_program_ == this);
00152 
00153         GLint loc = glGetUniformLocation(id_, name);
00154         glUniform1f(loc, value);
00155 }
00156 
00157 unsigned GLSLProgram::get_vertex_attrib_index(const char *name) const
00158 {
00159         DIALOG_ASSERT(used_program_ == this);
00160 
00161         return glGetAttribLocation(id_, name);
00162 }
00163 
00164 void GLSLProgram::use_fixed()
00165 {
00166         glUseProgram(0);
00167         used_program_ = 0;
00168 }

Generated on Mon Feb 16 15:14:45 2009 for Scorched3D by  doxygen 1.5.3