📄 glcanvas.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: src/mac/classic/glcanvas.cpp
// Purpose: wxGLCanvas, for using OpenGL with wxWidgets under Macintosh
// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
// RCS-ID: $Id: glcanvas.cpp,v 1.7 2006/05/24 07:16:09 ABX Exp $
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if defined(__BORLANDC__)
#pragma hdrstop
#endif
#if wxUSE_GLCANVAS
#include "wx/glcanvas.h"
#ifndef WX_PRECOMP
#include "wx/frame.h"
#include "wx/log.h"
#include "wx/settings.h"
#endif
#include "wx/mac/uma.h"
// DLL options compatibility check:
#include "wx/build.h"
WX_CHECK_BUILD_OPTIONS("wxGL")
/*
* GLContext implementation
*/
wxGLContext::wxGLContext(
AGLPixelFormat fmt, wxGLCanvas *win,
const wxPalette& palette,
const wxGLContext *other /* for sharing display lists */
)
{
m_window = win;
m_drawable = (AGLDrawable) UMAGetWindowPort(MAC_WXHWND(win->MacGetRootWindow()));
m_glContext = aglCreateContext(fmt, other ? other->m_glContext : NULL);
wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
GLboolean b;
b = aglSetDrawable(m_glContext, m_drawable);
wxCHECK_RET( b, wxT("Couldn't bind OpenGl context") );
aglEnable(m_glContext , AGL_BUFFER_RECT ) ;
b = aglSetCurrentContext(m_glContext);
wxCHECK_RET( b, wxT("Couldn't activate OpenGl context") );
}
wxGLContext::~wxGLContext()
{
if (m_glContext)
{
aglSetCurrentContext(NULL);
aglDestroyContext(m_glContext);
}
}
void wxGLContext::SwapBuffers()
{
if (m_glContext)
{
aglSwapBuffers(m_glContext);
}
}
void wxGLContext::SetCurrent()
{
if (m_glContext)
{
aglSetCurrentContext(m_glContext);
}
}
void wxGLContext::Update()
{
if (m_glContext)
{
aglUpdateContext(m_glContext);
}
}
void wxGLContext::SetColour(const wxChar *colour)
{
wxColour col = wxTheColourDatabase->Find(colour);
if (col.Ok())
{
float r = (float)(col.Red()/256.0);
float g = (float)(col.Green()/256.0);
float b = (float)(col.Blue()/256.0);
glColor3f( r, g, b);
}
}
/*
* wxGLCanvas implementation
*/
IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
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, 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, 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, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette);
}
wxGLCanvas::~wxGLCanvas()
{
if (m_glContext != NULL) {
delete m_glContext;
m_glContext = NULL;
}
}
static AGLPixelFormat ChoosePixelFormat(const int *attribList)
{
GLint data[512];
GLint defaultAttribs[] = { AGL_RGBA,
AGL_DOUBLEBUFFER,
AGL_MINIMUM_POLICY,
AGL_DEPTH_SIZE, 1, // use largest available depth buffer
AGL_RED_SIZE, 1,
AGL_GREEN_SIZE, 1,
AGL_BLUE_SIZE, 1,
AGL_ALPHA_SIZE, 0,
AGL_NONE };
GLint *attribs;
if (!attribList)
{
attribs = defaultAttribs;
}
else
{
int arg=0, p=0;
data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
while( (attribList[arg]!=0) && (p<512) )
{
switch( attribList[arg++] )
{
case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
case WX_GL_BUFFER_SIZE:
data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_LEVEL:
data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
case WX_GL_AUX_BUFFERS:
data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_RED:
data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_GREEN:
data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_BLUE:
data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_ALPHA:
data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_DEPTH_SIZE:
data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_STENCIL_SIZE:
data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_ACCUM_RED:
data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_ACCUM_GREEN:
data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_ACCUM_BLUE:
data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
case WX_GL_MIN_ACCUM_ALPHA:
data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
default:
break;
}
}
data[p] = 0;
attribs = data;
}
return aglChoosePixelFormat(NULL, 0, attribs);
}
bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style, const wxString& name,
int *attribList, const wxPalette& palette)
{
wxWindow::Create( parent, id, pos, size, style, name );
AGLPixelFormat fmt = ChoosePixelFormat(attribList);
wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") );
m_glContext = new wxGLContext(fmt, this, palette, shared);
m_macCanvasIsShown = true ;
aglDestroyPixelFormat(fmt);
return true;
}
void wxGLCanvas::SwapBuffers()
{
if (m_glContext)
m_glContext->SwapBuffers();
}
void wxGLCanvas::UpdateContext()
{
if (m_glContext)
m_glContext->Update();
}
void wxGLCanvas::SetViewport()
{
// viewport is initially set to entire port
// adjust glViewport to just this window
int x = 0 ;
int y = 0 ;
wxWindow* iter = this ;
while( iter->GetParent() )
{
iter = iter->GetParent() ;
}
if ( iter && iter->IsTopLevel() )
{
MacClientToRootWindow( &x , &y ) ;
int width, height;
GetClientSize(& width, & height);
Rect bounds ;
GetWindowPortBounds( MAC_WXHWND(MacGetRootWindow()) , &bounds ) ;
GLint parms[4] ;
parms[0] = x ;
parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
parms[2] = width ;
parms[3] = height ;
if ( !m_macCanvasIsShown )
parms[0] += 20000 ;
aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
}
}
void wxGLCanvas::OnSize(wxSizeEvent& event)
{
MacUpdateView() ;
}
void wxGLCanvas::MacUpdateView()
{
if (m_glContext)
{
UpdateContext();
m_glContext->SetCurrent();
SetViewport();
}
}
void wxGLCanvas::MacSuperChangedPosition()
{
MacUpdateView() ;
wxWindow::MacSuperChangedPosition() ;
}
void wxGLCanvas::MacTopLevelWindowChangedPosition()
{
MacUpdateView() ;
wxWindow::MacTopLevelWindowChangedPosition() ;
}
void wxGLCanvas::SetCurrent()
{
if (m_glContext)
{
m_glContext->SetCurrent();
}
}
void wxGLCanvas::SetColour(const wxChar *colour)
{
if (m_glContext)
m_glContext->SetColour(colour);
}
bool wxGLCanvas::Show(bool show)
{
if ( !wxWindow::Show( show ) )
return false ;
if ( !show )
{
if ( m_macCanvasIsShown )
{
m_macCanvasIsShown = false ;
SetViewport() ;
}
}
else
{
if ( MacIsReallyShown() && !m_macCanvasIsShown )
{
m_macCanvasIsShown = true ;
SetViewport() ;
}
}
return true ;
}
void wxGLCanvas::MacSuperShown( bool show )
{
if ( !show )
{
if ( m_macCanvasIsShown )
{
m_macCanvasIsShown = false ;
SetViewport() ;
}
}
else
{
if ( MacIsReallyShown() && !m_macCanvasIsShown )
{
m_macCanvasIsShown = true ;
SetViewport() ;
}
}
wxWindow::MacSuperShown( show ) ;
}
//---------------------------------------------------------------------------
// wxGLApp
//---------------------------------------------------------------------------
IMPLEMENT_CLASS(wxGLApp, wxApp)
bool wxGLApp::InitGLVisual(int *attribList)
{
AGLPixelFormat fmt = ChoosePixelFormat(attribList);
if (fmt != NULL) {
aglDestroyPixelFormat(fmt);
return true;
} else
return false;
}
wxGLApp::~wxGLApp(void)
{
}
#endif // wxUSE_GLCANVAS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -