126 lines
2.5 KiB
C++
126 lines
2.5 KiB
C++
#include "Program.h"
|
|
|
|
#include <iostream>
|
|
#include <cassert>
|
|
|
|
#include "GLSL.h"
|
|
|
|
using namespace std;
|
|
|
|
Program::Program() :
|
|
vShaderName(""),
|
|
fShaderName(""),
|
|
pid(0),
|
|
verbose(true)
|
|
{
|
|
|
|
}
|
|
|
|
Program::~Program()
|
|
{
|
|
|
|
}
|
|
|
|
void Program::setShaderNames(const string &v, const string &f)
|
|
{
|
|
vShaderName = v;
|
|
fShaderName = f;
|
|
}
|
|
|
|
bool Program::init()
|
|
{
|
|
GLint rc;
|
|
|
|
// Create shader handles
|
|
GLuint VS = glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint FS = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
// Read shader sources
|
|
const char *vshader = GLSL::textFileRead(vShaderName.c_str());
|
|
const char *fshader = GLSL::textFileRead(fShaderName.c_str());
|
|
glShaderSource(VS, 1, &vshader, NULL);
|
|
glShaderSource(FS, 1, &fshader, NULL);
|
|
|
|
// Compile vertex shader
|
|
glCompileShader(VS);
|
|
glGetShaderiv(VS, GL_COMPILE_STATUS, &rc);
|
|
if(!rc) {
|
|
if(isVerbose()) {
|
|
GLSL::printShaderInfoLog(VS);
|
|
cout << "Error compiling vertex shader " << vShaderName << endl;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Compile fragment shader
|
|
glCompileShader(FS);
|
|
glGetShaderiv(FS, GL_COMPILE_STATUS, &rc);
|
|
if(!rc) {
|
|
if(isVerbose()) {
|
|
GLSL::printShaderInfoLog(FS);
|
|
cout << "Error compiling fragment shader " << fShaderName << endl;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Create the program and link
|
|
pid = glCreateProgram();
|
|
glAttachShader(pid, VS);
|
|
glAttachShader(pid, FS);
|
|
glLinkProgram(pid);
|
|
glGetProgramiv(pid, GL_LINK_STATUS, &rc);
|
|
if(!rc) {
|
|
if(isVerbose()) {
|
|
GLSL::printProgramInfoLog(pid);
|
|
cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
GLSL::checkError(GET_FILE_LINE);
|
|
return true;
|
|
}
|
|
|
|
void Program::bind()
|
|
{
|
|
glUseProgram(pid);
|
|
}
|
|
|
|
void Program::unbind()
|
|
{
|
|
glUseProgram(0);
|
|
}
|
|
|
|
void Program::addAttribute(const string &name)
|
|
{
|
|
attributes[name] = glGetAttribLocation(pid, name.c_str());
|
|
}
|
|
|
|
void Program::addUniform(const string &name)
|
|
{
|
|
uniforms[name] = glGetUniformLocation(pid, name.c_str());
|
|
}
|
|
|
|
GLint Program::getAttribute(const string &name) const
|
|
{
|
|
map<string,GLint>::const_iterator attribute = attributes.find(name.c_str());
|
|
if(attribute == attributes.end()) {
|
|
if(isVerbose()) {
|
|
cout << name << " is not an attribute variable" << endl;
|
|
}
|
|
return -1;
|
|
}
|
|
return attribute->second;
|
|
}
|
|
|
|
GLint Program::getUniform(const string &name) const
|
|
{
|
|
map<string,GLint>::const_iterator uniform = uniforms.find(name.c_str());
|
|
if(uniform == uniforms.end()) {
|
|
if(isVerbose()) {
|
|
cout << name << " is not a uniform variable" << endl;
|
|
}
|
|
return -1;
|
|
}
|
|
return uniform->second;
|
|
}
|