00001
00008 #include "scene.h"
00009
00014 TScene::TScene()
00015 {
00016 lights.clear();
00017 useHDR = useSSAO = false;
00018 use_gshader_ref = false;
00019 f_buffer = r_buffer_color = r_buffer_depth = msamples = 0;
00020 load_list = load_actual = 0;
00021 testname = "...";
00022 }
00023
00028 TScene::~TScene()
00029 {
00030 Destroy(true);
00031
00032 glDeleteLists(font2D,256);
00033 }
00034
00049 bool TScene::PreInit(GLint _resx, GLint _resy, GLfloat _near, GLfloat _far, GLfloat _fovy, int _msamples, bool cust_cam, bool load_font)
00050 {
00051 resx = _resx;
00052 resy = _resy;
00053 near_p = _near;
00054 far_p = _far;
00055 fovy = _fovy;
00056 custom_cam = cust_cam;
00057 msamples = _msamples;
00058
00059 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00060 glClearColor(0.0, 0.0, 0.0, 0.5);
00061 glClearDepth(1.0);
00062 glEnable(GL_DEPTH_TEST);
00063 glDepthFunc(GL_LEQUAL);
00064 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00065 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
00066
00067
00068
00069 Resize(resx,resy);
00070
00071
00072 if(load_font)
00073 BuildFont();
00074
00076
00077 return true;
00078 }
00079
00080
00088 bool TScene::PostInit()
00089 {
00090
00091 for(il = lights.begin(); il != lights.end(); il++)
00092 {
00093 if(il->HasShadow())
00094 {
00095 if(!CreateShadowMap(il))
00096 return false;
00097
00098
00099 for(im = materials.begin(); im != materials.end(); im++)
00100 im->second.AddShadowMap(tex_cache[il->GetShadowCache()], il->ShadowIntensity() );
00101 }
00102 }
00103 cout<<"Baking materials...\n";
00104
00105 for(im = materials.begin(); im != materials.end(); im++)
00106 {
00107
00108 if(useSSAO)
00109 im->second.UseMRT(true);
00110
00111 im->second.BakeMaterial();
00112 im->second.SetLights(lights.size());
00113 }
00114
00115 return true;
00116 }
00117
00118
00125 void TScene::Resize(GLint _resx, GLint _resy)
00126 {
00127 resx = _resx;
00128 resy = _resy;
00129 glViewport(0,0,resx,resy);
00130 glMatrixMode(GL_PROJECTION);
00131 glLoadIdentity();
00132
00133 gluPerspective(fovy,(GLfloat)resx/resy,near_p,far_p);
00134 glMatrixMode(GL_MODELVIEW);
00135 glLoadIdentity();
00136 }
00137
00138
00139
00140
00147 void TScene::Redraw(bool delete_buffer)
00148 {
00149
00150 if(useHDR || useSSAO)
00151 {
00152
00153 glViewport(0,0,RT_resX,RT_resY);
00154
00155
00156 glBindFramebufferEXT(GL_FRAMEBUFFER, f_buffer);
00157
00158 glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, render_texture, 0);
00159
00161 if(msamples > 1 && GLEW_EXT_framebuffer_multisample && !useSSAO)
00162 glBindFramebufferEXT(GL_FRAMEBUFFER, msaa_f_buffer);
00163
00164
00165 if(useSSAO)
00166 {
00167 GLenum mrt[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
00168 glDrawBuffers(2, mrt);
00169 }
00170
00171
00172 if(delete_buffer)
00173 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00174 glLoadIdentity();
00175 }
00176 else
00177 {
00178 if(delete_buffer)
00179 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00180 glLoadIdentity();
00181 }
00182
00183 if(!custom_cam)
00184 cam.RenderCamera();
00185
00187 for(il = lights.begin(); il != lights.end(); il++)
00188 {
00189 il->KeepPos();
00190 il->DrawLight(viewMatrix);
00191
00193 if(il->HasShadow() && useShadows)
00194 {
00195
00196 if(useHDR || useSSAO)
00197 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
00198
00199 RenderShadowMap(*il);
00200 if(useHDR || useSSAO)
00201 {
00202
00203 if(msamples > 1 && GLEW_EXT_framebuffer_multisample && !useSSAO)
00204 glBindFramebufferEXT(GL_FRAMEBUFFER, msaa_f_buffer);
00205 else
00206 glBindFramebufferEXT(GL_FRAMEBUFFER, f_buffer);
00207 }
00208 }
00209 }
00210
00211
00212 for(im = materials.begin(); im != materials.end(); im++)
00213 {
00214 im->second.SetUniforms("camPos",cam.GetPos(),3);
00215 if(lights.size() > 0)
00216 im->second.SetUniform("lightRadius",lights[0].GetRadius());
00217 }
00218
00220 for(io = objects.begin(); io != objects.end(); io++)
00221 if(!io->second.IsTransparent())
00222 io->second.Draw(viewMatrix);
00223
00225 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00226 glEnable(GL_BLEND);
00227 for(io = objects.begin(); io != objects.end(); io++)
00228 if(io->second.IsTransparent())
00229 io->second.Draw(viewMatrix);
00230 glDisable(GL_BLEND);
00231
00233 for(io = objects.begin(); io != objects.end(); io++)
00234
00235 if(io->second.GetReflect() > 0.0)
00236 RenderToCubeMap(&io->second);
00237
00238 if(useHDR || useSSAO)
00239 {
00240
00242 if(msamples > 1 && GLEW_EXT_framebuffer_multisample && !useSSAO)
00243 {
00244 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, msaa_f_buffer);
00245 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, f_buffer);
00246 glBlitFramebufferEXT(0, 0, resx, resy, 0, 0, resx, resy, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
00247 }
00248
00249 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
00250 glClear(GL_DEPTH_BUFFER_BIT);
00251 glViewport(0,0,RT_resX,RT_resY);
00252
00253
00254 glBindFramebufferEXT(GL_FRAMEBUFFER, f_buffer);
00255
00256 GLenum srt[] = { GL_COLOR_ATTACHMENT0 };
00257 glDrawBuffers(1, srt);
00258
00259
00260 glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, bloom_texture, 0);
00261
00262
00263 if( useHDR && !useSSAO)
00264 SetMaterial("screen_quad","mat_bloom_hdr");
00265 if(!useHDR && useSSAO)
00266 SetMaterial("screen_quad","mat_bloom_ssao");
00267 if( useHDR && useSSAO)
00268 SetMaterial("screen_quad","mat_bloom_hdr_ssao");
00269
00270
00271 glViewport(0,0,RT_resX/2,RT_resY/2);
00272
00273 objects["screen_quad"].DrawScreenQuad();
00274
00275
00276 SetMaterial("screen_quad","mat_blur_horiz");
00277 objects["screen_quad"].DrawScreenQuad();
00278
00279
00280 glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, blur_texture, 0);
00281 SetMaterial("screen_quad","mat_blur_vert");
00282 objects["screen_quad"].DrawScreenQuad();
00283
00284 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
00285
00286
00287 glViewport(0,0,resx,resy);
00288
00289 SetMaterial("screen_quad","mat_tonemap");
00290 objects["screen_quad"].DrawScreenQuad();
00291 }
00292 }
00293
00298 void TScene::LoadScreen(bool swap)
00299 {
00300 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00301
00302
00303 materials["mat_background_quad"].RenderMaterial();
00304 glBegin(GL_TRIANGLE_STRIP);
00305 glTexCoord2f(0.0f,1.0f); glVertex2f(-1.0f, 1.0f);
00306 glTexCoord2f(1.0f,1.0f); glVertex2f( 1.0f, 1.0f);
00307 glTexCoord2f(0.0f,0.0f); glVertex2f(-1.0f,-1.0f);
00308 glTexCoord2f(1.0f,0.0f); glVertex2f( 1.0f,-1.0f);
00309 glEnd();
00310
00311 DrawScreenText(testname.c_str(),50.0,50.0,1.5);
00312 DrawScreenText("Initializing, please wait... ",50.0f,45.0f,1.2f);
00313
00314 materials["mat_load_polygon"].RenderMaterial();
00315
00316
00317 load_actual--;
00318 float loaded;
00319 if(load_actual > 0)
00320 loaded = -0.7f + (float)(load_list - load_actual)/load_list;
00321 else
00322 loaded = 0.7f;
00323
00324
00325 glBegin(GL_TRIANGLE_STRIP);
00326 glTexCoord2f(0.0f,1.0f); glVertex2f(-0.7f,-0.2f);
00327 glTexCoord2f(1.0f,1.0f); glVertex2f( loaded,-0.2f);
00328 glTexCoord2f(0.0f,0.0f); glVertex2f(-0.7f,-0.3f);
00329 glTexCoord2f(1.0f,0.0f); glVertex2f( loaded,-0.3f);
00330 glEnd();
00331
00332 if(swap)
00333 SDL_GL_SwapBuffers();
00334 }
00335
00342 void TScene::Destroy(bool delete_cache)
00343 {
00344 objects.clear();
00345 materials.clear();
00346 lights.clear();
00347 cam.Reset();
00348
00349 if(delete_cache)
00350 {
00351 tex_cache.clear();
00352 obj_cache.clear();
00353 }
00354
00355
00356 if(useHDR || useSSAO)
00357 {
00358 glDeleteFramebuffers(1, &f_buffer);
00359 glDeleteRenderbuffers(1, &r_buffer_color);
00360 glDeleteRenderbuffers(1, &r_buffer_depth);
00361 glDeleteTextures(1,&render_texture);
00362 glDeleteTextures(1,&bloom_texture);
00363 glDeleteTextures(1,&normal_texture);
00364 glDeleteTextures(1,&blur_texture);
00365 }
00366
00367
00368
00369
00370
00371 cam.Reset();
00372 }
00373
00374
00380 void TScene::UseDynReflections(bool use_gs)
00381 {
00382 use_gshader_ref = use_gs;
00383
00384
00385 for(io = objects.begin(); io != objects.end(); io++)
00386 {
00387 if(io->second.GetReflect() > 0.0)
00388 if(!CreateRenderCubeMap(&io->second))
00389 throw ERR;
00390 }
00391
00392
00393 for(im = materials.begin(); im != materials.end(); im++)
00394 {
00395 if(use_gshader_ref)
00396 {
00397 im->second.UseGShaderCubeMapRender(true);
00398 if(!im->second.BakeMaterial(true))
00399 throw ERR;
00400 }
00401 }
00402 }
00403
00404
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00439 void TScene::AddTexture(const char *name, const char *file, GLint textype, GLint texmode,
00440 GLfloat intensity, GLfloat tileX, GLfloat tileY, bool mipmap, bool aniso)
00441 {
00442
00443 if(materials.find(name) == materials.end())
00444 {
00445 cerr<<"WARNING (AddTexture): no material with name "<<name<<"\n";
00446 return;
00447 }
00449 it = tex_cache.find(file);
00450 GLint cache;
00452 if( it == tex_cache.end() )
00453 cache = -1;
00455 else
00456 cache = it->second;
00458 int texID;
00459 if( (texID = materials[name].AddTexture(file,textype,texmode,intensity,tileX,tileY,mipmap,aniso,cache)) == ERR)
00460 throw ERR;
00461 tex_cache[file] = texID;
00462 LoadScreen();
00463 }
00464
00465
00479 void TScene::AddTexture(const char *name, const char **files, GLint textype, GLint texmode,
00480 GLfloat intensity, GLfloat tileX, GLfloat tileY, bool aniso)
00481 {
00482
00483 if(materials.find(name) == materials.end())
00484 {
00485 cerr<<"WARNING (AddTexture): no material with name "<<name<<"\n";
00486 return;
00487 }
00488
00489
00490 it = tex_cache.find(files[0]);
00491 GLint cache;
00493 if( it == tex_cache.end() )
00494 cache = -1;
00496 else
00497 cache = it->second;
00499 int texID;
00500 if( (texID = materials[name].AddTexture(files,textype,texmode,intensity,tileX,tileY,aniso,cache)) == ERR)
00501 throw ERR;
00502 tex_cache[files[0]] = texID;
00503 LoadScreen();
00504 }
00505
00512 void TScene::SetMaterial(const char* obj_name, const char *mat_name)
00513 {
00514
00515 if(objects.find(obj_name) == objects.end())
00516 {
00517 cerr<<"WARNING (SetMaterial): no object with name "<<obj_name<<"\n";
00518 return;
00519 }
00520
00521 if(materials.find(mat_name) == materials.end())
00522 {
00523 cerr<<"WARNING (SetMaterial): no object with name "<<mat_name<<"\n";
00524 return;
00525 }
00526 objects[obj_name].SetMaterial(&materials[mat_name]);
00527 }
00528
00536 void TScene::AddObject(const char *name, const char* file)
00537 {
00539 iob = obj_cache.find(file);
00540
00542 if( iob == obj_cache.end() )
00543 {
00544 VBO vbo_ret = objects[name].Create(name,file,true);
00545 if(vbo_ret.vao == 0)
00546 throw ERR;
00547 obj_cache[file] = vbo_ret;
00548 }
00550 else
00551 {
00552 objects[name].SetVBOdata(iob->second);
00553 objects[name].Create(name,file,false);
00554 }
00555 LoadScreen();
00556 }