wave-glut/lib/obj-model/test/test.cpp

Go to the documentation of this file.
00001 /*
00002  * test.cpp
00003  *
00004  * Copyright (C) 2009,2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Program to test the obj-model library.
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include "glut-demo/glut-demo.h"
00012 #include "obj-model/obj-model.h"
00013 #include "perf/perf.h"
00014 #include "util/file.h"
00015 
00016 
00017 static int s_shape                              = 0;    // model
00018 static const int s_maxShape                     = 2;
00019 static float s_sphereRadius                     = 1.0;
00020 
00021 static float s_scale                            = 1.0;
00022 
00023 
00024 ////////////////////////////////////////////////////////////////////////////////
00025 //
00026 //      static helper methods
00027 //
00028 ////////////////////////////////////////////////////////////////////////////////
00029 
00030 ////////////////////////////////////////////////////////////////////////////////
00031 //
00032 //      display line objects
00033 //
00034 ////////////////////////////////////////////////////////////////////////////////
00035 
00036 class ShapeDisplay : public glut::DisplayLine {
00037 public:
00038         // constructor, destructor ---------------------------------------------
00039         ~ShapeDisplay(void) throw() { }
00040 
00041         // glut::DisplayLine class interface methods ---------------------------
00042         ePosition getPosition(void) { return eTopLeft; }
00043 
00044         const char * getText(void) {
00045                         const char * txt = "???";
00046                         switch (s_shape) {
00047                         case 0: txt = "model";          break;
00048                         case 1: txt = "sphere";         break;
00049                         case 2: txt = "triangles";      break;
00050                         }
00051 
00052                         sprintf(m_buffer, "(s)hape: %s", txt);
00053                         return m_buffer;
00054                 }
00055 
00056 private:
00057         // private member data -------------------------------------------------
00058         char            m_buffer[256];
00059 };
00060 
00061 
00062 
00063 
00064 static void
00065 setMaterials
00066 (
00067 void
00068 )
00069 {
00070         float d = 0.4;
00071         float diffuse[] = { d, d, d, 1.0 };
00072         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse);
00073 
00074         float s = 0.6;
00075         float specular[] = { s, s, s, 1.0 };
00076         glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
00077 }
00078 
00079 
00080 
00081 static void
00082 drawTriangle
00083 (
00084 void
00085 )
00086 {
00087         setMaterials();
00088 
00089         float q = s_sphereRadius;
00090         float q2 = 0.5 * q;
00091 
00092         glBegin(GL_TRIANGLES);
00093 
00094         // front side
00095         glNormal3f(0, 0, 1);
00096         glVertex3f(-q, -q2, q);
00097         glVertex3f(+q, -q2, q);
00098         glVertex3f( 0, +q2, q);
00099 
00100         // back side
00101         glNormal3f(0, 0, -1);
00102         glVertex3f(+q, -q2, -q);
00103         glVertex3f(-q, -q2, -q);
00104         glVertex3f( 0, +q2, -q);
00105 
00106         // left side
00107         glNormal3f(-1, 0, 0);
00108         glVertex3f(-q, +q2, +q);
00109         glVertex3f(-q, +q2, -q);
00110         glVertex3f(-q, -q2, 0);
00111 
00112         // right side
00113         glNormal3f(+1, 0, 0);
00114         glVertex3f(+q, +q2, -q);
00115         glVertex3f(+q, +q2, +q);
00116         glVertex3f(+q, -q2, 0);
00117 
00118         glEnd();
00119 }
00120 
00121 
00122 
00123 static void
00124 drawSphere
00125 (
00126 void
00127 )
00128 {
00129         setMaterials();
00130 
00131         int N = 32;
00132         glutSolidSphere(s_sphereRadius, N, N);
00133 }
00134 
00135 
00136 
00137 class TestHost : public glut::DemoHost {
00138 public:
00139         TestHost(void) throw() { }
00140         ~TestHost(void) throw() { }
00141 
00142         // glut::Host class interface methods ----------------------------------
00143         void onInit(void) {
00144                 // load model
00145                 smart_ptr<nstream::Manager> mgr =
00146                     nstream::getFilesystemManager("/");
00147                 ASSERT(mgr, "null");
00148 
00149                 smart_ptr<nstream::File> file = mgr->getEntry(m_file.c_str());
00150                 ASSERT_THROW(file, "Failed to find file: " << m_file);
00151 
00152                 smart_ptr<nstream::Stream> stream = file->openStream();
00153                 ASSERT_THROW(stream, "Failed to open stream: " << m_file);
00154 
00155                 float scale = 1.0;
00156                 m_model = obj::Model::create(stream, scale);
00157                 ASSERT(m_model, "null");
00158 
00159                 // figure out starting distance from center
00160                 rect3d_t r = m_model->getBoundingBox();
00161                 float dist = 0.0;
00162                 dist += r.x1 - r.x0;
00163                 dist += r.y1 - r.y0;
00164                 dist += r.z1 - r.z0;
00165                 dist *= .75;
00166 
00167                 if (dist > 0) {
00168                         s_scale = 10.0 / dist;
00169                 }
00170 
00171                 // set sphere size and position
00172                 s_sphereRadius = 2.0;
00173         }
00174 
00175         void getDisplayLines(IN glut::vec_display_lines_t& lines) {
00176                         lines.clear();
00177 
00178                         m_shapes = new ShapeDisplay;
00179                         THROW(m_shapes, "out of memory");
00180                         lines.push_back(m_shapes);
00181                 }
00182 
00183         void display3D(IN const glut::render_context_t& rc,
00184                                 IN glut::RenderQueue * rq) {
00185                         ASSERT(rq, "null");
00186 
00187                         // draw object
00188                         glMatrixMode(GL_MODELVIEW);
00189                         glPushMatrix();
00190                         switch (s_shape) {
00191                         case 0:
00192                         {
00193                                 // translate model so it is centered on the origin
00194                                 glScalef(s_scale, s_scale, s_scale);
00195                                 rect3d_t r = m_model->getBoundingBox();
00196                                 glTranslatef(-0.5 * (r.x0 + r.x1),
00197                                         -0.5 * (r.y0 + r.y1),
00198                                         -0.5 * (r.z0 + r.z1));
00199                                 m_model->render(rc, rq);
00200                         }
00201                         break;
00202 
00203                         case 1:
00204                                 drawSphere();
00205                                 break;
00206 
00207                         case 2:
00208                                 drawTriangle();
00209                                 break;
00210                         }
00211                         glPopMatrix();
00212                 }
00213 
00214         virtual void onKey(IN int key, IN int mods) {
00215                         switch (key) {
00216                         case 's':
00217                                 s_shape++;
00218                                 if (s_shape > s_maxShape) {
00219                                         s_shape = 0;
00220                                 }
00221                                 break;
00222                         }
00223                 }
00224 
00225         // static factory methods ----------------------------------------------
00226         static smart_ptr<glut::DemoHost> create(IN const char * model_file) {
00227                         ASSERT(model_file, "null");
00228 
00229                         smart_ptr<TestHost> local = new TestHost;
00230                         ASSERT(local, "out of memory");
00231 
00232                         local->m_file = model_file;
00233 
00234                         return local;
00235                 }
00236 
00237 private:
00238         // private member data -------------------------------------------------
00239         std::string                     m_file;
00240         smart_ptr<obj::Model>           m_model;
00241         smart_ptr<ShapeDisplay>         m_shapes;
00242 };
00243 
00244 
00245 
00246 ////////////////////////////////////////////////////////////////////////////////
00247 //
00248 //      entry point
00249 //
00250 ////////////////////////////////////////////////////////////////////////////////
00251 
00252 int
00253 main
00254 (
00255 IN int argc,
00256 IN const char * argv[]
00257 )
00258 {
00259         ASSERT(2 == argc, "Usage: obj-model-test <model-file>");
00260         const char * model_file = argv[1];
00261 
00262         try {
00263                 // create host object
00264                 smart_ptr<glut::DemoHost> host = TestHost::create(model_file);
00265                 THROW(host, "null");
00266 
00267                 // ask glut to run
00268                 const char * filename = GetFilename(model_file);
00269                 std::string title = "obj-model test: ";
00270                 title += filename;
00271 
00272                 glut::startDemo(argc, argv, title.c_str(), host);
00273 
00274         } catch (std::exception& e) {
00275                 DPRINTF("Exception: %s", e.what());
00276         }
00277 
00278         return 1;       // never get here!
00279 }
00280