Advertisement
pjs_

Untitled

Dec 5th, 2011
412
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.78 KB | None | 0 0
  1.  
  2.  
  3. #include "glwidget2.h"
  4. #include <QDebug>
  5.  
  6. // the global Assimp scene object
  7. const struct aiScene* scene = NULL;
  8. GLuint scene_list = 0;
  9. struct aiVector3D scene_min, scene_max, scene_center;
  10.  
  11. // current rotation angle
  12. static float angle = 0.f;
  13.  
  14. #define aisgl_min(x,y) (x<y?x:y)
  15. #define aisgl_max(x,y) (y>x?y:x)
  16.  
  17.  
  18.  
  19. GLWidget2::GLWidget2(QWidget *parent) :    QGLWidget(parent){
  20.  
  21.     struct aiLogStream stream;
  22.  
  23.     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  24.  
  25.  
  26.     stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
  27.     aiAttachLogStream(&stream);
  28.  
  29.     // ... same procedure, but this stream now writes the
  30.     // log messages to assimp_log.txt
  31.     stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
  32.     aiAttachLogStream(&stream);
  33.  
  34.     //loadasset( "models/Collada/duck.dae");
  35.  
  36.     // loadasset( "models/MD2/faerie.md2");
  37.      loadasset( "models/Collada/4band_resistor_kit.dae");
  38.  
  39.     glClearColor(1.0f,1.0f,1.0f,1.f);
  40.  
  41.     glEnable(GL_LIGHTING);
  42.     glEnable(GL_LIGHT0);    // Uses default lighting parameters
  43.  
  44.     glEnable(GL_DEPTH_TEST);
  45.  
  46.     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  47.     glEnable(GL_NORMALIZE);
  48.  
  49.     // XXX docs say all polygons are emitted CCW, but tests show that some aren't.
  50.     if(getenv("MODEL_IS_BROKEN"))
  51.             glFrontFace(GL_CW);
  52.  
  53.     glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
  54.  
  55.     glutGet(GLUT_ELAPSED_TIME);
  56.     GLWidget2::updateGL();
  57.     //glutMainLoop();
  58.  
  59.     // cleanup - calling 'aiReleaseImport' is important, as the library
  60.     // keeps internal resources until the scene is freed again. Not
  61.     // doing so can cause severe resource leaking.
  62.     aiReleaseImport(scene);
  63.  
  64.     // We added a log stream to the library, it's our job to disable it
  65.     // again. This will definitely release the last resources allocated
  66.     // by Assimp.
  67.     aiDetachAllLogStreams();
  68.  
  69. }
  70.  
  71.  
  72.  
  73.  
  74. // ----------------------------------------------------------------------------
  75. void GLWidget2::resizeGL(int width, int height)
  76. {
  77.         const double aspectRatio = (float) width / height, fieldOfView = 45.0;
  78.  
  79.         glMatrixMode(GL_PROJECTION);
  80.         glLoadIdentity();
  81.         gluPerspective(fieldOfView, aspectRatio, 0.0, 2000.0);  /* Znear and Zfar */
  82.         glViewport(0, 0, width, height);
  83. }
  84.  
  85. // ----------------------------------------------------------------------------
  86. void GLWidget2::get_bounding_box_for_node (const struct aiNode* nd,
  87.         struct aiVector3D* min,
  88.         struct aiVector3D* max,
  89.         struct aiMatrix4x4* trafo
  90. ){
  91.         struct aiMatrix4x4 prev;
  92.         unsigned int n = 0, t;
  93.  
  94.         prev = *trafo;
  95.         aiMultiplyMatrix4(trafo,&nd->mTransformation);
  96.  
  97.         //int xx =   nd->mNumMeshes;
  98.  
  99.         for (; n < nd->mNumMeshes; ++n) {
  100.                 const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
  101.                 for (t = 0; t < mesh->mNumVertices; ++t) {
  102.  
  103.                         struct aiVector3D tmp = mesh->mVertices[t];
  104.                         aiTransformVecByMatrix4(&tmp,trafo);
  105.  
  106.                         min->x = aisgl_min(min->x,tmp.x);
  107.                         min->y = aisgl_min(min->y,tmp.y);
  108.                         min->z = aisgl_min(min->z,tmp.z);
  109.  
  110.                         max->x = aisgl_max(max->x,tmp.x);
  111.                         max->y = aisgl_max(max->y,tmp.y);
  112.                         max->z = aisgl_max(max->z,tmp.z);
  113.                 }
  114.         }
  115.  
  116.         for (n = 0; n < nd->mNumChildren; ++n) {
  117.                 get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
  118.         }
  119.         *trafo = prev;
  120. }
  121.  
  122. // ----------------------------------------------------------------------------
  123. void GLWidget2::get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
  124. {
  125.         struct aiMatrix4x4 trafo;
  126.         aiIdentityMatrix4(&trafo);
  127.  
  128.         min->x = min->y = min->z =  1e10f;
  129.         max->x = max->y = max->z = -1e10f;
  130.         get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
  131. }
  132.  
  133. // ----------------------------------------------------------------------------
  134. void GLWidget2::color4_to_float4(const struct aiColor4D *c, float f[4])
  135. {
  136.         f[0] = c->r;
  137.         f[1] = c->g;
  138.         f[2] = c->b;
  139.         f[3] = c->a;
  140. }
  141.  
  142. // ----------------------------------------------------------------------------
  143. void GLWidget2::set_float4(float f[4], float a, float b, float c, float d)
  144. {
  145.         f[0] = a;
  146.         f[1] = b;
  147.         f[2] = c;
  148.         f[3] = d;
  149. }
  150.  
  151. // ----------------------------------------------------------------------------
  152. void GLWidget2::apply_material(const struct aiMaterial *mtl)
  153. {
  154.         float c[4];
  155.  
  156.         GLenum fill_mode;
  157.         unsigned int ret1, ret2;
  158.         struct aiColor4D diffuse;
  159.         struct aiColor4D specular;
  160.         struct aiColor4D ambient;
  161.         struct aiColor4D emission;
  162.         float shininess, strength;
  163.         int two_sided;
  164.         int wireframe;
  165.         unsigned int max;
  166.  
  167.         set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
  168.         if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
  169.                 color4_to_float4(&diffuse, c);
  170.         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
  171.  
  172.         set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
  173.         if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
  174.                 color4_to_float4(&specular, c);
  175.         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
  176.  
  177.         set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
  178.         if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
  179.                 color4_to_float4(&ambient, c);
  180.         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
  181.  
  182.         set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
  183.         if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
  184.                 color4_to_float4(&emission, c);
  185.         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
  186.  
  187.         max = 1;
  188.         ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
  189.         if(ret1 == AI_SUCCESS) {
  190.         max = 1;
  191.         ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
  192.                 if(ret2 == AI_SUCCESS)
  193.                         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
  194.         else
  195.                 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  196.     }
  197.         else {
  198.                 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
  199.                 set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
  200.                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
  201.         }
  202.  
  203.         max = 1;
  204.         if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
  205.                 fill_mode = wireframe ? GL_LINE : GL_FILL;
  206.         else
  207.                 fill_mode = GL_FILL;
  208.         glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
  209.  
  210.         max = 1;
  211.         if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
  212.                 glDisable(GL_CULL_FACE);
  213.         else
  214.                 glEnable(GL_CULL_FACE);
  215. }
  216.  
  217. // ----------------------------------------------------------------------------
  218. void GLWidget2::recursive_render (const struct aiScene *sc, const struct aiNode* nd)
  219. {
  220.         int i;
  221.         unsigned int n = 0, t;
  222.         struct aiMatrix4x4 m = nd->mTransformation;
  223.  
  224.         // update transform
  225.         aiTransposeMatrix4(&m);
  226.         glPushMatrix();
  227.         glMultMatrixf((float*)&m);
  228.  
  229.  
  230.         for (; n < nd->mNumMeshes; ++n) {
  231.                 const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
  232.  
  233.                 apply_material(sc->mMaterials[mesh->mMaterialIndex]);
  234.  
  235.  
  236.                 if(mesh->mNormals == NULL) {
  237.                         glDisable(GL_LIGHTING);
  238.                 } else {
  239.                         glEnable(GL_LIGHTING);
  240.                 }
  241.  
  242.  
  243.                 for (t = 0; t < mesh->mNumFaces; ++t) {
  244.                         const struct aiFace* face = &mesh->mFaces[t];
  245.                         GLenum face_mode;
  246.  
  247.                         switch(face->mNumIndices) {
  248.                                 case 1: face_mode = GL_POINTS; break;
  249.                                 case 2: face_mode = GL_LINES; break;
  250.                                 case 3: face_mode = GL_TRIANGLES; break;
  251.                                 default: face_mode = GL_POLYGON; break;
  252.                         }
  253.  
  254.                         glBegin(face_mode);
  255.  
  256.                         for(i = 0; i < face->mNumIndices; i++) {
  257.                                 int index = face->mIndices[i];
  258.                                 if(mesh->mColors[0] != NULL)
  259.                                         glColor4fv((GLfloat*)&mesh->mColors[0][index]);
  260.                                 if(mesh->mNormals != NULL)
  261.                                         glNormal3fv(&mesh->mNormals[index].x);
  262.                                 glVertex3fv(&mesh->mVertices[index].x);
  263.                         }
  264.  
  265.                         glEnd();
  266.                 }
  267.  
  268.         }
  269.  
  270.         // draw all children
  271.         for (n = 0; n < nd->mNumChildren; ++n) {
  272.                 recursive_render(sc, nd->mChildren[n]);
  273.         }
  274.  
  275.         glPopMatrix();
  276. }
  277.  
  278. // ----------------------------------------------------------------------------
  279. void GLWidget2::do_motion (void)
  280. {
  281.         static GLint prev_time = 0;
  282.  
  283.         int time = glutGet(GLUT_ELAPSED_TIME);
  284.         angle += (time-prev_time)*0.01;
  285.         prev_time = time;
  286.  
  287. }
  288.  
  289. // ----------------------------------------------------------------------------
  290. float rotx = 0.0f;
  291.  
  292. void GLWidget2::paintGL()
  293. {
  294.  
  295.     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
  296.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  297.         float tmp;
  298.  
  299.  
  300.         glMatrixMode(GL_MODELVIEW);
  301.         glLoadIdentity();
  302.  
  303.         gluLookAt(0.f,0.f,1.f,0.f,0.f,-5.f,0.f,1.f,0.f);
  304.  
  305.         // rotate it around the y axis
  306.         glRotatef(angle,0.f,1.f,0.f);
  307.  
  308.         // scale the whole asset to fit into our view frustum
  309.         tmp = scene_max.x-scene_min.x;
  310.         tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
  311.         tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
  312.         tmp = 1.f / tmp;
  313.         glScalef(tmp, tmp, tmp);
  314.  
  315.         // center the model
  316.         glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z);
  317.  
  318.         // if the display list has not been made yet, create a new one and
  319.         // fill it with scene contents
  320.         if(scene_list == 0) {
  321.             scene_list = glGenLists(1);
  322.             glNewList(scene_list, GL_COMPILE);
  323.             // now begin at the root node of the imported data and traverse
  324.             // the scenegraph by multiplying subsequent local transforms
  325.             // together on GL's matrix stack.
  326.             recursive_render(scene, scene->mRootNode);
  327.             glEndList();
  328.         }
  329.  
  330.         glCallList(scene_list);
  331.  
  332.         //  glutSwapBuffers();
  333.         // QGLWidget::swapBuffers();
  334.  
  335.         do_motion();
  336. }
  337.  
  338. // ----------------------------------------------------------------------------
  339. int GLWidget2::loadasset (const char* path)
  340. {
  341.         // we are taking one of the postprocessing presets to avoid
  342.         // spelling out 20+ single postprocessing flags here.
  343.         scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality);
  344.  
  345.         if (scene) {
  346.                 get_bounding_box(&scene_min,&scene_max);
  347.                 scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
  348.                 scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
  349.                 scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
  350.                 return 0;
  351.         }
  352.         return 1;
  353. }
  354.  
  355. // ----------------------------------------------------------------------------
  356.  
  357. void GLWidget2::initializeGL()
  358. {
  359.  
  360.     glEnable (GL_LIGHTING);
  361.     glEnable (GL_LIGHT0);
  362.  
  363. }
  364.  
  365.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement