Matrix translation help me!

im making a 3d robot that simply made of glutsolidcubes and will walk around the origin. but my problem is i cant get the robot drawn… i have made a function for each part of the robot, for example void torso() void upperRightarm() and so forth… the function that puts all these sub functions together you could say is void Robot() which is called by the glutdisplayfunc in main. my question is how do i get the parts to translate so they robot body will walk without leaving parts of him behind haha. i know you have to push/pop matrix but i cant seem to figure this out… i was able to get the torso to be drawn but after that it wont draw anything else. ideas or an example would be sweet! thanks

In each of your drawing functions (torso(), upperRightarm() and so forth) do you have push/pop pairs? Are the objects drawn at the origin in each of those functions? It is hard to tell not seeing any of your code.

I suggest reading Chapter 3 of the OpenGL Redbook
then take a careful look at Redbook Samples:robot.c

Alright here’s the code, iv been told so many ways of doing this that iv gotten confused. maybe my camera is just screwed up horrible, at this point im blind… help would be great! thanks

#include <stdlib.h>
#include <GL/glut.h>

GLsizei wh = 800,ww = 800;

void init();
void reshape(GLsizei w, GLsizei h);
void Robot();
void torso();
void head();
void upperRightArm();
void upperLeftArm();
void upperRightLeg();
void upperLeftLeg();
void lowerRightArm();
void lowerLeftArm();
void lowerRightLeg();
void lowerLeftLeg();

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(ww,wh);
glutInitWindowPosition(200,150);
glutCreateWindow(“Robot”);
glutReshapeFunc(reshape);
glutDisplayFunc(Robot);
init();
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}

void init()
{
glClearColor (0.0, 0.7, 1.0, 1.0);
glColor3f(0.,0.,1.);
glMatrixMode(GL_PROJECTION); //set the clipping space
glLoadIdentity();
glOrtho(-2.,2.0,-2.,2.,-2.,2.);
glMatrixMode(GL_MODELVIEW);
glutReshapeFunc(reshape);
}

void reshape(GLsizei w, GLsizei h)
{
/* adjust clipping box */

glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

/* adjust viewport and clear */

//glViewport(0,0,w,h);
glClearColor (0.0, 0.7, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();

/* set global size for use by drawing routine */

ww = w;
wh = h;

}

void Robot()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
glTranslatef(400,400,0.);
	torso();
	glPushMatrix();
		head();
    glPopMatrix();

/////////Attach Right Arms
glPushMatrix();
upperRightArm();
glPushMatrix();
lowerRightArm();
glPopMatrix();

////////Attach Left Arms
glPushMatrix();
upperLeftArm();
glPushMatrix();
lowerLeftArm();
glPopMatrix();

////////Attach Right Legs
glPushMatrix();
upperRightLeg();
glPushMatrix();
lowerRightLeg();
glPopMatrix();

////////Attach Left Legs
glPushMatrix();
upperLeftLeg();
glPushMatrix();
lowerLeftLeg();
glPopMatrix();

	glPopMatrix();


glutSwapBuffers();
glFlush();

}

void torso()
{
//glTranslatef(400,400,0.);
glColor3f(1.0,0.,.0);
glutSolidCube(150);
}

void head()
{
glTranslatef(400,520,0.);
glRotatef(-90,1.,0.,0.);
glScalef(20,40,20);
glColor3f(.0,1.,.0);
glutSolidCube(75);
}

void upperRightArm()
{
glColor3f(.5,.5,.0);
glutSolidCube(50);
}

void upperLeftArm()
{
glColor3f(.5,.5,.0);
glutSolidCube(50);
}

void upperRightLeg()
{
glColor3f(.5,.5,.0);
glutSolidCube(50);
}

void upperLeftLeg()
{
glColor3f(.5,.5,.0);
glutSolidCube(50);
}

void lowerRightArm()
{
glColor3f(.5,.0,1.0);
glutSolidCube(50);
}

void lowerLeftArm()
{
glColor3f(.0,1.5,1.0);
glutSolidCube(50);
}

void lowerRightLeg()
{
glColor3f(1.5,.0,1.0);
glutSolidCube(50);
}

void lowerLeftLeg()
{
glColor3f(.5,.5,.5);
glutSolidCube(50);
}

Two problems:

  1. You were reseting the clipping volume to a cube of size -1 to 1 with code in Robot()

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

  1. You have were not actually moving the arms legs etc – you have to tell where to put each with translate/scale/rotate etc inside appropriate push/pop pairs.

#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>

GLsizei wh = 800,ww = 800;

void init();
void reshape(GLsizei w, GLsizei h);
void Robot();
void torso();
void head();
void upperRightArm();
void upperLeftArm();
void upperRightLeg();
void upperLeftLeg();
void lowerRightArm();
void lowerLeftArm();
void lowerRightLeg();
void lowerLeftLeg();

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(ww,wh);
	glutInitWindowPosition(200,150);
	glutCreateWindow("Robot");
	glutReshapeFunc(reshape);
	glutDisplayFunc(Robot);
	init();
	glEnable(GL_DEPTH_TEST);
	glutMainLoop();
	return 0;
}


void init()
{
	glClearColor (0.0, 0.7, 1.0, 1.0);
	glColor3f(1.,1.,1.);
	glMatrixMode(GL_PROJECTION); //set the clipping space
	glLoadIdentity();
	glOrtho(-2000.,2000.0,-2000.,2000.,-2000.,2000.); // only need to call this once

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


void reshape(GLsizei w, GLsizei h)
{
	/* adjust clipping box */

	glViewport (0, 0, (GLsizei) w, (GLsizei) h);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	/* adjust viewport and clear */

	//glViewport(0,0,w,h);
	glClearColor (0.0, 0.7, 1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();

	/* set global size for use by drawing routine */

	ww = w;
	wh = h;

}


void Robot()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//	glMatrixMode (GL_PROJECTION); 
//	glLoadIdentity (); // this resets the cooridinate system to (-1,1 -1,1 -1,1) which ou don't want
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glPushMatrix();
	  torso();

	  glTranslatef(0,75,0.);
	  glRotatef(-90,1.,0.,0.);
	  glScalef(1,2,1);
	  head();
	glPopMatrix();

	glPushMatrix();
	  glTranslatef(-100,0,0.);
	  upperLeftArm();
	  glTranslatef(0,-50,0.);
	  lowerLeftArm();
	glPopMatrix();

	glPushMatrix();
	  glTranslatef(100,0,0.);
	  upperRightArm();
	  glTranslatef(0,-50,0.);
	  lowerRightArm();
	glPopMatrix();

	glPushMatrix();
	  glTranslatef(75,-100,0.);
	  upperRightLeg();
	  glTranslatef(0,-50,0.);
	  lowerRightLeg();
	glPopMatrix();

	glPushMatrix();
	  glTranslatef(-75,-100,0.);
	  upperLeftLeg();
	  glTranslatef(0,-50,0.);
	  lowerLeftLeg();
	glPopMatrix();

	glutSwapBuffers();
}


void torso()
{
	glColor3f(1.0,0.,.0);
	glutSolidCube(150);
}


void head()
{
	glColor3f(.0,1.,.0);
	glutSolidCube(75);
}


void upperRightArm()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}


void upperLeftArm()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}


void upperRightLeg()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}


void upperLeftLeg()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}


void lowerRightArm()
{
	glColor3f(.5,.0,1.0);
	glutSolidCube(50);
}


void lowerLeftArm()
{
	glColor3f(.0,1.5,1.0);
	glutSolidCube(50);
}


void lowerRightLeg()
{
	glColor3f(1.5,.0,1.0);
	glutSolidCube(50);
}


void lowerLeftLeg()
{
	glColor3f(.5,.5,.5);
	glutSolidCube(50);
}

Please read carefully chapter 3 in the Redbook … that chapter will really help you understand what these push/pop pairs are doing in conjunction with translate/scale/rotate. Also it explains in detail how to use glOrtho/gluPerpsective to set the correct clipping volume.

Hi Slong,

I spent some time fixing you code to make it actually draw something
that remotely looks like a robot… but without legs :slight_smile: - I didn’t have
time to finish them…

Check my comments - they begin with giv:
As marshats already mentioned read the Chapter 3 of the Red Book.
I also liked the approach that Edward Angel recommends in his
‘Interactive Computer Graphics. A top down approach with OpenGL’.

If you’re on Windows you should be able to copy the code and run it.


#include "stdafx.h"


#include <stdlib.h>
#include <GL/glut.h>

// giv: I'm on Windows...
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")

GLsizei wh = 800,ww = 800;

void init();
void reshape(GLsizei w, GLsizei h);
void Robot();
void torso();
void head();
//void upperRightArm();
//void upperLeftArm();
void upperArm();
void upperRightLeg();
void upperLeftLeg();
//void lowerRightArm();
//void lowerLeftArm();
void lowerArm();
void lowerRightLeg();
void lowerLeftLeg();

void main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(ww,wh);
	glutInitWindowPosition(200,150);
	glutCreateWindow("Robot");
	glutReshapeFunc(reshape);
	glutDisplayFunc(Robot);
	init();
	glEnable(GL_DEPTH_TEST);
	glutMainLoop();
}

void init()
{
	glClearColor (0.0, 0.7, 1.0, 1.0);
	glColor3f(0.,0.,1.);

	glMatrixMode(GL_PROJECTION); //set the clipping space
	glLoadIdentity();

	glOrtho(-2.,2.0,-2.,2.,-2.,2.);
	glMatrixMode(GL_MODELVIEW);

	glutReshapeFunc(reshape);
}

void reshape(GLsizei w, GLsizei h)
{
	/* adjust clipping box */

	glViewport (0, 0, (GLsizei) w, (GLsizei) h); 

	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
        // giv: maximize the viewing frustum, but beware of setting 
        // near plane too close, or far plane too far..
	gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 2000.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();


	/* adjust viewport and clear */

	//glViewport(0,0,w,h);
	glClearColor (0.0, 0.7, 1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();

	/* set global size for use by drawing routine */
	ww = w;
	wh = h;
}

void Robot()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // giv: you already set it reshape()...
	/*glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();*/
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	// giv: you missed this - this is logically the final transformation each 
	// vertex gets multiplied by, that transforms it into the camera frame
        // Check out Edward Angel's 'Interactive Computer Graphics. Second Edition. 
        // A top down approach to OpenGL'. In particular Chapter 4, section 9.
	gluLookAt(
	        25, 25, 75,
		0, 0, 0,
		0, 1, 0);

	glPushMatrix();
		
		// giv: put the torso right at the center of the world (0,0,0)
		torso();
		glPushMatrix();
			// giv: put the head slightly above the torso
			glTranslatef(0,9,0.);
			head();
		glPopMatrix();

		/////////Attach Right Arms
		glPushMatrix();
			glTranslatef(-15, -2, 0);
			//upperRightArm();
			upperArm();
			glTranslatef(0, -17, 1);
			//lowerRightArm();
			lowerArm();
		glPopMatrix(); 

		//////////Attach Left Arms
		//glPushMatrix();
		//	upperLeftArm();
		//	glPushMatrix();
		//		lowerLeftArm();
		//	glPopMatrix();
		glPushMatrix();
			glTranslatef(15, -2, 0);
			//upperRightArm();
			upperArm();
			glTranslatef(0, -17, 1);
			//lowerRightArm();
			lowerArm();
		glPopMatrix(); 

		//		////////Attach Right Legs
		//		glPushMatrix();
		//			upperRightLeg();
		//			glPushMatrix();
		//				lowerRightLeg();
		//			glPopMatrix();

		//			////////Attach Left Legs
		//			glPushMatrix();
		//				upperLeftLeg();
		//				glPushMatrix();
		//					lowerLeftLeg();
		//				glPopMatrix();

		//			glPopMatrix();

		//		// Igor's
		//		glPopMatrix();
		//	glPopMatrix();
		//glPopMatrix();
	glPopMatrix();

	glutSwapBuffers();
	glFlush();
}

void torso()
{
	glPushMatrix();
		glRotatef(90, 1, 0, 0);
		glColor3f(1.0,0.,.0);
		GLUquadric *q=gluNewQuadric();
		gluCylinder(q, 10, 10, 50, 50, 50);
		//glTranslatef(400,400,0.);
		gluDeleteQuadric(q);
		//glutSolidCube(3.5);
	glPopMatrix();
}

void head()
{
	// giv: the 2 commented out don't really make sense 
	//glTranslatef(400,520,0.); - translates the head way out of the camera view
	glRotatef(-90,1.,0.,0.);
	//glScalef(20,40,20); - makes the head way to big
	glColor3f(.0,1.,.0);
	glutSolidCube(/*7*/15);
}

//void upperRightArm()
//{
//	glColor3f(.5,.5,.0);
//	//glutSolidCube(10);
//
//	GLUquadric *q=gluNewQuadric();
//	gluCylinder(q, 3, 3, 20, 50, 50);
//	//glTranslatef(400,400,0.);
//	gluDeleteQuadric(q);
//}

//void upperLeftArm()
void upperArm()
{
	glPushMatrix();
		glRotatef(90, 1, 0, 0);
		glColor3f(.5,.5,.0);
		//glutSolidCube(10);
		GLUquadric *q=gluNewQuadric();
		gluCylinder(q, 3, 3, 15, 50, 50);
		//glTranslatef(400,400,0.);
		gluDeleteQuadric(q);
	glPopMatrix();
}

void upperRightLeg()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}

void upperLeftLeg()
{
	glColor3f(.5,.5,.0);
	glutSolidCube(50);
}

//void lowerRightArm()
//{
//	glColor3f(.5,.0,1.0);
//	glutSolidCube(50);
//}
//
//void lowerLeftArm()
//{
//	glColor3f(.0,1.5,1.0);
//	glutSolidCube(50);
//}
void lowerArm()
{
	glPushMatrix();
		glRotatef(55, 1, 0, 0);
		glColor3f(.5,.5,.0);
		//glutSolidCube(10);
		GLUquadric *q=gluNewQuadric();
		gluCylinder(q, 3, 3, 10, 50, 50);
		//glTranslatef(400,400,0.);
		gluDeleteQuadric(q);
	glPopMatrix();
}

void lowerRightLeg()
{
	glColor3f(1.5,.0,1.0);
	glutSolidCube(50);
}

void lowerLeftLeg()
{
	glColor3f(.5,.5,.5);
	glutSolidCube(50);
}

well trick of it is to have all the body parts connected to the torso so when the robot moves the parts move together as one… the reason i had it setup the way it was. just pushing and popping each part to the parent matrix, torso is the parent while the parts are the children (Tree nodes)… just couldnt figure out how to do this cause they were not drawing at all… when you translate the torso it translates everything else also. only unique changes is rotation and scaling to the parts that connect to the robot, the torso controls everything else.

igorgiv nice robot :slight_smile: ps without the stdafx.h it runs in linux too.

Note to move the entire robot as a unit just add the translate/rotate/etc just after the first glPushMatrix but before you start drawing the torso ie


	gluLookAt(
	        25, 25, 75,
		0, 0, 0,
		0, 1, 0);

	glPushMatrix();

		glRotatef(90,0,0.,1.); // affects entire robot as unit
		glTranslatef(0,9,-200.);
		
		// giv: put the torso right at the center of the world (0,0,0)
		torso();


Thanks.
That’s nice! :slight_smile:

Exactly - any transformation(s) inserted in between look-at and push-matrix (or after the first push-matrix) transform(s) the robot as the whole. Good catch…

Yea i got it working now, im building the robot as we speak, it was drawing the cubes as i had my code the first time they just were drawn inside of the torso so they were not showing up, after translating them they showed up :slight_smile: haha ima make this robot break dance :slight_smile: