@ -6,6 +6,14 @@
// Copyright 2011 Vadovas. All rights reserved.
// Copyright 2011 Vadovas. All rights reserved.
//
//
/*
This is a very basic shader class . The compilation and linking is done in the constructor , and deletion is don in the destructor . As a result , you can ' t copy a shader , use smart pointers instead . Because OpenGL ES2 uses attribute - indices at link - time , you have to specify your attributes in the constructor ( this is a bit cumbersome ) .
There are a lot of uniform setters , for both values and array ' s , they are called set_uniform ( ) for all types . For matrices a additional parameter ( trans ) can be given , but in ES2 this value has to be false . It ' s still a parameter to avoid ambiguity , because the overload works with c - style arrays ( vector4 is not distinguishable from matrix2x2 ) . A fix would be to introduce types like vector4 and matrix2x2 and such , but Astrant already has those , so I refrain to do that .
Using the setters should only be done between the begin ( ) and end ( ) functions .
*/
# ifndef SHADER_H
# ifndef SHADER_H
# define SHADER_H
# define SHADER_H
@ -19,17 +27,17 @@
# include "basic.h"
# include "basic.h"
# include "array.h"
# include "array.h"
// TODO: do glValidateProgram, like in the OpenGL template (see bottom)
// TODO: add error checking at set_uniforms?
// TODO: add error checking at set_uniforms?
// TODO: use an uniform map? (benchmark first!)
// TODO: use an uniform map? (benchmark first!)
// TODO: allow arrays is uniforms (now all counts are 1)
// TODO: allow arrays in uniforms (now all counts are 1). To make this possible, first make vector and matrix structs. (But Astrant already has those)
// TODO: matrix attributes are not handled well (they take up 4 indices in the attributes)
// TODO: matrix attributes are not handled well (they take up 4 indices in the attributes instead of one)
// TODO: make the attribute-list nicer (it is really cumbersome now, with the vector)
// NOTE: there is only 1 set_uniform for std::array...
// NOTE: there is only 1 set_uniform for std::array...
namespace J {
namespace J {
class shader {
class shader {
// NOTE: it could be hardcoded to use vertex_shader and fragment_shader, for ShaderMap.
// NOTE: it could be hardcoded to use vertex_shader and fragment_shader, for ShaderMap. There is no geometry_shader in ES2.
typedef std : : map < GLenum , GLuint > ShaderMap ; // shader_type -> shader_name
typedef std : : map < GLenum , GLuint > ShaderMap ; // shader_type -> shader_name
typedef std : : map < std : : string , GLuint > AttributeMap ; // attribute_name -> attribute_index
typedef std : : map < std : : string , GLuint > AttributeMap ; // attribute_name -> attribute_index
@ -77,7 +85,7 @@ public:
GLuint shader = it . second ;
GLuint shader = it . second ;
glDetachShader ( program , shader ) ;
glDetachShader ( program , shader ) ;
glDeleteShader ( shader ) ;
glDeleteShader ( shader ) ;
// NOTE: If a shader object to be deleted is attached to a program object, it will be flagged for deletion, but it will not be deleted until it is no longer attached to any program object
// NOTE: If a shader object to be deleted is attached to a program object, it will be flagged for deletion, but it will not be deleted until it is no longer attached to any program object. Also deleting a shader with name '0' is safe.
}
}
end ( ) ;
end ( ) ;
@ -96,6 +104,7 @@ public:
// *****************
// *****************
// attribute setters
// attribute setters
// NOTE: the normalized parameter is for integer types, if true they will be mapped to [0, 1], if false it stays in [0, 256] or so.
void set_attribute ( const std : : string & name , GLint size , GLenum type , GLboolean normalized , GLsizei stride , const GLvoid * ptr ) {
void set_attribute ( const std : : string & name , GLint size , GLenum type , GLboolean normalized , GLsizei stride , const GLvoid * ptr ) {
const GLuint index = attributes [ name ] ;
const GLuint index = attributes [ name ] ;
glVertexAttribPointer ( index , size , type , normalized , stride , ptr ) ;
glVertexAttribPointer ( index , size , type , normalized , stride , ptr ) ;
@ -173,7 +182,8 @@ public:
glUniform1iv ( glGetUniformLocation ( program , name ) , 1 , value ) ;
glUniform1iv ( glGetUniformLocation ( program , name ) , 1 , value ) ;
}
}
// matrices (in ES2 only square matrices)
// matrices
// NOTE: in ES2 there are only square matrices
void set_uniform ( char const * name , const GLfloat ( & value ) [ 16 ] , GLboolean trans ) const {
void set_uniform ( char const * name , const GLfloat ( & value ) [ 16 ] , GLboolean trans ) const {
glUniformMatrix4fv ( glGetUniformLocation ( program , name ) , 1 , trans , value ) ;
glUniformMatrix4fv ( glGetUniformLocation ( program , name ) , 1 , trans , value ) ;
}
}
@ -190,7 +200,8 @@ public:
glUniformMatrix2fv ( glGetUniformLocation ( program , name ) , 1 , trans , value ) ;
glUniformMatrix2fv ( glGetUniformLocation ( program , name ) , 1 , trans , value ) ;
}
}
// textures (see todo above)
// textures
// NOTE: with a texture class this can be made prettier (also se the TODO in fbo.h)
void set_texture ( const char * name , GLenum target , GLuint tex , int textureLocation , GLenum filter = GL_LINEAR ) const {
void set_texture ( const char * name , GLenum target , GLuint tex , int textureLocation , GLenum filter = GL_LINEAR ) const {
glActiveTexture ( GL_TEXTURE0 + textureLocation ) ;
glActiveTexture ( GL_TEXTURE0 + textureLocation ) ;
glBindTexture ( target , tex ) ;
glBindTexture ( target , tex ) ;
@ -219,7 +230,7 @@ private:
// *******************
// *******************
// compiling / linking
// compiling / linking
void compile_shader ( std : : istream & file , GLenum type ) {
void compile_shader ( std : : istream & file , GLenum type ) {
// get the c-string, the shortest way (not fastest)
// get the c-string, the shortest way (not fastest), from http://tinodidriksen.com/
std : : string buffer ( ( std : : istreambuf_iterator < char > ( file ) ) , std : : istreambuf_iterator < char > ( ) ) ;
std : : string buffer ( ( std : : istreambuf_iterator < char > ( file ) ) , std : : istreambuf_iterator < char > ( ) ) ;
const char * sptr = buffer . c_str ( ) ;
const char * sptr = buffer . c_str ( ) ;
int ssize = buffer . size ( ) ;
int ssize = buffer . size ( ) ;