From 089e55d6e83909598ff8b3f9296002af084ee715 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Fri, 14 May 1999 21:04:49 +0000 Subject: [PATCH] wxGTK now works a little again. Added new OpenGl code. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2464 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/dcclient.cpp | 2 +- src/gtk1/dcclient.cpp | 2 +- utils/glcanvas/gtk/glcanvas.cpp | 80 +++++++- utils/glcanvas/gtk/glcanvas.h | 38 +++- utils/glcanvas/samples/cube/cube.cpp | 269 ++++++++++++++++++++++++--- utils/glcanvas/samples/cube/cube.h | 20 +- utils/glcanvas/win/glcanvas.cpp | 131 ++++++++----- utils/glcanvas/win/glcanvas.h | 44 ++++- 8 files changed, 485 insertions(+), 101 deletions(-) diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 4e1147edb7..7735312440 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -1048,7 +1048,7 @@ void wxWindowDC::DoSetClippingRegion( long x, long y, long width, long height ) { wxCHECK_RET( Ok(), _T("invalid window dc") ); - wxDC::SetClippingRegion( x, y, width, height ); + wxDC::DoSetClippingRegion( x, y, width, height ); GdkRectangle rect; rect.x = XLOG2DEV(x); diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 4e1147edb7..7735312440 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -1048,7 +1048,7 @@ void wxWindowDC::DoSetClippingRegion( long x, long y, long width, long height ) { wxCHECK_RET( Ok(), _T("invalid window dc") ); - wxDC::SetClippingRegion( x, y, width, height ); + wxDC::DoSetClippingRegion( x, y, width, height ); GdkRectangle rect; rect.x = XLOG2DEV(x); diff --git a/utils/glcanvas/gtk/glcanvas.cpp b/utils/glcanvas/gtk/glcanvas.cpp index d8d12a8ab4..5832bac035 100644 --- a/utils/glcanvas/gtk/glcanvas.cpp +++ b/utils/glcanvas/gtk/glcanvas.cpp @@ -52,6 +52,26 @@ wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); } +wxGLContext::wxGLContext( + bool WXUNUSED(isRGB), wxWindow *win, + const wxPalette& WXUNUSED(palette), + const wxGLContext *other /* for sharing display lists */ +) +{ + m_window = win; + m_widget = ((wxGLCanvas*)win)->m_glWidget; + + wxCHECK_RET( g_vi, "invalid visual for OpenGl" ); + + if( other != 0 ) + m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, other->m_glContext, + GL_TRUE ); + else + m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, None, GL_TRUE ); + + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); +} + wxGLContext::~wxGLContext() { if (!m_glContext) return; @@ -170,22 +190,62 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, wxWindowID id, int *attribList, const wxPalette& palette ) { - Create( parent, id, pos, size, style, name, attribList, palette ); + Create( parent, NULL, id, pos, size, style, name, attribList, palette ); } -bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id, +wxGLCanvas::wxGLCanvas( wxWindow *parent, + const wxGLContext *shared, + wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette ) +{ + Create( parent, shared, id, pos, size, style, name, attribList, palette ); +} + +bool wxGLCanvas::Create( wxWindow *parent, + const wxGLContext *shared, + wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attribList, - const wxPalette& palette ) + const wxPalette& palette) { if (!attribList) { int data[] = { GLX_RGBA, GLX_DOUBLEBUFFER, - GLX_DEPTH_SIZE, 1, + GLX_DEPTH_SIZE, 1, /* use largest available depth buffer */ None }; attribList = (int*) data; + printf( "using default values\n" ); + } + else + { + int data[512], arg=0, p=0; + + while( (attribList[arg]!=0) && (p<512) ) + { + switch( attribList[arg++] ) + { + case WX_GL_RGBA: data[p++] = GLX_RGBA; break; + case WX_GL_DOUBLEBUFFER: data[p++] = GLX_DOUBLEBUFFER; break; + case WX_GL_DEPTH_SIZE: + data[p++]=GLX_DEPTH_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_RED: + data[p++]=GLX_RED_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_GREEN: + data[p++]=GLX_GREEN_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_BLUE: + data[p++]=GLX_BLUE_SIZE; data[p++]=attribList[arg++]; break; + default: + break; + } + } + data[p] = 0; + + attribList = (int*) data; } Display *dpy = GDK_DISPLAY(); @@ -209,7 +269,7 @@ bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id, GTK_WIDGET_SET_FLAGS( m_glWidget, GTK_CAN_FOCUS ); gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), m_glWidget, 0, 0, m_width, m_height ); - + gtk_signal_connect( GTK_OBJECT(m_glWidget), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); @@ -219,16 +279,19 @@ bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id, /* connect to key press and mouse handlers etc. */ ConnectWidget( m_glWidget ); + /* must be realized for OpenGl output */ gtk_widget_realize( m_glWidget ); - + gtk_widget_show( m_glWidget ); - m_glContext = new wxGLContext( TRUE, this, palette ); + m_glContext = new wxGLContext( TRUE, this, palette, shared ); XFree( g_vi ); g_vi = (XVisualInfo*) NULL; - + + gdk_window_set_back_pixmap( m_glWidget->window, None, 0 ); + return TRUE; } @@ -249,6 +312,7 @@ void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event)) if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) ) { SetCurrent(); +// gdk_window_set_back_pixmap( gtk_widget_get_parent_window(m_glWidget), None, 0 ); glViewport(0, 0, (GLint)width, (GLint)height ); glMatrixMode(GL_PROJECTION); diff --git a/utils/glcanvas/gtk/glcanvas.h b/utils/glcanvas/gtk/glcanvas.h index c407b70f63..837d92f3c5 100644 --- a/utils/glcanvas/gtk/glcanvas.h +++ b/utils/glcanvas/gtk/glcanvas.h @@ -25,6 +25,21 @@ extern "C" { #include "GL/glu.h" } +//--------------------------------------------------------------------------- +// Constants for attriblist +//--------------------------------------------------------------------------- + +enum +{ + WX_GL_RGBA=1, /* use true color palette */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ + WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ + WX_GL_MIN_BLUE /* use blue buffer with most bits (> MIN_BLUE bits) */ +/* these are enough constants for now, the remaining will be added later */ +}; + //--------------------------------------------------------------------------- // classes //--------------------------------------------------------------------------- @@ -44,6 +59,11 @@ class wxGLContext: public wxObject public: wxGLContext( bool isRGB, wxWindow *win, const wxPalette& palette = wxNullPalette ); + wxGLContext( + bool WXUNUSED(isRGB), wxWindow *win, + const wxPalette& WXUNUSED(palette), + const wxGLContext *other /* for sharing display lists */ + ); ~wxGLContext(); void SetCurrent(); @@ -80,11 +100,19 @@ class wxGLCanvas: public wxScrolledWindow wxGLCanvas( wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = "GLCanvas", - int *attribList = (int*) NULL, - const wxPalette& palette = wxNullPalette ); - - bool Create( wxWindow *parent, wxWindowID id = -1, + long style = 0, const wxString& name = "GLCanvas", + int *attribList = (int*) NULL, + const wxPalette& palette = wxNullPalette ); + wxGLCanvas( wxWindow *parent, const wxGLContext *shared = (wxGLContext *)NULL, + wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, const wxString& name = "GLCanvas", + int *attribList = (int*) NULL, + const wxPalette& palette = wxNullPalette ); + + bool Create( wxWindow *parent, const wxGLContext *shared = (wxGLContext *)NULL, + wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "GLCanvas", diff --git a/utils/glcanvas/samples/cube/cube.cpp b/utils/glcanvas/samples/cube/cube.cpp index 7a9735c98b..ce8afb40c2 100644 --- a/utils/glcanvas/samples/cube/cube.cpp +++ b/utils/glcanvas/samples/cube/cube.cpp @@ -29,6 +29,98 @@ #include "cube.h" +#define ID_NEW_WINDOW 10000 +#define ID_DEF_ROTATE_LEFT_KEY 10001 +#define ID_DEF_ROTATE_RIGHT_KEY 10002 + +////////////////////////////////////////////////////////////////////////////////// +// Control to get a keycode + +class CScanTextCtrl : public wxTextCtrl +{ +public: + CScanTextCtrl( wxWindow* parent, wxWindowID id, int code, + const wxPoint& pos, const wxSize& size ); + + void OnChar( wxKeyEvent& event ) { } /* do nothing */ + void OnKeyDown(wxKeyEvent& event); + +private: +// any class wishing to process wxWindows events must use this macro + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE( CScanTextCtrl, wxTextCtrl ) + EVT_CHAR( CScanTextCtrl::OnChar ) + EVT_KEY_DOWN( CScanTextCtrl::OnKeyDown ) +END_EVENT_TABLE() + +CScanTextCtrl::CScanTextCtrl( wxWindow* parent, wxWindowID id, int code, + const wxPoint& pos, const wxSize& size ) + : wxTextCtrl( parent, id, "", pos, size ) +{ + wxString buf; + buf.Printf( "0x%04x", code ); + SetValue( buf ); +} +void CScanTextCtrl::OnKeyDown( wxKeyEvent& event ) +{ + #ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, "[EVT_KEYDOWN]: Key = %04x, time = %d\n", event.KeyCode(), + event.m_timeStamp ); + #endif // __WXDEBUG__ + + wxString buf; + buf.Printf( "0x%04x", event.KeyCode() ); + SetValue( buf ); +} + +/////////////////////////////////////////////////////////// +// Dialog for defining a keypress + +class CMenuKeyDialog : public wxDialog +{ +public: + CMenuKeyDialog( wxWindow* parent, wxWindowID id, const int code, const wxString &descr, + const wxString& title ); + int GetValue(); + +private: + CScanTextCtrl *m_ScanCode; + wxTextCtrl *m_Description; + +// any class wishing to process wxWindows events must use this macro + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE( CMenuKeyDialog, wxDialog ) +// +END_EVENT_TABLE() + +CMenuKeyDialog::CMenuKeyDialog( wxWindow* parent, wxWindowID id, const int code, + const wxString &descr, const wxString& title ) + : wxDialog( parent, id, title, wxPoint(-1, -1), wxSize(96*2,76*2) ) +{ + new wxStaticText( this, -1, "Scancode", wxPoint(4*2,3*2), wxSize(31*2,12*2) ); + m_ScanCode = new CScanTextCtrl( this, -1, code, wxPoint(37*2,6*2), wxSize(53*2,14*2) ); + + new wxStaticText( this, -1, "Description", wxPoint(4*2,24*2), wxSize(32*2,12*2) ); + m_Description = new wxTextCtrl( this, -1, descr, wxPoint(37*2,27*2), wxSize(53*2,14*2) ); + + new wxButton( this, wxID_OK, "Ok", wxPoint(20*2,50*2), wxSize(20*2,13*2) ); + new wxButton( this, wxID_CANCEL, "Cancel", wxPoint(44*2,50*2), wxSize(25*2,13*2) ); +} +int CMenuKeyDialog::GetValue() +{ + int code; + wxString buf = m_ScanCode->GetValue(); + #ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, buf.c_str() ); + #endif // __WXDEBUG__ + sscanf( buf.c_str(), "%i", &code ); + return( code ); +} + // `Main program' equivalent, creating windows and returning main app frame bool MyApp::OnInit(void) { @@ -43,11 +135,18 @@ bool MyApp::OnInit(void) #endif // Make a menubar - wxMenu *fileMenu = new wxMenu; + wxMenu *winMenu = new wxMenu; - fileMenu->Append(wxID_EXIT, "E&xit"); + winMenu->Append(wxID_EXIT, "&Close"); + winMenu->Append(ID_NEW_WINDOW, "&New" ); wxMenuBar *menuBar = new wxMenuBar; - menuBar->Append(fileMenu, "&File"); + menuBar->Append(winMenu, "&Window"); + + winMenu = new wxMenu; + winMenu->Append(ID_DEF_ROTATE_LEFT_KEY, "Rotate &left"); + winMenu->Append(ID_DEF_ROTATE_RIGHT_KEY, "Rotate &right"); + menuBar->Append(winMenu, "&Key"); + frame->SetMenuBar(menuBar); frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200)); @@ -58,10 +157,59 @@ bool MyApp::OnInit(void) return TRUE; } +void MyFrame::OnNewWindow() +{ + MyFrame *frame = new MyFrame(NULL, "Cube OpenGL Demo Clone", wxPoint(50, 50), wxSize(400, 300)); + + // Give it an icon +#ifdef wx_msw + frame->SetIcon(wxIcon("mondrian")); +#endif + + // Make a menubar + wxMenu *winMenu = new wxMenu; + + winMenu->Append(wxID_EXIT, "&Close"); + winMenu->Append(ID_NEW_WINDOW, "&New" ); + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(winMenu, "&Window"); + + winMenu = new wxMenu; + winMenu->Append(ID_DEF_ROTATE_LEFT_KEY, "Rotate &left"); + winMenu->Append(ID_DEF_ROTATE_RIGHT_KEY, "Rotate &right"); + menuBar->Append(winMenu, "&Key"); + + frame->SetMenuBar(menuBar); + + frame->m_canvas = new TestGLCanvas( frame, *m_canvas, -1, + wxPoint(0, 0), wxSize(200, 200) ); + + // Show the frame + frame->Show(TRUE); +} + +void MyFrame::OnDefRotateLeftKey() +{ + CMenuKeyDialog dial( this, -1, m_canvas->m_rleft, wxString("Rotate left key"), "Define key" ); + int result = dial.ShowModal(); + if( result == wxID_OK ) + m_canvas->m_rleft = dial.GetValue(); +} +void MyFrame::OnDefRotateRightKey() +{ + CMenuKeyDialog dial( this, -1, m_canvas->m_rright, wxString("Rotate right key"), "Define key" ); + int result = dial.ShowModal(); + if( result == wxID_OK ) + m_canvas->m_rright = dial.GetValue(); +} + IMPLEMENT_APP(MyApp) BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(wxID_EXIT, MyFrame::OnExit) + EVT_MENU( ID_NEW_WINDOW, MyFrame::OnNewWindow) + EVT_MENU( ID_DEF_ROTATE_LEFT_KEY, MyFrame::OnDefRotateLeftKey) + EVT_MENU( ID_DEF_ROTATE_RIGHT_KEY, MyFrame::OnDefRotateRightKey) END_EVENT_TABLE() // My frame constructor @@ -82,13 +230,33 @@ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_SIZE(TestGLCanvas::OnSize) EVT_PAINT(TestGLCanvas::OnPaint) EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground) + EVT_KEY_DOWN( TestGLCanvas::OnKeyDown ) + EVT_KEY_UP( TestGLCanvas::OnKeyUp ) END_EVENT_TABLE() TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name): - wxGLCanvas(parent, id, pos, size, style, name) + wxGLCanvas(parent, NULL, id, pos, size, style, name ) +{ + m_init = FALSE; + m_gllist = 0; + m_rleft = 0x13b; + m_rright = 0x13d; +} + +TestGLCanvas::TestGLCanvas(wxWindow *parent, const TestGLCanvas &other, + wxWindowID id, const wxPoint& pos, const wxSize& size, long style, + const wxString& name ) : + wxGLCanvas(parent, other.GetContext(), id, pos, size, style, name ) { m_init = FALSE; + m_gllist = other.m_gllist; /* share display list */ + m_rleft = 0x13b; + m_rright = 0x13d; + +// SetBackgroundColour( *wxGREEN ); +// virtual void SetBackgroundColour(const wxColour& colour) + } TestGLCanvas::~TestGLCanvas(void) @@ -117,33 +285,45 @@ void TestGLCanvas::OnPaint( wxPaintEvent& event ) /* clear color and depth buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - /* draw six faces of a cube */ - glBegin(GL_QUADS); - glNormal3f( 0.0F, 0.0F, 1.0F); - glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); - glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); - - glNormal3f( 0.0F, 0.0F,-1.0F); - glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); - glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); - - glNormal3f( 0.0F, 1.0F, 0.0F); - glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); - glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); - - glNormal3f( 0.0F,-1.0F, 0.0F); - glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); - glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); - - glNormal3f( 1.0F, 0.0F, 0.0F); - glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); - glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); - - glNormal3f(-1.0F, 0.0F, 0.0F); - glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); - glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); - glEnd(); + if( m_gllist == 0 ) + { + m_gllist = glGenLists( 1 ); + printf( "List=%d\n", m_gllist ); + glNewList( m_gllist, GL_COMPILE_AND_EXECUTE ); + + /* draw six faces of a cube */ + glBegin(GL_QUADS); + glNormal3f( 0.0F, 0.0F, 1.0F); + glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); + glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); + + glNormal3f( 0.0F, 0.0F,-1.0F); + glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); + glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); + + glNormal3f( 0.0F, 1.0F, 0.0F); + glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); + glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); + + glNormal3f( 0.0F,-1.0F, 0.0F); + glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); + glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); + + glNormal3f( 1.0F, 0.0F, 0.0F); + glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); + glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); + + glNormal3f(-1.0F, 0.0F, 0.0F); + glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); + glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); + glEnd(); + + glEndList(); + } + else + glCallList( m_gllist ); + glFlush(); SwapBuffers(); } @@ -164,10 +344,13 @@ void TestGLCanvas::OnSize(wxSizeEvent& event) void TestGLCanvas::OnEraseBackground(wxEraseEvent& event) { // Do nothing, to avoid flashing. + printf( "in erase background\n" ); } void TestGLCanvas::InitGL(void) { + SetCurrent(); + /* set viewing projection */ glMatrixMode(GL_PROJECTION); glFrustum(-0.5F, 0.5F, -0.5F, 0.5F, 1.0F, 3.0F); @@ -185,3 +368,29 @@ void TestGLCanvas::InitGL(void) glEnable(GL_LIGHT0); } +void TestGLCanvas::OnKeyDown( wxKeyEvent& event ) +{ + if( event.KeyCode() == m_rleft ) Rotate( -5.0 ); + else if( event.KeyCode() == m_rright ) Rotate( 5.0 ); + #ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, "[EVT_KEYDOWN]: Key = %04x, time = %d\n", event.KeyCode(), + event.m_timeStamp ); + #endif // __WXDEBUG__ +} +void TestGLCanvas::OnKeyUp( wxKeyEvent& event ) +{ + #ifdef __WXDEBUG__ + wxLogTrace(wxTraceMessages, "[EVT_KEYUP]: Key = %04x, time = %d\n", event.KeyCode(), + event.m_timeStamp ); + #endif // __WXDEBUG__ +} + +void TestGLCanvas::Rotate( double deg ) +{ + SetCurrent(); + + glMatrixMode(GL_MODELVIEW); + glRotatef((GLfloat)deg, 0.0F, 0.0F, 1.0F); + Refresh(FALSE); +} + diff --git a/utils/glcanvas/samples/cube/cube.h b/utils/glcanvas/samples/cube/cube.h index 74d3219ece..9379861392 100644 --- a/utils/glcanvas/samples/cube/cube.h +++ b/utils/glcanvas/samples/cube/cube.h @@ -30,6 +30,10 @@ public: long style = wxDEFAULT_FRAME_STYLE); void OnExit(wxCommandEvent& event); + void OnNewWindow(); + void OnDefRotateLeftKey(); + void OnDefRotateRightKey(); + public: TestGLCanvas* m_canvas; @@ -38,19 +42,31 @@ DECLARE_EVENT_TABLE() class TestGLCanvas: public wxGLCanvas { + friend class MyFrame; + public: TestGLCanvas(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "TestGLCanvas"); + TestGLCanvas(wxWindow *parent, const TestGLCanvas &other, + const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0, + const wxString& name = "TestGLCanvas" ); + ~TestGLCanvas(void); void OnPaint(wxPaintEvent& event); void OnSize(wxSizeEvent& event); void OnEraseBackground(wxEraseEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); void InitGL(void); + void Rotate( double deg ); private: - - bool m_init; + bool m_init; + GLuint m_gllist; + long m_rleft; + long m_rright; DECLARE_EVENT_TABLE() }; diff --git a/utils/glcanvas/win/glcanvas.cpp b/utils/glcanvas/win/glcanvas.cpp index 44449532ea..e90b555a01 100644 --- a/utils/glcanvas/win/glcanvas.cpp +++ b/utils/glcanvas/win/glcanvas.cpp @@ -29,28 +29,44 @@ * GLContext implementation */ -wxGLContext::wxGLContext(bool isRGB, wxWindow *win, const wxPalette& palette) +wxGLContext::wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette) { m_window = win; - m_hDC = (WXHDC) ::GetDC((HWND) win->GetHWND()); - - SetupPixelFormat(); - SetupPalette(palette); + m_hDC = win->GetHDC(); m_glContext = wglCreateContext((HDC) m_hDC); + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); + wglMakeCurrent((HDC) m_hDC, m_glContext); } +wxGLContext::wxGLContext( + bool isRGB, wxGLCanvas *win, + const wxPalette& palette, + const wxGLContext *other /* for sharing display lists */ +) +{ + m_window = win; + + m_hDC = win->GetHDC(); + + m_glContext = wglCreateContext((HDC) m_hDC); + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); + + if( other != 0 ) + wglShareLists( other->m_glContext, m_glContext ); + + wglMakeCurrent((HDC) m_hDC, m_glContext); +} + wxGLContext::~wxGLContext() { if (m_glContext) { wglMakeCurrent(NULL, NULL); - wglDeleteContext(m_glContext); + wglDeleteContext(m_glContext); } - - ::ReleaseDC((HWND) m_window->GetHWND(), (HDC) m_hDC); } void wxGLContext::SwapBuffers() @@ -90,7 +106,54 @@ void wxGLContext::SetColour(const char *colour) } } -void wxGLContext::SetupPixelFormat() // (HDC hDC) + +/* + * wxGLCanvas implementation + */ + +IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) + +BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) + EVT_SIZE(wxGLCanvas::OnSize) + EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged) + EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette) +END_EVENT_TABLE() + +wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, + int *attribList /* not used yet! */, const wxPalette& palette): + wxScrolledWindow(parent, id, pos, size, style, name) +{ + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette); +} +wxGLCanvas::wxGLCanvas( wxWindow *parent, + const wxGLContext *shared, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, + int *attribList, const wxPalette& palette ) : + wxScrolledWindow(parent, id, pos, size, style, name) +{ + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette, shared ); +} + +wxGLCanvas::~wxGLCanvas() +{ + if (m_glContext) + delete m_glContext; + + ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); +} + +void wxGLCanvas::SetupPixelFormat() // (HDC hDC) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size */ @@ -128,7 +191,7 @@ void wxGLContext::SetupPixelFormat() // (HDC hDC) } } -void wxGLContext::SetupPalette(const wxPalette& palette) +void wxGLCanvas::SetupPalette(const wxPalette& palette) { int pixelFormat = GetPixelFormat((HDC) m_hDC); PIXELFORMATDESCRIPTOR pfd; @@ -157,7 +220,7 @@ void wxGLContext::SetupPalette(const wxPalette& palette) } } -wxPalette wxGLContext::CreateDefaultPalette() +wxPalette wxGLCanvas::CreateDefaultPalette() { PIXELFORMATDESCRIPTOR pfd; int paletteSize; @@ -199,32 +262,6 @@ wxPalette wxGLContext::CreateDefaultPalette() return palette; } -/* - * wxGLCanvas implementation - */ - -IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) - -BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) - EVT_SIZE(wxGLCanvas::OnSize) - EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged) - EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette) -END_EVENT_TABLE() - -wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *attribList /* not used yet! */, const wxPalette& palette): - wxScrolledWindow(parent, id, pos, size, style, name) -{ - m_glContext = new wxGLContext(TRUE, this, palette); -} - -wxGLCanvas::~wxGLCanvas() -{ - if (m_glContext) - delete m_glContext; -} - void wxGLCanvas::SwapBuffers() { if (m_glContext) @@ -267,10 +304,10 @@ void wxGLCanvas::SetColour(const char *colour) void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) { /* realize palette if this is the current window */ - if (m_glContext && m_glContext->GetPalette()->Ok()) { - ::UnrealizeObject((HPALETTE) m_glContext->GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) m_glContext->GetHDC(), (HPALETTE) m_glContext->GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) m_glContext->GetHDC()); + if ( GetPalette()->Ok() ) { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); Refresh(); event.SetPaletteRealized(TRUE); } @@ -282,14 +319,12 @@ void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) { /* realize palette if this is *not* the current window */ - if ( m_glContext && - m_glContext->GetPalette() && - m_glContext->GetPalette()->Ok() && - (this != event.GetChangedWindow()) ) + if ( GetPalette() && + GetPalette()->Ok() && (this != event.GetChangedWindow()) ) { - ::UnrealizeObject((HPALETTE) m_glContext->GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) m_glContext->GetHDC(), (HPALETTE) m_glContext->GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) m_glContext->GetHDC()); + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); Refresh(); } } diff --git a/utils/glcanvas/win/glcanvas.h b/utils/glcanvas/win/glcanvas.h index a21382a987..186df14faf 100644 --- a/utils/glcanvas/win/glcanvas.h +++ b/utils/glcanvas/win/glcanvas.h @@ -22,21 +22,39 @@ #include "gl/gl.h" +//--------------------------------------------------------------------------- +// Constants for attriblist +//--------------------------------------------------------------------------- + +enum +{ + WX_GL_RGBA=1, /* use true color palette */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ + WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ + WX_GL_MIN_BLUE /* use blue buffer with most bits (> MIN_BLUE bits) */ +/* these are enough constants for now, the remaining will be added later */ +}; + +class wxGLCanvas; /* forward reference */ + class wxGLContext: public wxObject { public: - wxGLContext(bool isRGB, wxWindow *win, const wxPalette& palette = wxNullPalette); + wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette = wxNullPalette); + wxGLContext( + bool isRGB, wxGLCanvas *win, + const wxPalette& WXUNUSED(palette), + const wxGLContext *other /* for sharing display lists */ + ); ~wxGLContext(); void SetCurrent(); void SetColour(const char *colour); void SwapBuffers(); - void SetupPixelFormat(); - void SetupPalette(const wxPalette& palette); - wxPalette CreateDefaultPalette(); - inline wxPalette* GetPalette() const { return (wxPalette*) & m_palette; } inline wxWindow* GetWindow() const { return m_window; } inline WXHDC GetHDC() const { return m_hDC; } inline HGLRC GetGLRC() const { return m_glContext; } @@ -44,7 +62,6 @@ public: public: HGLRC m_glContext; WXHDC m_hDC; - wxPalette m_palette; wxWindow* m_window; }; @@ -55,6 +72,11 @@ class wxGLCanvas: public wxScrolledWindow wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette); + wxGLCanvas( wxWindow *parent, const wxGLContext *shared = (wxGLContext *)NULL, + wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "GLCanvas", + int *attribList = (int*) NULL, const wxPalette& palette = wxNullPalette ); + ~wxGLCanvas(); void SetCurrent(); @@ -68,8 +90,18 @@ class wxGLCanvas: public wxScrolledWindow inline wxGLContext* GetContext() const { return m_glContext; } + + inline WXHDC GetHDC() const { return m_hDC; } + void SetupPixelFormat(); + void SetupPalette(const wxPalette& palette); + wxPalette CreateDefaultPalette(); + + inline wxPalette* GetPalette() const { return (wxPalette*) & m_palette; } + protected: wxGLContext* m_glContext; // this is typedef-ed ptr, in fact + wxPalette m_palette; + WXHDC m_hDC; DECLARE_EVENT_TABLE() }; -- 2.45.2