LWJGL Forum

Programming => OpenGL => Topic started by: Fritzendugan on November 08, 2011, 02:37:21

Title: Trouble with glDrawArrays and vertex arrays
Post by: Fritzendugan on November 08, 2011, 02:37:21
Ok, my end goal of what I'm currently trying to do is load in a mesh from file, storing the vertex data and texture coord data into arrays, and then render this mesh to the screen. After I create the arrays, I create buffers for those arrays, and then I'd like to render them using glDrawArrays().

I've tried a couple different ways of rendering besides glDrawArrays() just to make sure that the data is actually populated correctly, which it does (you can see these commented out in the code dump). I'm not doing anything silly like using GL_FLOAT for stride or anything like that, but for some reason the mesh just doesn't show up when I use glDrawArrays().

anyway, here's the code dump: http://www.pastie.org/2829501
(or if you prefer here: // unrelated code not shown:
public class Shapes
{
   private final static float[] triVerts = new float[] {
       0.0f,  1.0f,  0.0f,
      -1.0f, -1.0f,  1.0f,
       1.0f, -1.0f,  1.0f,
       0.0f,  1.0f,  0.0f,
       1.0f, -1.0f,  1.0f,
       1.0f, -1.0f, -1.0f,
       0.0f,  1.0f,  0.0f,
       1.0f, -1.0f, -1.0f,
      -1.0f, -1.0f, -1.0f,
       0.0f,  1.0f,  0.0f,
      -1.0f, -1.0f, -1.0f,
      -1.0f, -1.0f,  1.0f
   };
   private final static float[] triTexCoord = new float[] {
       0f, 1f,
       1f, 1f,
       0f, 1f,
       0f, 0f,
       0f, 1f,
       1f, 1f,
       0f, 1f,
       0f, 0f,
       0f, 1f,
       1f, 1f,
       0f, 1f,
       0f, 0f
   };
   private final static FloatBuffer triVertBuffer = BufferUtil.toDirect(FloatBuffer.wrap(triVerts));
   private final static FloatBuffer triTexCoordBuffer = BufferUtil.toDirect(FloatBuffer.wrap(triTexCoord));
   
   public static void drawPyramidArrays(final float x, final float y, final float z)
   {
       glPushMatrix();
       
       glTranslatef(x,y,z);
       //* // this doesn't work
       glEnableClientState(GL_VERTEX_ARRAY);
       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
       
       glVertexPointer(3, 0, triVertBuffer);
       glTexCoordPointer(2, 0, triTexCoordBuffer);
       
       glDrawArrays(GL_TRIANGLES, 0, triVerts.length / 3);
       
       glDisableClientState(GL_VERTEX_ARRAY);
       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       // */
       /* // this works
       glBegin(GL_TRIANGLES);
           for(int i = 0; i < triVerts.length / 3; i++)
           {
               glTexCoord2f(triTexCoord[i*2], triTexCoord[i*2+1]);
               glVertex3f(triVerts[i*3], triVerts[i*3+1], triVerts[i*3+2]);
           }
       glEnd();
       // */
       /* // this also works
       glBegin(GL_TRIANGLES);
       for(int i = 0; i < triVerts.length / 3; i++)
       {
           glTexCoord2f(triTexCoordBuffer.get(), triTexCoordBuffer.get());
           glVertex3f(triVertBuffer.get(), triVertBuffer.get(), triVertBuffer.get());
       }
       triTexCoordBuffer.flip();
       triVertBuffer.flip();
       glEnd();
       // */
       
       glPopMatrix();
   }
}

// and then in my rendering code I'm doing:
public void onRender()
   {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
       glLoadIdentity(); // Reset The View
       camera.use();
       
       glColor3f(1f,1f,1f);
       
       // TODO render meshes
       glEnable(GL_TEXTURE_2D);
       testpacker.bindTexture();
       
       this.test[0].render(-2f, 0f, 3f); // this renders fine using a method similar to the ones I've commented out in the Shapes code.
       
       glBegin(GL_QUADS);
           glTexCoord2f(this.tex_sdot.getLeft(),  this.tex_sdot.getTop());    glVertex3f(-1f, 0f, -1f);
           glTexCoord2f(this.tex_sdot.getRight(), this.tex_sdot.getTop());    glVertex3f(1f, 0f, -1f);
           glTexCoord2f(this.tex_sdot.getRight(), this.tex_sdot.getBottom()); glVertex3f(1f, 0f, 1f);
           glTexCoord2f(this.tex_sdot.getLeft(),  this.tex_sdot.getBottom()); glVertex3f(-1f, 0f, 1f);
       glEnd();
       Shapes.drawPyramidArrays(-1.5f, 0f, 1.6f); // nothing shows up
       TexturePacker.bindNoTextures();
       glDisable(GL_TEXTURE_2D);
       
       glScalef(100f, 10f, 100f);
       Shapes.drawCube(0f, 0.5f, 0f, 0f); // this shows up fine
   }


your help is greatly appreciated! :D
Title: Re: Trouble with glDrawArrays and vertex arrays
Post by: Mickelukas on November 08, 2011, 09:42:00
Solved on JGO: http://www.java-gaming.org/topics/trouble-with-gldrawarrays-and-vertex-arrays/25033/view.html (http://www.java-gaming.org/topics/trouble-with-gldrawarrays-and-vertex-arrays/25033/view.html)

Quote from: fritzendugan
figured it out, when I was creating the buffers I wasn't setting the byteorder.

relevant code for anyone stuck:

ByteBuffer secondbuf = ByteBuffer.allocateDirect(buf.capacity() * Float.SIZE);
secondbuf.order(ByteOrder.nativeOrder());
final FloatBuffer ret = secondbuf.asFloatBuffer();
ret.put(buf);
ret.flip();

Title: Re: Trouble with glDrawArrays and vertex arrays
Post by: abcdef on November 08, 2011, 11:54:44
The byte order was not the issue, it was the line

ret.flip();

Once you populate a buffer its position is at the end of the buffer. To something that gets the buffer its empty as there are no elements left in the buffer to get data for.

By doing a rewind() or flip() on the array you are resetting the position to position 0 in the buffer. Flip does the additional thing of removing any marks from the buffer too, if you have a mark set in the middle of the buffer and you rewind, you rewind to that mark and not the beginning. But as you don't set any the effect is the same for using either. When you populate your buffers always do a rewind() or flip() at the end to reset everything ready for rendering.
Title: Re: Trouble with glDrawArrays and vertex arrays
Post by: Chuck on November 09, 2011, 05:02:52
flip() also sets the limit of the buffer to the current position, which you do if you're at the end of your data but not the end of your buffer.  If you wrote to the middle of the buffer and don't want to truncate the contents at the current position, you always want to call rewind() instead.