Shader normalized coordinates.
albert69

Hi Everyone,

New member, so hello :)

Just beginning with shaders but am struggling with this one problem. Everything following is in relation to basic 2D, no 3D required...

If I draw a basic bitmap to the screen with a shader, how do I get access to the normalized (0.0 to 1.0) coordinates for just the bitmap, not the whole screen?

I want to do something with the bitmap in relation to the position within it & mapping it's texture coordinates to range 0.0, 1.0 makes things simpler.
I want to map 0.0 to the left side & 1.0 to the right side of the bitmap etc.
I believe 0.0 would be bottom & 1.0 would be top also?

It seems when Allegro gives you the texture coordinates for the bitmap, it is in relation to the screen size - say 1280 x 720.

For example:
I want r & g to be in the range 0.0 to 1.0, but just for the bitmap, no matter where the bitmap is located within the 2D screen.
gl_FragColor = vec4(r, g, 0.0, 1.0);

The following code is how it is recommended to normalize within the fragment shader, but this does not work when trying the normalize a bitmap within a 1280x720 screen space:
vec2 xy = gl_FragCoord.xy; // get coords for the current pixel
xy.x = xy.x / 1280; // divide the coords by the screen size
xy.y = xy.y / 720;

My simple shader just currently renders the texture normally:

Vertex Shader:

attribute vec4 al_pos;
attribute vec2 al_texcoord;
uniform mat4 al_projview_matrix;
varying vec2 varying_texcoord;

void main()
{
varying_texcoord = al_texcoord;
gl_Position = al_projview_matrix * al_pos;
}

Fragment Shader:

uniform sampler2D al_tex;
varying vec2 varying_texcoord;

void main()
{
vec4 color = texture2D(al_tex, varying_texcoord);
gl_FragColor = color;
}

Thank You if anybody is able to help.

Chris Katko

added <code> tags.

vec2 xy = gl_FragCoord.xy; // get coords for the current pixel
xy.x = xy.x / 1280; // divide the coords by the screen size
xy.y = xy.y / 720;

#SelectExpand
1 vec4 al_pos; 2attribute vec2 al_texcoord; 3uniform mat4 al_projview_matrix; 4varying vec2 varying_texcoord; 5 6void main() 7{ 8varying_texcoord = al_texcoord; 9gl_Position = al_projview_matrix * al_pos; 10} 11 12Fragment Shader: 13 14uniform sampler2D al_tex; 15varying vec2 varying_texcoord; 16 17void main() 18{ 19vec4 color = texture2D(al_tex, varying_texcoord); 20gl_FragColor = color; 21}

Edgar Reynaldo

I'm confused. don't you just want al_texcoord?

albert69

Hi

I read in a different thread the following:

"Allegro texture coordinates are [0-bitmap_width], [0-bitmap_height]. This is different from the usual [0-1], [0-1] texture coordinates that you get with UV textures."

So the following code lines are getting the correct color from the texture at the correct coord, but they are in [0-bitmap_width], [0-bitmap_height] scale.

varying_texcoord = al_texcoord;
vec4 color = texture2D(al_tex, varying_texcoord);

If I wanted to shade the bitmap a certain way - like mapping the r,g components to a color according to its position on the bitmap, do I need normalized coordinates? Because rgb colors are mapped in the 0.0 to 1.0 range.

gl_FragColor = vec4(r, g, 0.0, 1.0);

Sorry if I am confusing things. Just started.

Thanks.

Edgar Reynaldo

You can pass the texture width and height as uniforms and divide, which may work if your image is a single texture.

Another option is to use gl_TexCoord[0].xy

In your vertex shader :

    gl_TexCoord[0] = gl_MultiTexCoord0;

In your fragment shader :

    gl_FragColor = vec4(gl_TexCoord[0].x , gl_TexCoord[0].y , 0.0 , 1.0);

I think this will work. It's using the older fixed pipeline though, which is bad if you're trying to use modern techniques.

I attached a simple shader demo that shows how to vary the color of an image based on time. There's a static exe, source, a CB project, and a vertex and fragment shader.

BasicShader.7z

EDIT
I modified it to use your example coloring, and it produces this :

{"name":"611948","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/f\/df329f7cd0fe0754574e36794c7f3d23.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/f\/df329f7cd0fe0754574e36794c7f3d23"}611948

with this fragment shader :

    vec2 uv = gl_TexCoord[0].xy;
    gl_FragColor = vec4(uv.x , uv.y , texel.b , texel.a);

Red increases from left to right with x and green increases from bottom to top with y on the texture.

albert69

Hi Edgar,

Thank You. That works perfectly.

gl_TexCoord[0] seems to have done the trick, even though it's deprecated?

I really appreciate your help with this.

Thanks :)

Edgar Reynaldo

albert69, no problem. ;)

Since you're new to shaders, you may want to check out some really great OpenGL shader tutorials to get yourself acquainted with them.

https://learnopengl.com/Getting-started/Shaders

Thread #617777. Printed from Allegro.cc