X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=scene.c;h=69c5a820ed26fa4c983adfd966d7284f76c66f5c;hb=8ce9e04b2f947ad161075ba0a8cf822b5594d199;hp=6fab50e7d6368c4c910ef5a430f595d4d504bc52;hpb=78afa41d3d94bdcc99cbbf136ed730b5498dc1c2;p=atyndall%2Fcits2231.git diff --git a/scene.c b/scene.c index 6fab50e..69c5a82 100644 --- a/scene.c +++ b/scene.c @@ -1,9 +1,7 @@ -// compile this program using: -// gcc -O3 -Wall -std=c99 -o scene scene.c bitmap.c -lglut -// Or, with cygwin: (-mno-cygwin is only so the executable runs from windows) -// gcc -mno-cygwin -O3 -Wall -std=c99 -o scene scene.c bitmap.c -lglut32 -lglu32 -lopengl32 -// Or, use make via the supplied Makefile: (For cygwin, install the package for make) -// make +/** + * CITS2231 Graphics Scene Editor + * @author Ashley Tyndall (20915779), Jenna de la Harpe (20367932) + */ #include #include @@ -12,357 +10,451 @@ #include #include #include +#include #include "bitmap.h" +#include "globals.h" +#include "helper.h" +#include "types.h" +#include "scene.h" + +/** + * Event hander for main menu events + * @param id ID of menu item selected + */ +void processMainEvents(int id) { + switch (id) { + case M_ROTATE_MOVE_CAMERA: + manipulateState = STATE_CAMERA_ROTATE_MOVE; + break; + case M_POSITION_SCALE: + manipulateState = STATE_OBJECT_POSITION_SCALE; + break; + case M_ROTATION_TEXTURE_SCALE: + manipulateState = STATE_OBJECT_ROTATION_TEXTURE_SCALE; + break; + case M_EXIT: + exit(EXIT_SUCCESS); -// Type definitions for vertex-coordinates, normals, texture-coordinates, -// and triangles (via the indices of 3 vertices). -typedef GLfloat vertex[3]; -typedef GLfloat normal[3]; -typedef GLfloat texCoord[2]; -typedef GLint vertexIndex; -typedef vertexIndex triangle[3]; - -// A type for a mesh -typedef struct { - int nVertices; // The number of vertices in the mesh - vertex* vertices; // Array with coordinates of vertices - normal* normals; // Array with normals of vertices - texCoord* texCoords; // Array with texture-coordinates of vertices - int nTriangles; // The number of triangles in the mesh - triangle* triangles; // Array of trangles via 3 indices into "vertices" -} mesh; - -#define NMESH 54 // The number of meshes (in the models-textures dir) -mesh* meshes[NMESH]; // An array of pointers to the meshes - see getMesh - -// A type for a 2D texture, with height and width in pixels -typedef struct { - int height; - int width; - GLubyte *rgbData; // Array of bytes with the colour data for the texture -} texture; - -#define NTEXTURE 30 // The number of textures (in the models-textures dir) -texture* textures[NTEXTURE]; // An array of texture pointers - see getTexture - -typedef struct { - // You'll need to add scale, rotation, material, mesh number, etc., - // to this structure - float x,y,z; -} SceneObject; - -#define MAXOBJECTS 256 -SceneObject sceneObjs[MAXOBJECTS]; // An array with details of the objects in a scene -int nObjects=0; // How many objects there are in the scene currently. - -void fileErr(char* fileName) { - printf("Error reading file: %s\n", fileName); - printf("If not in the CSSE labs, you will need to include the directory containing\n"); - printf("the models on the command line, or put it in the same folder as the exectutable."); - exit(1); -} - -texture* loadTexture(char *fileName) { - texture* t = malloc(sizeof (texture)); - BITMAPINFO *info; - - t->rgbData = LoadDIBitmap(fileName, &info); - t->height=info->bmiHeader.biHeight; - t->width=info->bmiHeader.biWidth; - - return t; + } } -// The following works for the supplied .x files -// but probably not for .x files from other sources. -mesh* loadMesh(char* fileName) { - mesh* m = malloc(sizeof (mesh)); - FILE* fp = fopen(fileName, "r"); - char line[256] = ""; - int lineBuffSize = 256; - - if(fp == NULL) fileErr(fileName); - - while(strcmp(line,"Mesh {\r\n") != 0 && strcmp(line,"Mesh {\n") != 0 ) - fgets(line, lineBuffSize, fp); - - fscanf(fp, "%d;\n", &(m->nVertices)); - m->vertices = malloc(m->nVertices * sizeof(vertex)); - for(int i=0; i < m->nVertices; i++) - fscanf(fp, "%f; %f; %f;%*[,;]\n", &(m->vertices[i][0]), &(m->vertices[i][1]), &(m->vertices[i][2]) ); - - fscanf(fp, "%d;\n", &(m->nTriangles)); - m->triangles = malloc(m->nTriangles * sizeof(triangle)); - for(int i=0; i < m->nTriangles; i++) - fscanf(fp, "%*d; %d, %d, %d;%*[;,]", m->triangles[i], m->triangles[i]+1, m->triangles[i]+2); - - while(strcmp(line," MeshNormals {\r\n") != 0 && strcmp(line," MeshNormals {\n") != 0) - fgets(line, lineBuffSize, fp); - - fgets(line, lineBuffSize, fp); - m->normals = malloc(m->nVertices * sizeof(normal)); - for(int i=0; i < m->nVertices; i++) - fscanf(fp, "%f; %f; %f;%*[;,]\n", - &(m->normals[i][0]), &(m->normals[i][1]), &(m->normals[i][2])); - - while(strcmp(line,"MeshTextureCoords {\r\n") != 0 && strcmp(line,"MeshTextureCoords {\n") != 0) - fgets(line, lineBuffSize, fp); - - fgets(line, lineBuffSize, fp); - m->texCoords = malloc(m->nVertices * sizeof(texCoord)); - for(int i=0; i < m->nVertices; i++) - fscanf(fp, "%f;%f;%*[,;]\n", &(m->texCoords[i][0]), &(m->texCoords[i][1]) ); - fclose(fp); - - return m; -} +/** + * Event hander for materials menu events + * @param id ID of menu item selected + */ +void processMaterialEvents(int id) { + switch (id) { + case M_MATERIAL_ALL_RGB: + // Do stuff + break; -char dataDir[200]; // Stores the directory name for the meshes and textures. + case M_MATERIAL_AMBIENT_RGB: + // Do stuff + break; -// getMesh(i) loads mesh[i] if it isn't already loaded. -// You must call getMesh(i) at least once before using mesh[i]. -// [You may want to add to this function.] -void getMesh(int i) { // getMesh(i) loads mesh[i] if it isn't already loaded. - char fileName[220]; - if(i>=NMESH || i<0) { - printf("Error in getMesh - wrong model number"); - exit(1); - } - if(meshes[i] != NULL) - return; - sprintf(fileName, "%s/model%d.x", dataDir, i+1); - meshes[i] = loadMesh(fileName); -} + case M_MATERIAL_DIFFUSE_RGB: + // Do stuff + break; -// getTexture(i) loads texture i if it isn't already loaded. -// After calling getTexture(i), you can make texture i the current texture using -// glBindTexture(GL_TEXTURE_2D, i); (Use i=0 to return to the default plain texture.) -// You can then scale the texture via: (See the textbook, section 8.8.3.) -// glMatrixMode(GL_TEXTURE); -// You must call getTexture(i) at least once before using texture i. -void getTexture(int i) { // getTexture(i) loads texture i if it isn't already loaded. - char fileName[220]; - if(i<1 || i>NTEXTURE) { - printf("Error in getTexture - wrong texture number"); - exit(1); - } - if(textures[i-1] != NULL) - return; - sprintf(fileName, "%s/texture%d.bmp", dataDir, i); + case M_MATERIAL_SPECULAR_RGB: + // Do stuff + break; - textures[i-1] = loadTexture(fileName); + case M_MATERIAL_ALL_ADSS: + // Do stuff + break; - glBindTexture(GL_TEXTURE_2D, i); + case M_MATERIAL_RED_ADSS: + // Do stuff + break; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textures[i-1]->width, textures[i-1]->height, - 0, GL_RGB, GL_UNSIGNED_BYTE, textures[i-1]->rgbData); - gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, textures[i-1]->width, textures[i-1]->height, GL_RGB, - GL_UNSIGNED_BYTE, textures[i-1]->rgbData); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + case M_MATERIAL_GREEN_ADSS: + // Do stuff + break; - glBindTexture(GL_TEXTURE_2D, 0); // Back to default texture + case M_MATERIAL_BLUE_ADSS: + // Do stuff + break; + + } } -// Menu enum -enum menu { - // Main menu - ROTATE_MOVE_CAMERA, - POSITION_SCALE, - ROTATION_TEXTURE_SCALE, - EXIT, - - // Material submenu - MATERIAL_ALL_RGB, - MATERIAL_AMBIENT_RGB, - MATERIAL_DIFFUSE_RGB, - MATERIAL_SPECULAR_RGB, - MATERIAL_ALL_ADSS, - MATERIAL_RED_ADSS, - MATERIAL_GREEN_ADSS, - MATERIAL_BLUE_ADSS, - - // Light submenu - LIGHT_MOVE_LIGHT_1, - LIGHT_RGBALL_LIGHT_1, - LIGHT_MOVE_LIGHT_2, - LIGHT_RGBALL_LIGHT_2 -}; - -// Menu arrays -const char *textureMenuEntries[NTEXTURE] = { - "1 Plain", "2 Rust", "3 Concrete", "4 Carpet", "5 Beach Sand", - "6 Rocky", "7 Brick", "8 Water", "9 Paper", "10 Marble", - "11 Wood", "12 Scales", "13 Fur", "14 Denim", "15 Hessian", - "16 Orange Peel", "17 Ice Crystals", "18 Grass", "19 Corrugated Iron", "20 Styrofoam", - "21 Bubble Wrap", "22 Leather", "23 Camouflage", "24 Asphalt", "25 Scratched Ice", - "26 Rattan", "27 Snow", "28 Dry Mud", "29 Old Concrete", "30 Leopard Skin" -}; - -const char *objectMenuEntries[NMESH] = { - "1 Thin Dinosaur","2 Big Dog","3 Saddle Dinosaur", "4 Dragon", "5 Cleopatra", - "6 Bone I", "7 Bone II", "8 Rabbit", "9 Long Dragon", "10 Buddha", - "11 Sitting Rabbit", "12 Frog", "13 Cow", "14 Monster", "15 Sea Horse", - "16 Head", "17 Pelican", "18 Horse", "19 Kneeling Angel", "20 Porsche I", - "21 Truck", "22 Statue of Liberty", "23 Sitting Angel", "24 Metal Part", "25 Car", - "26 Apatosaurus", "27 Airliner", "28 Motorbike", "29 Dolphin", "30 Spaceman", - "31 Winnie the Pooh", "32 Shark", "33 Crocodile", "34 Toddler", "35 Fat Dinosaur", - "36 Chihuahua", "37 Sabre-toothed Tiger", "38 Lioness", "39 Fish", "40 Horse (head down)", - "41 Horse (head up)", "42 Skull", "43 Fighter Jet I", "44 Toad", "45 Convertible", - "46 Porsche II", "47 Hare", "48 Vintage Car", "49 Fighter Jet II", "50 Winged Monkey", - "51 Chef", "52 Parasaurolophus", "53 Rooster", "54 T-rex" -}; +/** + * Event hander for light menu events + * @param id ID of menu item selected + */ +void processLightEvents(int id) { + switch (id) { + case M_LIGHT_MOVE_LIGHT_1: + manipulateState = STATE_LIGHT_1_MOVE; + break; + case M_LIGHT_RGBALL_LIGHT_1: + // Do stuff + break; + case M_LIGHT_MOVE_LIGHT_2: + manipulateState = STATE_LIGHT_2_MOVE; + break; -void processMainEvents(int id) { - switch (id) { - case EXIT: - exit(0); + case M_LIGHT_RGBALL_LIGHT_2: + // Do stuff + break; } } +/** + * Event hander for object menu events + * @param id ID of object selected + */ void processObjectEvents(int id) { - -} - -void processMaterialEvents(int id) { - + addSceneObject(id); + manipulateState = STATE_OBJECT_POSITION_SCALE; + glutPostRedisplay(); } +/** + * Event hander for texture menu events + * @param id ID of texutre selected + */ void processTextureEvents(int id) { - + if ( curObject >= 0 ) { + sceneObjs[curObject].texture.id = id; + sceneObjs[curObject].texture.scale = 1; + glutPostRedisplay(); + } } +/** + * Event hander for ground texture menu events + * @param id ID of ground texture selected + */ void processGTextureEvents(int id) { - + currentGroundTexture = id; + glutPostRedisplay(); } -void processLightEvents(int id) { +/** + * Creates menu for program + */ +void makeMenu() { + // Construct material menu + int materialMenu = glutCreateMenu(processMaterialEvents); + glutAddMenuEntry("All R/G/B", M_MATERIAL_ALL_RGB); + glutAddMenuEntry("Ambient R/G/B", M_MATERIAL_AMBIENT_RGB); + glutAddMenuEntry("Diffuse R/G/B", M_MATERIAL_DIFFUSE_RGB); + glutAddMenuEntry("Specular R/G/B", M_MATERIAL_SPECULAR_RGB); + glutAddMenuEntry("All Amb/Diff/Spec/Shine", M_MATERIAL_ALL_ADSS); + glutAddMenuEntry("Red Amb/Diff/Spec/Shine", M_MATERIAL_RED_ADSS); + glutAddMenuEntry("Green Amb/Diff/Spec/Shine", M_MATERIAL_GREEN_ADSS); + glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", M_MATERIAL_BLUE_ADSS); + + // Construct light menu + int lightMenu = glutCreateMenu(processLightEvents); + glutAddMenuEntry("Move Light 1", M_LIGHT_MOVE_LIGHT_1); + //glutAddMenuEntry("R/G/B/All Light 1", M_LIGHT_RGBALL_LIGHT_1); + glutAddMenuEntry("Move Light 2", M_LIGHT_MOVE_LIGHT_2); + //glutAddMenuEntry("R/G/B/All Light 2", M_LIGHT_RGBALL_LIGHT_2); + + // Construct object menu + int objectMenu = makeSubmenuFromArray( objectMenuEntries, NMESH, processObjectEvents ); + + // Construct texture / ground texture menus + int textureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processTextureEvents ); + int gTextureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processGTextureEvents ); + + // Construct main menu + glutCreateMenu(processMainEvents); + glutAddMenuEntry("Rotate/Move Camera", M_ROTATE_MOVE_CAMERA); + glutAddSubMenu("Add object", objectMenu); + glutAddMenuEntry("Position/Scale", M_POSITION_SCALE); + glutAddMenuEntry("Rotation/Texture Scale", M_ROTATION_TEXTURE_SCALE); + //glutAddSubMenu("Material", materialMenu); + glutAddSubMenu("Texture", textureMenu); + glutAddSubMenu("Ground texture", gTextureMenu); + glutAddSubMenu("Lights", lightMenu); + glutAddMenuEntry("Exit", M_EXIT); + + // Bind to right mouse button + glutAttachMenu(GLUT_RIGHT_BUTTON); +} +/** + * Called when window is resized + * @param w New width + * @param h New height + */ +void windowReshape(int w, int h) { + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + width = w; + height = h; } -int makeSubmenuFromArray( const char *menuEntries[], void *callback ) { - int menuEntriesSize = sizeof(menuEntries) / sizeof(menuEntries[0]); - int menuNumber = menuEntriesSize / 10 + 1; - int submenuObjects[menuNumber-1]; - - for( int i = 0; i < menuNumber; i++ ) { - submenuObjects[i] = glutCreateMenu(callback); - int startNum = i*11 - (i-1); - for ( int j = startNum - 1; j < (startNum+9); j++ ) { - if ( j == menuEntriesSize ) break; // Detect if we've reached the end of the array - glutAddMenuEntry( menuEntries[j], j ); - } +/** + * Called when mouse event occurs + * @param btn Mouse button + * @param state State of mouse button + * @param x Mouse x position + * @param y Mouse y position + */ +void mouse(int button, int state, int x, int y) { + if ( button == GLUT_LEFT_BUTTON && glutGetModifiers() == GLUT_ACTIVE_SHIFT ) { + button = GLUT_MIDDLE_BUTTON; // Holding shift with left button is the same as the middle button } - - int mainMenu = glutCreateMenu(callback); - for ( int i = 0; i < menuNumber; i++ ) { - char name[10]; // buffer to hold name - int startNum = i*11 - (i-1); - int endNum = startNum + 9; - if ( i == menuNumber - 1 ) { // We're on the last one - endNum = startNum + 3; - } - sprintf(name, "%d-%d", startNum, endNum); - glutAddSubMenu( name, submenuObjects[i] ); + switch(button) { + case GLUT_LEFT_BUTTON: + case GLUT_MIDDLE_BUTTON: + if ( state == GLUT_DOWN ) { + buttonSelected = button; + } else if ( state == GLUT_UP ) { + buttonSelected = -1; + } + startx = x; + starty = y; + break; } - - return mainMenu; } -void makeMenu() { - // Construct material menu - int materialMenu = glutCreateMenu(processMaterialEvents); - glutAddMenuEntry("All R/G/B", MATERIAL_ALL_RGB); - glutAddMenuEntry("Ambient R/G/B", MATERIAL_AMBIENT_RGB); - glutAddMenuEntry("Diffuse R/G/B", MATERIAL_DIFFUSE_RGB); - glutAddMenuEntry("Specular R/G/B", MATERIAL_SPECULAR_RGB); - glutAddMenuEntry("All Amb/Diff/Spec/Shine", MATERIAL_ALL_ADSS); - glutAddMenuEntry("Red Amb/Diff/Spec/Shine", MATERIAL_RED_ADSS); - glutAddMenuEntry("Green Amb/Diff/Spec/Shine", MATERIAL_GREEN_ADSS); - glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", MATERIAL_BLUE_ADSS); +/** + * Called when motion event occurs + * @param x Mouse x position + * @param y Mouse y position + */ +void motion(int x, int y) { + if ( buttonSelected == -1 ) return; // No button selected, no action + + float diffx = x - startx; + float diffy = y - starty; + + switch ( manipulateState ) { + case STATE_CAMERA_ROTATE_MOVE: + // w: rotate + rotate += diffx; + + if ( buttonSelected == GLUT_LEFT_BUTTON ) { + // h: zoom + zoom += diffy; + } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) { + // h: tilt + camAngle += diffy; + } + break; + + case STATE_OBJECT_POSITION_SCALE: + + if ( buttonSelected == GLUT_LEFT_BUTTON ) { + // w: left/right, h: near/far + float angler = 2 * M_PI * ( (rotate*camRotateFactor)/360.0 ); + sceneObjs[curObject].x += diffx * cos(angler) * leftrightFactor + diffy * cos(M_PI/2 + angler) * nearfarFactor; + sceneObjs[curObject].z += diffx * sin(angler) * leftrightFactor + diffy * sin(M_PI/2 + angler) * nearfarFactor; + + } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) { + // w: big/small + float max = (float)height/bigsmallFactor; + float scaling = (diffx + max) / max; + + sceneObjs[curObject].scale[0] *= scaling; + sceneObjs[curObject].scale[1] *= scaling; + sceneObjs[curObject].scale[2] *= scaling; + + // h: up/down + sceneObjs[curObject].y -= diffy * updownFactor; + } + + break; + + case STATE_OBJECT_ROTATION_TEXTURE_SCALE: + + if ( buttonSelected == GLUT_LEFT_BUTTON ) { + // w: rotate on y + sceneObjs[curObject].rotation.y += diffx * rotateFactor; + + // h: rotate on x + sceneObjs[curObject].rotation.x += diffy * rotateFactor; + + } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) { + // w: rotate on x + sceneObjs[curObject].rotation.x += diffx * rotateFactor; + + // h: texture scale + // **NOTE: Seems to be problem with scaling, delayed action + float max = (float)height/texscaleFactor; + float scaling = (-diffy + max) / max; + sceneObjs[curObject].texture.scale *= scaling; + + } + + break; + + case STATE_LIGHT_1_MOVE: + case STATE_LIGHT_2_MOVE: + ; // Semi-colon required to allow variable declaration below + + int i = 0; + if ( manipulateState == STATE_LIGHT_2_MOVE ) i = 1; + + if ( buttonSelected == GLUT_LEFT_BUTTON ) { + // w: left/right, h: near/far + float angler = 2 * M_PI * ( (rotate*camRotateFactor)/360.0 ); + lightObjs[i].position[0] += diffx * cos(angler) * lleftrightFactor + diffy * cos(M_PI/2 + angler) * lnearfarFactor; + lightObjs[i].position[2] += diffx * sin(angler) * lleftrightFactor + diffy * sin(M_PI/2 + angler) * lnearfarFactor; + + } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) { + // w: increase/decrease some light param + // **NOTE: Currently not implemented + + // h: up/down + lightObjs[i].position[1] -= diffy * updownFactor; + } + + break; - // Construct light menu - int lightMenu = glutCreateMenu(processLightEvents); - glutAddMenuEntry("Move Light 1", LIGHT_MOVE_LIGHT_1); - glutAddMenuEntry("R/G/B/All Light 1", LIGHT_RGBALL_LIGHT_1); - glutAddMenuEntry("Move Light 2", LIGHT_MOVE_LIGHT_2); - glutAddMenuEntry("R/G/B/All Light 2", LIGHT_RGBALL_LIGHT_2); - - // Construct add object submenus - int addObjectMenu = makeSubmenuFromArray( &objectMenuEntries, processObjectEvents ); - - // Construct texture/ground texture submenus -/* int textureMenuEntries = sizeof(textureMenuEntries) / sizeof(textureMenuEntries[0]); - int menuNumber = textureMenuEntries / 10 + 1; - int textureSubmenu[menuNumber-1]; - - for( int i = 0; i < menuNumber; i++ ) { - textureSubmenu[i] = glutCreateMenu(processTextureEvents); - int startNum = i*11 - (i-1); - for ( int j = startNum - 1; j < (startNum+9); j++ ) { - if ( j == objectMenuEntriesSize ) break; // Detect if we've reached the end of the array - glutAddMenuEntry( objectMenuEntries[j], j ); - } - }*/ + } + starty = y; + startx = x; - int mainMenu = glutCreateMenu(processMainEvents); + glutPostRedisplay(); +} - glutAddMenuEntry("Rotate/Move Camera", ROTATE_MOVE_CAMERA); - glutAddSubMenu("Add object", addObjectMenu); - glutAddMenuEntry("Position/Scale", POSITION_SCALE); - glutAddMenuEntry("Rotation/Texture Scale", ROTATION_TEXTURE_SCALE); - //material - +/** + * Display function + */ +void display() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Redraw projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + float aspect; + if ( width <= height ) { + aspect = (float)height / (float)width; + } else { + aspect = (float)width / (float)height; + } - glutSetMenu(mainMenu); - glutAddSubMenu("Material", materialMenu); - - //texture - //ground texture - //lights + gluPerspective( + 75.0, + aspect, + 0.1, + 300 + ); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glutAddMenuEntry("Exit", EXIT); + gluLookAt( + 0.0, 0.0, 15.0 + (zoom*zoomFactor), /* eye is at (x,y,z) */ + 0.0, 0.0, 0.0, /* center is at (x,y,z) */ + 0.0, 10.0, 0.0 /* up is in postivie Y direction */ + ); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} + glRotatef(camAngle*camAngleFactor, 1.0, 0.0, 0.0); // Set camera angle upward -void display() { - // You probably want to change both of the following. - glClear(GL_COLOR_BUFFER_BIT); - glFlush(); -} + glPushMatrix(); -char *dirDefault1 = "models-textures"; -char *dirDefault2 = "/cslinux/examples/CITS2231/project-files/models-textures"; -int main(int argc, char **argv) { + /* Perform scene rotations based on user mouse input. */ + glRotatef(rotate*camRotateFactor, 0.0, 1.0, 0.0); - if(argc>1) - strcpy(dataDir, argv[1]); - else if(opendir(dirDefault1)) - strcpy(dataDir, dirDefault1); - else if(opendir(dirDefault2)) - strcpy(dataDir, dirDefault2); - else fileErr(dirDefault1); + drawFloor(); + + // Draw sceneObjs array + for ( int i = 0; i < nObjects; i++ ) { + glPushMatrix(); + SceneObject so = sceneObjs[i]; + + // Apply translation vector + glTranslatef(so.x, so.y, so.z); + + // Apply independant rotation vectors + glRotatef(so.rotation.x, 1.0, 0.0, 0.0); + glRotatef(so.rotation.y, 0.0, 1.0, 0.0); + glRotatef(so.rotation.z, 0.0, 0.0, 1.0); + + // Apply scaling vector + glScalef(so.scale[0], so.scale[1], so.scale[2]); + + // Apply texture + if ( so.texture.id > 0 ) { + getTexture(so.texture.id); + glBindTexture(GL_TEXTURE_2D, so.texture.id); + glMatrixMode(GL_TEXTURE); + glScalef(so.texture.scale, so.texture.scale, so.texture.scale); + glMatrixMode(GL_MODELVIEW); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + } + + // Draw actual object + if ( so.mesh > 0 ) { + // drawMesh(); + } else if ( so.mesh == -1 ) { // a mesh of -1 draws the teapot + // The teapot does not obey the right-hand rule + glFrontFace(GL_CW); + glutSolidTeapot(1); + glFrontFace(GL_CCW); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glPopMatrix(); + } - for(int i=0; i1) + strcpy(dataDir, argv[1]); + else if(opendir(dirDefault1)) + strcpy(dataDir, dirDefault1); + else if(opendir(dirDefault2)) + strcpy(dataDir, dirDefault2); + else fileErr(dirDefault1); + + for(int i=0; i