New GtkOgre widget with demo!

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

New GtkOgre widget with demo!

Post by DWORD »

Hi,

I'd like to announce the release of a new GtkOgre widget. It embeds Ogre render windows into GtkWidgets, but it's still very basic. You won't believe how many hours I spent with expose events and stopping it from flickering, though. ;)

This is actually a side-product, because in the end I want to write a cross-platform wxWidget so it becomes very easy to embed Ogre on all platforms (Windows and Linux at least, don't know Mac).

The small demo application in action (it does nothing but display the scene):

Image

Source code: gtkogre-0.1.0-src.tar.bz2

Now let's see some cross-platform tools! :twisted:
reimpell
OGRE Contributor
OGRE Contributor
Posts: 570
Joined: Mon Mar 01, 2004 10:35 am
Location: Hamburg, Germany

Post by reimpell »

Great! Now one just need to write a wrapper for gtkmm...
Ocelot
Kobold
Posts: 33
Joined: Fri Dec 23, 2005 11:09 am
Location: Kraków, Poland

Post by Ocelot »

DWORD YOU ARE GREAT !!!!
After some changes (thanks Shaft) I can use it in Windows !!!
Proof:
Image

And changes: ALL in gtkogre.cpp
1. include

Code: Select all

#if defined( __WIN32__ ) || defined( _WIN32 )
#include <gdk/gdkwin32.h>
#else
#include <gdk/gdkx.h>
#endif
2. Parameters for Ogre::Root::getSingleton().createRenderWindow

Code: Select all

  Ogre::NameValuePairList params;
#if defined( __WIN32__ ) || defined( _WIN32 )
  params["parentWindowHandle"] =
    Ogre::StringConverter::toString((unsigned long)GDK_WINDOW_HWND(parent));
#else
  Display* xdisplay = GDK_DISPLAY_XDISPLAY(display);
  Screen* xscreen = GDK_SCREEN_XSCREEN(screen);
  int screen_number = XScreenNumberOfScreen(xscreen);
  XID xid_parent = GDK_WINDOW_XWINDOW(parent);

  params["parentWindowHandle"] =
    Ogre::StringConverter::toString(reinterpret_cast<unsigned long>(xdisplay)) + ":" +
    Ogre::StringConverter::toString(static_cast<unsigned int>(screen_number)) + ":" +
    Ogre::StringConverter::toString(static_cast<unsigned long>(xid_parent));
#endif
3. Get the window id of the render window

Code: Select all

  /* Get the window id of the render window */
  GdkNativeWindow xid;
#if defined( __WIN32__ ) || defined( _WIN32 )
  ogre->render_window->getCustomAttribute("HWND", (void*)&xid);
#else
  ogre->render_window->getCustomAttribute("GLXWINDOW", (void*)&xid);
#endif
If you want, I can send you my code::blocks project file, which compile your demo program.

Wait for my GREAT, SUPER Ogre tools....
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

Ocelot wrote:After some changes (thanks Shaft) I can use it in Windows !!!
Wow, didn't expect that to be so easy; I thought GTK was difficult to set up on Windows. I'll put in your changes. Thanks. :)
Ocelot wrote:If you want, I can send you my code::blocks project file, which compile your demo program.
I don't use Code::Blocks myself but maybe others will find it useful.
Ocelot wrote:Wait for my GREAT, SUPER Ogre tools....
I will. :P
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Post by jacmoe »

@DWORD: Awesome! And it would be even more awesome once this is wxWidget'ed. 8)

@Ocelot: What do you need to download in order to build this on Windows? :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

By all reports the standard wxOgre widget from the wiki works fine for windows. I think we might need another custom effort like this on Mac, but I am not sure.

EDIT: Thanks for posting this, all the code you have to build the "parentWindowHandle" is directly applicable to wxOgre and wxGTK. Hopefully I or somebody else will actually find the time to update it. Now we really do need mac support.

I guess its time to start digging down into the Mac OpenGL support. For every ones edification, wxMac returns a ControlRef from Window::GetHandle().
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

I was not implying that the existing wxOgre didn't work. :) But it has some small limitations, no support for multiple render windows being one of them, but that's easy to overcome. Linux support was a bit more work, at least for wxGTK because it had to go through a custom GtkWidget. But I've put the cross-platform wxOgre on hold for a while, got tired of tumbling with wxWidgets, I hit some weird problems on Linux. And I found that the (free) tools for GTK development were much better. :?
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

I can understand the tools issue, the state of free wxWidgets RAD tools is not super good.

Its great to give people another alternative to wxWidgets and .NET for Ogre based tool making.
Ocelot
Kobold
Posts: 33
Joined: Fri Dec 23, 2005 11:09 am
Location: Kraków, Poland

Post by Ocelot »

DWORD, I'm playing a little with gtkogre widget and there is one "simple" problem. I can't force the widget to obtain signals other then "expose_event" and "scroll-event" (and probably destroy and delete ;) ).
I've try add mask

Code: Select all

gtk_widget_add_events(GTK_WIDGET(ogre), GDK_BUTTON_PRESS_MASK);
set mask (in gtkogre.h)

Code: Select all

gdk_window_set_events(widget->window, static_cast<GdkEventMask>(
      gdk_window_get_events(widget->window) | GDK_EXPOSURE_MASK |GDK_BUTTON_PRESS_MASK ));
and even add event box over a gtkogre widget. But without success.

Do you know how to solve this?
I think that, the problem is with "parentWindowHandle" and gdk_window_foreign_new struff. When I use "externalWindowHandle", gtk signals are o'k but window looks ... hm funy.

PS. I've try connect OIS to the Ogre render window, result:
An exception has occured: Win32Mouse::Win32Mouse >> Failed to set coop level 64
:cry: :cry: :cry:
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99

Post by Wolfmanfx »

I added a VC8 sln to buíld under windows i slightly modifi the demo to work against Eihort.
There a are still small bugs where no expose event is called.
I tested it with DX9 renderer plugin this works not so good as the OGL renderer maybe someone else should test it.

http://stud3.tuwien.ac.at/~e0126198/gtk ... ed_vc8.rar

@jacmoe
You need gtk-win32-devel-2.6.10-rc1.exe then u have to set OGRE_BASEPATH to ogre root and then u can build with VC8 Project files.
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99

Post by Wolfmanfx »

[edit]: Sry false URL
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99

Post by Wolfmanfx »

User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

To bring back and old topic, has anyone got this to work on Ubuntu Dapper? I have gotten it running but it doesn't embed the windows, they are floating.
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

So, I am trying this with Ubuntu Edgy, and Ogre 1.3 CVS and it needs some change to run with the new release of Ogre. See bellow for the line that fails.

Code: Select all

  /* Get the window id of the render window */
  XID xid;
  ogre->render_window->getCustomAttribute("GLXWINDOW", &xid);

  /* Create the widget's GdkWindow from the render window */
  widget->window = gdk_window_foreign_new(xid);  /* THIS FAILS */
  gdk_window_set_user_data(widget->window, widget);
The getCustomAttribute line needs to be changed to:

Code: Select all

ogre->render_window->getCustomAttribute("WINDOW", &xid);
Then it works just fine, now onto getting this to work with wxWidgets.
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99

Post by Wolfmanfx »

Hi iam also using ubuntu :)
Why all Guys using wxWidgets use gtk+ ^^ soon i will release a crossplattform windowmanager for gtk+(its like window forms) http://stud3.tuwien.ac.at/~e0126198/ogre2vp.jpg here a shot under linux http://stud3.tuwien.ac.at/~e0126198/win ... _linux.png but iam working now at a toolbar system...
Trigve
Kobold
Posts: 25
Joined: Sun Dec 17, 2006 10:20 pm
Location: Slovakia

gtkmm ogre widget

Post by Trigve »

Hi @ll,

I'm making game editor and want to make it with gtkmm/GTK+...On wiki I've found GTK ogre widget...I was happy:) but when I was using it I've encounter the bugs like no expose events or mouse motion notify events (as written in this topic)...so I was looking in code to find if something can be done to fix it...So I've made new gtkmm ogre widget...it is based on gtkmm custom widget example and GTK+ widget (first post in this topic)... I don't have any ftp server or so where can I put it...so I'm pasting the code here....hope it will help someone..it was tested on winXP with ogre 1.2.4, GTK+ 2.10.6, gtkmm 2.10.5-1

GtkOgreWidget.h

Code: Select all

#pragma once

#include <gtkmm/widget.h>

class GtkOgreWidget : public Gtk::Widget
{
	// Attributes
private:
	//! GDK window.
	Glib::RefPtr<Gdk::Window> m_refGdkWindow;
	//! Ogre render window.
	Ogre::RenderWindow* m_pWindow;
	//! ID of window.
	static int m_ID;

	// Operations
public:
	//! Get ogre render window.
	Ogre::RenderWindow* getRenderWindow(void) throw();

protected:
	virtual void on_size_request(Gtk::Requisition* requisition);
	virtual void on_size_allocate(Gtk::Allocation& allocation);
	virtual void on_map();
	virtual void on_unmap();
	virtual void on_realize();
	virtual void on_unrealize();
	virtual bool on_expose_event(GdkEventExpose* event);
	

	// Construction/Destruction
public:
	GtkOgreWidget(void);
	virtual ~GtkOgreWidget(void);
};
GtkOgreWidget.cpp

Code: Select all

#include "GtkOgreWidget.h"

int GtkOgreWidget::m_ID = 0;

GtkOgreWidget::GtkOgreWidget(void)
	: Glib::ObjectBase("GtkOgre"), Gtk::Widget(), m_pWindow(NULL)
{
	set_flags(Gtk::NO_WINDOW);
	//This shows the GType name, which must be used in the RC file.
	std::cout << "GType name: " <<G_OBJECT_TYPE_NAME(gobj()) << std::endl;
	
}

GtkOgreWidget::~GtkOgreWidget(void)
{
}

void GtkOgreWidget::on_size_request(Gtk::Requisition* requisition)
{
	//Initialize the output parameter:
	*requisition = Gtk::Requisition();

	//Discover the total amount of minimum space needed by this widget.

	//Let's make this simple example widget always need 50 by 50:
	requisition->height = 200;
	requisition->width = 200;
}

void GtkOgreWidget::on_size_allocate(Gtk::Allocation& allocation)
{
	std::cout << "GtkOgreWidget::on_size_allocate" << std::endl;
	//Do something with the space that we have actually been given:
	//(We will not be given heights or widths less than we have requested, though we might get more)

	//Use the offered allocation for this container:
	set_allocation(allocation);

	if(m_refGdkWindow)
		m_refGdkWindow->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height());

	
	if (m_pWindow)
	{
		/* Let Ogre update the viewport dimensions. */
		getRenderWindow()->windowMovedOrResized();
//		std::cout << "Width:" << getRenderWindow()->getWidth() << ", Height:" << getRenderWindow()->getHeight() << std::endl;
		on_expose_event(NULL);
	}
}

void GtkOgreWidget::on_map()
{
	//Call base class:
	Gtk::Widget::on_map();
}

void GtkOgreWidget::on_unmap()
{
	//Call base class:
	Gtk::Widget::on_unmap();
}

void GtkOgreWidget::on_realize()
{
	//Call base class:
	Gtk::Widget::on_realize();
	if(!m_refGdkWindow)
	{
		//Create the GdkWindow:
		GdkWindowAttr attributes;
		memset(&attributes, 0, sizeof(attributes));

		Gtk::Allocation allocation = get_allocation();

		//Set initial position and size of the Gdk::Window:
		attributes.x = allocation.get_x();
		attributes.y = allocation.get_y();
		attributes.width = allocation.get_width();
		attributes.height = allocation.get_height();

		attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK | Gdk::ALL_EVENTS_MASK ; 
		attributes.window_type = GDK_WINDOW_CHILD;
		attributes.wclass = GDK_INPUT_OUTPUT;

		m_refGdkWindow = Gdk::Window::create(get_window(), &attributes, GDK_WA_X | GDK_WA_Y);
		Ogre::NameValuePairList params; 
#ifdef WIN32
	params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned long)GDK_WINDOW_HWND(m_refGdkWindow->gobj()));
#else
#endif
		m_pWindow = Ogre::Root::getSingleton().createRenderWindow("GtkOgreWidget" + Ogre::StringConverter::toString(++m_ID),
			allocation.get_width(), allocation.get_height(), false, &params);
		
		unset_flags(Gtk::NO_WINDOW);
		set_window(m_refGdkWindow);

		set_double_buffered(false);
		//make the widget receive expose events
		m_refGdkWindow->set_user_data(gobj());
		m_refGdkWindow->set_back_pixmap(Glib::RefPtr<Gdk::Pixmap>(), false);
		//Allocate a GC for use in on_expose_event():
	}
}

void GtkOgreWidget::on_unrealize()
{
	 m_refGdkWindow.clear();

	 //Call base class:
	 Gtk::Widget::on_unrealize();
}

bool GtkOgreWidget::on_expose_event(GdkEventExpose* event)
{
//	std::cout << "GtkOgreWidget::onExpose" << std::endl;
	//Draw on the Gdk::Window:
    m_refGdkWindow->clear();
	getRenderWindow()->update();
//	std::cout << "Width:" << getRenderWindow()->getWidth() << ", Heiht:" << getRenderWindow()->getHeight() << std::endl;
	return true;
}

Ogre::RenderWindow* GtkOgreWidget::getRenderWindow(void) throw()
{
	assert(m_pWindow);
	return m_pWindow;
}
I think there is needed some code for destroying RenderWindow

thanks

Trigve
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

That "#else #endif" section with no lines in between should read:

Code: Select all

#else
#error Unsupported Platform
#endif
On the whole embedding Ogre issue, if I can't get this to work propely with stock wxWidgets, I will just use the GtkOgre widget with wxWidgets on Linux.
Trigve
Kobold
Posts: 25
Joined: Sun Dec 17, 2006 10:20 pm
Location: Slovakia

Post by Trigve »

Game_Ender wrote:That "#else #endif" section with no lines in between should read:

Code: Select all

#else
#error Unsupported Platform
#endif
There should by the same code as in the original GtkOgre....so something like this (haven't tried it!)

Code: Select all

GdkWindow* parent = m_refGdkWindow->gobj();
	GdkDisplay* display = gdk_drawable_get_display(GDK_DRAWABLE(parent));
	GdkScreen* screen = gdk_drawable_get_screen(GDK_DRAWABLE(parent));

Display* xdisplay = GDK_DISPLAY_XDISPLAY(display); 
	Screen* xscreen = GDK_SCREEN_XSCREEN(screen); 
	int screen_number = XScreenNumberOfScreen(xscreen); 
	XID xid_parent = GDK_WINDOW_XWINDOW(parent); 

	params["externalWindowHandle"] = 
		Ogre::StringConverter::toString(reinterpret_cast<unsigned long>(xdisplay)) + ":" + 
		Ogre::StringConverter::toString(static_cast<unsigned int>(screen_number)) + ":" + 
		Ogre::StringConverter::toString(static_cast<unsigned long>(xid_parent)); 
Trigve
Ocelot
Kobold
Posts: 33
Joined: Fri Dec 23, 2005 11:09 am
Location: Kraków, Poland

Post by Ocelot »

I was using it I've encounter the bugs like no expose events or mouse motion notify events (as written in this topic)...
I've resolved mouse event problems by using OIS :)
Trigve
Kobold
Posts: 25
Joined: Sun Dec 17, 2006 10:20 pm
Location: Slovakia

Post by Trigve »

Ocelot wrote:I've resolved mouse event problems by using OIS :)
Yes, using OIS is another solution...If everything else have failed then OIS would be the solution..but why should I use another library if input can be done with gtkmm? And also when I was using OIS I had problem that I can't get input only for particular window in win32 (for particular HWND) only for whole main window...so another computations were needed there

Trigve
Ocelot
Kobold
Posts: 33
Joined: Fri Dec 23, 2005 11:09 am
Location: Kraków, Poland

Post by Ocelot »

.so another computations were needed there
comparision only
eg.

Code: Select all

bool OISListeners::mouseMoved(const OIS::MouseEvent &evt){
    GtkAllocation rect = GTK_WIDGET(mApp->mOgre)->allocation;
    gint x(0),y(0);
    gtk_widget_get_pointer(GTK_WIDGET(mApp->mOgre), &x,&y);
    if ((x < 0)||(y<0)||(x>rect.width)||(y>rect.height)) return false;
Trigve
Kobold
Posts: 25
Joined: Sun Dec 17, 2006 10:20 pm
Location: Slovakia

Post by Trigve »

Ocelot wrote:

Code: Select all

bool OISListeners::mouseMoved(const OIS::MouseEvent &evt){
    GtkAllocation rect = GTK_WIDGET(mApp->mOgre)->allocation;
    gint x(0),y(0);
    gtk_widget_get_pointer(GTK_WIDGET(mApp->mOgre), &x,&y);
    if ((x < 0)||(y<0)||(x>rect.width)||(y>rect.height)) return false;
with gtkmm using only:

Code: Select all

bool MeshMapViewer::onNotify(GdkEventMotion* pMotion)
{
    // Do what you want
    return true;
}
And another problem is that I can't find OIS package in the FreeBSD ports (haven't tried to compile it from scratch).

Trigve
User avatar
pjcast
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2543
Joined: Fri Oct 24, 2003 2:53 am
Location: San Diego, Ca
x 2

Post by pjcast »

There is no current BSD port of OIS unfortunately. I setup a FreeBSD VM machine here to start working on one. However, I was unable to get autotools working the way I wanted. And since the BSD demand has been low, it has not been a priority :( Really, what I would love, is someone fluent with BSD (and its joystick API) to sumit a patch.
Have a question about Input? Video? WGE? Come on over... http://www.wreckedgames.com/forum/
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

Haven't really looked much at this lately, but I just wanted to let you know I've uploaded a new version, which should work with Eihort. You can grab it here: http://dword.dk/public/ogre/gtkogre-0.1.1-src.tar.bz2

The gtkmm stuff looks interesting. :) A lot cleaner than that "object-oriented" C in GTK+.
User avatar
marv
Gnoblar
Posts: 2
Joined: Sat Feb 24, 2007 11:46 am

Post by marv »

@Trigve: Is it possible to get a complete CB project of your gtkmm example(for windows). I´m trying to write a basic app with gtkmm and ogre (to stay object oriented), but need a working start point. Your example seems to be the perfect beginning. Thank you.
Carpe diem