OpenGL ES 2.0 Shader Interface

Started by
-1 comments, last by Adventus 15 years, 5 months ago
Hi, I'm writing an C++ OpenGL ES 2.0 based Application for the Pandora Console, however i've ran into bit of a design issue. What i want is an elegant and efficent way to statically load shaders and interface with them. My current implementation looks like this: ShaderDefn.hpp
namespace TranTexUcol{

    enum eAttribs { aPosition, aTexCoord, ATTRIB_COUNT};
    enum eUniforms { uColour, uDepth, uMVP, uOffset, uTex, UNIFORM_COUNT};

    extern GLuint Index;
    extern GLuint UniformLoc[];

    void     Init();
    void     Destroy();
    void     SetActive();
    void     SetUniforms(const GLuint Tex, const GLfloat* Colour, const GLfloat Depth, const GLfloat* Offset, const GLfloat* MVP);
    void     SetAttribs(const GLfloat* Position, const GLfloat* TexCoord);
};
ShaderDefn.cpp
namespace TranTexUcol {
    GLuint          Index;
    GLuint          UniformLoc[UNIFORM_COUNT];
    const char*     UniformNames[] = {"uColour", "uDepth", "uMVP", "uOffset", "uTex"};
    const char*     AttribNames[] = {"aPosition", "aTexCoord"};
}

void TranTexUcol::Init(){
    ShaderManager::ProgramCreate(&Index, UniformLoc, UniformNames, AttribNames,"TEXUCOL.fsh", "TRANTEXUCOL.vsh");
}

void TranTexUcol::SetActive(){
    glUseProgram(Index);
    glEnableVertexAttribArray(aPosition);
    glEnableVertexAttribArray(aTexCoord);
}

void TranTexUcol::SetUniforms(const GLuint Tex, const GLfloat* Colour, const GLfloat Depth, const GLfloat* Offset, const GLfloat* MVP){
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, Tex);
    glUniform4fv(UniformLoc[uColour], 1, Colour);
    glUniform1f(UniformLoc[uDepth], Depth);
    glUniform2fv(UniformLoc[uOffset], 1, Offset);
    glUniformMatrix2fv(UniformLoc[uMVP], 1, GL_FALSE, MVP);
}

void TranTexUcol::SetAttribs(const GLfloat* Position, const GLfloat* TexCoord){
    glVertexAttribPointer(aPosition, 2, GL_FLOAT, GL_FALSE, 0, Position);
    glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, TexCoord);
}
Inorder to render i do something like this:

TranTexUcol::SetActive();
TranTexUcol::SetUniforms(tex, Vec4(1.0,1.0,1.0,1.0), 0, Vec2(0,0), Mat2(1,0,0,1));
TranTexUcol::SetAttribs(vert, texcoord);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

For batched rendering i manually update the uniforms/attribs as neccessary using the enums and uniformloc specified. As you can see there's alot of hard coded constant variables in there, some of them being effectively written twice (like the eAttrib enum and AttribNames array). Theres also some nasty pitfalls in this technique, like if an attribute or uniform is not active and i dont notice. It may not be neccessary to specify the attrib and uniform names since i can grab them using glGetProgramiv() however i cannot think of a decent way to ensure that the order their written in the enum is the same as how thier returned in the function (i.e. the emulation library on the PC seems to put the uniform Sampler2D last). Most, if not all, of it could be auto generated from the shader source, but before i write such a tool i want to know if there's a better way of achieving this. Thanks,

This topic is closed to new replies.

Advertisement