rendering will not change with [dynamic] transformations

(sorry to post this in both categories, but I am not sure if the beginers will be enough help; I have never been here before)

I have trouble transforming objects; I just started with OpenGL, but I am NOT at all new to programming and 3D concepts (I read some up to lesson7 in the OpenGL red book online…)… I am using jGL (a java binding; you can look it up on google), since java is easy to use (unlike C++, which is the most practical, but a horrible mess)…

My problem is that I have a few rotation variables; I do something like this in display():

glPushMatrix();
glRotate3f(x, 1.0, 0.0, 0.0);
glRotate3f(y, 0.0, 1.0, 0.0);
drawSomething();
glPopMatrix();

(the values of x and y change with key presses; I know the key presses are working)

…and yet, everything is ALWAYS drawn the same!!
(I created this “glAbtractModel” class where you can fill in the abstract “draw” method…); if you replace drawSomething() with someModel.draw(), it always draws the same! However, if I explicity put those rotation commands in draw() with specific values, its works; but as soon as I try to use variables, it doesn’t.

Also, even though display lists can change OpenGL state variables, it seems that they do NOT respond to them (that is, if you store the rendering process of something in a display list, it will NOT be affected by any transformations to the ModelView Matrix); I thought that display lists stored the rendering process of something, not a FIXED [2D image] to be written to the display and depth buffer (or whatever you call the buffer that stores pixels/colors).

You can see my glAbstractModel at:

Please help me, this is SO frustrating!

This will inevitably turn out to be a basic question (Many other programs do not have any problems with transformations/rotations working in OpenGL).

However, perhaps if you post your “DrawSomething()” code (rather than us having to hunt around Yahoo for it) someone might spot the flaw (like for example starting your rendering code with glLoadIdentity()).

I don’t want to have to re-explain and dig it out out again… I posted everything including my code in the same topic in the coding:beginers section (I used both just in case it was something small that anybody could catch); please look at it there :slight_smile:

NEVERMIND! I figured it out, and it is so stupid.

All through the openGL programming guide so far (ch. 8) (correct me if I am wrong), it NEVER mentioned glutPostRedisplay(), and I must have overlooked it in the example programs; I just assumed that it automatically redisplayed everything (I would never usually asume stuff like that, but I overlooked it, and it just seemed to redisplay automatically)

ANYWAYS, here is the corrected code, which I think is very good (if know java, you could use this; it is a great setup for hierchial models with movable parts; subclass it to define one specific model (you can still create as many sperate instances as you want of such a defined model, each with its parts in their own place), or you can just create an instance of the class to quickly use and define one model) (I use jGL, which looks VERY similar to GL4JAVA; they seem to be the best; java is good to use OpenGL with because it is so easy and fast to use, and OpenGL is fast by itself anyways):

/* glAbstractModel.java
 * -created by Dan Cook
 *
 * Represents an OOP 3D model for use with jGL (a great java
 * binding for OpenGL). To use glAbstractModel, create a new
 * instance of it and fill in the draw() method with commands
 * to draw the object (these should be jGL commands so that a
 * call to getList() can store the whole drawing process into
 * a display list to improve efficiency when the object is
 * rendered). The other methods are all "final" because they
 * do not need to be modified/changed.
 *
 * Call render() to render the model with all of its [movable]
 * parts. Calling addPart() or setPart() add/set a part with
 * the current transformation of GL_MODELVIEW_MATRIX (to use a
 * default transformation, call glLoadIdentity() before you add
 * or modify a part; this is done automatically for parts that
 * are specified in the constructor).
 *
 * Points are included so that you can reference the same ones;
 * that does not make much difference, but it does same memory
 * in that you do not have to redeclare every point in the draw
 * method.
 *
 * Transformation matrices (array of 16 = 4x4 matrix) are used
 * to represent the transformation of each of the movable parts;
 * the reason that each glAbstractModel does not just have its
 * own transformation is because they are only needed for the
 * movable parts and NOT for the model itself (transformation of
 * the model can be done by transforming the model/view matrix,
 * or from a specified transformation because the model is part
 * of another model). "Nonmovable parts" should be drawn as part
 * of the model because there is no need for the extra recursion
 * and GL commands where they are not neccessary.
 */

import jgl.GL;

public abstract class glAbstractModel {
	public GL myGL;
	public float[][] points;
	public glAbstractModel[] parts;
	public float[][] transform;
	private boolean set;
	private int list;

	public glAbstractModel(GL gl, float[][] pts) {
		myGL = gl;
		points = pts;
		parts = new glAbstractModel[0];
		transform = new float[0][];
		set = false;
	}

	public glAbstractModel(GL gl, float[][] pts, glAbstractModel[] prts) {
		myGL = gl;
		points = pts;
		parts = prts;
		transform = new float[parts.length][];
		resetPart(0);
		for(int i=1; i<transform.length; i++)
			transform[i] = transform[0];
		set = false;
	}

	protected abstract void draw();

	public final void render() {
		draw();
		for(int i=0; i<parts.length; i++) {
			myGL.glPushMatrix();
				myGL.glMultMatrixf(transform[i]);
				parts[i].render();
			myGL.glPopMatrix();
		}
	}

	public boolean isList() {
		return set;
	}

	public final int getList() {
		if(set)
			return list;
		list = myGL.glGenLists(1);
		myGL.glNewList(list,myGL.GL_COMPILE);
			render();
		myGL.glEndList();
		set = true;
		return list;
	}

	public final void deleteList() {
		if(set) myGL.glDeleteLists(list,1);
		set = false;
	}

	public final void deleteLists() {
		deleteList();
		for(int i=0; i<parts.length; i++)
			parts[i].deleteLists();
	}

	public final void loadPart(int part) {
		myGL.glLoadMatrixf(transform[part]);
	}

	public final void setPart(int part) {
		myGL.glGetFloatv(myGL.GL_MODELVIEW_MATRIX, transform[part]);
	}

	public final void setPart(int part, glAbstractModel model) {
		parts[part] = model;
		setPart(part);
	}

	public final void resetPart(int part) {
		myGL.glPushMatrix();
			myGL.glLoadIdentity();
			myGL.glGetFloatv(myGL.GL_MODELVIEW_MATRIX, transform[part]);
		myGL.glPopMatrix();
	}

	public final void addPart(glAbstractModel part) {
		int size = parts.length;
		glAbstractModel[] prts = new glAbstractModel[size+1];
		float[][] trnsfrm = new float[size+1][];
		for(int i=0; i<size; i++) {
			prts[i] = parts[i];
			trnsfrm[i] = transform[i];
		}
		parts = prts;
		parts[size] = part;
		transform = trnsfrm;
		resetPart(size);
	}

	public final void deletePart(int part) {
		int size = parts.length-1;
		glAbstractModel[] prts = new glAbstractModel[size];
		float[][] trnsfrm = new float[size][];
		for(int i=0; i<part; i++) {
			prts[i] = parts[i];
			trnsfrm[i] = transform[i];
		}
		for(int i=part; i<size; i++) {
			prts[i] = parts[i+1];
			trnsfrm[i] = transform[i+1];
		}
		parts = prts;
		trnsfrm = transform;
	}

	public final glAbstractModel removePart(int part) {
		glAbstractModel removed = parts[part];
		deletePart(part);
		return removed;
	}
}
/* test.java
 *
 * a simple program to test
 * the glAbstractModel class
 */

import jgl.GL;
import jgl.GLCanvas;
import java.awt.Frame;

public class test extends GLCanvas {
	public glAbstractModel model;
	public int xAngle;
	public int yAngle;

	public void myinit() {
		xAngle = 0;
		yAngle = 0;

		float[] mat_specular = {1.0f, 1.0f, 1.0f, 1.0f};
		float[] mat_shininess = {50.0f};
		float[] light_position = {1.0f, 1.0f, 1.0f, 0.0f};
	
		myGL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		myGL.glShadeModel(GL.GL_SMOOTH);
	
		myGL.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular);
		myGL.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess);
		myGL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position);
	
		myGL.glEnable(GL.GL_LIGHTING);
		myGL.glEnable(GL.GL_LIGHT0);
		myGL.glEnable(GL.GL_DEPTH_TEST);

		model = new glAbstractModel(
			myGL,
			new float[][] {
				{ 1.0f, 1.0f, 1.0f},{ 1.0f, 1.0f,-1.0f},
				{ 1.0f,-1.0f, 1.0f},{ 1.0f,-1.0f,-1.0f},
				{-1.0f, 1.0f, 1.0f},{-1.0f, 1.0f,-1.0f},
				{-1.0f,-1.0f, 1.0f},{-1.0f,-1.0f,-1.0f}
			}
		) {
			public void draw() {
				myGL.glBegin(myGL.GL_QUAD_STRIP);
					myGL.glNormal3fv(points[0]);
					myGL.glVertex3fv(points[0]);
					myGL.glNormal3fv(points[1]);
					myGL.glVertex3fv(points[1]);
					myGL.glNormal3fv(points[2]);
					myGL.glVertex3fv(points[2]);
					myGL.glNormal3fv(points[3]);
					myGL.glVertex3fv(points[3]);
					myGL.glNormal3fv(points[6]);
					myGL.glVertex3fv(points[6]);
					myGL.glNormal3fv(points[7]);
					myGL.glVertex3fv(points[7]);
					myGL.glNormal3fv(points[4]);
					myGL.glVertex3fv(points[4]);
					myGL.glNormal3fv(points[5]);
					myGL.glVertex3fv(points[5]);
					myGL.glNormal3fv(points[0]);
					myGL.glVertex3fv(points[0]);
					myGL.glNormal3fv(points[1]);
					myGL.glVertex3fv(points[1]);
				myGL.glEnd();
				myGL.glBegin(myGL.GL_QUADS);
					myGL.glNormal3fv(points[0]);
					myGL.glVertex3fv(points[0]);
					myGL.glNormal3fv(points[4]);
					myGL.glVertex3fv(points[4]);
					myGL.glNormal3fv(points[6]);
					myGL.glVertex3fv(points[6]);
					myGL.glNormal3fv(points[2]);
					myGL.glVertex3fv(points[2]);
					myGL.glNormal3fv(points[1]);
					myGL.glVertex3fv(points[1]);
					myGL.glNormal3fv(points[3]);
					myGL.glVertex3fv(points[3]);
					myGL.glNormal3fv(points[7]);
					myGL.glVertex3fv(points[7]);
					myGL.glNormal3fv(points[5]);
					myGL.glVertex3fv(points[5]);
				myGL.glEnd();
			}
		};
		myGL.glTranslatef(0.0f, 0.0f, 2.0f);
	}

	public void display() {
		myGL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		myGL.glPushMatrix();
			myGL.glRotatef(xAngle, 1.0f, 0.0f, 0.0f);
			myGL.glRotatef(yAngle, 0.0f, 1.0f, 0.0f);
			model.render();
		myGL.glPopMatrix();
		myGL.glFlush();
	}

    public void myReshape (int w, int h) {
        myGL.glViewport(0, 0, w, h);
        myGL.glMatrixMode(GL.GL_PROJECTION);
        myGL.glLoadIdentity();
		if (w <= h)
		    myGL.glOrtho(
		    	-5.0f, 5.0f,
		    	-5.0f *(float)h/(float)w,
				5.0f *(float)h/(float)w,
				-5.0f, 5.0f
			);
		else
		    myGL.glOrtho(
		    	-5.0f *(float)w/(float)h,
		    	5.0f *(float)w/(float)h,
				-5.0f, 5.0f,
				-5.0f, 5.0f
			);
        myGL.glMatrixMode(GL.GL_MODELVIEW);
        myGL.glLoadIdentity();
    }

	public void keyboard(char key, int x, int y) {
		switch (key) {
			case 'x': xAngle = (xAngle+5)%360; break;
			case 'X': xAngle = (xAngle-5)%360; break;
			case 'y': yAngle = (yAngle+5)%360; break;
			case 'Y': yAngle = (yAngle-5)%360; break;
	    	case 27: System.exit(0);
	    	default: return;
		}
		myUT.glutPostRedisplay();
	}

	public void init() {
		myUT.glutInitWindowSize(500,500);
		myUT.glutInitWindowPosition(0,0);
		myUT.glutCreateWindow(this);
		myinit();
		myUT.glutDisplayFunc("display");
		myUT.glutReshapeFunc("myReshape");
		myUT.glutKeyboardFunc("keyboard");
		myUT.glutMainLoop();
	}

	public static void main (String args[]) {
		Frame mainFrame = new Frame();
		mainFrame.setSize(508,527);
		test mainCanvas = new test();
		mainCanvas.init();
		mainFrame.add(mainCanvas);
		mainFrame.setVisible(true);
    }
}