00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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;
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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 class ShapeDisplay : public glut::DisplayLine {
00037 public:
00038
00039 ~ShapeDisplay(void) throw() { }
00040
00041
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
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
00095 glNormal3f(0, 0, 1);
00096 glVertex3f(-q, -q2, q);
00097 glVertex3f(+q, -q2, q);
00098 glVertex3f( 0, +q2, q);
00099
00100
00101 glNormal3f(0, 0, -1);
00102 glVertex3f(+q, -q2, -q);
00103 glVertex3f(-q, -q2, -q);
00104 glVertex3f( 0, +q2, -q);
00105
00106
00107 glNormal3f(-1, 0, 0);
00108 glVertex3f(-q, +q2, +q);
00109 glVertex3f(-q, +q2, -q);
00110 glVertex3f(-q, -q2, 0);
00111
00112
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
00143 void onInit(void) {
00144
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
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
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
00188 glMatrixMode(GL_MODELVIEW);
00189 glPushMatrix();
00190 switch (s_shape) {
00191 case 0:
00192 {
00193
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
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
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
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
00264 smart_ptr<glut::DemoHost> host = TestHost::create(model_file);
00265 THROW(host, "null");
00266
00267
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;
00279 }
00280