Domanda

I'm migrating from OGL immediate mode to VBO. I'm rendering quads, and my normals work in immediate mode. But I can't get normals to work properly with VBO.

setup:

            vertexData = BufferUtils.createFloatBuffer(12);
            vertexData.put(new float[]{xCor[0], yCor[0], zCor[0],xCor[1], yCor[1], zCor[1],xCor[2], yCor[2], zCor[2],xCor[3], yCor[3], zCor[3]});
            vertexData.flip();

            texData = BufferUtils.createFloatBuffer(8);
            texData.put(new float[]{tCor[0],tCor[1],tCor[2],tCor[3],tCor[4],tCor[5],tCor[6],tCor[7]});
            texData.flip();

            normalData = BufferUtils.createFloatBuffer(3);
            normalData.put(new float[]{nCor[0],nCor[1],nCor[2]});
            normalData.flip();

            normalHandle = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, normalHandle);
            glBufferData(GL_ARRAY_BUFFER, normalData, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);

            vboVertexHandle = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
            glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);

            vboTexHandle = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, vboTexHandle);
            glBufferData(GL_ARRAY_BUFFER, texData, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);

rendering:

    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glVertexPointer(3, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, vboTexHandle);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, normalHandle);
    glNormalPointer(GL_FLOAT,0,0L);


    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);


    glDrawArrays(GL_QUADS, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

in it's current state it only lights up one out of the two triangles making up the quad. I can see why, but doubling the buffer size and repeating the normal vector coordinates didn't exactly solve it. How's one supposed to input a normalvector to a VBO with one quad, i.e two triangles?

È stato utile?

Soluzione

How does your normal data look like? Remember that each vertex consists of several attributes, in your case it's [position, normal, texture_coordinate].

A lot of newbies transitioning away from immediate mode have that misconception, that the "vertex" was just the position. They have 1 call to glNormal, followed by 3 or 4 calls to glVertex, making them think that there was 1 normal per 3 or 4 vertices. This is not the case. In fact glVertex makes a copy of all the other vertex attribute states, with the parameters of glVertex supplying the position attribute.

A more apt API would have been:

glNormal(…);
glPosition(…); /* that one doesn't exist */
glTexCoord(…);
glEmitVertex(); /* doesn't exist either, takes no parmeters */

However vertex arrays just see the readily usable data. So every vertex requires the full monty, so to speak. It's not clear from your code if you did that. But contemplating your problem's description it sounds a lot like this issue.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top