Working on the testbed application

This commit is contained in:
Daniel Chappuis 2015-08-06 21:06:35 +02:00
parent c7bff41ba8
commit 5d7cb3cfd5
19 changed files with 337 additions and 103 deletions

View File

@ -43,6 +43,8 @@ SET(TESTBED_SOURCES
src/SceneDemo.cpp
src/Timer.h
src/Timer.cpp
src/PhysicsEventListener.h
src/PhysicsEventListener.cpp
)
# IMGUI source files

View File

@ -30,19 +30,6 @@
#include "openglframework.h"
#include "reactphysics3d.h"
// Structure VertexData
struct VertexData {
/// Vertex position
openglframework::Vector3 position;
/// Vertex normal
openglframework::Vector3 normal;
// Vertex color
openglframework::Color color;
};
// Class Box
class Box : public openglframework::Object3D {

View File

@ -202,6 +202,7 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name)
// Create the floor
openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f));
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC);

View File

@ -46,12 +46,12 @@ namespace collisionshapesscene {
// Constants
const float SCENE_RADIUS = 30.0f;
const int NB_BOXES = 3;
const int NB_CUBES = 0;
const int NB_CONES = 0;
const int NB_CYLINDERS = 0;
const int NB_CAPSULES = 0;
const int NB_MESHES = 0;
const int NB_COMPOUND_SHAPES = 0;
const int NB_CUBES = 5;
const int NB_CONES = 3;
const int NB_CYLINDERS = 3;
const int NB_CAPSULES = 4;
const int NB_MESHES = 4;
const int NB_COMPOUND_SHAPES = 3;
const openglframework::Vector3 BOX_SIZE(2, 2, 2);
const float SPHERE_RADIUS = 1.5f;
const float CONE_RADIUS = 2.0f;

View File

@ -77,6 +77,7 @@ CubesScene::CubesScene(const std::string& name)
// Create the floor
openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f));
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC);
@ -202,3 +203,11 @@ void CubesScene::reset() {
mBoxes[i]->resetTransform(transform);
}
}
// Return all the contact points of the scene
std::vector<ContactPoint> CubesScene::getContactPoints() const {
std::vector<ContactPoint> contactPoints;
return contactPoints;
}

View File

@ -81,6 +81,9 @@ class CubesScene : public SceneDemo {
/// Reset the scene
virtual void reset();
/// Return all the contact points of the scene
std::vector<ContactPoint> virtual getContactPoints() const;
};
}

View File

@ -447,6 +447,7 @@ void JointsScene::createFloor() {
// Create the floor
openglframework::Vector3 floorPosition(0, 0, 0);
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
mFloor->setColor(Color(0.70f, 0.70f, 0.7f, 1.0f));
// The floor must be a static rigid body
mFloor->getRigidBody()->setType(rp3d::STATIC);

View File

@ -32,7 +32,7 @@ using namespace raycastscene;
// Constructor
RaycastScene::RaycastScene(const std::string& name)
: SceneDemo(name, SCENE_RADIUS), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false),
: SceneDemo(name, SCENE_RADIUS, false), mCurrentBodyIndex(-1), mAreNormalsDisplayed(false),
mMeshFolderPath("meshes/"), mRaycastManager(mPhongShader, mMeshFolderPath),
mVBOVertices(GL_ARRAY_BUFFER) {

View File

@ -221,6 +221,9 @@ class RaycastScene : public SceneDemo {
/// Called when a keyboard event occurs
virtual void keyboardEvent(int key, int scancode, int action, int mods);
/// Enabled/Disable the shadow mapping
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
};
// Display or not the surface normals at hit points
@ -228,6 +231,12 @@ inline void RaycastScene::showHideNormals() {
mAreNormalsDisplayed = !mAreNormalsDisplayed;
}
// Enabled/Disable the shadow mapping
inline void RaycastScene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
SceneDemo::setIsShadowMappingEnabled(false);
}
}
#endif

View File

@ -26,6 +26,8 @@
// Libraries
#include "Gui.h"
#include <GLFW/glfw3.h>
#include <sstream>
#include <iomanip>
#include "TestbedApplication.h"
GLFWwindow* Gui::mWindow = NULL;
@ -42,6 +44,10 @@ openglframework::VertexArrayObject Gui::mVAO;
Gui::LeftPane Gui::mLeftPane = SCENES;
double Gui::mScrollX = 0.0;
double Gui::mScrollY = 0.0;
double Gui::mTimeSinceLastProfilingDisplay = 0;
double Gui::mCachedFPS = 0;
double Gui::mCachedUpdateTime = 0;
double Gui::mCachedPhysicsUpdateTime = 0;
// Constructor
Gui::Gui() {
@ -80,47 +86,8 @@ void Gui::init() {
fprintf(stderr, "Could not init GUI renderer.\n");
exit(EXIT_FAILURE);
}
}
void Gui::displayHeader() {
TestbedApplication& app = TestbedApplication::getInstance();
int windowWidth, windowHeight;
glfwGetWindowSize(mWindow, &windowWidth, &windowHeight);
const int button_width = 150;
int scrollarea = 0;
imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT),
app.mWindowToFramebufferRatio.x * windowWidth,
app.mWindowToFramebufferRatio.y * HEADER_HEIGHT, &scrollarea);
imguiHorizontalSpace(10);
imguiVerticalSpace(20);
imguiStartLine();
// ----- Left Pane Header ----- //
// Play/Pause
if (imguiButton(app.mTimer.isRunning() ? "Pause" : "Play", true, button_width)) {
app.togglePlayPauseSimulation();
}
imguiHorizontalSpace(5);
// Step
if (imguiButton("Step", !app.mTimer.isRunning(), button_width)) {
app.toggleTakeSinglePhysicsStep();
}
imguiHorizontalSpace(5);
// Restart
if (imguiButton("Restart", true, button_width)) {
app.restartSimulation();
}
imguiEndLine();
imguiEndScrollArea();
mTimeSinceLastProfilingDisplay = glfwGetTime();
}
void Gui::displayLeftPane() {
@ -131,7 +98,7 @@ void Gui::displayLeftPane() {
glfwGetWindowSize(mWindow, &windowWidth, &windowHeight);
int scrollarea = 0;
imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT),
imguiBeginScrollArea(NULL, 0, app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT),
app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
app.mWindowToFramebufferRatio.y * LEFT_PANE_HEADER_HEIGHT, &scrollarea);
@ -161,6 +128,7 @@ void Gui::displayLeftPane() {
}
imguiEndLine();
imguiVerticalSpace(70);
imguiSeparatorLine();
imguiVerticalSpace(5);
@ -179,10 +147,14 @@ void Gui::displayLeftPane() {
}
imguiHorizontalSpace(5);
imguiButton("Rendering", true, widthButton);
if (imguiButton("Rendering", true, widthButton)) {
mLeftPane = RENDERING;
}
imguiHorizontalSpace(5);
imguiButton("Profiling", true, widthButton);
if (imguiButton("Profiling", true, widthButton)) {
mLeftPane = PROFILING;
}
imguiEndLine();
imguiVerticalSpace(BUTTON_HEIGHT + 8);
@ -213,7 +185,7 @@ void Gui::displayScenesPane() {
imguiBeginScrollArea("Scenes", 0, 0,
app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT),
app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT),
&scrollarea);
imguiVerticalSpace(15);
@ -243,7 +215,7 @@ void Gui::displayPhysicsPane() {
int scrollarea = 2;
imguiBeginScrollArea("Physics Engine Parameters", 0, 0,
app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
app.mWindowToFramebufferRatio.y * (windowHeight - HEADER_HEIGHT - LEFT_PANE_HEADER_HEIGHT),
app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT),
&scrollarea);
imguiVerticalSpace(15);
@ -314,10 +286,77 @@ void Gui::displayPhysicsPane() {
void Gui::displayRenderingPane() {
TestbedApplication& app = TestbedApplication::getInstance();
int windowWidth, windowHeight;
glfwGetWindowSize(mWindow, &windowWidth, &windowHeight);
int scrollarea = 2;
imguiBeginScrollArea("Rendering Parameters", 0, 0,
app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT),
&scrollarea);
imguiVerticalSpace(15);
// Enabled/Disable VSync
bool toggleVSync = imguiCheck("V Sync", app.mIsVSyncEnabled);
if (toggleVSync) {
app.enableVSync(!app.mIsVSyncEnabled);
}
// Enabled/Disable Shadows
bool toggleShadows = imguiCheck("Shadows", app.mIsShadowMappingEnabled);
if (toggleShadows) {
app.enableShadows(!app.mIsShadowMappingEnabled);
}
imguiEndScrollArea();
}
void Gui::displayProfilingPane() {
TestbedApplication& app = TestbedApplication::getInstance();
double currentTime = glfwGetTime();
if ((currentTime - mTimeSinceLastProfilingDisplay) > TIME_INTERVAL_DISPLAY_PROFILING_INFO) {
mTimeSinceLastProfilingDisplay = currentTime;
mCachedFPS = app.mFPS;
mCachedUpdateTime = app.mUpdateTime;
mCachedPhysicsUpdateTime = app.mPhysicsUpdateTime;
}
int windowWidth, windowHeight;
glfwGetWindowSize(mWindow, &windowWidth, &windowHeight);
int scrollarea = 2;
imguiBeginScrollArea("Profiling", 0, 0,
app.mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
app.mWindowToFramebufferRatio.y * (windowHeight - LEFT_PANE_HEADER_HEIGHT),
&scrollarea);
imguiVerticalSpace(15);
// Framerate (FPS)
std::stringstream ss;
ss << std::setprecision(4) << mCachedFPS;
std::string fps = std::string("FPS : ") + ss.str();
imguiItem(fps.c_str());
// Update time
std::stringstream ss1;
double updateTime = mCachedUpdateTime * 1000.0;
ss1 << std::setprecision(4) << updateTime;
std::string updateTimeStr = std::string("Update time (ms) : ") + ss1.str();
imguiItem(updateTimeStr.c_str());
// Update time (physics)
std::stringstream ss2;
ss2 << std::setprecision(4) << (mCachedPhysicsUpdateTime * 1000.0);
std::string updatePhysicsTimeStr = std::string("Update physics time (ms) : ") + ss2.str();
imguiItem(updatePhysicsTimeStr.c_str());
imguiEndScrollArea();
}
// Display the GUI

View File

@ -35,9 +35,9 @@
// Constants
const float GUI_SCALING = 2.0f;
const int HEADER_HEIGHT = 80;
const int LEFT_PANE_WIDTH = 300;
const int LEFT_PANE_HEADER_HEIGHT = 50;
const int LEFT_PANE_HEADER_HEIGHT = 90;
const double TIME_INTERVAL_DISPLAY_PROFILING_INFO = 1.0;
using namespace openglframework;
@ -64,7 +64,6 @@ class Gui {
static bool g_MousePressed[3];
static float g_MouseWheel;
static GLuint g_FontTexture;
//static int g_ShaderHandle, g_VertHandle, g_FragHandle;
static int g_AttribLocationTex, g_AttribLocationProjMtx;
static int g_AttribLocationPosition, g_AttribLocationUV, g_AttribLocationColor;
static size_t g_VboSize;
@ -76,7 +75,6 @@ class Gui {
// -------------------- Methods -------------------- //
static void displayHeader();
static void displayLeftPane();
/// Display the list of scenes
@ -88,6 +86,18 @@ class Gui {
static void resetScroll();
/// Current time (in seconds) from last profiling time display
static double mTimeSinceLastProfilingDisplay;
/// Cached Framerate
static double mCachedFPS;
/// Cached update time
static double mCachedUpdateTime;
// Cached update physics time
static double mCachedPhysicsUpdateTime;
public :

View File

@ -0,0 +1,38 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "PhysicsEventListener.h"
// Called when a new contact point is found between two bodies that were separated before
void PhysicsEventListener::beginContact(const rp3d::ContactPointInfo& contact) {
}
// Called when a new contact point is found between two bodies
void PhysicsEventListener::newContact(const rp3d::ContactPointInfo& contact) {
}

View File

@ -0,0 +1,66 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2015 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef PHYSICSEVENTLISTENER_H
#define PHYSICSEVENTLISTENER_H
// Libraries
#include "reactphysics3d.h"
#include "openglframework.h"
// Structure ContactPoint
struct ContactPoint {
public:
openglframework::Vector3 point;
/// Constructor
ContactPoint(const openglframework::Vector3& contactPoint) : point(contactPoint) {
}
};
// Class PhysicsEventListener
// This class inherits from the EventListener class
// of ReactPhysics3D in order to be notified of events
// that occured in a physics world
class PhysicsEventListener : rp3d::EventListener {
private:
// Current contact points
std::vector<ContactPoint> mCurrentContactPoints;
public:
/// Called when a new contact point is found between two bodies that were separated before
virtual void beginContact(const rp3d::ContactPointInfo& contact);
/// Called when a new contact point is found between two bodies
virtual void newContact(const rp3d::ContactPointInfo& contact);
};
#endif

View File

@ -30,9 +30,9 @@
using namespace openglframework;
// Constructor
Scene::Scene(const std::string& name)
Scene::Scene(const std::string& name, bool isShadowMappingEnabled)
: mName(name), mInterpolationFactor(0.0f), mViewportX(0), mViewportY(0),
mViewportWidth(0), mViewportHeight(0) {
mViewportWidth(0), mViewportHeight(0), mIsShadowMappingEnabled(isShadowMappingEnabled) {
}

View File

@ -28,6 +28,7 @@
// Libraries
#include "openglframework.h"
#include "PhysicsEventListener.h"
/// Structure EngineSettings
/// This structure contains several physics engine parameters
@ -90,6 +91,9 @@ class Scene {
/// Viewport x,y, width and height values
int mViewportX, mViewportY, mViewportWidth, mViewportHeight;
/// True if the shadow mapping is enabled
bool mIsShadowMappingEnabled;
// -------------------- Methods -------------------- //
/// Set the scene position (where the camera needs to look at)
@ -117,7 +121,7 @@ class Scene {
// -------------------- Methods -------------------- //
/// Constructor
Scene(const std::string& name);
Scene(const std::string& name, bool isShadowMappingEnabled = false);
/// Destructor
virtual ~Scene();
@ -172,6 +176,15 @@ class Scene {
/// Return the name of the scene
std::string getName() const;
/// Return true if the shadow mapping is enabled
bool getIsShadowMappingEnabled() const;
/// Enabled/Disable the shadow mapping
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
/// Return all the contact points of the scene
std::vector<ContactPoint> virtual getContactPoints() const;
};
// Called when a keyboard event occurs
@ -223,4 +236,21 @@ inline std::string Scene::getName() const {
return mName;
}
// Return true if the shadow mapping is enabled
inline bool Scene::getIsShadowMappingEnabled() const {
return mIsShadowMappingEnabled;
}
// Enabled/Disable the shadow mapping
inline void Scene::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
mIsShadowMappingEnabled = isShadowMappingEnabled;
}
// Return all the contact points of the scene
inline std::vector<ContactPoint> Scene::getContactPoints() const {
// Return an empty list of contact points
return std::vector<ContactPoint>();
}
#endif

View File

@ -32,8 +32,9 @@ using namespace openglframework;
int SceneDemo::shadowMapTextureLevel = 0;
// Constructor
SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name),
mLight0(0), mIsShadowMappingEnabled(true), mIsShadowMappingInitialized(false),
SceneDemo::SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled)
: Scene(name, isShadowMappingEnabled),
mLight0(0), mIsShadowMappingInitialized(false),
mDepthShader("shaders/depth.vert", "shaders/depth.frag"),
mPhongShader("shaders/phong.vert", "shaders/phong.frag"),
mQuadShader("shaders/quad.vert", "shaders/quad.frag"),

View File

@ -30,8 +30,8 @@
#include "Scene.h"
// Constants
const int SHADOWMAP_WIDTH = 2048;
const int SHADOWMAP_HEIGHT = 2048;
const int SHADOWMAP_WIDTH = 1024;
const int SHADOWMAP_HEIGHT = 1024;
// Class SceneDemo
// Abstract class that represents a 3D scene for the ReactPhysics3D examples.
@ -45,9 +45,6 @@ class SceneDemo : public Scene {
/// Light 0
openglframework::Light mLight0;
/// True if the shadow mapping is enabled
bool mIsShadowMappingEnabled;
/// True if the shadows FBO, textures have been created
bool mIsShadowMappingInitialized;
@ -96,7 +93,7 @@ class SceneDemo : public Scene {
// -------------------- Methods -------------------- //
/// Constructor
SceneDemo(const std::string& name, float sceneRadius);
SceneDemo(const std::string& name, float sceneRadius, bool isShadowMappingEnabled = true);
/// Destructor
virtual ~SceneDemo();
@ -108,21 +105,14 @@ class SceneDemo : public Scene {
virtual void renderSinglePass(openglframework::Shader& shader,
const openglframework::Matrix4& worldToCameraMatrix)=0;
/// Return true if the shadow mapping is enabled
bool getIsShadowMappingEnabled() const;
/// Enabled/Disable the shadow mapping
void setIsShadowMappingEnabled(bool isShadowMappingEnabled);
void virtual setIsShadowMappingEnabled(bool isShadowMappingEnabled);
};
// Return true if the shadow mapping is enabled
inline bool SceneDemo::getIsShadowMappingEnabled() const {
return mIsShadowMappingEnabled;
}
// Enabled/Disable the shadow mapping
inline void SceneDemo::setIsShadowMappingEnabled(bool isShadowMappingEnabled) {
mIsShadowMappingEnabled = isShadowMappingEnabled;
Scene::setIsShadowMappingEnabled(isShadowMappingEnabled);
if (mIsShadowMappingEnabled && !mIsShadowMappingInitialized) {
createShadowMapFBOAndTexture();

View File

@ -50,7 +50,9 @@ TestbedApplication& TestbedApplication::getInstance() {
}
// Constructor
TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(0) {
TestbedApplication::TestbedApplication()
: mFPS(0), mNbFrames(0), mPreviousTime(0),
mUpdateTime(0), mPhysicsUpdateTime(0) {
mCurrentScene = NULL;
mIsMultisamplingActive = true;
@ -59,6 +61,8 @@ TestbedApplication::TestbedApplication() : mFPS(0), mNbFrames(0), mPreviousTime(
mSinglePhysicsStepEnabled = false;
mSinglePhysicsStepDone = false;
mWindowToFramebufferRatio = Vector2(1, 1);
mIsShadowMappingEnabled = true;
mIsVSyncEnabled = true;
}
// Destructor
@ -107,8 +111,8 @@ void TestbedApplication::init() {
}
glfwMakeContextCurrent(mWindow);
// Disable Vertical Synchronization
glfwSwapInterval(0);
// Vertical Synchronization
enableVSync(mIsVSyncEnabled);
// Initialize the GLEW library
glewExperimental = GL_TRUE;
@ -214,6 +218,8 @@ void TestbedApplication::updatePhysics() {
void TestbedApplication::update() {
double currentTime = glfwGetTime();
// Update the physics
if (mSinglePhysicsStepEnabled && !mSinglePhysicsStepDone) {
updateSinglePhysicsStep();
@ -223,6 +229,9 @@ void TestbedApplication::update() {
updatePhysics();
}
// Compute the physics update time
mPhysicsUpdateTime = glfwGetTime() - currentTime;
// Compute the interpolation factor
float factor = mTimer.computeInterpolationFactor(mEngineSettings.timeStep);
assert(factor >= 0.0f && factor <= 1.0f);
@ -230,11 +239,11 @@ void TestbedApplication::update() {
// Notify the scene about the interpolation factor
mCurrentScene->setInterpolationFactor(factor);
// Enable/Disable shadow mapping
mCurrentScene->setIsShadowMappingEnabled(mIsShadowMappingEnabled);
// Update the scene
mCurrentScene->update();
// Compute the current framerate
//application->computeFPS();
}
// Render
@ -254,7 +263,7 @@ void TestbedApplication::render() {
mCurrentScene->setViewport(mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
0,
bufferWidth - mWindowToFramebufferRatio.x * LEFT_PANE_WIDTH,
bufferHeight - mWindowToFramebufferRatio.y * HEADER_HEIGHT);
bufferHeight);
// Render the scene
mCurrentScene->render();
@ -274,7 +283,7 @@ void TestbedApplication::reshape() {
glfwGetFramebufferSize(mWindow, &width, &height);
// Resize the camera viewport
mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height - HEADER_HEIGHT);
mCurrentScene->reshape(width - LEFT_PANE_WIDTH, height);
// Update the window size of the scene
int windowWidth, windowHeight;
@ -305,6 +314,9 @@ void TestbedApplication::startMainLoop() {
// Process events
glfwPollEvents();
// Compute the current framerate
computeFPS();
checkOpenGLErrors();
}
}
@ -355,17 +367,19 @@ void TestbedApplication::computeFPS() {
mNbFrames++;
// Get the number of milliseconds since glutInit called
// Get the number of seconds since start
mCurrentTime = glfwGetTime();
// Calculate time passed
double timeInterval = mCurrentTime - mPreviousTime;
mUpdateTime = mCurrentTime - mPreviousTime;
double timeInterval = mUpdateTime * 1000.0;
// Update the FPS counter each second
if(timeInterval > 1.0) {
if(timeInterval > 0.0001) {
// calculate the number of frames per second
mFPS = static_cast<double>(mNbFrames) / timeInterval;
mFPS *= 1000.0;
// Set time
mPreviousTime = mCurrentTime;

View File

@ -69,12 +69,18 @@ class TestbedApplication {
/// Number of frames during the last second
int mNbFrames;
/// Current time for fps computation
/// Current time for fps computation (in seconds)
double mCurrentTime;
/// Previous time for fps computation
/// Previous time for fps computation (in seconds)
double mPreviousTime;
/// Update time (in seconds)
double mUpdateTime;
/// Physics update time (in seconds)
double mPhysicsUpdateTime;
/// True if multisampling is active
bool mIsMultisamplingActive;
@ -89,6 +95,12 @@ class TestbedApplication {
openglframework::Vector2 mWindowToFramebufferRatio;
/// True if shadow mapping is enabled
bool mIsShadowMappingEnabled;
/// True if vsync is enabled
bool mIsVSyncEnabled;
// -------------------- Methods -------------------- //
/// Private constructor (for the singleton class)
@ -160,6 +172,9 @@ class TestbedApplication {
/// Set the variable to know if we need to take a single physics step
void toggleTakeSinglePhysicsStep();
/// Enable/Disable shadow mapping
void enableShadows(bool enable);
public :
// -------------------- Methods -------------------- //
@ -179,6 +194,9 @@ class TestbedApplication {
/// Change the current scene
void switchScene(Scene* newScene);
/// Enable/Disable Vertical synchronization
void enableVSync(bool enable);
// -------------------- Friendship -------------------- //
friend class Gui;
@ -216,4 +234,20 @@ inline void TestbedApplication::toggleTakeSinglePhysicsStep() {
}
}
// Enable/Disable shadow mapping
inline void TestbedApplication::enableShadows(bool enable) {
mIsShadowMappingEnabled = enable;
}
// Enable/Disable Vertical synchronization
inline void TestbedApplication::enableVSync(bool enable) {
mIsVSyncEnabled = enable;
if (mIsVSyncEnabled) {
glfwSwapInterval(1);
}
else {
glfwSwapInterval(0);
}
}
#endif