Difference between revisions of "Tutorial - Setup Horde with Gtkmm"

From Horde3D Wiki
Jump to: navigation, search
(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>
//We include the gtkmm header
 
 
#include <gtkmm.h>
 
#include <gtkmm.h>
//Now we include the gtkglmm header
 
 
#include <gtkglmm.h>
 
#include <gtkglmm.h>
 +
#include <sstream>
 +
#include <math.h>
 +
#include <iomanip>
 +
 +
using namespace std;
 +
  
//We declare the cHordeWidget class and it inherits the Gtk::GL::DrawingArea class
 
 
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 logoRes;
+
         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;
     //We pick are opengl config options.
+
     //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);
     //We set are options here.
+
     //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(){
    //we release the Horde3D engine here
 
 
     Horde3D::release();
 
     Horde3D::release();
 
}
 
}
  
 
void cHordeWidget::on_realize(){
 
void cHordeWidget::on_realize(){
    //We must call this base class before anything else
 
 
     Gtk::GL::DrawingArea::on_realize();
 
     Gtk::GL::DrawingArea::on_realize();
  
     //Get Our opengl window must do
+
     //get gl::window
 
     Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
 
     Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
  
     //Begin working with the gl context everything we do will go under here.
+
     //begin gl commands
 
     glwindow->gl_begin(get_gl_context());
 
     glwindow->gl_begin(get_gl_context());
     //Resize our Horde3D screen
+
 
     Horde3D::resize(0,0,800,600);
+
     //init horde
     //set camera view
+
     init_hordeScene();
    Horde3D::setupCameraView(cam,45.0f,(float)800/600,0.1f,1000.0f);
+
      
     //end opengl
+
     /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){
  
    //get gl window
 
 
     Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
 
     Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
     //Begin working with the gl context everything we do will go under here.
+
 
 +
    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::init();
+
     //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 );
 +
 
 +
}
  
    Horde3DUtils::setResourcePath( ResourceTypes::SceneGraph, "models" );
+
void cHordeWidget::setup_hordeViewport(){
     Horde3DUtils::setResourcePath( ResourceTypes::Geometry, "models" );
+
    //We have to init horde here becuase this is the first thing gtkmm calls when the widget is created.
     Horde3DUtils::setResourcePath( ResourceTypes::Animation, "models" );
+
     //This is also called everytime the window is expanded the boolean is there just so nothing bad happens when initing horde over and over.
     Horde3DUtils::setResourcePath( ResourceTypes::Material, "materials" );
+
     bool hinit = false;
    Horde3DUtils::setResourcePath( ResourceTypes::Code, "shaders" );
+
     if(hinit == false){ Horde3D::init(); hinit = true;}
     Horde3DUtils::setResourcePath( ResourceTypes::Shader, "shaders" );
+
     Horde3D::resize(0,0,get_width(),get_height());
    Horde3DUtils::setResourcePath( ResourceTypes::Texture2D, "textures" );
+
     Horde3D::setupCameraView(cam,45.0f,(float)get_width()/get_height(),0.1f,1000.0f);
     Horde3DUtils::setResourcePath( ResourceTypes::TextureCube, "textures" );
+
}
    Horde3DUtils::setResourcePath( ResourceTypes::Effect, "effects" );
 
    Horde3DUtils::setResourcePath( ResourceTypes::Pipeline, "pipelines" );
 
  
    ResHandle pipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "deferred.pipeline.xml",0);
+
void cHordeWidget::render_hordeScene(){
     ResHandle modelRes = Horde3D::addResource(ResourceTypes::SceneGraph,"charecter.scene.xml",0);
+
     float fps = 60;
     ResHandle animRes = Horde3D::addResource(ResourceTypes::Animation,"walk.anim.xml",0);
+
     _curFPS = fps;
    ResHandle fontRes = Horde3D::addResource(ResourceTypes::Material,"font.material.xml",0);
+
_timer += 1 / fps;
  
    logoRes = Horde3D::addResource(ResourceTypes::Material,"logo.material.xml",0);
+
Horde3D::setOption( EngineOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f );
 +
Horde3D::setOption( EngineOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f );
  
     Horde3DUtils::loadResourcesFromDisk("media");
+
     _animTime += 1.0f / _curFPS;
  
    Horde3D::setOption( EngineOptions::LoadTextures, 1 );
+
// Do animation blending
     Horde3D::setOption( EngineOptions::TexCompression, 0 );
+
     Horde3D::setModelAnimParams( _knight, 0, _animTime * 24.0f, _weight );
    Horde3D::setOption( EngineOptions::FastAnimation, 0 );
+
     Horde3D::setModelAnimParams( _knight, 1, _animTime * 24.0f, 1.0f - _weight );
    Horde3D::setOption( EngineOptions::AnisotropyFactor, 8 );
 
     Horde3D::setOption( EngineOptions::ShadowMapSize, 2048 );
 
    Horde3D::setOption( EngineOptions::DebugViewMode,0.0f);
 
    model = Horde3D::addNodes(RootNode,modelRes);
 
  
     //Horde3D::setupModelAnimStage(model,0,animRes,"",true);
+
     // 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 );
  
    NodeHandle light = Horde3D::addLightNode(RootNode,"Light1", 0,"LIGHTING","SHADOWMAP");
 
  
    Horde3D::setNodeTransform(light,0,2,0,0,00,0,1,1,1);
+
// Set camera parameters
 +
Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );
  
    Horde3D::setNodeParamf( light, LightNodeParams::Radius, 50 );
 
    Horde3D::setNodeParamf( light, LightNodeParams::FOV, 90 );
 
    Horde3D::setNodeParami( light, LightNodeParams::ShadowMapCount, 3 );
 
    Horde3D::setNodeParamf( light, LightNodeParams::ShadowSplitLambda, 0.9f );
 
    Horde3D::setNodeParamf( light, LightNodeParams::ShadowMapBias, 0.001f );
 
    Horde3D::setNodeParamf( light, LightNodeParams::Col_R, 0.9f );
 
    Horde3D::setNodeParamf( light, LightNodeParams::Col_G, 0.7f );
 
    Horde3D::setNodeParamf( light, LightNodeParams::Col_B, 0.75f );
 
  
    cam = Horde3D::addCameraNode(RootNode,"Camera",pipeRes);
+
// 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 );
  
     Horde3DUtils::dumpMessages();
+
// Render scene
     //end opengl
+
Horde3D::render( _cam );
     glwindow->gl_end();
+
 
 +
// 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(){
  
    return true;
 
 
}
 
}
//This on_expose_event is are game loop everything game related goes here
 
bool cHordeWidget::on_expose_event(GdkEventExpose* event){
 
    float curFps = 60;
 
    curFps = curFps + 10.0f * ( 1/curFps);
 
   
 
    //get gl::window
 
    Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
 
   
 
    //Begin working with the gl context everything we do will go under here.
 
    glwindow->gl_begin(get_gl_context());
 
  
    Horde3D::setNodeTransform(model,curFps*10,0,0,0,0,0,1,1,1);
+
bool cWindow::on_key_press_event(GdkEventKey* event){
     Horde3D::showOverlay(0.75f,0,0,0,1,0,1,0,1,0.2f,1,1,0.75f,0.2f,0,1,7,logoRes);
+
 
     Horde3D::render(cam);
+
     switch (event->keyval)
     Horde3D::clearOverlays();
+
     {
 +
    case GDK_a:
 +
      std::cout<<"test";
 +
      break;
 +
 
 +
     case GDK_Escape:
 +
      //ends our app
 +
      Gtk::Main::quit();
  
    //end opengl
+
      break;
    glwindow->gl_end();
+
      default:
     //Since we have a double buffer opengl context we must swap them here
+
      return true;
    glwindow->swap_buffers();
+
     }
  
 
     return true;
 
     return true;
Line 204: Line 386:
 
</source>
 
</source>
 
}}
 
}}
--[[User:Wild13|Rj]] 23:21, 7 August 2008 (CEST)
+
--[[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

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);
        void init_hordeScene();
        void setup_hordeViewport();
        void render_hordeScene();
        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;

};

#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;
    //Pick are 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 are 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 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::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.
    Glib::RefPtr<Gdk::Window> win = get_window();

    Gdk::Rectangle r(0, 0,get_width(),get_height());
    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 are 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)

Horde With Gtkmm
H3DPlaceHolder.png
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