PDA

View Full Version : OpenGL 3.1 texture coords - newbie problem[SOLVED]



Oz1571
12-06-2009, 08:13 PM
I'm new to OpenGL and I've been trying to draw a texture on a 2D quad using OpenGL 3.1 functions. I've done a lot of research and googling before posting this because I'm quite sure I'm making a silly newbie mistake, but I haven't been able to figure anything out, mostly because it's hard to tell exactly what the code I've found does, and it's even harder to know whether most of it still applies to OpenGL 3.1.

As you can see below, something is wrong with my texture coords. The quad is just slightly smaller than the drawing window (-0.9 to 0.9) and the texture is meant to take up the same space:
http://i46.tinypic.com/23it3mg.jpg

This is the code I use for setting up the vbo:

glBindVertexArray(m_vaoID[2]);
glGenBuffers(1, &m_vboID[3]);

glBindBuffer(GL_ARRAY_BUFFER, m_vboID[3]);
glBufferData(GL_ARRAY_BUFFER, 8*sizeof(GLfloat), vert, GL_STATIC_DRAW);

glVertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 0, 0); //position
glEnableVertexAttribArray(0);

glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); //texture
glEnableVertexAttribArray(2);
glBindVertexArray(0);
this is the code I use for drawing:

glBindVertexArray(m_vaoID[2]);

glUniform1i(my_sampler_uniform_location, 0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_ID);

glDrawArrays(GL_QUADS, 0, 4);
and these are my vert/frag shaders:

#version 140
precision mediump int;
precision highp float;

in vec3 in_Position;
in vec2 in_TexCoord0;
out vec2 TexCoord0;

void main()
{
gl_Position = ftransform();
TexCoord0 = in_TexCoord0;
}

#version 140
precision highp int;
precision highp float;

uniform sampler2D baseMap;

in vec2 TexCoord0;
out vec4 out_Color;

void main()
{
out_Color = texture2D(baseMap, TexCoord0.st);
}

I'd be extremely happy if someone could point me in the right direction. Thanks!

Ilian Dinev
12-06-2009, 09:14 PM
BUFFER_OFFSET(0) effectively evaluates to "0".
So, your vertex-position and vtx-coord arrays both specify exactly the same data.
The screen coordinates are [-1;1] , texture coords are [0;1] . Your texture-wrap is set to clamp mode, thus coordinates [-1;0] are being clamped to [0] .

Here's how your two arrays should be set up:
VertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 16, 0);
VertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 16, (void*)(sizeof(float)*2));

Oz1571
12-06-2009, 09:36 PM
If I try this, all I get is a black screen:
glBindVertexArray(m_vaoID[2]);
glGenBuffers(1, &m_vboID[3]);

glBindBuffer(GL_ARRAY_BUFFER, m_vboID[3]);
glBufferData(GL_ARRAY_BUFFER, 8*sizeof(GLfloat), vert, GL_STATIC_DRAW);

glVertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 16, 0); //position
glEnableVertexAttribArray(0);

glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 16, (void*)(sizeof(float)*2)); //texture
glEnableVertexAttribArray(2);
glBindVertexArray(0);

If I try it with "0" instead of "16" in both places, I get a different result, but it's still far from correct.
http://i50.tinypic.com/2m46glz.jpg

What exactly is 16 for, anyway? twice the vert amount? Should I be doing the positioning in one vbo and the texturing in another? They're currently done in the same vbo. Thanks again, I appreciate it.

Ilian Dinev
12-06-2009, 10:47 PM
My code was assuming that you interleave vertex positions and coords in that one VBO.


struct Vertex{
float posx,posy;
float s,t;
}; // 16 bytes

James A.
12-06-2009, 10:50 PM
How have you filled your VBO?

is it 4 vertices followed by 4 texture coordinates? VVVVTTTT

or interleaved so that it is one vertex followed by one texture 4 times? VTVTVTVT

the 16 in Ilian Dinev's post is the stride, see here:
http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml

If your vertices are VVVVTTTT your calls should maybe be:
VertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 0, 0);
VertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(float)*8));

If your vertices are VTVTVTVT your calls should maybe be:
stride = sizeof(float)*4;
VertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, stride, 0);
VertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float)*2));

or maybe stride is sizeof(float)*2 i can't remember.

I can't check this fully while I am here, but hopefully that should give you a clue.

Oz1571
12-06-2009, 11:31 PM
http://i45.tinypic.com/2i6jgpw.jpg

Woohoo!
Thanks a lot, guys. I was completely missing the part where I had to set up the texture coords in the vertex struct/class. It works perfectly now, as you can see. I thought it was a bit odd that I didn't have any code to do that, but figured it maybe it was handled automatically by those fancy shaders or something. I think I need to find some more documentation to study. Thanks again. :)