【问题标题】:If not GL_QUADS, then how?如果不是 GL_QUADS,那怎么办?
【发布时间】:2013-12-23 06:37:15
【问题描述】:

我正在使用用于 OpenGL 的 LWJGL 包装器在 Java 中开发一个简单的 2D 游戏。
对于渲染方法,我使用 VBO。其他渲染方法似乎非常好且速度更快。
我正在阅读一些文章并在 StackOverflow 上寻找一些问题,我发现使用 2 个三角形比使用一个四边形更好,因为现代 GPU 只显示三角形(让 GPU 将四边形转换为三角形将是一种浪费。

我知道的唯一方法是创建 2 个缓冲区来存储顶点数据和纹理坐标数据。这是一个四边形,这就是我的做法:

int vertexID; //Holding the GL buffer ID for the Vertex
int texCoordsID; //Holding the GL buffer ID for the texture coords

void init(){
    //BufferUtils is a Utility class provided by the SlickUtil library, I use it for creating buffers.
    //Create float buffer for storing vertex data
    FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(4 * 2);
    //Put vertex data inside the buffer
    vertexBuffer.put(new float[]{
        0, 0,
        100, 0,
        100, 100,
        0, 100
    });
    //Rewind the buffer
    vertexBuffer.rewind();

    FloatBuffer texCoordsBuffer = BufferUtils.createFloatBuffer(4 * 2);
    texCoordsBuffer.put(new float[]{
        0, 0,
        1, 0,
        1, 1,
        0, 1
    });
    texCoordsBuffer.rewind();

    vertexID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vertexID);
    glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    texCoordsID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, texCoordsID);
    glBufferData(GL_ARRAY_BUFFER, texCoordsBuffer, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void render(){
    glBindTexture(GL_TEXTURE_2D, texture.id); //Not so important.

    glBindBuffer(GL_ARRAY_BUFFER, vertexID);
    glVertexPointer(2, GL_FLOAT, 0, 0);

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

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

现在我的主要问题是,如何将其拆分为 2 个三角形而不是 1 个四边形?
还有一个附带的问题:2D 游戏真的很重要吗?会不会有细微的变化?

【问题讨论】:

  • 将四边形/矩形分割成三角形就像是基本的几何知识。
  • @Vallentin OpenGL 是否为它提供任何功能,或者我应该只制作 4 个缓冲区? 2 代表顶点,2 代表纹理?
  • 为什么要拥有 2 个顶点缓冲区?您可以简单地拥有一个顶点缓冲区。您甚至可以将 2 个顶点和 2 个纹理缓冲区作为单个缓冲区。它叫Interleaved Buffers
  • 具有讽刺意味的是,大多数实现都将四边形分解为三角形。如果您尝试绘制在某些实现中不共面的GL_QUADGL_POLYGON,您可以看到这一点;第一个三角形将被光栅化,不会出现其他任何内容。您所要做的就是使用索引三角形列表、条带或复制一些顶点。在索引三角形列表解决方案中,您实际上会引入一个新缓冲区,即索引缓冲区(元素数组,如 GL 所称)。
  • 顺便问一下,您真的需要 2D 游戏中的所有低级功能吗? libgdx 使许多常见任务变得更容易。 (适用于 2D 和 3D 游戏开发)

标签: java opengl lwjgl


【解决方案1】:

改变一下

glDrawArrays(GL_QUADS, 0, 4);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

并添加一个稍微不同的顶点缓冲区

vertexBuffer.put(new float[]{
     1.0, 1.0
    -1.0, 1.0
     1.0,-1.0
    -1.0,-1.0
});

这代表两个三角形,两个“点”是一样的,所以我们只有四个“点”。

就像:

x3__x4
| \  |
|  \ | 
x1__x2

【讨论】:

  • 当我运行带有这些更改的代码时,似乎什么也没有出现,我更改了 glDrawArrays 中的模式,并更改了 vertexBuffer,它会是什么?
  • 我不知道您的视图是如何构建的,但至少,当我查看上面的缓冲区时,您只需将值更改为在我的示例中,范围在 0 到100.
  • @OrelBitton:如果你想让它工作,请确保你使用单位矩阵进行投影和模型视图。如果你这样做,四边形将填满你的整个屏幕,因为你将在标准化设备坐标中绘图。否则,这些点可能在投影后的任何地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 2021-08-17
  • 2022-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多