OpenGL VBO - Array Stride错了吗?

时间:2012-01-30 07:12:13

标签: java android arrays opengl-es-2.0 vbo

现在我希望你可以帮助我解决这个问题,我已经有好几天了,没有找到任何解决方案。我觉得,我已经尽力解决这个问题,但没有一个能够解决问题。

首先: 我的场景中有一些对象,它们使用VBO进行渲染。没有别的,没有其他四边形,多边形等,只有屏幕截图中的那些,将会跟随。

我的一代 - 维也纳国际组织的代码非常简单,希望清晰易懂:

生成VBO

public boolean buffer() {
    FloatBuffer[] vertexBuffer = new FloatBuffer[1];
    vertexBuffer[0] = FloatBufferFactory.create(this.triangles.size() * 3 * 11);

    for (Triangle triangle : this.triangles) {
        for (int i = 0; i < 3; i++) {
            vertexBuffer[0].put(triangle.vertex[i].position.x);
            vertexBuffer[0].put(triangle.vertex[i].position.y);
            vertexBuffer[0].put(triangle.vertex[i].position.z);

            vertexBuffer[0].put(triangle.vertex[i].normal.x);
            vertexBuffer[0].put(triangle.vertex[i].normal.y);
            vertexBuffer[0].put(triangle.vertex[i].normal.z);

            vertexBuffer[0].put(triangle.vertex[i].color.r);
            vertexBuffer[0].put(triangle.vertex[i].color.g);
            vertexBuffer[0].put(triangle.vertex[i].color.b);

            vertexBuffer[0].put(triangle.vertex[i].uvset.x);
            vertexBuffer[0].put(triangle.vertex[i].uvset.y);
        }
    }

    vertexBuffer[0].position(0);

    GLES20.glGenBuffers(1, this.buffer, 0);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.buffer[0]);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer[0].capacity() * 4, vertexBuffer[0], GLES20.GL_STATIC_DRAW);

    return true;
}

非常简单:我自己在FloatBufferFactory中的函数创建了一个三角形计数* 3 * 11 * 4字节的Floatbuffer。 然后我将数据放入其中,用于三角形的每个顶点。

我的逻辑:一个顶点位置为12个字节(3 * 4个字节),一个正常位置为12个字节,Vertexcolordata为12个字节,UV坐标为8个字节。

渲染

当我渲染网格时,我使用跟随函数一样简单:

public void render() {
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.buffer[0]);

    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0]);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 12);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 24);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 36);        

    this.passMaterialUniforms();
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, this.triangles.size() * 3);
}

现在,我的逻辑,正如我所理解的那样: 一个顶点的字节中的所有数据是:12Bytes(位置)+ 12Bytes(正常)+12Bytes(颜色)+ 8Bytes(uv) - &gt;总结:每个顶点44个字节,因此下一个顶点应该在44个字节之后。 - &GT;步幅:每个数据44个字节。

下一个想法是设置起始偏移:位置为0Bytes,正常为12Bytes,颜色为24Bytes,uv为36Bytes。 到目前为止一切都很好。

主要问题

现在似乎在程序中发生了非常非常奇怪的事情。创建超过3个对象后,在前三个之后生成的对象显示错误。

这里有截图: 第一个例子并尝试(生成:连续5个圆环): As you can see, in the first picture the 4. and 5. Torus ( Tori?!) are distorted and look like beans or lenses, or something like that.

第二次尝试(Generated 2 Spheres,1 Torus,另一个Sphere,另一个Torus): the 3. Sphere ( 4. generated object) looks quite normal, when you just look at the positions, but the texture-coordinates are very strange.

正如你所看到的,在第一张照片中,4和5. Torus(Tori?!)是扭曲的,看起来像豆子或镜头,或类似的东西。 在第二张图片中,3.球体(4.生成的物体)看起来很正常,当你只看位置时,纹理坐标非常奇怪。

那为什么呢?我该如何解决这个问题?

谢谢! :)

1 个答案:

答案 0 :(得分:2)

我认为这是由于您启用了attrib指针的方式。

你写了这个:

GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0]);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 12);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 24);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 36);

应该是这样的:

GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, 0);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, 12);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, 24);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, 36);

无论如何,我建议为偏移计算定义一些常量。

在我的C引擎中,我使用sizeof函数

来构建所有内容