Difference between revisions of "Tutorial - Setup Horde with SFML"

From Horde3D Wiki
Jump to: navigation, search
(Fixed fullscreen toggling error)
 
(One intermediate revision by the same user not shown)
Line 47: Line 47:
 
static int benchmarkLength = 600;
 
static int benchmarkLength = 600;
  
bool setupWindow( int, int, bool, const char* title );
+
bool setupWindow( int&, int&, bool, const char* title );
 
static bool running;
 
static bool running;
 
static int mx0, my0;
 
static int mx0, my0;
Line 85: Line 85:
 
{
 
{
 
if( !running ) return;
 
if( !running ) return;
 
+
 
int width = appWidth, height = appHeight;
 
int width = appWidth, height = appHeight;
 
 
Line 97: Line 97:
 
// Toggle fullscreen mode
 
// Toggle fullscreen mode
 
fullScreen = !fullScreen;
 
fullScreen = !fullScreen;
setupWindow(appWidth, appHeight, fullScreen, app->getTitle());
+
setupWindow(width, height, fullScreen, app->getTitle());
 
app->init();
 
app->init();
 
app->resize( width, height );
 
app->resize( width, height );
 
break;
 
break;
+
//KLUDGE ALERT:  
+
//KLUDGE ALERT:  
//The samples in trunk use GLFW keycodes to set keystates
+
//The samples in trunk use GLFW keycodes to set keystates
//within Application. In order not to modify the sample code
+
//within Application. In order not to modify the sample code
//we play nice and set the GLFW keycoded array it is interested in
+
//we play nice and set the GLFW keycoded array it is interested in
 
case sf::Key::Space:
 
case sf::Key::Space:
 
app->setKeyState(32,true);
 
app->setKeyState(32,true);
Line 138: Line 138:
 
}
 
}
 
}
 
}
 
  
 
void mouseMoveListener( int x, int y )
 
void mouseMoveListener( int x, int y )
Line 153: Line 152:
  
  
bool setupWindow( int width, int height, bool fullscreen, const char* windowTitle = NULL)
+
bool setupWindow( int& width, int& height, bool fullscreen, const char* windowTitle = NULL)
 
{
 
{
 
//Initialise OpenGL context using SFML
 
//Initialise OpenGL context using SFML
Line 174: Line 173:
 
{
 
{
 
//Close the old window
 
//Close the old window
pSfmlWindow->Close();
+
//pSfmlWindow->Close();
  
 
//Initialise a new window
 
//Initialise a new window
Line 184: Line 183:
 
sf::Style::Fullscreen,
 
sf::Style::Fullscreen,
 
Settings);
 
Settings);
 +
width = pSfmlWindow->GetWidth();
 +
height = pSfmlWindow->GetHeight();
 
}
 
}
 
else
 
else
Line 202: Line 203:
 
 
 
// Initialize application and engine
 
// Initialize application and engine
app = new Application( extractAppPath(argv[0]) );
+
app = new Application( std::string(argv[0]) );
  
 
// Initialize a GLFW window
 
// Initialize a GLFW window
 
pSfmlWindow = NULL;
 
pSfmlWindow = NULL;
if( !setupWindow( appWidth, appHeight, fullScreen, app->getTitle() ) ) return -1;
+
int width = appWidth, height = appHeight;
 +
if( !setupWindow( width, height, fullScreen, app->getTitle() ) ) return -1;
 
 
 
// Check if benchmark mode is requested
 
// Check if benchmark mode is requested
Line 274: Line 276:
 
 
 
app->keyStateHandler();
 
app->keyStateHandler();
 
+
 
// Render
 
// Render
 
app->mainLoop( benchmark ? 60 : fps );
 
app->mainLoop( benchmark ? 60 : fps );
Line 322: Line 324:
 
version = 1.0|
 
version = 1.0|
 
horde3dversion = 1.0 beta|
 
horde3dversion = 1.0 beta|
released = 2008-07-31|
+
released = 2011-08-20|
 
author = Balajee.R.C (Hannofcart) |
 
author = Balajee.R.C (Hannofcart) |
 
}}
 
}}
 
|}
 
|}
 
[[category: Tutorials]]
 
[[category: Tutorials]]

Latest revision as of 07:39, 20 August 2011

Using Horde with SFML.

SFML - Simple Fast Multimedia Library is a free multimedia C++ API that provides you low and high level access to graphics, input, audio, etc.

The following example is a rewrite of main.cpp of the Horde sample - Chicago using SFML (instead of GLFW that the sample in trunk uses). To test the sample, simply replace the code in main.cpp of the Chicago sample app with this code. This code only requires SFML::Window library.


main.cpp for Chicago Sample
// *************************************************************************************************
//
// Horde3D
//   Next-Generation Graphics Engine
//
// Sample Application
// --------------------------------------
// Copyright (C) 2006-2011 Nicolas Schulz
//
//
// This sample source file is not covered by the EPL as the rest of the SDK
// and may be used without any restrictions. However, the EPL's disclaimer of
// warranty and liability shall be in effect for this file.
//
// *************************************************************************************************

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

#include <SFML/Window.hpp>

#include "app.h"

// Configuration
const int appWidth = 1024;
const int appHeight = 576;
static bool fullScreen = false;
static int benchmarkLength = 600;

bool setupWindow( int&, int&, bool, const char* title );
static bool running;
static int mx0, my0;
static Application *app;

sf::Window* pSfmlWindow;
sf::Clock RenderClock;
double timeAtLastFrame;
double timeSinceLastFrame;
double timeAtCurrentFrame;

std::string extractAppPath( char *fullPath )
{
#ifdef __APPLE__
	std::string s( fullPath );
	for( int i = 0; i < 4; ++i )
		s = s.substr( 0, s.rfind( "/" ) );
	return s + "/../";
#else
	const std::string s( fullPath );
	if( s.find( "/" ) != std::string::npos )
		return s.substr( 0, s.rfind( "/" ) ) + "/";
	else if( s.find( "\\" ) != std::string::npos )
		return s.substr( 0, s.rfind( "\\" ) ) + "\\";
	else
		return "";
#endif
}

int windowCloseListener()
{
	running = false;
	return 0;
}

void keyPressListener( int key )
{
	if( !running ) return;
	
	int width = appWidth, height = appHeight;
	
	switch (key)
	{
		case sf::Key::Escape:
			running = false;
			break;
		case sf::Key::F1:
			app->release();		
			// Toggle fullscreen mode
			fullScreen = !fullScreen;
			setupWindow(width, height, fullScreen, app->getTitle());		
			app->init();
			app->resize( width, height );
			break;
			
			//KLUDGE ALERT: 
			//The samples in trunk use GLFW keycodes to set keystates
			//within Application. In order not to modify the sample code
			//we play nice and set the GLFW keycoded array it is interested in
		case sf::Key::Space:
			app->setKeyState(32,true);
			break;
		case sf::Key::F3:
			app->setKeyState(260,true);
			break;
		case sf::Key::F6:
			app->setKeyState(263,true);
			break;
		case sf::Key::F7:
			app->setKeyState(264,true);
			break;
		case sf::Key::F8:
			app->setKeyState(265,true);
			break;
		case sf::Key::LShift:
			app->setKeyState(287,true);
			break;
		case sf::Key::W:
			app->setKeyState(int('W'),true);
			break;
		case sf::Key::A:
			app->setKeyState(int('A'),true);
			break;
		case sf::Key::S:
			app->setKeyState(int('S'),true);
			break;
		case sf::Key::D:
			app->setKeyState(int('D'),true);
			break;			
	}
}

void mouseMoveListener( int x, int y )
{
	if( !running )
	{
		mx0 = x; my0 = y;
		return;
	}

	app->mouseMoveEvent( (float)(x - mx0), (float)(my0 - y) );
	mx0 = x; my0 = y;
}


bool setupWindow( int& width, int& height, bool fullscreen, const char* windowTitle = NULL)
{	
	//Initialise OpenGL context using SFML
	sf::WindowSettings Settings;	 // Create a settings object to initialise OpenGL context with 	
	Settings.DepthBits         = 24; // Request a 24 bits depth buffer
	Settings.StencilBits       = 8;  // Request a 8 bits stencil buffer
	Settings.AntialiasingLevel = 2;  // Request 2 levels of antialiasing
	
	if(!windowTitle)
		windowTitle = "SFML Chicago sample";
	
	if (pSfmlWindow==NULL)	//First time creation
	{	
		pSfmlWindow = new sf::Window(sf::VideoMode(width, height, 32),	//Create a width * height framebuffer with 32 bits per pixel
									 windowTitle,						//Title for the window to be created
									 sf::Style::Close,					//Create a window with a titlebar and close button
									 Settings);							//Settings object to initialise the OpenGL context with		
	}
	else	//Reinitialisation of window
	{	
		//Close the old window
		//pSfmlWindow->Close();

		//Initialise a new window
		if(fullscreen)
		{	
			// Creating a fullscreen window with the best video mode supported
			pSfmlWindow->Create(sf::VideoMode::GetMode(0),
								windowTitle,
								sf::Style::Fullscreen,
								Settings);
			width = pSfmlWindow->GetWidth();
			height = pSfmlWindow->GetHeight();
		}
		else
		{	
			pSfmlWindow->Create(sf::VideoMode(width, height, 32),
								windowTitle,
								sf::Style::Close,					
								Settings);									
		}		
	}
		
	return true;
}

int main( int argc, char** argv )
{
	printf("Starting SFML Chicago!\n");
	
	// Initialize application and engine
	app = new Application( std::string(argv[0]) );

	// Initialize a GLFW window
	pSfmlWindow = NULL;
	int width = appWidth, height = appHeight;
	if( !setupWindow( width, height, fullScreen, app->getTitle() ) ) return -1;
		
	// Check if benchmark mode is requested
	bool benchmark = false;
	if( argc > 1 && strcmp( argv[1], "-bm" ) == 0 )
	{	
		benchmark = true;
		//TODO: Equivalent in SFML
		//glfwDisable( GLFW_AUTO_POLL_EVENTS );
	}
		
	if ( !app->init() )
	{
		std::cout << "Unable to initalize engine" << std::endl;
		std::cout << "Make sure you have an OpenGL 2.0 compatible graphics card";
		return -1;
	}
	
	app->resize( appWidth, appHeight );

	pSfmlWindow->ShowMouseCursor(false);

	int frames = 0;
	float fps = 30.0f;
	timeSinceLastFrame = RenderClock.GetElapsedTime();
	RenderClock.Reset();	
	timeAtCurrentFrame += timeSinceLastFrame;
	running = true;
	
	// Game loop
	while( running )
	{
		timeSinceLastFrame = RenderClock.GetElapsedTime();
		RenderClock.Reset();	
		timeAtCurrentFrame += timeSinceLastFrame;
		
		// Calc FPS
		++frames;
		if( !benchmark && frames >= 3 )
		{
			fps = frames / (float)timeSinceLastFrame;
			if( fps < 5 ) fps = 30;  // Handle breakpoints
			frames = 0;
		}
		
		//Initialise all app keys' states to false
		for( int i = 0; i < 320; ++i )
			app->setKeyState(i,false);

		// Inject inputs from SFML
		sf::Event Event;
		while (pSfmlWindow->GetEvent(Event))
		{
			// Window closed
			if (Event.Type == sf::Event::Closed)
				running = false;
			// Key Press Event
			else if (Event.Type == sf::Event::KeyPressed)
			{	
				keyPressListener(Event.Key.Code);
			}
			else if(Event.Type == sf::Event::MouseMoved)
			{
				mouseMoveListener(Event.MouseMove.X,Event.MouseMove.Y);
			}
		}
		
		app->keyStateHandler();
		
		// Render
		app->mainLoop( benchmark ? 60 : fps );		
		pSfmlWindow->Display();
		
		if( benchmark && frames == benchmarkLength ) break;
	}

	pSfmlWindow->ShowMouseCursor(true);
	
	// Show benchmark results
	if( benchmark )
	{	
		timeSinceLastFrame = RenderClock.GetElapsedTime();
		RenderClock.Reset();	
		timeAtCurrentFrame += timeSinceLastFrame;
		double avgFPS = benchmarkLength / timeSinceLastFrame;
		char title[256];
		sprintf( title, "Average FPS: %.2f", avgFPS );
		
		//Simply write the logistics to console
		printf("%s",title);
		
		//TODO: Equivalent in SFML
//		double startTime = glfwGetTime();
//		while( glfwGetTime() - startTime < 5.0 ) {}  // Sleep
	}	
	
	// Quit
	app->release();
	delete app;
	
	if(pSfmlWindow->IsOpened())
		pSfmlWindow->Close();
	
	delete pSfmlWindow;
	
	return 0;
}
Horde With SFML
H3DPlaceHolder.png
This tutorial introduces the use of Horde3D with SFML
Version: 1.0
Compatible with Horde3D: 1.0 beta
Release date: 2011-08-20
Author(s): Balajee.R.C (Hannofcart)