Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.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中的OpenGL,gluLookAt矩阵的手动创建_Java_Opengl Es_Glulookat - Fatal编程技术网

Java中的OpenGL,gluLookAt矩阵的手动创建

Java中的OpenGL,gluLookAt矩阵的手动创建,java,opengl-es,glulookat,Java,Opengl Es,Glulookat,我一直在尝试使用矩阵操作,而不是使用OpenGL ES和ulti库附带的基于euler或四元数的函数 我可以让大多数东西正常工作,但是我不能完全正确地重新创建gluLookAt函数,正如您可以从下面的屏幕截图中看到的: 正确的gluLookAt版本 被破坏的矩阵版本 请注意,屏幕截图只是实际屏幕的一部分。在两幅图像中看到的按钮都是使用二维正交法完成的重叠,它们有助于显示差异,因为它们在两幅图像中位于同一位置 我从这里获取了我的信息: 我在下面的java代码中重新创建了它,省略了一些细节: cl

我一直在尝试使用矩阵操作,而不是使用OpenGL ES和ulti库附带的基于euler或四元数的函数

我可以让大多数东西正常工作,但是我不能完全正确地重新创建gluLookAt函数,正如您可以从下面的屏幕截图中看到的:

正确的gluLookAt版本

被破坏的矩阵版本

请注意,屏幕截图只是实际屏幕的一部分。在两幅图像中看到的按钮都是使用二维正交法完成的重叠,它们有助于显示差异,因为它们在两幅图像中位于同一位置

我从这里获取了我的信息:

我在下面的java代码中重新创建了它,省略了一些细节:

class point3D {
    public double mX, mY, mZ;
}

double scaler(point3D pt){
    return Math.pow(
        Math.pow(pt.mX, 2.0) + Math.pow(pt.mY, 2.0) + Math.pow(pt.mZ, 2.0),
        1.0/3.0
    );
}

void cross(point3D A, point3D B, point3D output){
    output.mX = (A.mY*B.mZ) - (A.mZ*B.mY);
    output.mY = (A.mZ*B.mX) - (A.mX*B.mZ);
    output.mZ = (A.mX*B.mY) - (A.mY*B.mX);
}

void normalise(point3D normMe, point3D output){
    double s = scaler(normMe);
    output.mX = normMe.mX / s;
    output.mY = normMe.mY / s;
    output.mZ = normMe.mZ / s;
}

float mx, my, mz, mfx, mfy, mfz;
private FloatBuffer mLookatMx; //- All setup and stuff elsewhere

void myLookAt(){
    point3D ptTmpA, ptTmpB, ptTmpC, ptTmpD;

    //- 'forward' F part
    ptTmpA.mX = mfx - mx;
    ptTmpA.mY = mfy - my;
    ptTmpA.mZ = mfz - mz;
    normalise(ptTmpA, ptTmpA);

    //- 'up' part
    ptTmpB.mX = 0;
    ptTmpB.mY = 1.0;
    ptTmpB.mZ = 0;

    cross(ptTmpB, ptTmpA, ptTmpC);  //- S
    normalise(ptTmpC, ptTmpC);

    cross(ptTmpA, ptTmpC, ptTmpD);  //- U
    normalise(ptTmpD, ptTmpD);

    //- the 4x4 matrix. Not including the transformation this time for simplicity.
    //- m = {
    //-        s1,  s2,  s3, -x
    //-        u1,  u2,  u3, -y
    //-       -f1, -f2, -f3, -z
    //-         0,   0,   0,  1
    //- }

    //- 0
    mLookatMx.put((float)ptTmpC.mX);            
    mLookatMx.put((float)ptTmpC.mY);            
    mLookatMx.put((float)ptTmpC.mZ);            
    mLookatMx.put(0);

    //- 4
    mLookatMx.put((float)ptTmpD.mX);            
    mLookatMx.put((float)ptTmpD.mY);            
    mLookatMx.put((float)ptTmpD.mZ);            
    mLookatMx.put(0);

    //- 12
    mLookatMx.put((float)ptTmpA.mX *-1.0f); 
    mLookatMx.put((float)ptTmpA.mY *-1.0f); 
    mLookatMx.put((float)ptTmpA.mZ *-1.0f); 
    mLookatMx.put(0);

    //- 16
    mLookatMx.put(0);                           
    mLookatMx.put(0);                           
    mLookatMx.put(0);                           
    mLookatMx.put(1.0f);
    mLookatMx.position(0);
}

void myDraw(){
    glDisable(GL_DEPTH_BITS);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(mGL, 90.0, mScreen.mX / mScreen.mY, 0.01, 10.0);

    //- This works
    //gluLookAt(mGL, 
    //    mx, my, mz, 
    //    mfx, mfy, mfz,
    //    0.0f, 1.0f, 0.0f
    //);

    //- This is distorted
    glMultMatrixf(mLookatMx);
    glTranslatef(mx * -1.0f, my * -1.0f, mz * -1.0f)

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //- draw models as seen in screen shot
}

OpenGL使用列主矩阵。您似乎正在逐行填充矩阵,这实际上在Direct3D行中有效,仅供参考

最简单的解决方案是调用mLookatMx.transpose。。。如果您使用的是适当的矩阵类;这将为您翻转行和列

但是,由于您使用的是一个普通的旧FloatBuffer,因此需要将。。。矩阵的内容一次只显示一列,而不是一次显示一行


顺便说一下,OpenGL的核心总是使用矩阵进行转换。那些Euler角度和四元数辅助工具工具实际上只是为OpenGL创建变换矩阵。您可以在顶点着色器中实现非基于矩阵的变换,但这比您现在想象的更高级:

谢谢您的回复。我尝试了转置,但它仍然扭曲,但这次不是以错误的方式缩放,而是以一种非常有趣的方式拉伸。