Browse Source

added attributes, some small fixes

master
Joshua Moerman 13 years ago
parent
commit
9bf9d74b12
  1. 63
      J/shader.h

63
J/shader.h

@ -13,6 +13,7 @@
#include <fstream>
#include <stdexcept>
#include <map>
#include <vector>
#include <iterator>
#import "basic.h"
@ -21,28 +22,25 @@
// TODO: add error checking at set_uniforms?
// TODO: use an uniform map? (benchmark first!)
// TODO: allow arrays is uniforms (now all counts are 1)
// TODO: matrix attributes are not handled well (they take up 4 indices in the attributes)
namespace J {
enum {
ATTRIB_VERTEX,
ATTRIB_COLOR,
NUM_ATTRIBUTES
};
class shader {
// NOTE: it could be hardcoded to use vertex_shader and fragment_shader.
typedef std::map<GLenum, GLuint> ShaderMap;
// NOTE: it could be hardcoded to use vertex_shader and fragment_shader, for ShaderMap.
typedef std::map<GLenum, GLuint> ShaderMap; // shader_type -> shader_name
typedef std::map<std::string, GLuint> AttributeMap; // attribute_name -> attribute_index
GLuint program;
ShaderMap shaders;
AttributeMap attributes;
public:
// ***********
// constructor
shader(std::string vertex_shader_filename, std::string fragment_shader_filename) :
program(0), shaders() {
shader(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename, const std::vector<std::string>& attributes_to_use = std::vector<std::string>()) :
program(0), shaders(), attributes() {
program = glCreateProgram();
if(program == 0) {
throw std::runtime_error("Program couldn't be created");
@ -61,11 +59,9 @@ public:
throw std::runtime_error(fragment_shader_filename + " couldn't be opened");
compile_shader(fragment_shader, GL_FRAGMENT_SHADER);
}
{ // TODO: think of a nice way to implement this
// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(program, ATTRIB_VERTEX, "position");
glBindAttribLocation(program, ATTRIB_COLOR, "color");
for (unsigned int i = 0; i < attributes_to_use.size(); ++i) {
glBindAttribLocation(program, i, attributes_to_use[i].c_str());
attributes[attributes_to_use[i]] = i;
}
link_program();
@ -95,6 +91,14 @@ public:
void end() {
glUseProgram(0);
}
// *****************
// attribute setters
void set_attribute(const std::string& name, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr){
const GLuint index = attributes[name];
glVertexAttribPointer(index, size, type, normalized, stride, ptr);
glEnableVertexAttribArray(index);
}
// ***************
// uniform setters
@ -168,15 +172,15 @@ public:
}
// matrices (in ES2 only square matrices)
void set_uniform(char const* name, const GLfloat (&value)[16], GLboolean trans = GL_FALSE) const {
void set_uniform(char const* name, const GLfloat (&value)[16], GLboolean trans) const {
glUniformMatrix4fv(glGetUniformLocation(program, name), 1, trans, value);
}
void set_uniform(char const* name, const GLfloat (&value)[9], GLboolean trans = GL_FALSE) const {
void set_uniform(char const* name, const GLfloat (&value)[9], GLboolean trans) const {
glUniformMatrix3fv(glGetUniformLocation(program, name), 1, trans, value);
}
void set_uniform(char const* name, const GLfloat (&value)[4], GLboolean trans = GL_FALSE) const {
void set_uniform(char const* name, const GLfloat (&value)[4], GLboolean trans) const {
glUniformMatrix2fv(glGetUniformLocation(program, name), 1, trans, value);
}
@ -198,7 +202,7 @@ public:
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if(status == GL_FALSE){
std::cerr << "validator reports:" << std::endl;
show_log();
show_program_log();
throw std::runtime_error("Program not valid");
}
#endif
@ -248,7 +252,7 @@ private:
if(status == GL_FALSE || shader == 0) {
std::cerr << "source:\n" << source << std::endl;
std::cerr << "shader reports:" << std::endl;
show_log();
show_shader_log(shader);
throw std::runtime_error("Shader failed to compile");
}
#endif
@ -260,17 +264,26 @@ private:
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(status == GL_FALSE) {
std::cerr << "linker reports:" << std::endl;
show_log();
show_program_log();
throw std::runtime_error("Shader failed to link");
}
#endif
}
void show_log(std::ostream& out = std::cerr) {
GLsizei infoLength = 0;
void show_program_log(std::ostream& out = std::cerr) {
GLint infoLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLength);
char* infoBuffer = new GLchar[infoLength];
glGetProgramInfoLog(program, infoLength, &infoLength, infoBuffer);
char* infoBuffer = new GLchar[infoLength+10];
glGetProgramInfoLog(program, infoLength+10, &infoLength, infoBuffer);
out << infoBuffer << std::endl;
delete [] infoBuffer;
}
void show_shader_log(GLuint shader, std::ostream& out = std::cerr) {
GLint infoLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength);
char* infoBuffer = new GLchar[infoLength+10];
glGetShaderInfoLog(shader, infoLength+10, &infoLength, infoBuffer);
out << infoBuffer << std::endl;
delete [] infoBuffer;
}