diff --git a/distrib/msw/glcanvas.rsp b/distrib/msw/glcanvas.rsp index 923fc507bd..d23618a158 100644 --- a/distrib/msw/glcanvas.rsp +++ b/distrib/msw/glcanvas.rsp @@ -1,42 +1,37 @@ -utils/glcanvas/Makefile.in -utils/glcanvas/docs/*.* -utils/glcanvas/win/*.cpp -utils/glcanvas/win/*.h -utils/glcanvas/win/make*.* -utils/glcanvas/gtk/*.cpp -utils/glcanvas/gtk/*.h -utils/glcanvas/gtk/make*.* -utils/glcanvas/motif/*.cpp -utils/glcanvas/motif/*.h -utils/glcanvas/motif/make*.* -utils/glcanvas/motif/*.txt -utils/glcanvas/samples/cube/*.cpp -utils/glcanvas/samples/cube/*.h -utils/glcanvas/samples/cube/*.rc -utils/glcanvas/samples/cube/*.ico -utils/glcanvas/samples/cube/*.xbm -utils/glcanvas/samples/cube/make*.* -utils/glcanvas/samples/cube/Makefile +include/wx/glcanvas.h +include/wx/motif/glcanvas.h +include/wx/gtk/glcanvas.h +include/wx/msw/glcanvas.h -utils/glcanvas/samples/isosurf/*.cpp -utils/glcanvas/samples/isosurf/*.h -utils/glcanvas/samples/isosurf/*.rc -utils/glcanvas/samples/isosurf/*.ico -utils/glcanvas/samples/isosurf/*.xbm -utils/glcanvas/samples/isosurf/*.dat.gz -utils/glcanvas/samples/isosurf/make*.* -utils/glcanvas/samples/isosurf/Makefile +src/motif/glcanvas.cpp +src/gtk/glcanvas.cpp +src/msw/glcanvas.cpp -utils/glcanvas/samples/penguin/*.cpp -utils/glcanvas/samples/penguin/*.c -utils/glcanvas/samples/penguin/*.h -utils/glcanvas/samples/penguin/*.rc -utils/glcanvas/samples/penguin/*.ico -utils/glcanvas/samples/penguin/*.xbm -utils/glcanvas/samples/penguin/*.xpm -utils/glcanvas/samples/penguin/make*.* -utils/glcanvas/samples/penguin/Makefile -utils/glcanvas/samples/penguin/penguin.lwo +samples/opengl/cube/*.cpp +samples/opengl/cube/*.h +samples/opengl/cube/*.rc +samples/opengl/cube/*.ico +samples/opengl/cube/*.xbm +samples/opengl/cube/make*.* +samples/opengl/cube/Makefile +samples/opengl/isosurf/*.cpp +samples/opengl/isosurf/*.h +samples/opengl/isosurf/*.rc +samples/opengl/isosurf/*.ico +samples/opengl/isosurf/*.xbm +samples/opengl/isosurf/*.dat.gz +samples/opengl/isosurf/make*.* +samples/opengl/isosurf/Makefile +samples/opengl/penguin/*.cpp +samples/opengl/penguin/*.c +samples/opengl/penguin/*.h +samples/opengl/penguin/*.rc +samples/opengl/penguin/*.ico +samples/opengl/penguin/*.xbm +samples/opengl/penguin/*.xpm +samples/opengl/penguin/make*.* +samples/opengl/penguin/Makefile +samples/opengl/penguin/penguin.lwo diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index e483bf786b..e5f716ff6c 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -247,6 +247,7 @@ gauge95.cpp M 32 gaugemsw.cpp M 16 gdiimage.cpp M gdiobj.cpp M +glcanvas.cpp M helpwin.cpp M icon.cpp M imaglist.cpp M 32 @@ -343,6 +344,7 @@ fontdlg.cpp R frame.cpp R gauge.cpp R gdiobj.cpp R +glcanvas.cpp R icon.cpp R listbox.cpp R main.cpp R @@ -400,6 +402,7 @@ font.cpp X frame.cpp X gauge.cpp X gdiobj.cpp X +glcanvas.cpp X icon.cpp X listbox.cpp X main.cpp X @@ -603,6 +606,7 @@ gdicmn.h W gdiobj.h W geometry.h W gifdecod.h W +glcanvas.h W grid.h W gsocket.h W hash.h W B @@ -761,6 +765,7 @@ fontdlg.h K frame.h K gauge.h K gdiobj.h K +glcanvas.h K icon.h K joystick.h K listbox.h K @@ -823,6 +828,7 @@ fontdlg.h F frame.h F gauge.h F gdiobj.h F +glcanvas.h F icon.h F joystick.h F listbox.h F @@ -891,6 +897,7 @@ gauge95.h 9 gaugemsw.h 9 gdiimage.h 9 gdiobj.h 9 +glcanvas.h 9 helpwin.h 9 icon.h 9 imaglist.h 9 diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex index fb000358a0..a6adbfd61c 100644 --- a/docs/latex/wx/classes.tex +++ b/docs/latex/wx/classes.tex @@ -94,6 +94,7 @@ \input ftp.tex \input gauge.tex \input gdiobj.tex +\input glcanvas.tex \input valgen.tex \input grid.tex \input hash.tex diff --git a/docs/latex/wx/glcanvas.tex b/docs/latex/wx/glcanvas.tex new file mode 100644 index 0000000000..fddb1541ee --- /dev/null +++ b/docs/latex/wx/glcanvas.tex @@ -0,0 +1,67 @@ +\section{\class{wxGLCanvas}}\label{wxglcanvas} + +wxGLCanvas is a class for displaying OpenGL graphics. There are +wrappers for OpenGL on Windows, and GTK+ and Motif. + +To use this class, create a wxGLCanvas window, call \helpref{wxGLCanvas::SetCurrent}{wxglcanvassetcurrent} +to direct normal OpenGL commands to the window, and then call \helpref{wxGLCanvas::SwapBuffers}{wxglcanvasswapbuffers} +to show the OpenGL buffer on the window. + +Please note that despite deriving from wxScrolledWindow, scrolling is not enabled for this class under +Windows. + +To switch wxGLCanvas support on under Windows, edit setup.h and set wxUSE\_GLCANVAS to 1. + +\wxheading{Derived from} + +\helpref{wxScrolledWindow}{wxscrolledwindow}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\wxheading{Include files} + + + +\wxheading{Window styles} + +There are no specific window styles for this class. + +See also \helpref{window styles overview}{windowstyles}. + +\latexignore{\rtfignore{\wxheading{Members}}} + +\membersection{wxGLCanvas::wxGLCanvas}\label{wxglcanvasconstr} + +\func{void}{wxGLCanvas}{\param{wxWindow* }{parent}, \param{wxWindowID}{ id = -1}, \param{const wxPoint\&}{ pos}, + \param{const wxSize\&}{ size}, \param{long}{ style=0}, \param{const wxString\& }{name="GLCanvas"}, + \param{int*}{ attribList = 0}, \param{const wxPalette\&}{ palette = wxNullPalette}} + +\func{void}{wxGLCanvas}{\param{wxWindow* }{parent}, \param{wxGLCanvas* }{ sharedCanvas = NULL}, \param{wxWindowID}{ id = -1}, \param{const wxPoint\&}{ pos}, + \param{const wxSize\&}{ size}, \param{long}{ style=0}, \param{const wxString\& }{name="GLCanvas"}, + \param{int*}{ attribList = 0}, \param{const wxPalette\&}{ palette = wxNullPalette}} + +\func{void}{wxGLCanvas}{\param{wxWindow* }{parent}, \param{wxGLContext* }{ sharedContext = NULL}, \param{wxWindowID}{ id = -1}, \param{const wxPoint\&}{ pos}, + \param{const wxSize\&}{ size}, \param{long}{ style=0}, \param{const wxString\& }{name="GLCanvas"}, + \param{int*}{ attribList = 0}, \param{const wxPalette\&}{ palette = wxNullPalette}} + +Constructor. + +\membersection{wxGLCanvas::SetCurrent}\label{wxglcanvassetcurrent} + +\func{void}{SetCurrent}{\void} + +Sets this canvas as the current recipient of OpenGL calls. + +\membersection{wxGLCanvas::SetColour}\label{wxglcanvassetcolour} + +\func{void}{SetColour}{\param{const char*}{ colour}} + +Sets the current colour for this window, using the wxWindows colour database to find a named colour. + +\membersection{wxGLCanvas::SwapBuffers}\label{wxglcanvasswapbuffers} + +\func{void}{SwapBuffers}{\void} + +Displays the previous OpenGL commands on the window. + diff --git a/docs/latex/wx/grid.tex b/docs/latex/wx/grid.tex index 384d32438c..540ed2fed1 100644 --- a/docs/latex/wx/grid.tex +++ b/docs/latex/wx/grid.tex @@ -608,4 +608,3 @@ Call this function whenever a change has been made via the API that might alter size characteristics. You may also need to follow it with a call to AdjustScrollbars. - diff --git a/include/wx/glcanvas.h b/include/wx/glcanvas.h new file mode 100644 index 0000000000..2385447aab --- /dev/null +++ b/include/wx/glcanvas.h @@ -0,0 +1,21 @@ +#ifndef _WX_GLCANVAS_H_BASE_ +#define _WX_GLCANVAS_H_BASE_ + +#if defined(__WXMSW__) +#include "wx/msw/glcanvas.h" +#elif defined(__WXMOTIF__) +#include "wx/motif/glcanvas.h" +#elif defined(__WXGTK__) +#include "wx/gtk/glcanvas.h" +#elif defined(__WXQT__) +#include "wx/qt/glcanvas.h" +#elif defined(__WXMAC__) +#include "wx/mac/glcanvas.h" +#elif defined(__WXPM__) +#include "wx/os2/glcanvas.h" +#elif defined(__WXSTUBS__) +#include "wx/stubs/glcanvas.h" +#endif + +#endif + // _WX_GLCANVAS_H_BASE_ diff --git a/include/wx/gtk/glcanvas.h b/include/wx/gtk/glcanvas.h new file mode 100644 index 0000000000..14c439691d --- /dev/null +++ b/include/wx/gtk/glcanvas.h @@ -0,0 +1,169 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.h +// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWindows and GTK +// Author: Robert Roebling +// Modified by: +// Created: 17/8/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma interface "glcanvas.h" +#endif + +#ifndef _WX_GLCANVAS_H_ +#define _WX_GLCANVAS_H_ + +#include + +#if wxUSE_GLCANVAS + +#include + +extern "C" { +#include "GL/gl.h" +#include "GL/glx.h" +#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 +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLContext; +class WXDLLEXPORT wxGLCanvas; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + + +class WXDLLEXPORT 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(); + 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 GtkWidget* GetWidget() const { return m_widget; } + inline GLXContext GetContext() const { return m_glContext; } + +public: + GLXContext m_glContext; + + GtkWidget *m_widget; + wxPalette m_palette; + wxWindow* m_window; + +private: + DECLARE_CLASS(wxGLContext) +}; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow +{ +public: + inline wxGLCanvas() { + m_glContext = (wxGLContext*) NULL; + m_sharedContext = (wxGLContext*) NULL; + m_glWidget = (GtkWidget*) NULL; + m_vi = (void*) NULL; + m_exposed = FALSE; + } + 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 ); + 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( wxWindow *parent, const wxGLCanvas *shared = (wxGLCanvas *)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, + const wxGLCanvas *shared_context_of = (wxGLCanvas*)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(); + void SetColour(const char *colour); + void SwapBuffers(); + + void OnSize(wxSizeEvent& event); + + void OnInternalIdle(); + + inline wxGLContext* GetContext() const { return m_glContext; } + + // implementation + + wxGLContext *m_glContext, + *m_sharedContext; + wxGLCanvas *m_sharedContextOf; + void *m_vi; + GtkWidget *m_glWidget; + bool m_exposed; + +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(wxGLCanvas) +}; + +#endif + // wxUSE_GLCANVAS + +#endif + // _WX_GLCANVAS_H_ + diff --git a/include/wx/gtk1/glcanvas.h b/include/wx/gtk1/glcanvas.h new file mode 100644 index 0000000000..14c439691d --- /dev/null +++ b/include/wx/gtk1/glcanvas.h @@ -0,0 +1,169 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.h +// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWindows and GTK +// Author: Robert Roebling +// Modified by: +// Created: 17/8/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma interface "glcanvas.h" +#endif + +#ifndef _WX_GLCANVAS_H_ +#define _WX_GLCANVAS_H_ + +#include + +#if wxUSE_GLCANVAS + +#include + +extern "C" { +#include "GL/gl.h" +#include "GL/glx.h" +#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 +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLContext; +class WXDLLEXPORT wxGLCanvas; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + + +class WXDLLEXPORT 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(); + 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 GtkWidget* GetWidget() const { return m_widget; } + inline GLXContext GetContext() const { return m_glContext; } + +public: + GLXContext m_glContext; + + GtkWidget *m_widget; + wxPalette m_palette; + wxWindow* m_window; + +private: + DECLARE_CLASS(wxGLContext) +}; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow +{ +public: + inline wxGLCanvas() { + m_glContext = (wxGLContext*) NULL; + m_sharedContext = (wxGLContext*) NULL; + m_glWidget = (GtkWidget*) NULL; + m_vi = (void*) NULL; + m_exposed = FALSE; + } + 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 ); + 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( wxWindow *parent, const wxGLCanvas *shared = (wxGLCanvas *)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, + const wxGLCanvas *shared_context_of = (wxGLCanvas*)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(); + void SetColour(const char *colour); + void SwapBuffers(); + + void OnSize(wxSizeEvent& event); + + void OnInternalIdle(); + + inline wxGLContext* GetContext() const { return m_glContext; } + + // implementation + + wxGLContext *m_glContext, + *m_sharedContext; + wxGLCanvas *m_sharedContextOf; + void *m_vi; + GtkWidget *m_glWidget; + bool m_exposed; + +private: + DECLARE_EVENT_TABLE() + DECLARE_CLASS(wxGLCanvas) +}; + +#endif + // wxUSE_GLCANVAS + +#endif + // _WX_GLCANVAS_H_ + diff --git a/include/wx/motif/glcanvas.h b/include/wx/motif/glcanvas.h new file mode 100644 index 0000000000..b3a9ab8016 --- /dev/null +++ b/include/wx/motif/glcanvas.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.h +// Purpose: wxGLCanvas, for using OpenGL with wxWindows 2.0 for Motif. +// Uses the GLX extension. +// Author: Julian Smart and Wolfram Gloger +// Modified by: +// Created: 1995, 1999 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart, Wolfram Gloger +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma interface "glcanvas.h" +#endif + +#ifndef _WX_GLCANVAS_H_ +#define _WX_GLCANVAS_H_ + +#include + +#if wxUSE_GLCANVAS + +#include +#include +#include + +#include + +class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow +{ +DECLARE_CLASS(wxGLCanvas) +public: + GLXContext glx_cx; + + inline wxGLCanvas() { glx_cx = 0; } + + 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(void); + + void SetCurrent(); + void SwapBuffers(); + void SetColour(const char *col); +}; + +#endif + // wxUSE_GLCANVAS + +#endif + // _WX_GLCANVAS_H_ diff --git a/include/wx/msw/glcanvas.h b/include/wx/msw/glcanvas.h new file mode 100644 index 0000000000..f743c5430a --- /dev/null +++ b/include/wx/msw/glcanvas.h @@ -0,0 +1,174 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.h +// Purpose: wxGLCanvas, for using OpenGL with wxWindows under Windows +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma interface "glcanvas.h" +#endif + +#ifndef _WX_GLCANVAS_H_ +#define _WX_GLCANVAS_H_ + +#include + +#if wxUSE_GLCANVAS + +#include + +#include + +#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 WXDLLEXPORT wxGLCanvas; /* forward reference */ + +class WXDLLEXPORT wxGLContext: public wxObject +{ +public: + 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(); + + + inline wxWindow* GetWindow() const { return m_window; } + inline WXHDC GetHDC() const { return m_hDC; } + inline HGLRC GetGLRC() const { return m_glContext; } + +public: + HGLRC m_glContext; + WXHDC m_hDC; + wxWindow* m_window; +}; + +class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow +{ + DECLARE_CLASS(wxGLCanvas) + public: + 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( wxWindow *parent, const wxGLCanvas *shared = (wxGLCanvas *)NULL, 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(); + + // Replaces wxWindow::Create functionality, since we need to use a different window class + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name); + + void SetCurrent(); + void SetColour(const char *colour); + void SwapBuffers(); + + void OnSize(wxSizeEvent& event); + + void OnQueryNewPalette(wxQueryNewPaletteEvent& event); + void OnPaletteChanged(wxPaletteChangedEvent& event); + + 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() +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Give extensions proper function names. */ + +/* N.B. - this is not completely implemented as yet */ + +/* EXT_vertex_array */ +void glArrayElementEXT(GLint i); +void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count); +void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer); +void glGetPointervEXT(GLenum pname, GLvoid* *params); +void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); + +/* EXT_color_subtable */ +void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table); + +/* EXT_color_table */ +void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table); +void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params); +void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params); + +/* SGI_compiled_vertex_array */ +void glLockArraysSGI(GLint first, GLsizei count); +void glUnlockArraysSGI(); + +/* SGI_cull_vertex */ +void glCullParameterdvSGI(GLenum pname, GLdouble* params); +void glCullParameterfvSGI(GLenum pname, GLfloat* params); + +/* SGI_index_func */ +void glIndexFuncSGI(GLenum func, GLclampf ref); + +/* SGI_index_material */ +void glIndexMaterialSGI(GLenum face, GLenum mode); + +/* WIN_swap_hint */ +void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif + // wxUSE_GLCANVAS +#endif + // _WX_GLCANVAS_H_ + diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index d8e736f282..f86739919a 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -217,6 +217,9 @@ // Recommended setting: 1 #define wxUSE_PLOT 1 +// OpenGL canvas +#define wxUSE_GLCANVAS 0 + // ---------------------------------------------------------------------------- // Postscript support settings // ---------------------------------------------------------------------------- diff --git a/samples/opengl/cube/Makefile b/samples/opengl/cube/Makefile new file mode 100644 index 0000000000..56fac3db98 --- /dev/null +++ b/samples/opengl/cube/Makefile @@ -0,0 +1,31 @@ +# +# File: Makefile +# Author: Robert Roebling +# Created: 1999 +# Updated: +# Copyright: (c) 1998 Robert Roebling +# +# Makefile for OpenGl demo (GTK version) +# +# This makefile requires wxWindows/GTK to be +# installed (possibly using "make install") +# on your system. +# + +CC = gcc +WXCONFIG=../../../wx-config +WXINCLUDE=-I../../../include +WXLIB=-L../../../lib + +cube: cube.o # glcanvas.o + $(CC) -o cube cube.o `$(WXCONFIG) --libs` $(WXLIB) -lMesaGL -lMesaGLU + +cube.o: cube.cpp + $(CC) `$(WXCONFIG) --cflags` -I../../gtk $(WXINCLUDE) -c cube.cpp + +glcanvas.o: ../../gtk/glcanvas.cpp + $(CC) `$(WXCONFIG) --cflags` `gtk-config --cflags` -I../../gtk $(WXINCLUDE) -c ../../gtk/glcanvas.cpp + +clean: + rm -f *.o cube + diff --git a/samples/opengl/cube/cube.cpp b/samples/opengl/cube/cube.cpp new file mode 100644 index 0000000000..2f145970d2 --- /dev/null +++ b/samples/opengl/cube/cube.cpp @@ -0,0 +1,508 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: cube.cpp +// Purpose: wxGLCanvas demo program +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation +#pragma interface +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/log.h" + +#include "cube.h" + +#ifndef __WXMSW__ // for wxStopWatch, see remark below +#include +#include +#else +#include +#endif + +#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 ScanCodeCtrl : public wxTextCtrl +{ +public: + ScanCodeCtrl( 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( ScanCodeCtrl, wxTextCtrl ) + EVT_CHAR( ScanCodeCtrl::OnChar ) + EVT_KEY_DOWN( ScanCodeCtrl::OnKeyDown ) +END_EVENT_TABLE() + +ScanCodeCtrl::ScanCodeCtrl( 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 ScanCodeCtrl::OnKeyDown( wxKeyEvent& event ) +{ wxString buf; + buf.Printf( "0x%04x", event.KeyCode() ); + SetValue( buf ); +} + +/*------------------------------------------------------------------ + Dialog for defining a keypress +-------------------------------------------------------------------*/ + +class ScanCodeDialog : public wxDialog +{ +public: + ScanCodeDialog( wxWindow* parent, wxWindowID id, const int code, + const wxString &descr, const wxString& title ); + int GetValue(); +private: + ScanCodeCtrl *m_ScanCode; + wxTextCtrl *m_Description; +}; + +ScanCodeDialog::ScanCodeDialog( 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 ScanCodeCtrl( 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 ScanCodeDialog::GetValue() +{ + int code; + wxString buf = m_ScanCode->GetValue(); + sscanf( buf.c_str(), "%i", &code ); + return( code ); +} + +/*---------------------------------------------------------------------- + Utility function to get the elapsed time (in msec) since a given point + in time (in sec) (because current version of wxGetElapsedTime doesn´t + works right with glibc-2.1 and linux, at least for me) +-----------------------------------------------------------------------*/ +unsigned long wxStopWatch( unsigned long *sec_base ) +{ + unsigned long secs,msec; + +#ifndef __WXMSW__ // think every unice has gettimeofday + struct timeval tv; + gettimeofday( &tv, (struct timezone *)NULL ); + secs = tv.tv_sec; + msec = tv.tv_usec/1000; +#else + struct timeb tb; + + ftime( &tb ); + + secs = tb.time; + + msec = tb.millitm; + +#endif + + if( *sec_base == 0 ) + *sec_base = secs; + + return( (secs-*sec_base)*1000 + msec ); +} + +/*---------------------------------------------------------------- + Implementation of Test-GLCanvas +-----------------------------------------------------------------*/ + +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 ) + EVT_ENTER_WINDOW( TestGLCanvas::OnEnterWindow ) +END_EVENT_TABLE() + +unsigned long TestGLCanvas::m_secbase = 0; +int TestGLCanvas::m_TimeInitialized = 0; +unsigned long TestGLCanvas::m_xsynct; +unsigned long TestGLCanvas::m_gsynct; + +TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name): + wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, style, name ) +{ + m_init = FALSE; + m_gllist = 0; + m_rleft = WXK_LEFT; + m_rright = WXK_RIGHT; +} + +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 = WXK_LEFT; + m_rright = WXK_RIGHT; +} + +TestGLCanvas::~TestGLCanvas() +{ +} + +void TestGLCanvas::Render() +{ + wxPaintDC dc(this); + +#ifndef __WXMOTIF__ + if (!GetContext()) return; +#endif + + SetCurrent(); + /* init OpenGL once, but after SetCurrent */ + if (!m_init) + { + InitGL(); + m_init = TRUE; + } + + /* clear color and depth buffers */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if( m_gllist == 0 ) + { + m_gllist = glGenLists( 1 ); + 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(); +} + +void TestGLCanvas::OnEnterWindow( wxMouseEvent& event ) +{ + SetFocus(); +} + +void TestGLCanvas::OnPaint( wxPaintEvent& event ) +{ + Render(); +} + +void TestGLCanvas::OnSize(wxSizeEvent& event) +{ + int width, height; + GetClientSize(& width, & height); + +#ifndef __WXMOTIF__ + if (GetContext()) +#endif + { + SetCurrent(); + glViewport(0, 0, width, height); + } +} + +void TestGLCanvas::OnEraseBackground(wxEraseEvent& event) +{ + // Do nothing, to avoid flashing. +} + +void TestGLCanvas::InitGL() +{ + SetCurrent(); + + /* set viewing projection */ + glMatrixMode(GL_PROJECTION); + glFrustum(-0.5F, 0.5F, -0.5F, 0.5F, 1.0F, 3.0F); + + /* position viewer */ + glMatrixMode(GL_MODELVIEW); + glTranslatef(0.0F, 0.0F, -2.0F); + + /* position object */ + glRotatef(30.0F, 1.0F, 0.0F, 0.0F); + glRotatef(30.0F, 0.0F, 1.0F, 0.0F); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +} + +GLfloat TestGLCanvas::CalcRotateSpeed( unsigned long acceltime ) +{ + GLfloat t,v; + + t = ((GLfloat)acceltime) / 1000.0f; + + if( t < 0.5f ) + v = t; + else if( t < 1.0f ) + v = t * (2.0f - t); + else + v = 0.75f; + + return(v); +} + +GLfloat TestGLCanvas::CalcRotateAngle( unsigned long lasttime, + unsigned long acceltime ) +{ + GLfloat t,s1,s2; + + t = ((GLfloat)(acceltime - lasttime)) / 1000.0f; + s1 = CalcRotateSpeed( lasttime ); + s2 = CalcRotateSpeed( acceltime ); + + return( t * (s1 + s2) * 135.0f ); +} + +void TestGLCanvas::Action( long code, unsigned long lasttime, + unsigned long acceltime ) +{ + GLfloat angle = CalcRotateAngle( lasttime, acceltime ); + + if (code == m_rleft) + Rotate( angle ); + else if (code == m_rright) + Rotate( -angle ); +} + +void TestGLCanvas::OnKeyDown( wxKeyEvent& event ) +{ + long evkey = event.KeyCode(); + if (evkey == 0) return; + + if (!m_TimeInitialized) + { + m_TimeInitialized = 1; + m_xsynct = event.m_timeStamp; + m_gsynct = wxStopWatch(&m_secbase); + + m_Key = evkey; + m_StartTime = 0; + m_LastTime = 0; + m_LastRedraw = 0; + } + + unsigned long currTime = event.m_timeStamp - m_xsynct; + + if (evkey != m_Key) + { + m_Key = evkey; + m_LastRedraw = m_StartTime = m_LastTime = currTime; + } + + if (currTime >= m_LastRedraw) // Redraw: + { + Action( m_Key, m_LastTime-m_StartTime, currTime-m_StartTime ); + + m_LastRedraw = wxStopWatch(&m_secbase) - m_gsynct; + m_LastTime = currTime; + } + + event.Skip(); +} + +void TestGLCanvas::OnKeyUp( wxKeyEvent& event ) +{ + m_Key = 0; + m_StartTime = 0; + m_LastTime = 0; + m_LastRedraw = 0; + + event.Skip(); +} + +void TestGLCanvas::Rotate( GLfloat deg ) +{ + SetCurrent(); + + glMatrixMode(GL_MODELVIEW); + glRotatef((GLfloat)deg, 0.0F, 0.0F, 1.0F); + Refresh(FALSE); +} + + +/* ----------------------------------------------------------------------- + Main Window +-------------------------------------------------------------------------*/ + +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 +MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, + const wxSize& size, long style) + : wxFrame(frame, -1, title, pos, size, style) +{ + m_canvas = NULL; +} + +// Intercept menu commands +void MyFrame::OnExit(wxCommandEvent& event) +{ + Destroy(); +} + +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() +{ + ScanCodeDialog dial( this, -1, m_canvas->m_rleft, + wxString("Left"), "Define key" ); + int result = dial.ShowModal(); + if( result == wxID_OK ) + m_canvas->m_rleft = dial.GetValue(); +} +void MyFrame::OnDefRotateRightKey() +{ + ScanCodeDialog dial( this, -1, m_canvas->m_rright, + wxString("Right"), "Define key" ); + int result = dial.ShowModal(); + if( result == wxID_OK ) + m_canvas->m_rright = dial.GetValue(); +} + +/*------------------------------------------------------------------ + Application object ( equivalent to main() ) +------------------------------------------------------------------ */ + +IMPLEMENT_APP(MyApp) + +bool MyApp::OnInit(void) +{ + wxLog::SetTraceMask(wxTraceMessages); + + // Create the main frame window + MyFrame *frame = new MyFrame(NULL, "Cube OpenGL Demo", 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, -1, wxPoint(0, 0), wxSize(200, 200)); + + // Show the frame + frame->Show(TRUE); + + return TRUE; +} diff --git a/samples/opengl/cube/cube.h b/samples/opengl/cube/cube.h new file mode 100644 index 0000000000..66732f2453 --- /dev/null +++ b/samples/opengl/cube/cube.h @@ -0,0 +1,93 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: cube.h +// Purpose: wxGLCanvas demo program +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_CUBE_H_ +#define _WX_CUBE_H_ + +#include + +// Define a new application type +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +// Define a new frame type +class TestGLCanvas; +class MyFrame: public wxFrame +{ +public: + MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, + const wxSize& size, long style = wxDEFAULT_FRAME_STYLE); + + void OnExit(wxCommandEvent& event); + void OnNewWindow(); + void OnDefRotateLeftKey(); + void OnDefRotateRightKey(); + +public: + TestGLCanvas* m_canvas; + +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 OnEnterWindow( wxMouseEvent& event ); + + void Render( void ); + void InitGL(void); + void Rotate( GLfloat deg ); + static GLfloat CalcRotateSpeed( unsigned long acceltime ); + static GLfloat CalcRotateAngle( unsigned long lasttime, + unsigned long acceltime ); + void Action( long code, unsigned long lasttime, + unsigned long acceltime ); + +private: + bool m_init; + GLuint m_gllist; + long m_rleft; + long m_rright; + + static unsigned long m_secbase; + static int m_TimeInitialized; + static unsigned long m_xsynct; + static unsigned long m_gsynct; + + long m_Key; + unsigned long m_StartTime; + unsigned long m_LastTime; + unsigned long m_LastRedraw; + +DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/samples/opengl/cube/cube.rc b/samples/opengl/cube/cube.rc new file mode 100644 index 0000000000..7655c62a4c --- /dev/null +++ b/samples/opengl/cube/cube.rc @@ -0,0 +1,3 @@ +mondrian ICON "mondrian.ico" +#include "wx/msw/wx.rc" + diff --git a/samples/opengl/cube/makefile.b32 b/samples/opengl/cube/makefile.b32 new file mode 100644 index 0000000000..7bc170c87a --- /dev/null +++ b/samples/opengl/cube/makefile.b32 @@ -0,0 +1,18 @@ +# +# File: makefile.b32 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = $(WXWIN) + +TARGET=cube +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/samples/opengl/cube/makefile.bcc b/samples/opengl/cube/makefile.bcc new file mode 100644 index 0000000000..b46274d17e --- /dev/null +++ b/samples/opengl/cube/makefile.bcc @@ -0,0 +1,21 @@ +# +# File: makefile.bcc +# Author: Julian Smart +# Created: 1998 +# Updated: +# +# Builds a BC++ 16-bit sample + +!if "$(WXWIN)" == "" +!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx +!endif + +WXDIR = $(WXWIN) + +TARGET=cube +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.bcc + diff --git a/samples/opengl/cube/makefile.g95 b/samples/opengl/cube/makefile.g95 new file mode 100644 index 0000000000..60381560ed --- /dev/null +++ b/samples/opengl/cube/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: makefile.g95 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart, 1999 +# +# Makefile for wxWindows sample (Cygwin/Mingw32). + +WXDIR = ../../.. + +TARGET=cube +#EXTRACPPFLAGS=-I../../win +EXTRALIBS=-lopengl32 -lglu32 +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 + diff --git a/samples/opengl/cube/makefile.unx b/samples/opengl/cube/makefile.unx new file mode 100644 index 0000000000..ecf313ff33 --- /dev/null +++ b/samples/opengl/cube/makefile.unx @@ -0,0 +1,23 @@ +# +# File: makefile.unx +# Author: Julian Smart +# Created: 1998 +# Updated: +# Copyright: (c) 1998 Julian Smart +# +# "%W% %G%" +# +# Makefile for cube example (UNIX). + +PROGRAM=cube + +OPENGLHOME=/home/jacs/mesa/Mesa-2.3 + +EXTRACPPFLAGS=-I$(OPENGLHOME)/include +EXTRALDFLAGS=-L$(OPENGLHOME)/lib +EXTRALDLIBS=-lMesaGL -lMesaGLU + +OBJECTS=$(PROGRAM).o + +include ../../../src/makeprog.env + diff --git a/samples/opengl/cube/makefile.vc b/samples/opengl/cube/makefile.vc new file mode 100644 index 0000000000..c761a91325 --- /dev/null +++ b/samples/opengl/cube/makefile.vc @@ -0,0 +1,26 @@ +# +# File: makefile.vc +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart +# +# Makefile : Builds sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +# Set WXDIR for your system +WXDIR = $(WXWIN) + +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + +PROGRAM=cube +OBJECTS = $(PROGRAM).obj +#EXTRAINC=-I..\..\win +#EXTRALIBS=$(WXDIR)\lib\glcanvas$(LIBEXT).lib glu32.lib opengl32.lib +EXTRALIBS=glu32.lib opengl32.lib + +!include $(WXDIR)\src\makeprog.vc + diff --git a/samples/opengl/cube/makefile.wat b/samples/opengl/cube/makefile.wat new file mode 100644 index 0000000000..66cb0511c1 --- /dev/null +++ b/samples/opengl/cube/makefile.wat @@ -0,0 +1,17 @@ +# +# Makefile for WATCOM +# +# Created by Julian Smart, January 1999 +# +# + +WXDIR = $(%WXWIN) + +PROGRAM = cube +OBJECTS = $(PROGRAM).obj +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win + +!include $(WXDIR)\src\makeprog.wat + + diff --git a/samples/opengl/cube/mondrian.ico b/samples/opengl/cube/mondrian.ico new file mode 100644 index 0000000000..2310c5d275 Binary files /dev/null and b/samples/opengl/cube/mondrian.ico differ diff --git a/samples/opengl/isosurf/Makefile b/samples/opengl/isosurf/Makefile new file mode 100644 index 0000000000..b11b16b7b6 --- /dev/null +++ b/samples/opengl/isosurf/Makefile @@ -0,0 +1,32 @@ +# +# File: Makefile +# Author: Robert Roebling +# Created: 1999 +# Updated: +# Copyright: (c) 1998 Robert Roebling +# +# Makefile for OpenGl demo (GTK version) +# +# This makefile requires wxWindows/GTK to be +# installed (possibly using "make install") +# on your system. +# + +CC = g++ +WXCONFIG=../../../wx-config +WXINCLUDE=-I../../../include +WXLIB=-L../../../lib + +isosurf: isosurf.o # glcanvas.o + $(CC) -o isosurf \ + isosurf.o \ + `$(WXCONFIG) --libs` $(WXLIB) -lMesaGL -lMesaGLU + +isosurf.o: isosurf.cpp + $(CC) `$(WXCONFIG) --cflags` -I../../gtk $(WXINCLUDE) -c isosurf.cpp + +glcanvas.o: ../../gtk/glcanvas.cpp + $(CC) `$(WXCONFIG) --cflags` `gtk-config --cflags` -I../../gtk -c $(WXINCLUDE) ../../gtk/glcanvas.cpp + +clean: + rm -f *.o isosurf diff --git a/samples/opengl/isosurf/isosurf.cpp b/samples/opengl/isosurf/isosurf.cpp new file mode 100644 index 0000000000..6ba560cff1 --- /dev/null +++ b/samples/opengl/isosurf/isosurf.cpp @@ -0,0 +1,412 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: isosurf.cpp +// Purpose: wxGLCanvas demo program +// Author: Brian Paul (original gltk version), Wolfram Gloger +// Modified by: Julian Smart +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation +#pragma interface +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/timer.h" +#include "wx/glcanvas.h" + +#include +#include + +#include "isosurf.h" + +// The following part is taken largely unchanged from the original C Version + +#include + +GLboolean speed_test = GL_FALSE; +GLboolean use_vertex_arrays = GL_FALSE; + +GLboolean doubleBuffer = GL_TRUE; + +GLboolean smooth = GL_TRUE; +GLboolean lighting = GL_TRUE; + + +#define MAXVERTS 10000 + +static GLfloat verts[MAXVERTS][3]; +static GLfloat norms[MAXVERTS][3]; +static GLint numverts; + +static GLfloat xrot; +static GLfloat yrot; + + +static void read_surface( char *filename ) +{ + FILE *f; + + f = fopen(filename,"r"); + if (!f) { + wxString msg("Couldn't read "); + msg += filename; + wxMessageBox(msg); + return; + } + + numverts = 0; + while (!feof(f) && numvertsSetIcon(wxIcon("mondrian")); + + // Make a menubar + wxMenu *fileMenu = new wxMenu; + + fileMenu->Append(wxID_EXIT, "E&xit"); + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(fileMenu, "&File"); + frame->SetMenuBar(menuBar); + + // Make a TestGLCanvas + + // JACS +#ifdef __WXMSW__ + int *gl_attrib = NULL; +#else + int gl_attrib[20] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, + GLX_DOUBLEBUFFER, None }; +#endif + + if(!doubleBuffer) + { + printf("don't have double buffer, disabling\n"); +#ifdef __WXGTK__ + gl_attrib[9] = None; +#endif + doubleBuffer = GL_FALSE; + } + frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200), 0, "TestGLCanvas", + gl_attrib); + + // Show the frame + frame->Show(TRUE); + + frame->m_canvas->SetCurrent(); + read_surface( "isosurf.dat" ); + + Init(); + + return TRUE; +} + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU(wxID_EXIT, MyFrame::OnExit) +END_EVENT_TABLE() + +// My frame constructor +MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, + const wxSize& size, long style): + wxFrame(frame, -1, title, pos, size, style) +{ + m_canvas = NULL; +} + +// Intercept menu commands +void MyFrame::OnExit(wxCommandEvent& event) +{ + Destroy(); +} + +/* + * TestGLCanvas implementation + */ + +BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) + EVT_SIZE(TestGLCanvas::OnSize) + EVT_PAINT(TestGLCanvas::OnPaint) + EVT_CHAR(TestGLCanvas::OnChar) + EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent) + EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground) +END_EVENT_TABLE() + +TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib): + wxGLCanvas(parent, id, pos, size, style, name, gl_attrib) +{ + parent->Show(TRUE); + SetCurrent(); + /* Make sure server supports the vertex array extension */ + char* extensions = (char *) glGetString( GL_EXTENSIONS ); + if (!extensions || !strstr( extensions, "GL_EXT_vertex_array" )) { + use_vertex_arrays = GL_FALSE; + } +} + + +TestGLCanvas::~TestGLCanvas(void) +{ +} + +void TestGLCanvas::OnPaint( wxPaintEvent& event ) +{ + // This is a dummy, to avoid an endless succession of paint messages. + // OnPaint handlers must always create a wxPaintDC. + wxPaintDC dc(this); + + draw1(); + SwapBuffers(); +} + +void TestGLCanvas::OnSize(wxSizeEvent& event) +{ + SetCurrent(); + int width, height; + GetClientSize(& width, & height); + Reshape(width, height); +} + +void TestGLCanvas::OnChar(wxKeyEvent& event) +{ + switch(event.KeyCode()) { + case WXK_ESCAPE: + exit(0); + case WXK_LEFT: + yrot -= 15.0; + break; + case WXK_RIGHT: + yrot += 15.0; + break; + case WXK_UP: + xrot += 15.0; + break; + case WXK_DOWN: + xrot -= 15.0; + break; + case 's': case 'S': + smooth = !smooth; + if (smooth) { + glShadeModel(GL_SMOOTH); + } else { + glShadeModel(GL_FLAT); + } + break; + case 'l': case 'L': + lighting = !lighting; + if (lighting) { + glEnable(GL_LIGHTING); + } else { + glDisable(GL_LIGHTING); + } + break; + default: + { + event.Skip(); + return; + } + } + + Refresh(FALSE); +} + +void TestGLCanvas::OnMouseEvent(wxMouseEvent& event) +{ + static int dragging = 0; + static float last_x, last_y; + + //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown()); + if(event.LeftIsDown()) { + if(!dragging) { + dragging = 1; + } else { + yrot += (event.GetX() - last_x)*1.0; + xrot += (event.GetY() - last_y)*1.0; + Refresh(FALSE); + } + last_x = event.GetX(); + last_y = event.GetY(); + } else + dragging = 0; +} + +void TestGLCanvas::OnEraseBackground(wxEraseEvent& event) +{ + // Do nothing, to avoid flashing. +} + diff --git a/samples/opengl/isosurf/isosurf.dat.gz b/samples/opengl/isosurf/isosurf.dat.gz new file mode 100644 index 0000000000..c07dc570d2 Binary files /dev/null and b/samples/opengl/isosurf/isosurf.dat.gz differ diff --git a/samples/opengl/isosurf/isosurf.h b/samples/opengl/isosurf/isosurf.h new file mode 100644 index 0000000000..e84098c56b --- /dev/null +++ b/samples/opengl/isosurf/isosurf.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: isosurf.h +// Purpose: wxGLCanvas demo program +// Author: Brian Paul (original gltk version), Wolfram Gloger +// Modified by: Julian Smart +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_ISOSURF_H_ +#define _WX_ISOSURF_H_ + +// Define a new application type +class MyApp: public wxApp +{ public: + bool OnInit(void); +}; + +class TestGLCanvas: public wxGLCanvas +{ + public: + TestGLCanvas(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "TestGLCanvas", + int* gl_attrib = NULL); + ~TestGLCanvas(void); + + void OnPaint(wxPaintEvent& event); + void OnSize(wxSizeEvent& event); + void OnEraseBackground(wxEraseEvent& event); + void OnChar(wxKeyEvent& event); + void OnMouseEvent(wxMouseEvent& event); + +DECLARE_EVENT_TABLE() +}; + +class MyFrame: public wxFrame +{ +public: + MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, + long style = wxDEFAULT_FRAME_STYLE); + + void OnExit(wxCommandEvent& event); +public: + TestGLCanvas* m_canvas; + +DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/samples/opengl/isosurf/isosurf.rc b/samples/opengl/isosurf/isosurf.rc new file mode 100644 index 0000000000..7655c62a4c --- /dev/null +++ b/samples/opengl/isosurf/isosurf.rc @@ -0,0 +1,3 @@ +mondrian ICON "mondrian.ico" +#include "wx/msw/wx.rc" + diff --git a/samples/opengl/isosurf/makefile.b32 b/samples/opengl/isosurf/makefile.b32 new file mode 100644 index 0000000000..0154a0aac0 --- /dev/null +++ b/samples/opengl/isosurf/makefile.b32 @@ -0,0 +1,22 @@ +# +# File: makefile.b32 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = $(WXWIN) + +TARGET=isosurf +# EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +# EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj +EXTRATARGETS=isosurf.dat + +!include $(WXDIR)\src\makeprog.b32 + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat + diff --git a/samples/opengl/isosurf/makefile.bcc b/samples/opengl/isosurf/makefile.bcc new file mode 100644 index 0000000000..680d8c95bf --- /dev/null +++ b/samples/opengl/isosurf/makefile.bcc @@ -0,0 +1,25 @@ +# +# File: makefile.bcc +# Author: Julian Smart +# Created: 1998 +# Updated: +# +# Builds a BC++ 16-bit sample + +!if "$(WXWIN)" == "" +!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx +!endif + +WXDIR = $(WXWIN) + +TARGET=isosurf +# EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +# EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj +EXTRATARGETS=isosurf.dat + +!include $(WXDIR)\src\makeprog.bcc + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat + diff --git a/samples/opengl/isosurf/makefile.g95 b/samples/opengl/isosurf/makefile.g95 new file mode 100644 index 0000000000..f0396a5d3d --- /dev/null +++ b/samples/opengl/isosurf/makefile.g95 @@ -0,0 +1,20 @@ +# +# File: makefile.g95 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart, 1999 +# +# Makefile for wxWindows sample (Cygwin/Mingw32). + +WXDIR = ../../.. + +TARGET=isosurf +# EXTRACPPFLAGS=-I../../win +EXTRALIBS=-lopengl32 -lglu32 +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat diff --git a/samples/opengl/isosurf/makefile.unx b/samples/opengl/isosurf/makefile.unx new file mode 100644 index 0000000000..2c0a364808 --- /dev/null +++ b/samples/opengl/isosurf/makefile.unx @@ -0,0 +1,27 @@ +# +# File: makefile.unx +# Author: Julian Smart +# Created: 1998 +# Updated: +# Copyright: (c) 1998 Julian Smart +# +# "%W% %G%" +# +# Makefile for isosurf example (UNIX). + +PROGRAM=isosurf + +OPENGLHOME=/home/jacs/mesa/Mesa-2.3 + +EXTRACPPFLAGS=-I$(OPENGLHOME)/include +EXTRALDFLAGS=-L$(OPENGLHOME)/lib +EXTRALDLIBS=-lMesaGL -lMesaGLU + +OBJECTS=$(PROGRAM).o +EXTRATARGETS=isosurf.dat + +include ../../../src/makeprog.env + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat + diff --git a/samples/opengl/isosurf/makefile.vc b/samples/opengl/isosurf/makefile.vc new file mode 100644 index 0000000000..9c787154f2 --- /dev/null +++ b/samples/opengl/isosurf/makefile.vc @@ -0,0 +1,30 @@ +# +# File: makefile.vc +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart +# +# Makefile : Builds sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +# Set WXDIR for your system +WXDIR = $(WXWIN) + +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + +PROGRAM=isosurf +OBJECTS = $(PROGRAM).obj +#EXTRAINC=-I..\..\win +EXTRALIBS=glu32.lib opengl32.lib +EXTRATARGETS=isosurf.dat + +!include $(WXDIR)\src\makeprog.vc + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat + + diff --git a/samples/opengl/isosurf/makefile.wat b/samples/opengl/isosurf/makefile.wat new file mode 100644 index 0000000000..ba3a87cef8 --- /dev/null +++ b/samples/opengl/isosurf/makefile.wat @@ -0,0 +1,20 @@ +# +# Makefile for WATCOM +# +# Created by Julian Smart, January 1999 +# +# + +WXDIR = $(%WXWIN) + +PROGRAM = isosurf +OBJECTS = $(PROGRAM).obj +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +EXTRATARGETS=isosurf.dat + +!include $(WXDIR)\src\makeprog.wat + +isosurf.dat: isosurf.dat.gz + gzip -c -d isosurf.dat.gz > isosurf.dat + diff --git a/samples/opengl/isosurf/mondrian.ico b/samples/opengl/isosurf/mondrian.ico new file mode 100644 index 0000000000..2310c5d275 Binary files /dev/null and b/samples/opengl/isosurf/mondrian.ico differ diff --git a/samples/opengl/penguin/Makefile b/samples/opengl/penguin/Makefile new file mode 100644 index 0000000000..7a3ef78bbe --- /dev/null +++ b/samples/opengl/penguin/Makefile @@ -0,0 +1,37 @@ +# +# File: Makefile +# Author: Robert Roebling +# Created: 1999 +# Updated: +# Copyright: (c) 1998 Robert Roebling +# +# Makefile for OpenGL demo (GTK version) +# +# This makefile requires wxWindows/GTK to be +# installed (possibly using "make install") +# on your system. +# + +CPP = gcc +CC = gcc +WXCONFIG=../../../wx-config +WXINCLUDE=-I../../../include +WXLIB=-L../../../lib + +Penguin: penguin.o trackball.o lw.o # glcanvas.o + $(CPP) -o Penguin penguin.o trackball.o lw.o `$(WXCONFIG) --libs` $(WXLIB) -lMesaGL -lMesaGLU + +penguin.o: penguin.cpp + $(CPP) `$(WXCONFIG) --cflags` -I../../gtk $(WXINCLUDE) -c penguin.cpp + +lw.o: lw.cpp + $(CPP) `$(WXCONFIG) --cflags` -I../../gtk $(WXINCLUDE) -c lw.cpp + +trackball.o: trackball.c + $(CC) `$(WXCONFIG) --cflags` -I../../gtk $(WXINCLUDE) -c trackball.c + +glcanvas.o: ../../gtk/glcanvas.cpp + $(CPP) `$(WXCONFIG) --cflags` `gtk-config --cflags` -g -I../../gtk $(WXINCLUDE) -c ../../gtk/glcanvas.cpp + +clean: + rm -f *.o Penguin diff --git a/samples/opengl/penguin/lw.cpp b/samples/opengl/penguin/lw.cpp new file mode 100644 index 0000000000..e7bfe17843 --- /dev/null +++ b/samples/opengl/penguin/lw.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (C) 1998 Janne Löf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef __WXMSW__ +#include +#endif + +#include "lw.h" +#include +#include +#include + +#define wxInt32 int +#define wxUint32 unsigned int + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#define MK_ID(a,b,c,d) ((((wxUint32)(a))<<24)| \ + (((wxUint32)(b))<<16)| \ + (((wxUint32)(c))<< 8)| \ + (((wxUint32)(d)) )) + +#define ID_FORM MK_ID('F','O','R','M') +#define ID_LWOB MK_ID('L','W','O','B') +#define ID_PNTS MK_ID('P','N','T','S') +#define ID_SRFS MK_ID('S','R','F','S') +#define ID_SURF MK_ID('S','U','R','F') +#define ID_POLS MK_ID('P','O','L','S') +#define ID_COLR MK_ID('C','O','L','R') + +static wxInt32 read_char(FILE *f) +{ + int c = fgetc(f); + return c; +} + +static wxInt32 read_short(FILE *f) +{ + return (read_char(f)<<8) | read_char(f); +} + +static wxInt32 read_long(FILE *f) +{ + return (read_char(f)<<24) | (read_char(f)<<16) | (read_char(f)<<8) | read_char(f); +} + +static GLfloat read_float(FILE *f) +{ + wxInt32 x = read_long(f); + return *(GLfloat*)&x; +} + +static int read_string(FILE *f, char *s) +{ + int c; + int cnt = 0; + do { + c = read_char(f); + if (cnt < LW_MAX_NAME_LEN) + s[cnt] = c; + else + s[LW_MAX_NAME_LEN-1] = 0; + cnt++; + } while (c != 0); + /* if length of string (including \0) is odd skip another byte */ + if (cnt%2) { + read_char(f); + cnt++; + } + return cnt; +} + +static void read_srfs(FILE *f, int nbytes, lwObject *lwo) +{ + int guess_cnt = lwo->material_cnt; + + while (nbytes > 0) { + lwMaterial *material; + + /* allocate more memory for materials if needed */ + if (guess_cnt <= lwo->material_cnt) { + guess_cnt += guess_cnt/2 + 4; + lwo->material = (lwMaterial*) realloc(lwo->material, sizeof(lwMaterial)*guess_cnt); + } + material = lwo->material + lwo->material_cnt++; + + /* read name */ + nbytes -= read_string(f,material->name); + + /* defaults */ + material->r = 0.7; + material->g = 0.7; + material->b = 0.7; + } + lwo->material = (lwMaterial*) realloc(lwo->material, sizeof(lwMaterial)*lwo->material_cnt); +} + + +static void read_surf(FILE *f, int nbytes, lwObject *lwo) +{ + int i; + char name[LW_MAX_NAME_LEN]; + lwMaterial *material = NULL; + + /* read surface name */ + nbytes -= read_string(f,name); + + /* find material */ + for (i=0; i< lwo->material_cnt; i++) { + if (strcmp(lwo->material[i].name,name) == 0) { + material = &lwo->material[i]; + break; + } + } + + /* read values */ + while (nbytes > 0) { + int id = read_long(f); + int len = read_short(f); + nbytes -= 6 + len + (len%2); + + switch (id) { + case ID_COLR: + material->r = read_char(f) / 255.0; + material->g = read_char(f) / 255.0; + material->b = read_char(f) / 255.0; + read_char(f); /* dummy */ + break; + default: + fseek(f, len+(len%2), SEEK_CUR); + } + } +} + + +static void read_pols(FILE *f, int nbytes, lwObject *lwo) +{ + int guess_cnt = lwo->face_cnt; + + while (nbytes > 0) { + lwFace *face; + int i; + + /* allocate more memory for polygons if necessary */ + if (guess_cnt <= lwo->face_cnt) { + guess_cnt += guess_cnt + 4; + lwo->face = (lwFace*) realloc((void*) lwo->face, sizeof(lwFace)*guess_cnt); + } + face = lwo->face + lwo->face_cnt++; + + /* number of points in this face */ + face->index_cnt = read_short(f); + nbytes -= 2; + + /* allocate space for points */ + face->index = (int*) calloc(sizeof(int)*face->index_cnt,1); + + /* read points in */ + for (i=0; iindex_cnt; i++) { + face->index[i] = read_short(f); + nbytes -= 2; + } + + /* read surface material */ + face->material = read_short(f); + nbytes -= 2; + + /* skip over detail polygons */ + if (face->material < 0) { + int det_cnt; + face->material = -face->material; + det_cnt = read_short(f); + nbytes -= 2; + while (det_cnt-- > 0) { + int cnt = read_short(f); + fseek(f, cnt*2+2, SEEK_CUR); + nbytes -= cnt*2+2; + } + } + face->material -= 1; + } + /* readjust to true size */ + lwo->face = (lwFace*) realloc(lwo->face, sizeof(lwFace)*lwo->face_cnt); +} + + + +static void read_pnts(FILE *f, int nbytes, lwObject *lwo) +{ + int i; + lwo->vertex_cnt = nbytes / 12; + lwo->vertex = (float*) calloc(sizeof(GLfloat)*lwo->vertex_cnt*3, 1); + for (i=0; ivertex_cnt; i++) { + lwo->vertex[i*3+0] = read_float(f); + lwo->vertex[i*3+1] = read_float(f); + lwo->vertex[i*3+2] = read_float(f); + } +} + + + + + + +int lw_is_lwobject(const char *lw_file) +{ + FILE *f = fopen(lw_file, "rb"); + if (f) { + wxInt32 form = read_long(f); + wxInt32 nlen = read_long(f); + wxInt32 lwob = read_long(f); + fclose(f); + if (form == ID_FORM && nlen != 0 && lwob == ID_LWOB) + return TRUE; + } + return FALSE; +} + + +lwObject *lw_object_read(const char *lw_file) +{ + FILE *f = NULL; + lwObject *lw_object = NULL; + + wxInt32 form_bytes = 0; + wxInt32 read_bytes = 0; + + /* open file */ + f = fopen(lw_file, "rb"); + if (f == NULL) { + return NULL; + } + + /* check for headers */ + if (read_long(f) != ID_FORM) { + fclose(f); + return NULL; + } + form_bytes = read_long(f); + read_bytes += 4; + + if (read_long(f) != ID_LWOB) { + fclose(f); + return NULL; + } + + /* create new lwObject */ + lw_object = (lwObject*) calloc(sizeof(lwObject),1); + + /* read chunks */ + while (read_bytes < form_bytes) { + wxInt32 id = read_long(f); + wxInt32 nbytes = read_long(f); + read_bytes += 8 + nbytes + (nbytes%2); + + switch (id) { + case ID_PNTS: + read_pnts(f, nbytes, lw_object); + break; + case ID_POLS: + read_pols(f, nbytes, lw_object); + break; + case ID_SRFS: + read_srfs(f, nbytes, lw_object); + break; + case ID_SURF: + read_surf(f, nbytes, lw_object); + break; + default: + fseek(f, nbytes + (nbytes%2), SEEK_CUR); + } + } + + fclose(f); + return lw_object; +} + + + +void lw_object_free(lwObject *lw_object) +{ + if (lw_object->face) { + int i; + for (i=0; iface_cnt; i++) + free(lw_object->face[i].index); + free(lw_object->face); + } + free(lw_object->material); + free(lw_object->vertex); + free(lw_object); +} + + + + + +#define PX(i) (lw_object->vertex[face->index[i]*3+0]) +#define PY(i) (lw_object->vertex[face->index[i]*3+1]) +#define PZ(i) (lw_object->vertex[face->index[i]*3+2]) +void lw_object_show(const lwObject *lw_object) +{ + int i,j; + int prev_index_cnt = -1; + int prev_material = -1; + GLfloat prev_nx = 0; + GLfloat prev_ny = 0; + GLfloat prev_nz = 0; + + for (i=0; iface_cnt; i++) { + GLfloat ax,ay,az,bx,by,bz,nx,ny,nz,r; + const lwFace *face = lw_object->face+i; + + /* ignore faces with less than 3 points */ + if (face->index_cnt < 3) + continue; + + /* calculate normal */ + ax = PX(1) - PX(0); + ay = PY(1) - PY(0); + az = PZ(1) - PZ(0); + + bx = PX(face->index_cnt-1) - PX(0); + by = PY(face->index_cnt-1) - PY(0); + bz = PZ(face->index_cnt-1) - PZ(0); + + nx = ay * bz - az * by; + ny = az * bx - ax * bz; + nz = ax * by - ay * bx; + + r = sqrt(nx*nx + ny*ny + nz*nz); + if (r < 0.000001) /* avoid division by zero */ + continue; + nx /= r; + ny /= r; + nz /= r; + + /* glBegin/glEnd */ + if (prev_index_cnt != face->index_cnt || prev_index_cnt > 4) { + if (prev_index_cnt > 0) glEnd(); + prev_index_cnt = face->index_cnt; + switch (face->index_cnt) { + case 3: + glBegin(GL_TRIANGLES); + break; + case 4: + glBegin(GL_QUADS); + break; + default: + glBegin(GL_POLYGON); + } + } + + /* update material if necessary */ + if (prev_material != face->material) { + prev_material = face->material; + glColor3f(lw_object->material[face->material].r, + lw_object->material[face->material].g, + lw_object->material[face->material].b); + } + + /* update normal if necessary */ + if (nx != prev_nx || ny != prev_ny || nz != prev_nz) { + prev_nx = nx; + prev_ny = ny; + prev_nz = nz; + glNormal3f(nx,ny,nz); + } + + /* draw polygon/triangle/quad */ + for (j=0; jindex_cnt; j++) + glVertex3f(PX(j),PY(j),PZ(j)); + + } + + /* if glBegin was called call glEnd */ + if (prev_index_cnt > 0) + glEnd(); +} + + +GLfloat lw_object_radius(const lwObject *lwo) +{ + int i; + double max_radius = 0.0; + + for (i=0; ivertex_cnt; i++) { + GLfloat *v = &lwo->vertex[i*3]; + double r = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; + if (r > max_radius) + max_radius = r; + } + return sqrt(max_radius); +} + +void lw_object_scale(lwObject *lwo, GLfloat scale) +{ + int i; + + for (i=0; ivertex_cnt; i++) { + lwo->vertex[i*3+0] *= scale; + lwo->vertex[i*3+1] *= scale; + lwo->vertex[i*3+2] *= scale; + } +} + + diff --git a/samples/opengl/penguin/lw.h b/samples/opengl/penguin/lw.h new file mode 100644 index 0000000000..b49e8ffc91 --- /dev/null +++ b/samples/opengl/penguin/lw.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 1998 Janne Löf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef LW_H +#define LW_H + +#include + +#define LW_MAX_POINTS 200 +#define LW_MAX_NAME_LEN 500 + +typedef struct { + char name[LW_MAX_NAME_LEN]; + GLfloat r,g,b; +} lwMaterial; + +typedef struct { + int material; /* material of this face */ + int index_cnt; /* number of vertices */ + int *index; /* index to vertex */ + float *texcoord; /* u,v texture coordinates */ +} lwFace; + +typedef struct { + int face_cnt; + lwFace *face; + + int material_cnt; + lwMaterial *material; + + int vertex_cnt; + GLfloat *vertex; + +} lwObject; + +#ifdef __cplusplus +extern "C" { +#endif + +int lw_is_lwobject(const char *lw_file); +lwObject *lw_object_read(const char *lw_file); +void lw_object_free( lwObject *lw_object); +void lw_object_show(const lwObject *lw_object); + +GLfloat lw_object_radius(const lwObject *lw_object); +void lw_object_scale (lwObject *lw_object, GLfloat scale); + +#ifdef __cplusplus +} +#endif + +#endif /* LW_H */ + diff --git a/samples/opengl/penguin/makefile.b32 b/samples/opengl/penguin/makefile.b32 new file mode 100644 index 0000000000..0f8d581ddc --- /dev/null +++ b/samples/opengl/penguin/makefile.b32 @@ -0,0 +1,18 @@ +# +# File: makefile.b32 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = $(WXWIN) + +TARGET=penguin +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj lw.obj trackball.obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/samples/opengl/penguin/makefile.bcc b/samples/opengl/penguin/makefile.bcc new file mode 100644 index 0000000000..c789bde1b0 --- /dev/null +++ b/samples/opengl/penguin/makefile.bcc @@ -0,0 +1,21 @@ +# +# File: makefile.bcc +# Author: Julian Smart +# Created: 1998 +# Updated: +# +# Builds a BC++ 16-bit sample + +!if "$(WXWIN)" == "" +!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx +!endif + +WXDIR = $(WXWIN) + +TARGET=penguin +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.bcc + diff --git a/samples/opengl/penguin/makefile.g95 b/samples/opengl/penguin/makefile.g95 new file mode 100644 index 0000000000..a15d8d0306 --- /dev/null +++ b/samples/opengl/penguin/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: makefile.g95 +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart, 1999 +# +# Makefile for wxWindows sample (Cygwin/Mingw32). + +WXDIR = ../../.. + +TARGET=penguin +#EXTRACPPFLAGS=-I../../win +EXTRALIBS=-lopengl32 -lglu32 +OBJECTS = $(TARGET).o lw.o trackball.o + +include $(WXDIR)/src/makeprog.g95 + diff --git a/samples/opengl/penguin/makefile.unx b/samples/opengl/penguin/makefile.unx new file mode 100644 index 0000000000..c8d335c1bf --- /dev/null +++ b/samples/opengl/penguin/makefile.unx @@ -0,0 +1,21 @@ +# +# File: makefile.unx +# Author: Julian Smart +# Created: 1998 +# Updated: +# Copyright: (c) 1998 Julian Smart +# +# Makefile for penguin example (UNIX). + +PROGRAM=penguin + +OPENGLHOME=/home/jacs/mesa/Mesa-2.3 + +EXTRACPPFLAGS=-I$(OPENGLHOME)/include # -I../../motif +EXTRALDFLAGS=-L$(OPENGLHOME)/lib +EXTRALDLIBS=-lMesaGL -lMesaGLU + +OBJECTS=$(PROGRAM).o trackball.o lw.o + +include ../../../src/makeprog.env + diff --git a/samples/opengl/penguin/makefile.vc b/samples/opengl/penguin/makefile.vc new file mode 100644 index 0000000000..246fea6d3e --- /dev/null +++ b/samples/opengl/penguin/makefile.vc @@ -0,0 +1,30 @@ +# +# File: makefile.vc +# Author: Julian Smart +# Created: 1999 +# Updated: +# Copyright: (c) Julian Smart +# +# Makefile : Builds sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +# Set WXDIR for your system +WXDIR = $(WXWIN) + +!if "$(FINAL)" == "1" +!else +LIBEXT=_d +!endif + +PROGRAM=penguin +OBJECTS = $(PROGRAM).obj trackball.obj lw.obj +#EXTRAINC=-I..\..\win +EXTRALIBS=glu32.lib opengl32.lib + +!include $(WXDIR)\src\makeprog.vc + +lw.obj: lw.cpp lw.h + $(cc) @<< +$(CPPFLAGS2) /c $*.$(SRCSUFF) +<< + diff --git a/samples/opengl/penguin/makefile.wat b/samples/opengl/penguin/makefile.wat new file mode 100644 index 0000000000..c8a2f81645 --- /dev/null +++ b/samples/opengl/penguin/makefile.wat @@ -0,0 +1,17 @@ +# +# Makefile for WATCOM +# +# Created by Julian Smart, January 1999 +# +# + +WXDIR = $(%WXWIN) + +PROGRAM = penguin +OBJECTS = $(PROGRAM).obj +#EXTRALIBS=$(WXDIR)\lib\glcanvas.lib +#EXTRACPPFLAGS=-I$(WXDIR)\utils\glcanvas\win + +!include $(WXDIR)\src\makeprog.wat + + diff --git a/samples/opengl/penguin/penguin.cpp b/samples/opengl/penguin/penguin.cpp new file mode 100644 index 0000000000..8eaed6a1d9 --- /dev/null +++ b/samples/opengl/penguin/penguin.cpp @@ -0,0 +1,236 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: penguin.cpp +// Purpose: wxGLCanvas demo program +// Author: Robert Roebling +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation +#pragma interface +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "penguin.h" +#include + +#define VIEW_ASPECT 1.3 + +/* `Main program' equivalent, creating windows and returning main app frame */ +bool MyApp::OnInit(void) +{ + + /* Create the main frame window */ + MyFrame *frame = new MyFrame(NULL, "wxWindows OpenGL Demo", wxPoint(50, 50), wxSize(400, 300)); + + /* Make a menubar */ + wxMenu *fileMenu = new wxMenu; + + fileMenu->Append(wxID_EXIT, "E&xit"); + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(fileMenu, "&File"); + frame->SetMenuBar(menuBar); + + frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200)); + + /* Load file wiht mesh data */ + frame->m_canvas->LoadLWO( "penguin.lwo" ); + + /* Show the frame */ + frame->Show(TRUE); + + return TRUE; +} + +IMPLEMENT_APP(MyApp) + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU(wxID_EXIT, MyFrame::OnExit) +END_EVENT_TABLE() + +/* My frame constructor */ +MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, + const wxSize& size, long style): + wxFrame(frame, -1, title, pos, size, style) +{ + m_canvas = NULL; +} + +/* Intercept menu commands */ +void MyFrame::OnExit(wxCommandEvent& event) +{ + Destroy(); +} + +BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) + EVT_SIZE(TestGLCanvas::OnSize) + EVT_PAINT(TestGLCanvas::OnPaint) + EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground) + EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse) +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) +{ + block = FALSE; +} + +TestGLCanvas::~TestGLCanvas(void) +{ + /* destroy mesh */ + lw_object_free(info.lwobject); +} + +void TestGLCanvas::OnPaint( wxPaintEvent& event ) +{ + /* must always be here */ + wxPaintDC dc(this); + +#ifndef __WXMOTIF__ + if (!GetContext()) return; +#endif + + SetCurrent(); + + /* initialize OpenGL */ + if (info.do_init == TRUE) + { + InitGL(); + info.do_init = FALSE; + } + + /* view */ + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + gluPerspective( info.zoom, VIEW_ASPECT, 1, 100 ); + glMatrixMode( GL_MODELVIEW ); + + /* clear */ + glClearColor( .3, .4, .6, 1 ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + /* transformations */ + GLfloat m[4][4]; + glLoadIdentity(); + glTranslatef( 0, 0, -30 ); + build_rotmatrix( m,info.quat ); + glMultMatrixf( &m[0][0] ); + + /* draw object */ + lw_object_show( info.lwobject ); + + /* flush */ + glFlush(); + + /* swap */ + SwapBuffers(); +} + +void TestGLCanvas::OnSize(wxSizeEvent& event) +{ + int width, height; + GetClientSize(& width, & height); + +#ifndef __WXMOTIF__ + if (GetContext()) +#endif + { + SetCurrent(); + glViewport(0, 0, width, height); + } +} + +void TestGLCanvas::OnEraseBackground(wxEraseEvent& event) +{ + /* Do nothing, to avoid flashing on MSW */ +} + +void TestGLCanvas::LoadLWO(const wxString &filename) +{ + /* test if lightwave object */ + if (!lw_is_lwobject(filename)) return; + + /* read lightwave object */ + lwObject *lwobject = lw_object_read(filename); + + /* scale */ + lw_object_scale(lwobject, 10.0 / lw_object_radius(lwobject)); + + /* set up mesh info */ + info.do_init = TRUE; + info.lwobject = lwobject; + info.beginx = 0; + info.beginy = 0; + info.zoom = 45; + trackball( info.quat, 0.0, 0.0, 0.0, 0.0 ); +} + +void TestGLCanvas::OnMouse( wxMouseEvent& event ) +{ + wxSize sz(GetClientSize()); + if (event.Dragging()) + { + /* drag in progress, simulate trackball */ + float spin_quat[4]; + trackball(spin_quat, + (2.0*info.beginx - sz.x) / sz.x, + ( sz.y - 2.0*info.beginy) / sz.y, + ( 2.0*event.GetX() - sz.x) / sz.x, + ( sz.y - 2.0*event.GetY()) / sz.y); + + add_quats( spin_quat, info.quat, info.quat ); + + /* orientation has changed, redraw mesh */ + Refresh(FALSE); + } + + info.beginx = event.GetX(); + info.beginy = event.GetY(); +} + +void TestGLCanvas::InitGL(void) +{ + GLfloat light0_pos[4] = { -50.0, 50.0, 0.0, 0.0 }; + GLfloat light0_color[4] = { .6, .6, .6, 1.0 }; /* white light */ + GLfloat light1_pos[4] = { 50.0, 50.0, 0.0, 0.0 }; + GLfloat light1_color[4] = { .4, .4, 1, 1.0 }; /* cold blue light */ + + /* remove back faces */ + glDisable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + /* speedups */ + glEnable(GL_DITHER); + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); + + /* light */ + glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color); + glLightfv(GL_LIGHT1, GL_POSITION, light1_pos); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHTING); + + glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); +} + + diff --git a/samples/opengl/penguin/penguin.h b/samples/opengl/penguin/penguin.h new file mode 100644 index 0000000000..1730b2130f --- /dev/null +++ b/samples/opengl/penguin/penguin.h @@ -0,0 +1,84 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: penguin.h +// Purpose: wxGLCanvas demo program +// Author: Robert Roebling +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PENGUIN_H_ +#define _WX_PENGUIN_H_ + + +#include "wx/defs.h" +#include "wx/app.h" +#include "wx/menu.h" +#include "wx/dcclient.h" + +#include "wx/glcanvas.h" + +extern "C" { +#include "lw.h" +#include "trackball.h" +} + +/* information needed to display lightwave mesh */ +typedef struct +{ +// gint do_init; /* true if initgl not yet called */ + int do_init; + lwObject *lwobject; /* lightwave object mesh */ + float beginx,beginy; /* position of mouse */ + float quat[4]; /* orientation of object */ + float zoom; /* field of view in degrees */ +} mesh_info; + + +/* Define a new application type */ +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +/* Define a new frame type */ +class TestGLCanvas; +class MyFrame: public wxFrame +{ +public: + MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, + long style = wxDEFAULT_FRAME_STYLE); + + void OnExit(wxCommandEvent& event); +public: + TestGLCanvas* m_canvas; + +DECLARE_EVENT_TABLE() +}; + + +class TestGLCanvas: public wxGLCanvas +{ + public: + TestGLCanvas(wxWindow *parent, 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 LoadLWO( const wxString &filename); + void OnMouse( wxMouseEvent& event ); + void InitGL(void); + + mesh_info info; + bool block; + +DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/samples/opengl/penguin/penguin.lwo b/samples/opengl/penguin/penguin.lwo new file mode 100644 index 0000000000..3f5122db82 Binary files /dev/null and b/samples/opengl/penguin/penguin.lwo differ diff --git a/samples/opengl/penguin/penguin.rc b/samples/opengl/penguin/penguin.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/samples/opengl/penguin/penguin.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/samples/opengl/penguin/trackball.h b/samples/opengl/penguin/trackball.h new file mode 100644 index 0000000000..b676fb4e54 --- /dev/null +++ b/samples/opengl/penguin/trackball.h @@ -0,0 +1,78 @@ +/* + * (c) Copyright 1993, 1994, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(TM) is a trademark of Silicon Graphics, Inc. + */ +/* + * trackball.h + * A virtual trackball implementation + * Written by Gavin Bell for Silicon Graphics, November 1988. + */ + +/* + * Pass the x and y coordinates of the last and current positions of + * the mouse, scaled so they are from (-1.0 ... 1.0). + * + * The resulting rotation is returned as a quaternion rotation in the + * first paramater. + */ +void +trackball(float q[4], float p1x, float p1y, float p2x, float p2y); + +/* + * Given two quaternions, add them together to get a third quaternion. + * Adding quaternions to get a compound rotation is analagous to adding + * translations to get a compound translation. When incrementally + * adding rotations, the first argument here should be the new + * rotation, the second and third the total rotation (which will be + * over-written with the resulting new total rotation). + */ +void +add_quats(float *q1, float *q2, float *dest); + +/* + * A useful function, builds a rotation matrix in Matrix based on + * given quaternion. + */ +void +build_rotmatrix(float m[4][4], float q[4]); + +/* + * This function computes a quaternion based on an axis (defined by + * the given vector) and an angle about which to rotate. The angle is + * expressed in radians. The result is put into the third argument. + */ +void +axis_to_quat(float a[3], float phi, float q[4]); + diff --git a/src/generic/scrolwin.cpp b/src/generic/scrolwin.cpp index 1c28693778..ada5b1c236 100644 --- a/src/generic/scrolwin.cpp +++ b/src/generic/scrolwin.cpp @@ -85,6 +85,7 @@ wxScrolledWindow::wxScrolledWindow() m_yScrollLinesPerPage = 0; m_scaleX = 1.0; m_scaleY = 1.0; + m_targetWindow = (wxWindow*) NULL; } bool wxScrolledWindow::Create(wxWindow *parent, @@ -503,6 +504,9 @@ void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize) */ void wxScrolledWindow::Scroll( int x_pos, int y_pos ) { + if (!m_targetWindow) + return; + if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; diff --git a/src/gtk/glcanvas.cpp b/src/gtk/glcanvas.cpp new file mode 100644 index 0000000000..16c1cabe06 --- /dev/null +++ b/src/gtk/glcanvas.cpp @@ -0,0 +1,432 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.cpp +// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWindows and GTK +// Author: Robert Roebling +// Modified by: +// Created: 17/08/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "glcanvas.h" +#endif + +#include "wx/setup.h" + +#if wxUSE_GLCANVAS + +#include "wx/glcanvas.h" + +#include "wx/frame.h" +#include "wx/colour.h" +#include "wx/module.h" +#include "wx/app.h" + +extern "C" { +#include "gtk/gtk.h" +#include "gdk/gdk.h" +#include "gdk/gdkx.h" +} + +#include "wx/gtk/win_gtk.h" + +//--------------------------------------------------------------------------- +// global data +//--------------------------------------------------------------------------- + +XVisualInfo *g_vi = (XVisualInfo*) NULL; + +//----------------------------------------------------------------------------- +// idle system +//----------------------------------------------------------------------------- + +extern void wxapp_install_idle_handler(); +extern bool g_isIdle; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLContext,wxObject) + +wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) ) +{ + m_window = win; + m_widget = win->m_wxwindow; + + wxGLCanvas *gc = (wxGLCanvas*) win; + XVisualInfo *vi = (XVisualInfo *) gc->m_vi; + + wxCHECK_RET( vi, "invalid visual for OpenGl" ); + + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, None, GL_TRUE ); + + 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 = win->m_wxwindow; + + wxGLCanvas *gc = (wxGLCanvas*) win; + XVisualInfo *vi = (XVisualInfo *) gc->m_vi; + + wxCHECK_RET( vi, "invalid visual for OpenGl" ); + + if( other != 0 ) + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, other->m_glContext, GL_TRUE ); + else + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, None, GL_TRUE ); + + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); +} + +wxGLContext::~wxGLContext() +{ + if (!m_glContext) return; + + if (m_glContext == glXGetCurrentContext()) + { + glXMakeCurrent( GDK_DISPLAY(), None, NULL); + } + + glXDestroyContext( GDK_DISPLAY(), m_glContext ); +} + +void wxGLContext::SwapBuffers() +{ + if (m_glContext) + { + GdkWindow *window = GTK_PIZZA(m_widget)->bin_window; + glXSwapBuffers( GDK_DISPLAY(), GDK_WINDOW_XWINDOW( window ) ); + } +} + +void wxGLContext::SetCurrent() +{ + if (m_glContext) + { + GdkWindow *window = GTK_PIZZA(m_widget)->bin_window; + glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window), m_glContext ); + } +} + +void wxGLContext::SetColour(const char *colour) +{ + float r = 0.0; + float g = 0.0; + float b = 0.0; + wxColour *col = wxTheColourDatabase->FindColour(colour); + if (col) + { + r = (float)(col->Red()/256.0); + g = (float)(col->Green()/256.0); + b = (float)(col->Blue()/256.0); + glColor3f( r, g, b); + } +} + +void wxGLContext::SetupPixelFormat() +{ +} + +void wxGLContext::SetupPalette( const wxPalette& WXUNUSED(palette) ) +{ +} + +wxPalette wxGLContext::CreateDefaultPalette() +{ + return wxNullPalette; +} + +//----------------------------------------------------------------------------- +// "realize" from m_wxwindow +//----------------------------------------------------------------------------- + +static gint +gtk_glwindow_realized_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win ) +{ + wxGLContext *share= win->m_sharedContext; + if (share==NULL && win->m_sharedContextOf) share=win->m_sharedContextOf->GetContext(); + + win->m_glContext = new wxGLContext( TRUE, win, wxNullPalette, share ); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "map" from m_wxwindow +//----------------------------------------------------------------------------- + +static gint +gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win ) +{ + if (win->m_glContext/* && win->m_exposed*/) + { + wxPaintEvent event( win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + + win->m_exposed = FALSE; + win->GetUpdateRegion().Clear(); + } + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "expose_event" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + win->m_exposed = TRUE; + + win->GetUpdateRegion().Union( gdk_event->area.x, + gdk_event->area.y, + gdk_event->area.width, + gdk_event->area.height ); +} + +//----------------------------------------------------------------------------- +// "draw" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glwindow_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + win->m_exposed = TRUE; + + win->GetUpdateRegion().Union( rect->x, rect->y, + rect->width, rect->height ); +} + +//----------------------------------------------------------------------------- +// "size_allocate" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glcanvas_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (!win->m_hasVMT) + return; + + wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); +} + +//--------------------------------------------------------------------------- +// wxGlCanvas +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) + +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 *attribList, + const wxPalette& palette ) +{ + Create( parent, NULL, NULL, id, pos, size, style, name, attribList, 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 ) +{ + Create( parent, shared, NULL, id, pos, size, style, name, attribList, palette ); +} + +wxGLCanvas::wxGLCanvas( wxWindow *parent, + const wxGLCanvas *shared, + wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette ) +{ + Create( parent, NULL, shared, id, pos, size, style, name, attribList, palette ); +} + +bool wxGLCanvas::Create( wxWindow *parent, + const wxGLContext *shared, + const wxGLCanvas *shared_context_of, + wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette) +{ + m_sharedContext = (wxGLContext*)shared; // const_cast + m_sharedContextOf = (wxGLCanvas*)shared_context_of; // const_cast + m_glContext = (wxGLContext*) NULL; + + m_exposed = FALSE; + m_noExpose = TRUE; + m_nativeSizeEvent = TRUE; + + if (!attribList) + { + int data[] = { GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, // use largest available depth buffer + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 0, + None }; + attribList = (int*) data; + } + 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(); + + XVisualInfo *vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); + + m_vi = vi; // safe for later use + + wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); + + GdkVisual *visual = gdkx_visual_get( vi->visualid ); + GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); + + gtk_widget_push_colormap( colormap ); + gtk_widget_push_visual( visual ); + + wxScrolledWindow::Create( parent, id, pos, size, style, name ); + + m_glWidget = m_wxwindow; + + gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", + GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", + GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", + GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", + GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); + + gtk_widget_pop_visual(); + gtk_widget_pop_colormap(); + + return TRUE; +} + +wxGLCanvas::~wxGLCanvas() +{ + XVisualInfo *vi = (XVisualInfo *) m_vi; + + if (vi) XFree( vi ); + if (m_glContext) delete m_glContext; +} + +void wxGLCanvas::SwapBuffers() +{ + if (m_glContext) m_glContext->SwapBuffers(); +} + +void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event)) +{ + int width, height; + GetClientSize( &width, &height ); + + if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) ) + { + 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 ); + glMatrixMode(GL_MODELVIEW); + } +} + +void wxGLCanvas::SetCurrent() +{ + if (m_glContext) m_glContext->SetCurrent(); +} + +void wxGLCanvas::SetColour( const char *colour ) +{ + if (m_glContext) m_glContext->SetColour( colour ); +} + +void wxGLCanvas::OnInternalIdle() +{ + if (m_glContext && m_exposed) + { + wxPaintEvent event( GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + m_exposed = FALSE; + GetUpdateRegion().Clear(); + } + + wxWindow::OnInternalIdle(); +} + +#endif + // wxUSE_GLCANVAS + diff --git a/src/gtk1/glcanvas.cpp b/src/gtk1/glcanvas.cpp new file mode 100644 index 0000000000..16c1cabe06 --- /dev/null +++ b/src/gtk1/glcanvas.cpp @@ -0,0 +1,432 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.cpp +// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWindows and GTK +// Author: Robert Roebling +// Modified by: +// Created: 17/08/98 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "glcanvas.h" +#endif + +#include "wx/setup.h" + +#if wxUSE_GLCANVAS + +#include "wx/glcanvas.h" + +#include "wx/frame.h" +#include "wx/colour.h" +#include "wx/module.h" +#include "wx/app.h" + +extern "C" { +#include "gtk/gtk.h" +#include "gdk/gdk.h" +#include "gdk/gdkx.h" +} + +#include "wx/gtk/win_gtk.h" + +//--------------------------------------------------------------------------- +// global data +//--------------------------------------------------------------------------- + +XVisualInfo *g_vi = (XVisualInfo*) NULL; + +//----------------------------------------------------------------------------- +// idle system +//----------------------------------------------------------------------------- + +extern void wxapp_install_idle_handler(); +extern bool g_isIdle; + +//--------------------------------------------------------------------------- +// wxGLContext +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLContext,wxObject) + +wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) ) +{ + m_window = win; + m_widget = win->m_wxwindow; + + wxGLCanvas *gc = (wxGLCanvas*) win; + XVisualInfo *vi = (XVisualInfo *) gc->m_vi; + + wxCHECK_RET( vi, "invalid visual for OpenGl" ); + + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, None, GL_TRUE ); + + 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 = win->m_wxwindow; + + wxGLCanvas *gc = (wxGLCanvas*) win; + XVisualInfo *vi = (XVisualInfo *) gc->m_vi; + + wxCHECK_RET( vi, "invalid visual for OpenGl" ); + + if( other != 0 ) + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, other->m_glContext, GL_TRUE ); + else + m_glContext = glXCreateContext( GDK_DISPLAY(), vi, None, GL_TRUE ); + + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); +} + +wxGLContext::~wxGLContext() +{ + if (!m_glContext) return; + + if (m_glContext == glXGetCurrentContext()) + { + glXMakeCurrent( GDK_DISPLAY(), None, NULL); + } + + glXDestroyContext( GDK_DISPLAY(), m_glContext ); +} + +void wxGLContext::SwapBuffers() +{ + if (m_glContext) + { + GdkWindow *window = GTK_PIZZA(m_widget)->bin_window; + glXSwapBuffers( GDK_DISPLAY(), GDK_WINDOW_XWINDOW( window ) ); + } +} + +void wxGLContext::SetCurrent() +{ + if (m_glContext) + { + GdkWindow *window = GTK_PIZZA(m_widget)->bin_window; + glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window), m_glContext ); + } +} + +void wxGLContext::SetColour(const char *colour) +{ + float r = 0.0; + float g = 0.0; + float b = 0.0; + wxColour *col = wxTheColourDatabase->FindColour(colour); + if (col) + { + r = (float)(col->Red()/256.0); + g = (float)(col->Green()/256.0); + b = (float)(col->Blue()/256.0); + glColor3f( r, g, b); + } +} + +void wxGLContext::SetupPixelFormat() +{ +} + +void wxGLContext::SetupPalette( const wxPalette& WXUNUSED(palette) ) +{ +} + +wxPalette wxGLContext::CreateDefaultPalette() +{ + return wxNullPalette; +} + +//----------------------------------------------------------------------------- +// "realize" from m_wxwindow +//----------------------------------------------------------------------------- + +static gint +gtk_glwindow_realized_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win ) +{ + wxGLContext *share= win->m_sharedContext; + if (share==NULL && win->m_sharedContextOf) share=win->m_sharedContextOf->GetContext(); + + win->m_glContext = new wxGLContext( TRUE, win, wxNullPalette, share ); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "map" from m_wxwindow +//----------------------------------------------------------------------------- + +static gint +gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win ) +{ + if (win->m_glContext/* && win->m_exposed*/) + { + wxPaintEvent event( win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + + win->m_exposed = FALSE; + win->GetUpdateRegion().Clear(); + } + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "expose_event" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + win->m_exposed = TRUE; + + win->GetUpdateRegion().Union( gdk_event->area.x, + gdk_event->area.y, + gdk_event->area.width, + gdk_event->area.height ); +} + +//----------------------------------------------------------------------------- +// "draw" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glwindow_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + win->m_exposed = TRUE; + + win->GetUpdateRegion().Union( rect->x, rect->y, + rect->width, rect->height ); +} + +//----------------------------------------------------------------------------- +// "size_allocate" of m_wxwindow +//----------------------------------------------------------------------------- + +static void +gtk_glcanvas_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxGLCanvas *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (!win->m_hasVMT) + return; + + wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); +} + +//--------------------------------------------------------------------------- +// wxGlCanvas +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) + +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 *attribList, + const wxPalette& palette ) +{ + Create( parent, NULL, NULL, id, pos, size, style, name, attribList, 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 ) +{ + Create( parent, shared, NULL, id, pos, size, style, name, attribList, palette ); +} + +wxGLCanvas::wxGLCanvas( wxWindow *parent, + const wxGLCanvas *shared, + wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette ) +{ + Create( parent, NULL, shared, id, pos, size, style, name, attribList, palette ); +} + +bool wxGLCanvas::Create( wxWindow *parent, + const wxGLContext *shared, + const wxGLCanvas *shared_context_of, + wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette) +{ + m_sharedContext = (wxGLContext*)shared; // const_cast + m_sharedContextOf = (wxGLCanvas*)shared_context_of; // const_cast + m_glContext = (wxGLContext*) NULL; + + m_exposed = FALSE; + m_noExpose = TRUE; + m_nativeSizeEvent = TRUE; + + if (!attribList) + { + int data[] = { GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, // use largest available depth buffer + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 0, + None }; + attribList = (int*) data; + } + 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(); + + XVisualInfo *vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); + + m_vi = vi; // safe for later use + + wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); + + GdkVisual *visual = gdkx_visual_get( vi->visualid ); + GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); + + gtk_widget_push_colormap( colormap ); + gtk_widget_push_visual( visual ); + + wxScrolledWindow::Create( parent, id, pos, size, style, name ); + + m_glWidget = m_wxwindow; + + gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", + GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", + GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", + GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", + GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); + + gtk_widget_pop_visual(); + gtk_widget_pop_colormap(); + + return TRUE; +} + +wxGLCanvas::~wxGLCanvas() +{ + XVisualInfo *vi = (XVisualInfo *) m_vi; + + if (vi) XFree( vi ); + if (m_glContext) delete m_glContext; +} + +void wxGLCanvas::SwapBuffers() +{ + if (m_glContext) m_glContext->SwapBuffers(); +} + +void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event)) +{ + int width, height; + GetClientSize( &width, &height ); + + if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) ) + { + 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 ); + glMatrixMode(GL_MODELVIEW); + } +} + +void wxGLCanvas::SetCurrent() +{ + if (m_glContext) m_glContext->SetCurrent(); +} + +void wxGLCanvas::SetColour( const char *colour ) +{ + if (m_glContext) m_glContext->SetColour( colour ); +} + +void wxGLCanvas::OnInternalIdle() +{ + if (m_glContext && m_exposed) + { + wxPaintEvent event( GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + m_exposed = FALSE; + GetUpdateRegion().Clear(); + } + + wxWindow::OnInternalIdle(); +} + +#endif + // wxUSE_GLCANVAS + diff --git a/src/motif/glcanvas.cpp b/src/motif/glcanvas.cpp new file mode 100644 index 0000000000..1d5e2936a3 --- /dev/null +++ b/src/motif/glcanvas.cpp @@ -0,0 +1,168 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.cpp +// Purpose: wxGLCanvas, for using OpenGL with wxWindows 2.0 for Motif. +// Uses the GLX extension. +// Author: Julian Smart and Wolfram Gloger +// Modified by: +// Created: 1995, 1999 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart, Wolfram Gloger +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "glcanvas.h" +#endif + +#include "wx/setup.h" + +#if wxUSE_GLCANVAS + +#include "wx/glcanvas.h" +#include "wx/utils.h" +#include "wx/app.h" + +#include +#include "wx/motif/private.h" + +#ifdef OLD_MESA +// workaround for bug in Mesa's glx.c +static int bitcount( unsigned long n ) +{ + int bits; + for (bits=0; n>0;) { + if(n & 1) bits++; + n = n >> 1; + } + return bits; +} +#endif + +/* + * GLCanvas implementation + */ + +IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) + +wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos, + const wxSize& size, long style, + const wxString& name, int *attrib_list, const wxPalette& palette): + wxScrolledWindow(parent, id, pos, size, style, name) +{ + XVisualInfo *vi, vi_templ; + XWindowAttributes xwa; + int val, n; + + Display* display = (Display*) GetXDisplay(); + + glx_cx = 0; + // Check for the presence of the GLX extension + if(!glXQueryExtension(display, NULL, NULL)) { + wxDebugMsg("wxGLCanvas: GLX extension is missing\n"); + return; + } + + if(attrib_list) { + // Get an appropriate visual + vi = glXChooseVisual(display, DefaultScreen(display), attrib_list); + if(!vi) return; + + // Here we should make sure that vi is the same visual as the + // one used by the xwindow drawable in wxCanvas. However, + // there is currently no mechanism for this in wx_canvs.cc. + } else { + // By default, we use the visual of xwindow + XGetWindowAttributes(display, (Window) GetXWindow(), &xwa); + vi_templ.visualid = XVisualIDFromVisual(xwa.visual); + vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n); + if(!vi) return; + glXGetConfig(display, vi, GLX_USE_GL, &val); + if(!val) return; + // Basically, this is it. It should be possible to use vi + // in glXCreateContext() below. But this fails with Mesa. + // I notified the Mesa author about it; there may be a fix. +#ifdef OLD_MESA + // Construct an attribute list matching the visual + int a_list[32]; + n = 0; + if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual + a_list[n++] = GLX_RGBA; + a_list[n++] = GLX_RED_SIZE; + a_list[n++] = bitcount(vi->red_mask); + a_list[n++] = GLX_GREEN_SIZE; + a_list[n++] = bitcount(vi->green_mask); + a_list[n++] = GLX_BLUE_SIZE; + a_list[n++] = bitcount(vi->blue_mask); + glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val); + a_list[n++] = GLX_ALPHA_SIZE; + a_list[n++] = val; + } else { // Color index visual + glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val); + a_list[n++] = GLX_BUFFER_SIZE; + a_list[n++] = val; + } + a_list[n] = None; + XFree(vi); + vi = glXChooseVisual(display, DefaultScreen(display), a_list); + if(!vi) return; +#endif /* OLD_MESA */ + } + + // Create the GLX context and make it current + glx_cx = glXCreateContext(display, vi, 0, GL_TRUE); +#ifndef OLD_MESA + XFree(vi); +#endif + SetCurrent(); +} + +wxGLCanvas::~wxGLCanvas(void) +{ + Display* display = (Display*) GetXDisplay(); + if(glx_cx) glXDestroyContext(display, glx_cx); +} + +void wxGLCanvas::SwapBuffers() +{ + Display* display = (Display*) GetXDisplay(); + if(glx_cx) glXSwapBuffers(display, (Window) GetXWindow()); +} + +void wxGLCanvas::SetCurrent() +{ + Display* display = (Display*) GetXDisplay(); + if(glx_cx) glXMakeCurrent(display, (Window) GetXWindow(), glx_cx); +} + +void wxGLCanvas::SetColour(const char *col) +{ + wxColour *the_colour = wxTheColourDatabase->FindColour(col); + if(the_colour) { + GLboolean b; + glGetBooleanv(GL_RGBA_MODE, &b); + if(b) { + glColor3ub(the_colour->Red(), + the_colour->Green(), + the_colour->Blue()); + } else { + GLint pix = (GLint)the_colour->m_pixel; + if(pix == -1) { + XColor exact_def; + exact_def.red = (unsigned short)the_colour->Red() << 8; + exact_def.green = (unsigned short)the_colour->Green() << 8; + exact_def.blue = (unsigned short)the_colour->Blue() << 8; + exact_def.flags = DoRed | DoGreen | DoBlue; + if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) { + wxDebugMsg("wxGLCanvas: cannot allocate color\n"); + return; + } + pix = the_colour->m_pixel = exact_def.pixel; + } + glIndexi(pix); + } + } +} + +#endif + // wxUSE_GLCANVAS + diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp new file mode 100644 index 0000000000..dd49c13117 --- /dev/null +++ b/src/msw/glcanvas.cpp @@ -0,0 +1,624 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: glcanvas.cpp +// Purpose: wxGLCanvas, for using OpenGL with wxWindows under MS Windows +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "glcanvas.h" +#endif + +#include "wx/wxprec.h" + +#if defined(__BORLANDC__) +#pragma hdrstop +#endif + +#include + +#if wxUSE_GLCANVAS + +#ifndef WX_PRECOMP +#include +#endif + +#include + +#include + +wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass"); + +LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + +/* + * GLContext implementation + */ + +wxGLContext::wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette) +{ + m_window = win; + + 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); + } +} + +void wxGLContext::SwapBuffers() +{ + if (m_glContext) + { + wglMakeCurrent((HDC) m_hDC, m_glContext); + ::SwapBuffers((HDC) m_hDC); //blits the backbuffer into DC + } +} + +void wxGLContext::SetCurrent() +{ + if (m_glContext) + { + wglMakeCurrent((HDC) m_hDC, m_glContext); + } + +/* + setupPixelFormat(hDC); + setupPalette(hDC); +*/ +} + +void wxGLContext::SetColour(const char *colour) +{ + float r = 0.0; + float g = 0.0; + float b = 0.0; + wxColour *col = wxTheColourDatabase->FindColour(colour); + if (col) + { + r = (float)(col->Red()/256.0); + g = (float)(col->Green()/256.0); + b = (float)(col->Blue()/256.0); + glColor3f( r, g, b); + } +} + + +/* + * 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() +{ + m_glContext = (wxGLContext*) NULL; + + bool ret = Create(parent, id, pos, size, style, name); + + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } + + 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() +{ + m_glContext = (wxGLContext*) NULL; + + bool ret = Create(parent, id, pos, size, style, name); + + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } + + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette, shared ); +} + +// Not very usefull for wxMSW, but this is to be wxGTK compliant + +wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, + int *attribList, const wxPalette& palette ): + wxScrolledWindow() +{ + m_glContext = (wxGLContext*) NULL; + + bool ret = Create(parent, id, pos, size, style, name); + + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } + + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + wxGLContext *sharedContext=0; + if (shared) sharedContext=shared->GetContext(); + m_glContext = new wxGLContext(TRUE, this, palette, sharedContext ); +} + +wxGLCanvas::~wxGLCanvas() +{ + if (m_glContext) + delete m_glContext; + + ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); +} + +// Replaces wxWindow::Create functionality, since we need to use a different window class +bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name) +{ + static bool registeredGLCanvasClass = FALSE; + + // We have to register a special window class because we need + // the CS_OWNDC style for GLCanvas. + +/* + From Angel Popov + + Here are two snips from a dicussion in the OpenGL Gamedev list that explains + how this problem can be fixed: + + "There are 5 common DCs available in Win95. These are aquired when you call + GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. + OWNDC flagged windows do not get their DC from the common DC pool, the issue + is they require 800 bytes each from the limited 64Kb local heap for GDI." + + "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps + do), Win95 will actually "steal" it from you. MakeCurrent fails, + apparently, because Windows re-assigns the HDC to a different window. The + only way to prevent this, the only reliable means, is to set CS_OWNDC." +*/ + + if (!registeredGLCanvasClass) + { + WNDCLASS wndclass; + + static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; + + // the fields which are common to all classes + wndclass.lpfnWndProc = (WNDPROC)wxWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for? + wndclass.hInstance = wxhInstance; + wndclass.hIcon = (HICON) NULL; + wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); + wndclass.lpszMenuName = NULL; + + // Register the GLCanvas class name + wndclass.hbrBackground = (HBRUSH)NULL; + wndclass.lpszClassName = wxGLCanvasClassName; + wndclass.style = styleNormal; + + if ( !RegisterClass(&wndclass) ) + { + wxLogLastError("RegisterClass(wxGLCanvasClass)"); + + return FALSE; + } + registeredGLCanvasClass = TRUE; + } + + wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); + + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; + + parent->AddChild(this); + + DWORD msflags = 0; + if ( style & wxBORDER ) + msflags |= WS_BORDER; + if ( style & wxTHICK_FRAME ) + msflags |= WS_THICKFRAME; + + msflags |= WS_CHILD | WS_VISIBLE; + if ( style & wxCLIP_CHILDREN ) + msflags |= WS_CLIPCHILDREN; + + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + { + msflags |= WS_BORDER; + } + + // calculate the value to return from WM_GETDLGCODE handler + if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + { + // want everything: i.e. all keys and WM_CHAR message + m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | + DLGC_WANTTAB | DLGC_WANTMESSAGE; + } + + MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, + pos.x, pos.y, + WidthDefault(size.x), HeightDefault(size.y), + msflags, NULL, exStyle); + + return TRUE; + +} + +void wxGLCanvas::SetupPixelFormat() // (HDC hDC) +{ + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; + int pixelFormat; + + pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); + if (pixelFormat == 0) { + MessageBox(WindowFromDC((HDC) m_hDC), "ChoosePixelFormat failed.", "Error", + MB_ICONERROR | MB_OK); + exit(1); + } + + if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { + MessageBox(WindowFromDC((HDC) m_hDC), "SetPixelFormat failed.", "Error", + MB_ICONERROR | MB_OK); + exit(1); + } +} + +void wxGLCanvas::SetupPalette(const wxPalette& palette) +{ + int pixelFormat = GetPixelFormat((HDC) m_hDC); + PIXELFORMATDESCRIPTOR pfd; + + DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + if (pfd.dwFlags & PFD_NEED_PALETTE) + { + } + else + { + return; + } + + m_palette = palette; + + if ( !m_palette.Ok() ) + { + m_palette = CreateDefaultPalette(); + } + + if (m_palette.Ok()) + { + SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE); + RealizePalette((HDC) m_hDC); + } +} + +wxPalette wxGLCanvas::CreateDefaultPalette() +{ + PIXELFORMATDESCRIPTOR pfd; + int paletteSize; + int pixelFormat = GetPixelFormat((HDC) m_hDC); + + DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + paletteSize = 1 << pfd.cColorBits; + + LOGPALETTE* pPal = + (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY)); + pPal->palVersion = 0x300; + pPal->palNumEntries = paletteSize; + + /* build a simple RGB color palette */ + { + int redMask = (1 << pfd.cRedBits) - 1; + int greenMask = (1 << pfd.cGreenBits) - 1; + int blueMask = (1 << pfd.cBlueBits) - 1; + int i; + + for (i=0; ipalPalEntry[i].peRed = + (((i >> pfd.cRedShift) & redMask) * 255) / redMask; + pPal->palPalEntry[i].peGreen = + (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; + pPal->palPalEntry[i].peBlue = + (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; + pPal->palPalEntry[i].peFlags = 0; + } + } + + HPALETTE hPalette = CreatePalette(pPal); + free(pPal); + + wxPalette palette; + palette.SetHPALETTE((WXHPALETTE) hPalette); + + return palette; +} + +void wxGLCanvas::SwapBuffers() +{ + if (m_glContext) + m_glContext->SwapBuffers(); +} + +void wxGLCanvas::OnSize(wxSizeEvent& event) +{ + int width, height; + GetClientSize(& width, & height); + + if (m_glContext) + { + m_glContext->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 ); + glMatrixMode(GL_MODELVIEW); + } +} + +void wxGLCanvas::SetCurrent() +{ + if (m_glContext) + { + m_glContext->SetCurrent(); + } +} + +void wxGLCanvas::SetColour(const char *colour) +{ + if (m_glContext) + m_glContext->SetColour(colour); +} + +// TODO: Have to have this called by parent frame (?) +// So we need wxFrame to call OnQueryNewPalette for all children... +void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) +{ + /* realize palette if this is the current window */ + if ( GetPalette()->Ok() ) { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); + Refresh(); + event.SetPaletteRealized(TRUE); + } + else + event.SetPaletteRealized(FALSE); +} + +// I think this doesn't have to be propagated to child windows. +void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) +{ + /* realize palette if this is *not* the current window */ + if ( GetPalette() && + GetPalette()->Ok() && (this != event.GetChangedWindow()) ) + { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); + Refresh(); + } +} + +/* Give extensions proper function names. */ + +/* EXT_vertex_array */ +void glArrayElementEXT(GLint i) +{ +} + +void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) +{ +} + +void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count) +{ +#ifdef GL_EXT_vertex_array + static PFNGLDRAWARRAYSEXTPROC proc = 0; + + if ( !proc ) + { + proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT"); + } + + if ( proc ) + (* proc) (mode, first, count); +#endif +} + +void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer) +{ +} + +void glGetPointervEXT(GLenum pname, GLvoid* *params) +{ +} + +void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) +{ +} + +void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) +{ +#ifdef GL_EXT_vertex_array + static PFNGLNORMALPOINTEREXTPROC proc = 0; + + if ( !proc ) + { + proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT"); + } + + if ( proc ) + (* proc) (type, stride, count, pointer); +#endif +} + +void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) +{ +} + +void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) +{ +#ifdef GL_EXT_vertex_array + static PFNGLVERTEXPOINTEREXTPROC proc = 0; + + if ( !proc ) + { + proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT"); + } + + if ( proc ) + (* proc) (size, type, stride, count, pointer); +#endif +} + +/* EXT_color_subtable */ +void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table) +{ +} + +/* EXT_color_table */ +void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) +{ +} + +void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) +{ +} + +void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table) +{ +} + +void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params) +{ +} + +void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params) +{ +} + +/* SGI_compiled_vertex_array */ +void glLockArraysSGI(GLint first, GLsizei count) +{ +} + +void glUnlockArraysSGI() +{ +} + + +/* SGI_cull_vertex */ +void glCullParameterdvSGI(GLenum pname, GLdouble* params) +{ +} + +void glCullParameterfvSGI(GLenum pname, GLfloat* params) +{ +} + +/* SGI_index_func */ +void glIndexFuncSGI(GLenum func, GLclampf ref) +{ +} + +/* SGI_index_material */ +void glIndexMaterialSGI(GLenum face, GLenum mode) +{ +} + +/* WIN_swap_hint */ +void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height) +{ +} + +#endif + // wxUSE_GLCANVAS diff --git a/src/msw/makefile.b32 b/src/msw/makefile.b32 index 908733e039..5259b6be0a 100644 --- a/src/msw/makefile.b32 +++ b/src/msw/makefile.b32 @@ -1,6 +1,6 @@ -# This file was automatically generated by tmake at 18:32, 2000/02/17 +# This file was automatically generated by tmake at 15:17, 2000/02/27 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE B32.T! # @@ -257,6 +257,7 @@ MSWOBJS = $(MSWDIR)\accel.obj \ $(MSWDIR)\gauge95.obj \ $(MSWDIR)\gdiimage.obj \ $(MSWDIR)\gdiobj.obj \ + $(MSWDIR)\glcanvas.obj \ $(MSWDIR)\gsocket.obj \ $(MSWDIR)\helpwin.obj \ $(MSWDIR)\icon.obj \ @@ -469,6 +470,8 @@ $(MSWDIR)\gdiimage.obj: $(MSWDIR)\gdiimage.$(SRCSUFF) $(MSWDIR)\gdiobj.obj: $(MSWDIR)\gdiobj.$(SRCSUFF) +$(MSWDIR)\glcanvas.obj: $(MSWDIR)\glcanvas.$(SRCSUFF) + $(MSWDIR)\gsocket.obj: $(MSWDIR)\gsocket.c $(MSWDIR)\helpwin.obj: $(MSWDIR)\helpwin.$(SRCSUFF) diff --git a/src/msw/makefile.bcc b/src/msw/makefile.bcc index c60cbc60b8..161d261176 100644 --- a/src/msw/makefile.bcc +++ b/src/msw/makefile.bcc @@ -1,6 +1,6 @@ -# This file was automatically generated by tmake at 18:32, 2000/02/17 +# This file was automatically generated by tmake at 15:18, 2000/02/27 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE BCC.T! # @@ -226,6 +226,7 @@ MSWOBJS = $(MSWDIR)\accel.obj \ $(MSWDIR)\gaugemsw.obj \ $(MSWDIR)\gdiimage.obj \ $(MSWDIR)\gdiobj.obj \ + $(MSWDIR)\glcanvas.obj \ $(MSWDIR)\gsocket.obj \ $(MSWDIR)\helpwin.obj \ $(MSWDIR)\icon.obj \ @@ -378,6 +379,8 @@ $(MSWDIR)\gdiimage.obj: $(MSWDIR)\gdiimage.$(SRCSUFF) $(MSWDIR)\gdiobj.obj: $(MSWDIR)\gdiobj.$(SRCSUFF) +$(MSWDIR)\glcanvas.obj: $(MSWDIR)\glcanvas.$(SRCSUFF) + $(MSWDIR)\gsocket.obj: $(MSWDIR)\gsocket.c $(MSWDIR)\helpwin.obj: $(MSWDIR)\helpwin.$(SRCSUFF) diff --git a/src/msw/makefile.g95 b/src/msw/makefile.g95 index a8e77fbb68..0762df0d7c 100644 --- a/src/msw/makefile.g95 +++ b/src/msw/makefile.g95 @@ -255,6 +255,7 @@ MSWOBJS = \ $(MSWDIR)/gauge95.$(OBJSUFF) \ $(MSWDIR)/gdiimage.$(OBJSUFF) \ $(MSWDIR)/gdiobj.$(OBJSUFF) \ + $(MSWDIR)/glcanvas.$(OBJSUFF) \ $(MSWDIR)/gsocket.$(OBJSUFF) \ $(MSWDIR)/helpwin.$(OBJSUFF) \ $(MSWDIR)/icon.$(OBJSUFF) \ diff --git a/src/msw/makefile.vc b/src/msw/makefile.vc index e555f8b83c..3ceaa58c47 100644 --- a/src/msw/makefile.vc +++ b/src/msw/makefile.vc @@ -1,4 +1,4 @@ -# This file was automatically generated by tmake at 18:32, 2000/02/17 +# This file was automatically generated by tmake at 15:17, 2000/02/27 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE VC.T! # File: makefile.vc @@ -274,6 +274,7 @@ MSWOBJS = ..\msw\$D\accel.obj \ ..\msw\$D\gauge95.obj \ ..\msw\$D\gdiimage.obj \ ..\msw\$D\gdiobj.obj \ + ..\msw\$D\glcanvas.obj \ ..\msw\$D\gsocket.obj \ ..\msw\$D\helpwin.obj \ ..\msw\$D\icon.obj \ diff --git a/src/msw/makefile.wat b/src/msw/makefile.wat index e13fc89232..c2a5bc5448 100644 --- a/src/msw/makefile.wat +++ b/src/msw/makefile.wat @@ -1,6 +1,6 @@ #!/binb/wmake.exe -# This file was automatically generated by tmake at 18:32, 2000/02/17 +# This file was automatically generated by tmake at 15:18, 2000/02/27 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE WAT.T! # @@ -230,6 +230,7 @@ MSWOBJS = accel.obj & gaugemsw.obj & gdiimage.obj & gdiobj.obj & + glcanvas.obj & gsocket.obj & helpwin.obj & icon.obj & @@ -450,6 +451,9 @@ gdiimage.obj: $(MSWDIR)\gdiimage.cpp gdiobj.obj: $(MSWDIR)\gdiobj.cpp *$(CCC) $(CPPFLAGS) $(IFLAGS) $< +glcanvas.obj: $(MSWDIR)\glcanvas.cpp + *$(CCC) $(CPPFLAGS) $(IFLAGS) $< + gsocket.obj: $(MSWDIR)\gsocket.c *$(CC) $(CPPFLAGS) $(IFLAGS) $< diff --git a/src/wxvc.dsp b/src/wxvc.dsp index 6c87170f6c..b95508cacb 100644 --- a/src/wxvc.dsp +++ b/src/wxvc.dsp @@ -853,6 +853,10 @@ SOURCE=.\msw\gdiobj.cpp # End Source File # Begin Source File +SOURCE=.\msw\glcanvas.cpp +# End Source File +# Begin Source File + SOURCE=.\msw\gsocket.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff --git a/src/wxvc_dll.dsp b/src/wxvc_dll.dsp index edacc9f9f9..ee66692879 100644 --- a/src/wxvc_dll.dsp +++ b/src/wxvc_dll.dsp @@ -851,6 +851,10 @@ SOURCE=.\msw\gdiobj.cpp # End Source File # Begin Source File +SOURCE=.\msw\glcanvas.cpp +# End Source File +# Begin Source File + SOURCE=.\msw\gsocket.c # SUBTRACT CPP /YX /Yc /Yu # End Source File diff --git a/utils/projgen/makeproj.cpp b/utils/projgen/makeproj.cpp index fa66425fe4..c8a377f17b 100644 --- a/utils/projgen/makeproj.cpp +++ b/utils/projgen/makeproj.cpp @@ -183,6 +183,7 @@ bool MyApp::GenerateSample(const wxString& projectName, const wxString& targetNa project.SetLibDirs(wxStringList((const char*) relativeLibPath, 0)); project.SetDebugLibDirs(wxStringList((const char*) relativeDebugPath, (const char*) relativeDebugPathJPEG, (const char*) relativeDebugPathTIFF, 0)); project.SetReleaseLibDirs(wxStringList((const char*) relativeReleasePath, (const char*) relativeReleasePathJPEG, (const char*) relativeReleasePathTIFF, 0)); + project.SetExtraLibs(wxStringList("opengl32.lib", "glu32.lib", 0)); project.SetProjectName(projectName); project.SetTargetName(targetName); @@ -228,6 +229,14 @@ void MyApp::GenerateSamples(const wxString& dir) GenerateSample("NewGridVC", "griddemo", dir + wxString("/samples/newgrid"), wxStringList("griddemo.cpp", 0)); GenerateSample("HelpVC", "demo", dir + wxString("/samples/help"), wxStringList("demo.cpp", 0)); + // OpenGL samples + GenerateSample("CubeVC", "cube", dir + wxString("/samples/opengl/cube"), wxStringList("cube.cpp", "cube.h", 0), + "../../.."); + GenerateSample("IsosurfVC", "isosurf", dir + wxString("/samples/opengl/isosurf"), wxStringList("isosurf.cpp", "isousrf.h", 0), + "../../.."); + GenerateSample("PenguinVC", "penguin", dir + wxString("/samples/opengl/penguin"), wxStringList("penguin.cpp", "penguin.h", + "lw.cpp", "lw.h", "trackball.c", "trackball.h", 0), "../../.."); + // wxHTML samples GenerateSample("AboutVC", "about", dir + wxString("/samples/html/about"), wxStringList("about.cpp", 0), "../../.."); @@ -488,72 +497,6 @@ void MyApp::GenerateSamples(const wxString& dir) wxString msg("Could not generate OGL Studio project"); wxMessageBox(msg); } - - // GLCanvas cube sample - - project.SetIncludeDirs(wxStringList("../../../../include", "../../win", 0)); - project.SetResourceIncludeDirs(wxStringList("../../../../include", 0)); - project.SetLibDirs(wxStringList("../../../../lib", 0)); - project.SetDebugLibDirs(wxStringList("../../../../src/Debug", "../../win/Debug", "../../../../src/jpeg/Debug", "../../../../src/tiff/Debug", 0)); - project.SetReleaseLibDirs(wxStringList("../../../../src/Release", "../../win/Release", "../../../../src/jpeg/Release", "../../../../src/tiff/Release", 0)); - - project.SetExtraLibs(wxStringList("glcanvas.lib", "opengl32.lib", "glu32.lib", 0)); - - project.SetProjectName("CubeVC"); - project.SetTargetName("cube"); - project.SetProjectPath(dir + wxString("/utils/glcanvas/samples/cube")); - project.SetSourceFiles(wxStringList("cube.cpp", "cube.h", - 0)); - - if (!project.GenerateVCProject()) - { - wxString msg("Could not generate GLCanvas Cube project"); - wxMessageBox(msg); - } - - // GLCanvas isosurf sample - - project.SetIncludeDirs(wxStringList("../../../../include", "../../win", 0)); - project.SetResourceIncludeDirs(wxStringList("../../../../include", 0)); - project.SetLibDirs(wxStringList("../../../../lib", 0)); - project.SetDebugLibDirs(wxStringList("../../../../src/Debug", "../../win/Debug", "../../../../src/jpeg/Debug", "../../../../src/tiff/Debug", 0)); - project.SetReleaseLibDirs(wxStringList("../../../../src/Release", "../../win/Release", "../../../../src/jpeg/Release", "../../../../src/tiff/Release", 0)); - project.SetExtraLibs(wxStringList("glcanvas.lib", "opengl32.lib", "glu32.lib", 0)); - - project.SetProjectName("IsoSurfVC"); - project.SetTargetName("isosurf"); - project.SetProjectPath(dir + wxString("/utils/glcanvas/samples/isosurf")); - project.SetSourceFiles(wxStringList("isosurf.cpp", "isosurf.h", - 0)); - - if (!project.GenerateVCProject()) - { - wxString msg("Could not generate GLCanvas IsoSurf project"); - wxMessageBox(msg); - } - - // GLCanvas penguin sample - - project.SetIncludeDirs(wxStringList("../../../../include", "../../win", 0)); - project.SetResourceIncludeDirs(wxStringList("../../../../include", 0)); - project.SetLibDirs(wxStringList("../../../../lib", 0)); - project.SetDebugLibDirs(wxStringList("../../../../src/Debug", "../../win/Debug", "../../../../src/jpeg/Debug", "../../../../src/tiff/Debug", 0)); - project.SetReleaseLibDirs(wxStringList("../../../../src/Release", "../../win/Release", "../../../../src/jpeg/Release", "../../../../src/tiff/Release", 0)); - project.SetExtraLibs(wxStringList("glcanvas.lib", "opengl32.lib", "glu32.lib", 0)); - - project.SetProjectName("PenguinVC"); - project.SetTargetName("penguin"); - project.SetProjectPath(dir + wxString("/utils/glcanvas/samples/penguin")); - project.SetSourceFiles(wxStringList("penguin.cpp", "penguin.h", - "lw.cpp", "lw.h", - "trackball.c", "trackball.h", - 0)); - - if (!project.GenerateVCProject()) - { - wxString msg("Could not generate GLCanvas Penguin project"); - wxMessageBox(msg); - } } // ----------------------------------------------------------------------------