OpenGl works now under GTK
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1360 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
71432ef81f
commit
aae24d21a3
@ -31,9 +31,6 @@ class wxLog;
|
||||
|
||||
extern wxApp *wxTheApp;
|
||||
|
||||
extern GdkVisual *wxVisualSetByExternal;
|
||||
extern GdkColormap *wxColormapSetByExternal;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// global functions
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -66,8 +63,7 @@ class wxApp: public wxEvtHandler
|
||||
|
||||
/* this may have to be overwritten when special, non-default visuals have
|
||||
to be set. it is also platform dependent as only X knows about displays
|
||||
and visuals. by standard, this routine looks at wxVisualSetByExternal
|
||||
which might have been set in the wxModule code of the OpenGL canvas */
|
||||
and visuals. */
|
||||
virtual bool InitVisual();
|
||||
|
||||
virtual bool OnInit();
|
||||
|
@ -31,9 +31,6 @@ class wxLog;
|
||||
|
||||
extern wxApp *wxTheApp;
|
||||
|
||||
extern GdkVisual *wxVisualSetByExternal;
|
||||
extern GdkColormap *wxColormapSetByExternal;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// global functions
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -66,8 +63,7 @@ class wxApp: public wxEvtHandler
|
||||
|
||||
/* this may have to be overwritten when special, non-default visuals have
|
||||
to be set. it is also platform dependent as only X knows about displays
|
||||
and visuals. by standard, this routine looks at wxVisualSetByExternal
|
||||
which might have been set in the wxModule code of the OpenGL canvas */
|
||||
and visuals. */
|
||||
virtual bool InitVisual();
|
||||
|
||||
virtual bool OnInit();
|
||||
|
@ -44,9 +44,6 @@ wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
|
||||
extern wxList wxPendingDelete;
|
||||
extern wxResourceCache *wxTheResourceCache;
|
||||
|
||||
GdkVisual *wxVisualSetByExternal = (GdkVisual*) NULL;
|
||||
GdkColormap *wxColormapSetByExternal = (GdkColormap*) NULL;
|
||||
|
||||
unsigned char g_palette[64*3] =
|
||||
{
|
||||
0x0, 0x0, 0x0,
|
||||
@ -174,45 +171,28 @@ wxApp::~wxApp(void)
|
||||
|
||||
bool wxApp::InitVisual()
|
||||
{
|
||||
if (wxVisualSetByExternal)
|
||||
{
|
||||
/* this happens in the wxModule code of the OpenGl canvas.
|
||||
it chooses the best display for OpenGl and stores it
|
||||
in wxDisplaySetByExternal. we then have to make it the
|
||||
default for the system */
|
||||
|
||||
gtk_widget_set_default_visual( wxVisualSetByExternal );
|
||||
}
|
||||
|
||||
if (wxColormapSetByExternal)
|
||||
{
|
||||
/* OpenGl also gives us a colormap */
|
||||
|
||||
gtk_widget_set_default_colormap( wxColormapSetByExternal );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this initiates the standard palette as defined by GdkImlib
|
||||
in the GNOME libraries. it ensures that all GNOME applications
|
||||
use the same 64 colormap entries on 8-bit displays so you
|
||||
can use several rather graphics-heavy applications at the
|
||||
same time */
|
||||
|
||||
GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
|
||||
return TRUE;
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
GdkColor col;
|
||||
col.red = g_palette[i*3 + 0] << 8;
|
||||
col.green = g_palette[i*3 + 1] << 8;
|
||||
col.blue = g_palette[i*3 + 2] << 8;
|
||||
col.pixel = 0;
|
||||
/* this initiates the standard palette as defined by GdkImlib
|
||||
in the GNOME libraries. it ensures that all GNOME applications
|
||||
use the same 64 colormap entries on 8-bit displays so you
|
||||
can use several rather graphics-heavy applications at the
|
||||
same time */
|
||||
|
||||
GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
|
||||
|
||||
gdk_color_alloc( cmap, &col );
|
||||
}
|
||||
|
||||
gtk_widget_set_default_colormap( cmap );
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
GdkColor col;
|
||||
col.red = g_palette[i*3 + 0] << 8;
|
||||
col.green = g_palette[i*3 + 1] << 8;
|
||||
col.blue = g_palette[i*3 + 2] << 8;
|
||||
col.pixel = 0;
|
||||
|
||||
gdk_color_alloc( cmap, &col );
|
||||
}
|
||||
|
||||
gtk_widget_set_default_colormap( cmap );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -467,15 +447,15 @@ int wxEntry( int argc, char *argv[] )
|
||||
|
||||
gtk_init( &argc, &argv );
|
||||
|
||||
wxModule::RegisterModules();
|
||||
if (!wxModule::InitializeModules()) return FALSE;
|
||||
|
||||
if (!wxTheApp->InitVisual()) return 0;
|
||||
|
||||
wxApp::CommonInit();
|
||||
|
||||
if (!wxTheApp->OnInitGui()) return 0;
|
||||
|
||||
wxModule::RegisterModules();
|
||||
if (!wxModule::InitializeModules()) return FALSE;
|
||||
|
||||
// Here frames insert themselves automatically
|
||||
// into wxTopLevelWindows by getting created
|
||||
// in OnInit().
|
||||
|
@ -288,6 +288,7 @@ gtk_myfixed_realize (GtkWidget *widget)
|
||||
attributes.event_mask |=
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_BUTTON1_MOTION_MASK |
|
||||
GDK_BUTTON2_MOTION_MASK |
|
||||
|
@ -634,6 +634,17 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
|
||||
|
||||
static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
|
||||
{
|
||||
if (gdk_event->is_hint)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
GdkModifierType state;
|
||||
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
|
||||
gdk_event->x = x;
|
||||
gdk_event->y = y;
|
||||
gdk_event->state = state;
|
||||
}
|
||||
|
||||
if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
|
||||
|
||||
if (g_blockEventsOnDrag) return TRUE;
|
||||
@ -646,7 +657,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
|
||||
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
|
||||
printf( win->GetClassInfo()->GetClassName() );
|
||||
printf( ".\n" );
|
||||
*/
|
||||
*/
|
||||
|
||||
wxMouseEvent event( wxEVT_MOTION );
|
||||
event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
|
||||
|
@ -44,9 +44,6 @@ wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
|
||||
extern wxList wxPendingDelete;
|
||||
extern wxResourceCache *wxTheResourceCache;
|
||||
|
||||
GdkVisual *wxVisualSetByExternal = (GdkVisual*) NULL;
|
||||
GdkColormap *wxColormapSetByExternal = (GdkColormap*) NULL;
|
||||
|
||||
unsigned char g_palette[64*3] =
|
||||
{
|
||||
0x0, 0x0, 0x0,
|
||||
@ -174,45 +171,28 @@ wxApp::~wxApp(void)
|
||||
|
||||
bool wxApp::InitVisual()
|
||||
{
|
||||
if (wxVisualSetByExternal)
|
||||
{
|
||||
/* this happens in the wxModule code of the OpenGl canvas.
|
||||
it chooses the best display for OpenGl and stores it
|
||||
in wxDisplaySetByExternal. we then have to make it the
|
||||
default for the system */
|
||||
|
||||
gtk_widget_set_default_visual( wxVisualSetByExternal );
|
||||
}
|
||||
|
||||
if (wxColormapSetByExternal)
|
||||
{
|
||||
/* OpenGl also gives us a colormap */
|
||||
|
||||
gtk_widget_set_default_colormap( wxColormapSetByExternal );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this initiates the standard palette as defined by GdkImlib
|
||||
in the GNOME libraries. it ensures that all GNOME applications
|
||||
use the same 64 colormap entries on 8-bit displays so you
|
||||
can use several rather graphics-heavy applications at the
|
||||
same time */
|
||||
|
||||
GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
|
||||
return TRUE;
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
GdkColor col;
|
||||
col.red = g_palette[i*3 + 0] << 8;
|
||||
col.green = g_palette[i*3 + 1] << 8;
|
||||
col.blue = g_palette[i*3 + 2] << 8;
|
||||
col.pixel = 0;
|
||||
/* this initiates the standard palette as defined by GdkImlib
|
||||
in the GNOME libraries. it ensures that all GNOME applications
|
||||
use the same 64 colormap entries on 8-bit displays so you
|
||||
can use several rather graphics-heavy applications at the
|
||||
same time */
|
||||
|
||||
GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
|
||||
|
||||
gdk_color_alloc( cmap, &col );
|
||||
}
|
||||
|
||||
gtk_widget_set_default_colormap( cmap );
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
GdkColor col;
|
||||
col.red = g_palette[i*3 + 0] << 8;
|
||||
col.green = g_palette[i*3 + 1] << 8;
|
||||
col.blue = g_palette[i*3 + 2] << 8;
|
||||
col.pixel = 0;
|
||||
|
||||
gdk_color_alloc( cmap, &col );
|
||||
}
|
||||
|
||||
gtk_widget_set_default_colormap( cmap );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -467,15 +447,15 @@ int wxEntry( int argc, char *argv[] )
|
||||
|
||||
gtk_init( &argc, &argv );
|
||||
|
||||
wxModule::RegisterModules();
|
||||
if (!wxModule::InitializeModules()) return FALSE;
|
||||
|
||||
if (!wxTheApp->InitVisual()) return 0;
|
||||
|
||||
wxApp::CommonInit();
|
||||
|
||||
if (!wxTheApp->OnInitGui()) return 0;
|
||||
|
||||
wxModule::RegisterModules();
|
||||
if (!wxModule::InitializeModules()) return FALSE;
|
||||
|
||||
// Here frames insert themselves automatically
|
||||
// into wxTopLevelWindows by getting created
|
||||
// in OnInit().
|
||||
|
@ -288,6 +288,7 @@ gtk_myfixed_realize (GtkWidget *widget)
|
||||
attributes.event_mask |=
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_BUTTON1_MOTION_MASK |
|
||||
GDK_BUTTON2_MOTION_MASK |
|
||||
|
@ -634,6 +634,17 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
|
||||
|
||||
static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
|
||||
{
|
||||
if (gdk_event->is_hint)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
GdkModifierType state;
|
||||
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
|
||||
gdk_event->x = x;
|
||||
gdk_event->y = y;
|
||||
gdk_event->state = state;
|
||||
}
|
||||
|
||||
if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
|
||||
|
||||
if (g_blockEventsOnDrag) return TRUE;
|
||||
@ -646,7 +657,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
|
||||
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
|
||||
printf( win->GetClassInfo()->GetClassName() );
|
||||
printf( ".\n" );
|
||||
*/
|
||||
*/
|
||||
|
||||
wxMouseEvent event( wxEVT_MOTION );
|
||||
event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
|
||||
|
@ -1 +0,0 @@
|
||||
include ../../setup/general/makedirs
|
@ -2,4 +2,4 @@ wxGLCanvas
|
||||
----------
|
||||
|
||||
No known issues, though probably palettes aren't correctly
|
||||
handled under Windows.
|
||||
handled under Windows. They are ignored under GTK.
|
||||
|
16
utils/glcanvas/samples/cube/Makefile
Normal file
16
utils/glcanvas/samples/cube/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
CC = g++
|
||||
|
||||
cube: cube.o glcanvas.o
|
||||
$(CC) -o cube \
|
||||
cube.o glcanvas.o \
|
||||
`wx-config --libs` -lMesaGL -lMesaGLU
|
||||
|
||||
cube.o: cube.cpp
|
||||
$(CC) `wx-config --cflags` -I../../src -c cube.cpp
|
||||
|
||||
glcanvas.o: ../../src/glcanvas.cpp
|
||||
$(CC) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o cube
|
@ -29,8 +29,6 @@
|
||||
|
||||
#include "cube.h"
|
||||
|
||||
IMPLEMENT_APP(MyApp)
|
||||
|
||||
// `Main program' equivalent, creating windows and returning main app frame
|
||||
bool MyApp::OnInit(void)
|
||||
{
|
||||
@ -54,7 +52,7 @@ bool MyApp::OnInit(void)
|
||||
|
||||
frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200));
|
||||
|
||||
InitGL();
|
||||
// InitGL();
|
||||
|
||||
// Show the frame
|
||||
frame->Show(TRUE);
|
||||
@ -81,6 +79,8 @@ void MyApp::InitGL(void)
|
||||
glEnable(GL_LIGHT0);
|
||||
}
|
||||
|
||||
IMPLEMENT_APP(MyApp)
|
||||
|
||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
||||
END_EVENT_TABLE()
|
||||
@ -169,8 +169,11 @@ void TestGLCanvas::OnSize(wxSizeEvent& event)
|
||||
int width, height;
|
||||
GetClientSize(& width, & height);
|
||||
|
||||
if ( GetContext() )
|
||||
if (GetContext())
|
||||
{
|
||||
SetCurrent();
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void TestGLCanvas::OnEraseBackground(wxEraseEvent& event)
|
||||
|
16
utils/glcanvas/samples/isosurf/Makefile
Normal file
16
utils/glcanvas/samples/isosurf/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
CC = g++
|
||||
|
||||
isosurf: isosurf.o glcanvas.o
|
||||
$(CC) -o isosurf \
|
||||
isosurf.o glcanvas.o \
|
||||
`wx-config --libs` -lMesaGL -lMesaGLU
|
||||
|
||||
isosurf.o: isosurf.cpp
|
||||
$(CC) `wx-config --cflags` -I../../src -c isosurf.cpp
|
||||
|
||||
glcanvas.o: ../../src/glcanvas.cpp
|
||||
$(CC) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o cube
|
23
utils/glcanvas/samples/penguin/Makefile
Normal file
23
utils/glcanvas/samples/penguin/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
CPP = g++
|
||||
CC = gcc
|
||||
|
||||
Penguin: penguin.o trackball.o lw.o glcanvas.o
|
||||
$(CPP) -o Penguin \
|
||||
penguin.o trackball.o lw.o glcanvas.o \
|
||||
`wx-config --libs` -lMesaGL -lMesaGLU
|
||||
|
||||
penguin.o: penguin.cpp
|
||||
$(CPP) `wx-config --cflags` -I../../src -c penguin.cpp
|
||||
|
||||
lw.o: lw.c
|
||||
$(CC) `wx-config --cflags` -I../../src -c lw.c
|
||||
|
||||
trackball.o: trackball.c
|
||||
$(CC) `wx-config --cflags` -I../../src -c trackball.c
|
||||
|
||||
glcanvas.o: ../../src/glcanvas.cpp
|
||||
$(CPP) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o penguin
|
426
utils/glcanvas/samples/penguin/lw.c
Normal file
426
utils/glcanvas/samples/penguin/lw.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (C) 1998 Janne Löf <jlof@mail.student.oulu.fi>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "lw.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#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 = 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 = 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 = realloc(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 = calloc(sizeof(int)*face->index_cnt,1);
|
||||
|
||||
/* read points in */
|
||||
for (i=0; i<face->index_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 = 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 = calloc(sizeof(GLfloat)*lwo->vertex_cnt*3, 1);
|
||||
for (i=0; i<lwo->vertex_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 = 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; i<lw_object->face_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; i<lw_object->face_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; j<face->index_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; i<lwo->vertex_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; i<lwo->vertex_cnt; i++) {
|
||||
lwo->vertex[i*3+0] *= scale;
|
||||
lwo->vertex[i*3+1] *= scale;
|
||||
lwo->vertex[i*3+2] *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
62
utils/glcanvas/samples/penguin/lw.h
Normal file
62
utils/glcanvas/samples/penguin/lw.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 1998 Janne Löf <jlof@mail.student.oulu.fi>
|
||||
*
|
||||
* 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 <GL/gl.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
#endif /* LW_H */
|
||||
|
236
utils/glcanvas/samples/penguin/penguin.cpp
Normal file
236
utils/glcanvas/samples/penguin/penguin.cpp
Normal file
@ -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 <GL/glu.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
bool MyFrame::OnClose(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!GetContext()) return;
|
||||
|
||||
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);
|
||||
|
||||
if (GetContext())
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if (event.Dragging())
|
||||
{
|
||||
/* drag in progress, simulate trackball */
|
||||
float spin_quat[4];
|
||||
trackball(spin_quat,
|
||||
(2.0*info.beginx - m_width) / m_width,
|
||||
( m_height - 2.0*info.beginy) / m_height,
|
||||
( 2.0*event.GetX() - m_width) / m_width,
|
||||
( m_height - 2.0*event.GetY()) / m_height);
|
||||
|
||||
add_quats( spin_quat, info.quat, info.quat );
|
||||
|
||||
/* orientation has changed, redraw mesh */
|
||||
Refresh();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
84
utils/glcanvas/samples/penguin/penguin.h
Normal file
84
utils/glcanvas/samples/penguin/penguin.h
Normal file
@ -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 "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 */
|
||||
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);
|
||||
bool OnClose(void);
|
||||
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
|
||||
|
324
utils/glcanvas/samples/penguin/trackball.c
Normal file
324
utils/glcanvas/samples/penguin/trackball.c
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
* (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 code:
|
||||
*
|
||||
* Implementation of a virtual trackball.
|
||||
* Implemented by Gavin Bell, lots of ideas from Thant Tessman and
|
||||
* the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
|
||||
*
|
||||
* Vector manip code:
|
||||
*
|
||||
* Original code from:
|
||||
* David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
|
||||
*
|
||||
* Much mucking with by:
|
||||
* Gavin Bell
|
||||
*/
|
||||
#include <math.h>
|
||||
#include "trackball.h"
|
||||
|
||||
/*
|
||||
* This size should really be based on the distance from the center of
|
||||
* rotation to the point on the object underneath the mouse. That
|
||||
* point would then track the mouse as closely as possible. This is a
|
||||
* simple example, though, so that is left as an Exercise for the
|
||||
* Programmer.
|
||||
*/
|
||||
#define TRACKBALLSIZE (0.8)
|
||||
|
||||
/*
|
||||
* Local function prototypes (not defined in trackball.h)
|
||||
*/
|
||||
static float tb_project_to_sphere(float, float, float);
|
||||
static void normalize_quat(float [4]);
|
||||
|
||||
void
|
||||
vzero(float *v)
|
||||
{
|
||||
v[0] = 0.0;
|
||||
v[1] = 0.0;
|
||||
v[2] = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
vset(float *v, float x, float y, float z)
|
||||
{
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
}
|
||||
|
||||
void
|
||||
vsub(const float *src1, const float *src2, float *dst)
|
||||
{
|
||||
dst[0] = src1[0] - src2[0];
|
||||
dst[1] = src1[1] - src2[1];
|
||||
dst[2] = src1[2] - src2[2];
|
||||
}
|
||||
|
||||
void
|
||||
vcopy(const float *v1, float *v2)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0 ; i < 3 ; i++)
|
||||
v2[i] = v1[i];
|
||||
}
|
||||
|
||||
void
|
||||
vcross(const float *v1, const float *v2, float *cross)
|
||||
{
|
||||
float temp[3];
|
||||
|
||||
temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
|
||||
temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
|
||||
temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
|
||||
vcopy(temp, cross);
|
||||
}
|
||||
|
||||
float
|
||||
vlength(const float *v)
|
||||
{
|
||||
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
}
|
||||
|
||||
void
|
||||
vscale(float *v, float div)
|
||||
{
|
||||
v[0] *= div;
|
||||
v[1] *= div;
|
||||
v[2] *= div;
|
||||
}
|
||||
|
||||
void
|
||||
vnormal(float *v)
|
||||
{
|
||||
vscale(v,1.0/vlength(v));
|
||||
}
|
||||
|
||||
float
|
||||
vdot(const float *v1, const float *v2)
|
||||
{
|
||||
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
}
|
||||
|
||||
void
|
||||
vadd(const float *src1, const float *src2, float *dst)
|
||||
{
|
||||
dst[0] = src1[0] + src2[0];
|
||||
dst[1] = src1[1] + src2[1];
|
||||
dst[2] = src1[2] + src2[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, simulate a track-ball. Project the points onto the virtual
|
||||
* trackball, then figure out the axis of rotation, which is the cross
|
||||
* product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
|
||||
* Note: This is a deformed trackball-- is a trackball in the center,
|
||||
* but is deformed into a hyperbolic sheet of rotation away from the
|
||||
* center. This particular function was chosen after trying out
|
||||
* several variations.
|
||||
*
|
||||
* It is assumed that the arguments to this routine are in the range
|
||||
* (-1.0 ... 1.0)
|
||||
*/
|
||||
void
|
||||
trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
|
||||
{
|
||||
float a[3]; /* Axis of rotation */
|
||||
float phi; /* how much to rotate about axis */
|
||||
float p1[3], p2[3], d[3];
|
||||
float t;
|
||||
|
||||
if (p1x == p2x && p1y == p2y) {
|
||||
/* Zero rotation */
|
||||
vzero(q);
|
||||
q[3] = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, figure out z-coordinates for projection of P1 and P2 to
|
||||
* deformed sphere
|
||||
*/
|
||||
vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
|
||||
vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
|
||||
|
||||
/*
|
||||
* Now, we want the cross product of P1 and P2
|
||||
*/
|
||||
vcross(p2,p1,a);
|
||||
|
||||
/*
|
||||
* Figure out how much to rotate around that axis.
|
||||
*/
|
||||
vsub(p1,p2,d);
|
||||
t = vlength(d) / (2.0*TRACKBALLSIZE);
|
||||
|
||||
/*
|
||||
* Avoid problems with out-of-control values...
|
||||
*/
|
||||
if (t > 1.0) t = 1.0;
|
||||
if (t < -1.0) t = -1.0;
|
||||
phi = 2.0 * asin(t);
|
||||
|
||||
axis_to_quat(a,phi,q);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an axis and angle, compute quaternion.
|
||||
*/
|
||||
void
|
||||
axis_to_quat(float a[3], float phi, float q[4])
|
||||
{
|
||||
vnormal(a);
|
||||
vcopy(a,q);
|
||||
vscale(q,sin(phi/2.0));
|
||||
q[3] = cos(phi/2.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
|
||||
* if we are away from the center of the sphere.
|
||||
*/
|
||||
static float
|
||||
tb_project_to_sphere(float r, float x, float y)
|
||||
{
|
||||
float d, t, z;
|
||||
|
||||
d = sqrt(x*x + y*y);
|
||||
if (d < r * 0.70710678118654752440) { /* Inside sphere */
|
||||
z = sqrt(r*r - d*d);
|
||||
} else { /* On hyperbola */
|
||||
t = r / 1.41421356237309504880;
|
||||
z = t*t / d;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given two rotations, e1 and e2, expressed as quaternion rotations,
|
||||
* figure out the equivalent single rotation and stuff it into dest.
|
||||
*
|
||||
* This routine also normalizes the result every RENORMCOUNT times it is
|
||||
* called, to keep error from creeping in.
|
||||
*
|
||||
* NOTE: This routine is written so that q1 or q2 may be the same
|
||||
* as dest (or each other).
|
||||
*/
|
||||
|
||||
#define RENORMCOUNT 97
|
||||
|
||||
void
|
||||
add_quats(float q1[4], float q2[4], float dest[4])
|
||||
{
|
||||
static int count=0;
|
||||
float t1[4], t2[4], t3[4];
|
||||
float tf[4];
|
||||
|
||||
vcopy(q1,t1);
|
||||
vscale(t1,q2[3]);
|
||||
|
||||
vcopy(q2,t2);
|
||||
vscale(t2,q1[3]);
|
||||
|
||||
vcross(q2,q1,t3);
|
||||
vadd(t1,t2,tf);
|
||||
vadd(t3,tf,tf);
|
||||
tf[3] = q1[3] * q2[3] - vdot(q1,q2);
|
||||
|
||||
dest[0] = tf[0];
|
||||
dest[1] = tf[1];
|
||||
dest[2] = tf[2];
|
||||
dest[3] = tf[3];
|
||||
|
||||
if (++count > RENORMCOUNT) {
|
||||
count = 0;
|
||||
normalize_quat(dest);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
|
||||
* If they don't add up to 1.0, dividing by their magnitued will
|
||||
* renormalize them.
|
||||
*
|
||||
* Note: See the following for more information on quaternions:
|
||||
*
|
||||
* - Shoemake, K., Animating rotation with quaternion curves, Computer
|
||||
* Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
|
||||
* - Pletinckx, D., Quaternion calculus as a basic tool in computer
|
||||
* graphics, The Visual Computer 5, 2-13, 1989.
|
||||
*/
|
||||
static void
|
||||
normalize_quat(float q[4])
|
||||
{
|
||||
int i;
|
||||
float mag;
|
||||
|
||||
mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
|
||||
for (i = 0; i < 4; i++) q[i] /= mag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a rotation matrix, given a quaternion rotation.
|
||||
*
|
||||
*/
|
||||
void
|
||||
build_rotmatrix(float m[4][4], float q[4])
|
||||
{
|
||||
m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
|
||||
m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
|
||||
m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
|
||||
m[0][3] = 0.0;
|
||||
|
||||
m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
|
||||
m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
|
||||
m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
|
||||
m[1][3] = 0.0;
|
||||
|
||||
m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
|
||||
m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
|
||||
m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
|
||||
m[2][3] = 0.0;
|
||||
|
||||
m[3][0] = 0.0;
|
||||
m[3][1] = 0.0;
|
||||
m[3][2] = 0.0;
|
||||
m[3][3] = 1.0;
|
||||
}
|
||||
|
78
utils/glcanvas/samples/penguin/trackball.h
Normal file
78
utils/glcanvas/samples/penguin/trackball.h
Normal file
@ -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]);
|
||||
|
@ -1 +0,0 @@
|
||||
include ../../../setup/general/makedirs
|
@ -1,67 +0,0 @@
|
||||
#
|
||||
# wxGLCanvas source makefile for Unix
|
||||
#
|
||||
# Copyright 1998, Robert Roebling
|
||||
#
|
||||
|
||||
# wxWindows base directory
|
||||
WXBASEDIR=@WXBASEDIR@
|
||||
|
||||
# set the OS type for compilation
|
||||
OS=@OS@
|
||||
|
||||
# compile a library only
|
||||
RULE=gslib
|
||||
|
||||
# needed for unactivated
|
||||
NONE=
|
||||
|
||||
# define library name
|
||||
LIB_TARGET=wx_opengl_gtk
|
||||
LIB_MAJOR=1
|
||||
LIB_MINOR=0
|
||||
|
||||
# define library sources
|
||||
|
||||
LIB_CPP_SRC= \
|
||||
\
|
||||
glcanvas.cpp
|
||||
|
||||
#define library objects
|
||||
LIB_OBJ= \
|
||||
\
|
||||
$(LIB_CPP_SRC:.cpp=.o)
|
||||
|
||||
all::
|
||||
|
||||
clean::
|
||||
|
||||
#additional things needed for compile
|
||||
ADD_COMPILE=
|
||||
|
||||
# include the definitions now
|
||||
include ../../../../template.mak
|
||||
|
||||
install::
|
||||
@echo "Installing library files and headers for libwx_opengl_gtk.."
|
||||
@echo " Creating directory.."
|
||||
@$(WXBASEDIR)/mkinstalldirs /usr/local/include/wx_opengl
|
||||
@echo " Copying headers from /include/wx"
|
||||
@cd $(WXBASEDIR)/utils/glcanvas/src ; \
|
||||
for f in *.h ; do \
|
||||
rm -f /usr/local/include/wx_opengl/$$f ; \
|
||||
$(INSTALL_DATA) $$f /usr/local/include/wx_opengl/$$f ; \
|
||||
done
|
||||
@echo " Copying static library files to /usr/local/lib"
|
||||
@cd $(WXBASEDIR)/lib/$(OS) ; \
|
||||
for f in libwx_opengl_gtk.a ; do \
|
||||
rm -f /usr/local/lib/$$f ; \
|
||||
$(INSTALL_DATA) $$f /usr/local/lib/$$f ; \
|
||||
done
|
||||
@echo " Copying shared libraries to /usr/local/lib"
|
||||
@cd $(WXBASEDIR)/lib/$(OS) ; \
|
||||
for f in libwx_opengl_gtk.so* ; do \
|
||||
rm -f /usr/local/lib/$$f ; \
|
||||
$(INSTALL_PROGRAM) $$f /usr/local/lib/$$f ; \
|
||||
done
|
||||
|
@ -20,17 +20,19 @@
|
||||
#include "wx/module.h"
|
||||
#include "wx/app.h"
|
||||
|
||||
extern "C" {
|
||||
#include "gtk/gtk.h"
|
||||
#include "gdk/gdk.h"
|
||||
extern "C" {
|
||||
#include "gdk/gdkx.h"
|
||||
}
|
||||
|
||||
#include "wx/gtk/win_gtk.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// global variables
|
||||
// global data
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
XVisualInfo *g_visual_info = (XVisualInfo*) NULL;
|
||||
XVisualInfo *g_vi = (XVisualInfo*) NULL;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// wxGLContext
|
||||
@ -41,25 +43,25 @@ IMPLEMENT_CLASS(wxGLContext,wxObject)
|
||||
wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) )
|
||||
{
|
||||
m_window = win;
|
||||
m_widget = win->m_wxwindow;
|
||||
m_widget = ((wxGLCanvas*)win)->m_glWidget;
|
||||
|
||||
wxCHECK_RET( g_visual_info != NULL, "invalid visual for OpenGl" );
|
||||
wxCHECK_RET( g_vi, "invalid visual for OpenGl" );
|
||||
|
||||
m_glContext = glXCreateContext( GDK_DISPLAY(), g_visual_info, None, GL_TRUE );
|
||||
m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, None, GL_TRUE );
|
||||
|
||||
wxCHECK_RET( m_glContext != NULL, "Couldn't create OpenGl context" );
|
||||
|
||||
glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
|
||||
wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" );
|
||||
}
|
||||
|
||||
wxGLContext::~wxGLContext()
|
||||
{
|
||||
if (m_glContext)
|
||||
{
|
||||
glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
|
||||
if (!m_glContext) return;
|
||||
|
||||
glXDestroyContext( GDK_DISPLAY(), m_glContext );
|
||||
if (m_glContext == glXGetCurrentContext())
|
||||
{
|
||||
glXMakeCurrent( GDK_DISPLAY(), None, NULL);
|
||||
}
|
||||
|
||||
glXDestroyContext( GDK_DISPLAY(), m_glContext );
|
||||
}
|
||||
|
||||
void wxGLContext::SwapBuffers()
|
||||
@ -116,12 +118,71 @@ 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 *WXUNUSED(attribList), const wxPalette& palette):
|
||||
wxScrolledWindow(parent, id, pos, size, style, name)
|
||||
wxGLCanvas::wxGLCanvas( wxWindow *parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size,
|
||||
long style, const wxString& name,
|
||||
int *attribList,
|
||||
const wxPalette& palette )
|
||||
{
|
||||
Create( parent, id, pos, size, style, name, attribList, palette );
|
||||
}
|
||||
|
||||
bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size,
|
||||
long style, const wxString& name,
|
||||
int *attribList,
|
||||
const wxPalette& palette )
|
||||
{
|
||||
if (!attribList)
|
||||
{
|
||||
int data[] = { GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None };
|
||||
attribList = (int*) data;
|
||||
}
|
||||
|
||||
Display *dpy = GDK_DISPLAY();
|
||||
|
||||
g_vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList );
|
||||
|
||||
GdkVisual *visual = gdkx_visual_get( g_vi->visualid );
|
||||
GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(g_vi->visualid), TRUE );
|
||||
|
||||
gtk_widget_push_colormap( colormap );
|
||||
gtk_widget_push_visual( visual );
|
||||
|
||||
m_glWidget = gtk_drawing_area_new();
|
||||
gtk_widget_set_events( m_glWidget,
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_BUTTON1_MOTION_MASK |
|
||||
GDK_BUTTON2_MOTION_MASK |
|
||||
GDK_BUTTON3_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_KEY_PRESS_MASK |
|
||||
GDK_KEY_RELEASE_MASK |
|
||||
GDK_ENTER_NOTIFY_MASK |
|
||||
GDK_LEAVE_NOTIFY_MASK );
|
||||
|
||||
gtk_widget_pop_visual();
|
||||
gtk_widget_pop_colormap();
|
||||
|
||||
wxScrolledWindow::Create( parent, id, pos, size, style, name );
|
||||
|
||||
gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), m_glWidget, 0, 0 );
|
||||
|
||||
gtk_widget_show( m_glWidget );
|
||||
|
||||
m_glContext = new wxGLContext( TRUE, this, palette );
|
||||
|
||||
XFree( g_vi );
|
||||
g_vi = (XVisualInfo*) NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wxGLCanvas::~wxGLCanvas()
|
||||
@ -137,13 +198,12 @@ void wxGLCanvas::SwapBuffers()
|
||||
void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
|
||||
{
|
||||
int width, height;
|
||||
GetClientSize(& width, & height);
|
||||
|
||||
if (m_glContext)
|
||||
GetClientSize( &width, &height );
|
||||
if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) )
|
||||
{
|
||||
m_glContext->SetCurrent();
|
||||
|
||||
glViewport(0, 0, (GLint)width, (GLint)height);
|
||||
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 );
|
||||
@ -161,39 +221,92 @@ void wxGLCanvas::SetColour( const char *colour )
|
||||
if (m_glContext) m_glContext->SetColour( colour );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// wxGLModule
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
class wxGLModule : public wxModule
|
||||
void wxGLCanvas::SetSize( int x, int y, int width, int height, int sizeFlags )
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual void OnExit();
|
||||
if (m_resizing) return; // I don't like recursions
|
||||
m_resizing = TRUE;
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxGLModule)
|
||||
};
|
||||
if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
|
||||
{
|
||||
// don't set the size for children of wxNotebook, just take the values.
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
int old_width = m_width;
|
||||
int old_height = m_height;
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
|
||||
if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
|
||||
{
|
||||
if (x != -1) m_x = x;
|
||||
if (y != -1) m_y = y;
|
||||
if (width != -1) m_width = width;
|
||||
if (height != -1) m_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
bool wxGLModule::OnInit()
|
||||
{
|
||||
int data[] = { GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1,
|
||||
GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,None};
|
||||
if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
|
||||
{
|
||||
if (width == -1) m_width = 80;
|
||||
}
|
||||
|
||||
g_visual_info = glXChooseVisual( GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), data );
|
||||
|
||||
wxCHECK_MSG( g_visual_info != NULL, FALSE, "Couldn't choose visual for OpenGl" );
|
||||
|
||||
wxVisualSetByExternal = gdkx_visual_get(g_visual_info->visualid);
|
||||
|
||||
wxColormapSetByExternal = gdk_colormap_new( gdkx_visual_get(g_visual_info->visualid), TRUE );
|
||||
|
||||
return TRUE;
|
||||
if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
|
||||
{
|
||||
if (height == -1) m_height = 26;
|
||||
}
|
||||
|
||||
if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
|
||||
if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
|
||||
if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
|
||||
if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
|
||||
|
||||
wxPoint pt( m_parent->GetClientAreaOrigin() );
|
||||
gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y );
|
||||
|
||||
if ((old_width != m_width) || (old_height != m_height))
|
||||
{
|
||||
gtk_widget_set_usize( m_widget, m_width, m_height );
|
||||
|
||||
gtk_drawing_area_size( GTK_DRAWING_AREA(m_glWidget), m_width, m_height );
|
||||
|
||||
GtkAllocation allo;
|
||||
allo.x = 0;
|
||||
allo.y = 0;
|
||||
allo.width = m_width;
|
||||
allo.height = m_height;
|
||||
gtk_widget_size_allocate( m_glWidget, &allo );
|
||||
}
|
||||
}
|
||||
|
||||
m_sizeSet = TRUE;
|
||||
|
||||
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
|
||||
event.SetEventObject( this );
|
||||
GetEventHandler()->ProcessEvent( event );
|
||||
|
||||
m_resizing = FALSE;
|
||||
}
|
||||
|
||||
void wxGLModule::OnExit()
|
||||
void wxGLCanvas::SetSize( int width, int height )
|
||||
{
|
||||
SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
|
||||
}
|
||||
|
||||
GtkWidget *wxGLCanvas::GetConnectWidget()
|
||||
{
|
||||
return m_glWidget;
|
||||
}
|
||||
|
||||
bool wxGLCanvas::IsOwnGtkWindow( GdkWindow *window )
|
||||
{
|
||||
return (window == m_glWidget->window);
|
||||
}
|
||||
|
@ -19,9 +19,11 @@
|
||||
#include "wx/defs.h"
|
||||
#include "wx/scrolwin.h"
|
||||
|
||||
extern "C" {
|
||||
#include "GL/gl.h"
|
||||
#include "GL/glx.h"
|
||||
#include "GL/glu.h"
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// classes
|
||||
@ -75,9 +77,20 @@ class 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, wxWindowID id = -1,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0, const wxString& name = "GLCanvas",
|
||||
int *attribList = (int*) NULL,
|
||||
const wxPalette& palette = wxNullPalette );
|
||||
|
||||
bool Create( wxWindow *parent, wxWindowID id = -1,
|
||||
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();
|
||||
@ -86,11 +99,19 @@ class wxGLCanvas: public wxScrolledWindow
|
||||
|
||||
void OnSize(wxSizeEvent& event);
|
||||
|
||||
inline wxGLContext* GetContext() const { return m_glContext; }
|
||||
inline wxGLContext* GetContext() const { return m_glContext; }
|
||||
|
||||
protected:
|
||||
// implementation
|
||||
|
||||
wxGLContext* m_glContext; // this is typedef-ed ptr, in fact
|
||||
virtual void SetSize( int x, int y, int width, int height,
|
||||
int sizeFlags = wxSIZE_AUTO );
|
||||
virtual void SetSize( int width, int height );
|
||||
|
||||
virtual GtkWidget *GetConnectWidget();
|
||||
bool IsOwnGtkWindow( GdkWindow *window );
|
||||
|
||||
wxGLContext *m_glContext;
|
||||
GtkWidget *m_glWidget;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user