View Full Version : VAO, VBO acting strangely.
Meanz
12-24-2011, 08:17 AM
Just announcing theese functions
VBO
GLuint create() {
glGenBuffers(1, &vboId);
return vboId;
};
GLvoid bind(int __type__) {
glBindBuffer(__type__, vboId);
};
GLvoid unbind() {
glBindBuffer(0, 0);
}
VAO
GLuint create() { glGenVertexArrays(1, &vaoId);
return vaoId;
};
GLvoid bind() {
glBindVertexArray(vaoId);
};
GLvoid unbind() {
glBindVertexArray(0);
};
Here is my init code
float verts[4 * 3]; verts[0] = 0.0f; verts[1] = 5.0f; verts[2] = 0.0f;
verts[3] = 1.0f; verts[4] = 5.0f; verts[5] = 0.0f;
verts[6] = 1.0f; verts[7] = 5.0f; verts[8] = 1.0f;
verts[9] = 0.0f; verts[10] = 5.0f; verts[11] = 1.0f;
vao.create();
vao.bind();
{
vbo.create();
vbo.bind(GL_ARRAY_BUFFER);
{
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), &verts[0], GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
}
vbo.unbind();
}
vao.unbind();
And my draw code
vao.bind(); {
glDrawArrays(GL_QUADS, 0, 4);
}
vao.unbind();
For some reason my output is this
http://cboard.cprogramming.com/attachments/cplusplus-programming/11266d1324573425-gl-vbo-vao-weird.png
And the red circle indicates a point that is always on the center of the screen, even if I rotate the camera.
So, is there any obvious faults in my code?
I guess the code is sloppy, due to me beeing a java programmer.
C++ seems kinda odd
mobeen
12-24-2011, 09:11 AM
Hi,
Change this line
glVertexAttribPointer((GLuint)0, 4, GL_FLOAT, GL_FALSE, 0, 0);
to this
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
Reason: the second parameter of glVertexAttribPointer contains the number of components in one vertex which for your case is 3 not 4. See if this helps.
Meanz
12-24-2011, 03:05 PM
Damn, how did I miss that ;)
I honestly believed the parameter was for "how many vertices per unit" for instance for quads it would be 4 and for triangles it would be 3.
Thanks alot ;)
Meanz
12-24-2011, 05:57 PM
I would hate to create a new topic just for this, so I hope the community is observant and reads this post too.
I am trying to implement texture coordinates into my VAO / VBO solution.
Earlier I used glTexCoordPointer or something along thoose lines. But I am pretty sure I am not supposed to use that now.
Should I place the texture coordinates alongside the vertices?
texcoord, vertices, texcoord, vertice.
And how do I make sure OpenGL knows they are texture coordinates? I am having issues googling this. So any quick response, or response at all would be appreciated ;)
mhagain
12-24-2011, 09:25 PM
"glVertexAttribPointer (8, ..." is equivalent to glTexCoordPointer; you can find the rest of the mappings here: http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_program.txt
Conventional Attribute Binding Generic Attribute Binding
------------------------------ -------------------------
vertex.position vertex.attrib[0]
vertex.weight vertex.attrib[1]
vertex.weight[0] vertex.attrib[1]
vertex.normal vertex.attrib[2]
vertex.color vertex.attrib[3]
vertex.color.primary vertex.attrib[3]
vertex.color.secondary vertex.attrib[4]
vertex.fogcoord vertex.attrib[5]
vertex.texcoord vertex.attrib[8]
vertex.texcoord[0] vertex.attrib[8]
vertex.texcoord[1] vertex.attrib[9]
vertex.texcoord[2] vertex.attrib[10]
vertex.texcoord[3] vertex.attrib[11]
vertex.texcoord[4] vertex.attrib[12]
vertex.texcoord[5] vertex.attrib[13]
vertex.texcoord[6] vertex.attrib[14]
vertex.texcoord[7] vertex.attrib[15]
vertex.texcoord[n] vertex.attrib[8+n]
Alfonse Reinheart
12-24-2011, 10:08 PM
"glVertexAttribPointer (8, ..." is equivalent to glTexCoordPointer
No, it most certainly is not.
The OpenGL specification is very clear on this: there is to be no aliasing (in GLSL) between generic attributes and fixed-function attributes. At all. Yes, NVIDIA drivers will still have aliasing, but this is incorrect behavior, and you should not rely upon it.
If you're still using fixed-function vertex processing, there's no point in you not using fixed-function vertex attribute passing (ie: glTexCoordPointer). If you're using shaders, then you should just use a user-defined attribute, and then you'll know whether it is a texture coordinate or something else.
Meanz
12-24-2011, 10:19 PM
So I assume you are saying that I should use a shader to define the behavior of my rendering?
mobeen
12-24-2011, 10:49 PM
Hi,
I would recommend using shaders and custom per-vertex attributes. Here is a tutorial which details how to do it.
http://spacesimulator.net/wiki/index.php?title=Tutorials:Texture_Mapping_(OpenGL3 .3)
Meanz
12-26-2011, 01:08 AM
Alright, I managed to make the shader draw textured geometry.
But now I want to add 2 samplers to the texture, so I can mix the images.
My init code
worldData.addTexCoord(0.0f, 1.0f); worldData.addVertex(x, y + slopeBL, z);
worldData.addTexCoord(1.0f, 1.0f); worldData.addVertex(x + 1.0f, y + slopeBR, z);
worldData.addTexCoord(1.0f, 0.0f); worldData.addVertex(x + 1.0f, y + slopeTR, z + 1.0f);
worldData.addTexCoord(0.0f, 0.0f); worldData.addVertex(x, y + slopeTL, z + 1.0f);
//VT
int stride = 5 * 4; //3 for position 2 for tex
vao.create();
vao.bind();
{
vbo.create();
vbo.bind(GL_ARRAY_BUFFER);
{
glBufferData(GL_ARRAY_BUFFER, worldData.getVertexByteSize(), &worldData.getVerticeData()[0], GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(0));
glVertexAttribPointer((GLuint)1, 2, GL_FLOAT, GL_FALSE, stride, BUFFER_OFFSET(3*sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
}
vbo.unbind();
}
vao.unbind();
Draw Code:
GLint tex1 = worldShaderProgram.getUniformLocation("terrainTex");
worldShaderProgram.uniformi(tex1, 2);
GLint tex2 = worldShaderProgram.getUniformLocation("terrainTex2");
worldShaderProgram.uniformi(tex2, 3);
glClientActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texAtlas);
glClientActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, texAtlas2);
worldShaderProgram.use();
vao.bind();
{
glDrawArrays(GL_QUADS, 0, worldData.getNumVertices());
}
vao.unbind();
worldShaderProgram.useNone();
texAtlas and texAtlas2 are two different textures, it's tested and verified, even though no code assumes anything different.
My frag shader.
varying vec2 outTex;
uniform sampler2D terrainTex;
uniform sampler2D terrainTex2;
void main (void)
{
vec4 col = mix(texture2D(terrainTex, outTex), texture2D(terrainTex2, outTex), 0.5);
gl_FragColor = col;
}
I tried only using
gl_FragColor = texture2D(terrainTex, outTex);
and
gl_FragColor = texture2D(terrainTex2, outTex);
I get the same output.
Any obvious faults here?
mobeen
12-26-2011, 01:15 AM
Hi,
1) Replace glClientActiveTexture call with glActiveTexture like this,
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texAtlas);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, texAtlas2);
2) You should query the uniform locations after you have use the shader program.
3) A performance note here. I would recommend setting the uniforms once when the texture is loaded rather than setting them each frame as you are doing it right now.
Meanz
12-26-2011, 01:24 AM
Thank you.
I corrected my code,
in the init after I compile and link my shaders.
I "use" my shader program and query the uniforms.
Then I "use none", and buffer my geometry.
This is my current draw code.
worldShaderProgram.use();
vao.bind();
{
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texAtlas);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, texAtlas2);
glDrawArrays(GL_QUADS, 0, worldData.getNumVertices());
}
vao.unbind();
worldShaderProgram.useNone();
Would this be a recommended drawing setup?
And also, in my init code. What happends if I use glActiveTexture after I bound my vao and vbo, will the next call to bind my vao do the glActiveTexture for me, or will I have to call glActiveTexture each time I bind my vao ?
mobeen
12-26-2011, 01:32 AM
VAO do not store active texture. Since opengl is a state machine once u set a state it remains in that state unless you change it. The reason I told u to do it at initialization was because you were not changing your textures therefore you should not rebind the same texture when it is already bound. What I recommend is something like this,
At initialization (after the progam is compiled and linked), you use the program, query the locations and set the textures like this
shader.use();
//set the uniforms
GLint tex1 = worldShaderProgram.getUniformLocation("terrainTex");
worldShaderProgram.uniformi(tex1, 2);
GLint tex2 = worldShaderProgram.getUniformLocation("terrainTex2");
worldShaderProgram.uniformi(tex2, 3);
//Load and bind the texture here
// assuming that you will call glBindTexture in LoadTexture
glActiveTexture(GL_TEXTURE2);
LoadTexture(...);
glActiveTexture(GL_TEXTURE3);
LoadTexture(...);
shader.useNone();
Now in display function you do it like this,
shaderuse();
vao.bind();
glDrawArrays(GL_QUADS, 0, worldData.getNumVertices());
vao.unbind();
shader.useNone();
see if this helps.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.