map-drawer.cpp

Go to the documentation of this file.
00001 /*
00002  * map-drawer.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  *
00031  * Implementation of a aesop terminal.  Manages display in particular.
00032  */
00033 
00034 // includes --------------------------------------------------------------------
00035 #include "map-kdtree.h"                 // always list our own header first!
00036 
00037 #include "glut/frustum.h"
00038 #include "perf/perf.h"
00039 
00040 
00041 
00042 namespace aesop {
00043 
00044 
00045 ////////////////////////////////////////////////////////////////////////////////
00046 //
00047 //      static helper methods
00048 //
00049 ////////////////////////////////////////////////////////////////////////////////
00050 
00051 static void
00052 drawObject
00053 (
00054 IN glut::Renderable * model,
00055 IN const glut::render_context_t& rc,
00056 IN glut::RenderQueue * rq,
00057 IN void * context
00058 )
00059 {
00060         ASSERT(model, "null");
00061         map_draw_stats_t * stats = (map_draw_stats_t *) context;
00062         ASSERT(stats, "null context");
00063         ASSERT(rq, "null");
00064 
00065 //      DPRINTF("Drawing instance of type '%s'", instance->getTypeId());
00066 //      instance->getPlacement().position.dump("  at");
00067 
00068         // update model view to correspond to placement
00069         glMatrixMode(GL_MODELVIEW);
00070         glPushMatrix();
00071         glut::setPlacement(rc.placement);
00072 
00073         // increment count, and render
00074         stats->nObjects++;
00075         model->render(rc, rq);
00076 
00077         // clean up
00078         glMatrixMode(GL_MODELVIEW);
00079         glPopMatrix();
00080 }
00081 
00082 
00083 
00084 static void
00085 setLights
00086 (
00087 void
00088 )
00089 {
00090         // basic enabling
00091         glEnable(GL_LIGHTING);
00092         glEnable(GL_LIGHT0);
00093         glShadeModel(GL_SMOOTH);
00094 
00095         // direction
00096         float lightDir[] = { 1, 0.5, -0.2, 0 };
00097         glLightfv(GL_LIGHT0, GL_POSITION, lightDir);
00098 
00099         // ambient white light
00100         float lightAmbient[] = { 0.4, 0.4, 0.4, 1.0 };
00101         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightAmbient);
00102 
00103         // set light parameters
00104         float lightOn[] = { 1, 1, 1, 1 };
00105         float lightOff[] = { 0, 0, 0, 1 };
00106 
00107         glLightfv(GL_LIGHT0, GL_DIFFUSE, lightOn);
00108         glLightfv(GL_LIGHT0, GL_AMBIENT, lightOff);
00109         glLightfv(GL_LIGHT0, GL_SPECULAR, lightOn);
00110 }
00111 
00112 
00113 
00114 ////////////////////////////////////////////////////////////////////////////////
00115 //
00116 //      public API
00117 //
00118 ////////////////////////////////////////////////////////////////////////////////
00119 
00120 void
00121 drawMap
00122 (
00123 IN MapKdTree * mapKdTree,
00124 IN const glut::render_context_t& rc,
00125 IN glut::RenderQueue * rq,
00126 OUT map_draw_stats_t& stats
00127 )
00128 {
00129         perf::Timer timer("drawMap");
00130         ASSERT(mapKdTree, "null");
00131         ASSERT(rq, "null");
00132         stats.clear();
00133 
00134         // enable global glut capabilities
00135         glEnable(GL_DEPTH_TEST);
00136         glEnable(GL_CULL_FACE);
00137         glDisable(GL_BLEND);
00138 //      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00139 
00140         // polygon mode
00141         int wire = 0;
00142         if (wire) {
00143                 glPolygonMode(GL_FRONT, GL_LINE);
00144         } else {
00145                 glPolygonMode(GL_FRONT, GL_FILL);
00146         }
00147 
00148         // clear buffers
00149         {
00150 //              perf::Timer timer("map-draw:clear"); - on the order of 0.13ms per buffer
00151                 if (wire) {
00152                         glClearColor(0.0, 0.0, 0.9, 1.0);
00153                         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00154                 } else {
00155                         glClear(GL_DEPTH_BUFFER_BIT);
00156                 }
00157         }
00158 
00159         // ambient lighting
00160         // TODO: map should specify this!
00161         setLights();
00162 
00163         glColor4f(1.0, 1.0, 1.0, 1.0);
00164 
00165         // set up camera and projection matrices
00166         glut::setOpenGLProjection(rc.camera);
00167         glut::setOpenGLViewer(rc.viewer);
00168 
00169         // okay, draw everything in regular leaf zones
00170         mapKdTree->walkFrontToBack(rc, rq, drawObject, &stats);
00171 
00172         // now handle transparencies etc
00173         glEnable(GL_BLEND);
00174         glEnable(GL_TEXTURE_2D);
00175         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00176 
00177         // reset modelview matrix (queued polygons should be transformed
00178         // already)
00179         glMatrixMode(GL_MODELVIEW);
00180         glPushMatrix();
00181         glLoadIdentity();
00182         {
00183                 perf::Timer timer("map-drawer:transparent");
00184                 while (glut::poly_request_t * pr = rq->popRequest()) {
00185                         if (pr->nVertices < 3 || pr->textureId < 1)
00186                                 continue;       // skip these
00187 
00188                         // bind texture and normal
00189                         glBindTexture(GL_TEXTURE_2D, pr->textureId);
00190                         glNormal3fv((GLfloat *) &pr->normal.x);
00191 
00192                         // send vertices
00193                         glBegin(GL_POLYGON);
00194                         for (int i = 0; i < pr->nVertices; ++i) {
00195                                 glTexCoord2f(pr->u[i], pr->v[i]);
00196                                 glVertex3fv((GLfloat *) &pr->vertex[i].x);
00197                         }
00198                         glEnd();
00199                 }
00200         }
00201         glPopMatrix();
00202 
00203         // disable everything we enabled
00204         glDisable(GL_BLEND);
00205         glDisable(GL_TEXTURE_2D);
00206         glDisable(GL_CULL_FACE);
00207         glDisable(GL_LIGHT0);
00208 //      glDisable(GL_LIGHT1);
00209         glDisable(GL_LIGHTING);
00210         glDisable(GL_DEPTH_TEST);
00211 
00212         // quickly draw frustum
00213 //      frustum_t f;
00214 //      glut::getViewFrustum(rc.camera, rc.viewer, f);
00215 //      glut::drawFrustumEdges(f, glut_color_t(.9, .9, .9));
00216 }
00217 
00218 
00219 };              // aesop namespace
00220