Sample_SimpleOpenGL.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // ----------------------------------------------------------------------------
  2. // Simple sample to prove that Assimp is absolutely easy to use with OpenGL.
  3. // It takes a file name as command line parameter, loads it using standard
  4. // settings and displays it.
  5. //
  6. // If you intend to _use_ this code sample in your app, do yourself a favour
  7. // and replace immediate mode calls with VBOs ...
  8. //
  9. // The vc8 solution links against assimp-release-dll_win32 - be sure to
  10. // have this configuration built.
  11. // ----------------------------------------------------------------------------
  12. #include "GL/glut.h"
  13. // assimp include files. These three are usually needed.
  14. #include "assimp.h"
  15. #include "aiPostProcess.h"
  16. #include "aiScene.h"
  17. // the global Assimp scene object
  18. const struct aiScene* scene = NULL;
  19. struct aiVector3D scene_min,scene_max;
  20. // current rotation angle
  21. static float angle = 0.f;
  22. #define aisgl_min(x,y) (x<y?x:y)
  23. #define aisgl_max(x,y) (y>x?y:x)
  24. // ----------------------------------------------------------------------------
  25. void reshape(int width, int height)
  26. {
  27. const double aspectRatio = (float) width / height, fieldOfView = 45.0;
  28. glMatrixMode(GL_PROJECTION);
  29. glLoadIdentity();
  30. gluPerspective(fieldOfView, aspectRatio,
  31. 1.0, 1000.0); /* Znear and Zfar */
  32. glViewport(0, 0, width, height);
  33. }
  34. // ----------------------------------------------------------------------------
  35. void get_bounding_box_for_node (const struct aiNode* nd,
  36. struct aiVector3D* min,
  37. struct aiVector3D* max,
  38. struct aiMatrix4x4* trafo
  39. ){
  40. struct aiMatrix4x4 prev;
  41. unsigned int n = 0, t;
  42. aiMultiplyMatrix4(trafo,&nd->mTransformation);
  43. for (; n < nd->mNumMeshes; ++n) {
  44. const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
  45. for (t = 0; t < mesh->mNumVertices; ++t) {
  46. struct aiVector3D tmp = mesh->mVertices[t];
  47. aiTransformVecByMatrix4(&tmp,trafo);
  48. min->x = aisgl_min(min->x,tmp.x);
  49. min->y = aisgl_min(min->y,tmp.y);
  50. min->z = aisgl_min(min->z,tmp.z);
  51. max->x = aisgl_max(max->x,tmp.x);
  52. max->y = aisgl_max(max->y,tmp.y);
  53. max->z = aisgl_max(max->z,tmp.z);
  54. }
  55. }
  56. prev = nd->mTransformation;
  57. for (n = 0; n < nd->mNumChildren; ++n) {
  58. get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
  59. }
  60. *trafo = prev;
  61. }
  62. // ----------------------------------------------------------------------------
  63. void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
  64. {
  65. struct aiMatrix4x4 trafo;
  66. aiIdentityMatrix4(&trafo);
  67. min->x = min->y = min->z = 1e10f;
  68. max->x = max->y = max->z = -1e10f;
  69. get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
  70. }
  71. // ----------------------------------------------------------------------------
  72. void recursive_render (const struct aiNode* nd)
  73. {
  74. unsigned int n = 0, t;
  75. struct aiMatrix4x4 m = nd->mTransformation;
  76. // update transform
  77. aiTransposeMatrix4(&m);
  78. glMultMatrixf((float*)&m);
  79. // draw all meshes assigned to this node
  80. for (; n < nd->mNumMeshes; ++n) {
  81. const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
  82. glBegin(GL_TRIANGLES);
  83. for (t = 0; t < mesh->mNumFaces; ++t) {
  84. const struct aiFace* face = &mesh->mFaces[t];
  85. glColor3f(1.f,0.f,0.f);
  86. glVertex3fv(&mesh->mVertices[face->mIndices[0]].x);
  87. glVertex3fv(&mesh->mVertices[face->mIndices[1]].x);
  88. glVertex3fv(&mesh->mVertices[face->mIndices[2]].x);
  89. }
  90. glEnd();
  91. }
  92. // draw all children
  93. for (n = 0; n < nd->mNumChildren; ++n) {
  94. recursive_render(nd->mChildren[n]);
  95. }
  96. }
  97. // ----------------------------------------------------------------------------
  98. void do_motion (void)
  99. {
  100. static GLint prev_time = 0;
  101. int time = glutGet(GLUT_ELAPSED_TIME);
  102. angle += (time-prev_time)*0.01;
  103. prev_time = time;
  104. glutPostRedisplay ();
  105. }
  106. // ----------------------------------------------------------------------------
  107. void display(void)
  108. {
  109. float tmp;
  110. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  111. glMatrixMode(GL_MODELVIEW);
  112. glLoadIdentity();
  113. gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
  114. // scale the whole asset to fit into our view frustum
  115. tmp = scene_max.x-scene_min.x;
  116. tmp = aisgl_max(scene_max.y-scene_min.y,tmp);
  117. tmp = aisgl_max(scene_max.z-scene_min.z,tmp);
  118. tmp = 1.f/(tmp);
  119. glScalef(tmp,tmp,tmp);
  120. // fixme: center around origin
  121. // rotate it around the y axis
  122. glRotatef(angle,0.f,1.f,0.f);
  123. // now begin at the root node of the imported data and traverse
  124. // the scenegraph by multipliying subsequent local transforms
  125. // together on GL's matrix stack.
  126. recursive_render(scene->mRootNode);
  127. glutSwapBuffers();
  128. do_motion();
  129. }
  130. // ----------------------------------------------------------------------------
  131. int loadasset (const char* path)
  132. {
  133. // we are taking one of the postprocessing presets to avoid
  134. // writing 20 single postprocessing flags here.
  135. scene = aiImportFile(path,aiProcessPreset_TargetRealtime_Quality);
  136. if (scene) {
  137. get_bounding_box(&scene_min,&scene_max);
  138. return 0;
  139. }
  140. return 1;
  141. }
  142. // ----------------------------------------------------------------------------
  143. int main(int argc, char **argv)
  144. {
  145. struct aiLogStream stream;
  146. glutInitWindowSize(900,600);
  147. glutInitWindowPosition(100,100);
  148. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  149. glutInit(&argc, argv);
  150. glutCreateWindow("Assimp - Very simple OpenGL sample");
  151. glutDisplayFunc(display);
  152. glutReshapeFunc(reshape);
  153. // get a handle to the predefined STDOUT log stream and attach
  154. // it to the logging system. It will be active for all further
  155. // calls to aiImportFile(Ex) and aiApplyPostProcessing.
  156. stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
  157. aiAttachLogStream(&stream);
  158. // ... exactly the same, but this stream will now write the
  159. // log file to assimp_log.txt
  160. stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
  161. aiAttachLogStream(&stream);
  162. if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models/X/dwarf.x")) {
  163. if( argc != 1 || 0 != loadasset( "../../../../test/models/X/dwarf.x")) {
  164. return -1;
  165. }
  166. }
  167. glPolygonMode(GL_FRONT,GL_LINE);
  168. glPolygonMode(GL_BACK,GL_LINE);
  169. glClearColor(0.1f,0.1f,0.1f,1.f);
  170. glutGet(GLUT_ELAPSED_TIME);
  171. glutMainLoop();
  172. // cleanup - calling 'aiReleaseImport' is important, as the library
  173. // keeps internal resources until the scene is freed again. Not
  174. // doing so can cause severe resource leaking.
  175. aiReleaseImport(scene);
  176. // We added a log stream to the library, it's our job to disable it
  177. // again. This will definitely release the last resources allocated
  178. // by Assimp.
  179. aiDetachAllLogStreams();
  180. return 0;
  181. }