有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从OpenGLES开始。使用像素绘制

我开始学习使用java在安卓中使用OpenGL(GL10),并按照一些教程绘制正方形、三角形等

现在我开始画一些我的想法,但我真的很困惑于绘制屏幕的顶点。当我使用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?

真的谢谢你,也很抱歉我的英语不好。谢谢


共 (3) 个答案

  1. # 1 楼答案

    Why is this fullscreen? Isn't the center of OpenGL coordinates at top left (0, 0)? Why with that vertexs the draw is correct? It seems that the center is really the real center of the screen and the width and height is from -1...1, but I dont really understand it because I thought that the center was at the top left...

    这里有三件事。所谓的视口,所谓的标准化设备坐标(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中,大多数情况下,您都会应用于连续的转换:

    • modelview

    • 投影

    modelview变换用于在静止的眼睛/相机(始终位于(0,0,0))前面环游世界。放置相机只是意味着,添加整个世界的附加变换(视图变换),这与将相机放置在世界中的方式完全相反固定函数OpenGL将其称为模型视图矩阵,如果矩阵模式已设置为GL\u模型视图,则可访问

    投影变换是OpenGL的一种镜头。您可以使用它来设置它是宽角度还是小角度(在透视的情况下)或长方体的边缘(正交投影),甚至是不同的东西固定函数OpenGL将其称为投影矩阵,如果矩阵模式已设置为GL_投影,则可访问

    在投影原语被剪裁之后,然后应用所谓的同质分割,如果应用了透视投影,这将创建实际的透视效果

    此时,顶点已转换为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);
    }
    
  2. # 2 楼答案

    默认情况下,opengl相机位于指向负z轴的原点。 在飞机附近的摄像机上投射的东西就是你在屏幕上看到的东西。 因此,屏幕的中心对应于(0,0)

    根据您想要绘制的内容,您可以选择使用GL_点、GL_线和GL_三角形进行绘制

    你可以使用GL_点给屏幕上的一些像素上色,但如果你需要绘制对象/网格,比如茶壶、立方体等,你应该选择三角形

  3. # 3 楼答案

    你需要多读一点才能把事情弄清楚。在openGL中,可以指定视口。这个视口是OpenGL空间的视图,所以如果你设置它,使屏幕的中心位于屏幕的中间,并且视图从-1扩展到1,那么这就是OpenGL预览的完整视图。不要将其与Android中的屏幕坐标混合(这些坐标的原点如您所述位于左上角)。您需要在这些坐标之间进行平移(例如,对于touchevents),以匹配其他坐标系