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...) |
|||
(8 intermediate revisions by the same user not shown) | |||
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> | ||
+ | #include <glibmm/timer.h> | ||
+ | |||
+ | 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(); | |
+ | 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); | ||
+ | virtual bool on_motion_notify_event(GdkEventMotion* event); | ||
+ | void init_hordeScene(); | ||
+ | void setup_hordeViewport(); | ||
+ | void render_hordeScene(); | ||
+ | void update_hordeScene(); | ||
+ | void get_FramesPerSecond(); | ||
private: | private: | ||
− | ResHandle | + | 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 | #endif // CHORDEWIDGET_HPP_INCLUDED | ||
− | |||
− | |||
</source> | </source> | ||
Line 54: | Line 76: | ||
Glib::RefPtr<Gdk::GL::Config> glconfig; | Glib::RefPtr<Gdk::GL::Config> glconfig; | ||
− | + | ||
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); | ||
− | + | add_events(Gdk::POINTER_MOTION_MASK); | |
set_gl_capability(glconfig); | set_gl_capability(glconfig); | ||
+ | Glib::signal_timeout().connect( sigc::mem_fun(*this, &cHordeWidget::on_timeout), 10); | ||
+ | m_animtimer.start(); | ||
} | } | ||
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 107: | ||
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 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 ); | |
− | |||
− | |||
− | Horde3D:: | ||
− | |||
− | |||
− | + | 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; | ||
+ | } | ||
+ | |||
+ | </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 <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 | ||
+ | |||
+ | </source> | ||
+ | }} | ||
+ | Now the window widgets cpp | ||
+ | {{CppSourceCode| | ||
+ | description= cWindow.cpp| | ||
+ | code= | ||
+ | <source lang="cpp" line="1"> | ||
+ | |||
+ | #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; | 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 176: | Line 460: | ||
#include <gtkmm.h> | #include <gtkmm.h> | ||
− | //Include | + | //Include our custom widget |
− | #include "include/ | + | #include "include/cWindow.hpp" |
int main(int argc, char *argv[]){ | int main(int argc, char *argv[]){ | ||
Line 185: | Line 469: | ||
Gtk::GL::init (argc, argv); | Gtk::GL::init (argc, argv); | ||
//Create our Window object | //Create our Window object | ||
− | + | cWindow window; | |
− | // | + | //Run the program |
− | + | Gtk::Main::run(window); | |
− | + | //Safe exit message | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Gtk::Main::run (window); | ||
− | // | ||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||
+ | |||
} | } | ||
</source> | </source> | ||
}} | }} | ||
− | --[[User:Wild13|Rj]] 23:21, | + | --[[User:Wild13|Rj]] 23:21, 8 August 2008 (CEST) |
}} | }} | ||
| valign="top" | {{Extension_Summary| | | valign="top" | {{Extension_Summary| |
Latest revision as of 19:06, 17 August 2008
|
|