opengl规范化设备坐标大于1

时间:2014-09-03 01:52:07

标签: opengl jogl projection

我目前正在编写JAVA中的菜单系统,需要将世界坐标转换为屏幕坐标。我已经阅读了很多关于如何做的帖子,并建立了以下内容:

    float[] v = new float[]{0,0,0,1}; //four vector location of object in object space


    //multiply by model matrix

    v[0] = model[0]*v[0] + model[4]*v[1] + model[8]*v[2] + model[12]*v[3];
    v[1] = model[1]*v[0] + model[5]*v[1] + model[9]*v[2] + model[13]*v[3];
    v[2] = model[2]*v[0] + model[6]*v[1] + model[10]*v[2] + model[14]*v[3];
    v[3] = model[3]*v[0] + model[7]*v[1] + model[11]*v[2] + model[15]*v[3];

    //multiply by projection matrix

    v[0] = projection[0]*v[0] + projection[4]*v[1] + projection[8]*v[2] + projection[12]*v[3];
    v[1] = projection[1]*v[0] + projection[5]*v[1] + projection[9]*v[2] + projection[13]*v[3];
    v[2] = projection[2]*v[0] + projection[6]*v[1] + projection[10]*v[2] + projection[14]*v[3];
    v[3] = projection[3]*v[0] + projection[7]*v[1] + projection[11]*v[2] + projection[15]*v[3];

    //account for distortions
    v[0] = v[0]/v[3];
    v[1] = v[1]/v[3];
    v[2] = v[2]/v[3];
    v[3] = v[3]/v[3];   

    //transform to screen coords.
    onScreenX = (int)((viewport[2] * (v[0] + 1.0f)) / 2.0f) + viewport[0];
    onScreenY = (int)((viewport[3] * (v[1] + 1.0f)) / 2.0f) + viewport[1];

    System.out.println(onScreenX + ", " + onScreenY);

现在我遇到的一个大问题是,在我进行透视分割之后,我的值应该在-1和1之间。但是,即使对象明显在屏幕上,我也会得到一些超出此范围的值。我不确定我在这里可以找到什么。

我已经知道函数gluProject()但是这个计算远离我的glu对象所在的位置,因此该函数没有用。必须用矩阵数学来完成。

1 个答案:

答案 0 :(得分:1)

这些计算用新的值覆盖v向量中的值,然后在仍应使用旧值的地方使用它们。

只看前两个作业:

v[0] = model[0]*v[0] + model[4]*v[1] + model[8]*v[2] + model[12]*v[3];
v[1] = model[1]*v[0] + model[5]*v[1] + model[9]*v[2] + model[13]*v[3];

第一个语句为v[0]分配一个新值,然后在第二个语句的右侧使用它。因此,对于v[1]的计算,v[0]的新值与v[1]v[2]v[3]的旧值一起使用。

在整个计算过程中,同样的模式仍在继续。

避免这种情况的最简单方法是为计算的每个步骤使用新的向量。例如:

float[] vModel = new float[4];
vModel[0] = model[0]*v[0] + model[4]*v[1] + model[8]*v[2] + model[12]*v[3];
vModel[1] = model[1]*v[0] + model[5]*v[1] + model[9]*v[2] + model[13]*v[3];
...

float[] vProj = new float[4];
vProj[0] = projection[0]*vModel[0] + ...
...

这可以避免在旧值仍在使用时用新值覆盖值。