00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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;
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 Projection::~Projection(){
00075 }
00076
00077
00079 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
00088
00089
00090
00091
00092
00093
00094
00095
00096
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
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
00148 bool select = (mask_select>>i) & 1 == 1;
00149 bool enable = (mask_enable>>i) & 1 == 1;
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: selected_material->applyAmbient (l); break;
00157 case 17l: selected_material->applyDiffuse (l); break;
00158 case 18l: selected_material->applySpecular (l); break;
00159 case 19l: selected_material->applyEmission (l); break;
00160 case 20l: selected_material->applyShinyness(l); break;
00161
00162
00163
00164
00165 default:
00166 break;
00167 }
00168 }
00169 }
00170
00171 unsigned long master_mode = master_material->getMode();
00172
00173 if( master_mode == Material::RENDER_MODE_FILL_OUTLINE ){
00174
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
00208
00209 switch( render_pass ){
00210 case 1: {
00211
00212 switch( MIN( active_material->getMode(), master_material->getMode() ) ){
00213 case 1: view->setPolygonMode( GL_POINT ); break;
00214 case 2: view->setPolygonMode( GL_LINE ); break;
00215 case 3: view->setPolygonMode( GL_FILL ); break;
00216 case 4: 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;
00243
00244
00245 view->disable ( View::POLYGON_OFFSET );
00246 view->disable ( View::LIGHTING );
00247 view->disable ( View::TEXTURE_2D );
00248 view->setPolygonMode( GL_LINE );
00249
00250
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 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
00294
00295 }
00296 # endif
00297
00298
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
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 };
00427 };
00428