简体   繁体   中英

Unable to show 2 items simultaneously with Java OpenGL VBO's

I started to learn OpenGL and i try to extend my program by VBO's. I have the following code :

public void init(GLAutoDrawable d) {

        [...]

            int perVertexFloats = (3+4+2+3);
            float vertexData[] = loadVertexData("ball.vbo", perVertexFloats);
            float vertexData1[] = loadVertexData("bar.vbo", perVertexFloats);

            vertNo = vertexData.length / perVertexFloats;
            FloatBuffer dataIn = Buffers.newDirectFloatBuffer(vertexData.length);
            dataIn.put(vertexData);
            dataIn.flip();

            vertNo1 = vertexData1.length / perVertexFloats;
            FloatBuffer dataIn1 = Buffers.newDirectFloatBuffer(vertexData1.length);
            dataIn1.put(vertexData1);
            dataIn1.flip();

         // generating vertex VBO
            gl.glGenBuffers(1, vertBufID, 0);
            gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertBufID[0]);
            gl.glBufferData(GL2.GL_ARRAY_BUFFER, dataIn.capacity()*Buffers.SIZEOF_FLOAT, dataIn, GL2.GL_STATIC_DRAW);

         // generating vertex VBO2
            gl.glGenBuffers(1, vertBufID, 1);
            gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertBufID[1]);
            gl.glBufferData(GL2.GL_ARRAY_BUFFER, dataIn1.capacity()*Buffers.SIZEOF_FLOAT, dataIn1, GL2.GL_STATIC_DRAW);

        }

public void display(GLAutoDrawable d) {

[...]

        // activating VBO
        gl.glTranslatef(-0.1f, -0.85f, 0.0f);
        gl.glScalef(0.3f, 0.3f, 0.3f);                              // resize the ball
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertBufID[0]);
        int stride = (3+4+2+3)*Buffers.SIZEOF_FLOAT;
        int offset = 0;

     // activating VBO2
        gl.glTranslatef(2.0f, -0.2f, 0.0f);             
        gl.glScalef(3.0f, 3.0f, 3.0f);                              //resize the bar
        gl.glRotatef(90, 0.0f, 0.0f, 1.0f);     
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertBufID[1]);


     // position
        gl.glVertexPointer(3, GL2.GL_FLOAT, stride, offset);
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);

     // color
        offset = 0 + 3*Buffers.SIZEOF_FLOAT;
        gl.glColorPointer(4, GL2.GL_FLOAT, stride, offset);
        gl.glEnableClientState(GL2.GL_COLOR_ARRAY);

     // texture
        offset = 0 + (3+4)*Buffers.SIZEOF_FLOAT;
        gl.glTexCoordPointer(2, GL2.GL_FLOAT, stride, offset);
        gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);

        // normals
        offset = 0 + (3+4+2)*Buffers.SIZEOF_FLOAT;
        gl.glNormalPointer(GL2.GL_FLOAT, stride, offset);
        gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);

     // bind texture
        if(mode == 0) {
          gl.glEnable(GL2.GL_TEXTURE_2D);
          gl.glBindTexture(GL2.GL_TEXTURE_2D, texID);
          gl.glBindTexture(GL2.GL_TEXTURE_2D, texID1);
        }else{
          gl.glDisable(GL2.GL_TEXTURE_2D);
          gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
        }

        // render data
        gl.glDrawArrays(GL2.GL_TRIANGLES, 0, vertNo);

     // render data2
        gl.glDrawArrays(GL2.GL_TRIANGLES, 0, vertNo1);


        gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
        gl.glDisable(GL2.GL_TEXTURE_2D);

        gl.glFlush();
    }

My objects are a ball and a bar. Firstly i tested the code only with the ball. It appeared. Then i wanted to also add the bar. The bar appeared. My problem is that, when the bar appeared, the ball disappeared. I want both the ball and the bar to be shown at one time. Can somebody help me and tell me where is my mistake?

The problem lies in the display function: You are only specifying Vertex/Color/... pointers for the second buffer bound. The reason for this is that OpenGL always operates on the current state. So if you bind another buffer, then the first buffer is not present anymore. Thus the vertex pointer are only operating on the buffer that is bound last. Same for the draw function which also only operates on the currently set vertex pointers.

If you want to have both drawn, then the logical order has to look somehow like this:

//First object
glTranslatef/glScalef/... for object1
glBindBuffer(buffer1)

gl.glVertexPointer(...) and all the other pointers/glEnableClientStates

gl.glDrawArrays(vertNo);

//Now second object

glTranslatef/glScalef/... for object2
glBindBuffer(buffer2)

gl.glVertexPointer(...) and all the other pointers/glEnableClientStates

gl.glDrawArrays(vertNo1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM