glUseProgram var update problem

Hi!

I’m rendering my per pixel lights with help of glsl built-in light variables (emulating fixed function). For each object I use the lights closest to it. In my glsl program I have created five shaders (I only allow five lights per object) which emulate 1-5 lights. I turn them on depending on how many of the fixed function lights that are currently in use. The problem is that when I render an object with for example four lights and then I render another object with the same amount of lights the second object is unlit. However, if I execute glUseProgram() with the same program that is already running the problem is solved.

The only cause of the problem that I can come up with is that glsl won’t update the built-in light variables if I don’t execute glUseProgram(). This can cause as much as 10x as many calls to glUseProgram(). I have on the other hand not detected any significant frame drop but it bothers me to execute the same program over and over. I am not very confident that it will run fast on other systems when calling glUseProgram() that many times (around 70-100 times). Is there anyone that can shed some light on this, is it expensive to execute a shader program that already is in use? When does the built-in variables update? Help appreciated.

havent encountered this but sounds like a bug. it is wise actually to bind program once and render all geometry with it updating some uniforms if needed, sortof sorting geometry by shader. can you post your gfx card and driver version, would be interesting to know.

Thanks for the reply! I’m developing on a GeForce7800 GT, forceware 84.25

i honestly don’t know how much of impact it causes on performance but those are additional calls that are made which is still something depending on the scene. one workaround would be to pass your light values directly as uniforms not build in uniforms another one apparently to bind them again. try to update to latest drivers and maybe check again. i try to reconstruct that later as well on GeForce 8800 GT and post back.

out of curiosity tried to reproduce on GeForce 8800 GT with omega drivers passing light values via gl calls. setting up 3 lights, binding program, drawing multiple objects with different vertex data and without calling glUseProgramObject inbetween. not reproduceable, perpixel lighting works in this case as expected.

The problem is that when I render an object with for example four lights and then I render another object with the same amount of lights the second object is unlit. However, if I execute glUseProgram() with the same program that is already running the problem is solved.

You mean that the only thing you change between two different objects rendering is lights properties through the OpenGL fixed functionnality and using for both the same program object?

_NK47, did you try to change light properties through opengl commands between each object rendering?

@dletozeun. Yes, exactly.

Let’s say I got three objects, each object has one light source shining on it. The objects are so far apart that I only need one OGL light source that they can share if I move it.

This all works well when rendering using fixed function lighting. When I try to use per pixel lighting using glsl built-in light variables I only get the first object lit.

I can solve this if I enable the shader for each object but I can’t see why this should be necessary. It will amount to a silly number of calls to glUseProgram when there only should be one call. I thought of swapping places with my function calls when I move the lights, i.e.

glEnable(gameMap->mGLLight[index].mGLID);
glLightfv(…)

and

glLightfv(…)
glEnable(gameMap->mGLLight[index].mGLID);

… Just to see if that might help, it didn’t.

Yes it is strange… maybe it is a driver bug, forceware 84.25 is very old! If I am correct we are at the 181.20 release. Did you try your program on other hardwares? I may run it on my computer if you can provide a compilable code for linux.

Anyway, using the gl_LightSource built-in and almost all others are deprecated AFAIK in glslang 1.30, it is better for you to manage light sources with your own data structures and custom uniforms passed to your shader as _NK47 said.

well okay I read about the Omega drivers and thought that I might update my drivers. Downloaded the latest release from nvidia.com and the problem was solved… sigh I thought that my card was old enough that it didn’t need any driver updates, guess I was wrong. Thanks everyone for the help!

Here’s a screenshot showing it all in action :slight_smile:

dletozeun:
“_NK47, did you try to change light properties through opengl commands between each object rendering?”
yes i have updated light sources inbetween, the tested scene on the screenshot showing redish, greenish and white light. no problems detected and good to know its a driver bug.
O-san thanks for pointing it out, usefull information.

Great! Nice pics! :slight_smile:

Indeed !
There is room for improvement for shadow maps in the tile editor though :slight_smile:

thanks. glad to hear. :slight_smile: