1717#include " ../framework/Timer.h"
1818#include " ../framework/UniformBlockArray.h"
1919#include " ../framework/directories.h"
20+ #include " ../framework/MousePole.h"
21+ #include " ../framework/Interpolators.h"
22+ #include " LightEnv.h"
2023#include < glm/glm.hpp>
2124#include < glm/gtc/type_ptr.hpp>
2225#include < glm/gtc/matrix_transform.hpp>
@@ -28,6 +31,7 @@ struct ProgramData
2831 GLuint theProgram;
2932
3033 GLuint modelToCameraMatrixUnif;
34+ GLuint numberOfLightsUnif;
3135};
3236
3337struct UnlitProgData
@@ -45,7 +49,7 @@ ProgramData g_progStandard;
4549UnlitProgData g_progUnlit;
4650
4751const int g_projectionBlockIndex = 0 ;
48- const int g_lightBlockIndex = 0 ;
52+ const int g_lightBlockIndex = 1 ;
4953const int g_colorTexUnit = 0 ;
5054
5155ProgramData LoadProgram (const std::string &strVertexShader, const std::string &strFragmentShader)
@@ -58,10 +62,14 @@ ProgramData LoadProgram(const std::string &strVertexShader, const std::string &s
5862 ProgramData data;
5963 data.theProgram = Framework::CreateProgram (shaderList);
6064 data.modelToCameraMatrixUnif = glGetUniformLocation (data.theProgram , " modelToCameraMatrix" );
65+ data.numberOfLightsUnif = glGetUniformLocation (data.theProgram , " numberOfLights" );
6166
6267 GLuint projectionBlock = glGetUniformBlockIndex (data.theProgram , " Projection" );
6368 glUniformBlockBinding (data.theProgram , projectionBlock, g_projectionBlockIndex);
6469
70+ GLuint lightBlockIndex = glGetUniformBlockIndex (data.theProgram , " Light" );
71+ glUniformBlockBinding (data.theProgram , lightBlockIndex, g_lightBlockIndex);
72+
6573 GLuint colorTextureUnif = glGetUniformLocation (data.theProgram , " diffuseColorTex" );
6674 glUseProgram (data.theProgram );
6775 glUniform1i (colorTextureUnif, g_colorTexUnit);
@@ -100,6 +108,7 @@ struct ProjectionBlock
100108};
101109
102110GLuint g_projectionUniformBuffer = 0 ;
111+ GLuint g_lightUniformBuffer = 0 ;
103112GLuint g_linearTexture = 0 ;
104113// GLuint g_gammaTexture = 0;
105114
@@ -175,89 +184,23 @@ glutil::ViewData g_initialView =
175184
176185glutil::ViewScale g_initialViewScale =
177186{
178- 5 .0f ,
179- 90 .0f ,
180- 2 .0f ,
181- 0 .5f ,
182- 4 .0f ,
183- 1 .0f ,
187+ 5 .0f , 90 .0f ,
188+ 2 .0f , 0 .5f ,
189+ 4 .0f , 1 .0f ,
184190 90 .0f /250 .0f
185191};
186192
187193glutil::ViewPole g_viewPole (g_initialView, g_initialViewScale, glutil::MB_LEFT_BTN);
188194
189-
190195namespace
191196{
192- int calc_glut_modifiers ()
193- {
194- int ret = 0 ;
195-
196- int modifiers = glutGetModifiers ();
197- if (modifiers & GLUT_ACTIVE_SHIFT)
198- ret |= glutil::MM_KEY_SHIFT;
199- if (modifiers & GLUT_ACTIVE_CTRL)
200- ret |= glutil::MM_KEY_CTRL;
201- if (modifiers & GLUT_ACTIVE_ALT)
202- ret |= glutil::MM_KEY_ALT;
203-
204- return ret;
205- }
206-
207- void MouseMotion (int x, int y)
208- {
209- g_viewPole.MouseMove (glm::ivec2 (x, y));
210- glutPostRedisplay ();
211- }
212-
213-
214- void MouseButton (int button, int state, int x, int y)
215- {
216- int modifiers = calc_glut_modifiers ();
217-
218- glm::ivec2 mouseLoc = glm::ivec2 (x, y);
219-
220- glutil::MouseButtons eButton;
221-
222- switch (button)
223- {
224- case GLUT_LEFT_BUTTON:
225- eButton = glutil::MB_LEFT_BTN;
226- break ;
227- case GLUT_MIDDLE_BUTTON:
228- eButton = glutil::MB_MIDDLE_BTN;
229- break ;
230- case GLUT_RIGHT_BUTTON:
231- eButton = glutil::MB_RIGHT_BTN;
232- break ;
233- #ifdef LOAD_X11
234- // Linux Mouse wheel support
235- case 3 :
236- {
237- g_viewPole.MouseWheel (1 , modifiers, mouseLoc);
238- return ;
239- }
240- case 4 :
241- {
242- g_viewPole.MouseWheel (-1 , modifiers, mouseLoc);
243- return ;
244- }
245- #endif
246- default :
247- return ;
248- }
249-
250- g_viewPole.MouseClick (eButton, state == GLUT_DOWN, modifiers, glm::ivec2 (x, y));
251- glutPostRedisplay ();
252- }
253-
254- void MouseWheel (int wheel, int direction, int x, int y)
255- {
256- g_viewPole.MouseWheel (direction, calc_glut_modifiers (), glm::ivec2 (x, y));
257- glutPostRedisplay ();
258- }
197+ void MouseMotion (int x, int y) { Framework::ForwardMouseMotion (g_viewPole, x, y); }
198+ void MouseButton (int button, int state, int x, int y) { Framework::ForwardMouseButton (g_viewPole, button, state, x, y); }
199+ void MouseWheel (int wheel, int direction, int x, int y) { Framework::ForwardMouseWheel (g_viewPole, wheel, direction, x, y); }
259200}
260201
202+ LightEnv *g_pLightEnv = NULL ;
203+
261204Framework::Mesh *g_pTerrain = NULL ;
262205Framework::Mesh *g_pSphere = NULL ;
263206
@@ -266,6 +209,8 @@ void init()
266209{
267210 try
268211 {
212+ g_pLightEnv = new LightEnv (" LightEnv.xml" );
213+
269214 InitializePrograms ();
270215
271216 g_pTerrain = new Framework::Mesh (" terrain.xml" );
@@ -302,6 +247,13 @@ void init()
302247 glBindBufferRange (GL_UNIFORM_BUFFER, g_projectionBlockIndex, g_projectionUniformBuffer,
303248 0 , sizeof (ProjectionBlock));
304249
250+ glGenBuffers (1 , &g_lightUniformBuffer);
251+ glBindBuffer (GL_UNIFORM_BUFFER, g_lightUniformBuffer);
252+ glBufferData (GL_UNIFORM_BUFFER, sizeof (LightBlock), NULL , GL_STREAM_DRAW);
253+
254+ glBindBufferRange (GL_UNIFORM_BUFFER, g_lightBlockIndex, g_lightUniformBuffer,
255+ 0 , sizeof (LightBlock));
256+
305257 glBindBuffer (GL_UNIFORM_BUFFER, 0 );
306258
307259 LoadTextures ();
@@ -322,26 +274,36 @@ bool g_useGammaDisplay = false;
322274// If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
323275void display ()
324276{
325- glClearColor (0 .75f , 0 .75f , 1 .0f , 1 .0f );
326- glClearDepth (1 .0f );
327- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
328277 if (g_useGammaDisplay)
329278 glEnable (GL_FRAMEBUFFER_SRGB);
330279 else
331280 glDisable (GL_FRAMEBUFFER_SRGB);
332281
333- if (g_pSphere && g_pTerrain)
334- {
335- glutil::MatrixStack modelMatrix;
282+ g_pLightEnv->UpdateTime ();
283+
284+ glm::vec4 bgColor = g_pLightEnv->GetBackgroundColor ();
285+ glClearColor (bgColor.x , bgColor.y , bgColor.z , bgColor.w );
286+ glClearDepth (1 .0f );
287+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
288+
289+ glutil::MatrixStack modelMatrix;
290+ modelMatrix.ApplyMatrix (g_viewPole.CalcMatrix ());
291+
292+ LightBlock lightData = g_pLightEnv->GetLightBlock (g_viewPole.CalcMatrix ());
336293
337- modelMatrix.ApplyMatrix (g_viewPole.CalcMatrix ());
294+ glBindBuffer (GL_UNIFORM_BUFFER, g_lightUniformBuffer);
295+ glBufferData (GL_UNIFORM_BUFFER, sizeof (LightBlock), &lightData, GL_STREAM_DRAW);
296+ glBindBuffer (GL_UNIFORM_BUFFER, 0 );
338297
298+ if (g_pSphere && g_pTerrain)
299+ {
339300 glutil::PushStack push (modelMatrix);
340301 modelMatrix.RotateX (-90 .0f );
341302
342303 glUseProgram (g_progStandard.theProgram );
343304 glUniformMatrix4fv (g_progStandard.modelToCameraMatrixUnif , 1 , GL_FALSE,
344305 glm::value_ptr (modelMatrix.Top ()));
306+ glUniform1i (g_progStandard.numberOfLightsUnif , g_pLightEnv->GetNumLights ());
345307
346308 glActiveTexture (GL_TEXTURE0 + g_colorTexUnit);
347309 glBindTexture (GL_TEXTURE_2D, g_linearTexture);
@@ -357,6 +319,23 @@ void display()
357319
358320 push.ResetStack ();
359321
322+ // Render the sun
323+ {
324+ glm::vec3 sunlightDir (g_pLightEnv->GetSunlightDirection ());
325+ modelMatrix.Translate (sunlightDir * 500 .0f );
326+ modelMatrix.Scale (30 .0f , 30 .0f , 30 .0f );
327+
328+ glUseProgram (g_progUnlit.theProgram );
329+ glUniformMatrix4fv (g_progUnlit.modelToCameraMatrixUnif , 1 , GL_FALSE,
330+ glm::value_ptr (modelMatrix.Top ()));
331+
332+ glm::vec4 lightColor = g_pLightEnv->GetSunlightIntensity (), gamma;
333+ glUniform4fv (g_progUnlit.objectColorUnif , 1 , glm::value_ptr (lightColor));
334+ g_pSphere->Render (" flat" );
335+ }
336+
337+
338+ push.ResetStack ();
360339
361340 if (g_bDrawCameraPos)
362341 {
@@ -387,7 +366,7 @@ void display()
387366void reshape (int w, int h)
388367{
389368 glutil::MatrixStack persMatrix;
390- persMatrix.Perspective (60 .0f , (h / (float )w ), g_fzNear, g_fzFar);
369+ persMatrix.Perspective (60 .0f , (w / (float )h ), g_fzNear, g_fzFar);
391370
392371 ProjectionBlock projData;
393372 projData.cameraToClipMatrix = persMatrix.Top ();
@@ -412,8 +391,10 @@ void keyboard(unsigned char key, int x, int y)
412391 case 27 :
413392 delete g_pSphere;
414393 delete g_pTerrain;
394+ delete g_pLightEnv;
415395 g_pSphere = NULL ;
416396 g_pTerrain = NULL ;
397+ g_pLightEnv = NULL ;
417398 glutLeaveMainLoop ();
418399 return ;
419400 case ' a' :
@@ -422,7 +403,25 @@ void keyboard(unsigned char key, int x, int y)
422403 case 32 :
423404 g_useGammaDisplay = !g_useGammaDisplay;
424405 break ;
406+ case ' -' : g_pLightEnv->RewindTime (1 .0f ); break ;
407+ case ' =' : g_pLightEnv->FastForwardTime (1 .0f ); break ;
425408 case ' t' : g_bDrawCameraPos = !g_bDrawCameraPos; break ;
409+ case ' r' :
410+ {
411+ bool isPaused = g_pLightEnv->IsPaused ();
412+ float elapsed = g_pLightEnv->GetElapsedTime ();
413+ delete g_pLightEnv;
414+
415+ g_pLightEnv = new LightEnv (" LightEnv.xml" );
416+ g_pLightEnv->SetPause (isPaused);
417+ g_pLightEnv->FastForwardTime (elapsed);
418+
419+ printf (" Elapsed: %f\n " , elapsed);
420+ }
421+ break ;
422+ case ' p' :
423+ g_pLightEnv->TogglePause ();
424+ break ;
426425 }
427426
428427 if ((' 1' <= key) && (key <= ' 9' ))
0 commit comments