Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Translating an object

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2009
    Posts
    6

    Translating an object

    Okay, so first let me get it out of the way that this is not entirely my project. I have not done all the coding, so everything you will see in the code is not completely from my knowledge. I am rather new at OpenGL, and rather new at programming all together. That said, I am in the middle of a lengthy project with a group, and so far we have come up with an octahedron that bounces within a cube, translating after each wall hit. Complete with materials, lights and shadows. I am now at the task of having to add menu functionality for translating the octahedron (up, down, left, right, forward, backward). The easiest way I see this being done is relative to where the octahedron currently is when you do the translating. I am just not exactly sure how I should be going about this. Any helpful hints or tips will be GREATLY appreciated. Thanks for everything guys. Note; making the menu will not be the problem, I can do that easily, its the actual coding of the translations I am worried about.

    That all said, here is the code.

    octahedron.h
    Code :
    #include <GL/glut.h>
     
    /**********************************************************/
    /* Material */
    /**********************************************************/
     
    struct Material {
      GLfloat ambient[4];
      GLfloat diffuse[4];
      GLfloat specular[4];
      GLfloat shiny;
    };
    typedef struct Material Material;
     
    struct Point{
    	GLfloat x;
    	GLfloat y;
    	GLfloat z;
    };
    typedef struct Point Point;
     
    Material WhatIsBrass(void);
    Material WhatIsWhiteShiny(void);
    Material WhatIsRedPlastic(void);
     
    #define Brass WhatIsBrass()
    #define WhiteShiny WhatIsWhiteShiny()
    #define RedPlastic WhatIsRedPlastic()
     
    void SetMaterial(Material m);

    octahedron.cpp
    Code :
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <GL/glut.h>
    #include <math.h>
    #include "octahedron.h"
     
    #define PI 3.14159265
     
    GLsizei ww = 700, wh = 700;
    GLdouble orthoX = 700, orthoY = 700, orthoZ = 700;
    GLint wcx = 180, wcy = 180;
    int xTrack, yTrack;					//tracks mouse movement
    GLfloat moveX = 0.0, moveY = 0.0, moveZ = 0.0;
    GLfloat rotX = 0, rotY = 0, rotZ = 0;
    GLfloat delX = 0.16, delY = 0.05, delZ = 0.2;
     
    float rotSpeed[2];					//to be possibly used later for automatic rotation
     
    bool tracking = false;				//true when left mouse is held down
    									//since the octahedron rotation is handled by bouncing,
    									//should probably use this to move camera around
     
    const GLfloat f[16] = {1, 0, 0, 0,
    						0, 0, 0, 0,
    						0, 0, 1, 0,
    						0,-4, 0, 1};
     
    double rotation[2] = {0,0};			//keeps track of current rotation
     
    GLfloat vertices[6][3] =	{{0,1,0}, //0, 1, ... , 5
    							{0,-1,0}, 
    							{0,0,1}, 
    							{1,0,0}, 
    							{-1,0,0}, 
    							{0,0,-1}};
    GLubyte octaIndices[24] =	{0,2,3,     //face indices
    							 0,2,4,
    							 0,5,4,
    							 0,5,3,
    							 1,2,4,
    							 1,2,3,
    							 1,5,3,
    							 1,5,4};
     
     
     
    //calculate the norm from three points
    //could be optimized a bit
    Point norm(GLfloat a[3], GLfloat b[3], GLfloat c[3])
    {
    	GLfloat v1[3] = {a[0] - c[0], a[1] - c[1], a[2] - c[2]};
    	GLfloat v2[3] = {b[0] - c[0], b[1] - c[1], b[2] - c[2]};
    	//(a2b3 &amp;#8722; a3b2, a3b1 &amp;#8722; a1b3, a1b2 &amp;#8722; a2b1)
    	Point n = {(v1[1] * v2[2]) - (v1[2] * v2[1]),
    		(v1[2] * v2[0]) - (v1[0] * v2[2]),
    		(v1[0] * v2[1]) - (v1[1] * v2[0])};
     
    	return n;
    }
     
    //calculate normal of each face, draw the face
    //for some reason the normal of each odd face points inwards, so they are negated
    void drawOcta(char shadow){
    	GLfloat x, y;
    	int i = 0;
    	Point n;
    	for(i; i < 8; i++){
    		//glColor3ub(colors[i * 3],colors[i * 3 + 1],colors[i * 3 + 2]);
     
    		if (shadow == 1){
    		n = norm(vertices[octaIndices[i*3 + 1]], vertices[octaIndices[i*3 + 2]], vertices[octaIndices[i*3]]);
     
    		if(i % 2 == 0)
    			glNormal3f(n.x, n.y, n.z);
     
    		else
    			glNormal3f(- n.x, - n.y, - n.z);
    		}
     
    		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, &amp;octaIndices[i*3]);
     
    	}
     
     
    }
     
     
    void ani() {
     
     
    	int i, j, k;
    	GLfloat pos[2];		//x,y,z
    	GLfloat dir[2];		//dx,dy,dz
    	GLint rot;			//degrees
     
     
     
    	for (i = 0; i < 9000000; i++) 
    		;
    	// printf ("%f\t%f\t%f\n", moveX, moveY, moveZ);
    	if (moveX > 3.0){
    		delX = -delX;
    		if(delY > 0)
    			rotY = rotY + 15;
    		else
    			rotY = rotY - 15;
    		if(delZ > 0)
    			rotZ = rotZ + 15;
    		else
    			rotZ = rotZ - 15;
    	}
     
    	if (moveY > 3.0){
    		delY = -delY;
    		if(delX > 0)
    			rotX = rotX + 15;
    		else
    			rotX = rotX - 15;
    		if(delX > 0)
    			rotX = rotX + 15;
    		else
    			rotX = rotX - 15;
    	}
     
    	if (moveZ > 3.0){
    		delZ = -delZ;
    		if(delY > 0)
    			rotY = rotY + 15;
    		else
    			rotY = rotY - 15;
    		if(delX > 0)
    			rotX = rotX + 15;
    		else
    			rotX = rotX - 15;
    	}
    	if (moveX < -3.0){
    		delX = -delX;
    		if(delY > 0)
    			rotY = rotY + 15;
    		else
    			rotY = rotY - 15;
    		if(delZ > 0)
    			rotZ = rotZ + 15;
    		else
    			rotZ = rotZ - 15;
    	}
     
    	if (moveY < -3.0){
    		delY = -delY;
    		if(delX > 0)
    			rotX = rotX + 15;
    		else
    			rotX = rotX - 15;
    		if(delZ > 0)
    			rotZ = rotZ + 15;
    		else
    			rotZ = rotZ - 15;
    	}
     
    	if (moveZ < -3.0){
    		delZ = -delZ;
    		if(delY > 0)
    			rotY = rotY + 15;
    		else
    			rotY = rotY - 15;
    		if(delX > 0)
    			rotX = rotX + 15;
    		else
    			rotX = rotX - 15;
    	}
     
    	moveX += delX;
    	moveY += delY;
    	moveZ += delZ;
     
     
    	glutPostRedisplay ( );
    } 
     
     
     
    /**********************************************************/
    /* Material */
    /**********************************************************/
     
    Material WhatIsBrass(void)
         /* brass material */
    {
      Material thisIsIt =
        {{0.33, 0.22, 0.03, 1.0},
         {0.78, 0.57, 0.11, 1.0},
         {0.99, 0.91, 0.81, 1.0},
         27.8};
     
      return thisIsIt;
    }
     
    Material WhatIsWhiteShiny(void)
    {
      Material thisIsIt =
        {{1.0, 1.0, 1.0, 1.0},
         {1.0, 1.0, 1.0, 1.0},
         {1.0, 1.0, 1.0, 1.0},
         100.0};
     
      return thisIsIt;
    }
     
    Material WhatIsRedPlastic(void)
    {
      Material thisIsIt =
        {{0.3, 0.0, 0.0, 1.0},
         {0.6, 0.0, 0.0, 1.0},
         {0.8, 0.6, 0.6, 1.0},
         32.0};
     
      return thisIsIt;
    }
     
     
    void SetMaterial(Material m)
         /* sets the current material */
    {
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m.ambient);
      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m.diffuse);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m.specular);
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m.shiny);
    }
     
    void display() {
     
     
    	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
     
    	//store view matrix
    	glPushMatrix();
    	glMatrixMode (GL_MODELVIEW);
    	glLoadIdentity();
     
    	//lights off
    	glDisable(GL_LIGHT0);
    	//apply rotation
     
    	//black lines for the cube
    	glColor3ub(0, 0, 0);
     
    	//these two represent camera rotation
    	glRotated(30, 1.0, 0.0, 0.0);
    	glRotated(30, 0.0, 1.0, 0.0);
    	glBegin(GL_LINE_STRIP);
    		glVertex3f(-4,-4,-4);
    		glVertex3f(-4,4,-4);
    		glVertex3f(-4,4,4);
    		glVertex3f(-4,-4,4);
    		glVertex3f(-4,-4,-4);
    		glVertex3f(4,-4,-4);
    		glVertex3f(4,4,-4);
    		glVertex3f(4,4,4);
    		glVertex3f(4,-4,4);
    		glVertex3f(4,-4,-4);
    	glEnd();
    	glBegin(GL_LINES);
    		glVertex3f(-4, 4, -4);
    		glVertex3f(4, 4, -4);
    		glVertex3f(-4, 4, 4);
    		glVertex3f(4, 4, 4);
    		glVertex3f(-4, -4, 4);
    		glVertex3f(4, -4, 4);
    	glEnd();
     
     
    	//these four transformations apply only to the octahedron
    	glTranslatef (moveX, moveY, moveZ);
    	glRotatef(rotX, 1.0, 0.0, 0.0);
    	glRotatef(rotY, 0.0, 1.0, 0.0);
    	glRotatef(rotZ, 0.0, 0.0, 1.0);
     
     
     
    	//lights on
    	glEnable(GL_LIGHT0);
     
    	//glEnable(GL_LIGHT1);    but not this light
     
    	SetMaterial(Brass);
    	drawOcta(1);
    	glLoadIdentity();
     
     
    	glDisable(GL_LIGHT0);
     
     
    	//once again, camera rotations
    	glRotated(30, 1.0, 0.0, 0.0);
    	glRotated(30, 0.0, 1.0, 0.0);
     
    	//these five transformations apply only to the shadow of the octahedron
    	//later, should have a function for each light, can modify the mult matrix per light fairly easily, or have them be
    	//part of the struct, which we haven't done yet
    	glTranslatef (moveX, 0, moveZ);
    	//mult matrix: basically, draw the octahedron again, but flatten it against the floor to achieve the shadow
    	//only works if the light is considered to be far above the scene
    	glMultMatrixf(f);
    	glRotatef(rotX, 1.0, 0.0, 0.0);
    	glRotatef(rotY, 0.0, 1.0, 0.0);
    	glRotatef(rotZ, 0.0, 0.0, 1.0);
    	drawOcta(0);
     
    	//recover viewing matrix
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
     
    	glFlush();
    	glutSwapBuffers();
     
     
    }
     
    //left mouse toggles tracking bool
    void mouse(int button, int state, int x, int y) {
     
    	if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN) {
    		tracking = true;
     
    	}
    	if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_UP) {
     
    		tracking = false;
    	}
     
    }
     
    //tracks mouse position while mouse button is being held
    void mouseTrackActive(int x, int y) {
     
     
    		if(tracking == true){
     
    			rotation[0] = rotation[0] + .7*(x - xTrack);
    			if (rotation[0] >= 360) rotation[0]-=360;
    			rotation[1] = rotation[1] + .7*(y - yTrack);
    			if (rotation[1] >= 360) rotation[1]-=360;
    		}
     
    		xTrack = x;
    		yTrack = y;
    		glutPostRedisplay();
    	}
     
    //tracks mouse position while mouse button not being held
    //essential to remain consistent with active mouse function
    void mouseTrackPassive(int x, int y){
     
    		xTrack = x;
    		yTrack = y;
    		glutPostRedisplay();
    }
     
    int main(int argc, char **argv) {
    	GLfloat lightPos1[] = {0.0, 10.0, 0.0, 0.0};
     
        /* yellow light */
        GLfloat diffuse1[] = {1.0, 1.0, 0.75, 1.0};
        GLfloat specular1[] = {0.8, 0.8, 0.4, 1.0};
        GLfloat ambient1[] = {0.35, 0.35, 0.35, 1.0};
     
    	//another light
    	GLfloat lightPos2[] = {0.0, 1.0, -1.0, 0.0};
        GLfloat diffuse2[] = {0.4, 0.4, 0.4, 1.0};
        GLfloat specular2[] = {0.0, 0.0, 0.0, 1.0};
        GLfloat ambient2[] = {0.05, 0.05, 0.05, 0};
     
        /* background light */
        GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
     
    	glutInit (&amp;argc, argv);
    	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB| GLUT_DEPTH);
    	glutInitWindowSize (ww, wh);
    	glutInitWindowPosition (wcx, wcy);
    	glutCreateWindow ("Octahedron");
    	glutDisplayFunc(display);
     
     
    	glMatrixMode (GL_PROJECTION);
    	glViewport (0,0, ww, wh);
    	glLoadIdentity ( );
    	glOrtho (-12.0, 12.0, -12.0, 12.0, -12.0, 12.0);
    	glFrustum(-10.0, 10.0, -10.0, 10.0, -10.0, 10.0);
     
    	//glMatrixMode (GL_MODELVIEW);
    	glutIdleFunc(ani);
    	glutMotionFunc(mouseTrackActive);
    	glutPassiveMotionFunc(mouseTrackPassive);
    	glutMouseFunc(mouse);
    	glEnable(GL_DEPTH_TEST);
    	glEnableClientState(GL_VERTEX_ARRAY);
     
    	//color handled mostly by materials + light
    	//glEnableClientState(GL_COLOR_ARRAY);
    	//glColorPointer(3,GL_UNSIGNED_BYTE, 0, &amp;colors);
    	glVertexPointer(3, GL_FLOAT, 0, &amp;vertices);
    	glShadeModel(GL_FLAT);
        glEnable(GL_LIGHTING);
        glEnable(GL_NORMALIZE);
     
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
        /* set a low background light such that objects in the scene
           can be seen at all */
     
    	glClearColor (1.0, 1.0, 1.0, 1.0);	   /*white background */
     
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
     
        glLightfv(GL_LIGHT0, GL_POSITION, lightPos1);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse1);
        glLightfv(GL_LIGHT0, GL_SPECULAR, specular1);
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient1);
    	glLightfv(GL_LIGHT1, GL_POSITION, lightPos2);
        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2);
        glLightfv(GL_LIGHT1, GL_SPECULAR, specular2);
        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient2);
    	glutMainLoop();
    }

    Again, thanks for all your time and consideration guys.

  2. #2
    Junior Member Newbie
    Join Date
    Apr 2009
    Posts
    6

    Re: Translating an object

    Just to add, my personal thoughts are to just make menu functions for rotX, rotY, and rotZ. But would that be enough? And would I have to push and pop the matrix to do this effect or would it truly be that simple to do?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •