matrix stack problems?

I’m only drawing a single object in my model and trying to rotate it. I clear the screen, set gluLookAt(view), call glMultMatrix on my arcball tranform(model), and draw it. AFAIK, this is as simple as it can get.

I call glOrtho() (my projection transform) after the model/view transforms and before I draw my model. Becaue I only have a single object to draw … I don’t see the need to use matrix stacks (other than change between modelview and projection), but my model is disappearing now and I have a feeling it’s the order of stuff I do in my display().

My test code looks like this …


   gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

   // reset the modelview matrix
   gl.glColor3f(1.0f, 1.0f, 1.0f);
   gl.glMatrixMode(GL.GL_MODELVIEW);
   gl.glLoadIdentity();

   // Viewing transformation.
   glu.gluLookAt(0, 0, getZScale(), 
      centroid.getX(), centroid.getY(), centroid.getZ(),
      0.0, 1.0, 0.0);

   // Modeling tranformation, w/ my arcball transform.
   arcBall.getTransform().get(transf);
   gl.glMultMatrixf(transf);

   gl.glMatrixMode(GL.GL_PROJECTION);
   gl.glLoadIdentity();
   gl.glOrtho(-winWidth / 2, winWidth / 2, -winHeight / 2, winHeight / 2, 100, -100);

   // Draw model.
   {
      drawModel(drawable);
   }

All I’m trying to do is incr/decr the eye z coord in my gluLookAt for zooming in and out of the model and some rotation control. But even changing this value doesn’t change the position of the camera it seems.

I don’t think my arcball tranform is the problem. I think that works. But I now think it’s the way/order I’m doing all this. Currently, my model either dissappears when I start a drag operation, or just won’t show up.

Anyone have ideas/comments on what I’ve got above?

Not sure, but I think you have to switch back to the modelview matrix before drawing your model:


// Draw model.
{
   gl.glMatrixMode(GL.GL_MODELVIEW);
   drawModel(drawable);
}

You can’t “zoom” in an orthographic projection by chaning the z position of the camera or the model. You will just move the object out of the clipping volume. To achieve a zoom effect you have to change values you put into glOrtho. If you want to zoom in you make the bounds smaller, to zoom out you make the bounds larger.

Yeah, I tried that as well since the redbook didn’t give me any real good examples of this. But to no avail.

Thanks, I found where my book said zooming in ortho couldn’t be done by moving the camera back and forth, but this didn’t help my prob.

Are you saying I should just change the left, right, bottom, and top of glOrtho? Or should I just do a modeling transform of glScale? When to use what and in what order really confuse me.

Using glScale is OK, but it will mess with your lighting if you use it. I would just change the values of top, bottom, left, and right. Make them bigger and your model will look smaller. Make them smaller and your model will look larger. The front and back values just mark the clipping bounds and won’t have any effect on the appearance of the model.

Yep. You need to not just add an adjustment factor. The left and bottom need to have a different sign than the top and right values or you will just be moving the viewing volume not expanding or contracting it. Maybe something like:


gl.glOrtho(-winWidth - getAdjust(), winWidth + getAdjust(),
-winHeight - getAdjust(), winHeight + getAdjust(), 100, -100);

Well, I tried to delete the other post as soon as I could realizing what I had done. Then my problem was trying to get it to zoom in and out smoothly, so I now incr/decr the value of 0.007 to the last value of whatever getScale() contains each time the user presses a + or - key. It works, not real smooth, but I hope that’s how it’s supposed to be done. I now have …


   gl.glOrtho(-winWidth * getScale(), winWidth * getScale(), -winHeight * getScale(), winHeight * getScale(), 100, -100);

But now my problem is that, when I drag my model, it completely disappears. It doesn’t disappear like it’s being moved beyond a clipping pane. It just dissappears on the very first pixel drag. Any ideas on that? I can’t think of how to make it any simpler to find out where the problem is.


public void display(GLAutoDrawable drawable) {
	GL gl = drawable.getGL();
		
	this.glDrawable = drawable;
		
   	// clear the window
	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
				
	// reset the modelview matrix
	gl.glColor3f(1.0f, 1.0f, 1.0f);
	gl.glMatrixMode(GL.GL_MODELVIEW);
	gl.glLoadIdentity();

	// viewing transformation
	glu.gluLookAt(0, 0, 5, 0, 0, 0, 0.0, 1.0, 0.0);
	
	arcBall.getTransform().get(transf);
	gl.glMultMatrixf(transf);
		
	gl.glMatrixMode(GL.GL_PROJECTION);
	gl.glLoadIdentity();
		
	gl.glOrtho(-winWidth * getXScale(), winWidth * getXScale(),
		-winHeight * getXScale(), winHeight * getXScale(), 100, -100);
		
	// model tranformation
	{
		gl.glMatrixMode(GL.GL_MODELVIEW);
		drawModel(drawable);
	}

        return;
}

My model now appears on screen and most of the time it stays on my screen when I start to rotate it. I made it work because I changed some of the lines around.

I have just a few questions below to what I don’t understand. I marked the 3 lines w/ " // ??? " for the ones I don’t know why had to be added.


void display() {

   gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

   // reset the modelview matrix			   
   gl.glColor3f(1.0f, 1.0f, 1.0f);
   gl.glMatrixMode(GL.GL_MODELVIEW);
   gl.glLoadIdentity();

   // Viewing transformation.
   glu.gluLookAt(0, 0, eyeZ, 
      centroid.getX(), centroid.getY(),      
      centroid.getZ(), 0.0, 1.0, 0.0);
   
   // Modeling tranformation.
   // Apply arcball    transformation.arcBall.getTransform().get(transf);
   gl.glMultMatrixf(transf);

   // Projection transformation.
   gl.glMatrixMode(GL.GL_PROJECTION);
   gl.glPushMatrix(); // ?????????
   gl.glLoadIdentity();
   
   gl.glOrtho(-winWidth * getScaleFactor(), winWidth * getScaleFactor(), 
      -winHeight * getScaleFactor(), winHeight * getScaleFactor(), 100, -100);

   // Draw the model.
   {
      drawModel(drawable);
   }

   gl.glMatrixMode(GL.GL_PROJECTION); // ????????
   gl.glPopMatrix(); // ????????????

Q#1 Does it matter which mode glMatrixMode is in when the model is drawn?

Q#2 Why does it matter that the 2nd glMatrixMode(PROJECTION) is in this snippet of code. Isn’t it already in that mode when the model is drawn? It seems if I take it out, my model dissappears more.

Q#3 Why do I have to have a pushMatrix and popMatrix in GL_PROJECTION to make this work? I only display one object.

Still trying to figure out why when I start a drag operation that my model sometimes dissappears.

A: Yes is does matter. glTranslate, glRotate and glScale generate a matrix and multiply it by the current matrix. You need to be in modelview otherwise your projection matrix will be messed up.

B: Your code is messed up. But you already know that.

C: See B.

Do all your projection matrix math at the start of the method. Do the modelview transforms after. Can you distill your problem in to a simple demo that I/others could look at?

Maybe you misunderstood the book. There is no special order in how to modify your matrices, but there is an order of applying them, which is out of your control, since it is in the realm of the GL driver.

Indeed. It is nice to have all the projection transforms in one spot and all the modelview transforms in one spot for ease of reading.

I took a quick look at your code last night and there is something wrong with your arcball transforms. The matrix you read from the arcball is all zeros. That is why your model disappears as soon as you drag the mouse.

Remove this line from init in MyRenderer:

arcBall.getThisRot().set(transf);

It is setting that matrix to all zeros. It works if you pull that line.

Wow, that was like the one place I was never looking at. I thought that should go in the init since it gets called once but, I guess now realizing that a transform of all zeros was getting carried over into the display still multiplying against 0’s …

Thanks a ton!