Search code examples
c++openglopengl-esglsles

Opengl/glsl trying to write a shader for drawing quads but not sure how to handle changes in aspect ratio of the screen


I'm using opengl es 2 and I'm trying to create a shader optimized to render textured quads.

vert shader:

attribute float vertIndex;

uniform vec4 verts[4] = vec4[](vec4(-1,-1,0,1), vec4(-1,1,0,1), vec4(1,1,0,1), vec4(1,-1,0,1));
uniform vec2 texCoords[4] = vec2[](vec2(0,0), vec2(0,1), vec2(1,1), vec2(1,0));
uniform vec2 size(0,0); //size of the quad about to be rendered
uniform vec2 translation(0,0); //position of the quad about to be rendered

varying vec2 TexCoordOut;

void main() {
    vec2 vert = verts[int(vertIndex)];
    vert.x *= size.x;
    vert.y *= size.y;
    vert.x += translation.x;
    vert.y += translation.y;

    gl_Position = vert;
    TexCoordOut = texCoords[int(vertIndex)];
}

In my program I have the screen bounds set so that the x will always be -1,1 and the y will be adjusted based on the aspect ratio of the screen. The problem is that the screen bounds in glsl are always -1,1,1,-1 . How do I handle this? Also, I'm using floats instead of unsigned chars for the indices because when I tried transferring ints to the vert shader it didn't work properly. Is there a working way to do that with opengl es 2?

Thanks :).


Solution

  • There are just no integer attributes in GLES 2.0, there is no way around using floating-point attributes. In fact, the hardware GLES2 targets might not even have support for integer in the shader cores at all, and the implementation might just use floating point types under the hood whenever you use int - it would be not uncommon for such embedded GPUs to have no dedicated integer ALUs at all.

    The GLSL ES spec explicitely defines the precision requirements for floats and ints such as to make any int exactly representable by an available floating point type. Section 4.5.1 of the GLSL_ES Shading Language Specification, Version 1.0 (which is the shading language for GLES2) states:

    For high and medium precisions, integer ranges must be such that they can be accurately represented by the corresponding floating point value of the same precision qualifier. That is, a highp int can be represented by a highp float, a mediump int can be represented by a mediump float. However, lowp int cannot be represented by a lowp float;

    It doesn't matter that lowp int can't be represented by lowp float, as it can always be reprsented by a mediump float as well. The critical point here is that even an highp int can always be represented by an available floating point type, meaning any int can.