KWin
program.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00048
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
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
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
00096 glLinkProgram(glId());
00097
00098 int linked;
00099 glGetProgramiv(glId(), GL_LINK_STATUS, &linked);
00100 mValid = linked;
00101
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