VAO, VBO acting strangely.

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

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

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.

Damn, how did I miss that :wink:
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 :wink:

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 :wink:

“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]

“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.

So I assume you are saying that I should use a shader to define the behavior of my rendering?

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)

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?

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);

  1. You should query the uniform locations after you have use the shader program.
  2. 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.

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 ?

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.