From 20545128d20687f5f9e9e6c424ff6f3e38e8b80e Mon Sep 17 00:00:00 2001 From: James Turk Date: Mon, 8 Aug 2005 07:27:50 +0000 Subject: [PATCH] VideoCore integrated into Application --- include/Application.hpp | 110 +++++++++++++++-- include/audio/AudioCore.hpp | 16 +-- include/photon.hpp | 1 - include/util/Timer.hpp | 4 +- src/Application.cpp | 233 ++++++++++++++++++++++++++---------- 5 files changed, 271 insertions(+), 93 deletions(-) diff --git a/include/Application.hpp b/include/Application.hpp index 551fdf1..b4632df 100644 --- a/include/Application.hpp +++ b/include/Application.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.hpp,v 1.13 2005/08/08 07:00:46 cozman Exp $ +// $Id: Application.hpp,v 1.14 2005/08/08 07:27:50 cozman Exp $ #ifndef PHOTON_APPLICATION_HPP #define PHOTON_APPLICATION_HPP @@ -124,6 +124,88 @@ public: // Returns: // True if application is active, false otherwise. bool isActive(); + +// Group: Ortho +public: + // Function: setOrthoView + // Sets new ortho viewport within a rectangular portion of the screen. + // All drawing is relative to the rectangle, x,y becomes 0,0 and anything + // drawn outside rect is clipped. + // + // Parameters: + // x - X coord for top left corner of new viewport. + // y - Y coord for top left corner of new viewport. + // viewWidth - Width of new viewport. + // viewHeight - Height of new viewport. + // orthoWidth - Width of ortho perspective. + // orthoHeight - Height of ortho perspective. + void setOrthoView(int x, int y, int viewWidth, int viewHeight, + scalar orthoWidth, scalar orthoHeight); + + // Function: setOrthoView + // Sets entire screen as current viewport with a given ortho perspective. + // + // Parameters: + // width - Width of view. + // height - Height of view. + void setOrthoView(scalar width, scalar height); + + // Function: setOrthoView + // Sets entire screen as current viewport with a given ortho perspective. + void setOrthoView(); + +// Group: Perspective +public: + // Function: setPerspectiveView + // Creates a viewport with a given 3D perspective inside of a rectangular + // portion of the screen. + // + // Parameters: + // x - X coord for top left corner of new viewport. + // y - Y coord for top left corner of new viewport. + // width - Width of new viewport. + // height - Height of new viewport. + // fovy - The y axis field of view angle, in degrees. + // zNear - Distance from viewer to near clipping plane. + // zFar - Distance from viewer to far clipping plane. + void setPerspectiveView(int x, int y, int width, int height, + scalar fovy, scalar zNear, scalar zFar); + + // Function: setPerspectiveView + // Sets entire screen as current viewport with a given 3D perspective. + // + // Same as call to setPerspective + // + // Parameters: + // fovy - The y axis field of view angle, in degrees. + // zNear - Distance from viewer to near clipping plane. + // zFar - Distance from viewer to far clipping plane. + void setPerspectiveView(scalar fovy, scalar zNear, scalar zFar); + +// Group: Viewport/Projection +// These functions are called by the above Ortho/Perspective functions, very +// rarely do they need to be called directly. +public: + // Function: setViewport + // Set the current viewport rectangle within the screen. + void setViewport(int x, int y, int width, int height); + + // Function: setOrthoProjection + // Sets an orthographic projection matrix. + // + // Parameters: + // width - Width of view. + // height - Height of view. + void setOrthoProjection(scalar width, scalar height); + + // Function: setPerspectiveProjection + // Sets a perspective projection matrix. + // + // Parameters: + // fovy - The y axis field of view angle, in degrees. + // zNear - Distance from viewer to near clipping plane. + // zFar - Distance from viewer to far clipping plane. + void setPerspectiveProjection(scalar fovy, scalar zNear, scalar zFar); // Group: Input public: @@ -237,17 +319,16 @@ public: // Group: Core Access public: - video::VideoCore& getVideoCore(); audio::AudioCore& getAudioCore(); - void initVideoCore(uint width, uint height); void initAudioCore(const std::string& deviceName); // Group: API Initialization private: util::VersionInfo initPhysFS(const std::string& arg0); util::VersionInfo initGLFW(); + void initOpenGL(); -// Group: Task Classes +// Task Classes private: // UpdateTask, does the updating work of AppCore, registered as a Task // so that user need not call something akin to AppCore::update() every @@ -274,7 +355,16 @@ private: scalar lastUpdate_; }; - // StateUpdate + // VideoTask, does the updating work of OpenGL + class VideoTask : public Task + { + public: + VideoTask(); + + void update(); + }; + + // StateUpdate, calls State::update class StateUpdate : public Task { @@ -288,7 +378,7 @@ private: StatePtr state_; }; - // StateRender + // StateRender, calls State::render class StateRender : public Task { @@ -302,13 +392,16 @@ private: StatePtr state_; }; +// Data members private: // version number for photon util::VersionInfo photonVer_; // Application info - uint dispWidth_; - uint dispHeight_; + uint displayWidth_; + uint displayHeight_; + uint viewportWidth_; + uint viewportHeight_; // tasks shared_ptr updateTask_; @@ -320,7 +413,6 @@ private: static std::vector pressedKeys_; // Cores - std::auto_ptr videoCore_; std::auto_ptr audioCore_; }; diff --git a/include/audio/AudioCore.hpp b/include/audio/AudioCore.hpp index 166e36e..7e8acc6 100644 --- a/include/audio/AudioCore.hpp +++ b/include/audio/AudioCore.hpp @@ -5,7 +5,7 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: AudioCore.hpp,v 1.11 2005/08/07 07:12:47 cozman Exp $ +// $Id: AudioCore.hpp,v 1.12 2005/08/08 07:27:50 cozman Exp $ #ifdef PHOTON_USE_OPENAL @@ -47,20 +47,6 @@ public: // Returns: // Name of audio device currently in use. std::string getAudioDeviceName() const; - -// Group: Initialization -public: - // Function: initAudioDevice - // Initialize audio device. _MUST_ be called prior to any use of audio - // functionality. - // - // Takes an optional parameter, if existant the initialization of the audio - // library will attempt to use the specified audio device, otherwise the - // default device will be used. - // - // Parameters: - // deviceName - Name of audio device to use. (optional, default=default) - static void initAudioDevice(const std::string& deviceName=""); // Group: Error Checking public: diff --git a/include/photon.hpp b/include/photon.hpp index 1f60e7b..fe8024c 100644 --- a/include/photon.hpp +++ b/include/photon.hpp @@ -2,7 +2,6 @@ #define PHOTON_HPP #include "Kernel.hpp" -#include "AppCore.hpp" #include "types.hpp" #include "Application.hpp" #include "Task.hpp" diff --git a/include/util/Timer.hpp b/include/util/Timer.hpp index 9c65ce2..bf67b96 100644 --- a/include/util/Timer.hpp +++ b/include/util/Timer.hpp @@ -5,13 +5,11 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Timer.hpp,v 1.3 2005/08/07 07:12:47 cozman Exp $ +// $Id: Timer.hpp,v 1.4 2005/08/08 07:27:50 cozman Exp $ #ifndef PHOTON_UTIL_TIMER_HPP #define PHOTON_UTIL_TIMER_HPP -#include "AppCore.hpp" - namespace photon { namespace util diff --git a/src/Application.cpp b/src/Application.cpp index 28dc52a..676734e 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -5,19 +5,20 @@ // James Turk (jpt2433@rit.edu) // // Version: -// $Id: Application.cpp,v 1.17 2005/08/08 07:00:46 cozman Exp $ +// $Id: Application.cpp,v 1.18 2005/08/08 07:27:50 cozman Exp $ #include "Application.hpp" -#include "physfs.h" //This file depends on physfs -#include "GL/glfw.h" //This file depends on glfw +#include "physfs.h" // This file depends on physfs +#include "GL/glfw.h" // This file depends on glfw +#include "GL/gl.h" // This file depends on OpenGL +#include "GL/glu.h" #include #include "exceptions.hpp" #include "Log.hpp" #include "Kernel.hpp" #include "Application.hpp" -#include "video/VideoCore.hpp" #include "audio/AudioCore.hpp" #include "util/filesys/filesys.hpp" @@ -25,12 +26,16 @@ namespace photon { +// static class members std::vector Application::listeners_; std::vector Application::pressedKeys_; +// (Con/De)structors /////////////////////////////////////////////////////////// + Application::Application(const std::string& arg0) : photonVer_(0,0,1), // this is the current version - dispWidth_(0), dispHeight_(0), + displayWidth_(0), displayHeight_(0), + viewportWidth_(0), viewportHeight_(0), updateTask_(new UpdateTask()), stateUpdate_(new StateUpdate()), stateRender_(new StateRender()) @@ -50,7 +55,7 @@ Application::Application(const std::string& arg0) : Application::~Application() { - if(dispWidth_ && dispHeight_) + if(displayWidth_ && displayHeight_) { glfwCloseWindow(); //close GLFW window } @@ -62,6 +67,8 @@ Application::~Application() Kernel::destroy(); // destroy Kernel on way out } +// Window ////////////////////////////////////////////////////////////////////// + void Application::createDisplay(uint width, uint height, uint redBits, uint greenBits, uint blueBits, uint alphaBits, uint depthBits, uint stencilBits, @@ -75,19 +82,21 @@ void Application::createDisplay(uint width, uint height, { throw APIError("Failed to create display."); } + displayWidth_ = width; + displayHeight_ = height; + glfwSetWindowTitle(title.c_str()); // title is set separately + + initOpenGL(); + setOrthoView(); + Kernel::getInstance().addTask(TaskPtr(new VideoTask())); + // register the callbacks (after a window is open) glfwSetKeyCallback(Application::keyCallback); //glfwSetCharCallback(Application::charCallback); glfwSetMouseButtonCallback(Application::mouseButtonCallback); glfwSetMousePosCallback(Application::mouseMoveCallback); //glfwSetMouseWheelCallback(Application::mouseWheelCallback); - - Application::initVideoCore(width, height); - dispWidth_ = width; - dispHeight_ = height; - - glfwSetWindowTitle(title.c_str()); // title is set separately } void Application::createDisplay(uint width, uint height, uint bpp, @@ -120,6 +129,106 @@ void Application::createDisplay(uint width, uint height, uint bpp, } } +void Application::setTitle(const std::string& title) +{ + glfwSetWindowTitle(title.c_str()); +} + +uint Application::getDisplayWidth() +{ + return displayWidth_; +} + +uint Application::getDisplayHeight() +{ + return displayHeight_; +} + +bool Application::isActive() +{ + return updateTask_->active_; +} + +// Ortho /////////////////////////////////////////////////////////////////////// + +void Application::setOrthoView(int x, int y, int viewWidth, int viewHeight, + scalar orthoWidth, scalar orthoHeight) +{ + // set viewport & ortho projection + setViewport(x,y,viewWidth,viewHeight); + setOrthoProjection(orthoWidth,orthoHeight); +} + +void Application::setOrthoView(scalar width, scalar height) +{ + // set viewport to fullscreen, then set ortho (alternative ratio) + setViewport(0, 0, displayWidth_, displayHeight_); + setOrthoProjection(width,height); +} + +void Application::setOrthoView() +{ + // set viewport to fullscreen, then set ortho (1:1 ratio) + setViewport(0, 0, displayWidth_, displayHeight_); + setOrthoProjection(displayWidth_, displayHeight_); +} + +// Perspective ///////////////////////////////////////////////////////////////// + +void Application::setPerspectiveView(int x, int y, int width, int height, + scalar fovy, scalar zNear, scalar zFar) +{ + // set viewport & perspective projection + setViewport(x, y, width, height); + setPerspectiveProjection(fovy, zNear, zFar); +} + +void Application::setPerspectiveView(scalar fovy, scalar zNear, scalar zFar) +{ + // set viewport fullscreen, then set perspective + setViewport(0, 0, displayWidth_, displayHeight_); + setPerspectiveProjection(fovy, zNear, zFar); +} + +// Viewport/Projection ///////////////////////////////////////////////////////// + +void Application::setViewport(int x, int y, int width, int height) +{ + // viewport described from bottom corner, so flip y + glViewport(x, displayHeight_-(y+height), width, height); + viewportWidth_ = width; + viewportHeight_ = height; +} + +void Application::setOrthoProjection(scalar width, scalar height) +{ + // setup default Ortho + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, static_cast(width), static_cast(height), + 0, -1.0, 1.0); + + //back to modelview + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void Application::setPerspectiveProjection(scalar fovy, scalar zNear, scalar zFar) +{ + GLdouble ratio = static_cast(viewportWidth_) / + static_cast(viewportHeight_); + + //set new projection + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(fovy, ratio, zNear, zFar); + + //back to modelview + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +// Input /////////////////////////////////////////////////////////////////////// bool Application::keyPressed(KeyCode key) { return glfwGetKey(key) == GLFW_PRESS; @@ -150,6 +259,8 @@ int Application::getMouseWheelPos() return glfwGetMouseWheel(); } +// Input Listeners ///////////////////////////////////////////////////////////// + void Application::addInputListener(InputListener *listener) { // should never happen since listeners add themselves with a this pointer @@ -259,25 +370,21 @@ void GLFWCALL Application::mouseMoveCallback(int x, int y) } } +// Timing ////////////////////////////////////////////////////////////////////// + scalar Application::getTime() { return glfwGetTime() - updateTask_->pausedTime_; } -void Application::setTitle(const std::string& title) +double Application::getElapsedTime() { - glfwSetWindowTitle(title.c_str()); + return updateTask_->secPerFrame_; } -video::VideoCore& Application::getVideoCore() +double Application::getFramerate() { - // return VideoCore if it has been created - if(videoCore_.get() == 0) - { - throw PreconditionException("call to Application::getVideoCore() before" - " Application::initAudioDevice"); - } - return *videoCore_; + return 1/updateTask_->secPerFrame_; } audio::AudioCore& Application::getAudioCore() @@ -291,19 +398,6 @@ audio::AudioCore& Application::getAudioCore() return *audioCore_; } -void Application::initVideoCore(uint width, uint height) -{ - // create VideoCore, avoid double initializaiton - if(videoCore_.get() == 0) - { - videoCore_.reset(new video::VideoCore(width, height)); - } - else - { - throw PreconditionException("Attempt to double initialize VideoCore"); - } -} - void Application::initAudioCore(const std::string& deviceName) { // create AudioCore, avoid double initializaiton @@ -317,32 +411,7 @@ void Application::initAudioCore(const std::string& deviceName) } } -bool Application::isActive() -{ - return updateTask_->active_; -} - -double Application::getElapsedTime() -{ - return updateTask_->secPerFrame_; -} - -double Application::getFramerate() -{ - return 1/updateTask_->secPerFrame_; -} - -uint Application::getDisplayWidth() -{ - return dispWidth_; -} - -uint Application::getDisplayHeight() -{ - return dispHeight_; -} - -// API initialization +// API initialization ////////////////////////////////////////////////////////// util::VersionInfo Application::initPhysFS(const std::string& arg0) { @@ -364,7 +433,30 @@ util::VersionInfo Application::initGLFW() return util::VersionInfo(maj,min,patch); } -// Application's Tasks +void Application::initOpenGL() +{ + // Set smooth shading. + glShadeModel(GL_SMOOTH); + + // Setup depth checking. + //glDepthFunc(GL_LEQUAL); + //glEnable(GL_DEPTH_TEST); + + //setup hints + glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); + + glEnable(GL_POLYGON_SMOOTH); + + //enable texturing + glEnable(GL_TEXTURE_2D); + + //setup alpha blending of 2D textures with the scene + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +} + +// Tasks /////////////////////////////////////////////////////////////////////// Application::UpdateTask::UpdateTask() : Task("Application::UpdateTask", PRI_APP_UPDATE), @@ -379,7 +471,7 @@ void Application::UpdateTask::update() { scalar curTime = glfwGetTime() - pausedTime_; - // update the display here instead of VideoCore (since it belongs to glfw) + // update the display here instead of Application (since it belongs to glfw) glfwSwapBuffers(); glfwGetMousePos(&mouseX_, &mouseY_); @@ -414,8 +506,19 @@ void Application::UpdateTask::update() } } +Application::VideoTask::VideoTask() : + Task("Application::VideoTask", PRI_VIDEO_UPDATE) +{ +} + +void Application::VideoTask::update() +{ + // TODO: clear depth/stencil if requested + glClear(GL_COLOR_BUFFER_BIT); +} + Application::StateUpdate::StateUpdate() : - Task("StateUpdate", PRI_NORMAL) + Task("Application::StateUpdate", PRI_NORMAL) { } @@ -425,7 +528,7 @@ void Application::StateUpdate::update() } Application::StateRender::StateRender() : - Task("StateRender", PRI_RENDER) + Task("Application::StateRender", PRI_RENDER) { }