Sign in to follow this  
zerorepent

glshaderprogram reuse?

Recommended Posts

I have a rather odd problem, If I create a new shaderprogram for every object i render, everything renders correctly however its very slow and lags a lot when adding new objects during gameplay. My plan to solve this was to use a std::map and simply reuse the same shaderprogram if it is loaded several times (which it is). But this doesnt work it renders the first object I load and ignores the rest, I have checked that it takes the correct value from the map and it does.

I have no clue of what can cause this behaviour. If it works with several different shaderprograms (with the same shaders) it really should work with one single shaderprogram (or I've definitely missunderstood the usage of shaderprograms). I've been checking for glErrors but the only one I get is from SOIL, and Im quite certain this isn't the cause (why should it work with many shaderprograms but not one?) and it still loads the textures.

Since I don't know where this error could be caused I won't post any source, but if you want to see something particular piece of code please write and I will try to post it asap.

Share this post


Link to post
Share on other sites
Firstly calling them glshaderprograms is a bit confusing. GLSL separates shaders and programs into separate concepts. A shader is a chunk of a program responsible for a particular part of the pipeline. e.g. a vertex shader, or a fragment shader. A program is the result of linking a number of these shaders together. A number of shader chunks for a particular pipeline stage can be added to a single program as long as they only contain a single "main()" function.

The problem you are experiencing is usually solved using what most people call materials:
- for each unique set of shaders used in the game you compile and link a single program.
- for each unique set of parameters used for a program you create a material that maps the values of the parameters to the parameters themselves.

Generally this is made more manageable through something called an effects framework. An effect is generally a definition file that references the shaders that make up its program, and maps symbolic parameter names to the parameters of the program generated. Cg is an example of an effects framework, DX also has one that is based off Cg. Some people make their own.

Still it is possible to use a material system without using an effects framework, but it is definitely less flexible.

The pipeline when using materials with programs would look something like:

[code]
struct Effect
{
GLuint programHandle;
std::map<string, GLuint> parameterNameToHandleMap;

void set_parameter(string paramName, variant_type value)
{
GLuint paramHandle = parameterNameToHandleMap[paramName];
set_param_with_handle(paramHandle, value); // maps the type to an appropriate glUniform function
}

void bind()
{
glUseProgram(programHandle);
}
}


struct Material
{
std::map<string, variant_type> parameterNameToValue;
Effect effect;

void set_parameter(string paramName, variant_type value)
{
parameterNameToValue[paramName] = value;
}

void bind()
{
effect.bind();
foreach(param in parameterNameToValue)
{
effect.set_parameter(param.first, param.second);
}
}
}

struct Geometry
{
Material material;
Mesh mesh;
}


void render_object(Geometry ob)
{
ob.material.bind();
draw_ob(ob.mesh);
}[/code]


Personally I use boost variant for my variant type, it works very well.

For more help paste your drawing code including where you bind your programs.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this