|
|
(4 intermediate revisions by the same user not shown) |
Line 21: |
Line 21: |
| #include <math.h> | | #include <math.h> |
| #include <iomanip> | | #include <iomanip> |
| + | #include <glibmm/timer.h> |
| | | |
| using namespace std; | | using namespace std; |
Line 30: |
Line 31: |
| virtual ~cHordeWidget(); | | virtual ~cHordeWidget(); |
| bool on_timeout(); | | bool on_timeout(); |
− | | + | float _x, _y, _z, _rx, _ry; // Viewer position and orientation |
| + | float _curFPS; |
| protected: | | protected: |
| virtual void on_realize(); | | virtual void on_realize(); |
| virtual bool on_configure_event(GdkEventConfigure* event); | | virtual bool on_configure_event(GdkEventConfigure* event); |
| virtual bool on_expose_event(GdkEventExpose* event); | | virtual bool on_expose_event(GdkEventExpose* event); |
− | //our horde init function | + | virtual bool on_motion_notify_event(GdkEventMotion* event); |
| void init_hordeScene(); | | void init_hordeScene(); |
− | //our horde viewport functon
| |
| void setup_hordeViewport(); | | void setup_hordeViewport(); |
− | //our horde render function
| |
| void render_hordeScene(); | | void render_hordeScene(); |
− | //finnaly our horde update function
| |
| void update_hordeScene(); | | void update_hordeScene(); |
− | | + | void get_FramesPerSecond(); |
| private: | | private: |
− | ResHandle _pipeRes, _fontMatRes, _logoMatRes, _hdrPipeRes, _forwardPipeRes; | + | ResHandle _pipeRes, _fontMatRes, _logoMatRes, _hdrPipeRes, _forwardPipeRes, _deferredPipeRes; |
| NodeHandle _cam, _knight, _particleSys; | | NodeHandle _cam, _knight, _particleSys; |
− | float _x, _y, _z, _rx, _ry; // Viewer position and orientation
| |
− | float _velocity; // Velocity for movement
| |
− | float _curFPS, _timer;
| |
| | | |
− | stringstream _fpsText;
| |
| | | |
− | bool _freeze, _showFPS, _debugViewMode, _wireframeMode; | + | bool _freeze; |
| float _animTime, _weight; | | float _animTime, _weight; |
| + | |
| + | double last_time; |
| + | int frames; |
| + | |
| + | Glib::Timer m_animtimer; |
| + | Glib::Timer m_fpstimer; |
| | | |
| }; | | }; |
Line 75: |
Line 76: |
| | | |
| Glib::RefPtr<Gdk::GL::Config> glconfig; | | Glib::RefPtr<Gdk::GL::Config> glconfig; |
− | //Pick our opengl options
| + | |
| glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE); | | glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE); |
− | //set the opengl options | + | add_events(Gdk::POINTER_MOTION_MASK); |
| set_gl_capability(glconfig); | | set_gl_capability(glconfig); |
− | //add our idle signal.
| + | Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 10); |
− | Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 20 ); | + | m_animtimer.start(); |
| | | |
| } | | } |
Line 162: |
Line 163: |
| Horde3D::setOption( EngineOptions::ShadowMapSize, 2048 ); | | Horde3D::setOption( EngineOptions::ShadowMapSize, 2048 ); |
| | | |
− | // Add resources
| |
− | // Pipelines
| |
| _hdrPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "hdr.pipeline.xml", 0 ); | | _hdrPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "hdr.pipeline.xml", 0 ); |
| _forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "forward.pipeline.xml", 0 ); | | _forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "forward.pipeline.xml", 0 ); |
| + | _deferredPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "deferred.pipeline.xml",0); |
| // Font | | // Font |
| _fontMatRes = Horde3D::addResource( ResourceTypes::Material, "font.material.xml", 0 ); | | _fontMatRes = Horde3D::addResource( ResourceTypes::Material, "font.material.xml", 0 ); |
Line 179: |
Line 179: |
| ResHandle particleSysRes = Horde3D::addResource( ResourceTypes::SceneGraph, "particleSys1.scene.xml", 0 ); | | ResHandle particleSysRes = Horde3D::addResource( ResourceTypes::SceneGraph, "particleSys1.scene.xml", 0 ); |
| | | |
− | // Load resources
| + | ResHandle skyBoxRes = Horde3D::addResource( ResourceTypes::SceneGraph, "skybox.scene.xml" ,0); |
| + | // Load resources |
| Horde3DUtils::loadResourcesFromDisk( "media" ); | | Horde3DUtils::loadResourcesFromDisk( "media" ); |
| | | |
− | // Add scene nodes
| + | |
| // Add camera | | // Add camera |
− | _cam = Horde3D::addCameraNode( RootNode, "Camera", _hdrPipeRes ); | + | _cam = Horde3D::addCameraNode( RootNode, "Camera", _forwardPipeRes ); |
| //Horde3D::setNodeParami( _cam, CameraNodeParams::OcclusionCulling, 1 ); | | //Horde3D::setNodeParami( _cam, CameraNodeParams::OcclusionCulling, 1 ); |
| // Add environment | | // Add environment |
| NodeHandle env = Horde3D::addNodes( RootNode, envRes ); | | NodeHandle env = Horde3D::addNodes( RootNode, envRes ); |
| + | |
| Horde3D::setNodeTransform( env, 0, -20, 0, 0, 0, 0, 20, 20, 20 ); | | Horde3D::setNodeTransform( env, 0, -20, 0, 0, 0, 0, 20, 20, 20 ); |
| // Add knight | | // Add knight |
Line 194: |
Line 196: |
| Horde3D::setupModelAnimStage( _knight, 0, knightAnim1Res, "", false ); | | Horde3D::setupModelAnimStage( _knight, 0, knightAnim1Res, "", false ); |
| Horde3D::setupModelAnimStage( _knight, 1, knightAnim2Res, "", false ); | | Horde3D::setupModelAnimStage( _knight, 1, knightAnim2Res, "", false ); |
| + | |
| // Attach particle system to hand joint | | // Attach particle system to hand joint |
| Horde3D::findNodes( _knight, "Bip01_R_Hand", SceneNodeTypes::Joint ); | | Horde3D::findNodes( _knight, "Bip01_R_Hand", SceneNodeTypes::Joint ); |
Line 200: |
Line 203: |
| Horde3D::setNodeTransform( _particleSys, 0, 40, 0, 90, 0, 0, 1, 1, 1 ); | | Horde3D::setNodeTransform( _particleSys, 0, 40, 0, 90, 0, 0, 1, 1, 1 ); |
| | | |
| + | //add skybox |
| + | NodeHandle sky = Horde3D::addNodes( RootNode, skyBoxRes); |
| + | //set skybox position |
| + | Horde3D::setNodeTransform( sky, 0, 0, 0, 0, 0, 0, 210, 50, 210 ); |
| // Add light source | | // Add light source |
| NodeHandle light = Horde3D::addLightNode( RootNode, "Light1", 0, "LIGHTING", "SHADOWMAP" ); | | NodeHandle light = Horde3D::addLightNode( RootNode, "Light1", 0, "LIGHTING", "SHADOWMAP" ); |
Line 228: |
Line 235: |
| | | |
| void cHordeWidget::render_hordeScene(){ | | void cHordeWidget::render_hordeScene(){ |
− | //sets the fps we want | + | m_fpstimer.start(); |
− | float fps = 60;
| |
− | _curFPS = fps;
| |
− | _timer += 1 / fps;
| |
| | | |
− | Horde3D::setOption( EngineOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f );
| + | //Horde3D::setOption( EngineOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f ); |
− | Horde3D::setOption( EngineOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f );
| + | //Horde3D::setOption( EngineOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f ); |
| | | |
− | _animTime += 1.0f / _curFPS; | + | // Do animation blending |
− | | + | Horde3D::setModelAnimParams( _knight, 0, _animTime , _weight ); |
− | // Do animation blending
| + | Horde3D::setModelAnimParams( _knight, 1, _animTime , 1.0f - _weight ); |
− | Horde3D::setModelAnimParams( _knight, 0, _animTime * 24.0f, _weight ); | |
− | Horde3D::setModelAnimParams( _knight, 1, _animTime * 24.0f, 1.0f - _weight ); | |
| | | |
| // Animate particle systems (several emitters in a group node) | | // Animate particle systems (several emitters in a group node) |
| unsigned int cnt = cnt = Horde3D::findNodes( _particleSys, "", SceneNodeTypes::Emitter ); | | unsigned int cnt = cnt = Horde3D::findNodes( _particleSys, "", SceneNodeTypes::Emitter ); |
| + | |
| for( unsigned int i = 0; i < cnt; ++i ) | | for( unsigned int i = 0; i < cnt; ++i ) |
| Horde3D::advanceEmitterTime( Horde3D::getNodeFindResult( i ), 1.0f / _curFPS ); | | Horde3D::advanceEmitterTime( Horde3D::getNodeFindResult( i ), 1.0f / _curFPS ); |
| | | |
| | | |
− | // Set camera parameters
| + | // Set camera parameters |
− | Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );
| |
| | | |
| | | |
− | // Show logo
| + | // Show logo |
− | Horde3D::showOverlay( 0.75f, 0, 0, 0, 1, 0, 1, 0,
| + | Horde3D::showOverlay( 0.75f, 0, 0, 0, 1, 0, 1, 0, |
− | 1, 0.2f, 1, 1, 0.75f, 0.2f, 0, 1,
| + | 1, 0.2f, 1, 1, 0.75f, 0.2f, 0, 1, |
− | 7, _logoMatRes );
| + | 7, _logoMatRes ); |
| | | |
− | // Render scene
| + | // Render scene |
− | Horde3D::render( _cam );
| + | Horde3D::render( _cam ); |
| | | |
− | // Remove all overlays
| + | // Remove all overlays |
− | Horde3D::clearOverlays();
| + | Horde3D::clearOverlays(); |
| + | |
| + | get_FramesPerSecond(); |
| | | |
| } | | } |
| | | |
| void cHordeWidget::update_hordeScene(){ | | void cHordeWidget::update_hordeScene(){ |
− | //This is to update the screen when it goes idle you can use this has a extra update function.
| |
− | Glib::RefPtr<Gdk::Window> win = get_window();
| |
| | | |
− | Gdk::Rectangle r(0, 0,get_width(),get_height()); | + | double seconds = m_animtimer.elapsed(); |
| + | |
| + | _animTime += seconds * 30; |
| + | |
| + | m_animtimer.reset(); |
| + | Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 ); |
| Gtk::Widget::queue_draw(); | | Gtk::Widget::queue_draw(); |
| } | | } |
| | | |
| + | void cHordeWidget::get_FramesPerSecond(){ |
| + | ++frames; |
| + | |
| + | last_time = last_time + m_fpstimer.elapsed(); |
| + | |
| + | if(last_time >= 0){ |
| + | _curFPS = (float)(frames / last_time); |
| + | frames = 0; |
| + | last_time = 0; |
| + | m_fpstimer.reset(); |
| + | } |
| + | |
| + | std::cout<<_curFPS<<endl; |
| + | } |
| + | |
| + | //This event handler must be set and return false in order for are mouse movement to be captured |
| + | bool cHordeWidget::on_motion_notify_event(GdkEventMotion* event){ |
| + | |
| + | return false; |
| + | } |
| | | |
| </source> | | </source> |
Line 285: |
Line 312: |
| #define CWINDOW_HPP_INCLUDED | | #define CWINDOW_HPP_INCLUDED |
| #include <gtkmm.h> | | #include <gtkmm.h> |
| + | #include <math.h> |
| #include "cHordeWidget.hpp" | | #include "cHordeWidget.hpp" |
| | | |
Line 295: |
Line 323: |
| | | |
| virtual bool on_key_press_event(GdkEventKey* event); | | virtual bool on_key_press_event(GdkEventKey* event); |
− | | + | virtual bool on_key_release_event(GdkEventKey* event); |
| + | virtual bool on_motion_notify_event(GdkEventMotion* event); |
| + | virtual bool on_focus_in (GdkEventFocus*); |
| + | bool on_timeout(); |
| + | void handleinput(); |
| private: | | private: |
| Gtk::VBox m_vBox; | | Gtk::VBox m_vBox; |
Line 314: |
Line 346: |
| | | |
| #include "../include/cWindow.hpp" | | #include "../include/cWindow.hpp" |
| + | |
| + | inline float degToRad( float f ) |
| + | { |
| + | return f * (3.1415926f / 180.0f); |
| + | } |
| + | //array to hold keys |
| + | int keyDown[256]; |
| | | |
| cWindow::cWindow(){ | | cWindow::cWindow(){ |
− | //set the windows title
| |
| set_title("Horde with gtkmm"); | | set_title("Horde with gtkmm"); |
− | //makes the window update if it is expanded etc.
| |
| set_reallocate_redraws(true); | | set_reallocate_redraws(true); |
− | //adds a box to place the hordewidget and other widgets into
| + | |
| add(m_vBox); | | add(m_vBox); |
− | //sets the minimum and default size for our window | + | add_events(Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | |
| + | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); |
| + | Glib::signal_timeout().connect( sigc::mem_fun(*this, &cWindow::on_timeout), 10); |
| + | signal_focus_in_event().connect(sigc::mem_fun(*this, &cWindow::on_focus_in) ); |
| m_hordeWidget.set_size_request(800,600); | | m_hordeWidget.set_size_request(800,600); |
− | //makes the widget expand when the window is expanded
| + | |
| m_vBox.pack_start(m_hordeWidget); | | m_vBox.pack_start(m_hordeWidget); |
− | //shows all widgets. by default all widgets are invisible.
| + | |
| show_all(); | | show_all(); |
| } | | } |
Line 336: |
Line 376: |
| bool cWindow::on_key_press_event(GdkEventKey* event){ | | bool cWindow::on_key_press_event(GdkEventKey* event){ |
| | | |
− | switch (event->keyval) | + | if(event->keyval == GDK_Escape){ |
− | { | + | Gtk::Main::quit();}else{ |
− | case GDK_a: | + | |
− | std::cout<<"test";
| + | //sets the key in the array to true |
− | break;
| + | keyDown[event->keyval] = 1;} |
| + | return true; |
| + | } |
| + | |
| + | bool cWindow::on_key_release_event(GdkEventKey *event){ |
| + | //sets the key in the array to false |
| + | keyDown[event->keyval] = 0; |
| + | return true; |
| + | } |
| + | |
| + | void cWindow::handleinput(){ |
| + | float curVel = 240/m_hordeWidget._curFPS; |
| + | //checks if a certain key is true and acts on it |
| + | if(keyDown['w']){ |
| + | m_hordeWidget._x -= sinf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | m_hordeWidget._y -= sinf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | m_hordeWidget._z -= cosf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | } |
| + | |
| + | if(keyDown['s']){ |
| + | m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | m_hordeWidget._y += sinf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel; |
| + | } |
| | | |
− | case GDK_Escape: | + | if(keyDown['a']){ |
− | //ends our app
| + | m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry - 90) ) * curVel; |
− | Gtk::Main::quit();
| + | m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry - 90 ) ) * curVel; |
| + | } |
| | | |
− | break;
| + | if(keyDown['d']){ |
− | default:
| + | m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry + 90 ) ) * curVel; |
− | return true;
| + | m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry + 90 ) ) * curVel; |
| } | | } |
| + | |
| + | } |
| + | //called only when mouse is moved *cause for the camera appearing glitchy* |
| + | bool cWindow::on_motion_notify_event(GdkEventMotion* event){ |
| + | |
| + | m_hordeWidget._ry -= (event->x -(get_width() /2)) / 450 ; |
| + | |
| + | m_hordeWidget._rx -= (event->y -(get_height()/2)) / 450 ; |
| + | |
| + | if( m_hordeWidget._rx > 90 ) m_hordeWidget._rx = 90; |
| + | if( m_hordeWidget._rx < -90 ) m_hordeWidget._rx = -90; |
| + | |
| + | return false; |
| + | } |
| + | //called constantly |
| + | bool cWindow::on_timeout(){ |
| + | int xp = 0; |
| + | int yp = 0; |
| + | get_pointer(xp,yp); |
| + | handleinput(); |
| + | return true; |
| + | } |
| + | |
| + | bool cWindow::on_focus_in(GdkEventFocus* event ) |
| + | { |
| + | //Hide the curosr |
| + | // Ok, here we create a dummy cursor. See gdkmm reference for more details |
| + | Gdk::Cursor cursor = Gdk::Cursor(Gdk::Display::get_default(), |
| + | Gdk::Pixbuf::create( |
| + | Gdk::COLORSPACE_RGB, true, 8, 1, 1), |
| + | 0, 0); |
| + | |
| + | get_window()->set_cursor(cursor); |
| | | |
| return true; | | return true; |
Line 364: |
Line 461: |
| #include <gtkmm.h> | | #include <gtkmm.h> |
| //Include our custom widget | | //Include our custom widget |
− | #include "include/cHordeWidget.hpp" | + | #include "include/cWindow.hpp" |
| | | |
| int main(int argc, char *argv[]){ | | int main(int argc, char *argv[]){ |
Line 372: |
Line 469: |
| Gtk::GL::init (argc, argv); | | Gtk::GL::init (argc, argv); |
| //Create our Window object | | //Create our Window object |
− | Gtk::Window window; | + | cWindow window; |
− | //Set our window title | + | //Run the program |
− | window.set_title ("Horde3D In Gtk+ Window");
| + | Gtk::Main::run(window); |
− | //Create our cHordeWidget
| + | //Safe exit message |
− | cHordeWidget drawing;
| |
− | //Set the cHordeWidgets size
| |
− | drawing.set_size_request(800, 600);
| |
− | //Add the cHordeWidget to our window
| |
− | window.add (drawing);
| |
− | //Show our cHordeWidget. All widgets are invisible by default.
| |
− | window.show_all ();
| |
− | //Run our window
| |
− | Gtk::Main::run (window); | |
− | //Just a return statement | |
| return EXIT_SUCCESS; | | return EXIT_SUCCESS; |
| + | |
| } | | } |
| | | |
Here is a small example on how to use Horde with Gtkmm.
This is a small tutorial on how to setup Horde with Gtk+ using Gtkmm and Gtkglextmm. This one is setup with the knight example. I leave the adjusting of the camera to you :)
cHordeWidget.hpp |
#ifndef CHORDEWIDGET_HPP_INCLUDED
#define CHORDEWIDGET_HPP_INCLUDED
#include <iostream>
#include <Horde3D.h>
#include <Horde3DUtils.h>
#include <cstdlib>
#include <gtkmm.h>
#include <gtkglmm.h>
#include <sstream>
#include <math.h>
#include <iomanip>
#include <glibmm/timer.h>
using namespace std;
class cHordeWidget : public Gtk::GL::DrawingArea{
public:
cHordeWidget();
virtual ~cHordeWidget();
bool on_timeout();
float _x, _y, _z, _rx, _ry; // Viewer position and orientation
float _curFPS;
protected:
virtual void on_realize();
virtual bool on_configure_event(GdkEventConfigure* event);
virtual bool on_expose_event(GdkEventExpose* event);
virtual bool on_motion_notify_event(GdkEventMotion* event);
void init_hordeScene();
void setup_hordeViewport();
void render_hordeScene();
void update_hordeScene();
void get_FramesPerSecond();
private:
ResHandle _pipeRes, _fontMatRes, _logoMatRes, _hdrPipeRes, _forwardPipeRes, _deferredPipeRes;
NodeHandle _cam, _knight, _particleSys;
bool _freeze;
float _animTime, _weight;
double last_time;
int frames;
Glib::Timer m_animtimer;
Glib::Timer m_fpstimer;
};
#endif // CHORDEWIDGET_HPP_INCLUDED
|
Now for the cHordeWidget.cpp *Read the comments*
cHordeWidget.cpp |
#include "../include/cHordeWidget.hpp"
NodeHandle model = 0, cam = 0;
cHordeWidget::cHordeWidget(){
Glib::RefPtr<Gdk::GL::Config> glconfig;
glconfig = Gdk::GL::Config::create(Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE);
add_events(Gdk::POINTER_MOTION_MASK);
set_gl_capability(glconfig);
Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 10);
m_animtimer.start();
}
cHordeWidget::~cHordeWidget(){
Horde3D::release();
}
void cHordeWidget::on_realize(){
Gtk::GL::DrawingArea::on_realize();
//get gl::window
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
//begin gl commands
glwindow->gl_begin(get_gl_context());
//init horde
init_hordeScene();
/end gl commands
glwindow->gl_end();
}
bool cHordeWidget::on_configure_event(GdkEventConfigure* event){
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
glwindow->gl_begin(get_gl_context());
//setup the viewport
setup_hordeViewport();
glwindow->gl_end();
return true;
}
bool cHordeWidget::on_expose_event(GdkEventExpose* event){
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
glwindow->gl_begin(get_gl_context());
//render the horde scene
render_hordeScene();
//swap our gl buffers use glflush if you use only one buffer
glwindow->swap_buffers();
glwindow->gl_end();
return true;
}
bool cHordeWidget::on_timeout(){
//update the horde scee
update_hordeScene();
return true;
}
void cHordeWidget::init_hordeScene(){
Horde3DUtils::setResourcePath( ResourceTypes::SceneGraph, "models" );
Horde3DUtils::setResourcePath( ResourceTypes::Geometry, "models" );
Horde3DUtils::setResourcePath( ResourceTypes::Animation, "models" );
Horde3DUtils::setResourcePath( ResourceTypes::Material, "materials" );
Horde3DUtils::setResourcePath( ResourceTypes::Code, "shaders" );
Horde3DUtils::setResourcePath( ResourceTypes::Shader, "shaders" );
Horde3DUtils::setResourcePath( ResourceTypes::Texture2D, "textures" );
Horde3DUtils::setResourcePath( ResourceTypes::TextureCube, "textures" );
Horde3DUtils::setResourcePath( ResourceTypes::Effect, "effects" );
Horde3DUtils::setResourcePath( ResourceTypes::Pipeline, "pipelines" );
// Set options
Horde3D::setOption( EngineOptions::LoadTextures, 1 );
Horde3D::setOption( EngineOptions::TexCompression, 0 );
Horde3D::setOption( EngineOptions::FastAnimation, 0 );
Horde3D::setOption( EngineOptions::AnisotropyFactor, 8 );
Horde3D::setOption( EngineOptions::ShadowMapSize, 2048 );
_hdrPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "hdr.pipeline.xml", 0 );
_forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "forward.pipeline.xml", 0 );
_deferredPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "deferred.pipeline.xml",0);
// Font
_fontMatRes = Horde3D::addResource( ResourceTypes::Material, "font.material.xml", 0 );
// Logo
_logoMatRes = Horde3D::addResource( ResourceTypes::Material, "logo.material.xml", 0 );
// Environment
ResHandle envRes = Horde3D::addResource( ResourceTypes::SceneGraph, "sphere.scene.xml", 0 );
// Knight
ResHandle knightRes = Horde3D::addResource( ResourceTypes::SceneGraph, "knight.scene.xml", 0 );
ResHandle knightAnim1Res = Horde3D::addResource( ResourceTypes::Animation, "knight_order.anim", 0 );
ResHandle knightAnim2Res = Horde3D::addResource( ResourceTypes::Animation, "knight_attack.anim", 0 );
// Particle system
ResHandle particleSysRes = Horde3D::addResource( ResourceTypes::SceneGraph, "particleSys1.scene.xml", 0 );
ResHandle skyBoxRes = Horde3D::addResource( ResourceTypes::SceneGraph, "skybox.scene.xml" ,0);
// Load resources
Horde3DUtils::loadResourcesFromDisk( "media" );
// Add camera
_cam = Horde3D::addCameraNode( RootNode, "Camera", _forwardPipeRes );
//Horde3D::setNodeParami( _cam, CameraNodeParams::OcclusionCulling, 1 );
// Add environment
NodeHandle env = Horde3D::addNodes( RootNode, envRes );
Horde3D::setNodeTransform( env, 0, -20, 0, 0, 0, 0, 20, 20, 20 );
// Add knight
_knight = Horde3D::addNodes( RootNode, knightRes );
Horde3D::setNodeTransform( _knight, 0, 0, 0, 0, 180, 0, 0.1f, 0.1f, 0.1f );
Horde3D::setupModelAnimStage( _knight, 0, knightAnim1Res, "", false );
Horde3D::setupModelAnimStage( _knight, 1, knightAnim2Res, "", false );
// Attach particle system to hand joint
Horde3D::findNodes( _knight, "Bip01_R_Hand", SceneNodeTypes::Joint );
NodeHandle hand = Horde3D::getNodeFindResult( 0 );
_particleSys = Horde3D::addNodes( hand, particleSysRes );
Horde3D::setNodeTransform( _particleSys, 0, 40, 0, 90, 0, 0, 1, 1, 1 );
//add skybox
NodeHandle sky = Horde3D::addNodes( RootNode, skyBoxRes);
//set skybox position
Horde3D::setNodeTransform( sky, 0, 0, 0, 0, 0, 0, 210, 50, 210 );
// Add light source
NodeHandle light = Horde3D::addLightNode( RootNode, "Light1", 0, "LIGHTING", "SHADOWMAP" );
Horde3D::setNodeTransform( light, 0, 15, 10, -60, 0, 0, 1, 1, 1 );
Horde3D::setNodeParamf( light, LightNodeParams::Radius, 30 );
Horde3D::setNodeParamf( light, LightNodeParams::FOV, 90 );
Horde3D::setNodeParami( light, LightNodeParams::ShadowMapCount, 1 );
Horde3D::setNodeParamf( light, LightNodeParams::ShadowMapBias, 0.01f );
Horde3D::setNodeParamf( light, LightNodeParams::Col_R, 1.0f );
Horde3D::setNodeParamf( light, LightNodeParams::Col_G, 0.8f );
Horde3D::setNodeParamf( light, LightNodeParams::Col_B, 0.7f );
// Customize post processing effects
NodeHandle matRes = Horde3D::findResource( ResourceTypes::Material, "postHDR.material.xml" );
// hdrParams: exposure, brightpass threshold, brightpass offset (see shader for description)
Horde3D::setMaterialUniform( matRes, "hdrParams", 2.5f, 0.5f, 0.08f, 0 );
}
void cHordeWidget::setup_hordeViewport(){
//We have to init horde here becuase this is the first thing gtkmm calls when the widget is created.
//This is also called everytime the window is expanded the boolean is there just so nothing bad happens when initing horde over and over.
bool hinit = false;
if(hinit == false){ Horde3D::init(); hinit = true;}
Horde3D::resize(0,0,get_width(),get_height());
Horde3D::setupCameraView(cam,45.0f,(float)get_width()/get_height(),0.1f,1000.0f);
}
void cHordeWidget::render_hordeScene(){
m_fpstimer.start();
//Horde3D::setOption( EngineOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f );
//Horde3D::setOption( EngineOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f );
// Do animation blending
Horde3D::setModelAnimParams( _knight, 0, _animTime , _weight );
Horde3D::setModelAnimParams( _knight, 1, _animTime , 1.0f - _weight );
// Animate particle systems (several emitters in a group node)
unsigned int cnt = cnt = Horde3D::findNodes( _particleSys, "", SceneNodeTypes::Emitter );
for( unsigned int i = 0; i < cnt; ++i )
Horde3D::advanceEmitterTime( Horde3D::getNodeFindResult( i ), 1.0f / _curFPS );
// Set camera parameters
// Show logo
Horde3D::showOverlay( 0.75f, 0, 0, 0, 1, 0, 1, 0,
1, 0.2f, 1, 1, 0.75f, 0.2f, 0, 1,
7, _logoMatRes );
// Render scene
Horde3D::render( _cam );
// Remove all overlays
Horde3D::clearOverlays();
get_FramesPerSecond();
}
void cHordeWidget::update_hordeScene(){
double seconds = m_animtimer.elapsed();
_animTime += seconds * 30;
m_animtimer.reset();
Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );
Gtk::Widget::queue_draw();
}
void cHordeWidget::get_FramesPerSecond(){
++frames;
last_time = last_time + m_fpstimer.elapsed();
if(last_time >= 0){
_curFPS = (float)(frames / last_time);
frames = 0;
last_time = 0;
m_fpstimer.reset();
}
std::cout<<_curFPS<<endl;
}
//This event handler must be set and return false in order for are mouse movement to be captured
bool cHordeWidget::on_motion_notify_event(GdkEventMotion* event){
return false;
}
|
Now for the window widget.
cWindow.hpp |
#ifndef CWINDOW_HPP_INCLUDED
#define CWINDOW_HPP_INCLUDED
#include <gtkmm.h>
#include <math.h>
#include "cHordeWidget.hpp"
class cWindow : public Gtk::Window{
public:
cWindow();
virtual ~cWindow();
protected:
virtual bool on_key_press_event(GdkEventKey* event);
virtual bool on_key_release_event(GdkEventKey* event);
virtual bool on_motion_notify_event(GdkEventMotion* event);
virtual bool on_focus_in (GdkEventFocus*);
bool on_timeout();
void handleinput();
private:
Gtk::VBox m_vBox;
cHordeWidget m_hordeWidget;
};
#endif // CWINDOW_HPP_INCLUDED
|
Now the window widgets cpp
cWindow.cpp |
#include "../include/cWindow.hpp"
inline float degToRad( float f )
{
return f * (3.1415926f / 180.0f);
}
//array to hold keys
int keyDown[256];
cWindow::cWindow(){
set_title("Horde with gtkmm");
set_reallocate_redraws(true);
add(m_vBox);
add_events(Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK |
Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
Glib::signal_timeout().connect( sigc::mem_fun(*this, &cWindow::on_timeout), 10);
signal_focus_in_event().connect(sigc::mem_fun(*this, &cWindow::on_focus_in) );
m_hordeWidget.set_size_request(800,600);
m_vBox.pack_start(m_hordeWidget);
show_all();
}
cWindow::~cWindow(){
}
bool cWindow::on_key_press_event(GdkEventKey* event){
if(event->keyval == GDK_Escape){
Gtk::Main::quit();}else{
//sets the key in the array to true
keyDown[event->keyval] = 1;}
return true;
}
bool cWindow::on_key_release_event(GdkEventKey *event){
//sets the key in the array to false
keyDown[event->keyval] = 0;
return true;
}
void cWindow::handleinput(){
float curVel = 240/m_hordeWidget._curFPS;
//checks if a certain key is true and acts on it
if(keyDown['w']){
m_hordeWidget._x -= sinf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel;
m_hordeWidget._y -= sinf( -degToRad( m_hordeWidget._rx ) ) * curVel;
m_hordeWidget._z -= cosf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel;
}
if(keyDown['s']){
m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel;
m_hordeWidget._y += sinf( -degToRad( m_hordeWidget._rx ) ) * curVel;
m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry ) ) * cosf( -degToRad( m_hordeWidget._rx ) ) * curVel;
}
if(keyDown['a']){
m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry - 90) ) * curVel;
m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry - 90 ) ) * curVel;
}
if(keyDown['d']){
m_hordeWidget._x += sinf( degToRad( m_hordeWidget._ry + 90 ) ) * curVel;
m_hordeWidget._z += cosf( degToRad( m_hordeWidget._ry + 90 ) ) * curVel;
}
}
//called only when mouse is moved *cause for the camera appearing glitchy*
bool cWindow::on_motion_notify_event(GdkEventMotion* event){
m_hordeWidget._ry -= (event->x -(get_width() /2)) / 450 ;
m_hordeWidget._rx -= (event->y -(get_height()/2)) / 450 ;
if( m_hordeWidget._rx > 90 ) m_hordeWidget._rx = 90;
if( m_hordeWidget._rx < -90 ) m_hordeWidget._rx = -90;
return false;
}
//called constantly
bool cWindow::on_timeout(){
int xp = 0;
int yp = 0;
get_pointer(xp,yp);
handleinput();
return true;
}
bool cWindow::on_focus_in(GdkEventFocus* event )
{
//Hide the curosr
// Ok, here we create a dummy cursor. See gdkmm reference for more details
Gdk::Cursor cursor = Gdk::Cursor(Gdk::Display::get_default(),
Gdk::Pixbuf::create(
Gdk::COLORSPACE_RGB, true, 8, 1, 1),
0, 0);
get_window()->set_cursor(cursor);
return true;
}
|
Finnaly the main.cpp *Read the Comments*
main.cpp |
#include <gtkmm.h>
//Include our custom widget
#include "include/cWindow.hpp"
int main(int argc, char *argv[]){
//Init Gtk+
Gtk::Main init (argc, argv);
//Init Gtk+ opengl
Gtk::GL::init (argc, argv);
//Create our Window object
cWindow window;
//Run the program
Gtk::Main::run(window);
//Safe exit message
return EXIT_SUCCESS;
}
|
--Rj 23:21, 8 August 2008 (CEST)
|
|
|
|
Horde With Gtkmm |
|
This tutorial introduces the use of Horde3D with Gtkmm |
Version: |
1.0 |
Compatible with Horde3D: |
1.0 beta |
Release date: |
2008-07-8 |
Author(s): |
Raynaldo Rivera |
|