Modern opengl. (Flipping a texture)

Hi!

In modern opengl we have to pass each matrix to a shader, I use a texture matrix for passing from [0,size] to [0,1] for uv coordinates.

It works fine except I can’t flip a texture, when I try to invert the y coordinates with this matrix :


math::Matrix4f Texture::getTextureMatrix() const {
            math::Matrix4f matrix(1.f, 0.f, 0.f, 0.f,
                       0.f, 1.f, 0.f, 0.f,
                       0.f, 0.f, 1.f, 0.f,
                       0.f, 0.f, 0.f, 1.f);
            matrix.m11 = 1.f / m_actualSize.x;
            matrix.m22 = 1.f / m_actualSize.y;
            if (m_pixelsFlipped)
            {
                matrix.m22 = -matrix.m22;
            }
            return matrix;
        }

Here is how I do in the vertex shader :

[code=cpp]
#version 330 core
layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 uv;
layout (location = 3) in vec3 normals;
uniform mat4 p;
uniform mat4 v;
uniform mat4 t;
uniform float haveTexture;
out vec4 f_color;
out vec2 texCoords;
void main() {
gl_Position = p * v * position;
texCoords = (haveTexture == 1) ? (t * vec4(uv.xy, 0, 0)).xy : vec2(0, 0);
f_color = color;
}



If I don't invert the v coordinate, the texture is well displayed but if I invert the v coordinates, the texture is not displayed. :/

Are you using GL_REPEAT as texture wrap mode?

Are you using GL_REPEAT as texture wrap mode?

No, I use GL_CAMP_TO_EDGE

If you have a number that goes from [0, size], and you multiply it by -1, then you get numbers on the range [-size, 0]. Therefore, if you divide this by size, you get [-1, 0]. Which is clearly not the same as [0, 1].

To “flip” a texture, you need to divide by the size, multiply by -1, and add 1 to the result. You’re using a 4x4 matrix, so you just need to use the translation part of the matrix.

Alternatively, you can flip the texture on the CPU and just load it into OpenGL correctly.

I’ve added a 1 to the translation part of the matrix, but, it doesn’t solve the problem.


 math::Matrix4f Texture::getTextureMatrix() const {
            math::Matrix4f matrix(1.f, 0.f, 0.f, 0.f,
                       0.f, 1.f, 0.f, 0.f,
                       0.f, 0.f, 1.f, 0.f,
                       0.f, 0.f, 0.f, 1.f);
            matrix.m11 = 1.f / m_actualSize.x;
            matrix.m22 = 1.f / m_actualSize.y;
            if (m_pixelsFlipped)
            {
                matrix.m22 = -matrix.m22;
                matrix.m42 = 1.f;
            }
            return matrix;
        }

so, I’ve just flipped the texture on the CPU and now it works, thanks.


frameBufferTile->setScale(math::Vec3f(1.f, -1.f, 1.f));