Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Projection.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id: Projection.cpp,v 1.6 2002/03/12 10:46:07 tksuoran Exp $
00022 */
00023 
00024 
00025 #include "Teddy/TeddyConfig.h"
00026 #include "Teddy/Graphics/Texture.h"
00027 #include "Teddy/Graphics/View.h"
00028 #include "Teddy/Materials/Material.h"
00029 #include "Teddy/PhysicalComponents/EventListener.h"
00030 #include "Teddy/PhysicalComponents/Projection.h"
00031 #include "Teddy/Scenes/Camera.h"
00032 #include "Teddy/SysSupport/Messages.h"
00033 #include "Teddy/SysSupport/StdIO.h"
00034 #ifndef SWIG
00035 #include "cassert"
00036 #endif
00037 using namespace Teddy::Graphics;
00038 using namespace Teddy::Scenes;
00039 
00040 
00041 namespace Teddy              {
00042 namespace PhysicalComponents {
00043 
00044 
00045 int Projection::material_skip_count = 0;
00046 
00047 
00049 Projection::Projection( const std::string &name, Camera *camera )
00050 :
00051 Area  ( name   ),
00052 camera( camera )
00053 {
00054     options           = Area::CLEAR | Area::CLIP_RENDERING;
00055     drawing_ordering  = separate_self;  //  Separate drawSelf() invocation
00056     active_material   = NULL;
00057     active_texture    = NULL;
00058     clear_color       = Color::BLACK;
00059     render_pass_count = 0;
00060     master_material   = new Material( "Projection master material", Material::RENDER_OPTION_ALL_M );
00061     master_material->setMode    ( Material::RENDER_MODE_FILL_OUTLINE );
00062     master_material->setLighting( Material::RENDER_LIGHTING_SIMPLE );
00063     master_material->setAmbient ( Color::GRAY_25 );
00064     master_material->setDiffuse ( Color::GRAY_50 );
00065     master_material->setSpecular( Color::GRAY_25 );
00066     master_material->setBorder  ( Color::BLACK   );
00067     setSelect( Material::RENDER_OPTION_ALL_M );
00068 
00069     fill_free_size_relative = Vector2( 1.0f, 1.0f );
00070 }
00071 
00072 
00074 /*virtual*/ Projection::~Projection(){
00075 }
00076 
00077 
00079 /*virtual*/ Area *Projection::getHit( const Vector2 &pos ){
00080     dmsg( M_WM, "Try Projection Area" );
00081 
00082     if( rect.hit(pos) ){
00083         dmsg( M_WM, "Hit Projection Area" );
00084         return this;
00085     }
00086 
00087 /*  wm_debug_msg( "Begin Layer Children" );
00088     list<Area*>::iterator a_it = areas.begin();
00089     while( a_it != areas.end() ){
00090         Area *hit = (*a_it)->getHit( x, y );
00091         if( hit != NULL ){
00092             return hit;
00093         }
00094         a_it++;
00095     }
00096     wm_debug_msg( "End Layer Children" );*/
00097 
00098     return NULL;
00099 }
00100 
00101 
00103 void Projection::doMaterial( Material *m ){
00104     render_pass = 0;
00105 
00106     if( render_pass_count==1 ){
00107         if( (active_material==m) || (m==NULL) ){
00108             dmsg( M_MAT, "already active material %s reset", m->getName().c_str() );
00109             material_skip_count++;
00110             return;
00111         }
00112     }
00113 
00114     render_pass_count = 1;
00115 
00116     if( isEnabled(Area::PICK) ){
00117         return;
00118     }
00119 
00120     if( m == NULL ){
00121         dmsg( M_MAT, "NULL material" );
00122     }
00123 
00124     active_material = m;
00125 
00126     dmsg( M_MAT, "Activating material %s", m->getName().c_str() );
00127 
00128     materialReapplyActive();
00129 }
00130 
00131 
00133 void Projection::materialReapplyActive(){
00134     Material *m = active_material;
00135 
00136     Uint8 l = MIN( m->getLighting(), master_material->getLighting() );
00137     if( l >= Material::RENDER_LIGHTING_PRIMARY_LIGHT_ONLY ){
00138         view->enable( View::LIGHTING );
00139     }else{
00140         view->disable( View::LIGHTING );
00141     }
00142 
00143     //  Apply rendering options
00144     Uint32 mask_select = m->getOptions() & render_options_selection_mask.getOptions();
00145     Uint32 mask_enable = mask_select & master_material->getOptions();
00146     for( int i=0; i<32; i++ ){
00147 //      bool no_master = (render_options_selection_mask.getOptions() >> i ) & 1 == 1;
00148         bool select    = (mask_select>>i) & 1 == 1;  // true if select material, false if select projection
00149         bool enable    = (mask_enable>>i) & 1 == 1;  // true if enabled, false if disabled
00150         Material *selected_material = select ? m : master_material;
00151 
00152         if( Material::getFeature(i) != 0 ){
00153             view->setState( Material::getFeature(i), enable );
00154         }else if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_MASTER_LIGHTING_ONLY_M) ){
00155             switch( i ){
00156             case 16l/*Material::RENDER_OPTION_AMBIENT*/:   selected_material->applyAmbient  (l); break;
00157             case 17l/*Material::RENDER_OPTION_DIFFUSE*/:   selected_material->applyDiffuse  (l); break;
00158             case 18l/*Material::RENDER_OPTION_SPECULAR*/:  selected_material->applySpecular (l); break;
00159             case 19l/*Material::RENDER_OPTION_EMISSION*/:  selected_material->applyEmission (l); break;
00160             case 20l/*Material::RENDER_OPTION_SHINYNESS*/: selected_material->applyShinyness(l); break;
00161 //          case Material::RENDER_OPTION_REMOVE_HIDDEN:  if( select ){ applyRemoveHidden (); } break;
00162 //          case Material::RENDER_OPTION_FRUSTUM_CULL:   if( select ){ applyFrustumCull  (); } break;
00163 //          case Material::RENDER_OPTION_SORT_INSTANCES: if( select ){ applySortInstances(); } break;
00164 //          case Material::RENDER_OPTION_SORT_ELEMENTS:  if( select ){ applySortElements (); } break;
00165             default:
00166                 break;
00167             }
00168         }
00169     }  //  for all features
00170 
00171     unsigned long master_mode = master_material->getMode();
00172 
00173     if( master_mode == Material::RENDER_MODE_FILL_OUTLINE ){
00174         //printf( "materialReapplyActive() render_pass_count = 2\n" );
00175         render_pass_count = 2;
00176     }else{
00177         if( render_pass_count != 1 ){
00178             dmsg( M_MAT, "materialReapplyActive() render_pass_count = 1\n" );
00179             render_pass_count = 1;
00180         }
00181 
00182     }
00183 }
00184 
00185 
00187 bool Projection::materialPass(){
00188     render_pass++;
00189 
00190     if( render_pass <= render_pass_count ){
00191 
00192         if( isEnabled(Area::PICK) ){
00193             return true;
00194         }
00195 
00196         if( active_material == NULL ){
00197             false;
00198         }
00199 
00200         float    polygon_offset = 2;
00201         Texture *t              = NULL;
00202 
00203         if( active_material->getPolygonOffset() == 1 ){
00204             polygon_offset -= 1;
00205         }
00206 
00207 /*&& (t != active_texture)*/
00208         
00209         switch( render_pass ){
00210         case 1: {
00211             //  Apply polygon rendering mode
00212             switch(  MIN( active_material->getMode(), master_material->getMode() )  ){
00213             case 1/*Material::RENDER_MODE_POINT*/:        view->setPolygonMode( GL_POINT ); break;
00214             case 2/*Material::RENDER_MODE_LINE*/:         view->setPolygonMode( GL_LINE  ); break;
00215             case 3/*Material::RENDER_MODE_FILL*/:         view->setPolygonMode( GL_FILL  ); break;
00216             case 4/*Material::RENDER_MODE_FILL_OUTLINE*/: view->setPolygonMode( GL_FILL  ); break;
00217             default: break;
00218             }
00219 
00220             t = active_material->getTexture();
00221             if( 
00222                 (t!=NULL)            && 
00223                 (t->isGood()==true)  && 
00224                 master_material->isEnabled(Material::RENDER_OPTION_TEXTURE_2D_M) 
00225             ){
00226                 active_texture = t;
00227                 view->setTexture( t );
00228                 view->enable( View::TEXTURE_2D );
00229             }else{
00230                 view->disable( View::TEXTURE_2D );
00231             }
00232 
00233         } break;
00234 
00235         case 2: {
00236             if( master_material->getMode() == Material::RENDER_MODE_FILL_OUTLINE ){
00237                 polygon_offset += -1;
00238             }
00239 
00240             Uint32 mask_select = *active_material & render_options_selection_mask;
00241 
00242             bool select = (mask_select>>Material::RENDER_OPTION_BORDER) & 1 == 1;  // true if select material, false if select projection
00243 
00244             //  Borders are rendered without lighting.
00245             view->disable       ( View::POLYGON_OFFSET );
00246             view->disable       ( View::LIGHTING       );
00247             view->disable       ( View::TEXTURE_2D     );
00248             view->setPolygonMode( GL_LINE        );
00249 
00250             //  ..using either material or projection color setting
00251             if( select ){
00252                 active_material->applyBorder( Material::RENDER_LIGHTING_COLOR );
00253             }else{
00254                 master_material->applyBorder( Material::RENDER_LIGHTING_COLOR );
00255             }
00256 
00257         } break;
00258 
00259         default:
00260             break;
00261         }
00262 
00263         if( polygon_offset != 0 ){
00264             view->enable( View::POLYGON_OFFSET );
00265             glPolygonOffset( 2, polygon_offset );
00266         }else{
00267             view->disable( View::POLYGON_OFFSET );
00268         }
00269 
00270         return true;
00271     }else{
00272         return false;
00273     }
00274 }
00275 
00276 
00278 /*virtual*/ void Projection::drawSelf(){
00279     glViewport( (int)rect.min[0], (int)(view->getSize()[1]-rect.max[1]), (int)size[0], (int)size[1] );
00280 
00281     if( isEnabled(Area::CLIP_RENDERING) ){
00282 #       if !defined( USE_TINY_GL )
00283         glScissor( (int)rect.min[0], (int)(view->getSize()[1]-rect.max[1]), (int)size[0], (int)size[1] );
00284         view->enable( View::SCISSOR_TEST );
00285 #       endif
00286     }
00287 
00288 #   if !defined( USE_TINY_GL )
00289     if( isEnabled(Area::CLEAR) ){
00290         glClearDepth( 1 );
00291         glClearColor( clear_color.rgba[0], clear_color.rgba[1], clear_color.rgba[2], clear_color.rgba[3] );
00292         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00293 //      glClear( GL_DEPTH_BUFFER_BIT );
00294 
00295     }
00296 #   endif
00297 
00298     //  Set projection global settings
00299 
00300     if( render_options_selection_mask.isEnabled(Material::RENDER_OPTION_MASTER_LIGHTING_ONLY_M) ){
00301         Uint8 l = master_material->getLighting();
00302         if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_AMBIENT_M  ) ){ master_material->applyAmbient  (l); }
00303         if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_DIFFUSE_M  ) ){ master_material->applyDiffuse  (l); }
00304         if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_SPECULAR_M ) ){ master_material->applySpecular (l); }
00305         if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_EMISSION_M ) ){ master_material->applyEmission (l); }
00306         if( render_options_selection_mask.isDisabled(Material::RENDER_OPTION_SHINYNESS_M) ){ master_material->applyShinyness(l); }
00307     }
00308 
00309     //  Make sure first material is always applied
00310     active_material = NULL;
00311     view->disable( View::TEXTURE_2D );
00312     material_skip_count = 0;
00313     camera->projectScene( this );
00314 
00315 #if !defined( USE_TINY_GL )
00316     view->disable( View::SCISSOR_TEST );
00317     glScissor( 0, 0, view->getSize()[0], view->getSize()[1] );
00318 #endif
00319 }
00320 
00321 
00323 Camera *Projection::getCamera(){
00324     return this->camera;
00325 }
00326 
00327 
00329 void Projection::setCamera( Camera *c ){
00330     this->camera = c;
00331 }
00332 
00333 
00335 Options &Projection::getSelect(){
00336     return render_options_selection_mask;
00337 }
00338 
00339 
00341 void Projection::setSelect( unsigned long select ){
00342     render_options_selection_mask = select;
00343 }
00344 
00345 
00347 void Projection::enableSelect( unsigned long select ){
00348     render_options_selection_mask |= select;
00349 }
00350 
00351 
00353 void Projection::disableSelect( unsigned long select ){
00354     render_options_selection_mask &= ~select;
00355 }
00356 
00357 
00359 void Projection::pickState( const bool state ){
00360     if( state == true ){
00361         enable ( Area::PICK );
00362     }else{
00363         disable( Area::PICK );
00364     }
00365 
00366     active_material = NULL;
00367     active_texture  = NULL;
00368 }
00369 
00370 
00372 Material *Projection::getMaster(){
00373     return master_material;
00374 }
00375 
00376 
00378 void Projection::setClearColor( Color c ){
00379     this->clear_color = c;
00380 }
00381 
00382 
00384 Color Projection::getClearColor(){
00385     return this->clear_color;
00386 }
00387 
00388 
00390 void Projection::setProjectionMatrix(){
00391     view->setProjectionMatrix();
00392 }
00393 
00394 
00396 void Projection::setProjectionMatrix( Matrix &m ){
00397     view->setProjectionMatrix( m );
00398 }
00399 
00400 
00402 void Projection::setModelViewMatrix(){
00403     view->setModelViewMatrix();
00404 }
00405 
00406 
00408 void Projection::setModelViewMatrix( Matrix &m ){
00409     view->setModelViewMatrix( m );
00410 }
00411 
00412 
00414 Model *Projection::pick( const Vector2 &pos ){
00415     Vector2 my_pos( pos );
00416     my_pos[1] = this->view->getSize()[1] - pos[1];
00417     return camera->pick( this, my_pos );
00418 }
00419 
00420 
00421 float Projection::getRatio(){
00422     return size[0] / size[1];
00423 }
00424 
00425 
00426 };  //  namespace PhysicalComponents
00427 };  //  namespace Teddy
00428