Files
wxWidgets/samples/opengl/cube/cube.cpp
Vadim Zeitlin 43c742d005 1. switched to new wxGLCanvas API (not using the implicit context)
2. pruned everything not related to OpenGL, making the remaining code much
   more readable
3. show using the same wxGLContext with multiple wxGLCanvases


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45369 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2007-04-09 22:54:40 +00:00

275 lines
6.8 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: cube.cpp
// Purpose: wxGLCanvas demo program
// Author: Julian Smart
// Modified by: Vadim Zeitlin to use new wxGLCanvas API (2007-04-09)
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// 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
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
#include "cube.h"
#if !defined(__WXMSW__) && !defined(__WXPM__)
#include "../../sample.xpm"
#endif
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// MyApp: the application object
// ----------------------------------------------------------------------------
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
// Create the main window
new MyFrame();
return true;
}
int MyApp::OnExit()
{
delete m_glContext;
return wxApp::OnExit();
}
void MyApp::SetCurrent(wxGLCanvas *canvas)
{
wxCHECK_RET( canvas, _T("canvas can't be NULL") );
if ( !m_glContext )
m_glContext = new wxGLContext(canvas);
m_glContext->SetCurrent(*canvas);
}
// ----------------------------------------------------------------------------
// TestGLCanvas
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_SIZE(TestGLCanvas::OnSize)
EVT_PAINT(TestGLCanvas::OnPaint)
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
END_EVENT_TABLE()
static /* const */ int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
TestGLCanvas::TestGLCanvas(wxWindow *parent)
: wxGLCanvas(parent, wxID_ANY, attribs)
{
InitGL();
}
// this function is called on each repaint so it should be fast
void TestGLCanvas::Render()
{
wxGetApp().SetCurrent(this);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glCallList(m_gllist);
glFlush();
SwapBuffers();
}
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
Render();
}
void TestGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
{
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
int w, h;
GetClientSize(&w, &h);
wxGetApp().SetCurrent(this);
glViewport(0, 0, w, h);
}
void TestGLCanvas::InitGL()
{
wxGetApp().SetCurrent(this);
/* set viewing projection */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 3.0f);
/* position viewer */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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);
// create the list of commands to draw the cube: then we can just (quickly)
// execute it in Render() later
m_gllist = glGenLists(1);
glNewList(m_gllist, GL_COMPILE);
/* 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();
}
void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
{
GLfloat x = 0,
y = 0,
z = 0;
bool inverse = false;
switch ( event.GetKeyCode() )
{
case WXK_RIGHT:
inverse = true;
// fall through
case WXK_LEFT:
// rotate around Z axis
z = 1;
break;
case WXK_DOWN:
inverse = true;
// fall through
case WXK_UP:
// rotate around Y axis
y = 1;
break;
default:
event.Skip();
return;
}
float angle = 5;
if ( inverse )
angle = -angle;
wxGetApp().SetCurrent(this);
glMatrixMode(GL_MODELVIEW);
glRotatef(angle, x, y, z);
// refresh all cubes
for ( wxWindowList::const_iterator i = wxTopLevelWindows.begin();
i != wxTopLevelWindows.end();
++i )
{
(*i)->Refresh(false);
}
}
// ----------------------------------------------------------------------------
// MyFrame: main application window
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
EVT_MENU(wxID_NEW, MyFrame::OnNewWindow)
END_EVENT_TABLE()
MyFrame::MyFrame()
: wxFrame(NULL, wxID_ANY, _T("wxWidgets OpenGL Cube Sample"),
wxDefaultPosition, wxSize(400, 300))
{
m_canvas = new TestGLCanvas(this);
SetIcon(wxICON(sample));
// Make a menubar
wxMenu *winMenu = new wxMenu;
winMenu->Append(wxID_EXIT, _T("&Close"));
winMenu->Append(wxID_NEW, _T("&New") );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(winMenu, _T("&Window"));
SetMenuBar(menuBar);
Show();
}
void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) )
{
// true is to force the frame to close
Close(true);
}
void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) )
{
(void) new MyFrame();
}