Jump to content
  • Advertisement
Sign in to follow this  

OpenGL Switching GLSL shaders for a object?

This topic is 2074 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys.


As i have been going through OpenGL, i wanted to ask one thing. How would i switch shaders for one/multiple objects?


Because i have made a lot of 3D Models for Game Engine and i want to do a basic render of those models so how would i switch the shaders for each individual Model? Or do i re-use the shaders i made by using glUseProgram(Shader)? I am very knew to loading models and i wanted to how shaders for multiple models are handled. Any help would be greatly aprreciated.

Share this post

Link to post
Share on other sites

Each model is essentially a mesh which you just render using any command your library gives you. In opengl it's done with the glDraw* commands.

These commands are not tied to any shader you have selected, except you need to have the same mesh structure. (Or the shaders needs to be do with less)

An example:

x, y, z,   nx, ny, nz,    u, v, w

A format with position normals and uvs.

If the mesh provides those things, the VAO has those as attribs set up properly, and finally, the shader needs only those 3 things (or less), then that's really all there is to it.

Another example, same format as before:

A format with position normals and uvs. Except this time the shader only uses the position (x, y, z). This works nicely, because while you HAVE positions, normals and uvs, you can still choose to use less. You may still need to define the attribs in your shader, just not use them.


What this means is that as long as the shader is set up to read your format properly, the shader program can run, and it can do whatever you want it to.

As an example, just copy the shader you are currently using, rename it to copy.glsl, and render using that instead. It will shade the model in exactly the same way as the other shader, except one thing, they ARE different shaders (internally, as well as in name). Now you just need to change the second shader to do something else.. smile.png

Edited by Kaptein

Share this post

Link to post
Share on other sites

I see so what you are saying, is that as long as my shader reads the format of my mesh properly it can run and i modify it to my liking If i am correct. So then for example, say that i want to render 3 Character meshes with a simple fragment shader and vertex shader and their format for the shaders is the same. Can i use just those two shaders when they are rendered?

Share this post

Link to post
Share on other sites

Can i use just those two shaders when they are rendered?


Say the position is defined as in vec3 in_vertex;

The normals are defined as in vec3 in_normal;


#version 130


uniform mat4 matproj;

uniform mat4 matview;


in vec3 in_vertex;     // these in statements is what makes this a unique shader that works for a specific mesh format

in vec3 in_normal;    // what this means is that the mesh format provides (x, y, z)  (nx, ny, nz) and (r, g, b, a)

in vec4 in_color;


out vec4 out_color;


void main(void)


     gl_Position = matproj * matview * vec4(in_vertex, 1.0);  // a valid vertex shader MUST set gl_Position (that's the only requirement)

     out_color = in_color;



A basic shader which transforms a vertex, and passes a color attribute to the fragment shader. Notice how we don't use in_normal, yet I still defined it.

You can make a copy of this shader, and as long as the attributes (in's) are the same, and the shader is valid, you can use it for ANY mesh that has this structure defined.

If the model also provided uvs, then I could not use them, simply because I didn't define them in the shader. It doesn't matter if the model provides 30 attributes, what matters is which of them I use in the shader, and which attributes have been enabled before rendering.


I imagine the answer to your question is yes. Their formats should be similar. What those formats look like is defined by your attrib statements when forming the VAO. The shader doesn't care if the model uses SHORT or FLOAT for (x, y, z) as long as the bindings are correct, and the number of elements are the same.

The binding is towards the string "in_vertex" and the number of elements is 3 as in "vec3" --> in vec3 in_vertex;

Whether or not the model stores (x, y, z) as float or short is not important, because you define that with attrib array pointer, which is tied to an index value.


To a shader these statements are the same:

        glVertexAttribPointer(0, 3, GL_SHORT,            GL_FALSE, sizeof(vertex_t), (void*) offsetof(vertex_t, x )); // vertex
Is the same as:

        glVertexAttribPointer(0, 3, GL_FLOAT            GL_FALSE, sizeof(vertex_t), (void*) offsetof(vertex_t, x )); // vertex

The difference is how the data is treated, but you just defined that. You are making a promise to OpenGL that the data you provided are of a specific type, and should be treated so and so. The shader must know there is an index 0, and that index is typically the position of the vertex (x,y,z) which in my example above would be "in_vertex."

Other than that, you just provide what indexes you want. Enabling and disabling them.

Edited by Kaptein

Share this post

Link to post
Share on other sites

The right path:


Mesh Subset: materials, buffers, textures and render state;

Mesh: vertices, indices, collection of mesh subsets;

Model: collection of meshes;



Irlan Robson

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!