Search code examples
c++openglglsl

How I can draw a tile from a texture tilemap in an OpenGL shader?


So I have an AtlasTexture that contains all the tiles I need to draw a tile map.

Right now I pass the AtlasTexture through a uniform, and the idea is to change the texture coordinate to select just the portion I need from the atlas.

The issue is that I can only specify on the fragment shader to cut the texture from the zero origin, is it possible to specify an offsetX to tell to the shader where I want to start drawing?

float vertices[] = {
    // aPosition     // aTextureCoordinate
    0.0f,   0.0f,    0.0f, 0.0f,
    100.0f, 0.0f,    1.0f, 0.0f,
    0.0f,   100.0f,  0.0f, 1.0f,
    100.0f, 100.0f,  1.0f, 1.0f,
};

uint32_t indices[] = {0, 1, 2, 2, 3, 1};

Vertex shader

#version 330 core

layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTextureCoordinate;
out vec2 textureCoordinate;

void main() {
    gl_Position = vec4( aPosition.x, aPosition.y, 1.0f, 1.0f);
    textureCoordinate = vec2(
    aTextureCoordinate.x / 3.0f, // This selects the first tile in the uAtlasTexture
    aTextureCoordinate.y
    );
}

Fragment shader

#version 330 core

in vec2 textureCoordinate;
uniform sampler2D uAtlasTexture; // Has 3 tiles
out vec4 color;

void main() {
    color = texture(uAtlasTexture, textureCoordinate);
}

Solution

  • Use an Uniform variable for the offset. vec2(1.0/3.0 + aTextureCoordinate.x / 3.0f, aTextureCoordinate.y);' is always the second tile. Instead use a uniform variable to draw different parts and initialize it with the value 1.0/3.0:

    #version 330 core
    
    layout(location = 0) in vec2 aPosition;
    layout(location = 1) in vec2 aTextureCoordinate;
    out vec2 textureCoordinate;
    
    uniform float textureOffsetX;
    
    void main() {
        gl_Position = vec4( aPosition.x, aPosition.y, 1.0f, 1.0f);
        textureCoordinate = vec2(
            textureOffsetX + aTextureCoordinate.x / 3.0f, 
            aTextureCoordinate.y
        );
    }