Advertisement
Guest User

?

a guest
May 22nd, 2019
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include "Angel.h"
  3.  
  4. #include <stdlib.h>
  5. #include <dirent.h>
  6. #include <time.h>
  7.  
  8. // Open Asset Importer header files (in ../../assimp--3.0.1270/include)
  9. // This is a standard open source library for loading meshes, see gnatidread.h
  10. #include <assimp/cimport.h>
  11. #include <assimp/scene.h>
  12. #include <assimp/postprocess.h>
  13.  
  14. GLint windowHeight=640, windowWidth=960;
  15.  
  16. // gnatidread.cpp is the CITS3003 "Graphics n Animation Tool Interface & Data
  17. // Reader" code.  This file contains parts of the code that you shouldn't need
  18. // to modify (but, you can).
  19. #include "gnatidread.h"
  20. #include "gnatidread2.h"
  21.  
  22. using namespace std;        // Import the C++ standard functions (e.g., min)
  23.  
  24.  
  25. // IDs for the GLSL program and GLSL variables.
  26. GLuint shaderProgram; // The number identifying the GLSL shader program
  27. GLuint vPosition, vNormal, vTexCoord; // IDs for vshader input vars (from glGetAttribLocation)
  28. GLuint projectionU, modelViewU; // IDs for uniform variables (from glGetUniformLocation)
  29. GLuint vBoneIDs, vBoneWeights, uBoneTransforms;
  30. //GLuint timeParam;
  31.  
  32. static float viewDist = 1.5; // Distance from the camera to the centre of the scene
  33. static float camRotSidewaysDeg=0; // rotates the camera sideways around the centre
  34. static float camRotUpAndOverDeg=20; // rotates the camera up and over the centre.
  35.  
  36. mat4 projection; // Projection matrix - set in the reshape function
  37. mat4 view; // View matrix - set in the display function.
  38.  
  39. // These are used to set the window title
  40. char lab[] = "Project1";
  41. char *programName = NULL; // Set in main
  42. int numDisplayCalls = 0; // Used to calculate the number of frames per second
  43.  
  44. //------Meshes----------------------------------------------------------------
  45. // Uses the type aiMesh from ../../assimp--3.0.1270/include/assimp/mesh.h
  46. //                           (numMeshes is defined in gnatidread.h)
  47. aiMesh* meshes[numMeshes]; // For each mesh we have a pointer to the mesh to draw
  48. const aiScene* scenes[numMeshes];
  49. GLuint vaoIDs[numMeshes]; // and a corresponding VAO ID from glGenVertexArrays
  50.  
  51.  
  52. // -----Textures--------------------------------------------------------------
  53. //                           (numTextures is defined in gnatidread.h)
  54. texture* textures[numTextures]; // An array of texture pointers - see gnatidread.h
  55. GLuint textureIDs[numTextures]; // Stores the IDs returned by glGenTextures
  56.  
  57. //------Scene Objects---------------------------------------------------------
  58. //
  59. // For each object in a scene we store the following
  60. // Note: the following is exactly what the sample solution uses, you can do things differently if you want.
  61. typedef struct {
  62.     vec4 loc;
  63.     float scale;
  64.     float angles[3]; // rotations around X, Y and Z axes.
  65.     float diffuse, specular, ambient; // Amount of each light component
  66.     float shine;
  67.     vec3 rgb;
  68.     float brightness; // Multiplies all colours
  69.     int meshId;
  70.     int texId;
  71.     float texScale;
  72. } SceneObject;
  73.  
  74. const int maxObjects = 1024; // Scenes with more than 1024 objects seem unlikely
  75.  
  76. SceneObject sceneObjs[maxObjects]; // An array storing the objects currently in the scene.
  77. int nObjects = 0;    // How many objects are currenly in the scene.
  78. int currObject = -1; // The current object
  79. int toolObj = -1;    // The object currently being modified
  80.  
  81. //----------------------------------------------------------------------------
  82. //
  83. // Loads a texture by number, and binds it for later use.    
  84. void loadTextureIfNotAlreadyLoaded(int i)
  85. {
  86.     if (textures[i] != NULL) return; // The texture is already loaded.
  87.  
  88.     textures[i] = loadTextureNum(i); CheckError();
  89.     glActiveTexture(GL_TEXTURE0); CheckError();
  90.  
  91.     // Based on: http://www.opengl.org/wiki/Common_Mistakes
  92.     glBindTexture(GL_TEXTURE_2D, textureIDs[i]); CheckError();
  93.  
  94.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textures[i]->width, textures[i]->height,
  95.                  0, GL_RGB, GL_UNSIGNED_BYTE, textures[i]->rgbData); CheckError();
  96.     glGenerateMipmap(GL_TEXTURE_2D); CheckError();
  97.  
  98.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); CheckError();
  99.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); CheckError();
  100.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); CheckError();
  101.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); CheckError();
  102.  
  103.     glBindTexture(GL_TEXTURE_2D, 0); CheckError(); // Back to default texture
  104. }
  105.  
  106. //------Mesh loading----------------------------------------------------------
  107. //
  108. // The following uses the Open Asset Importer library via loadMesh in
  109. // gnatidread.h to load models in .x format, including vertex positions,
  110. // normals, and texture coordinates.
  111. // You shouldn't need to modify this - it's called from drawMesh below.
  112.  
  113. void loadMeshIfNotAlreadyLoaded(int meshNumber)
  114. {
  115.     if (meshNumber>=numMeshes || meshNumber < 0) {
  116.         printf("Error - no such model number");
  117.         exit(1);
  118.     }
  119.  
  120.     if (meshes[meshNumber] != NULL)
  121.         return; // Already loaded
  122.  
  123.     const aiScene* scene = loadScene(meshNumber);
  124.     scenes[meshNumber] = scene;
  125.     aiMesh* mesh = scene->mMeshes[0];
  126.     meshes[meshNumber] = mesh;;
  127.  
  128.     glBindVertexArrayAPPLE( vaoIDs[meshNumber] );
  129.  
  130.     // Create and initialize a buffer object for positions and texture coordinates, initially empty.
  131.     // mesh->mTextureCoords[0] has space for up to 3 dimensions, but we only need 2.
  132.     GLuint buffer[1];
  133.     glGenBuffers( 1, buffer );
  134.     glBindBuffer( GL_ARRAY_BUFFER, buffer[0] );
  135.     glBufferData( GL_ARRAY_BUFFER, sizeof(float)*(3+3+3)*mesh->mNumVertices, NULL, GL_STATIC_DRAW );
  136.  
  137.     int nVerts = mesh->mNumVertices;
  138.     // Next, we load the position and texCoord data in parts.    
  139.     glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(float)*3*nVerts, mesh->mVertices );
  140.     glBufferSubData( GL_ARRAY_BUFFER, sizeof(float)*3*nVerts, sizeof(float)*3*nVerts, mesh->mTextureCoords[0] );
  141.     glBufferSubData( GL_ARRAY_BUFFER, sizeof(float)*6*nVerts, sizeof(float)*3*nVerts, mesh->mNormals);
  142.  
  143. //////////////////////////////////////////////////////////////////////////////////////
  144. //  GLuint buffer[2];
  145. //    glGenBuffers( 2, buffer );
  146. //    glBindBuffer( GL_ARRAY_BUFFER, buffer[0] );
  147. //    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW );
  148. //    GLuint vPosition = glGetAttribLocation( program, "vPosition" );
  149. //    glEnableVertexAttribArray( vPosition );
  150. //    glVertexAttribPointer( vPosition, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
  151. //////////////////////////////////////////////////////////////////////////////////////
  152.  
  153.     // Load the element index data
  154.     GLuint elements[mesh->mNumFaces*3];
  155.     for (GLuint i=0; i < mesh->mNumFaces; i++) {
  156.         elements[i*3] = mesh->mFaces[i].mIndices[0];
  157.         elements[i*3+1] = mesh->mFaces[i].mIndices[1];
  158.         elements[i*3+2] = mesh->mFaces[i].mIndices[2];
  159.     }
  160.  
  161.     GLuint elementBufferId[1];
  162.     glGenBuffers(1, elementBufferId);
  163.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferId[0]);
  164.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * mesh->mNumFaces * 3, elements, GL_STATIC_DRAW);
  165.  
  166.     // vPosition it actually 4D - the conversion sets the fourth dimension (i.e. w) to 1.0                
  167.     glVertexAttribPointer( vPosition, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
  168.     glEnableVertexAttribArray( vPosition );
  169.  
  170.     // vTexCoord is actually 2D - the third dimension is ignored (it's always 0.0)
  171.     glVertexAttribPointer( vTexCoord, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*3*mesh->mNumVertices) );
  172.     glEnableVertexAttribArray( vTexCoord );
  173.  
  174.     glVertexAttribPointer( vNormal,   3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(float)*6*mesh->mNumVertices) );
  175.     glEnableVertexAttribArray( vNormal );
  176.     CheckError();
  177.  
  178.     //**************
  179.     // Get boneIDs and boneWeights for each vertex from the imported mesh data
  180.     GLint boneIDs[mesh->mNumVertices][4];
  181.     GLfloat boneWeights[mesh->mNumVertices][4];
  182.     getBonesAffectingEachVertex(mesh, boneIDs, boneWeights);
  183.  
  184.     GLuint buffers[2];
  185.     glGenBuffers( 2, buffers );  // Add two vertex buffer objects
  186.    
  187.     glBindBuffer( GL_ARRAY_BUFFER, buffers[0] ); CheckError();
  188.     glBufferData( GL_ARRAY_BUFFER, sizeof(int)*4*mesh->mNumVertices, boneIDs, GL_STATIC_DRAW ); CheckError();
  189.     glVertexAttribPointer(vBoneIDs, 4, GL_INT, GL_FALSE, 0, BUFFER_OFFSET(0)); CheckError();
  190.     glEnableVertexAttribArray(vBoneIDs);     CheckError();
  191.    
  192.     glBindBuffer( GL_ARRAY_BUFFER, buffers[1] );
  193.     glBufferData( GL_ARRAY_BUFFER, sizeof(float)*4*mesh->mNumVertices, boneWeights, GL_STATIC_DRAW );
  194.     glVertexAttribPointer(vBoneWeights, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
  195.     glEnableVertexAttribArray(vBoneWeights);    CheckError();
  196.     //**************
  197.    
  198. }
  199.  
  200. //----------------------------------------------------------------------------
  201.  
  202. static void mouseClickOrScroll(int button, int state, int x, int y)
  203. {
  204.     if (button==GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  205.         if (glutGetModifiers()!=GLUT_ACTIVE_SHIFT) activateTool(button);
  206.         else activateTool(GLUT_LEFT_BUTTON);
  207.     }
  208.     else if (button==GLUT_LEFT_BUTTON && state == GLUT_UP) deactivateTool();
  209.     else if (button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) { activateTool(button); }
  210.     else if (button==GLUT_MIDDLE_BUTTON && state==GLUT_UP) deactivateTool();
  211.  
  212.     else if (button == 3) { // scroll up
  213.         viewDist = (viewDist < 0.0 ? viewDist : viewDist*0.8) - 0.05; // ?: is a ternary operator.. syntax ... condition ? if_true : if_false
  214.     }
  215.     else if (button == 4) { // scroll down
  216.         viewDist = (viewDist < 0.0 ? viewDist : viewDist*1.25) + 0.05;
  217.     }
  218. }
  219.  
  220. //----------------------------------------------------------------------------
  221.  
  222. static void mousePassiveMotion(int x, int y)
  223. {
  224.     mouseX=x;
  225.     mouseY=y;
  226. }
  227.  
  228. //----------------------------------------------------------------------------
  229.  
  230. mat2 camRotZ()
  231. {
  232.     return rotZ(-camRotSidewaysDeg) * mat2(10.0, 0, 0, -10.0);
  233. }
  234.  
  235. //------callback functions for doRotate below and later-----------------------
  236.  
  237. static void adjustCamrotsideViewdist(vec2 cv)
  238. {
  239.     cout << cv << endl;
  240.     camRotSidewaysDeg+=cv[0]; viewDist+=cv[1];
  241. }
  242.  
  243. static void adjustcamSideUp(vec2 su)
  244. {
  245.     camRotSidewaysDeg+=su[0]; camRotUpAndOverDeg+=su[1];
  246. }
  247.    
  248. static void adjustLocXZ(vec2 xz)
  249. {
  250.     sceneObjs[toolObj].loc[0]+=xz[0]; sceneObjs[toolObj].loc[2]+=xz[1];
  251. }
  252.  
  253. static void adjustScaleY(vec2 sy)
  254. {
  255.     sceneObjs[toolObj].scale+=sy[0]; sceneObjs[toolObj].loc[1]+=sy[1];
  256. }
  257.  
  258.  
  259. //----------------------------------------------------------------------------
  260. //------Set the mouse buttons to rotate the camera----------------------------
  261. //------around the centre of the scene.---------------------------------------
  262. //----------------------------------------------------------------------------
  263.  
  264. static void doRotate()
  265. {
  266.     setToolCallbacks(adjustCamrotsideViewdist, mat2(400,0,0,-2),
  267.                      adjustcamSideUp, mat2(400, 0, 0,-90) );
  268. }
  269.                                      
  270. //------Add an object to the scene--------------------------------------------
  271.  
  272. static void addObject(int id)
  273. {
  274.  
  275.     vec2 currPos = currMouseXYworld(camRotSidewaysDeg);
  276.     sceneObjs[nObjects].loc[0] = currPos[0];
  277.     sceneObjs[nObjects].loc[1] = 0.0;
  278.     sceneObjs[nObjects].loc[2] = currPos[1];
  279.     sceneObjs[nObjects].loc[3] = 1.0;
  280.  
  281.     if (id!=0 && id!=55)
  282.         sceneObjs[nObjects].scale = 0.005;
  283.  
  284.     sceneObjs[nObjects].rgb[0] = 0.7; sceneObjs[nObjects].rgb[1] = 0.7;
  285.     sceneObjs[nObjects].rgb[2] = 0.7; sceneObjs[nObjects].brightness = 1.0;
  286.  
  287.     sceneObjs[nObjects].diffuse = 1.0; sceneObjs[nObjects].specular = 0.5;
  288.     sceneObjs[nObjects].ambient = 0.7; sceneObjs[nObjects].shine = 10.0;
  289.  
  290.     sceneObjs[nObjects].angles[0] = 0.0; sceneObjs[nObjects].angles[1] = 180.0;
  291.     sceneObjs[nObjects].angles[2] = 0.0;
  292.  
  293.     sceneObjs[nObjects].meshId = id;
  294.     sceneObjs[nObjects].texId = rand() % numTextures;
  295.     sceneObjs[nObjects].texScale = 2.0;
  296.  
  297.     toolObj = currObject = nObjects++;
  298.     setToolCallbacks(adjustLocXZ, camRotZ(),
  299.                      adjustScaleY, mat2(0.05, 0, 0, 10.0) );
  300.     glutPostRedisplay();
  301. }
  302.  
  303. //------The init function-----------------------------------------------------
  304.  
  305. void init( void )
  306. {
  307.     srand ( time(NULL) ); /* initialize random seed - so the starting scene varies */
  308.     aiInit();
  309.     //timeParam = glGetUniformLocation(program, "time");
  310.  
  311.  
  312.     // for (int i=0; i < numMeshes; i++)
  313.     //     meshes[i] = NULL;
  314.  
  315.     glGenVertexArraysAPPLE(numMeshes, vaoIDs); CheckError(); // Allocate vertex array objects for meshes
  316.     glGenTextures(numTextures, textureIDs); CheckError(); // Allocate texture objects
  317.  
  318.     // Load shaders and use the resulting shader program
  319.     shaderProgram = InitShader( "vStart.glsl", "fStart.glsl" );
  320.  
  321.     glUseProgram( shaderProgram ); CheckError();
  322.  
  323.     // Initialize the vertex position attribute from the vertex shader        
  324.     vPosition = glGetAttribLocation( shaderProgram, "vPosition" );
  325.     vNormal = glGetAttribLocation( shaderProgram, "vNormal" ); CheckError();
  326.  
  327.     // Likewise, initialize the vertex texture coordinates attribute.    
  328.     vTexCoord = glGetAttribLocation( shaderProgram, "vTexCoord" );
  329.     CheckError();
  330.  
  331.     projectionU = glGetUniformLocation(shaderProgram, "Projection");
  332.     modelViewU = glGetUniformLocation(shaderProgram, "ModelView");
  333.  
  334.     // Objects 0, and 1 are the ground and the first light.
  335.     addObject(0); // Square for the ground
  336.     sceneObjs[0].loc = vec4(0.0, 0.0, 0.0, 1.0);
  337.     sceneObjs[0].scale = 10.0;
  338.     sceneObjs[0].angles[0] = 90.0; // Rotate it.
  339.     sceneObjs[0].texScale = 5.0; // Repeat the texture.
  340.  
  341.     addObject(55); // Sphere for the first light
  342.     sceneObjs[1].loc = vec4(2.0, 1.0, 1.0, 1.0);
  343.     sceneObjs[1].scale = 0.1;
  344.     sceneObjs[1].texId = 0; // Plain texture
  345.     sceneObjs[1].brightness = 0.2; // The light's brightness is 5 times this (below).
  346.  
  347.     addObject(rand() % numMeshes); // A test mesh
  348.  
  349.     // We need to enable the depth test to discard fragments that
  350.     // are behind previously drawn fragments for the same pixel.
  351.     glEnable( GL_DEPTH_TEST );
  352.     doRotate(); // Start in camera rotate mode.
  353.     glClearColor( 0.0, 0.0, 0.0, 1.0 ); /* black background */
  354. }
  355.  
  356. //----------------------------------------------------------------------------
  357.  
  358. void drawMesh(SceneObject sceneObj)
  359. {
  360.  
  361.     // Activate a texture, loading if needed.
  362.     loadTextureIfNotAlreadyLoaded(sceneObj.texId);
  363.     glActiveTexture(GL_TEXTURE0 );
  364.     glBindTexture(GL_TEXTURE_2D, textureIDs[sceneObj.texId]);
  365.  
  366.     // Texture 0 is the only texture type in this program, and is for the rgb
  367.     // colour of the surface but there could be separate types for, e.g.,
  368.     // specularity and normals.
  369.     glUniform1i( glGetUniformLocation(shaderProgram, "texture"), 0 );
  370.  
  371.     float texscale = sceneObj.texScale;
  372.     sceneObj.texScale = texscale*camRotUpAndOverDeg;
  373.  
  374.     // Set the texture scale for the shaders
  375.     glUniform1f( glGetUniformLocation( shaderProgram, "texScale"), sceneObj.texScale);
  376.  
  377.     // Set the projection matrix for the shaders
  378.     glUniformMatrix4fv( projectionU, 1, GL_TRUE, projection );
  379.  
  380.     // Set the model matrix - this should combine translation, rotation and scaling based on what's
  381.     // in the sceneObj structure (see near the top of the program).
  382.  
  383.     mat4 model = Translate(sceneObj.loc) * Scale(sceneObj.scale)*RotateX(-sceneObj.angles[0])*RotateY(sceneObj.angles[1])*RotateZ(sceneObj.angles[2]);
  384.  
  385.  
  386.     // Set the model-view matrix for the shaders
  387.     glUniformMatrix4fv( modelViewU, 1, GL_TRUE, view * model );
  388.  
  389.     // Activate the VAO for a mesh, loading if needed.
  390.     loadMeshIfNotAlreadyLoaded(sceneObj.meshId);
  391.     CheckError();
  392.     glBindVertexArrayAPPLE( vaoIDs[sceneObj.meshId] );
  393.     CheckError();
  394.  
  395.     //*************
  396.  
  397.     int nBones = meshes[sceneObj.meshId]->mNumBones;
  398.     if(nBones == 0)
  399.         // If no bones, just a single identity matrix is used
  400.         nBones = 1;
  401.  
  402.     // get boneTransforms for the first (0th) animation at the given
  403.     // time (a float measured in frames)
  404.     // (Replace <POSE_TIME> appropriately with a float expression
  405.     // giving the time relative to the start of the animation,
  406.     // measured in frames, like the frame numbers in Blender.)
  407.  
  408.     mat4 boneTransforms[nBones];     // was: mat4 boneTransforms[mesh->mNumBones];
  409.     //calculateAnimPose(meshes[sceneObj.meshId], scenes[sceneObj.meshId], 0,
  410.     //                  <POSE_TIME>, boneTransforms);
  411.     glUniformMatrix4fv(uBoneTransforms, nBones, GL_TRUE,
  412.                       (const GLfloat *)boneTransforms);
  413.     //glUniform1f( timeParam, glutGet(GLUT_ELAPSED_TIME) );
  414.     //**************
  415.  
  416.     glDrawElements(GL_TRIANGLES, meshes[sceneObj.meshId]->mNumFaces * 3,
  417.                    GL_UNSIGNED_INT, NULL);
  418.     CheckError();
  419. }
  420.  
  421. //----------------------------------------------------------------------------
  422.  
  423. void display( void )
  424. {
  425.     numDisplayCalls++;
  426.  
  427.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  428.     CheckError(); // May report a harmless GL_INVALID_OPERATION with GLEW on the first frame
  429.  
  430.     // Set the view matrix.  To start with this just moves the camera
  431.     // backwards.  You'll need to add appropriate rotations.
  432.  
  433.     view = Translate(0.0, 0.0, -viewDist)*RotateX(camRotUpAndOverDeg)*RotateY(camRotSidewaysDeg);
  434.  
  435.     SceneObject lightObj1 = sceneObjs[1];
  436.     vec4 lightPosition = view * lightObj1.loc ;
  437.  
  438.     glUniform4fv( glGetUniformLocation(shaderProgram, "LightPosition"),
  439.                   1, lightPosition);
  440.     CheckError();
  441.  
  442.     for (int i=0; i < nObjects; i++) {
  443.         SceneObject so = sceneObjs[i];
  444.  
  445.         vec3 rgb = so.rgb * lightObj1.rgb * so.brightness * lightObj1.brightness * 2.0;
  446.         glUniform3fv( glGetUniformLocation(shaderProgram, "AmbientProduct"), 1, so.ambient * rgb );
  447.         CheckError();
  448.         glUniform3fv( glGetUniformLocation(shaderProgram, "DiffuseProduct"), 1, so.diffuse * rgb );
  449.         glUniform3fv( glGetUniformLocation(shaderProgram, "SpecularProduct"), 1, so.specular * rgb );
  450.         glUniform1f( glGetUniformLocation(shaderProgram, "Shininess"), so.shine );
  451.         CheckError();
  452.  
  453.         drawMesh(sceneObjs[i]);
  454.     }
  455.  
  456.  
  457.     glutSwapBuffers();
  458. }
  459.  
  460. //----------------------------------------------------------------------------
  461. //------Menus-----------------------------------------------------------------
  462. //----------------------------------------------------------------------------
  463.  
  464. static void objectMenu(int id)
  465. {
  466.     deactivateTool();
  467.     addObject(id);
  468. }
  469.  
  470. static void texMenu(int id)
  471. {
  472.     deactivateTool();
  473.     if (currObject>=0) {
  474.         sceneObjs[currObject].texId = id;
  475.         glutPostRedisplay();
  476.     }
  477. }
  478.  
  479. static void groundMenu(int id)
  480. {
  481.     deactivateTool();
  482.     sceneObjs[0].texId = id;
  483.     glutPostRedisplay();
  484. }
  485.  
  486. static void adjustBrightnessY(vec2 by)
  487. {
  488.     sceneObjs[toolObj].brightness+=by[0];
  489.     sceneObjs[toolObj].loc[1]+=by[1];
  490. }
  491.  
  492. static void adjustRedGreen(vec2 rg)
  493. {
  494.     sceneObjs[toolObj].rgb[0]+=rg[0];
  495.     sceneObjs[toolObj].rgb[1]+=rg[1];
  496. }
  497.  
  498. static void adjustBlueBrightness(vec2 bl_br)
  499. {
  500.     sceneObjs[toolObj].rgb[2]+=bl_br[0];
  501.     sceneObjs[toolObj].brightness+=bl_br[1];
  502. }
  503.  
  504. static void adjustAmbientDiffuse (vec2 ad)
  505. {
  506.     sceneObjs[toolObj].ambient+=ad[0];
  507.     sceneObjs[toolObj].diffuse+=ad[1];
  508. }
  509.  
  510. static void adjustSpecularShine (vec2 ss)
  511. {
  512.     sceneObjs[toolObj].specular+=ss[0];
  513.     sceneObjs[toolObj].shine+=ss[1];
  514. }
  515.  
  516. static void lightMenu(int id)
  517. {
  518.     deactivateTool();
  519.     if (id == 70) {
  520.         toolObj = 1;
  521.         setToolCallbacks(adjustLocXZ, camRotZ(),
  522.                          adjustBrightnessY, mat2( 1.0, 0.0, 0.0, 10.0) );
  523.  
  524.     }
  525.     else if (id >= 71 && id <= 74) {
  526.         toolObj = 1;
  527.         setToolCallbacks(adjustRedGreen, mat2(1.0, 0, 0, 1.0),
  528.                          adjustBlueBrightness, mat2(1.0, 0, 0, 1.0) );
  529.     }
  530.     else {
  531.         printf("Error in lightMenu\n");
  532.         exit(1);
  533.     }
  534. }
  535.  
  536. static int createArrayMenu(int size, const char menuEntries[][128], void(*menuFn)(int))
  537. {
  538.     int nSubMenus = (size-1)/10 + 1;
  539.     int subMenus[nSubMenus];
  540.  
  541.     for (int i=0; i < nSubMenus; i++) {
  542.         subMenus[i] = glutCreateMenu(menuFn);
  543.         for (int j = i*10+1; j <= min(i*10+10, size); j++)
  544.             glutAddMenuEntry( menuEntries[j-1] , j);
  545.         CheckError();
  546.     }
  547.     int menuId = glutCreateMenu(menuFn);
  548.  
  549.     for (int i=0; i < nSubMenus; i++) {
  550.         char num[6];
  551.         sprintf(num, "%d-%d", i*10+1, min(i*10+10, size));
  552.         glutAddSubMenu(num,subMenus[i]);
  553.         CheckError();
  554.     }
  555.     return menuId;
  556. }
  557.  
  558. static void materialMenu(int id)
  559. {
  560.     deactivateTool();
  561.     if (currObject < 0) return;
  562.     if (id==10) {
  563.         toolObj = currObject;
  564.         setToolCallbacks(adjustRedGreen, mat2(1, 0, 0, 1),
  565.                          adjustBlueBrightness, mat2(1, 0, 0, 1) );
  566.     }
  567.     if (id==20) {
  568.         toolObj = currObject;
  569.         setToolCallbacks(adjustAmbientDiffuse, mat2(1, 0, 0, 1),
  570.                          adjustSpecularShine, mat2(5, 0, 0, 20) );
  571.     }
  572.     // You'll need to fill in the remaining menu items here.                                                
  573.     else {
  574.         printf("Error in materialMenu\n");
  575.     }
  576. }
  577.  
  578. static void adjustAngleYX(vec2 angle_yx)
  579. {
  580.     sceneObjs[currObject].angles[1]+=angle_yx[0];
  581.     sceneObjs[currObject].angles[0]+=angle_yx[1];
  582. }
  583.  
  584. static void adjustAngleZTexscale(vec2 az_ts)
  585. {
  586.     sceneObjs[currObject].angles[2]+=az_ts[0];
  587.     sceneObjs[currObject].texScale+=az_ts[1];
  588. }
  589.  
  590. static void mainmenu(int id)
  591. {
  592.     deactivateTool();
  593.     if (id == 41 && currObject>=0) {
  594.         toolObj=currObject;
  595.         setToolCallbacks(adjustLocXZ, camRotZ(),
  596.                          adjustScaleY, mat2(0.05, 0, 0, 10) );
  597.     }
  598.     if (id == 50)
  599.         doRotate();
  600.     if (id == 55 && currObject>=0) {
  601.         setToolCallbacks(adjustAngleYX, mat2(400, 0, 0, -400),
  602.                          adjustAngleZTexscale, mat2(400, 0, 0, 15) );
  603.     }
  604.     if (id == 99) exit(0);
  605. }
  606.  
  607. static void makeMenu()
  608. {
  609.     int objectId = createArrayMenu(numMeshes, objectMenuEntries, objectMenu);
  610.  
  611.     int materialMenuId = glutCreateMenu(materialMenu);
  612.     glutAddMenuEntry("R/G/B/All",10);
  613.     glutAddMenuEntry("Ambient/Diffuse/Specular/Shine",20);
  614.  
  615.     int texMenuId = createArrayMenu(numTextures, textureMenuEntries, texMenu);
  616.     int groundMenuId = createArrayMenu(numTextures, textureMenuEntries, groundMenu);
  617.  
  618.     int lightMenuId = glutCreateMenu(lightMenu);
  619.     glutAddMenuEntry("Move Light 1",70);
  620.     glutAddMenuEntry("R/G/B/All Light 1",71);
  621.     glutAddMenuEntry("Move Light 2",80);
  622.     glutAddMenuEntry("R/G/B/All Light 2",81);
  623.  
  624.     glutCreateMenu(mainmenu);
  625.     glutAddMenuEntry("Rotate/Move Camera",50);
  626.     glutAddSubMenu("Add object", objectId);
  627.     glutAddMenuEntry("Position/Scale", 41);
  628.     glutAddMenuEntry("Rotation/Texture Scale", 55);
  629.     glutAddSubMenu("Material", materialMenuId);
  630.     glutAddSubMenu("Texture",texMenuId);
  631.     glutAddSubMenu("Ground Texture",groundMenuId);
  632.     glutAddSubMenu("Lights",lightMenuId);
  633.     glutAddMenuEntry("EXIT", 99);
  634.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  635. }
  636.  
  637. //----------------------------------------------------------------------------
  638.  
  639. void keyboard( unsigned char key, int x, int y )
  640. {
  641.     switch ( key ) {
  642.     case 033:
  643.         exit( EXIT_SUCCESS );
  644.         break;
  645.     }
  646. }
  647.  
  648. //----------------------------------------------------------------------------
  649.  
  650. void idle( void )
  651. {
  652.     glutPostRedisplay();
  653. }
  654.  
  655. //----------------------------------------------------------------------------
  656.  
  657. void reshape( int width, int height )
  658. {
  659.     windowWidth = width;
  660.     windowHeight = height;
  661.  
  662.     glViewport(0, 0, windowWidth, windowHeight);
  663.  
  664.     // You'll need to modify this so that the view is similar to that in the
  665.     // sample solution.
  666.     // In particular:
  667.     //     - the view should include "closer" visible objects (slightly tricky)
  668.     //     - when the width is less than the height, the view should adjust so
  669.     //         that the same part of the scene is visible across the width of
  670.     //         the window.
  671.  
  672.     GLfloat nearDist = 0.00001;
  673.  
  674.     if (width > height){
  675.     projection = Frustum(-nearDist*(float)width/(float)height,
  676.                          nearDist*(float)width/(float)height,
  677.                          -nearDist, nearDist,
  678.                          nearDist, 100.0);
  679.     }
  680.     else{
  681.     projection = Frustum(-nearDist, nearDist,
  682.                          -nearDist*(float)height/(float)width,
  683.                          nearDist*(float)height/(float)width,
  684.                          nearDist, 100.0);
  685.     }
  686.  
  687. }
  688.  
  689. //----------------------------------------------------------------------------
  690.  
  691. void timer(int unused)
  692. {
  693.     char title[256];
  694.     sprintf(title, "%s %s: %d Frames Per Second @ %d x %d",
  695.                     lab, programName, numDisplayCalls, windowWidth, windowHeight );
  696.  
  697.     glutSetWindowTitle(title);
  698.  
  699.     numDisplayCalls = 0;
  700.     glutTimerFunc(1000, timer, 1);
  701. }
  702.  
  703. //----------------------------------------------------------------------------
  704.  
  705. char dirDefault1[] = "models-textures";
  706. char dirDefault3[] = "/tmp/models-textures";
  707. char dirDefault4[] = "/d/models-textures";
  708. char dirDefault2[] = "/cslinux/examples/CITS3003/project-files/models-textures";
  709.  
  710. void fileErr(char* fileName)
  711. {
  712.     printf("Error reading file: %s\n", fileName);
  713.     printf("When not in the CSSE labs, you will need to include the directory containing\n");
  714.     printf("the models on the command line, or put it in the same folder as the exectutable.");
  715.     exit(1);
  716. }
  717.  
  718. //----------------------------------------------------------------------------
  719.  
  720. int main( int argc, char* argv[] )
  721. {
  722.     // Get the program name, excluding the directory, for the window title
  723.     programName = argv[0];
  724.     for (char *cpointer = argv[0]; *cpointer != 0; cpointer++)
  725.         if (*cpointer == '/' || *cpointer == '\\') programName = cpointer+1;
  726.  
  727.     // Set the models-textures directory, via the first argument or some handy defaults.
  728.     if (argc > 1)
  729.         strcpy(dataDir, argv[1]);
  730.     else if (opendir(dirDefault1)) strcpy(dataDir, dirDefault1);
  731.     else if (opendir(dirDefault2)) strcpy(dataDir, dirDefault2);
  732.     else if (opendir(dirDefault3)) strcpy(dataDir, dirDefault3);
  733.     else if (opendir(dirDefault4)) strcpy(dataDir, dirDefault4);
  734.     else fileErr(dirDefault1);
  735.  
  736.     glutInit( &argc, argv );
  737.     glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  738.     glutInitWindowSize( windowWidth, windowHeight );
  739.  
  740.     // glutInitContextVersion( 3, 2);
  741.     // glutInitContextProfile( GLUT_CORE_PROFILE );            // May cause issues, sigh, but you
  742.     // glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE ); // should still use only OpenGL 3.2 Core
  743.                                                             // features.
  744.     glutCreateWindow( "Initialising..." );
  745.  
  746.     // glewInit(); // With some old hardware yields GL_INVALID_ENUM, if so use glewExperimental.
  747.     CheckError(); // This bug is explained at: http://www.opengl.org/wiki/OpenGL_Loading_Library
  748.  
  749.     init();
  750.     CheckError();
  751.  
  752.     glutDisplayFunc( display );
  753.     glutKeyboardFunc( keyboard );
  754.     glutIdleFunc( idle );
  755.  
  756.     glutMouseFunc( mouseClickOrScroll );
  757.     glutPassiveMotionFunc(mousePassiveMotion);
  758.     glutMotionFunc( doToolUpdateXY );
  759.  
  760.     glutReshapeFunc( reshape );
  761.     glutTimerFunc( 1000, timer, 1 );
  762.     CheckError();
  763.  
  764.     makeMenu();
  765.     CheckError();
  766.  
  767.     glutMainLoop();
  768.     return 0;
  769. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement