我开始学习使用java在android (GL10)中使用open GL,我还学习了一些绘制正方形、三角形等的教程。
现在我开始画一些我有的想法,但我真的对绘制屏幕的顶点感到困惑。当我使用openGL ES绘制一些东西时,我必须指定我想要绘制的屏幕部分,对于纹理也是如此。
所以我开始做一些测试,我用这个顶点打印了一个全屏纹理:
(-1, -1, //top left
-1, 1, //bottom left
1, -1, //top right
1, 1); //bottom right
为什么是全屏?OpenGL坐标的中心不是在左上角(0,0)吗?为什么使用顶点绘制是正确的?看起来中心实际上是屏幕的中心,宽度和高度是-1...1,但我并不是真的理解它,因为我以为中心在左上角……
另一个问题。我读了很多使用像素打印的c++代码。在视频游戏中使用像素似乎真的很有必要,因为它需要物体的确切位置,而使用-1...1我不能真正精确。如何使用像素而不是-1...1?
对于我糟糕的英语,真的很感谢和抱歉。谢谢
发布于 2012-02-19 20:51:33
为什么是全屏?OpenGL坐标的中心不是在左上角(0,0)吗?为什么使用顶点绘制是正确的?看起来中心实际上是屏幕的中心,宽度和高度是-1...1,但我并不是真的理解它,因为我以为中心在左上角……
有3件事情在一起。所谓的视区,即所谓的归一化设备坐标( NDC ),以及从模型空间到眼睛空间再到裁剪空间到NDC空间的投影。
视口将选择窗口中NDC范围所在的部分
[-1…1]×[-1…1]
映射到。函数签名为glViewport(x, y, width, height)
。OpenGL假设一个坐标系,其中NDC x坐标向右上升,NDC y坐标上升。
因此,如果调用glViewport(0, 0, window_width, window_height)
,这也是OpenGL上下文第一次绑定到窗口后的默认值,NDC坐标(-1,-1)将位于窗口的左下角,NDC坐标(1,1)位于窗口的右上角。
OpenGL首先将所有变换设置为identity,这意味着您通过的顶点坐标将直接到达NDC空间,并按如下方式解释。但是,在OpenGL中,大部分时间都是应用于连续的转换:
和
模型视图变换用于在静止的眼睛/相机(始终位于(0,0,0))前面的世界中移动。放置相机只是意味着,添加一个额外的整个世界的变换(视图变换),这与你在世界中放置相机的方式完全相反。固定函数OpenGL将其称为MODELVIEW矩阵,如果矩阵模式已设置为GL_MODELVIEW,则可以访问该函数。
投影变换是一种OpenGL的透镜。您可以使用它来设置它是宽角度还是小角度(在透视的情况下),或者长方体的边缘(正交投影),或者甚至是不同的东西。固定函数OpenGL将其称为投影矩阵,如果矩阵模式已设置为GL_PROJECTION,则可以访问该函数。
在剪切投影基元之后,如果应用了透视投影,则应用所谓的同质分割,这将产生实际的透视效果。
此时,顶点已转换到NDC空间,然后将其映射到视口,如开头所述。
关于您的问题:您需要的是将顶点坐标1:1映射到视口像素的投影。很简单:
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if( origin_lower_left ) {
glOrtho(0, width, height, 0, -1, 1);
} else {
glOrtho(0, width, 0, height, -1, 1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
现在,顶点坐标映射到视口像素。
更新:通过三角形绘制纹理四边形的完整视口:
OpenGL-2.1和OpenGL ES-1
void fullscreenquad(int width, int height, GLuint texture)
{
GLfloat vtcs[] = {
0, 0,
1, 0,
1, 1,
0, 1
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vtcs);
glTexCoordPointer(2, GL_FLOAT, 0, vtcs);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
发布于 2012-02-19 19:57:51
默认情况下,opengl摄影机放置在指向负z轴的原点。在平面附近的相机上投影的就是你屏幕上看到的东西。因此,屏幕的中心对应于(0,0)
根据您想要绘制的内容,您可以选择使用GL_POINT、GL_LINE和GL_TRIANGLE进行绘制。
你可以使用GL_POINTS给屏幕上的一些像素上色,但如果你需要绘制物体/网格,如茶壶,立方体等,那么你应该使用三角形。
发布于 2012-02-19 19:59:45
你需要多读一点,才能看得更清楚。在openGL中,可以指定视口。此视口是您的OpenGL空间视图,因此,如果您将其设置为屏幕中心位于屏幕中央,并且视图从-1延伸到1,则这是您的OpenGL透视全视图。不要把它和Android中的屏幕坐标混在一起(这些坐标的原点在左上角,就像你提到的那样)。您需要在这些坐标之间进行转换(例如,对于touchevents )来匹配另一个坐标系。
https://stackoverflow.com/questions/9348856
复制相似问题