这是使用 OpenGL 渲染图块的有效方法吗?

Posted

技术标签:

【中文标题】这是使用 OpenGL 渲染图块的有效方法吗?【英文标题】:Is this an efficient way of rendering tiles with OpenGL? 【发布时间】:2020-05-04 14:42:19 【问题描述】:

这是我用来渲染图块的例程

    private static void renderTile(int x1, int y1, int size) 
        glBegin(GL_TRIANGLES);

        double halfSize = size/2;

        glVertex2d(x1 + halfSize, y1 + halfSize);
        glVertex2d(x1 + halfSize, y1 - halfSize);
        glVertex2d(x1 - halfSize, y1 - halfSize);

        glVertex2d(x1 - halfSize, y1 - halfSize);
        glVertex2d(x1 - halfSize, y1 + halfSize);
        glVertex2d(x1 + halfSize, y1 + halfSize);
        glEnd();
    

现在,例程可以正常工作,但是看起来有点混乱。有没有更好的方法来使用 Java OpenGL + LWJGL 做到这一点?

【问题讨论】:

您使用的是 opengl 1 api。使用现代的 opengl api 更好。 使用瓷砖的确切原因是什么?也许您一直都不需要图块,只需渲染一个四边形和一个适当的片段着色器即可获得相同的结果。 【参考方案1】:

您在旧 GL 中的代码存在重大问题:

计算glBegin/glEnd内部的坐标 混合使用 doubleint 会强制在类型之间进行代价高昂的转换 不使用向量 昂贵的原语 使用double

使用glVertex2dv 并将坐标预先计算到某个表中会更快(遗憾的是,您当前的 api 不支持需要更改应用架构的静态表)。顺便说一句,这是对 VBO 使用的一个简单的小飞跃。此外,doubles 通常在旧 GL 中被浪费,因为插值器无论如何都是 32 位的(即使在新硬件上也是如此)。所以为了优化,我会将你的代码转换成这样的东西(对不起,我不是用 C++ 编写的 JAVA 编码器,所以它可能在语法上不正确):

private static void renderTile(float x, float y, float size) 
    
    const float  a = 0.5*size;
    const float p[4*2]= 
        
        x-a,y-a,
        x+a,y-a,
        x+a,y+a,
        x-a,y+a,
        ;

    glBegin(GL_QUADS);
    glVertex2fv(p); p+=2;
    glVertex2fv(p); p+=2;
    glVertex2fv(p); p+=2;
    glVertex2fv(p); p+=2;
    glEnd();
    

但是,如果您想要真正的力量,请使用 VBO。见

complete GL+GLSL+VAO/VBO C++ example。

【讨论】:

【参考方案2】:

不,它没有效率。您应该使用显示列表甚至更好 - 顶点缓冲区对象 (VBO)。

【讨论】:

DisplayLists 通常会减慢当前硬件的速度……它们是 20 年前的事情,但即便如此,也仅适用于某些 gfx 卡。

以上是关于这是使用 OpenGL 渲染图块的有效方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 opencl 将软件渲染到 opengl 2d 视图 [关闭]

AS3 从图块表中批量裁切图块的最佳方法?

OpenGL - 会使用多个 VBO 减慢渲染速度吗?

在 OpenGL 中重用纹理和顶点

在 OpenGL 中绘制 3d 图形的最有效方法是啥?

渲染大量四边形的有效方法(LibGDX/OpenGL ES)