Distortion on reshape.

	
public void reshape( GLAutoDrawable drawable, int x, int y, int width,
			int height )
	{
		gl = drawable.getGL();
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45, ((float)(Config.WINDOW_WIDTH/Config.WINDOW_HEIGHT)), 0, 1000);
	}

When i resize the frame,it still distorts the objects in the viewport,why?
Can some one help?
tia.

two things:

  • the aspect ration should calculate from the actual width and hight arguments, not from a configuration constants
  • if your constants are integers, you are casting too late :wink:

use


public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
    GL gl = drawable.getGL();
    GLU glu = new GLU();

    // avoid a divide by zero error!
    if (height <= 0) height = 1;

    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();

    // don't use 0 as near clipping plane
    glu.gluPerspective(45.0f, (float) width / (float) height, 0.1, 1000.0);
}

Thanks cylab,i tried your code,same problem…

Maybe you aren’t setting the matrix mode to GL_MODELVIEW in your display()-Method. Then you need to switch back to it in reshape:


public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
    GL gl = drawable.getGL();
    GLU glu = new GLU();

    // avoid a divide by zero error!
    if (height <= 0) height = 1;

    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();

    // don't use 0 as near clipping plane
    glu.gluPerspective(45.0f, (float) width / (float) height, 0.1, 1000.0);

    // Switch back to MODELVIEW mode after fiddling with the perspective
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glLoadIdentity();
}

Thanks cylab,but still not works,i am new to opengl,sorry about my stupid question.ok,here is the main code:


	public void init( GLAutoDrawable drawable )
	{
		gl = drawable.getGL();
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glu = new GLU();
		display = FengGUI.createDisplay(new JOGLBinding(canvas));
		new EventBinding(canvas, display);
	}



	public void display( GLAutoDrawable drawable )
	{
		gl.glLoadIdentity();
		if ((drawable instanceof GLJPanel)
				&& !((GLJPanel) drawable).isOpaque()
				&& ((GLJPanel) drawable)
						.shouldPreserveColorBufferIfTranslucent())
		{
			gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
		}
		else
		{
			gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		}
		
		gl.glPushMatrix();
		
		view_scale += (view_scroll_scale - view_scale) * .06;
		gl.glScalef(view_scale, view_scale, view_scale);
		gl.glTranslatef(0.0f, 0.0f, 0.0f);
		gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
		gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
		
                                //
                                FuncOfDrawingThings();
                                //
		
		gl.glPopMatrix();
		
		gl.glFlush();
		
                                //This function is what the FengGUI needs
		display.display();
		
	}



	public void reshape( GLAutoDrawable drawable, int x, int y, int width,
			int height )
	{
		gl = drawable.getGL();
		 if (height <= 0) height = 1;
                                 gl.glViewport(0, 0, width, height);
                                 gl.glMatrixMode(GL.GL_PROJECTION);
                                 gl.glLoadIdentity();
                                 glu.gluPerspective(0.0f, (float) width / (float) height, 0.1, 1000.0);
                                 gl.glMatrixMode(GL.GL_MODELVIEW);
                                 gl.glLoadIdentity();
	}



	public void displayChanged( GLAutoDrawable drawable, boolean modeChanged,
			boolean deviceChanged )
	{
                                 //did nothing
                 }




In “FuncOfDrawingThings” i did something like:


		gl.glColor3f(0.25f, 0.25f, 0.25f);
		gl.glPointSize(1f);
		gl.glBegin(GL.GL_POINTS);
		for (int i = 0; i < mypoints.size(); i++)
		{
		             gl.glVertex3d(x, y, z);
		}
		gl.glEnd();

That’s all.

Can you help me to find out what i missed?

Do you really have


glu.gluPerspective(0.0f, (float) width / (float) height, 0.1, 1000.0);

with 0.0 as FOV parameter? Should be 45 or something.

Other than that, I can’t see any real problem related to reshape. Try to make a minimal self contained test case to reproduce the problem. Post it here to let us try it out.

I made a simple program can explain what i met.


import java.awt.BorderLayout;
import java.awt.Color;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;

import org.fenggui.Display;
import org.fenggui.FengGUI;
import org.fenggui.render.jogl.EventBinding;
import org.fenggui.render.jogl.JOGLBinding;

import com.sun.opengl.util.Animator;

public class DistortionTestFrame extends JFrame implements GLEventListener
{
	
	private static final long serialVersionUID = 1L;
	
	private GL gl = null;
	
	private GLU glu = null;
	
	private GLCanvas canvas = null;
	
	private Display display = null;
	
	public void display( GLAutoDrawable drawable )
	{
		gl = drawable.getGL();
		gl.glLoadIdentity();
		if ((drawable instanceof GLJPanel)
				&& !((GLJPanel) drawable).isOpaque()
				&& ((GLJPanel) drawable)
						.shouldPreserveColorBufferIfTranslucent())
		{
			gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
		}
		else
		{
			gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		}
		//
		gl.glPushMatrix();
		
		gl.glColor3f(1.0f, 1.0f, 1.0f);
        gl.glBegin(GL.GL_QUADS);
        gl.glVertex3f(-0.1f, 0.1f, 0.1f);
        gl.glVertex3f(0.1f, 0.1f, 0.1f);
        gl.glVertex3f(0.1f, -0.1f, 0.1f);
        gl.glVertex3f(-0.1f, -0.1f, 0.1f);
        gl.glEnd();	
        
		gl.glPopMatrix();
		
		//
		display.display();
	}
	
	public void displayChanged( GLAutoDrawable drawable, boolean modeChanged,
			boolean deviceChanged )
	{}
	
	public void init( GLAutoDrawable drawable )
	{
		gl = drawable.getGL();
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glu = new GLU();
		display = FengGUI.createDisplay(new JOGLBinding(canvas));
		new EventBinding(canvas, display);
	}
	
	public void reshape( GLAutoDrawable drawable, int x, int y, int width,
			int height )
	{
		
		gl = drawable.getGL();
		if (height <= 0)
			height = 1;
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluPerspective(0.0f, (float) width / (float) height, 1.0, 1000.0);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		
	}

	
	public DistortionTestFrame()
	{
		
		setTitle("DistortionTestFrame");
		setSize(800, 600);
		setBackground(Color.BLACK);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//
		canvas = new GLCanvas();
		canvas.setBackground(Color.BLACK);
		canvas.addGLEventListener(this);
		getContentPane().add(canvas, BorderLayout.CENTER);
		
		Animator animator = new Animator(canvas);
		animator.start();
		
		setVisible(true);
		
	}
	
	public static void main( String[] args )
	{
		new DistortionTestFrame();
	}
	
}


How to keep the square when resize frame?

Still the 0.0 in gluPerspective is wrong. Try 45.0.

I am currently at work, so I can’t try it out. I will do this evening (would be 9 o’clock in the morning for you, if your timezone is set up correctly in the forum ;))

Thanks cylab.
“fovy
Specifies the field of view angle, in degrees, in the y direction.”
is that right? so i think i can see the square whatever the angle is.but the wired thing is when i set the fovy to 45.0f ,i can see nothing in the viewport.if i set the angle to 0 ,i can see the square but not in right shape.resize the window it changes with the frame ratio…

Your quad may simple be too small or wrongly positioned (clipped by near clipping plane) and the fov of 0 might lead to some calculation error that results in your distorted display. Try 45.0 as fov and replace


        gl.glBegin(GL.GL_QUADS);
        gl.glVertex3f(-0.1f, 0.1f, 0.1f);
        gl.glVertex3f(0.1f, 0.1f, 0.1f);
        gl.glVertex3f(0.1f, -0.1f, 0.1f);
        gl.glVertex3f(-0.1f, -0.1f, 0.1f);
        gl.glEnd();

with


        // Move the "drawing cursor" to another position
        gl.glTranslatef(0.0f, 0.0f, -3.0f);

        gl.glBegin(GL.GL_QUADS);
        gl.glVertex3f(-1f,  1f, 0f);
        gl.glVertex3f( 1f,  1f, 0f);
        gl.glVertex3f( 1f, -1f, 0f);
        gl.glVertex3f(-1f, -1f, 0f);
        gl.glEnd();

Edit: wrong glTranslate values

still not works :’(

FOV = 0

http://undefined.cn/fov0_1.jpg

after resize window

http://undefined.cn/fov0_2.jpg

FOV = 45 see nothing.

http://undefined.cn/fov45.jpg

Repost your complete current code and I’ll test it this evening.


import java.awt.BorderLayout;
import java.awt.Color;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;

import org.fenggui.Display;
import org.fenggui.FengGUI;
import org.fenggui.render.jogl.EventBinding;
import org.fenggui.render.jogl.JOGLBinding;

import com.sun.opengl.util.Animator;

public class DistortionTestFrame extends JFrame implements GLEventListener
{
	
	private static final long serialVersionUID = 1L;
	
	private GL gl = null;
	
	private GLU glu = null;
	
	private GLCanvas canvas = null;
	
	private Display display = null;
	
	public void display( GLAutoDrawable drawable )
	{
		gl = drawable.getGL();
		gl.glLoadIdentity();
		if ((drawable instanceof GLJPanel)
				&& !((GLJPanel) drawable).isOpaque()
				&& ((GLJPanel) drawable)
						.shouldPreserveColorBufferIfTranslucent())
		{
			gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
		}
		else
		{
			gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		}
		//
		gl.glPushMatrix();
		
		gl.glColor3f(1.0f, 1.0f, 1.0f);
        
		gl.glTranslatef(0.1f, 0.1f, 0.1f);
                                gl.glBegin(GL.GL_QUADS);
                                gl.glVertex3f(-0.1f,  0.1f, 0f);
                                gl.glVertex3f( 0.1f,  0.1f, 0f);
                                gl.glVertex3f( 0.1f, -0.1f, 0f);
                                gl.glVertex3f(-0.1f, -0.1f, 0f);
                                gl.glEnd();
        
		gl.glPopMatrix();
		
		gl.glLoadIdentity();
		//
		display.display();
	}
	
	public void displayChanged( GLAutoDrawable drawable, boolean modeChanged,
			boolean deviceChanged )
	{}
	
	public void init( GLAutoDrawable drawable )
	{
		gl = drawable.getGL();
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glu = new GLU();
		display = FengGUI.createDisplay(new JOGLBinding(canvas));
		new EventBinding(canvas, display);
	}
	
	public void reshape( GLAutoDrawable drawable, int x, int y, int width,
			int height )
	{
		
		gl = drawable.getGL();
		if (height <= 0)
			height = 1;
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluPerspective(0.0f, (float) width / (float) height, 1.0, 1000.0);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		
	}

	
	public DistortionTestFrame()
	{
		
		setTitle("DistortionTestFrame");
		setSize(800, 600);
		setBackground(Color.BLACK);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//
		canvas = new GLCanvas();
		canvas.setBackground(Color.BLACK);
		canvas.addGLEventListener(this);
		getContentPane().add(canvas, BorderLayout.CENTER);
		
		Animator animator = new Animator(canvas);
		animator.start();
		
		setVisible(true);
		
	}
	
	public static void main( String[] args )
	{
		new DistortionTestFrame();
	}
	
}


You didn’t follow cylab’s advice all the way. There was a glTranslatef() call before drawing anything to adjust the camera’s “position”. If you do this, and change the fov to 60 or some other number, then the square appears and isn’t distorted when resizing the frame.

Indeed. ::slight_smile:

Thank you very much cylab and lhkbob.Now i see the rect.I did what cylab told me,i think the reason is i don’t know OPENGL.Whatever thank you, i learned a lot.

something i still can’t understand:

CODE 1:


gl.glTranslatef(0.0f, 0.0f, -3.0f);
gl.glPushMatrix();
gl.glBegin(GL.GL_QUADS);
gl.glVertex3f(-1f,  1f, -1f);
gl.glVertex3f( 1f,  1f, -1f);
gl.glVertex3f( 1f, -1f, -1f);
gl.glVertex3f(-1f, -1f, -1f);
gl.glEnd();
gl.glPopMatrix();

CODE 2:


gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, -3.0f);
gl.glBegin(GL.GL_QUADS);
gl.glVertex3f(-1f,  1f, -1f);
gl.glVertex3f( 1f,  1f, -1f);
gl.glVertex3f( 1f, -1f, -1f);
gl.glVertex3f(-1f, -1f, -1f);
gl.glEnd();
gl.glPopMatrix();

CODE 3:


gl.glPushMatrix();
gl.glBegin(GL.GL_QUADS);
gl.glVertex3f(-1f,  1f, -1f);
gl.glVertex3f( 1f,  1f, -1f);
gl.glVertex3f( 1f, -1f, -1f);
gl.glVertex3f(-1f, -1f, -1f);
gl.glEnd();
gl.glPopMatrix();
gl.glTranslatef(0.0f, 0.0f, -3.0f);

CODE 1 and CODE 2 have the same result,CODE 3 doesn’t.
What i think is glTranslatef move current coordinate ZERO to where i specified,and glPushMatrix,glPopMatrix is a way to save current coordinate.
Why CODE 3 not works?(i know it must be another stupid question…)

glTranslate() changes the current matrix used to transform the geometry sent to opengl.

Think about it like this: there is a virtual “drawing pen” that draws your quads and triangles. Everytime you call glTranslate, this “pen” is moved to a new position. So if you call glTranslate after your drawing (like in code 3), the QUAD is first drawed relative to the origin (0,0,0) which might be too near and remoced by the near clipping plane (as set up with gluPerspective). After that the “pen” in code 3 is moved to (0,0,-3), which has no effect, since you don’t draw anything afterwards.

The difference between code 1 and code 2 is not in drawing but in the matrix stack management. With glPushMatrix you copy the current “pen” position (and other transformations like rotate/skew) to a stack for later retrieval. Since the current matrix is only saved and not changed, you don’t see any difference between code 1 and code 2 regarding your quad. But there is an important difference: the call to glPopMatrix results in different “pen” positions since it retrieves the last pushed matrix from the stack and this way restores the “pen” position to the state before glPushMatrix. In code 1 your drawing pen will be positioned at 0,0,-3, which might cause FenGUI to appear at the wrong place.

Take a look at the NEHE tutorials (http://nehe.gamedev.net/). Allthough they are in c++, they cover the basic principles of OpenGL quite good (even if a bit outdated).