帮我配置OpenGL for 2D

4 android 2d opengl-es

我正在使用OpenGL编写我的第一个Android应用程序.我正在写我的欲望,所以我的屏幕坐标在横向模式下应该是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);
Run Code Online (Sandbox Code Playgroud)

我想在这里理解0.01f和100.0f.我用什么来描述一个0,0 - > 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   
};
Run Code Online (Sandbox Code Playgroud)

我最终不打算通过nZoomin - 我已经这样做了,因为这是我发现实际看到任何东西所需要的"神奇数字"!目前我需要在那里使用-1000,数字越小,图像越小.我正确地认为,当投影矩阵设置正确时,nZoomin必须有某种方法使其值为零吗?

我的纹理目前是128x128(但最终可能会有不同的大小,但可能总是正方形).我无法知道他们当前以实际尺寸显示的时间.我希望能够为nScaleup传递128的值,以便将其绘制为实际大小.这与投影矩阵有关,还是我有两个不同的问题?

Tho*_*mas 8

如果你在2D工作,你不需要glFrustum,只需使用glOrtho.像这样的东西:

void glOrthof(0, 800, 0, 480, -1, 1);
Run Code Online (Sandbox Code Playgroud)

那将原点放在左下角.如果您想要它在左上角,请使用:

void glOrthof(0, 800, 480, 0, -1, 1);
Run Code Online (Sandbox Code Playgroud)

对于480和800,您显然应该替换视图的实际大小,以便您的应用程序可以移植到不同的屏幕尺寸和配置.

我正在为z范围传递-1和1,但这些并不重要,因为正交投影将(x,y,z)放在屏幕上的同一位置,无论z的值如何.(但是,near和far必须不相等.)这是告诉OpenGL忽略z坐标的唯一方法; 没有特定的"2D"模式,您的矩阵仍然是4x4,而2维顶点将接收0的z坐标.

请注意,您的座标从0到799,但真正从0到800的原因是OpenGL的解释坐标躺着之间的像素,不他们.可以把它想象成30厘米的尺子:它上面有30个厘米的间隔,刻度线编号为0-30.

您正在使用的顶点缓冲区不起作用,因为您正在使用GL_FIXED格式.这意味着小数点前16位,后面16位,因此要指定原点周围的2x2方形,需要将每个值乘以0x10000:

int vertices[] =  
{
    -0x10000, -0x10000,
     0x10000, -0x10000,
    -0x10000,  0x10000,
     0x10000,  0x10000
};
Run Code Online (Sandbox Code Playgroud)

这可能是您需要如此扩展它的原因.如果你使用这个数组,没有缩放,你应该得到一个2x2像素的正方形.把它变成一个1x1的正方形,所以尺寸可以直接用比例因子控制,留给读者练习;)