/*************************************************************************
** main.cpp                                                             **
** --------                                                             **
**                                                                      **
** This is contains the main entry point for this demo.  The main()     **
**    routine creates and sets up the window.  In this demo we use the  **
**    built-in IGLU class IGLUMultiDisplayWindow, which allows multiple **
**    "display modes" that can be thought of as independent OpenGL      **
**    programs, or a collection of related techniques that we'd like to **
**    compare between and may need to share settings.                   **
**                                                                      **
** The code creates a window, sets its OpenGL/FLTK/IGLU properties,     **
**    specifies callbacks (most important: an initialization callback   **
**    that occurs after an OpenGL context is available), adds all the   **
**    different render modes we want to allow, creates the window (so   **
**    it is visible), then starts the main render loop by calling the   **
**    static method IGLUMultiDisplayWindow::Run().                      **
**                                                                      **
** Upon calling Run(), control passes to IGLU to create the window,     **
**    initialize OpenGL and any extensions, after which the developer   **
**    program reclaims control in the SetPreprocessOnGLInit() callback. **
**    After that callback, the render modes' Initialize() methods are   **
**    called (in the order they were added to the window), after which  **
**    rendering begins.                                                 **
**                                                                      **
** When rendering begins, your program may get control with a window    **
**    reshape, visibility, or mouse entry callback.  But more likely    **
**    the next logical step (where you'll get control again) will be in **
**    the Display() method of the currently active display mode.  (The  **
**    default active mode will be the first one added to the window.)   **
**                                                                      **
** Chris Wyman (04/06/2012)                                             **
*************************************************************************/

// A global that includes almost all of the necessary headers, data 
//    structures, and prototypes for all the main files of this demo
#include "projectIncludes.h"

// To add our display modes to the window, we need to include their
//    class definitions.
#include "DisplayModes/Mode_ParaboloidShadowMaps.h"
#include "DisplayModes/Mode_SampleVoxelsFromShadowMap.h"
#include "DisplayModes/Mode_CreateVoxelizedShadowVolumes.h"
#include "DisplayModes/Mode_VisualizeVoxelizedShadowVolumes.h"

// A global data structure containing all shared data for all the
//    display modes (and UI controls) in this program
RenderingData *data;


// Main entry point for our program
int main(int argc, char** argv)
{
	// Create our main window
	IGLUMultiDisplayWindow::Ptr myWin = new IGLUMultiDisplayWindow( 768, 768, 
		"Advanced IGLU Example:  A demonstration of a window with multiple display / rendering modes",
		600, 400 );

	myWin->SetWindowProperties( IGLU_WINDOW_NO_RESIZE |	      // This window will be non-resizable,
		                        IGLU_WINDOW_DOUBLE |          // have double buffering in the OpenGL window,
								IGLU_WINDOW_REDRAW_ON_IDLE |  // automatically redraws @ end of its idle function,
								IGLU_WINDOW_W_FRAMERATE |     // displays a framerate counter
								IGLU_WINDOW_DEPTH );          // and has a depth buffer (non needing on Windows, is on Linux)

	myWin->SetIdleCallback        ( IGLUWindow::NullIdle );   // Use an IGLU-provided empty idle function
	myWin->SetPreprocessOnGLInit  ( OpenGLInitialization );   // User-specified callback occurs once after OpenGL has been initialized
	myWin->SetActiveMotionCallback( MouseMotion );            // User-specified callback when active mouse motion occurs
	myWin->SetMouseButtonCallback ( MouseButton );            // User-specified callback when mouse buttons pressed/release

	// Create the various display modes we can use in this demo.
	myWin->AddDisplayMode( new RenderParaboloidShadowMaps() );
	myWin->AddDisplayMode( new SampleVoxelsShadowMaps() );
	myWin->AddDisplayMode( new CreateVoxelizedShadowVolumes() );
	myWin->AddDisplayMode( new VisualizeVoxelizedShadowVolumes() );
	
	// Must be called after all calls to myWin->AddDisplayMode();
	myWin->CreateWindow( argc, argv );     
	
	// Start running our IGLU OpenGL program!
	IGLUMultiDisplayWindow::Run();
	return 0;
}
