Reputation: 5
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):
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
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