Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用二维HUD图标在三维环境中跟踪对象_Java_Opengl_Vector_Jogl_Hud - Fatal编程技术网

Java 使用二维HUD图标在三维环境中跟踪对象

Java 使用二维HUD图标在三维环境中跟踪对象,java,opengl,vector,jogl,hud,Java,Opengl,Vector,Jogl,Hud,我试图有一个2D HUD,其中有图标,跟踪3D环境中HUD后面3D对象在屏幕上的位置 推理:有时你看不到3D对象(太远或离屏幕太远),但你仍然想知道它在哪里 问题:3D场景使用透视矩阵进行变换,赋予其深度(z轴),HUD严格为2D(xy平面)。由于深度的原因,2D HUD无法正确跟踪距离较远/较近的对象 我想要的:一种获取二维向量[(x,y)pos]的方法,用于放置图标,使其位于背景中三维对象的中心位置 xy平面(z=0)中所有对象的示例: // Function call in the Ope

我试图有一个2D HUD,其中有图标,跟踪3D环境中HUD后面3D对象在屏幕上的位置

推理:有时你看不到3D对象(太远或离屏幕太远),但你仍然想知道它在哪里

问题:3D场景使用透视矩阵进行变换,赋予其深度(z轴),HUD严格为2D(xy平面)。由于深度的原因,2D HUD无法正确跟踪距离较远/较近的对象

我想要的:一种获取二维向量[(x,y)pos]的方法,用于放置图标,使其位于背景中三维对象的中心位置

xy平面(z=0)中所有对象的示例:

// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );

// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
    float asp = w/h;
    float fov_cos = (float) Math.cos( fov / 2.0d );
    float fov_sin = (float) Math.sin( fov / 2.0d );
    float fov_cot = fov_cos/fov_sin;
    float a_0  = fov_cot/asp;
    float a_3  = (far + near)/(near-far);
    float a_43 = (2.0f * far * near)/(near-far);
    float[] an = {
            a_0,  0.0f,    0.0f, 0.0f,
            0.0f, fov_cot, 0.0f, 0.0f,
            0.0f, 0.0f,    a_3,  -1.0f,
            0.0f, 0.0f,    a_43, 0.0f,
    };
    return new FloatMatrix( an, 4, 4 );

}
您可以看到,随着对象离中心越来越远,图标(白色的圆圈)越来越偏离中心。

深度增加的对象示例(离中心越远==越深):

// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );

// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
    float asp = w/h;
    float fov_cos = (float) Math.cos( fov / 2.0d );
    float fov_sin = (float) Math.sin( fov / 2.0d );
    float fov_cot = fov_cos/fov_sin;
    float a_0  = fov_cot/asp;
    float a_3  = (far + near)/(near-far);
    float a_43 = (2.0f * far * near)/(near-far);
    float[] an = {
            a_0,  0.0f,    0.0f, 0.0f,
            0.0f, fov_cot, 0.0f, 0.0f,
            0.0f, 0.0f,    a_3,  -1.0f,
            0.0f, 0.0f,    a_43, 0.0f,
    };
    return new FloatMatrix( an, 4, 4 );

}
可以看到,HUD认为三维对象仍然在同一平面上。

伪代码:

// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );

// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
    float asp = w/h;
    float fov_cos = (float) Math.cos( fov / 2.0d );
    float fov_sin = (float) Math.sin( fov / 2.0d );
    float fov_cot = fov_cos/fov_sin;
    float a_0  = fov_cot/asp;
    float a_3  = (far + near)/(near-far);
    float a_43 = (2.0f * far * near)/(near-far);
    float[] an = {
            a_0,  0.0f,    0.0f, 0.0f,
            0.0f, fov_cot, 0.0f, 0.0f,
            0.0f, 0.0f,    a_3,  -1.0f,
            0.0f, 0.0f,    a_43, 0.0f,
    };
    return new FloatMatrix( an, 4, 4 );

}
.getPos()获取向量(x,y,z)

我的透视矩阵:

// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );

// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
    float asp = w/h;
    float fov_cos = (float) Math.cos( fov / 2.0d );
    float fov_sin = (float) Math.sin( fov / 2.0d );
    float fov_cot = fov_cos/fov_sin;
    float a_0  = fov_cot/asp;
    float a_3  = (far + near)/(near-far);
    float a_43 = (2.0f * far * near)/(near-far);
    float[] an = {
            a_0,  0.0f,    0.0f, 0.0f,
            0.0f, fov_cot, 0.0f, 0.0f,
            0.0f, 0.0f,    a_3,  -1.0f,
            0.0f, 0.0f,    a_43, 0.0f,
    };
    return new FloatMatrix( an, 4, 4 );

}

这很简单。你可以用。它将采用给定的模型视图、投影和视口变换,以及一个三维点,并应用反转,在窗口坐标中为您吐出一个二维点(对于小的输入错误,我深表歉意,只需在此处键入此项):

完成此操作后,将在二维窗口坐标中创建三维点。然后简单地将投影切换到二维正交投影,以窗口像素为单位,并在二维空间中绘制HUD


对于性能,如果每帧要绘制多个HUD项目;只需每帧获取一次modelview/projection/viewport(或者,更好的是,如果您更改缓存并仅在需要时重新查询它们,则使其无效),并在后续调用
gluProject
时重用它们

@MichaelMitchell如果你想了解数学,请查看官方文件,其中底部显示了使用的矩阵方程。对于一个非常深入的描述,将给你一个完整的理解所涉及的数学加上一些,检查。这个链接显示了OpenGL从3D位置到最终渲染窗口坐标的所有步骤。哇!谢谢你的链接!