我正在使用OpenGL为Android编写我的第一个2D应用程序。我正在写我的欲望,所以我的屏幕坐标在横向模式下应该是0到799,479。我试图让OpenGL在世界坐标中使用这个范围。
应用程序,比如它,到目前为止工作得很好,但是我不得不调整数字以便让屏幕上显示内容,而我对无法理解投影矩阵之间的关系感到沮丧,并且在这方面渲染纹理。
设置投影矩阵:
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
float size = .01f * (float) Math.tan(Math.toRadians(45.0) / 2);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-size, size, -size / ratio, size / ratio, 0.01f, 100.0f);
// GLU.gluOrtho2D(gl, 0,width, 0, height);
我想在这里理解0.01f和100.0f。我用什么来描述0,0 - >的2D世界? 799,479,z值为零?
另外,我不确定什么是“最好” - 使用glFrustumF或GLU.gluOrtho2D后者有更简单的参数 - 只是视口的尺寸 - 但我没有任何地方。 (有些网站的高度和0相反,但没有区别。)但这不应该是2D使用OpenGL的自然选择吗?我是否必须在某个地方设置一些内容来对OpenGL说“我在2D中这样做 - 请为了速度而无视任何地方的第三个维度”?
绘制纹理
我正在使用2个纹理三角形绘制内容。我的init的相关部分(让我知道是否需要更详细地编辑我的问题)是:
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatex(nXpos, nYpos, nZoomin);
gl.glRotatef(nRotZ, 0, 0, 1);
gl.glScalef((float)nScaleup,(float)nScaleup, 0.0f);
...
...
gl.glVertexPointer(2, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
mVertexBuffer is an IntBuffer and contains:
int vertices[] =
{
-1, -1,
1, -1,
-1, 1,
1, 1
};
我最终不打算通过nZoomin - 我已经这样做了,因为这是我发现实际看到任何东西所需的“神奇数字”!目前我需要在那里使用-1000,数字越小,图像越小。我正确地认为,当投影矩阵设置正确时,nZoomin必须有某种方法使其值为零吗?
我的纹理目前是128x128(但最终可能会有不同的尺寸,但可能总是正方形)。我无法知道他们当前以实际尺寸显示的时间。我希望能够为nScaleup传递128的值,以便将其绘制为实际大小。这与投影矩阵有关,还是我有两个不同的问题?
答案 0 :(得分:8)
如果您使用的是2D,则不需要glFrustum
,只需使用glOrtho
。像这样:
void glOrthof(0, 800, 0, 480, -1, 1);
那将原点放在左下角。如果您想要它在左上角,请使用:
void glOrthof(0, 800, 480, 0, -1, 1);
对于480和800,您显然应该替换视图的实际大小,以便您的应用程序可以移植到不同的屏幕尺寸和配置。
我为z范围传递-1和1,但这些并不重要,因为正交投影将(x,y,z)放在屏幕上的同一位置,无论z的值如何。 (但是,near和far必须不相等。)这是告诉OpenGL忽略z坐标的唯一方法;没有特定的“2D”模式,您的矩阵仍然是4x4,而2维顶点将获得z坐标为0。
请注意,您的坐标不是的范围是0到799,但实际上是0到800.原因是OpenGL将坐标解释为位于像素之间的,而不是< em> on 他们。可以把它想象成一个30厘米的尺子:它上面有30个厘米的间隔,刻度为0-30。
您正在使用的顶点缓冲区不起作用,因为您使用的是GL_FIXED
格式。这意味着小数点前16位,后面16位,因此要在原点周围指定2x2方格,您需要将每个值乘以0x10000
:
int vertices[] =
{
-0x10000, -0x10000,
0x10000, -0x10000,
-0x10000, 0x10000,
0x10000, 0x10000
};
这可能是您需要如此扩展它的原因。如果你使用这个数组,没有缩放,你应该得到一个2x2像素的正方形。把它变成一个1x1的正方形,所以尺寸可以直接用比例因子控制,留给读者练习;)
答案 1 :(得分:1)
我是否必须在某处设置某些内容以对OpenGL说“我在2D中这样做
我认为问题在于您使用投影矩阵进行透视投影。 相反,你应该使用平行投影。 要获得此矩阵,您可以使用glOrtho()函数。
gl.glMatrixMode(GL10.GL_PROJECTION);
...
gl.glOrtho(0, width, 0, height, 0, 128);
现在,z值不再影响对象的大小。
我想在这里理解0.01f和100.0f。我用什么来描述0,0 - >的2D世界? 799,479,z值为零?
在2D世界中,你并不真正拥有z值。但你必须决定 首先要绘制哪些对象。 有两种方法可以决定:
GL_DEPTH_TEST
并按照您选择的顺序绘制所有内容GL_DEPTH_TEST
并让OpenGL决定