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>
using namespace std;
class cHordeWidget : public Gtk::GL::DrawingArea{
public:
cHordeWidget();
virtual ~cHordeWidget();
bool on_timeout();
protected:
virtual void on_realize();
virtual bool on_configure_event(GdkEventConfigure* event);
virtual bool on_expose_event(GdkEventExpose* event);
//our horde init function
void init_hordeScene();
//our horde viewport functon
void setup_hordeViewport();
//our horde render function
void render_hordeScene();
//finnaly our horde update function
void update_hordeScene();
private:
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,fps;
};
#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(){
//sets the fps we want
fps = 60;
_curFPS = fps;
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);
//set the opengl options
set_gl_capability(glconfig);
//add our idle signal.
Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 20 );
}
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 );
// 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(){
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 * 24.0f, _weight );
Horde3D::setModelAnimParams( _knight, 1, _animTime * 24.0f, 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
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.
_timer += 1 / fps;
_animTime += 1.0f / _curFPS;
Gtk::Widget::queue_draw();
}
|
Now for the window widget.
cWindow.hpp |
#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
|
Now the window widgets cpp
cWindow.cpp |
#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;
}
|
Finnaly the main.cpp *Read the Comments*
main.cpp |
#include <gtkmm.h>
//Include our custom widget
#include "include/cHordeWidget.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
Gtk::Window window;
//Set our window title
window.set_title ("Horde3D In Gtk+ Window");
//Create our cHordeWidget
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;
}
|
--Rj 23:21, 8 August 2008 (CEST)
|