GLSL - setting uniform problem

Whats up programmers,
I went into a little problem here, My render loop doesn’t render my world because of GLSL issues.

The program updates the uniform in the render loop :

map[mapPos].light = Lighting.checkSunLight(mapPosY, mapPosX, this); // It works good.. returns float
Shaders.blockS.begin();
Shaders.blockS.setUniformf("lightBlock", map[mapPos].light); // Problem is here!!!
Shaders.blockS.end();
batch.draw(map[mapPos].getBlockTexture(), (mapPosX * Block.WIDTH), (mapPosY * Block.HEIGHT), Block.WIDTH, Block.HEIGHT); // Doesn't draw the block.

Just if you curious about the fragment shader -


varying vec4 vColor;
varying vec2 vTexCoord;

uniform vec2 screenSize;

uniform sampler2D u_texture;
uniform vec4 gameTime;
uniform float lightBlock;

const float RADIUS = 0.75;

const float SOFTNESS = 0.6;

void main() {

	vec4 texColor = texture2D(u_texture, vTexCoord);

    vec4 timedColor = (vColor + gameTime);

	vec2 position = (gl_FragCoord.xy / screenSize.xy) - vec2(0.5);
	float len = length(position);

	float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len);

	texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5);
		
	gl_FragColor = vec4(texColor.rgb * timedColor.rgb * lightBlock, texColor.a);
}

Pedantic is

ShaderProgram.pedantic= false;

Thanks for helping buddies :smiley:

You are not using your shader to draw the square.

Fixed code:


map[mapPos].light = Lighting.checkSunLight(mapPosY, mapPosX, this); // It works good.. returns float
Shaders.blockS.begin();
Shaders.blockS.setUniformf("lightBlock", map[mapPos].light); // Problem is here!!!
batch.draw(map[mapPos].getBlockTexture(), (mapPosX * Block.WIDTH), (mapPosY * Block.HEIGHT), Block.WIDTH, Block.HEIGHT); // Doesn't draw the block.
Shaders.blockS.end(); //end the shader as the draw call is over

You should end the shader once you have finished drawing everything with the shader. Basically the shader was useless as you ended your shader before you actually begin drawing with your sprite batcher.

Now it works, but its really weird, wow… it doesn’t work right but i guess its a problem with my code.
Is it? :slight_smile:

Thanks anyways :slight_smile:

[quote]ShaderProgram.pedantic= false;
[/quote]
I’m assuming the begin method in Shaders calls glUseProgram(). If so, that should be a program behaviour and not a shader behaviour. I’m also assuming that setUniformf calls glUniform1f()? Again, that should be a program behaviour.

The program that you want to use has to be in use when whatever you want to render is rendered.

if it is “weird” it is your shader. not my fixed code, i just re arranged your draw call.

how shaders should be used:


shader.begin(); //Begin the shader we want to use

spriteBatcher.draw(...); //put EVERYTHING we want to draw between "begin()" and "end()"

shader.end(); //Our draw call is over, lets stop the shader

To add to this: It’s technically not the shader that’s in use, but instead the program object. The shader(s) are compiled and then attached to the program object, which is then linked to the pipeline. When you’re calling [icode]glUseProgram()[/icode] you are allowing for all subsequent calls to affect or to be affected by the program object, however when the program is not in use nothing will affect or be affected by it.

I don’t use .begin() and the .end() functions everytime i render, i just use

batch.setShader(ShaderProgram);

I use this before i render stuff, and if i need to switch to another ShaderProgram, i just set the shader program i wish to use to the SpriteBatcher.
Is it the right way to use shaders?

Thanks

As long as the draw method in the sprite batcher calls glUseProgram(), then that’s fine. However, if you’re going to update the uniform and then call draw(…), binding the program, unbinding it, binding it again and unbinding it again is wasteful.