Use a single GL context for all windows.

This commit is contained in:
leo 2013-01-12 18:06:37 +00:00
parent b2d80bf128
commit c9241b83f9
2 changed files with 107 additions and 98 deletions

View file

@ -1,7 +1,3 @@
//
// OpenGL window
//
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@ -14,12 +10,17 @@
struct GLWindowPrivate
{
GtkWidget *widget;
Display* xdisplay;
GLXContext context;
LC_CURSOR_TYPE Cursor;
bool Multisample;
// bool Multisample;
};
static Display* WindowDisplay = NULL;
static GdkVisual* WindowGdkVisual = NULL;
static XVisualInfo* WindowXVisualInfo = NULL;
static bool WindowMultisample = false;
static GLXContext WindowContext;
int WindowContextCount;
// =============================================================================
// static functions
@ -158,76 +159,76 @@ GLWindow::~GLWindow()
g_free(m_pData);
}
bool GLWindow::CreateFromWindow (void *data)
bool GLWindow::CreateFromWindow(void *data)
{
int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0 };
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
Display *dpy = GDK_DISPLAY();
GdkVisual *visual;
XVisualInfo *vi = NULL;
// choose visual
visual = gdk_visual_get_system();
if (visual->depth < 16)
printf("OpenGL fatal error: LeoCAD needs a display with at least 16 bit colors.\n");
if (dpy == NULL)
if (WindowContext)
WindowContextCount++;
else
{
printf("OpenGL fatal error: Cannot get display.\n");
return false;
}
prv->xdisplay = dpy;
int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0 };
int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1);
WindowDisplay = GDK_DISPLAY();
if (AASamples > 1)
{
int attrlistAA[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, AASamples, 0 };
vi = pfnglXChooseVisual(dpy, DefaultScreen(dpy), attrlistAA);
if (!WindowDisplay)
{
printf("OpenGL fatal error: Cannot get display.\n");
return false;
}
if (vi)
prv->Multisample = true;
else
printf("OpenGL error: Could not find multisample visual.\n");
}
WindowGdkVisual = gdk_visual_get_system();
if (WindowGdkVisual->depth < 16)
printf("OpenGL fatal error: LeoCAD needs a display with at least 16 bit colors.\n");
if (!vi)
{
vi = pfnglXChooseVisual(dpy, DefaultScreen(dpy), attrlist);
if (vi == NULL)
int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1);
if (AASamples > 1)
{
int attrlistAA[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_SAMPLE_BUFFERS_ARB, 1, GLX_SAMPLES_ARB, AASamples, 0 };
WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlistAA);
if (WindowXVisualInfo)
WindowMultisample = true;
else
printf("OpenGL error: Could not find multisample visual.\n");
}
if (!WindowXVisualInfo)
{
WindowXVisualInfo = pfnglXChooseVisual(WindowDisplay, DefaultScreen(WindowDisplay), attrlist);
if (!WindowXVisualInfo)
{
printf("OpenGL fatal error: glXChooseVisual failed.\n");
return false;
}
}
WindowGdkVisual = gdkx_visual_get(WindowXVisualInfo->visualid);
if (WindowGdkVisual == NULL)
{
printf("OpenGL fatal error: Cannot get visual.\n");
return false;
}
WindowContext = pfnglXCreateContext(WindowDisplay, WindowXVisualInfo, NULL, True);
if (!WindowContext)
{
printf("OpenGL fatal error: glXChooseVisual failed.\n");
printf("OpenGL fatal error: Cannot create context.\n");
return false;
}
}
}
visual = gdkx_visual_get(vi->visualid);
if (visual == NULL)
{
printf("OpenGL fatal error: Cannot get visual.\n");
return false;
}
gtk_widget_push_colormap(gdk_colormap_new(visual, TRUE));
gtk_widget_push_visual(visual);
gtk_widget_push_colormap(gdk_colormap_new(WindowGdkVisual, TRUE));
gtk_widget_push_visual(WindowGdkVisual);
prv->widget = gtk_drawing_area_new();
gtk_widget_set_double_buffered(GTK_WIDGET(prv->widget), FALSE);
if (m_pShare == NULL)
prv->context = pfnglXCreateContext(dpy, vi, NULL, True);
else
{
GLWindowPrivate *share = (GLWindowPrivate*)m_pShare->m_pData;
prv->context = pfnglXCreateContext(dpy, vi, share->context, True);
}
gtk_widget_pop_visual();
gtk_widget_pop_colormap();
XFree(vi);
GTK_WIDGET_SET_FLAGS(prv->widget, GTK_CAN_FOCUS);
gtk_widget_set_events(GTK_WIDGET(prv->widget), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
@ -249,46 +250,50 @@ bool GLWindow::CreateFromWindow (void *data)
void GLWindow::DestroyContext()
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
if (!WindowContext)
return;
if (prv->context == pfnglXGetCurrentContext())
pfnglXMakeCurrent(prv->xdisplay, None, NULL);
WindowContextCount--;
if (prv->context)
pfnglXDestroyContext(prv->xdisplay, prv->context);
if (WindowContextCount)
return;
prv->context = NULL;
if (WindowContext == pfnglXGetCurrentContext())
pfnglXMakeCurrent(WindowDisplay, None, NULL);
pfnglXDestroyContext(WindowDisplay, WindowContext);
WindowContext = NULL;
XFree(WindowXVisualInfo);
WindowXVisualInfo = NULL;
}
void GLWindow::OnInitialUpdate()
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
MakeCurrent();
GL_InitializeSharedExtensions();
// GL_InitializeExtensions();
if (prv->Multisample)
if (WindowMultisample)
glEnable(GL_MULTISAMPLE_ARB);
}
bool GLWindow::MakeCurrent()
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
gboolean ret = false;
if (prv->context)
ret = pfnglXMakeCurrent(prv->xdisplay, GDK_WINDOW_XWINDOW(prv->widget->window), prv->context);
if (!WindowContext)
return false;
return ret;
return pfnglXMakeCurrent(WindowDisplay, GDK_WINDOW_XWINDOW(prv->widget->window), WindowContext);
}
void GLWindow::SwapBuffers()
{
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
if (prv->context)
if (WindowContext)
pfnglXSwapBuffers(GDK_WINDOW_XDISPLAY(prv->widget->window), GDK_WINDOW_XWINDOW(prv->widget->window));
}

View file

@ -10,7 +10,7 @@
#include "opengl.h"
#include "gtktools.h"
#include "main.h"
#include "globals.h"
#include "globals.h"
#include "project.h"
#include "pieceinf.h"
#include "toolbar.h"
@ -199,46 +199,46 @@ void create_toolbars(GtkWidget *window, GtkWidget *vbox)
gtk_container_add (GTK_CONTAINER (tool_toolbar.handle_box), tool_toolbar.toolbar);
gtk_widget_show (tool_toolbar.toolbar);
tool_toolbar.brick = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.brick = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL, "Piece", "Insert Piece", "",
new_pixmap (window, ac_brick), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_INSERT);
tool_toolbar.light = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Light", "Insert Light", "",
tool_toolbar.light = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Light", "Insert Light", "",
new_pixmap (window, ac_light), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_LIGHT);
tool_toolbar.spot = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.spot = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Spot", "Insert Spotlight", "",
new_pixmap (window, ac_spot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SPOTLIGHT);
tool_toolbar.camera = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.camera = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Camera", "Insert Camera", "",
new_pixmap (window, ac_cam), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_CAMERA);
tool_toolbar.select = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.select = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Select", "Select Objects", "",
new_pixmap (window, ac_sel), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SELECT);
tool_toolbar.move = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.move = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Move", "Move Objects", "",
new_pixmap (window, ac_move), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_MOVE);
tool_toolbar.rotate = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.rotate = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rotate", "Rotate Pieces", "",
new_pixmap (window, ac_rot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE);
tool_toolbar.erase = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.erase = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Delete", "Remove Objects", "",
new_pixmap (window, ac_erase), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ERASER);
tool_toolbar.paint = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.paint = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Paint", "Paint Bricks", "",
new_pixmap (window, ac_paint), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAINT);
tool_toolbar.zoom = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.zoom = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom", "Zoom", "",
new_pixmap (window, ac_zoom), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM);
tool_toolbar.pan = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.pan = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Pan", "Pan", "",
new_pixmap (window, ac_pan), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAN);
tool_toolbar.rotview = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.rotview = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rot. View", "Rotate View", "",
new_pixmap (window, ac_rotv), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE_VIEW);
tool_toolbar.roll = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.roll = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Roll", "Roll", "",
new_pixmap (window, ac_roll), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROLL);
tool_toolbar.zoomreg = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
tool_toolbar.zoomreg = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom Box", "Zoom Region", "",
new_pixmap (window, ac_zoomr), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM_REGION);
gtk_toolbar_append_item (GTK_TOOLBAR (tool_toolbar.toolbar), "Zoom Ext.", "Zoom Extents", "",
@ -260,7 +260,7 @@ void create_toolbars(GtkWidget *window, GtkWidget *vbox)
gtk_widget_show (anim_toolbar.toolbar);
anim_toolbar.first = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
"First", "Go to the Start", "", new_pixmap (window, an_first),
"First", "Go to the Start", "", new_pixmap (window, an_first),
GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_FIRST);
anim_toolbar.prev = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
"Previous", "Go Back", "", new_pixmap (window, an_prev),
@ -367,7 +367,7 @@ void fill_piecetree()
gtk_tree_store_append(model, &pat, &entry);
gtk_tree_store_set(model, &pat, 0, desc, 1, child, -1);
}
}
}
}
}
@ -504,7 +504,7 @@ static gint piececombo_key(GtkWidget* widget, GdkEventKey* event)
// Remove all children.
while (gtk_tree_model_iter_children(model, &child, &iter))
gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
// Perform search.
PtrArray<PieceInfo> SinglePieces, GroupedPieces;
@ -720,7 +720,7 @@ static gboolean colorlist_expose(GtkWidget *widget, GdkEventExpose *event, gpoin
PangoContext *context;
PangoLayout *layout;
ColorListData* Data;
Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist");
Data->UpdateLayout(widget);
@ -779,7 +779,7 @@ static gboolean colorlist_expose(GtkWidget *widget, GdkEventExpose *event, gpoin
static gboolean colorlist_realize(GtkWidget* widget, gpointer user)
{
ColorListData* Data;
Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist");
delete Data;
@ -795,7 +795,7 @@ static gboolean colorlist_realize(GtkWidget* widget, gpointer user)
static gboolean colorlist_unrealize(GtkWidget* widget, gpointer user)
{
ColorListData* Data;
Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist");
delete Data;
@ -921,7 +921,7 @@ static gboolean colorlist_tooltip(GtkWidget *widget, gint x, gint y, gboolean ke
{
if (keyboard_mode)
return FALSE;
ColorListData* Data = (ColorListData*)gtk_object_get_data(GTK_OBJECT(widget), "colorlist");
for (int CellIdx = 0; CellIdx < Data->mCells.GetSize(); CellIdx++)
@ -954,8 +954,12 @@ void colorlist_set(int new_color)
if (new_color != cur_color)
{
cur_color = new_color;
gtk_widget_draw(colorlist, NULL);
preview->Redraw();
if (colorlist)
gtk_widget_draw(colorlist, NULL);
if (preview)
preview->Redraw();
}
}
@ -966,7 +970,7 @@ GtkWidget* create_piecebar(GtkWidget *window, GLWindow *share)
frame = gtk_frame_new(NULL);
gtk_widget_show(frame);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
vbox1 = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox1);