Loads an image from a file.
+\func{}{wxImage}{\param{wxInputStream\& }{stream}, \param{long}{ type = wxIMAGE\_TYPE\_PNG}}
+
+Loads an image from an input stream.
+
\wxheading{Parameters}
\docparam{width}{Specifies the width of the image.}
\docparam{name}{This refers to an image filename. Its meaning is determined by the {\it type} parameter.}
+\docparam{stream}{This refers to an input stream. Its meaning is determined by the {\it type} parameter. It is equal to loading from file except that you provide opened stream (file, HTTP or any other custom class).}
+
\docparam{type}{May be one of the following:
\twocolwidtha{5cm}
Loads an image from a file.
+\func{bool}{LoadFile}{\param{wxInputStream\&}{ stream}, \param{long}{ type}}
+
+Loads an image from an input stream.
+
\wxheading{Parameters}
\docparam{name}{A filename.
The meaning of {\it name} is determined by the {\it type} parameter.}
+\docparam{stream}{An input stream.
+The meaning of {\it stream} data is determined by the {\it type} parameter.}
+
\docparam{type}{One of the following values:
\twocolwidtha{5cm}
Saves a image in the named file.
+\func{bool}{SaveFile}{\param{wxOutputStream\& }{stream}, \param{int}{ type}}
+
+Saves a image in the given stream.
+
\wxheading{Parameters}
\docparam{name}{A filename. The meaning of {\it name} is determined by the {\it type} parameter.}
+\docparam{stream}{An output stream. The meaning of {\it stream} is determined by the {\it type} parameter.}
+
\docparam{type}{Currently only one type can be used:
\twocolwidtha{5cm}
\membersection{wxImageHandler::LoadFile}\label{wximagehandlerloadfile}
-\func{bool}{LoadFile}{\param{wxImage* }{image}, \param{const wxString\&}{ name}}
+\func{bool}{LoadFile}{\param{wxImage* }{image}, \param{wxInputStream\&}{ stream}}
-Loads a image from a file or resource, putting the resulting data into {\it image}.
+Loads a image from a stream, putting the resulting data into {\it image}.
\wxheading{Parameters}
\docparam{image}{The image object which is to be affected by this operation.}
-\docparam{name}{Either a filename or a Windows resource name.
-The meaning of {\it name} is determined by the {\it type} parameter.}
+\docparam{stream}{Opened input stream.
+The meaning of {\it stream} is determined by the {\it type} parameter.}
\wxheading{Return value}
\membersection{wxImageHandler::SaveFile}\label{wximagehandlersavefile}
-\func{bool}{SaveFile}{\param{wxImage* }{image}, \param{const wxString\& }{name}}
+\func{bool}{SaveFile}{\param{wxImage* }{image}, \param{wxOutputStream\& }{stream}}
-Saves a image in the named file.
+Saves a image in the output stream.
\wxheading{Parameters}
\docparam{image}{The image object which is to be affected by this operation.}
-\docparam{name}{A filename. The meaning of {\it name} is determined by the {\it type} parameter.}
+\docparam{stream}{A stream. The meaning of {\it stream} is determined by the {\it type} parameter.}
\wxheading{Return value}
- Miscellaneous events.
+- Get wxGLCanvas from 1.68 working.
+
Low Priority
------------
+- Visuals: how to select an appropriate one?
+
- Work out why XFreeFont in font.cpp produces a segv. This is
currently commented out, which presumably causes a memory leak.
- Documentation: mention include files with each class.
+- Get Karsten to remove trashed CVS files:
+
+ utils/glcanvas/isosurf/isosurf.dat.gz
+ src/msw/ctl3d/*
+
+ and re-add them.
+
- Complete this ToDo list :-)
samples/isosurf/*.dat
samples/isosurf/*.dat.gz
samples/isosurf/make*.*
+samples/penguin/*.cpp
+samples/penguin/*.c
+samples/penguin/*.h
+samples/penguin/*.rc
+samples/penguin/*.ico
+samples/penguin/*.xbm
+samples/penguin/*.xpm
+samples/penguin/make*.*
+samples/penguin/penguin.lwo
+
+
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
+lw.o: lw.cpp
+ $(CPP) `wx-config --cflags` -I../../src -c lw.cpp
trackball.o: trackball.c
$(CC) `wx-config --cflags` -I../../src -c trackball.c
+++ /dev/null
-/*
- * 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;
- }
-}
-
-
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifdef __WXMSW__
+#include <windows.h>
+#endif
+
+#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 = (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; 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 = (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; 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 = (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; 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;
+ }
+}
+
+
} lwObject;
+#ifdef __cplusplus
+extern "C" {
+#endif
int lw_is_lwobject(const char *lw_file);
lwObject *lw_object_read(const char *lw_file);
GLfloat lw_object_radius(const lwObject *lw_object);
void lw_object_scale (lwObject *lw_object, GLfloat scale);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* LW_H */
--- /dev/null
+#
+# File: makefile.nt
+# Author: Julian Smart
+# Created: 1997
+# Updated:
+#
+# "%W% %G%"
+#
+# Makefile : Builds penguin example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+EXTRAINC=-I..\..\win
+EXTRALIBS=$(WXDIR)\lib\glcanvas.lib glu32.lib opengl32.lib
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\utils\glcanvas\samples\penguin
+PROGRAM=penguin
+
+OBJECTS = $(PROGRAM).obj trackball.obj lw.obj
+
+$(PROGRAM): $(PROGRAM).exe
+
+all: wx $(PROGRAM).exe
+
+wx:
+ cd $(WXDIR)\src\msw
+ nmake -f makefile.nt FINAL=$(FINAL)
+ cd $(THISDIR)
+
+wxclean:
+ cd $(WXDIR)\src\msw
+ nmake -f makefile.nt clean
+ cd $(THISDIR)
+
+$(PROGRAM).exe: $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+ $(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj: $(PROGRAM).$(SRCSUFF) $(PROGRAM).h $(DUMMYOBJ)
+ $(cc) @<<
+$(CPPFLAGS2) /c /Tp $*.$(SRCSUFF)
+<<
+
+lw.obj: lw.c lw.h
+ $(cc) @<<
+$(CPPFLAGS2) /c $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res : $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+ $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+ -erase *.obj
+ -erase *.exe
+ -erase *.res
+ -erase *.map
+ -erase *.sbr
+ -erase *.pdb
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 - 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);
+ (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 );
/* information needed to display lightwave mesh */
typedef struct
{
- gint do_init; /* true if initgl not yet called */
+// 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 */
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+