坐标系错误,opengl es系统显示android屏幕

坐标系错误,opengl es系统显示android屏幕,android,opengl-es,coordinates,Android,Opengl Es,Coordinates,我正在尝试使用opengl es坐标系,并将其转换为屏幕坐标系。这将使我能够找到屏幕上的顶点位置,并使碰撞检测更容易。到目前为止,我已经找到了顶点,并将它们乘以模型视图投影矩阵,然后使用android屏幕的高度和宽度(以像素为单位),我已经将顶点转换为正确的范围。我必须转换,因为opengl es坐标系的原点位于屏幕的中心,从-1变为1。当屏幕的原点位于屏幕的左下角时,当设备处于横向模式时,我发现尺寸为800x480像素 问题是,当我看一个顶点在屏幕上的值范围时,它的宽度范围是147-640,高

我正在尝试使用opengl es坐标系,并将其转换为屏幕坐标系。这将使我能够找到屏幕上的顶点位置,并使碰撞检测更容易。到目前为止,我已经找到了顶点,并将它们乘以模型视图投影矩阵,然后使用android屏幕的高度和宽度(以像素为单位),我已经将顶点转换为正确的范围。我必须转换,因为opengl es坐标系的原点位于屏幕的中心,从-1变为1。当屏幕的原点位于屏幕的左下角时,当设备处于横向模式时,我发现尺寸为800x480像素

问题是,当我看一个顶点在屏幕上的值范围时,它的宽度范围是147-640,高度范围是185-480。其宽度范围应为0-800,高度范围应为0-480

我的代码有什么问题?是模型视图投影矩阵,还是我使用了错误的屏幕测量值,或者可能是我从opengl es范围转换到屏幕像素范围的方式

这将找到形状顶点,将其乘以mvp矩阵,并转换值的范围,使其与像素屏幕尺寸一致。我只检查一个形状顶点

        dimension[0] = MyGLSurfaceView.width;
        dimension[1] = MyGLSurfaceView.height;

        float starW;
        float starH;

        for (int i = 0; i < star.vertices.length; i += star.vertices.length) {//only checking one vertex

            Matrix.multiplyMM(starVerts, 0, mMVPMatrix, 0, star.vertices, 0);//vertices multiplied by model view projection matrix

           //starVerts[i] is in the range .433 to -.466 should be 1 to -1
           //starVert[i+1] is in the range .973 to -.246  should be 1 to -1

            starW = (starVerts[i] * (dimension[0] / 2)) + (dimension[0] / 2);//should be range 0-800 // instead 147 - 640
            starH = (starVerts[i + 1] * (dimension[1] / 2)) + (dimension[1] / 2);//should be range 0-480 // instead 185 - 480
这就是我如何找到android屏幕的像素尺寸

Display display = ((WindowManager)
                context.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        height = size.y;
        width = size.x;
自derhass回答后的更新

starVerts[i] = starVerts[i]/starVerts[i+3];    //clip.x divided by clip.w
starVerts[i+1] = starVerts[i+1]/starVerts[i+3];//clip.y divided by clip.w

你错过了关键的一步。将ModelViewProjection矩阵乘以某个向量时,将该向量从对象空间变换到剪辑空间

GL所做的下一步是转换为标准化设备坐标,其中查看体积是所有3维中的单位立方体[-1,1]。要从剪辑空间到标准化设备空间,剪辑空间
x
y
z
值除以剪辑空间
w
值(这最终创建透视效果,变换链中的所有其他操作都是线性的)。这是你忘记的一步

但是,仅添加此选项可能无法完全解决问题(取决于场景)。问题是GL在从剪辑空间到NDC之前会做一些其他的事情:剪辑,即将原语(显然,此操作适用于整个原语,而不是单独的顶点)与查看体积(仅[-
w
w
)相交^3在这一点上,仅此
w
随顶点而变化)


如果您只想处理单点,您可以检查关系-
w
谢谢您的帮助。因此,如果我是对的,我的变量是剪辑空间值“x”、“y”、“z”。你知道如何计算剪辑空间“w”值吗?@toom:我不知道矩阵和向量函数是如何工作的,但一般来说,GL使用4x4矩阵和4d向量,其中最后一个分量是
w
(通常在输入端为1)。剪辑空间
w
自然是4x4矩阵乘以4d向量的结果。通常,透视矩阵只具有设置
w_clip=-z_eye
的效果(投影矩阵的最后一行是(0,0,-1,0))。嘿,兄弟,谢谢你的回答。它帮助我了解了发生的事情,我找到了clip.w。你是指透视矩阵的最后一行吗?嗯,对于透视投影,投影矩阵的最后一行通常是(0,0,-1,0)(或者实际上,在一般情况下,只是图像平面的法线)。
starVerts[i] = starVerts[i]/starVerts[i+3];    //clip.x divided by clip.w
starVerts[i+1] = starVerts[i+1]/starVerts[i+3];//clip.y divided by clip.w