GLES2 - Why can't I switch shaders?

Hi I am trying to figure out how to switch shader in a simple test program but every time i enable the 2nd shader program all polygons disappear completely.
If I enable only one of the shaders (doesn’t matter which) then I see both tris rendered but of course both using that shader.

I have tested both shader programs individually and they work on their own.

The two geometries are two slightly different single triangles.
My setup is like this:

	GLuint shader_program, shader_program2;
	GLint pos, pos2;
	shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
	shader_program2 = common_get_shader_program(vertex_shader_source, fragment_shader_source2);
	pos = glGetAttribLocation(shader_program, "position");
	pos2 = glGetAttribLocation(shader_program2, "position");

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
	glEnableVertexAttribArray(0);

	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vVertices2);
	glEnableVertexAttribArray(1);

Then my draw loop looks like:

glViewport(0, 0, 1280, 720);
glClearColor(1.0, 1.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
		
glUseProgram(shader_program2);
glDrawArrays(GL_TRIANGLES, 1, 3);

I have been trying to look for a simple example program but all tutorial programs only use one shader.

What am I doing wrong?
(probably several things)

Cheers!

You’re querying the attribute locations for each program but then using hard-coded locations for the glVertexAttribPointer and glEnableVertexAttribArray calls. If both programs use the same attribute location, you’ll have to change the array state between draw calls.

Also: are you using any uniform variables? The default uniform block is part of the program object, so any uniforms have to be set for each program.

Thanks and hmm, so when you say “If both programs use the same attribute location” are you referring to both shader programs using “position”? (btw no other attributes are used in the vtx shader and none at all in the frag shader)

When I tried printing the values of ‘pos’ and ‘pos2’ after setting them they were both 0.
Seemed odd to me is that correct?

So should I be setting glEnableVertexAttribArray in the draw loop/call?

glEnableVertexAttribArray(pos2)
glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);

Separate programs are separate. Why wouldn’t they both be able to use attribute location 0? Locations aren’t a global resource.

Ok thanks sure.
But that doesn’t make it clearer to me what I need to do.

It’s not really clear what you’re trying to do. For example, are vVertices and vVertices2 supposed to be the vertex data for different objects or different data meant for the same object? When you invoke glDrawArrays, are you expecting both objects to appear?

Yes that’s it vVertices and vVertices2 are two lists of vertex positions making up a triangle each.
I don’t have any uv’s or indices.

I have one vtx shader that just passes throught the vertex positions and nothing else.
I have two frag shaders that only hard code in two different colors green and blue.
The two shader programs share the source for the vtx shader and adds the gree/blue frag shader.

I am trying to get the two triangles rendering on the same screen at the same time, each with a different blue/green frag shader.

My goal is merely to render two different meshes with two different frag shaders.
If I should be going about it in a different way I’m happy to be told so.

glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(pos);
glUseProgram(shader_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(pos);

glVertexAttribPointer(pos2, 3, GL_FLOAT, GL_FALSE, 0, vVertices2);
glEnableVertexAttribArray(pos2);
glUseProgram(shader_program2);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(pos2);

If the two draw calls are using different data, you need to set up the vertex arrays before each draw call.

In OpenGL 3+, vertex array state is stored in vertex array objects (VAOs), so you can use multiple VAOs and switch between them to change all state related to vertex arrays. This is more efficient if you have many attributes.

Thank you.
I just tried using your blocks here but again this results in no triangles being rendered at all.

You can see my full source here for the tiny test program,

I’m still not understanding why pos and pos2 are being fed into functions as differentiators when they both print as having the same value, 0. Basically they are the same.

You don’t know that they’re the same unless you explicitly set them with a layout qualifier or glBindAttribLocation.

Also: you have two different sets of vertex data. They can’t both be bound to location zero simultaneously.

In a similar project I’ve worked on before, I used the following method to draw meshes:

glUseProgram(shader_program);
glEnableVertexAttribArray(pos);
glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(pos);

glUseProgram(shader_program2);
glEnableVertexAttribArray(pos2);
glVertexAttribPointer(pos2, 3, GL_FLOAT, GL_FALSE, 0, vVertices2);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(pos2);

This is very similar to what was posted above, with only some of the ordering being different. I’m not entirely sure how flexible the calling order of these functions is.

If the above code doesn’t work, make sure:

  • Both shaders compile without errors.
  • Have you made sure that the second triangle is not just being drawn below the previous triangle? You can try a glTranslate(0.1, 0, 0); between drawing the two triangles, to make sure they are not both occupying the same pixels.