3

我正在用这段代码生成我的 VBO

    int SCREEN_WIDTH = 800;
    int SCREEN_HEIGHT = 480;
    int PIXEL_PER_VERTEX = 4;
    int CAVERN_TEXTURE_WIDTH = 1024;
    int CAVERN_TEXTURE_HEIGHT = 512;

    final int vertexCount = ((SCREEN_WIDTH / PIXEL_PER_VERTEX) +1 ) * 2;
    final float[] bufferDataLowerCave = new float[vertexCount * CavernBoundMesh.VERTEX_SIZE];

    for(int i=0; i < vertexCount; i += 2) {
        bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_X] = PIXEL_PER_VERTEX * i / 2.f;
        bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_Y] = 200;
        bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_U] = ( (float) PIXEL_PER_VERTEX * i / 2.f) / SCREEN_WIDTH;
        bufferDataLowerCave[i * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_V] = 0.f;

        bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_X] = PIXEL_PER_VERTEX * i / 2;
        bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.VERTEX_INDEX_Y] = 0;
        bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_U] = ( (float) PIXEL_PER_VERTEX * i / 2.f) / SCREEN_WIDTH;
        bufferDataLowerCave[(i + 1 ) * CavernBoundMesh.VERTEX_SIZE + CavernBoundMesh.TEXTURECOORDINATES_INDEX_V] = 0.5f;
    }

我正在用 TRIANGLE_STRIP 绘制网格(以原点为中心)。

抱歉,因为我使用的是引擎(AndEngine),所以没有 openGL 代码。但如果你真的需要,我可以尝试追踪它.. 显示的网格不正确

正如您在图像中看到的,最后 2 个顶点与原点中的一个顶点相连。我调试了 VBO 的创建,这是第一个和最后一个顶点

//X       Y       U        V
[0.0,    200.0,  0.0,     0.0,
 0.0,    0.0,    0.0,     0.5,
 4.0,    200.0,  0.0050,  0.0,
 4.0,    0.0,    0.0050,  0.5,
 8.0,    200.0,  0.01,    0.0,
 8.0,    0.0,    0.01,    0.5,
 12.0,   200.0,  0.015,   0.0,
 12.0,   0.0,    0.015,   0.5,
 16.0,   200.0,  0.02,    0.0,
 16.0,   0.0,    0.02,    0.5
 [..]
 780.0,  200.0,  0.975,   0.0,
 780.0,  0.0,    0.975,   0.5,
 784.0,  200.0,  0.98,    0.0,
 784.0,  0.0,    0.98,    0.5,
 788.0,  200.0,  0.985,   0.0,
 788.0,  0.0,    0.985,   0.5,
 792.0,  200.0,  0.99,    0.0,
 792.0,  0.0,    0.99,    0.5,
 796.0,  200.0,  0.995,   0.0,
 796.0,  0.0,    0.995,   0.5]

这是我使用的顶点着色器

uniform mat4 u_modelViewProjectionMatrix;
uniform float u_elapsedSeconds;

attribute vec4 a_position;
attribute vec2 a_textureCoordinates;

varying vec2 v_textureCoordinates;

void main(void)
{
    v_textureCoordinates = a_textureCoordinates;
    vec4 temp_position = u_modelViewProjectionMatrix * a_position;

    float variation = 0.3*sin((u_elapsedSeconds + 1.5 * temp_position.x))*(1.0 + temp_position.y);
    temp_position.y += variation;

    gl_Position = temp_position;
}

我对这个东西很陌生,所以我不太了解规格和​​它是如何工作的,但我真的不明白是怎么回事产生这种奇怪的效果。你能帮我吗?

编辑1:

我做了一些更多的测试。即使使用标准的顶点和片段着色器,它只是设置位置和从纹理中获取它的颜色,它会给出奇怪的结果。

EDIT2:更多图像,这次只是使用 2 个标准的垂直和碎片着色器用于位置和纹理颜色(这些图像是从平板电脑拍摄的,而第一张是从手机拍摄的)

错误的图像 1 2° 错误图像 3° 错误图像 我最喜欢的错误图片

4

2 回答 2

2

我很确定您为绘图代码指定了错误数量的图元,因为顶点本身对我来说看起来不错。当您对 openGL 或任何其他 3D 图元绘图进行绘图调用时,您不需要指定要绘制的顶点数,而是图元数。在您的情况下,原语是三角形。

因为它是一个三角形带,所以你正在绘制它numberOfVertices - 2在你的调用中总是原始的。如果它是一个三角形列表,它本来就是numberOfVertices/3​​,而对于一个三角形风扇,它又是一个numberOfVertices - 2

由于您可能指定要绘制的三角形多于要绘制的数据,因此它可能使用了一些默认值(0,0,0,0),这解释了它试图在左下角绘制两个退化三角形,这也引用了纹理坐标0,0。这也是有道理的,因为在您的列表中甚至没有具有位置0,0和 T/U0,0的顶点,因此最后一个顶点必须是某个默认值。

于 2012-08-28T17:17:26.803 回答
0

好的,我解决了。

在尝试了 libgdx 之后(我不是很喜欢它,它接缝了很多实用功能,而且我还没有真正掌握它背后的概念,例如它如何处理纹理,如何管理实体等)并实现一个非常小的带有 jni 的本地语言渲染器,还设置了 cocos-2d-x(但没有尝试过,因为我第一次使用 jni 代码并编写了上面提到的渲染器)我回到了 AndEngine。

我成功地用 VBO 和 IBO 实现了一个网格,但最后我通过在 VBO 的开始和结束处复制(添加 2 个相同的顶点)解决了我的问题,这样额外的三角形就会退化并且不会被绘制。所以,这是最有效的解决方法,但只要它有效..

于 2012-09-02T19:51:50.303 回答