sdfsdf21
sdfsdf21

Reputation: 5

OpenGL - texture is shown only partially and muddy

I am trying to show a texture on a square. I make array with 6x5 float values (6 vertices, each with x,y,z position and x,y UV position), set vertex attribute pointers, load bitmap with CImg library and load it with glTexImage2D.

Image is read correctly and can be shown with src.display().

But my image looks like it is zoomed on a small part of image.

Here is the result (it should be a clear Lenna image): Texture result

Vertex shader:

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 uvPos;

out vec2 uvPosition;

void main() {
    uvPosition = uvPos;
    gl_Position = vec4(position, 1.0);
}

Fragment shader:

#version 330

in vec2 uvPosition;

out vec4 color;

uniform sampler2D tileTex;

void main() {
    color = texture(tileTex, uvPosition);
}

And code for loading the texture:

imageShader = new OpenGL::OpenGLShader(Common::GetShaderResource(IDR_SHADERS_BASIC_VERTEX), Common::GetShaderResource(IDR_SHADERS_BASIC_FRAGMENT));
        imageShader->bind();

        float verticesImage[6][5] = {
            0.0f,  0.0f, 0.0f, 0.0f,  0.0f, // Top-left
            3.0f,  0.0f, 0.0f, 1.0f,  0.0f, // Top-right
            3.0f,  5.0f, 0.0f, 1.0f,  1.0f, // Bottom-right
            0.0f,  0.0f, 0.0f, 0.0f,  0.0f, // Top-left
            0.0f,  5.0f, 0.0f, 0.0f,  1.0f, // Bottom-left
            3.0f,  5.0f, 0.0f, 1.0f,  1.0f // Bottom-right
        };
        unsigned int vboIndexImage;

        glGenVertexArrays(1, &vaoIndexImage);
        glGenBuffers(1, &vboIndexImage);

        glBindVertexArray(vaoIndexImage);
        glBindBuffer(GL_ARRAY_BUFFER, vboIndexImage);
        glBufferData(GL_ARRAY_BUFFER, sizeof(verticesImage), &verticesImage[0][0], GL_STATIC_DRAW);

        GLint position = glGetAttribLocation(imageShader->shader_id, "position");
        GLint uvPos = glGetAttribLocation(imageShader->shader_id, "uvPos");
        glEnableVertexAttribArray(position);
        glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);

        glEnableVertexAttribArray(uvPos);
        glVertexAttribPointer(uvPos, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));

        CImg<unsigned char> src("images\\lena512.bmp");
        int width = src.width();
        int height = src.height();

        GLuint textureID;
        glGenTextures(1, &textureID);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureID);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, src);

        glEnable(GL_TEXTURE_2D);

        imageShader->unbind();

Upvotes: 0

Views: 284

Answers (1)

Michael Nastenko
Michael Nastenko

Reputation: 3053

The last parameter in glVertexAttribPointer function is a pointer to the first element. In your case, uvPos has offset 3 * sizeof(float), but you have 2 * sizeof(float).

You have:

glVertexAttribPointer(uvPos, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));

Must be:

glVertexAttribPointer(uvPos, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));

Upvotes: 3

Related Questions