OpenGl works now under GTK

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1360 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
1999-01-10 10:49:57 +00:00
parent 71432ef81f
commit aae24d21a3
24 changed files with 1534 additions and 225 deletions

View File

@@ -20,17 +20,19 @@
#include "wx/module.h"
#include "wx/app.h"
extern "C" {
#include "gtk/gtk.h"
#include "gdk/gdk.h"
extern "C" {
#include "gdk/gdkx.h"
}
#include "wx/gtk/win_gtk.h"
//---------------------------------------------------------------------------
// global variables
// global data
//---------------------------------------------------------------------------
XVisualInfo *g_visual_info = (XVisualInfo*) NULL;
XVisualInfo *g_vi = (XVisualInfo*) NULL;
//---------------------------------------------------------------------------
// wxGLContext
@@ -41,25 +43,25 @@ IMPLEMENT_CLASS(wxGLContext,wxObject)
wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) )
{
m_window = win;
m_widget = win->m_wxwindow;
m_widget = ((wxGLCanvas*)win)->m_glWidget;
wxCHECK_RET( g_visual_info != NULL, "invalid visual for OpenGl" );
wxCHECK_RET( g_vi, "invalid visual for OpenGl" );
m_glContext = glXCreateContext( GDK_DISPLAY(), g_visual_info, None, GL_TRUE );
m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, None, GL_TRUE );
wxCHECK_RET( m_glContext != NULL, "Couldn't create OpenGl context" );
glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" );
}
wxGLContext::~wxGLContext()
{
if (m_glContext)
{
glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
if (!m_glContext) return;
glXDestroyContext( GDK_DISPLAY(), m_glContext );
if (m_glContext == glXGetCurrentContext())
{
glXMakeCurrent( GDK_DISPLAY(), None, NULL);
}
glXDestroyContext( GDK_DISPLAY(), m_glContext );
}
void wxGLContext::SwapBuffers()
@@ -116,12 +118,71 @@ BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
EVT_SIZE(wxGLCanvas::OnSize)
END_EVENT_TABLE()
wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style, const wxString& name,
int *WXUNUSED(attribList), const wxPalette& palette):
wxScrolledWindow(parent, id, pos, size, style, name)
wxGLCanvas::wxGLCanvas( wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size,
long style, const wxString& name,
int *attribList,
const wxPalette& palette )
{
Create( parent, id, pos, size, style, name, attribList, palette );
}
bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size,
long style, const wxString& name,
int *attribList,
const wxPalette& palette )
{
if (!attribList)
{
int data[] = { GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
None };
attribList = (int*) data;
}
Display *dpy = GDK_DISPLAY();
g_vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList );
GdkVisual *visual = gdkx_visual_get( g_vi->visualid );
GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(g_vi->visualid), TRUE );
gtk_widget_push_colormap( colormap );
gtk_widget_push_visual( visual );
m_glWidget = gtk_drawing_area_new();
gtk_widget_set_events( m_glWidget,
GDK_EXPOSURE_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_MOTION_MASK |
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON2_MOTION_MASK |
GDK_BUTTON3_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK );
gtk_widget_pop_visual();
gtk_widget_pop_colormap();
wxScrolledWindow::Create( parent, id, pos, size, style, name );
gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), m_glWidget, 0, 0 );
gtk_widget_show( m_glWidget );
m_glContext = new wxGLContext( TRUE, this, palette );
XFree( g_vi );
g_vi = (XVisualInfo*) NULL;
return TRUE;
}
wxGLCanvas::~wxGLCanvas()
@@ -137,13 +198,12 @@ void wxGLCanvas::SwapBuffers()
void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
{
int width, height;
GetClientSize(& width, & height);
if (m_glContext)
GetClientSize( &width, &height );
if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) )
{
m_glContext->SetCurrent();
glViewport(0, 0, (GLint)width, (GLint)height);
SetCurrent();
glViewport(0, 0, (GLint)width, (GLint)height );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
@@ -161,39 +221,92 @@ void wxGLCanvas::SetColour( const char *colour )
if (m_glContext) m_glContext->SetColour( colour );
}
//--------------------------------------------------------------------
// wxGLModule
//--------------------------------------------------------------------
class wxGLModule : public wxModule
void wxGLCanvas::SetSize( int x, int y, int width, int height, int sizeFlags )
{
public:
virtual bool OnInit();
virtual void OnExit();
if (m_resizing) return; // I don't like recursions
m_resizing = TRUE;
private:
DECLARE_DYNAMIC_CLASS(wxGLModule)
};
if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
{
// don't set the size for children of wxNotebook, just take the values.
m_x = x;
m_y = y;
m_width = width;
m_height = height;
}
else
{
int old_width = m_width;
int old_height = m_height;
IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
{
if (x != -1) m_x = x;
if (y != -1) m_y = y;
if (width != -1) m_width = width;
if (height != -1) m_height = height;
}
else
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
}
bool wxGLModule::OnInit()
{
int data[] = { GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1,
GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,None};
if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
{
if (width == -1) m_width = 80;
}
g_visual_info = glXChooseVisual( GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), data );
wxCHECK_MSG( g_visual_info != NULL, FALSE, "Couldn't choose visual for OpenGl" );
wxVisualSetByExternal = gdkx_visual_get(g_visual_info->visualid);
wxColormapSetByExternal = gdk_colormap_new( gdkx_visual_get(g_visual_info->visualid), TRUE );
return TRUE;
if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
{
if (height == -1) m_height = 26;
}
if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
wxPoint pt( m_parent->GetClientAreaOrigin() );
gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y );
if ((old_width != m_width) || (old_height != m_height))
{
gtk_widget_set_usize( m_widget, m_width, m_height );
gtk_drawing_area_size( GTK_DRAWING_AREA(m_glWidget), m_width, m_height );
GtkAllocation allo;
allo.x = 0;
allo.y = 0;
allo.width = m_width;
allo.height = m_height;
gtk_widget_size_allocate( m_glWidget, &allo );
}
}
m_sizeSet = TRUE;
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
event.SetEventObject( this );
GetEventHandler()->ProcessEvent( event );
m_resizing = FALSE;
}
void wxGLModule::OnExit()
void wxGLCanvas::SetSize( int width, int height )
{
SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
}
GtkWidget *wxGLCanvas::GetConnectWidget()
{
return m_glWidget;
}
bool wxGLCanvas::IsOwnGtkWindow( GdkWindow *window )
{
return (window == m_glWidget->window);
}