Difference between revisions of "Tutorial - Setup Horde with Gtkmm"
From Horde3D Wiki
(New page: {| border="0" | {{ContentBlock|width=800|color=white |content='''Here is a small example on how to use Horde with Gtkmm.''' This is a small tutorial on how to setup Horde with Gtk+ usin...) |
|||
Line 3: | Line 3: | ||
|content='''Here is a small example on how to use Horde with Gtkmm.''' | |content='''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 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 :) | ||
{{CppSourceCode| | {{CppSourceCode| | ||
Line 11: | Line 12: | ||
#ifndef CHORDEWIDGET_HPP_INCLUDED | #ifndef CHORDEWIDGET_HPP_INCLUDED | ||
#define CHORDEWIDGET_HPP_INCLUDED | #define CHORDEWIDGET_HPP_INCLUDED | ||
− | + | #include <iostream> | |
− | #include <iostream> | ||
#include <Horde3D.h> | #include <Horde3D.h> | ||
#include <Horde3DUtils.h> | #include <Horde3DUtils.h> | ||
#include <cstdlib> | #include <cstdlib> | ||
− | |||
#include <gtkmm.h> | #include <gtkmm.h> | ||
− | |||
#include <gtkglmm.h> | #include <gtkglmm.h> | ||
+ | #include <sstream> | ||
+ | #include <math.h> | ||
+ | #include <iomanip> | ||
+ | |||
+ | using namespace std; | ||
+ | |||
− | |||
class cHordeWidget : public Gtk::GL::DrawingArea{ | class cHordeWidget : public Gtk::GL::DrawingArea{ | ||
public: | public: | ||
cHordeWidget(); | cHordeWidget(); | ||
virtual ~cHordeWidget(); | virtual ~cHordeWidget(); | ||
+ | bool on_timeout(); | ||
protected: | protected: | ||
Line 31: | Line 35: | ||
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); | ||
+ | void init_hordeScene(); | ||
+ | void setup_hordeViewport(); | ||
+ | void render_hordeScene(); | ||
+ | void update_hordeScene(); | ||
+ | |||
private: | private: | ||
− | ResHandle | + | ResHandle _pipeRes, _fontMatRes, _logoMatRes, _hdrPipeRes, _forwardPipeRes; |
+ | 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; | ||
+ | float _animTime, _weight; | ||
+ | |||
}; | }; | ||
#endif // CHORDEWIDGET_HPP_INCLUDED | #endif // CHORDEWIDGET_HPP_INCLUDED | ||
− | |||
− | |||
</source> | </source> | ||
Line 54: | Line 71: | ||
Glib::RefPtr<Gdk::GL::Config> glconfig; | Glib::RefPtr<Gdk::GL::Config> glconfig; | ||
− | // | + | //Pick are 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 |
set_gl_capability(glconfig); | set_gl_capability(glconfig); | ||
+ | //add are idle signal. | ||
+ | Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 20 ); | ||
} | } | ||
cHordeWidget::~cHordeWidget(){ | cHordeWidget::~cHordeWidget(){ | ||
− | |||
Horde3D::release(); | Horde3D::release(); | ||
} | } | ||
void cHordeWidget::on_realize(){ | void cHordeWidget::on_realize(){ | ||
− | |||
Gtk::GL::DrawingArea::on_realize(); | Gtk::GL::DrawingArea::on_realize(); | ||
− | // | + | //get gl::window |
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window(); | Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window(); | ||
− | // | + | //begin gl commands |
glwindow->gl_begin(get_gl_context()); | glwindow->gl_begin(get_gl_context()); | ||
− | // | + | |
− | + | //init horde | |
− | + | init_hordeScene(); | |
− | + | ||
− | + | /end gl commands | |
glwindow->gl_end(); | glwindow->gl_end(); | ||
} | } | ||
Line 85: | Line 102: | ||
bool cHordeWidget::on_configure_event(GdkEventConfigure* event){ | bool cHordeWidget::on_configure_event(GdkEventConfigure* event){ | ||
− | |||
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window(); | 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()); | glwindow->gl_begin(get_gl_context()); | ||
− | Horde3D:: | + | //render the horde scene |
+ | render_hordeScene(); | ||
+ | |||
+ | //swap are 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 ); | ||
+ | |||
+ | // Add resources | ||
+ | // Pipelines | ||
+ | _hdrPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "hdr.pipeline.xml", 0 ); | ||
+ | _forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "forward.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 ); | ||
+ | |||
+ | // Load resources | ||
+ | Horde3DUtils::loadResourcesFromDisk( "media" ); | ||
+ | |||
+ | // Add scene nodes | ||
+ | // Add camera | ||
+ | _cam = Horde3D::addCameraNode( RootNode, "Camera", _hdrPipeRes ); | ||
+ | //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 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(){ | |
− | + | float fps = 60; | |
− | + | _curFPS = fps; | |
− | + | _timer += 1 / fps; | |
− | + | Horde3D::setOption( EngineOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f ); | |
+ | Horde3D::setOption( EngineOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f ); | ||
− | + | _animTime += 1.0f / _curFPS; | |
− | + | // Do animation blending | |
− | Horde3D:: | + | Horde3D::setModelAnimParams( _knight, 0, _animTime * 24.0f, _weight ); |
− | + | Horde3D::setModelAnimParams( _knight, 1, _animTime * 24.0f, 1.0f - _weight ); | |
− | |||
− | Horde3D:: | ||
− | |||
− | |||
− | //Horde3D:: | + | // 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 | |
+ | Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 ); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | // 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(); | ||
+ | |||
+ | } | ||
+ | |||
+ | 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()); | ||
+ | Gtk::Widget::queue_draw(); | ||
+ | } | ||
+ | |||
+ | |||
+ | </source> | ||
+ | }} | ||
+ | Now for the window widget. | ||
+ | {{CppSourceCode| | ||
+ | description= cWindow.hpp| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | |||
+ | #ifndef CWINDOW_HPP_INCLUDED | ||
+ | #define CWINDOW_HPP_INCLUDED | ||
+ | #include <gtkmm.h> | ||
+ | #include "cHordeWidget.hpp" | ||
+ | |||
+ | class cWindow : public Gtk::Window{ | ||
+ | public: | ||
+ | cWindow(); | ||
+ | virtual ~cWindow(); | ||
+ | |||
+ | protected: | ||
+ | |||
+ | virtual bool on_key_press_event(GdkEventKey* event); | ||
+ | |||
+ | private: | ||
+ | Gtk::VBox m_vBox; | ||
+ | |||
+ | cHordeWidget m_hordeWidget; | ||
+ | |||
+ | }; | ||
+ | |||
+ | #endif // CWINDOW_HPP_INCLUDED | ||
+ | |||
+ | </source> | ||
+ | }} | ||
+ | Now the window widgets cpp | ||
+ | {{CppSourceCode| | ||
+ | description= cWindow.cpp| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | |||
+ | #include "../include/cWindow.hpp" | ||
+ | |||
+ | cWindow::cWindow(){ | ||
+ | //set the windows title | ||
+ | set_title("Horde with gtkmm"); | ||
+ | //makes the window update if it is expanded etc. | ||
+ | set_reallocate_redraws(true); | ||
+ | //adds a box to place the hordewidget and other widgets into | ||
+ | add(m_vBox); | ||
+ | //sets the minimum and default size for our window | ||
+ | m_hordeWidget.set_size_request(800,600); | ||
+ | //makes the widget expand when the window is expanded | ||
+ | m_vBox.pack_start(m_hordeWidget); | ||
+ | //shows all widgets. by default all widgets are invisible. | ||
+ | show_all(); | ||
+ | } | ||
+ | |||
+ | cWindow::~cWindow(){ | ||
− | |||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | bool cWindow::on_key_press_event(GdkEventKey* event){ | |
− | + | ||
− | + | switch (event->keyval) | |
− | + | { | |
+ | case GDK_a: | ||
+ | std::cout<<"test"; | ||
+ | break; | ||
+ | |||
+ | case GDK_Escape: | ||
+ | //ends our app | ||
+ | Gtk::Main::quit(); | ||
− | + | break; | |
− | + | default: | |
− | + | return true; | |
− | + | } | |
return true; | return true; | ||
Line 204: | Line 386: | ||
</source> | </source> | ||
}} | }} | ||
− | --[[User:Wild13|Rj]] 23:21, | + | --[[User:Wild13|Rj]] 23:21, 8 August 2008 (CEST) |
}} | }} | ||
| valign="top" | {{Extension_Summary| | | valign="top" | {{Extension_Summary| |
Revision as of 19:41, 8 August 2008
|
|