• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KWin

program.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Rivo Laks <rivolaks@hot.ee>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either 
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public 
00015  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include "program.h"
00019 
00020 #include <shader.h>
00021 #include "renderer.h"
00022 
00023 #include <qlist.h>
00024 #include <qstring.h>
00025 #include <qhash.h>
00026 #include <QtDebug>
00027 
00028 
00029 namespace KGLLib
00030 {
00031 
00032 Program::Program()
00033 {
00034     init();
00035 }
00036 
00037 Program::Program(const QList<Shader*>& shaders)
00038 {
00039     init();
00040     addShaders(shaders);
00041     link();
00042 }
00043 
00044 Program::Program(const QString& vertexshaderfile, const QString& fragmentshaderfile)
00045 {
00046     init();
00047     // Load both shaders, even if one is invalid. This way developer can see
00048     //  any errors/warnings for both shaders at once.
00049     VertexShader vs(vertexshaderfile);
00050     FragmentShader fs(fragmentshaderfile);
00051     if (!vs.isValid() || !fs.isValid()) {
00052         return;
00053     }
00054     addShader(&vs);
00055     addShader(&fs);
00056     link();
00057 }
00058 
00059 Program::~Program()
00060 {
00061     glDeleteProgram(glId());
00062     delete[] mLinkLog;
00063     delete mUniformLocations;
00064     delete mAttributeLocations;
00065 }
00066 
00067 void Program::init()
00068 {
00069     // Create program object
00070     mGLId = glCreateProgram();
00071     mValid = false;
00072     mLinkLog = 0;
00073     mUniformLocations = mAttributeLocations = 0;
00074 }
00075 
00076 void Program::addShader(Shader* shader)
00077 {
00078     if (!shader->isValid()) {
00079         qCritical() << "Program::addShader(): Cannot add invalid shader";
00080         return;
00081     }
00082     // Attach the shader to the program
00083     glAttachShader(glId(), shader->glId());
00084 }
00085 
00086 void Program::addShaders(const QList<Shader*>& shaders)
00087 {
00088     foreach (Shader* s, shaders) {
00089         addShader(s);
00090     }
00091 }
00092 
00093 bool Program::link()
00094 {
00095     // Link the program
00096     glLinkProgram(glId());
00097     // Make sure it linked correctly
00098     int linked;
00099     glGetProgramiv(glId(), GL_LINK_STATUS, &linked);
00100     mValid = linked;
00101     // Get info log
00102     GLsizei logsize, logarraysize;
00103     glGetProgramiv(glId(), GL_INFO_LOG_LENGTH, &logarraysize);
00104     mLinkLog = new char[logarraysize];
00105     glGetProgramInfoLog(glId(), logarraysize, &logsize, mLinkLog);
00106     if (!mValid) {
00107         qCritical() << "Program::link(): Couldn't link program. Log follows:" << endl << mLinkLog;
00108     } else {
00109         mUniformLocations = new QHash<QString, int>;
00110         mAttributeLocations = new QHash<QString, int>;
00111     }
00112     if (!logsize) {
00113         delete[] mLinkLog;
00114         mLinkLog = 0;
00115     }
00116     return mValid;
00117 }
00118 
00119 void Program::bind() const
00120 {
00121     renderer->bindProgram(this);
00122 }
00123 
00124 void Program::unbind() const
00125 {
00126     renderer->bindProgram(0);
00127 }
00128 
00129 int Program::uniformLocation(const QString& name)
00130 {
00131     return uniformLocation(name.toLatin1().data());
00132 }
00133 
00134 int Program::uniformLocation(const char* name)
00135 {
00136     if (!mValid) {
00137         return -1;
00138     }
00139     if (!mUniformLocations->contains(name)) {
00140         int location = glGetUniformLocation(glId(), name);
00141         mUniformLocations->insert(name, location);
00142     }
00143     return mUniformLocations->value(name);
00144 }
00145 
00146 int Program::attributeLocation(const QString& name)
00147 {
00148     return attributeLocation(name.toLatin1().data());
00149 }
00150 
00151 int Program::attributeLocation(const char* name)
00152 {
00153     if (!mValid) {
00154         return -1;
00155     }
00156     if (!mAttributeLocations->contains(name)) {
00157         int location = glGetAttribLocation(glId(), name);
00158         mAttributeLocations->insert(name, location);
00159     }
00160     return mAttributeLocations->value(name);
00161 }
00162 
00163 void Program::invalidateLocations()
00164 {
00165     mUniformLocations->clear();
00166     mAttributeLocations->clear();
00167 }
00168 
00169 bool Program::setUniform(const char* name, float value)
00170 {
00171     int location = uniformLocation(name);
00172     if (location >= 0) {
00173         glUniform1f(location, value);
00174     }
00175     return (location >= 0);
00176 }
00177 
00178 bool Program::setUniform(const char* name, Eigen::Vector2f value)
00179 {
00180     int location = uniformLocation(name);
00181     if (location >= 0) {
00182         glUniform2fv(location, 1, value.array());
00183     }
00184     return (location >= 0);
00185 }
00186 
00187 bool Program::setUniform(const char* name, Eigen::Vector3f value)
00188 {
00189     int location = uniformLocation(name);
00190     if (location >= 0) {
00191         glUniform3fv(location, 1, value.array());
00192     }
00193     return (location >= 0);
00194 }
00195 
00196 bool Program::setUniform(const char* name, Eigen::Vector4f value)
00197 {
00198     int location = uniformLocation(name);
00199     if (location >= 0) {
00200         glUniform4fv(location, 1, value.array());
00201     }
00202     return (location >= 0);
00203 }
00204 
00205 bool Program::setUniform(const char* name, int value)
00206 {
00207     int location = uniformLocation(name);
00208     if (location >= 0) {
00209         glUniform1i(location, value);
00210     }
00211     return (location >= 0);
00212 }
00213 
00214 }
00215 

KWin

Skip menu "KWin"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal