Strange problem: Gtkmm + Ogre3D eating widget and menu text



Hi everyone, I am fairly new to Gtk(mm) and I am trying to embed Ogre3D
(www.ogre3d.org) into Gtkmm, using Ogre 1.6 and Gtkmm 2.16. Now putting
it in and getting it to run was no problem at all but as soon as I start
adding other Widgets or Menus to my Gtk Window all the text of other
widgets is disappearing.

I have looked around on various gtkmm sites, gone through the gtkmm
docs, checked various Ogre projects and posts here on the boards and I
can't seem to figure out the reason or fix for it. I am basically using
the Widget setup found here on the boards discussed in several threads,
which seems to work fine for others. So what is the catch or what am I
missing?

I would immensely appreciate a pointer or tip for a fix since I am stuck
with the problem since almost a full week now, trying, testing, reading,
digging, debugging. I have also tried it on different systems, with
different Ogre & Gtkmm versions, no luck.

I am working with VC++ Express 2005 on WindowsXP. Here is the code, a
fairly simple Ogre Gtk Window and the Widget and a button:

main.cpp:
#include <gtkmm/main.h>
#include "ogrewindow.h"

int main (int argc, char *argv[])
{
   Ogre::Root* root = new Ogre::Root();

   if (!root->showConfigDialog())
       return -1;

   root->initialise(false);

   Gtk::Main kit(argc, argv);

   OgreWindow oWindow;
   oWindow.show();

   while (!oWindow.hasExited())
   {
       kit.iteration();
   }

   delete root;
   return 0;
}

ogrewindow.h:
#ifndef OGREWINDOW_H
#define OGREWINDOW_H

#include <gtkmm.h>
#include <gtkmm/button.h>
#include <gtkmm/window.h>

#include "ogrewidget.h"

class OgreWindow : public Gtk::Window
{

public:
 OgreWindow();
 virtual ~OgreWindow();
 virtual bool on_delete_event(GdkEventAny* event);
 bool hasExited() { return mExited; }

 virtual bool on_key_press_event(GdkEventKey *event);
 virtual bool on_key_release_event(GdkEventKey *event);

protected:
 OgreWidget mOgreWidget;
 bool mExited;
};

#endif

ogrewindow.cpp
#include "ogrewindow.h"
#include <iostream>

OgreWindow::OgreWindow() :
   mOgreWidget(),
   mExited(false)
{
 set_border_width(10);

 Gtk::VBox *vb = new Gtk::VBox(false,10);

 Gtk::Button *mb = new Gtk::Button("Some Button");

 vb->pack_start(*mb,true,true,10);
 vb->pack_start(mOgreWidget,true,true,10);

 add(*vb);
 show_all();
}

OgreWindow::~OgreWindow()
{
}

bool OgreWindow::on_delete_event(GdkEventAny* event)
{
   mExited = true;
   return false;
}

bool OgreWindow::on_key_press_event(GdkEventKey *event) {
   std::cout << "keydown\n";
   return true;
}

bool OgreWindow::on_key_release_event(GdkEventKey *event) {
   std::cout << "keyup\n";
   return true;
}


ogrewidget.h
#ifndef OGREWIDGET_H
#define OGREWIDGET_H

#include <gtkmm.h>
#include <glibmm/timer.h>

#include <Ogre.h>

class OgreWidget : public Gtk::Widget
{
public:
 OgreWidget();
 virtual ~OgreWidget();

protected:
 void createScene();

 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);
 virtual bool on_idle();

 virtual bool on_motion_notify_event(GdkEventMotion *event);
 virtual bool on_button_press_event(GdkEventButton *event);
 virtual bool on_button_release_event(GdkEventButton *event);

 Glib::RefPtr<Gdk::Window> mRefGdkWindow;

 Ogre::RenderWindow* mRenderWindow;
 Ogre::SceneManager* mSceneMgr;
 Ogre::Viewport* mViewport;
 Ogre::Camera* mCamera;

};
#endif

ogrewidget.cpp
#include "ogrewidget.h"

#include <gdkmm/drawable.h>
#include <gdkmm/general.h>
#include <iostream>
#include <cstring>

#ifdef WIN32
   #include <gdk/gdkwin32.h>
#endif

OgreWidget::OgreWidget() :
 Glib::ObjectBase("ogrewidget"),
 Gtk::Widget(),
 mRenderWindow(0), mCamera(0), mSceneMgr(0), mViewport(0)
{
 set_flags(Gtk::NO_WINDOW);
 std::cout << "GType name: " << G_OBJECT_TYPE_NAME(gobj()) << std::endl;
}

OgreWidget::~OgreWidget()
{
}

void OgreWidget::on_size_request(Gtk::Requisition* requisition)
{
 *requisition = Gtk::Requisition();

 requisition->width = 800;
 requisition->height = 600;
}

void OgreWidget::on_size_allocate(Gtk::Allocation& allocation)
{
 set_allocation(allocation);

 if(mRefGdkWindow)
 {
   mRefGdkWindow->move_resize( allocation.get_x(), allocation.get_y(),
           allocation.get_width(), allocation.get_height() );
 }

 if (mRenderWindow)
 {
     mRenderWindow->windowMovedOrResized();
     mCamera->setAspectRatio(Ogre::Real(allocation.get_width()) /
Ogre::Real(allocation.get_height()));
     on_expose_event(NULL);
 }
}

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

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

void OgreWidget::on_realize()
{
  //Call base class:
  Gtk::Widget::on_realize();

  Gtk::Allocation allocation = get_allocation();

  if(!mRefGdkWindow)
  {
     //Create the GdkWindow:
     GdkWindowAttr attributes;
     memset(&attributes, 0, sizeof(attributes));

     //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;

     mRefGdkWindow = Gdk::Window::create(get_window(), &attributes,
GDK_WA_X | GDK_WA_Y);

  }

  if (!mRenderWindow)
  {
     Ogre::NameValuePairList params;
#ifdef WIN32
   params["externalWindowHandle"] =
Ogre::StringConverter::toString((unsigned
long)GDK_WINDOW_HWND(mRefGdkWindow->gobj()));
#else
GdkWindow* parent = mRefGdkWindow->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));
#endif
     mRenderWindow =
Ogre::Root::getSingleton().createRenderWindow("Gtk+Ogre Widget",
        allocation.get_width(), allocation.get_height(), false, &params);

    mRenderWindow->setAutoUpdated(false);

    unset_flags(Gtk::NO_WINDOW);

    set_window(mRefGdkWindow);


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

     createScene();

     // Start idle function for frame update/rendering
     Glib::signal_idle().connect( sigc::mem_fun(*this,
&OgreWidget::on_idle) );

  }
}

void OgreWidget::on_unrealize()
{
 mRefGdkWindow.clear();
 //Call base class:
 Gtk::Widget::on_unrealize();
}

bool OgreWidget::on_expose_event(GdkEventExpose* event)
{

 if (mRenderWindow)
 {
     Ogre::Root::getSingletonPtr()->_fireFrameStarted();
     mRenderWindow->update();
     Ogre::Root::getSingletonPtr()->_fireFrameEnded();

 }
 return true;
}

bool OgreWidget::on_idle()
{
   on_expose_event(0);
   return true;
}

void OgreWidget::createScene()
{
   // Set default mipmap level & texture filtering
   Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);

Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_TRILINEAR);

   // Create scene manager
   mSceneMgr =
Ogre::Root::getSingletonPtr()->createSceneManager(Ogre::ST_GENERIC,
"SceneManager");

   // Create the camera
   mCamera = mSceneMgr->createCamera("Camera");

   // Create one viewport, entire window
   mViewport = mRenderWindow->addViewport(mCamera);

   // Alter the camera aspect ratio to match the viewport
   mCamera->setAspectRatio(Ogre::Real(mViewport->getActualWidth()) /
Ogre::Real(mViewport->getActualHeight()));
}

bool OgreWidget::on_motion_notify_event(GdkEventMotion *event) {
   std::cout << ".";
   return true;
}

bool OgreWidget::on_button_press_event(GdkEventButton *event) {
   std::cout << "button press\n";
   return true;
}

bool OgreWidget::on_button_release_event(GdkEventButton *event) {
   std::cout << "button release\n";
   return true;
}

As a further description of the problem, when I try a more complex setup
loading a Glade layout with many widgets, menu, etc and then add the
ogrewidget to a notebook, as soon as i click/focus whatever widget,
label, menu with text it disappears.

Thanks in advance for anyone possibly helping :).

/Nauk



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]