这是使用OpenGL渲染瓦片的有效方法吗?

huangapple go评论65阅读模式
英文:

Is this an efficient way of rendering tiles with OpenGL?

问题

这是我用于渲染瓷砖的例程:

	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时有没有更好的方法来完成这个任务呢?

英文:

This is the routine I use for rendering the tiles

	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();
	}

Now, the routine works, but, it looks a bit messy. Is there a better way to do this with Java OpenGL + LWJGL?

答案1

得分: 1

不,这并不高效。你应该使用显示列表,甚至更好的选择是顶点缓冲对象(VBO)。

英文:

No, it is not efficient. You should use display lists or even better - vertex buffer object (VBO).

答案2

得分: 0

你的旧GL代码存在主要问题:

  • glBegin/glEnd内计算坐标
  • 混合使用doubleint,强制进行昂贵的类型转换
  • 不使用向量
  • 昂贵的图元
  • 使用double

使用glVertex2dv并预先计算坐标到某个表格中,会快得多(遗憾的是你当前的API不支持静态表格,这需要改变你的应用架构)。从那里,进一步跨入VBO的使用是很简单的。另外,旧GL中通常浪费了doubles,因为插值器无论如何都是32位的(即使在新硬件上也是如此)。所以为了优化,我会将你的代码转换成类似这样的形式(抱歉,我不是JAVA编程人员,我用的是C++,所以语法可能不正确):

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。请参考:

英文:

Your code in old GL has major problems:

  • computing the coordinates inside glBegin/glEnd
  • mixing double and int forcing costly conversion between types
  • not using vectors
  • expensive primitive
  • using double

Much faster would be to use glVertex2dv and precompute the coordinates once into some table (sadly your current api does not support static table that would require change in your app architecture). From that its a simple small leap into VBO usage btw. Also doubles are usually wasted in old GL as the interpolators are 32bit anyways (even on new HW). So to optimize I would convert your code to something like this (sorry not a JAVA coder I code in C++ so it might be syntacticaly incorrect):

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();
    }

However if you want true power then use VBO. See

huangapple
  • 本文由 发表于 2020年5月4日 22:42:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/61594873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定