Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Some help with VBOs and glDrawElements()

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    12

    Some help with VBOs and glDrawElements()

    Hey new here, and new to OpenGL I also will apologize if there has already been a thread or a discussion (as I am a bit lazy to use the Search function and didn't really find anything that pertained to my question when I did) Anyways the issue is that I'm building a 3D game engine in Java using OpenGL and the LWJGL and i'm trying to get multi-texturing to work however when I try to render it (with a glDrawElements() call
    Code :
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
    glDrawElements(GL_TRIANGLES, m_index.length, GL_UNSIGNED_INT, (long)0);
    I get the error of "cannot use an offset when ELEMENT_ARRAY_BUFFER is disabled" which is driving me mad and I've been caught on this for 3 weeks now and I really need to move on from it.
    3dgep.com/?p=1116
    this is the site that i'm trying to convert C++ to Java from to get the very effect shown in it.

    If anyone can help me solve this issue, and maybe explain how Buffers and the like work would be much appreciated too. I'm also using Java to do this just as a reminder.

  2. #2
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by Hugo_the_Dwarf View Post
    I get the error of "cannot use an offset when ELEMENT_ARRAY_BUFFER is disabled"
    Has indexBuffer been initialised with glGenBuffers()? Has the buffer been populated with e.g. glBufferData()?

  3. #3
    Junior Member Regular Contributor
    Join Date
    Aug 2006
    Posts
    226
    This link should help you:

    http://lwjgl.org/forum/index.php?topic=4494.0

    Regards
    elFarto

  4. #4
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    12
    Quote Originally Posted by GClements View Post
    Has indexBuffer been initialised with glGenBuffers()? Has the buffer been populated with e.g. glBufferData()?
    yes I have used glGenBuffers()
    Code :
    createVertBuffer(indexBuffer);
     
    //Method used:
    private static int createVertBuffer(int ID)
    	{
    		deleteVertBuffer(ID);
    		ID = glGenBuffers();
    		return ID;
    	}
     
    private static void deleteVertBuffer(int ID)
    	{
    		if (ID != 0)
    		{
    			glDeleteBuffers(ID);
    			ID = 0;
    		}
    	}

    Probably how i'm doing it is incorrect and should just say "indexBuffer = glGenBuffer();" and leave the fancy method stuff out.

    Also elFarto I'm going to read that thread a bit and see, It seems close to my error and I tried changing the binding of my buffer and even using and glEnable still get this error:
    Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Element Array Buffer Object is disabled
    at org.lwjgl.opengl.GLChecks.ensureElementVBOenabled( GLChecks.java:105)
    at org.lwjgl.opengl.GL11.glDrawElements(GL11.java:111 7)
    at terrain.Chunk.drawChunk(Chunk.java:320)
    at terrain.Terrain.draw(Terrain.java:84)
    at Main.render(Main.java:145)
    at Main.main(Main.java:83)


    If you are wondering how I put data into some of my buffers I have a init method that runs before the drawChunk can even be called.
    when I run this code: (PS the part of the code with a problem I added a bunch of "//" spacers so you can quickly scroll to it.)
    Code :
    public void drawChunk()
    	{
    		ByteBuffer off = BufferUtils.createByteBuffer(1);
     
    		glMatrixMode( GL_MODELVIEW );
    		glPushMatrix();
    		//Below is suppose to take a float? Ref code:
    		//glMultMatrixf( glm::value_ptr(m_LocalToWorldMatrix) );
    //		glMultMatrix(m);
     
    		/* Setting up texture stage 0 (or bottom texture) */
    		glActiveTexture( GL_TEXTURE0 );
    		glMatrixMode( GL_TEXTURE );
    		glPushMatrix();
    //		glScalef(32.0f, 32.0f, 1.0f); scaling out for now
     
    		glEnable( GL_TEXTURE_2D );
    		glBindTexture(GL_TEXTURE_2D, textures[0]);
     
    		glClientActiveTexture( GL_TEXTURE0 );
    		glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    		glBindBuffer( GL_ARRAY_BUFFER, tex0Buffer);
    		glTexCoordPointer(2, GL_FLOAT, 0, off );
     
    	    // Disable lighting because it changes the primary color of the vertices that are
    	    // used for the multitexture blending.
    	    glDisable( GL_LIGHTING );
     
    	    // Texture Stage 1
    	    // Perform a linear interpolation between the output of stage 0
    	    // (i.e texture0) and texture1 and use the RGB portion of the vertex's
    	    // color to mix the two.
    	    glActiveTexture(GL_TEXTURE1 );
    	    glMatrixMode( GL_TEXTURE );
    	    glPushMatrix();
    //	    glScalef( 32.0f, 32.0f , 1.0f );
     
    	    glEnable( GL_TEXTURE_2D );
    	    glBindTexture( GL_TEXTURE_2D, textures[1] );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR );
     
    	    glClientActiveTexture(GL_TEXTURE1);
    	    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    	    glBindBuffer( GL_ARRAY_BUFFER, tex1Buffer );
    	    glTexCoordPointer(2, GL_FLOAT, 0, off );
     
    	    // Texture Stage 2
    	    // Perform a linear interpolation between the output of stage 1
    	    // (i.e texture0 mixed with texture1) and texture2 and use the ALPHA
    	    // portion of the vertex's color to mix the two.
    	    glActiveTexture( GL_TEXTURE2 );
    	    glMatrixMode( GL_TEXTURE );
    	    glPushMatrix();
    //	    glScalef( 32.0f, 32.0f , 1.0f );
     
    	    glEnable( GL_TEXTURE_2D );
    	    glBindTexture( GL_TEXTURE_2D, textures[2] );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
     
    	    glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR );
    	    glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA );
     
    	    glClientActiveTexture(GL_TEXTURE2);
    	    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    	    glBindBuffer( GL_ARRAY_BUFFER, tex2Buffer );
    	    glTexCoordPointer(2, GL_FLOAT, 0, off );
     
    	    //Rendering
    	    glEnableClientState( GL_VERTEX_ARRAY );
    	    glEnableClientState( GL_COLOR_ARRAY );
    	    glEnableClientState( GL_NORMAL_ARRAY );
     
    	    glBindBuffer( GL_ARRAY_BUFFER, vboVertexHandle );
    	    glVertexPointer( 3, GL_FLOAT, 0, off );
    //	    glBindBuffer( GL_ARRAY_BUFFER, color );
    //	    glColorPointer( 4, GL_FLOAT, 0, 0 );
    	    glBindBuffer( GL_ARRAY_BUFFER, vboNormalHandle );
    	    glNormalPointer( GL_FLOAT, 0, off );
     
    //
    //
    //
    //
                glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
    	    glDrawElements(GL_TRIANGLES, m_index.length, GL_UNSIGNED_INT, (long)0);
    //	    glDrawArrays(GL_TRIANGLES, 0, 3); //Works but causes crashes and weird rendering
    //
    //
    //
     
    	    //Cleanup 
    	    glDisableClientState( GL_NORMAL_ARRAY );
    	    glDisableClientState( GL_COLOR_ARRAY );
    	    glDisableClientState( GL_VERTEX_ARRAY );
     
    	    glActiveTexture(GL_TEXTURE2);
    	    glPopMatrix();
    	    glDisable(GL_TEXTURE_2D);
    	    glClientActiveTexture(GL_TEXTURE2);
    	    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
     
    	    glActiveTexture(GL_TEXTURE1);
    	    glPopMatrix();
    	    glDisable(GL_TEXTURE_2D);
    	    glClientActiveTexture(GL_TEXTURE1);
    	    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
     
    	    glActiveTexture(GL_TEXTURE0);
    	    glPopMatrix();
    	    glDisable(GL_TEXTURE_2D);
    	    glClientActiveTexture(GL_TEXTURE0);
    	    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
     
    	    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    	    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
     
    	    glMatrixMode( GL_MODELVIEW );
    	    glPopMatrix();
    	}

    Also Thank you guys for posting.

    Edit:
    Also sorry that this code is a mess, as some of the the spots I'm putting a byteBuffer called "off" that is size one, could be giving me grief but idk I'm new to all this (VBOs and OpenGL)
    Last edited by Hugo_the_Dwarf; 07-14-2013 at 10:53 AM. Reason: Forgot to mention something

  5. #5
    Junior Member Regular Contributor
    Join Date
    Aug 2006
    Posts
    226
    Change this:
    Code :
    glVertexPointer( 3, GL_FLOAT, 0, off );
    to:
    Code :
    glVertexPointer( 3, GL_FLOAT, 0, 0 );
    Aswell as the glNormalPointer and glTexCoordPointer calls.

    And you'll probably need:
    Code :
    glEnableClientState(GL_INDEX_ARRAY);

    Regards
    elFarto

  6. #6
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    12
    Alright i've changed the pointers to use 0 now it's complaining about the Array Buffer now and is failing ont he texcoord pointer

    Code :
    	    glClientActiveTexture(GL_TEXTURE2);
    	    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    	    glEnableClientState(GL_ARRAY_BUFFER);
    	    glBindBuffer( GL_ARRAY_BUFFER, tex2Buffer );
    	    glTexCoordPointer(2, GL_FLOAT, 0, 0 );
     
    also I added this:
     
    	    //Rendering
    	    glEnableClientState( GL_INDEX_ARRAY );
    	    glEnableClientState( GL_VERTEX_ARRAY );
    	    glEnableClientState( GL_COLOR_ARRAY );
    	    glEnableClientState( GL_NORMAL_ARRAY );
     
    	    glBindBuffer( GL_ARRAY_BUFFER, vboVertexHandle );
    	    glVertexPointer( 3, GL_FLOAT, 0, 0 );
    //	    glBindBuffer( GL_ARRAY_BUFFER, color );
    //	    glColorPointer( 4, GL_FLOAT, 0, 0 );
    	    glBindBuffer( GL_ARRAY_BUFFER, vboNormalHandle );
    	    glNormalPointer( GL_FLOAT, 0, 0 );

  7. #7
    Junior Member Regular Contributor
    Join Date
    Aug 2006
    Posts
    226
    Firstly, remove the glEnableClientState(GL_ARRAY_BUFFER); call, that's not legal.

    Secondly, check that tex2Buffer really is non-zero.

    Regards
    elFarto
    Last edited by elFarto; 07-14-2013 at 01:29 PM.

  8. #8
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by elFarto View Post
    And you'll probably need:
    Code :
    glEnableClientState(GL_INDEX_ARRAY);
    Nope. GL_INDEX_ARRAY is the equivalent of GL_COLOR_ARRAY, except the former uses palette indices while the latter uses RGBA colours.

  9. #9
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    498
    Quote Originally Posted by Hugo_the_Dwarf View Post
    yes I have used glGenBuffers()
    That only answers one of the questions. Have you allocated the buffer's data store with glBufferData()?

  10. #10
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    12
    Quote Originally Posted by GClements View Post
    That only answers one of the questions. Have you allocated the buffer's data store with glBufferData()?
    Here is my Method for filling data

    Code :
    public void setUpVBO()
    	{
    		/* size the m_holders */
    		m_position = new Vector3f[faces.size() * 9];// not sure if this is the height * width??
    		m_color = new Vector4f[faces.size() * 9];
    		m_normal = new Vector3f[faces.size() * 9];
    		m_tex0 = new Vector2f[faces.size() * 9];
     
    		//set up the handles
    		createVertBuffer(vboVertexHandle);
    		createVertBuffer(vboNormalHandle);
     
            //set up the buffers
            FloatBuffer verticesBuffer = BufferTools.reserveData(faces.size() * 9);
            FloatBuffer normalsBuffer = BufferTools.reserveData(faces.size() * 9);     		
     
            //loop through every face in the chunk
            for (Face face : faces) {
            	verticesBuffer.put(BufferTools.asFloats(vertices.get(face.getVertexIndices()[0])));
            	verticesBuffer.put(BufferTools.asFloats(vertices.get(face.getVertexIndices()[1])));
            	verticesBuffer.put(BufferTools.asFloats(vertices.get(face.getVertexIndices()[2])));
     
            	normalsBuffer.put(BufferTools.asFloats(normals.get(face.getVertexIndices()[0])));
            	normalsBuffer.put(BufferTools.asFloats(normals.get(face.getVertexIndices()[1])));
            	normalsBuffer.put(BufferTools.asFloats(normals.get(face.getVertexIndices()[2])));
            }
           // Vector3f n1 = normals.get(face.getVertexIndices()[0]);
            //glNormal3f(n1.x, n1.y, n1.z);
     
            verticesBuffer.flip();
            normalsBuffer.flip();
     
            glPushMatrix();
            glTranslatef(location.x, 0, location.y);
            glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
            glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, vboNormalHandle);
            glBufferData(GL_ARRAY_BUFFER, normalsBuffer, GL_DYNAMIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            if (len.length > 0)
            {        	
            	int numTriangles = (len.length - 1) * (len.length - 1) * 2;
     
            	m_index = new int[numTriangles * 3];
            	int index = 0;
            	for (int j = 0; j < (len.length - 1); ++j)
            	{
            		for (int i = 0; i < (len.length - 1); ++i)
            		{
            			int vertexIndex = (j * len.length) + i;
            			//Top Triangle
            			m_index[index++] = vertexIndex;
            			m_index[index++] = vertexIndex + len.length + 1;
            			m_index[index++] = vertexIndex + 1;
            			//Bottom Triangle
            			m_index[index++] = vertexIndex;
            			m_index[index++] = vertexIndex + len.length;
            			m_index[index++] = vertexIndex + len.length + 1;
            		}
            	}
            }
     
            /* create the buffers for drawing */
    		createVertBuffer(vertBuffer);
    		createVertBuffer(normBuffer);
    		createVertBuffer(colBuffer);
    		createVertBuffer(tex0Buffer);
    		createVertBuffer(tex1Buffer);
    		createVertBuffer(tex2Buffer);
    		createVertBuffer(indexBuffer);
     
    		glBindBuffer( GL_ARRAY_BUFFER, colBuffer );
    	    glBufferData( GL_ARRAY_BUFFER, m_color.length, GL_STATIC_DRAW );
     
    		/* setup the textures and give the buffers the intel */
    		textures[0]=setupTextures("res/textures/Grass.png");
     
            glBindBuffer(GL_ARRAY_BUFFER, tex0Buffer);
            glBufferData(GL_ARRAY_BUFFER, textures[0], GL_DYNAMIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            textures[1]=setupTextures("res/textures/Dirt.png");
     
            glBindBuffer(GL_ARRAY_BUFFER, tex1Buffer);
            glBufferData(GL_ARRAY_BUFFER, textures[1], GL_DYNAMIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            textures[2]=setupTextures("res/textures/Stone.png");
     
            glBindBuffer(GL_ARRAY_BUFFER, tex2Buffer);
            glBufferData(GL_ARRAY_BUFFER, textures[2], GL_DYNAMIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index.length, GL_STATIC_DRAW);
     
            hasList = true;
     
    	}

    And I will check the Tex2Buffer != 0 when I get back from work. Thanks for helping guys.

    EDIT:
    Ok I ran some lines to output the buffers int (the id placeholder) and yes Tex2Buffer was 0, so I scrapped the idea of my "createVertBuffer" method and went right for <buffer> = glGenBuffers(); which now I stop getting the "Cannot do this since the Array Buffer is disabled" can it now runs without crashing. However nothing renders at this point. If anyone can see how to get it to render correctly that'd be nice, however I'm gonna try to plug away at this and see if something jumps to life.

    Thank you for all the help, and if anymore help on getting this stuff to actually get drawn would be nice too. But overall thank you (never thought to see if my helper method was not doing it's job)
    Last edited by Hugo_the_Dwarf; 07-14-2013 at 08:15 PM. Reason: Confirming some things

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •