简体   繁体   中英

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.

Picture of y axis distortion

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. This is the link: Link

I believe it has something to do with gluPerspective, or glFrustrum but I can not figure out what. Here are the vital methods to drawing the 3D shapes:

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:

//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. Any help would be greatly appreciated.

Thank you for your time

You call toRadians on values which aren't angles:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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