0
\$\begingroup\$

I want to choose from 2 fragment shaders based on the value of an uniform variable. I want to know how to do that.

I have onSurfaceCreated function which does compile and link to create program1 and glGetAttribLocation of that program1

In my onDrawFrame I do glUseProgram(program1). This function runs for every frame.

My problem is that, in the function onDrawFrame(), I get value of my uniform variable. There I have to choose between program1 or program2. But program1 is already compiled linked and all. How to do this? How will I change my program accordingly and use that since it is already done in onSurfaceCreated.?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You can think of glUseProgram as a temporary function. You call it and it "binds" the program to the current context. What you need to do is call glUseProgram(program2) if the uniform variable is a certain value, though I'd highly recommend you avoid this if at all possible. You usually would compile program1 and program2 separately and then just bind whichever one whenever you need it. Example:

//compile shader 1
//compile shader 2
glUseProgram(prog1);
//Draw stuff that you want to draw with prog1
glUseProgram(prog2);
//Draw more stuff using prog2
glUseProgram(0);

Or if you insist on changing it based off of a uniform value:

//compile shaders
glUseProgram(prog1);
//get the uniform value here (but this will be slow)
if(uniformVal == whatever)
    glUseProgram(prog1);
else
    glUseProgram(prog2);
//Draw stuff
glUseProgram(0);

Again, I highly recommend you do NOT use the uniform value, because communicating from the GPU towards the CPU is harder. Instead solve which shader you require before ever binding the shader at all.

\$\endgroup\$
3
  • \$\begingroup\$ As a different solution, if the programs are similar enough in the parameters, he could combine them into a single program that in the entrypoint dispatches to one of two functions which performs the actual work. This is a valuable technique if you end up wanting to switch within a single Draw. \$\endgroup\$ Commented Apr 5, 2016 at 14:14
  • \$\begingroup\$ If I am reading you correctly you are saying that your idea is to use one big if statement within the shaders, is there any reason that could be wrong? I read somewhere that the GPU ends up doing most of the work of the stuff within the if regardless. \$\endgroup\$
    – devmane144
    Commented Apr 7, 2016 at 11:33
  • \$\begingroup\$ With the introduction of proper branching in shaders it's way less of an issue of the old "let's run everything and mask the results out" way, particularly if you're coherent in your execution. There may of course be other overheads, always profile. \$\endgroup\$ Commented Apr 8, 2016 at 3:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.