model-draw.cpp

Go to the documentation of this file.
00001 /*
00002  * model-draw.cpp
00003  *
00004  * Copyright (C) 2008-2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * Routines to draw GLUT 3D models.
00031  */
00032 
00033 // includes --------------------------------------------------------------------
00034 #include "glut-model.h"         // always include our own header first
00035 
00036 #include "common/wave_ex.h"
00037 #include "geometry/matrix_4.h"
00038 #include "perf/perf.h"
00039 #include "wave-glut/wave-glut.h"
00040 
00041 
00042 namespace glut {
00043 
00044 
00045 
00046 ////////////////////////////////////////////////////////////////////////////////
00047 //
00048 //      static helper methods
00049 //
00050 ////////////////////////////////////////////////////////////////////////////////
00051 
00052 static void
00053 renderColorPolygon
00054 (
00055 IN const polygon_t& p
00056 )
00057 throw()
00058 {
00059         float material[] = {
00060             p.material->color.red,
00061             p.material->color.green,
00062             p.material->color.blue,
00063             1.0 };
00064 
00065 //      DPRINTF("matl: [%f %f %f %f]",
00066 //          material[0], material[1], material[2], material[3]);
00067 
00068         glColor4f(material[0], material[1], material[2], material[3]);
00069 //      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material);
00070 
00071         glNormal3fv(&p.normal.x);
00072 
00073         glDrawElements(GL_POLYGON, p.nVertices, GL_UNSIGNED_INT, p.indices);
00074 }
00075 
00076 
00077 
00078 static void
00079 queuePolygon
00080 (
00081 IN const point3d_t * vertex_array,
00082 IN const polygon_t& p,
00083 IO poly_request_t& pr
00084 )
00085 throw()
00086 {
00087         ASSERT(vertex_array, "null");
00088 
00089         if (p.nVertices > poly_request_t::eMaxVertices) {
00090                 DPRINTF("Too many vertices for queuing");
00091                 return;
00092         }
00093 
00094         // stash high-level details
00095         pr.nVertices = p.nVertices;
00096         pr.textureId = p.material->texture_id;
00097         pr.normal = p.normal;
00098 
00099         // transform all points
00100         matrix4_t M;
00101         glGetFloatv(GL_MODELVIEW_MATRIX, M.m);
00102         M.transpose();
00103         const int * pi = p.indices;
00104         for (int i = 0; i < p.nVertices; ++i, ++pi) {
00105                 const point3d_t& pModel = vertex_array[*pi];
00106                 pr.u[i] = p.u[i];
00107                 pr.v[i] = p.v[i];
00108                 pr.vertex[i] = M * pModel;
00109         }
00110 }
00111 
00112 
00113 
00114 static void
00115 renderTexturePolygon
00116 (
00117 IN const point3d_t * vertex_array,
00118 IN const polygon_t& p
00119 )
00120 throw()
00121 {
00122         ASSERT(vertex_array, "null");
00123 
00124         glEnable(GL_TEXTURE_2D);
00125         glBindTexture(GL_TEXTURE_2D, p.material->texture_id);
00126         glNormal3fv(&p.normal.x);
00127 
00128         //DPRINTF("  Drawing polygon");
00129 
00130         // loop through all vertices
00131         const int *pi = p.indices;
00132         const float * pu = p.u;
00133         const float * pv = p.v;
00134         glBegin(GL_POLYGON);
00135         for (int i = 0; i < p.nVertices; ++i, ++pu, ++pv, ++pi) {
00136                 const point3d_t& vtx = vertex_array[*pi];
00137                 glTexCoord2f(*pu, *pv);
00138                 glVertex3f(vtx.x, vtx.y, vtx.z);
00139 
00140         //      DPRINTF("    Vertex: (%f, %f, %f) - (%f, %f)",
00141         //          vtx.x, vtx.y, vtx.z, *pu, *pv);
00142         }
00143         glEnd();
00144         glDisable(GL_TEXTURE_2D);
00145 }
00146 
00147 
00148 
00149 ////////////////////////////////////////////////////////////////////////////////
00150 //
00151 //      public API
00152 //
00153 ////////////////////////////////////////////////////////////////////////////////
00154 
00155 void
00156 model_t::render
00157 (
00158 IN const render_context_t& rc,
00159 IN RenderQueue * rq
00160 )
00161 {
00162         perf::Timer timer("model::render");
00163         ASSERT(rq, "null");
00164 
00165 //      position.dump("drawing here");
00166 
00167         // set up all vertices
00168         glEnable(GL_VERTEX_ARRAY);
00169         glVertexPointer(3, GL_FLOAT, 0, vertices);
00170 
00171 //      DPRINTF("Drawing object");
00172 
00173         // render all polygons
00174         for (int i = 0; i < nPolygons; ++i) {
00175                 const polygon_t& p = polygons[i];
00176                 ASSERT(p.material, "null");     // should always have material!
00177 
00178                 if (p.material->texture_id) {
00179                         if (p.material->isTransparent) {
00180                                 poly_request_t * pr = rq->grabRequestSlot();
00181                                 if (pr) {
00182                                         queuePolygon(vertices, p, *pr);
00183                                 } else {
00184                                 //      DPRINTF("No more request slots!");
00185                                 }
00186                         } else {
00187                                 renderTexturePolygon(vertices, p);
00188                         }
00189                 } else {
00190                         renderColorPolygon(p);
00191                 }
00192         }
00193 
00194         // clean up
00195         glDisable(GL_VERTEX_ARRAY);
00196 }
00197 
00198 
00199 
00200 void
00201 lod_model_t::render
00202 (
00203 IN const render_context_t& rc,
00204 IN RenderQueue * rq
00205 )
00206 {
00207         ASSERT(rq, "null");
00208 
00209         // for now, just draw first model!
00210         if (nEntries < 1) {
00211                 return;         // empty!
00212         }
00213 
00214         entries[0].model.render(rc, rq);
00215 }
00216 
00217 
00218 
00219 };      // glut namespace
00220