1
\$\begingroup\$

I am writing a game project in Go and I am using an OpenGl 3.3 core context to do my rendering stuff. At the moment I have different types of renderers. Each renderer has it's own pair of vertex- and fragment-shader, a struct of uniform- and attribute locations. A struct with glBuffers, vertex-array-object, and numverts (int) which contains all data required to render one object (mesh). Last but not least a constructor to create and initialize the attribute/uniform locations a method to load a mesh into mesh data and the render method itself.

I am absolutely not happy with this design. Every time I want to create a new simple shader, I have to write all this code, and I haven't found a way to make the overhead of a new shader smaller. All I was able to make with the help of go reflections is to automatically get the attribute/uniform location based on the variable name in attribute/uniform location struct and to automatically set the attribute pointers based on the layout of the vertex struct.

another thing that I don't like, is that when I want to implement for example the functionality of the function glClipPlane of the fixed function pipeline, I need to add the uniform to each shader separately and I need to set this uniform in each shader and I need to implement the discard of fragments in each fragment shader

Are there some common practices that significantly reduce the code overhead of a new shader? Are there good shader pipelines that you can recommend me to take a look at? Are there some good practices to add functionality to several shaders at once?

\$\endgroup\$
3
  • \$\begingroup\$ Can you define the word "overhead" as you're using it in the last paragraph of this question? Most of your question makes it sound like you're talking about minimising the amount of code you need to write per shader -- is that correct? (When we're talking about rendering architectures, that's usually not what we mean when we talk about "overheads", which is usually more about performance -- just want to make sure that we're talking about the same thing. :) ) \$\endgroup\$ Commented Jan 29, 2014 at 23:43
  • \$\begingroup\$ yes you are right, I mean in this context overhead if the form of code, especially duplicated code or when I am required to declare a uniform in the shader and in my source code as a shader location. \$\endgroup\$
    – Arne
    Commented Jan 30, 2014 at 0:33
  • \$\begingroup\$ stackoverflow.com/questions/10754437/… \$\endgroup\$ Commented Jan 30, 2014 at 6:15

1 Answer 1

1
\$\begingroup\$

What I understand from your question, you are trying to minimize the amount of code you are writing for new shaders.

One thing I use, even though not without its problem is, conditional shader compilation, using preprocessor directive. What I do is pass conditional directive when compiling the shader program, and build the functions accordingly. For example you have specular function, diffuse, texture sampling etc.. And build the shader based on that.

void glShaderSource(GLuint shader,
                    GLsizei count,
                    const GLchar **string,
                    const GLint *length);

Notice that glShaderSource takes an array of strings (Not sure how Go handles this) but that's the OpenGL standard; it takes an array so you can concatenate shader strings. Also horde3D use a similar technique.

If that's not entirely satisfying you can investigate using uniform constants, but as far as I know GLSL doesn't support that, so if uniforms are not optimized by the GLSL compiler you don't really want branching in your shaders. Direct3D on the other hand supports this.

As for managing uniforms and attributes:

For attributes I bind constant attributes locations, and save that in a dictionary. This is simple yet effective and easy to use.

Uniforms on the other hand are a bit more complex. I wrote an article on this topic, the summery is; I used the observar pattern for updating the uniforms, while for the actual uniform types, I used some kind of static polymorphism to handle different uniform types correctly. This is only a suggestion and might not be the best solution.

\$\endgroup\$
1
  • \$\begingroup\$ article link is dead \$\endgroup\$
    – user8709
    Commented Jul 23, 2016 at 20:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .