简体   繁体   English

沿 y 轴的 OpenGL 透视扭曲场景比预期的要多得多

[英]OpenGL perspective distorting scene much more than expected along y axis

Hey I am beginning to work with JOGL, and everything is working out except, when utilizing a FloatBuffer matrix, my creations are being distorted along the y axis.嘿,我开始使用 JOGL,一切都在解决,除了在使用 FloatBuffer 矩阵时,我的创作沿 y 轴扭曲。

Picture of y axis distortion y 轴畸变图片

It is supposed to look like the following picture, but currently I can not make it do so while still bein allowed to move.它应该看起来像下图,但目前我无法在仍然允许移动的情况下做到这一点。

Picture of what it should look like它应该是什么样子的图片

I saw that a few years ago, someone had this question (but about the z axis) but I was unable to use the corrections they gave to fix my problem.几年前我看到有人有这个问题(但关于 z 轴),但我无法使用他们提供的更正来解决我的问题。 This is the link: Link这是链接: 链接

I believe it has something to do with gluPerspective, or glFrustrum but I can not figure out what.我相信它与 gluPerspective 或 glFrustrum 有关,但我不知道是什么。 Here are the vital methods to drawing the 3D shapes:以下是绘制 3D 形状的重要方法:

public static void main(String[]args)
{       
    Frame frame = new Frame("JOGL Events");
    Toolkit t=Toolkit.getDefaultToolkit();
    Image img=new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
    Cursor pointer=t.createCustomCursor(img, new Point(0,0), "none");
    Driver m=new Driver();
    GLCanvas canvas = new GLCanvas();
    canvas.addGLEventListener(m);
    canvas.addKeyListener(m);
    canvas.addMouseListener(m);
    canvas.setFocusable(true);
    canvas.requestFocus();

    frame.add(canvas);
    frame.setUndecorated(true);
    frame.setSize(1024, 768);
    frame.setLocationRelativeTo(null);
    frame.setCursor(pointer);
    frame.setVisible(true);
    GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
    if(fullscreen){
        ge.getDefaultScreenDevice().setFullScreenWindow(frame);
    }
    final Animator animator = new Animator(canvas);
    animator.setRunAsFastAsPossible(true);
    animator.start();
    Rectangle r=frame.getBounds();
    center=new Point(r.x+r.width/2, r.y+r.height/2);
}

public void init(GLAutoDrawable drawable) {
    final GL2 gl = drawable.getGL().getGL2();
    gl.glShadeModel( GL2.GL_SMOOTH );
    gl.glClearColor( 0f, 0f, 0f, 0f );
    gl.glClearDepth( 1.0f );
    gl.glEnable( GL2.GL_DEPTH_TEST );
    gl.glDepthFunc( GL2.GL_LEQUAL );
    gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
    gh=new GameHandler(gl);
    gh.setMouseCenter(center);
}

public void dispose(GLAutoDrawable drawable) {

}

public void display(GLAutoDrawable drawable) {
    final GL2 gl = drawable.getGL().getGL2(); 
    gl.glShadeModel( GL2.GL_SMOOTH );
    gl.glClearColor( 0f, 0f, 0f, 0f );
    gl.glClearDepth( 1.0f );
    gl.glEnable( GL2.GL_DEPTH_TEST );
    gl.glDepthFunc( GL2.GL_LEQUAL );
    gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
    //gl.glColor3f(1f,0f,0f);
    gl.glClear (GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );      
    // Clear The Screen And The Depth Buffer 
    gl.glLoadIdentity();

    //gl.glTranslatef( -0.0f, 0.0f, -6f );  // Move the triangle  
    //gl.glRotatef( rotZ+0f, rotX+.5f, rotY+1f, rotX+1.0f ); 


    //gl.glFrustumf(left, right, bottom, top, zNear, zFar);

    gh.run();
    gl.glFlush();
}

public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

    final GL2 gl = drawable.getGL().getGL2(); 
    if(height <=0) 
    height =1; 
    final float h = ( float ) width / ( float ) height; 
    gl.glViewport( 0, 0, width, height ); 
    gl.glMatrixMode( GL2.GL_PROJECTION ); 
    gl.glLoadIdentity(); 
    glu.gluPerspective( 45.0f, h, 0.01f, 50.0f); 
    glu.gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);
    gl.glMatrixMode( GL2.GL_MODELVIEW ); 
    gl.glLoadIdentity();
        gl.glLoadIdentity();
    center=new Point(x+width/2, y+height/2);
    gh.setMouseCenter(center);
}

From there, it calls the GameHandler Class which uses the following code to determine which directions to move, then calls the cube class to draw the background, and then calls the player class in order to draw the matrix:从那里,它调用 GameHandler 类,该类使用以下代码来确定要移动的方向,然后调用立方体类来绘制背景,然后调用玩家类以绘制矩阵:

//in GameHandler
public void checkEvents()
{
    long now=System.nanoTime();
    float period=(float)((now-lastTime)*0.000005);
    lastTime=now;

    dx=MouseInfo.getPointerInfo().getLocation().x;
    dy=MouseInfo.getPointerInfo().getLocation().y;
    float head=(mouseCenter.x-dx)/3;
    float pit=(mouseCenter.y-dy)/3;

    if(head!=0) 
        player.setHeading(head*headSens);
    if(pit!=0) 
        player.setPitch(pit*pitchSens);
    if(ford) 
        player.setFord((float)period);
    if(back) 
        player.setBack((float)period);
    if(strafel) 
        player.setStrafel((float)period);
    if(strafer) 
        player.setStrafer((float)period);
    if(jump)
        player.jump("up");
    if(down)
        player.jump("down");
    player.set();

}

public void run()
{
    checkEvents();
    if(robot!=null)
        robot.mouseMove(mouseCenter.x, mouseCenter.y);
    player.draw(gl);
    for(Cube c:getCubes())
        c.draw(gl);

}
//in cube
public void draw(GL2 gl)
{
    gl.glBegin(GL2.GL_QUADS);
     gl.glColor3f(1f,0f,0f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);

     gl.glColor3f(0f,1f,0f);
     gl.glVertex3f(x+-.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);

     gl.glColor3f(1f,0f,0f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+-.5f,y+.5f, z+.5f);


     gl.glColor3f(0f,0f,1f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);

     gl.glColor3f(1f,0f,1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);

     gl.glColor3f(1f,.5f,1f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);

     gl.glEnd();



     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+-.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+-.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+-.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+-.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+-.5f, y+.5f, z+.5f);
     gl.glEnd();

     gl.glBegin(GL2.GL_LINES);
     gl.glColor3f(1f, 1f, 1f);
     gl.glVertex3f(x+.5f, y+.5f, z+-.5f);
     gl.glVertex3f(x+.5f, y+.5f, z+.5f);
     gl.glEnd();
}
//player class
public class Player {

private static final float _90=(float)Math.toRadians(90);
private static final float _maxPitch=(float)Math.toRadians(90);
private float heading=0.0f;
private float pitch=0.0f;
private float cosa, cosb, cosz, sina, sinb, sinz;
private float cosc=1.0f;
private float sinc=0.0f;
private float x,y,z;
private float[] mat={ 1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,1};
private FloatBuffer matrix;

public Player()
{
    matrix=Buffers.newDirectFloatBuffer(mat.length);
    matrix.put(mat);
    x=y=z=0;
}

public void setHeading(float amount){
    heading-=amount;
    cosb=(float)Math.toRadians(Math.cos(heading));
    sinb=(float)Math.toRadians(Math.sin(heading));
    cosz=(float)Math.toRadians(Math.cos(heading+_90));
    sinz=(float)Math.toRadians(Math.sin(heading+_90));
}

public void setPitch(float amount){
    pitch-=amount;
    if(pitch>_maxPitch)pitch=_maxPitch;
    if(pitch<-_maxPitch)pitch=-_maxPitch;
    cosa=(float)Math.cos(pitch);
    sina=(float)Math.sin(pitch);
}

public void setFord(float amount){
    x+=cosz*cosa*amount*2;
    z+=sinz*cosa*amount*2;
    y+=Math.toRadians(sina)*2;

}

public void setBack(float amount){
    x-=cosz*cosa*amount*2;
    z-=sinz*cosa*amount*2;
    y-=Math.toRadians(sina)*2;
}

public void setStrafel(float amount){
    x+=cosb*amount*2;
    z+=sinb*amount*2;
}

public void setStrafer(float amount){
    x-=cosb*amount*2;
    z-=sinb*amount*2;
}

public void set(){
    matrix.put(0, cosc*cosb-sinc*sina*sinb);
    matrix.put(1, sinc*cosb+cosc*sina*sinb);
    matrix.put(2, -cosa*sinb);
    matrix.put(4, -sinc*cosa);
    matrix.put(5, cosc*cosa);
    matrix.put(6, sina);
    matrix.put(8, cosc*sinb+sinc*sina*cosb);
    matrix.put(9, sinc*sinb-cosc*sina*cosb);
    matrix.put(10, cosa*cosb);
    matrix.put(12, matrix.get(0)*x+matrix.get(4)*y+matrix.get(8)*z);
    matrix.put(13, matrix.get(1)*x+matrix.get(5)*y+matrix.get(9)*z);
    matrix.put(14, matrix.get(2)*x+matrix.get(6)*y+matrix.get(10)*z);
}

public void jump(String dir)
{
    if(dir.equals("up"))
        y-=.03;
    else if(dir.equals("down"))
        y+=.03;
}

public void draw(GL2 gl){
    gl.glLoadIdentity();
    gl.glBegin(gl.GL_QUADS);
    gl.glColor3f(5.0f, 0.0f, 3.0f);
    gl.glVertex3f(1.0f, 1.0f, 0.0f);
    gl.glVertex3f(2.0f, 1.0f, 0.0f);
    gl.glVertex3f(2.0f, 1.0f, -5.0f);
    gl.glVertex3f(1.0f, 1.0f, -5.0f);
    gl.glEnd();
    matrix.rewind();
    gl.glLoadMatrixf(matrix);
}

} }

To be clear as possible, my question is what should I add/delete in order to not have the distortion along the yAxis.为了尽可能清楚,我的问题是我应该添加/删除什么才能不沿 yAxis 产生失真。 Any help would be greatly appreciated.任何帮助将不胜感激。

Thank you for your time感谢您的时间

You call toRadians on values which aren't angles:您在不是角度的值上调用toRadians

cosb=(float)Math.toRadians(Math.cos(heading));
sinb=(float)Math.toRadians(Math.sin(heading));
cosz=(float)Math.toRadians(Math.cos(heading+_90));
sinz=(float)Math.toRadians(Math.sin(heading+_90));

That's nonsense.那是胡说八道。 Because you do it only sometimes, it's probably causing the distortion.因为你只是偶尔这样做,它可能会导致失真。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM