1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWindows and GTK
4 // Author: Robert Roebling
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "glcanvas.h"
19 #include "wx/colour.h"
20 #include "wx/module.h"
29 #include "wx/gtk/win_gtk.h"
31 //---------------------------------------------------------------------------
33 //---------------------------------------------------------------------------
35 XVisualInfo
*g_vi
= (XVisualInfo
*) NULL
;
37 //---------------------------------------------------------------------------
39 //---------------------------------------------------------------------------
41 IMPLEMENT_CLASS(wxGLContext
,wxObject
)
43 wxGLContext::wxGLContext( bool WXUNUSED(isRGB
), wxWindow
*win
, const wxPalette
& WXUNUSED(palette
) )
46 m_widget
= ((wxGLCanvas
*)win
)->m_glWidget
;
48 wxCHECK_RET( g_vi
, "invalid visual for OpenGl" );
50 m_glContext
= glXCreateContext( GDK_DISPLAY(), g_vi
, None
, GL_TRUE
);
52 wxCHECK_RET( m_glContext
, "Couldn't create OpenGl context" );
55 wxGLContext::~wxGLContext()
57 if (!m_glContext
) return;
59 if (m_glContext
== glXGetCurrentContext())
61 glXMakeCurrent( GDK_DISPLAY(), None
, NULL
);
64 glXDestroyContext( GDK_DISPLAY(), m_glContext
);
67 void wxGLContext::SwapBuffers()
71 glXSwapBuffers( GDK_DISPLAY(), GDK_WINDOW_XWINDOW( m_widget
->window
) );
75 void wxGLContext::SetCurrent()
79 glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget
->window
), m_glContext
);
83 void wxGLContext::SetColour(const char *colour
)
88 wxColour
*col
= wxTheColourDatabase
->FindColour(colour
);
91 r
= (float)(col
->Red()/256.0);
92 g
= (float)(col
->Green()/256.0);
93 b
= (float)(col
->Blue()/256.0);
98 void wxGLContext::SetupPixelFormat()
102 void wxGLContext::SetupPalette( const wxPalette
& WXUNUSED(palette
) )
106 wxPalette
wxGLContext::CreateDefaultPalette()
108 return wxNullPalette
;
111 //---------------------------------------------------------------------------
113 //---------------------------------------------------------------------------
115 IMPLEMENT_CLASS(wxGLCanvas
, wxScrolledWindow
)
117 BEGIN_EVENT_TABLE(wxGLCanvas
, wxScrolledWindow
)
118 EVT_SIZE(wxGLCanvas::OnSize
)
121 wxGLCanvas::wxGLCanvas( wxWindow
*parent
, wxWindowID id
,
122 const wxPoint
& pos
, const wxSize
& size
,
123 long style
, const wxString
& name
,
125 const wxPalette
& palette
)
127 Create( parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
130 bool wxGLCanvas::Create( wxWindow
*parent
, wxWindowID id
,
131 const wxPoint
& pos
, const wxSize
& size
,
132 long style
, const wxString
& name
,
134 const wxPalette
& palette
)
138 int data
[] = { GLX_RGBA
,
142 attribList
= (int*) data
;
145 Display
*dpy
= GDK_DISPLAY();
147 g_vi
= glXChooseVisual( dpy
, DefaultScreen(dpy
), attribList
);
149 GdkVisual
*visual
= gdkx_visual_get( g_vi
->visualid
);
150 GdkColormap
*colormap
= gdk_colormap_new( gdkx_visual_get(g_vi
->visualid
), TRUE
);
152 gtk_widget_push_colormap( colormap
);
153 gtk_widget_push_visual( visual
);
155 m_glWidget
= gtk_drawing_area_new();
156 gtk_widget_set_events( m_glWidget
,
158 GDK_POINTER_MOTION_HINT_MASK
|
159 GDK_POINTER_MOTION_MASK
|
160 GDK_BUTTON_MOTION_MASK
|
161 GDK_BUTTON1_MOTION_MASK
|
162 GDK_BUTTON2_MOTION_MASK
|
163 GDK_BUTTON3_MOTION_MASK
|
164 GDK_BUTTON_PRESS_MASK
|
165 GDK_BUTTON_RELEASE_MASK
|
167 GDK_KEY_RELEASE_MASK
|
168 GDK_ENTER_NOTIFY_MASK
|
169 GDK_LEAVE_NOTIFY_MASK
);
171 gtk_widget_pop_visual();
172 gtk_widget_pop_colormap();
174 wxScrolledWindow::Create( parent
, id
, pos
, size
, style
, name
);
176 gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), m_glWidget
, 0, 0 );
178 gtk_widget_show( m_glWidget
);
180 m_glContext
= new wxGLContext( TRUE
, this, palette
);
183 g_vi
= (XVisualInfo
*) NULL
;
188 wxGLCanvas::~wxGLCanvas()
190 if (m_glContext
) delete m_glContext
;
193 void wxGLCanvas::SwapBuffers()
195 if (m_glContext
) m_glContext
->SwapBuffers();
198 void wxGLCanvas::OnSize(wxSizeEvent
& WXUNUSED(event
))
201 GetClientSize( &width
, &height
);
202 if (m_glContext
&& GTK_WIDGET_REALIZED(m_glWidget
) )
206 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
207 glMatrixMode(GL_PROJECTION
);
209 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
210 glMatrixMode(GL_MODELVIEW
);
214 void wxGLCanvas::SetCurrent()
216 if (m_glContext
) m_glContext
->SetCurrent();
219 void wxGLCanvas::SetColour( const char *colour
)
221 if (m_glContext
) m_glContext
->SetColour( colour
);
224 void wxGLCanvas::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
226 if (m_resizing
) return; // I don't like recursions
229 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
231 // don't set the size for children of wxNotebook, just take the values.
239 int old_width
= m_width
;
240 int old_height
= m_height
;
242 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
244 if (x
!= -1) m_x
= x
;
245 if (y
!= -1) m_y
= y
;
246 if (width
!= -1) m_width
= width
;
247 if (height
!= -1) m_height
= height
;
257 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
259 if (width
== -1) m_width
= 80;
262 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
264 if (height
== -1) m_height
= 26;
267 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
268 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
269 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
270 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
272 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
273 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
275 if ((old_width
!= m_width
) || (old_height
!= m_height
))
277 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
279 gtk_drawing_area_size( GTK_DRAWING_AREA(m_glWidget
), m_width
, m_height
);
284 allo
.width
= m_width
;
285 allo
.height
= m_height
;
286 gtk_widget_size_allocate( m_glWidget
, &allo
);
292 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
293 event
.SetEventObject( this );
294 GetEventHandler()->ProcessEvent( event
);
299 void wxGLCanvas::SetSize( int width
, int height
)
301 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
304 GtkWidget
*wxGLCanvas::GetConnectWidget()
309 bool wxGLCanvas::IsOwnGtkWindow( GdkWindow
*window
)
311 return (window
== m_glWidget
->window
);