| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- // ----------------------------------------------------------------------------
- // Simple sample to prove that Assimp is absolutely easy to use with OpenGL.
- // It takes a file name as command line parameter, loads it using standard
- // settings and displays it.
- //
- // If you intend to _use_ this code sample in your app, do yourself a favour
- // and replace immediate mode calls with VBOs ...
- //
- // The vc8 solution links against assimp-release-dll_win32 - be sure to
- // have this configuration built.
- // ----------------------------------------------------------------------------
- #include "GL/glut.h"
- // assimp include files. These three are usually needed.
- #include "assimp.h"
- #include "aiPostProcess.h"
- #include "aiScene.h"
- // the global Assimp scene object
- const struct aiScene* scene = NULL;
- struct aiVector3D scene_min,scene_max;
- // current rotation angle
- static float angle = 0.f;
- #define aisgl_min(x,y) (x<y?x:y)
- #define aisgl_max(x,y) (y>x?y:x)
- // ----------------------------------------------------------------------------
- void reshape(int width, int height)
- {
- const double aspectRatio = (float) width / height, fieldOfView = 45.0;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(fieldOfView, aspectRatio,
- 1.0, 1000.0); /* Znear and Zfar */
- glViewport(0, 0, width, height);
- }
- // ----------------------------------------------------------------------------
- void get_bounding_box_for_node (const struct aiNode* nd,
- struct aiVector3D* min,
- struct aiVector3D* max,
- struct aiMatrix4x4* trafo
- ){
- struct aiMatrix4x4 prev;
- unsigned int n = 0, t;
- aiMultiplyMatrix4(trafo,&nd->mTransformation);
- for (; n < nd->mNumMeshes; ++n) {
- const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
- for (t = 0; t < mesh->mNumVertices; ++t) {
- struct aiVector3D tmp = mesh->mVertices[t];
- aiTransformVecByMatrix4(&tmp,trafo);
- min->x = aisgl_min(min->x,tmp.x);
- min->y = aisgl_min(min->y,tmp.y);
- min->z = aisgl_min(min->z,tmp.z);
- max->x = aisgl_max(max->x,tmp.x);
- max->y = aisgl_max(max->y,tmp.y);
- max->z = aisgl_max(max->z,tmp.z);
- }
- }
- prev = nd->mTransformation;
- for (n = 0; n < nd->mNumChildren; ++n) {
- get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
- }
- *trafo = prev;
- }
- // ----------------------------------------------------------------------------
- void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
- {
- struct aiMatrix4x4 trafo;
- aiIdentityMatrix4(&trafo);
- min->x = min->y = min->z = 1e10f;
- max->x = max->y = max->z = -1e10f;
- get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
- }
- // ----------------------------------------------------------------------------
- void recursive_render (const struct aiNode* nd)
- {
- unsigned int n = 0, t;
- struct aiMatrix4x4 m = nd->mTransformation;
- // update transform
- aiTransposeMatrix4(&m);
- glMultMatrixf((float*)&m);
- // draw all meshes assigned to this node
- for (; n < nd->mNumMeshes; ++n) {
- const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
- glBegin(GL_TRIANGLES);
- for (t = 0; t < mesh->mNumFaces; ++t) {
- const struct aiFace* face = &mesh->mFaces[t];
- glColor3f(1.f,0.f,0.f);
- glVertex3fv(&mesh->mVertices[face->mIndices[0]].x);
- glVertex3fv(&mesh->mVertices[face->mIndices[1]].x);
- glVertex3fv(&mesh->mVertices[face->mIndices[2]].x);
- }
- glEnd();
- }
- // draw all children
- for (n = 0; n < nd->mNumChildren; ++n) {
- recursive_render(nd->mChildren[n]);
- }
- }
- // ----------------------------------------------------------------------------
- void do_motion (void)
- {
- static GLint prev_time = 0;
- int time = glutGet(GLUT_ELAPSED_TIME);
- angle += (time-prev_time)*0.01;
- prev_time = time;
- glutPostRedisplay ();
- }
- // ----------------------------------------------------------------------------
- void display(void)
- {
- float tmp;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
- // scale the whole asset to fit into our view frustum
- tmp = scene_max.x-scene_min.x;
- tmp = aisgl_max(scene_max.y-scene_min.y,tmp);
- tmp = aisgl_max(scene_max.z-scene_min.z,tmp);
- tmp = 1.f/(tmp);
- glScalef(tmp,tmp,tmp);
- // fixme: center around origin
-
- // rotate it around the y axis
- glRotatef(angle,0.f,1.f,0.f);
- // now begin at the root node of the imported data and traverse
- // the scenegraph by multipliying subsequent local transforms
- // together on GL's matrix stack.
- recursive_render(scene->mRootNode);
- glutSwapBuffers();
- do_motion();
- }
- // ----------------------------------------------------------------------------
- int loadasset (const char* path)
- {
- // we are taking one of the postprocessing presets to avoid
- // writing 20 single postprocessing flags here.
- scene = aiImportFile(path,aiProcessPreset_TargetRealtime_Quality);
- if (scene) {
- get_bounding_box(&scene_min,&scene_max);
- return 0;
- }
- return 1;
- }
- // ----------------------------------------------------------------------------
- int main(int argc, char **argv)
- {
- struct aiLogStream stream;
- glutInitWindowSize(900,600);
- glutInitWindowPosition(100,100);
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
- glutInit(&argc, argv);
- glutCreateWindow("Assimp - Very simple OpenGL sample");
- glutDisplayFunc(display);
- glutReshapeFunc(reshape);
- // get a handle to the predefined STDOUT log stream and attach
- // it to the logging system. It will be active for all further
- // calls to aiImportFile(Ex) and aiApplyPostProcessing.
- stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
- aiAttachLogStream(&stream);
- // ... exactly the same, but this stream will now write the
- // log file to assimp_log.txt
- stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
- aiAttachLogStream(&stream);
- if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models/X/dwarf.x")) {
- if( argc != 1 || 0 != loadasset( "../../../../test/models/X/dwarf.x")) {
- return -1;
- }
- }
- glPolygonMode(GL_FRONT,GL_LINE);
- glPolygonMode(GL_BACK,GL_LINE);
- glClearColor(0.1f,0.1f,0.1f,1.f);
- glutGet(GLUT_ELAPSED_TIME);
- glutMainLoop();
- // cleanup - calling 'aiReleaseImport' is important, as the library
- // keeps internal resources until the scene is freed again. Not
- // doing so can cause severe resource leaking.
- aiReleaseImport(scene);
- // We added a log stream to the library, it's our job to disable it
- // again. This will definitely release the last resources allocated
- // by Assimp.
- aiDetachAllLogStreams();
- return 0;
- }
|