Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Create our own GL widget instead of using gtkglext which hasn't been …

…ported to Gtk3 yet
  • Loading branch information...
commit d97d7628d421adf8a8b03f92b92740f53fa8f054 1 parent 61f0296
@Kazade authored
View
20 platformation/editor_view.cpp
@@ -185,7 +185,7 @@ void EditorView::do_scroll(GdkEventScroll* event)
if(zoom_ <= 0.2f) zoom_ = 0.2f;
- MakeCurrent context(this);
+ if(!make_current()) return;
do_resize(get_widget()->get_width(), get_widget()->get_height());
}
@@ -203,10 +203,7 @@ void EditorView::do_button_press(GdkEventButton* event)
if(event->button == 1) {
//Select the tile instance under the cursor
- MakeCurrent context(this);
- if(!context.ok) {
- return;
- }
+
assert(picker_);
@@ -229,7 +226,8 @@ void EditorView::do_button_press(GdkEventButton* event)
//Spawn a new tile instance
//Get the spawn position (where we clicked
- MakeCurrent context(this);
+ if(!make_current()) return;
+
kmVec2 pos = unproject(event->x, event->y);
//Snap the position to the grid
grid_->snap_to(pos.x, pos.y);
@@ -243,10 +241,7 @@ void EditorView::do_button_press(GdkEventButton* event)
}
} else if (event->button == 3) {
//Delete the instance under the cursor
- MakeCurrent context(this);
- if(!context.ok) {
- return;
- }
+ if(!make_current()) return;
gfloat x = event->x;
gfloat y = event->y;
@@ -279,10 +274,7 @@ void EditorView::do_motion(GdkEventMotion* event)
*/
if(active_object_ && event->state & GDK_BUTTON1_MASK && active_timer_.elapsed() >= 0.2) {
- MakeCurrent context(this);
- if(!context.ok) {
- return;
- }
+ if(!make_current()) return;
kmVec2 pos = unproject(event->x, event->y);
grid_->snap_to(pos.x, pos.y);
View
128 platformation/gtkgl/gtk_gl_widget.cpp
@@ -0,0 +1,128 @@
+#include "gtk_gl_widget.h"
+
+const int attributes[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, True,
+ GLX_DEPTH_SIZE, 24,
+ None
+};
+
+static XVisualInfo *
+gdk_x11_visual_get_xvinfo (GdkScreen *screen,
+ GdkVisual *visual)
+{
+ Display *xdisplay;
+ XVisualInfo xvinfo_template;
+ XVisualInfo *xvinfo_list;
+ int nitems_return;
+
+ xdisplay = GDK_SCREEN_XDISPLAY (screen);
+ xvinfo_template.visualid = XVisualIDFromVisual (GDK_VISUAL_XVISUAL (visual));
+ xvinfo_template.screen = GDK_SCREEN_XNUMBER (screen);
+
+ xvinfo_list = XGetVisualInfo (xdisplay,
+ VisualIDMask | VisualScreenMask,
+ &xvinfo_template,
+ &nitems_return);
+
+ /* Returned XVisualInfo needs to be unique */
+ g_assert (xvinfo_list != NULL && nitems_return == 1);
+
+ return xvinfo_list;
+}
+
+GtkGLWidget::GtkGLWidget(Gtk::DrawingArea* area):
+ area_(area) {
+
+ area_->set_double_buffered(false);
+
+ Glib::RefPtr<Gdk::Display> display = Gdk::Display::get_default();
+ Glib::RefPtr<Gdk::Screen> screen = display->get_default_screen();
+ Glib::RefPtr<Gdk::Visual> visual = screen->get_rgba_visual();
+ Glib::RefPtr<Gdk::Colormap> colourmap = Gdk::Colormap::create(visual, false);
+
+ area->set_colormap(colourmap);
+
+ Display* xdisplay = GDK_DISPLAY_XDISPLAY(display->gobj());
+
+ context_ = glXCreateContext (xdisplay, gdk_x11_visual_get_xvinfo(screen->gobj(), visual->gobj()), NULL, TRUE);
+
+ area_->add_events(
+ Gdk::EXPOSURE_MASK |
+ Gdk::BUTTON_PRESS_MASK |
+ Gdk::BUTTON_RELEASE_MASK |
+ Gdk::POINTER_MOTION_MASK |
+ Gdk::POINTER_MOTION_HINT_MASK |
+ Gdk::KEY_PRESS_MASK |
+ Gdk::KEY_RELEASE_MASK
+ );
+
+ area_->signal_realize().connect(sigc::mem_fun(this, &GtkGLWidget::on_area_realize));
+ //area_->signal_draw().connect(sigc::mem_fun(this, &GtkGLWidget::on_area_draw));
+ area_->signal_expose_event().connect(sigc::mem_fun(this, &GtkGLWidget::on_area_expose));
+ area_->signal_configure_event().connect(sigc::mem_fun(this, &GtkGLWidget::on_area_configure));
+ idle_connection_ = Glib::signal_timeout().connect(sigc::mem_fun(this, &GtkGLWidget::on_area_idle), 10);
+}
+
+bool GtkGLWidget::make_current() {
+ Glib::RefPtr<Gdk::Window> window = area_->get_window();
+ Display* xdisplay = gdk_x11_drawable_get_xdisplay(window->gobj());
+ int id = gdk_x11_drawable_get_xid(window->gobj());
+ return glXMakeCurrent(xdisplay, id, context_) == TRUE;
+}
+
+bool GtkGLWidget::on_area_idle() {
+ area_->queue_draw();
+ return true;
+}
+
+void GtkGLWidget::on_area_realize() {
+ if(make_current()) {
+ glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
+ glEnable (GL_DEPTH_TEST);
+ glDepthFunc (GL_LEQUAL);
+ glEnable (GL_CULL_FACE);
+ glCullFace (GL_BACK);
+ glDisable (GL_DITHER);
+ glShadeModel (GL_SMOOTH);
+
+ do_init();
+ }
+}
+
+/*
+bool GtkGLWidget::on_area_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr) {
+
+
+ return true;
+}
+
+*/
+bool GtkGLWidget::on_area_expose(GdkEventExpose *event) {
+ if(event->count > 0) return true;
+
+ if(make_current()) {
+ Glib::RefPtr<Gdk::Window> window = area_->get_window();
+ Display* xdisplay = gdk_x11_drawable_get_xdisplay(window->gobj());
+ int id = gdk_x11_drawable_get_xid(window->gobj());
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ do_render();
+
+ glXSwapBuffers(xdisplay, id);
+ }
+
+ return true;
+}
+
+bool GtkGLWidget::on_area_configure(GdkEventConfigure* event) {
+ Gtk::Allocation allocation = area_->get_allocation();
+ if(make_current()) {
+ glViewport (0, 0, allocation.get_width(), allocation.get_height());
+ do_resize(allocation.get_width(), allocation.get_height());
+ }
+ return true;
+}
View
43 platformation/gtkgl/gtk_gl_widget.h
@@ -0,0 +1,43 @@
+#ifndef GTK_GL_WIDGET_H
+#define GTK_GL_WIDGET_H
+
+#include <gtkmm.h>
+#include <tr1/memory>
+
+#include <GL/glx.h>
+#include <gdk/gdkx.h>
+
+class GtkGLWidget {
+public:
+ typedef std::tr1::shared_ptr<GtkGLWidget> ptr;
+
+ GtkGLWidget(Gtk::DrawingArea* area);
+ virtual ~GtkGLWidget() {
+ if(idle_connection_.connected()) {
+ idle_connection_.disconnect();
+ }
+ }
+
+ Gtk::DrawingArea* area() { return area_; }
+ Gtk::DrawingArea* get_widget() { return area(); }
+
+ void on_area_realize();
+ //bool on_area_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr);
+
+ bool on_area_expose(GdkEventExpose *event);
+ bool on_area_configure(GdkEventConfigure* event);
+ bool on_area_idle();
+
+protected:
+ bool make_current();
+
+ virtual void do_render() {}
+ virtual void do_init() {}
+ virtual void do_resize(int width, int height) {}
+private:
+ Gtk::DrawingArea* area_;
+ GLXContext context_;
+ sigc::connection idle_connection_;
+};
+
+#endif
View
20 platformation/main_window.cpp
@@ -48,6 +48,8 @@ MainWindow::MainWindow():
void MainWindow::create_widgets() {
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create();
+
+ Gtk::DrawingArea* canvas = nullptr;
//Just let exceptions propagate - we can't do anything about them anyway
builder->add_from_file(UI_FILE);
@@ -59,18 +61,23 @@ void MainWindow::create_widgets() {
builder->get_widget("redo_toolbutton", gtk_redo_toolbutton_);
builder->get_widget("add_tile_button", gtk_add_tile_button_);
- builder->get_widget("canvas", gtk_canvas_);
+ builder->get_widget("canvas", canvas);
builder->get_widget("layer_tree_view", gtk_layer_view_);
builder->get_widget("add_layer_button", gtk_add_layer_button_);
builder->get_widget("delete_layer_button", gtk_delete_layer_button_);
builder->get_widget("side_bar_alignment", gtk_side_bar_);
- assert(gtk_canvas_);
- editor_view_.reset(new EditorView(gtk_canvas_, this));
+ gtk_canvas_.reset(new GtkGLWidget(canvas));
+
+ //assert(gtk_canvas_);
+ editor_view_.reset(new EditorView(gtk_canvas_->area(), this));
assert(gtk_tile_selector_canvas_);
selector_.reset(new OpenGLTileSelector(gtk_tile_selector_canvas_));
- editor_view_->set_tile_selector(selector_.get());
+
+ if(editor_view_) {
+ editor_view_->set_tile_selector(selector_.get());
+ }
layer_manager_.reset(new LayerManager(this, gtk_layer_view_, gtk_add_layer_button_, gtk_delete_layer_button_));
@@ -136,7 +143,10 @@ void MainWindow::create_new_level(const std::string& name, uint32_t tile_size) {
level_changed_connection_ = level_->signal_changed().connect(sigc::mem_fun(this, &MainWindow::on_level_changed));
level_saved_connection_ = level_->signal_saved().connect(sigc::mem_fun(this, &MainWindow::on_level_saved));
- editor_view_->set_level(level_.get());
+ if(editor_view_) {
+ editor_view_->set_level(level_.get());
+ }
+
layer_manager_->set_level(level_.get());
}
View
4 platformation/main_window.h
@@ -33,6 +33,7 @@
#include "editor_view.h"
#include "layer_manager.h"
#include "action_manager.h"
+#include "gtkgl/gtk_gl_widget.h"
class MainWindow {
public:
@@ -73,7 +74,8 @@ class MainWindow {
Gtk::Button* gtk_add_layer_button_;
Gtk::Button* gtk_delete_layer_button_;
- Gtk::DrawingArea* gtk_canvas_, *gtk_tile_selector_canvas_;
+ GtkGLWidget::ptr gtk_canvas_;
+ Gtk::DrawingArea* gtk_tile_selector_canvas_;
Gtk::TreeView* gtk_layer_view_;
void initialize_tile_canvas();
View
2  platformation/opengl_tile_editor.cpp
@@ -256,7 +256,7 @@ void OpenGLTileEditorCanvas::do_button_press(GdkEventButton* event)
} else if (event->button == 3) {
//TODO: Only the current layer iterators should be passed to pick() otherwise we'll get
//false positives
- MakeCurrent context(this);
+ make_current();
Tile::GeometryIteratorPair iters = parent_->get_tile()->get_geometry_iterators();
GeometryElement::ptr elem = picker_->pick(event->x, event->y, iters.first, iters.second);
View
13 platformation/opengl_tile_selector.cpp
@@ -76,7 +76,7 @@ void OpenGLTileSelector::do_render()
glDepthFunc(GL_LEQUAL);
float ytrans = 0.0f;
- if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(get_widget()->get_parent())) {
+ if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(area()->get_parent())) {
ytrans = scr->get_vadjustment()->get_value();
}
@@ -164,7 +164,7 @@ GLuint OpenGLTileSelector::get_texture_for_tile(Tile* tile)
*/
void OpenGLTileSelector::do_scroll(GdkEventScroll* event)
{
- if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(get_widget()->get_parent())) {
+ if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(area()->get_parent())) {
gdouble val = scr->get_vadjustment()->get_value();
if(event->direction == GDK_SCROLL_UP) {
@@ -190,10 +190,7 @@ void OpenGLTileSelector::do_button_press(GdkEventButton* event)
}
if(event->type == GDK_BUTTON_PRESS && event->button == 1 && tileset_) {
- MakeCurrent context(this);
- if(!context.ok) {
- return;
- }
+ if(!make_current()) return;
assert(picker_);
@@ -237,7 +234,7 @@ void OpenGLTileSelector::init_tileset()
total_display_height_ = -y;
- if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(get_widget()->get_parent())) {
+ if(Gtk::ScrolledWindow* scr = dynamic_cast<Gtk::ScrolledWindow*>(area()->get_parent())) {
scr->get_vadjustment()->set_upper(total_display_height_ + 1.0f);
scr->get_vadjustment()->set_value(0);
}
@@ -257,7 +254,7 @@ void OpenGLTileSelector::on_tile_edit()
tile_editor_.reset(new OpenGLTileEditor(tile.get()));
- if(tile_editor_->run(dynamic_cast<Gtk::Window*>(get_widget()->get_toplevel())) == Gtk::RESPONSE_OK) {
+ if(tile_editor_->run(dynamic_cast<Gtk::Window*>(area()->get_toplevel())) == Gtk::RESPONSE_OK) {
tile->save();
}
}
View
104 platformation/opengl_widget.cpp
@@ -26,31 +26,11 @@
*
* @todo: document this function
*/
-void OpenGLWidget::initialize_context()
-{
- assert(widget_);
-
- Glib::RefPtr<Gdk::GL::Config> gl_config;
- gl_config = Gdk::GL::Config::create(Gdk::GL::MODE_RGBA | Gdk::GL::MODE_ALPHA | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE);
-
- assert(gl_config);
-
- //Set the widget to be gl enabled
- Gtk::GL::widget_set_gl_capability(*widget_, gl_config);
- widget_->add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON3_MOTION_MASK |
- Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK |
- Gdk::KEY_PRESS_MASK | Gdk::VISIBILITY_NOTIFY_MASK);
-
-
- widget_->signal_realize().connect(sigc::mem_fun(this, &OpenGLWidget::on_realize));
- widget_->signal_configure_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_configure));
- widget_->signal_expose_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_expose));
- widget_->signal_motion_notify_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_motion_notify));
- widget_->signal_button_press_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_button_press));
- widget_->signal_button_release_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_button_release));
- widget_->signal_scroll_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_scroll));
-
- idle_connection_ = Glib::signal_idle().connect(sigc::mem_fun(this, &OpenGLWidget::on_idle));
+void OpenGLWidget::initialize() {
+ area()->signal_motion_notify_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_motion_notify));
+ area()->signal_button_press_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_button_press));
+ area()->signal_button_release_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_button_release));
+ area()->signal_scroll_event().connect(sigc::mem_fun(this, &OpenGLWidget::on_scroll));
}
/** @brief OpenGLWidget
@@ -58,9 +38,8 @@ void OpenGLWidget::initialize_context()
* @todo: document this function
*/
OpenGLWidget::OpenGLWidget(Gtk::DrawingArea* widget):
-widget_(widget)
-{
- initialize_context();
+GtkGLWidget(widget) {
+ initialize();
}
/** @brief on_scroll
@@ -97,82 +76,19 @@ bool OpenGLWidget::on_button_press(GdkEventButton* event)
*
* @todo: document this function
*/
-bool OpenGLWidget::on_motion_notify(GdkEventMotion* event)
-{
+bool OpenGLWidget::on_motion_notify(GdkEventMotion* event) {
do_motion(event);
return true;
}
-/** @brief on_expose
- *
- * @todo: document this function
- */
-bool OpenGLWidget::on_expose(GdkEventExpose *event)
-{
- MakeCurrent context(this);
-
- if(!context.ok) {
- return true;
- }
-
- do_render();
-
- context.drawable_->swap_buffers();
-
- return true;
-}
-
-/** @brief on_realize
- *
- * @todo: document this function
- */
-void OpenGLWidget::on_realize()
-{
- MakeCurrent context(this);
-
- if(!context.ok) {
- return;
- }
-
- do_init();
-}
-
-/** @brief on_configure
- *
- * @todo: document this function
- */
-bool OpenGLWidget::on_configure(GdkEventConfigure* event)
-{
- MakeCurrent context(this);
-
- if(!context.ok) {
- return true;
- }
-
- do_resize(event->width, event->height);
-
- return true;
-}
-
-/** @brief on_idle
- *
- * @todo: document this function
- */
-bool OpenGLWidget::on_idle()
-{
- widget_->queue_draw();
- return true;
-}
-
/** @brief unproject
*
* @todo: document this function
*/
-kmVec2 OpenGLWidget::unproject(gdouble winx, gdouble winy)
-{
+kmVec2 OpenGLWidget::unproject(gdouble winx, gdouble winy) {
GLdouble winz = 0.0;
- MakeCurrent context(this);
+ make_current();
GLint viewport[4];
GLdouble modelview[16];
View
48 platformation/opengl_widget.h
@@ -19,68 +19,26 @@
#ifndef OPENGL_WIDGET_H_INCLUDED
#define OPENGL_WIDGET_H_INCLUDED
-#include <gtkmm.h>
-#include <gdkmm.h>
-#include <gtkglmm.h>
-#include <GL/gl.h>
-
+#include "gtkgl/gtk_gl_widget.h"
#include <kazmath/vec2.h>
-class OpenGLWidget {
+class OpenGLWidget : public GtkGLWidget {
public:
OpenGLWidget(Gtk::DrawingArea* widget);
- virtual ~OpenGLWidget() {
- if(idle_connection_.connected()) {
- idle_connection_.disconnect();
- }
- }
-
- void initialize_context();
+ void initialize();
- bool on_configure(GdkEventConfigure* event);
- void on_realize();
- bool on_expose(GdkEventExpose *event);
bool on_motion_notify(GdkEventMotion* event);
bool on_button_press(GdkEventButton* event);
bool on_button_release(GdkEventButton* event);
bool on_scroll(GdkEventScroll* event);
- bool on_idle();
-
- Gtk::DrawingArea* get_widget() { return widget_; }
private:
- Gtk::DrawingArea* widget_;
-
- virtual void do_render() {}
- virtual void do_init() {}
- virtual void do_resize(int width, int height) {}
virtual void do_button_press(GdkEventButton* event) {}
virtual void do_motion(GdkEventMotion* event) {}
virtual void do_button_release(GdkEventButton* event) {}
virtual void do_scroll(GdkEventScroll* event) {}
- sigc::connection idle_connection_;
-
protected:
- struct MakeCurrent {
- Glib::RefPtr<Gdk::GL::Context> context_;
- Glib::RefPtr<Gdk::GL::Drawable> drawable_;
- bool ok;
-
- MakeCurrent(OpenGLWidget* canvas):
- ok(true) {
- context_ = Gtk::GL::widget_get_gl_context(*canvas->get_widget());
- drawable_ = Gtk::GL::widget_get_gl_drawable(*canvas->get_widget());
- if(!drawable_->gl_begin(context_)) {
- ok = false;
- }
- }
-
- ~MakeCurrent() {
- drawable_->gl_end();
- }
- };
-
kmVec2 unproject(gdouble x, gdouble y);
};
Please sign in to comment.
Something went wrong with that request. Please try again.