From: Julian Smart Date: Mon, 14 Nov 2005 17:38:24 +0000 (+0000) Subject: Applied patch [ 1355355 ] Replace GPLed code in penguin sample and add features X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/4b764db3795a5f202f379ee3b0314b2de91c15fa Applied patch [ 1355355 ] Replace GPLed code in penguin sample and add features (with Unicode and scope mods) By Sandro Sigala git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36174 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/build/bakefiles/make_dist.mk b/build/bakefiles/make_dist.mk index 2b30839093..7a2b140846 100644 --- a/build/bakefiles/make_dist.mk +++ b/build/bakefiles/make_dist.mk @@ -855,7 +855,7 @@ SAMPLES_DIST: ALL_GUI_DIST $(CP_P) $(SAMPDIR)/opengl/penguin/*.cpp $(DISTDIR)/samples/opengl/penguin $(CP_P) $(SAMPDIR)/opengl/penguin/*.c $(DISTDIR)/samples/opengl/penguin $(CP_P) $(SAMPDIR)/opengl/penguin/*.h $(DISTDIR)/samples/opengl/penguin - $(CP_P) $(SAMPDIR)/opengl/penguin/*.lwo $(DISTDIR)/samples/opengl/penguin + $(CP_P) $(SAMPDIR)/opengl/penguin/*.dxf.gz $(DISTDIR)/samples/opengl/penguin mkdir $(DISTDIR)/samples/opengl/cube $(CP_P) $(SAMPDIR)/opengl/cube/Makefile.in $(DISTDIR)/samples/opengl/cube $(CP_P) $(SAMPDIR)/opengl/cube/makefile.unx $(DISTDIR)/samples/opengl/cube diff --git a/distrib/msw/generic.rsp b/distrib/msw/generic.rsp index 3ac61eb3f4..20771ab854 100644 --- a/distrib/msw/generic.rsp +++ b/distrib/msw/generic.rsp @@ -974,7 +974,7 @@ samples/opengl/penguin/*.xbm samples/opengl/penguin/*.xpm samples/opengl/penguin/*.pro samples/opengl/penguin/make*.* -samples/opengl/penguin/penguin.lwo +samples/opengl/penguin/penguin.dxf.gz samples/opengl/penguin/*.bkl samples/png/*.cpp diff --git a/distrib/msw/makefile.rsp b/distrib/msw/makefile.rsp index d9206458f2..fe1e061711 100644 --- a/distrib/msw/makefile.rsp +++ b/distrib/msw/makefile.rsp @@ -67,6 +67,7 @@ samples/propsize/Makefile.in samples/regtest/Makefile.in samples/render/Makefile.in samples/richedit/Makefile.in +samples/richtext/Makefile.in samples/rotate/Makefile.in samples/sashtest/Makefile.in samples/scroll/Makefile.in diff --git a/distrib/msw/vc.rsp b/distrib/msw/vc.rsp index 9465a87017..9dd2531c71 100644 --- a/distrib/msw/vc.rsp +++ b/distrib/msw/vc.rsp @@ -211,6 +211,9 @@ samples/render/*.dsw samples/richedit/*.dsp samples/richedit/*.dsw +samples/richtext/*.dsp +samples/richtext/*.dsw + samples/rotate/rotate.dsp samples/rotate/rotate.dsw diff --git a/distrib/msw/wince.rsp b/distrib/msw/wince.rsp index bb5d2dfea5..28a9bac02c 100644 --- a/distrib/msw/wince.rsp +++ b/distrib/msw/wince.rsp @@ -194,6 +194,9 @@ samples/render/render_render.vcw samples/richedit/richedit.vcp samples/richedit/richedit.vcw +samples/richtext/richtext.vcp +samples/richtext/richtext.vcw + samples/rotate/rotate.vcp samples/rotate/rotate.vcw diff --git a/samples/opengl/penguin/Makefile.in b/samples/opengl/penguin/Makefile.in index b54aea2900..48f3922b7a 100644 --- a/samples/opengl/penguin/Makefile.in +++ b/samples/opengl/penguin/Makefile.in @@ -52,7 +52,7 @@ PENGUIN_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \ PENGUIN_OBJECTS = \ $(__penguin_os2_lib_res) \ penguin_penguin.o \ - penguin_lw.o \ + penguin_dxfrenderer.o \ penguin_trackball.o \ $(__penguin___win32rc) @@ -187,7 +187,7 @@ penguin.app/Contents/PkgInfo: $(__penguin___depname) $(top_srcdir)/src/mac/carbo data: @mkdir -p . - @for f in penguin.lwo; do \ + @for f in penguin.dxf.gz; do \ if test ! -f ./$$f -a ! -d ./$$f ; \ then x=yep ; \ else x=`find $(srcdir)/$$f -newer ./$$f -print` ; \ @@ -200,8 +200,8 @@ data: penguin_penguin.o: $(srcdir)/penguin.cpp $(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/penguin.cpp -penguin_lw.o: $(srcdir)/lw.cpp - $(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/lw.cpp +penguin_dxfrenderer.o: $(srcdir)/dxfrenderer.cpp + $(CXXC) -c -o $@ $(PENGUIN_CXXFLAGS) $(srcdir)/dxfrenderer.cpp penguin_trackball.o: $(srcdir)/trackball.c $(CCC) -c -o $@ $(PENGUIN_CFLAGS) $(srcdir)/trackball.c diff --git a/samples/opengl/penguin/dxfrenderer.cpp b/samples/opengl/penguin/dxfrenderer.cpp new file mode 100644 index 0000000000..5d18667872 --- /dev/null +++ b/samples/opengl/penguin/dxfrenderer.cpp @@ -0,0 +1,680 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dxfrenderer.cpp +// Purpose: DXF reader and renderer +// Author: Sandro Sigala +// Modified by: +// Created: 2005-11-10 +// RCS-ID: $Id$ +// Copyright: (c) Sandro Sigala +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/wfstream.h" +#include "wx/txtstrm.h" + +#if !wxUSE_GLCANVAS + #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" +#endif + +#ifdef __WXMAC__ +# ifdef __DARWIN__ +# include +# else +# include +# endif +#else +# include +#endif + +#include "dxfrenderer.h" + +#include +WX_DEFINE_LIST(DXFEntityList); +WX_DEFINE_LIST(DXFLayerList); + +// Conversion table from AutoCAD ACI colours to RGB values +static const struct { unsigned char r, g, b; } aci_to_rgb[256] = { +/* 0 */ 255, 255, 255, +/* 1 */ 255, 0, 0, +/* 2 */ 255, 255, 0, +/* 3 */ 0, 255, 0, +/* 4 */ 0, 255, 255, +/* 5 */ 0, 0, 255, +/* 6 */ 255, 0, 255, +/* 7 */ 255, 255, 255, +/* 8 */ 128, 128, 128, +/* 9 */ 192, 192, 192, +/* 10 */ 255, 0, 0, +/* 11 */ 255, 127, 127, +/* 12 */ 204, 0, 0, +/* 13 */ 204, 102, 102, +/* 14 */ 153, 0, 0, +/* 15 */ 153, 76, 76, +/* 16 */ 127, 0, 0, +/* 17 */ 127, 63, 63, +/* 18 */ 76, 0, 0, +/* 19 */ 76, 38, 38, +/* 20 */ 255, 63, 0, +/* 21 */ 255, 159, 127, +/* 22 */ 204, 51, 0, +/* 23 */ 204, 127, 102, +/* 24 */ 153, 38, 0, +/* 25 */ 153, 95, 76, +/* 26 */ 127, 31, 0, +/* 27 */ 127, 79, 63, +/* 28 */ 76, 19, 0, +/* 29 */ 76, 47, 38, +/* 30 */ 255, 127, 0, +/* 31 */ 255, 191, 127, +/* 32 */ 204, 102, 0, +/* 33 */ 204, 153, 102, +/* 34 */ 153, 76, 0, +/* 35 */ 153, 114, 76, +/* 36 */ 127, 63, 0, +/* 37 */ 127, 95, 63, +/* 38 */ 76, 38, 0, +/* 39 */ 76, 57, 38, +/* 40 */ 255, 191, 0, +/* 41 */ 255, 223, 127, +/* 42 */ 204, 153, 0, +/* 43 */ 204, 178, 102, +/* 44 */ 153, 114, 0, +/* 45 */ 153, 133, 76, +/* 46 */ 127, 95, 0, +/* 47 */ 127, 111, 63, +/* 48 */ 76, 57, 0, +/* 49 */ 76, 66, 38, +/* 50 */ 255, 255, 0, +/* 51 */ 255, 255, 127, +/* 52 */ 204, 204, 0, +/* 53 */ 204, 204, 102, +/* 54 */ 153, 153, 0, +/* 55 */ 153, 153, 76, +/* 56 */ 127, 127, 0, +/* 57 */ 127, 127, 63, +/* 58 */ 76, 76, 0, +/* 59 */ 76, 76, 38, +/* 60 */ 191, 255, 0, +/* 61 */ 223, 255, 127, +/* 62 */ 153, 204, 0, +/* 63 */ 178, 204, 102, +/* 64 */ 114, 153, 0, +/* 65 */ 133, 153, 76, +/* 66 */ 95, 127, 0, +/* 67 */ 111, 127, 63, +/* 68 */ 57, 76, 0, +/* 69 */ 66, 76, 38, +/* 70 */ 127, 255, 0, +/* 71 */ 191, 255, 127, +/* 72 */ 102, 204, 0, +/* 73 */ 153, 204, 102, +/* 74 */ 76, 153, 0, +/* 75 */ 114, 153, 76, +/* 76 */ 63, 127, 0, +/* 77 */ 95, 127, 63, +/* 78 */ 38, 76, 0, +/* 79 */ 57, 76, 38, +/* 80 */ 63, 255, 0, +/* 81 */ 159, 255, 127, +/* 82 */ 51, 204, 0, +/* 83 */ 127, 204, 102, +/* 84 */ 38, 153, 0, +/* 85 */ 95, 153, 76, +/* 86 */ 31, 127, 0, +/* 87 */ 79, 127, 63, +/* 88 */ 19, 76, 0, +/* 89 */ 47, 76, 38, +/* 90 */ 0, 255, 0, +/* 91 */ 127, 255, 127, +/* 92 */ 0, 204, 0, +/* 93 */ 102, 204, 102, +/* 94 */ 0, 153, 0, +/* 95 */ 76, 153, 76, +/* 96 */ 0, 127, 0, +/* 97 */ 63, 127, 63, +/* 98 */ 0, 76, 0, +/* 99 */ 38, 76, 38, +/* 100 */ 0, 255, 63, +/* 101 */ 127, 255, 159, +/* 102 */ 0, 204, 51, +/* 103 */ 102, 204, 127, +/* 104 */ 0, 153, 38, +/* 105 */ 76, 153, 95, +/* 106 */ 0, 127, 31, +/* 107 */ 63, 127, 79, +/* 108 */ 0, 76, 19, +/* 109 */ 38, 76, 47, +/* 110 */ 0, 255, 127, +/* 111 */ 127, 255, 191, +/* 112 */ 0, 204, 102, +/* 113 */ 102, 204, 153, +/* 114 */ 0, 153, 76, +/* 115 */ 76, 153, 114, +/* 116 */ 0, 127, 63, +/* 117 */ 63, 127, 95, +/* 118 */ 0, 76, 38, +/* 119 */ 38, 76, 57, +/* 120 */ 0, 255, 191, +/* 121 */ 127, 255, 223, +/* 122 */ 0, 204, 153, +/* 123 */ 102, 204, 178, +/* 124 */ 0, 153, 114, +/* 125 */ 76, 153, 133, +/* 126 */ 0, 127, 95, +/* 127 */ 63, 127, 111, +/* 128 */ 0, 76, 57, +/* 129 */ 38, 76, 66, +/* 130 */ 0, 255, 255, +/* 131 */ 127, 255, 255, +/* 132 */ 0, 204, 204, +/* 133 */ 102, 204, 204, +/* 134 */ 0, 153, 153, +/* 135 */ 76, 153, 153, +/* 136 */ 0, 127, 127, +/* 137 */ 63, 127, 127, +/* 138 */ 0, 76, 76, +/* 139 */ 38, 76, 76, +/* 140 */ 0, 191, 255, +/* 141 */ 127, 223, 255, +/* 142 */ 0, 153, 204, +/* 143 */ 102, 178, 204, +/* 144 */ 0, 114, 153, +/* 145 */ 76, 133, 153, +/* 146 */ 0, 95, 127, +/* 147 */ 63, 111, 127, +/* 148 */ 0, 57, 76, +/* 149 */ 38, 66, 76, +/* 150 */ 0, 127, 255, +/* 151 */ 127, 191, 255, +/* 152 */ 0, 102, 204, +/* 153 */ 102, 153, 204, +/* 154 */ 0, 76, 153, +/* 155 */ 76, 114, 153, +/* 156 */ 0, 63, 127, +/* 157 */ 63, 95, 127, +/* 158 */ 0, 38, 76, +/* 159 */ 38, 57, 76, +/* 160 */ 0, 63, 255, +/* 161 */ 127, 159, 255, +/* 162 */ 0, 51, 204, +/* 163 */ 102, 127, 204, +/* 164 */ 0, 38, 153, +/* 165 */ 76, 95, 153, +/* 166 */ 0, 31, 127, +/* 167 */ 63, 79, 127, +/* 168 */ 0, 19, 76, +/* 169 */ 38, 47, 76, +/* 170 */ 0, 0, 255, +/* 171 */ 127, 127, 255, +/* 172 */ 0, 0, 204, +/* 173 */ 102, 102, 204, +/* 174 */ 0, 0, 153, +/* 175 */ 76, 76, 153, +/* 176 */ 0, 0, 127, +/* 177 */ 63, 63, 127, +/* 178 */ 0, 0, 76, +/* 179 */ 38, 38, 76, +/* 180 */ 63, 0, 255, +/* 181 */ 159, 127, 255, +/* 182 */ 51, 0, 204, +/* 183 */ 127, 102, 204, +/* 184 */ 38, 0, 153, +/* 185 */ 95, 76, 153, +/* 186 */ 31, 0, 127, +/* 187 */ 79, 63, 127, +/* 188 */ 19, 0, 76, +/* 189 */ 47, 38, 76, +/* 190 */ 127, 0, 255, +/* 191 */ 191, 127, 255, +/* 192 */ 102, 0, 204, +/* 193 */ 153, 102, 204, +/* 194 */ 76, 0, 153, +/* 195 */ 114, 76, 153, +/* 196 */ 63, 0, 127, +/* 197 */ 95, 63, 127, +/* 198 */ 38, 0, 76, +/* 199 */ 57, 38, 76, +/* 200 */ 191, 0, 255, +/* 201 */ 223, 127, 255, +/* 202 */ 153, 0, 204, +/* 203 */ 178, 102, 204, +/* 204 */ 114, 0, 153, +/* 205 */ 133, 76, 153, +/* 206 */ 95, 0, 127, +/* 207 */ 111, 63, 127, +/* 208 */ 57, 0, 76, +/* 209 */ 66, 38, 76, +/* 210 */ 255, 0, 255, +/* 211 */ 255, 127, 255, +/* 212 */ 204, 0, 204, +/* 213 */ 204, 102, 204, +/* 214 */ 153, 0, 153, +/* 215 */ 153, 76, 153, +/* 216 */ 127, 0, 127, +/* 217 */ 127, 63, 127, +/* 218 */ 76, 0, 76, +/* 219 */ 76, 38, 76, +/* 220 */ 255, 0, 191, +/* 221 */ 255, 127, 223, +/* 222 */ 204, 0, 153, +/* 223 */ 204, 102, 178, +/* 224 */ 153, 0, 114, +/* 225 */ 153, 76, 133, +/* 226 */ 127, 0, 95, +/* 227 */ 127, 63, 111, +/* 228 */ 76, 0, 57, +/* 229 */ 76, 38, 66, +/* 230 */ 255, 0, 127, +/* 231 */ 255, 127, 191, +/* 232 */ 204, 0, 102, +/* 233 */ 204, 102, 153, +/* 234 */ 153, 0, 76, +/* 235 */ 153, 76, 114, +/* 236 */ 127, 0, 63, +/* 237 */ 127, 63, 95, +/* 238 */ 76, 0, 38, +/* 239 */ 76, 38, 57, +/* 240 */ 255, 0, 63, +/* 241 */ 255, 127, 159, +/* 242 */ 204, 0, 51, +/* 243 */ 204, 102, 127, +/* 244 */ 153, 0, 38, +/* 245 */ 153, 76, 95, +/* 246 */ 127, 0, 31, +/* 247 */ 127, 63, 79, +/* 248 */ 76, 0, 19, +/* 249 */ 76, 38, 47, +/* 250 */ 51, 51, 51, +/* 251 */ 91, 91, 91, +/* 252 */ 132, 132, 132, +/* 253 */ 173, 173, 173, +/* 254 */ 214, 214, 214, +/* 255 */ 255, 255, 255, +}; + +inline DXFVector Cross(const DXFVector& v1, const DXFVector& v2) +{ + return DXFVector(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); +} + +void DXFFace::CalculateNormal() +{ + DXFVector v01, v02; + v01.x = v0.x - v1.x; + v01.y = v0.y - v1.y; + v01.z = v0.z - v1.z; + v02.x = v0.x - v2.x; + v02.y = v0.y - v2.y; + v02.z = v0.z - v2.z; + n = Cross(v01, v02); + float mod = sqrt(n.x*n.x + n.y*n.y + n.z*n.z); + n.x /= mod; + n.y /= mod; + n.z /= mod; +} + +// convert an AutoCAD ACI colour to wxWidgets RGB colour +inline wxColour ACIColourToRGB(int col) +{ + wxASSERT(col >= 0 && col <= 255); + return wxColour(aci_to_rgb[col].r, aci_to_rgb[col].g, aci_to_rgb[col].b); +} + +// DXFReader constructor +DXFRenderer::DXFRenderer() +{ + m_loaded = false; +} + +// DXFReader destructor +DXFRenderer::~DXFRenderer() +{ + Clear(); +} + +// deallocate all the dynamic data +void DXFRenderer::Clear() +{ + m_loaded = false; + { + for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext()) + { + DXFLayer *current = node->GetData(); + delete current; + } + } + m_layers.Clear(); + { + for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext()) + { + DXFEntity *current = node->GetData(); + delete current; + } + m_entities.Clear(); + } +} + +int DXFRenderer::GetLayerColour(const wxString& layer) const +{ + for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext()) + { + DXFLayer *current = node->GetData(); + if (current->name == layer) + return current->colour; + } + return 7; // white +} + +// read two sequential lines +inline void GetLines(wxTextInputStream& text, wxString& line1, wxString& line2) +{ + line1 = text.ReadLine().Trim().Trim(false); + line2 = text.ReadLine().Trim().Trim(false); +} + +// parse header section: just skip everything +bool DXFRenderer::ParseHeader(wxInputStream& stream) +{ + wxTextInputStream text(stream); + wxString line1, line2; + while (stream.CanRead()) + { + GetLines(text, line1, line2); + if (line1 == wxT("0") && line2 == wxT("ENDSEC")) + return true; + } + return false; +} + +// parse tables section: save layers name and colour +bool DXFRenderer::ParseTables(wxInputStream& stream) +{ + wxTextInputStream text(stream); + wxString line1, line2; + bool inlayer=false; + DXFLayer layer; + while (stream.CanRead()) + { + GetLines(text, line1, line2); + if (line1 == wxT("0") && inlayer) + { + // flush layer + if (!layer.name.IsEmpty() && layer.colour != -1) + { + DXFLayer *p = new DXFLayer; + p->name = layer.name; + p->colour = layer.colour; + m_layers.Append(p); + } + layer = DXFLayer(); + inlayer = false; + } + if (line1 == wxT("0") && line2 == wxT("ENDSEC")) + return true; + else if (line1 == wxT("0") && line2 == wxT("LAYER")) + inlayer = true; + else if (inlayer) + { + if (line1 == wxT("2")) // layer name + layer.name = line2; + else if (line1 == wxT("62")) // ACI colour + { + long l; + line2.ToLong(&l); + layer.colour = l; + } + } + } + return false; +} + +// parse entities section: save 3DFACE and LINE entities +bool DXFRenderer::ParseEntities(wxInputStream& stream) +{ + wxTextInputStream text(stream); + wxString line1, line2; + int state = 0; // 0: none, 1: 3DFACE, 2: LINE + DXFVector v[4]; + int colour = -1; + wxString layer; + while (stream.CanRead()) + { + GetLines(text, line1, line2); + if (line1 == wxT("0") && state > 0) + { + // flush entity + if (state == 1) // 3DFACE + { + DXFFace *p = new DXFFace; + p->v0 = v[0]; + p->v1 = v[1]; + p->v2 = v[2]; + p->v3 = v[3]; + p->CalculateNormal(); + if (colour != -1) + p->colour = colour; + else + p->colour = GetLayerColour(layer); + m_entities.Append(p); + colour = -1; layer = wxEmptyString; + v[0] = v[1] = v[2] = v[3] = DXFVector(); + state = 0; + } + else if (state == 2) // LINE + { + DXFLine *p = new DXFLine; + p->v0 = v[0]; + p->v1 = v[1]; + if (colour != -1) + p->colour = colour; + else + p->colour = GetLayerColour(layer); + m_entities.Append(p); + colour = -1; layer = wxEmptyString; + v[0] = v[1] = v[2] = v[3] = DXFVector(); + state = 0; + } + } + if (line1 == wxT("0") && line2 == wxT("ENDSEC")) + return true; + else if (line1 == wxT("0") && line2 == wxT("3DFACE")) + state = 1; + else if (line1 == wxT("0") && line2 == wxT("LINE")) + state = 2; + else if (state > 0) + { + double d; + line2.ToDouble(&d); + if (line1 == wxT("10")) + v[0].x = d; + else if (line1 == wxT("20")) + v[0].y = d; + else if (line1 == wxT("30")) + v[0].z = d; + else if (line1 == wxT("11")) + v[1].x = d; + else if (line1 == wxT("21")) + v[1].y = d; + else if (line1 == wxT("31")) + v[1].z = d; + else if (line1 == wxT("12")) + v[2].x = d; + else if (line1 == wxT("22")) + v[2].y = d; + else if (line1 == wxT("32")) + v[2].z = d; + else if (line1 == wxT("13")) + v[3].x = d; + else if (line1 == wxT("23")) + v[3].y = d; + else if (line1 == wxT("33")) + v[3].z = d; + else if (line1 == wxT("8")) // layer + layer = line2; + else if (line1 == wxT("62")) // colour + { + long l; + line2.ToLong(&l); + colour = l; + } + } + } + return false; +} + +// parse and load a DXF file +// currently pretty limited, but knows enought do handle 3DFACEs and LINEs +bool DXFRenderer::Load(wxInputStream& stream) +{ + Clear(); + wxTextInputStream text(stream); + + wxString line1, line2; + while (stream.CanRead()) + { + GetLines(text, line1, line2); + if (line1 == wxT("999")) // comment + continue; + else if (line1 == wxT("0") && line2 == wxT("SECTION")) + { + GetLines(text, line1, line2); + if (line1 == wxT("2")) + { + if (line2 == wxT("HEADER")) + { + if (!ParseHeader(stream)) + return false; + } + else if (line2 == wxT("TABLES")) + { + if (!ParseTables(stream)) + return false; + } + else if (line2 == wxT("ENTITIES")) + { + if (!ParseEntities(stream)) + return false; + } + } + } + } + + NormalizeEntities(); + m_loaded = true; + return true; +} + +inline float mymin(float x, float y) { return x < y ? x : y; } +inline float mymax(float x, float y) { return x > y ? x : y; } + +// Scale object boundings to [-5,5] +void DXFRenderer::NormalizeEntities() +{ + // calculate current min and max boundings of object + DXFVector minv(10e20f, 10e20f, 10e20f); + DXFVector maxv(-10e20f, -10e20f, -10e20f); + for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext()) + { + DXFEntity *p = node->GetData(); + if (p->type == DXFEntity::Line) + { + DXFLine *line = (DXFLine *)p; + const DXFVector *v[2] = { &line->v0, &line->v1 }; + for (int i = 0; i < 2; ++i) + { + minv.x = mymin(v[i]->x, minv.x); + minv.y = mymin(v[i]->y, minv.y); + minv.z = mymin(v[i]->z, minv.z); + maxv.x = mymax(v[i]->x, maxv.x); + maxv.y = mymax(v[i]->y, maxv.y); + maxv.z = mymax(v[i]->z, maxv.z); + } + } else if (p->type == DXFEntity::Face) + { + DXFFace *face = (DXFFace *)p; + const DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 }; + for (int i = 0; i < 4; ++i) + { + minv.x = mymin(v[i]->x, minv.x); + minv.y = mymin(v[i]->y, minv.y); + minv.z = mymin(v[i]->z, minv.z); + maxv.x = mymax(v[i]->x, maxv.x); + maxv.y = mymax(v[i]->y, maxv.y); + maxv.z = mymax(v[i]->z, maxv.z); + } + } + } + + // rescale object down to [-5,5] + DXFVector span(maxv.x - minv.x, maxv.y - minv.y, maxv.z - minv.z); + float factor = mymin(mymin(10.0f / span.x, 10.0f / span.y), 10.0f / span.z); + for (DXFEntityList::Node *node2 = m_entities.GetFirst(); node2; node2 = node2->GetNext()) + { + DXFEntity *p = node2->GetData(); + if (p->type == DXFEntity::Line) + { + DXFLine *line = (DXFLine *)p; + DXFVector *v[2] = { &line->v0, &line->v1 }; + for (int i = 0; i < 2; ++i) + { + v[i]->x -= minv.x + span.x/2; v[i]->x *= factor; + v[i]->y -= minv.y + span.y/2; v[i]->y *= factor; + v[i]->z -= minv.z + span.z/2; v[i]->z *= factor; + } + } else if (p->type == DXFEntity::Face) + { + DXFFace *face = (DXFFace *)p; + DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 }; + for (int i = 0; i < 4; ++i) + { + v[i]->x -= minv.x + span.x/2; v[i]->x *= factor; + v[i]->y -= minv.y + span.y/2; v[i]->y *= factor; + v[i]->z -= minv.z + span.z/2; v[i]->z *= factor; + } + } + } +} + +// OpenGL renderer for DXF entities +void DXFRenderer::Render() const +{ + if (!m_loaded) + return; + + for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext()) + { + DXFEntity *p = node->GetData(); + wxColour c = ACIColourToRGB(p->colour); + if (p->type == DXFEntity::Line) + { + DXFLine *line = (DXFLine *)p; + glBegin(GL_LINES); + glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0); + glVertex3f(line->v0.x, line->v0.y, line->v0.z); + glVertex3f(line->v1.x, line->v1.y, line->v1.z); + glEnd(); + } + else if (p->type == DXFEntity::Face) + { + DXFFace *face = (DXFFace *)p; + glBegin(GL_TRIANGLES); + glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0); + glNormal3f(face->n.x, face->n.y, face->n.z); + glVertex3f(face->v0.x, face->v0.y, face->v0.z); + glVertex3f(face->v1.x, face->v1.y, face->v1.z); + glVertex3f(face->v2.x, face->v2.y, face->v2.z); + glEnd(); + } + } +} diff --git a/samples/opengl/penguin/dxfrenderer.h b/samples/opengl/penguin/dxfrenderer.h new file mode 100644 index 0000000000..0e803e6feb --- /dev/null +++ b/samples/opengl/penguin/dxfrenderer.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: dxfrenderer.h +// Purpose: DXF reader and renderer +// Author: Sandro Sigala +// Modified by: +// Created: 2005-11-10 +// RCS-ID: $Id$ +// Copyright: (c) Sandro Sigala +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _DXFRENDERER_H_ +#define _DXFRENDERER_H_ + +struct DXFVector +{ + DXFVector() { x = y = z = 0.0f; } + DXFVector(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } + float x, y, z; +}; + +struct DXFEntity +{ + enum Type { Line, Face } type; + int colour; +}; + +struct DXFLine: public DXFEntity +{ + DXFLine() { type = Line; } + DXFVector v0; + DXFVector v1; +}; + +struct DXFFace: public DXFEntity +{ + DXFFace() { type = Face; } + void CalculateNormal(); + DXFVector v0; + DXFVector v1; + DXFVector v2; + DXFVector v3; + DXFVector n; // normal +}; + +struct DXFLayer +{ + DXFLayer() { colour = -1; } + wxString name; + int colour; +}; + +WX_DECLARE_LIST(DXFEntity, DXFEntityList); +WX_DECLARE_LIST(DXFLayer, DXFLayerList); + +class DXFRenderer +{ +public: + DXFRenderer(); + ~DXFRenderer(); + + void Clear(); + bool Load(wxInputStream& stream); + bool IsOk() const { return m_loaded; } + void Render() const; + +private: + bool ParseHeader(wxInputStream& stream); + bool ParseTables(wxInputStream& stream); + bool ParseEntities(wxInputStream& stream); + int GetLayerColour(const wxString& layer) const; + void NormalizeEntities(); + + bool m_loaded; + DXFLayerList m_layers; + DXFEntityList m_entities; +}; + +#endif // !_DXFRENDERER_H_ diff --git a/samples/opengl/penguin/lw.cpp b/samples/opengl/penguin/lw.cpp deleted file mode 100644 index 9b2202000c..0000000000 --- a/samples/opengl/penguin/lw.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (C) 1998 Janne Löf - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -// 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 - -#ifdef __WXMSW__ -#include -#endif - -#include "lw.h" -#include -#include - -#if wxUSE_GLCANVAS - -#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) -{ - // the execution path was not always correct - // when using the direct evaluation in the return statement - wxInt32 first = read_char(f) ; - wxInt32 second = read_char(f) ; - - return (first<<8) | second ; -} - -static wxInt32 read_long(FILE *f) -{ - // the execution path was not always correct - // when using the direct evaluation in the return statement - wxInt32 first = read_char(f) ; - wxInt32 second = read_char(f) ; - wxInt32 third = read_char(f) ; - wxInt32 fourth = read_char(f) ; - return (first<<24) | (second<<16) | (third<<8) | fourth ; -} - -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] = (char)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.7f; - material->g = 0.7f; - material->b = 0.7f; - } - lwo->material = (lwMaterial*) realloc(lwo->material, sizeof(lwMaterial)*lwo->material_cnt); -} - - -static void read_surf(FILE *f, int nbytes, lwObject *lwo) -{ - int i; - char name[LW_MAX_NAME_LEN]; - lwMaterial *material = NULL; - - /* read surface name */ - nbytes -= read_string(f,name); - - /* find material */ - for (i=0; i< lwo->material_cnt; i++) { - if (strcmp(lwo->material[i].name,name) == 0) { - material = &lwo->material[i]; - break; - } - } - - /* read values */ - while (nbytes > 0) { - int id = read_long(f); - int len = read_short(f); - nbytes -= 6 + len + (len%2); - - switch (id) { - case ID_COLR: - material->r = read_char(f) / 255.0; - material->g = read_char(f) / 255.0; - material->b = read_char(f) / 255.0; - read_char(f); /* dummy */ - break; - default: - fseek(f, len+(len%2), SEEK_CUR); - } - } -} - - -static void read_pols(FILE *f, int nbytes, lwObject *lwo) -{ - int guess_cnt = lwo->face_cnt; - - while (nbytes > 0) { - lwFace *face; - int i; - - /* allocate more memory for polygons if necessary */ - if (guess_cnt <= lwo->face_cnt) { - guess_cnt += guess_cnt + 4; - lwo->face = (lwFace*) realloc((void*) lwo->face, sizeof(lwFace)*guess_cnt); - } - face = lwo->face + lwo->face_cnt++; - - /* number of points in this face */ - face->index_cnt = read_short(f); - nbytes -= 2; - - /* allocate space for points */ - face->index = (int*) calloc(sizeof(int)*face->index_cnt,1); - - /* read points in */ - for (i=0; iindex_cnt; i++) { - face->index[i] = read_short(f); - nbytes -= 2; - } - - /* read surface material */ - face->material = read_short(f); - nbytes -= 2; - - /* skip over detail polygons */ - if (face->material < 0) { - int det_cnt; - face->material = -face->material; - det_cnt = read_short(f); - nbytes -= 2; - while (det_cnt-- > 0) { - int cnt = read_short(f); - fseek(f, cnt*2+2, SEEK_CUR); - nbytes -= cnt*2+2; - } - } - face->material -= 1; - } - /* readjust to true size */ - lwo->face = (lwFace*) realloc(lwo->face, sizeof(lwFace)*lwo->face_cnt); -} - - - -static void read_pnts(FILE *f, int nbytes, lwObject *lwo) -{ - int i; - lwo->vertex_cnt = nbytes / 12; - lwo->vertex = (float*) calloc(sizeof(GLfloat)*lwo->vertex_cnt*3, 1); - for (i=0; ivertex_cnt; i++) { - lwo->vertex[i*3+0] = read_float(f); - lwo->vertex[i*3+1] = read_float(f); - lwo->vertex[i*3+2] = read_float(f); - } -} - - - - - - -bool 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) -{ - - /* open file */ - FILE *f = fopen(lw_file, "rb"); - if (f == NULL) { - return NULL; - } - - /* check for headers */ - if (read_long(f) != ID_FORM) { - fclose(f); - return NULL; - } - - wxInt32 read_bytes = 0; - - wxInt32 form_bytes = read_long(f); - read_bytes += 4; - - if (read_long(f) != ID_LWOB) { - fclose(f); - return NULL; - } - - /* create new lwObject */ - lwObject *lw_object = (lwObject*) calloc(sizeof(lwObject),1); - - /* read chunks */ - while (read_bytes < form_bytes) { - wxInt32 id = read_long(f); - wxInt32 nbytes = read_long(f); - read_bytes += 8 + nbytes + (nbytes%2); - - switch (id) { - case ID_PNTS: - read_pnts(f, nbytes, lw_object); - break; - case ID_POLS: - read_pols(f, nbytes, lw_object); - break; - case ID_SRFS: - read_srfs(f, nbytes, lw_object); - break; - case ID_SURF: - read_surf(f, nbytes, lw_object); - break; - default: - fseek(f, nbytes + (nbytes%2), SEEK_CUR); - } - } - - fclose(f); - return lw_object; -} - - - -void lw_object_free(lwObject *lw_object) -{ - if (lw_object->face) { - int i; - for (i=0; iface_cnt; i++) - free(lw_object->face[i].index); - free(lw_object->face); - } - free(lw_object->material); - free(lw_object->vertex); - free(lw_object); -} - - - - - -#define PX(i) (lw_object->vertex[face->index[i]*3+0]) -#define PY(i) (lw_object->vertex[face->index[i]*3+1]) -#define PZ(i) (lw_object->vertex[face->index[i]*3+2]) -void lw_object_show(const lwObject *lw_object) -{ - int i,j; - int prev_index_cnt = -1; - int prev_material = -1; - GLfloat prev_nx = 0; - GLfloat prev_ny = 0; - GLfloat prev_nz = 0; - - for (i=0; iface_cnt; i++) { - GLfloat ax,ay,az,bx,by,bz,nx,ny,nz,r; - const lwFace *face = lw_object->face+i; - - /* ignore faces with less than 3 points */ - if (face->index_cnt < 3) - continue; - - /* calculate normal */ - ax = PX(1) - PX(0); - ay = PY(1) - PY(0); - az = PZ(1) - PZ(0); - - bx = PX(face->index_cnt-1) - PX(0); - by = PY(face->index_cnt-1) - PY(0); - bz = PZ(face->index_cnt-1) - PZ(0); - - nx = ay * bz - az * by; - ny = az * bx - ax * bz; - nz = ax * by - ay * bx; - - r = sqrt(nx*nx + ny*ny + nz*nz); - if (r < 0.000001) /* avoid division by zero */ - continue; - nx /= r; - ny /= r; - nz /= r; - - /* glBegin/glEnd */ - if (prev_index_cnt != face->index_cnt || prev_index_cnt > 4) { - if (prev_index_cnt > 0) glEnd(); - prev_index_cnt = face->index_cnt; - switch (face->index_cnt) { - case 3: - glBegin(GL_TRIANGLES); - break; - case 4: - glBegin(GL_QUADS); - break; - default: - glBegin(GL_POLYGON); - } - } - - /* update material if necessary */ - if (prev_material != face->material) { - prev_material = face->material; - glColor3f(lw_object->material[face->material].r, - lw_object->material[face->material].g, - lw_object->material[face->material].b); - } - - /* update normal if necessary */ - if (nx != prev_nx || ny != prev_ny || nz != prev_nz) { - prev_nx = nx; - prev_ny = ny; - prev_nz = nz; - glNormal3f(nx,ny,nz); - } - - /* draw polygon/triangle/quad */ - for (j=0; jindex_cnt; j++) - glVertex3f(PX(j),PY(j),PZ(j)); - - } - - /* if glBegin was called call glEnd */ - if (prev_index_cnt > 0) - glEnd(); -} - - -GLfloat lw_object_radius(const lwObject *lwo) -{ - int i; - double max_radius = 0.0; - - for (i=0; ivertex_cnt; i++) { - GLfloat *v = &lwo->vertex[i*3]; - double r = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (r > max_radius) - max_radius = r; - } - return sqrt(max_radius); -} - -void lw_object_scale(lwObject *lwo, GLfloat scale) -{ - int i; - - for (i=0; ivertex_cnt; i++) { - lwo->vertex[i*3+0] *= scale; - lwo->vertex[i*3+1] *= scale; - lwo->vertex[i*3+2] *= scale; - } -} - -#endif - diff --git a/samples/opengl/penguin/lw.h b/samples/opengl/penguin/lw.h deleted file mode 100644 index 0a4ca382d9..0000000000 --- a/samples/opengl/penguin/lw.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 1998 Janne Löf - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#ifndef LW_H -#define LW_H - -#ifdef __WXMAC__ -# ifdef __DARWIN__ -# include -# else -# include -# endif -#else -# include -#endif - -#define LW_MAX_POINTS 200 -#define LW_MAX_NAME_LEN 500 - -typedef struct { - char name[LW_MAX_NAME_LEN]; - GLfloat r,g,b; -} lwMaterial; - -typedef struct { - int material; /* material of this face */ - int index_cnt; /* number of vertices */ - int *index; /* index to vertex */ - float *texcoord; /* u,v texture coordinates */ -} lwFace; - -typedef struct { - int face_cnt; - lwFace *face; - - int material_cnt; - lwMaterial *material; - - int vertex_cnt; - GLfloat *vertex; - -} lwObject; - -#ifdef __cplusplus -extern "C" { -#endif - -#if wxUSE_GLCANVAS -bool 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 - -#ifdef __cplusplus -} -#endif - -#endif /* LW_H */ - diff --git a/samples/opengl/penguin/makefile.bcc b/samples/opengl/penguin/makefile.bcc index d7ef2b8dce..f2c02cf4fc 100644 --- a/samples/opengl/penguin/makefile.bcc +++ b/samples/opengl/penguin/makefile.bcc @@ -41,7 +41,7 @@ PENGUIN_CXXFLAGS = $(__RUNTIME_LIBS_7) -I$(BCCDIR)\include $(__DEBUGINFO) \ -DNOPCH $(CPPFLAGS) $(CXXFLAGS) PENGUIN_OBJECTS = \ $(OBJS)\penguin_penguin.obj \ - $(OBJS)\penguin_lw.obj \ + $(OBJS)\penguin_dxfrenderer.obj \ $(OBJS)\penguin_trackball.obj ### Conditionally set variables: ### @@ -232,12 +232,12 @@ $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res data: if not exist $(OBJS) mkdir $(OBJS) - for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS) + for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS) $(OBJS)\penguin_penguin.obj: .\penguin.cpp $(CXX) -q -c -P -o$@ $(PENGUIN_CXXFLAGS) $** -$(OBJS)\penguin_lw.obj: .\lw.cpp +$(OBJS)\penguin_dxfrenderer.obj: .\dxfrenderer.cpp $(CXX) -q -c -P -o$@ $(PENGUIN_CXXFLAGS) $** $(OBJS)\penguin_trackball.obj: .\trackball.c diff --git a/samples/opengl/penguin/makefile.gcc b/samples/opengl/penguin/makefile.gcc index 679422d256..b7cec871ba 100644 --- a/samples/opengl/penguin/makefile.gcc +++ b/samples/opengl/penguin/makefile.gcc @@ -34,7 +34,7 @@ PENGUIN_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) PENGUIN_OBJECTS = \ $(OBJS)\penguin_penguin.o \ - $(OBJS)\penguin_lw.o \ + $(OBJS)\penguin_dxfrenderer.o \ $(OBJS)\penguin_trackball.o \ $(OBJS)\penguin_penguin_rc.o @@ -225,12 +225,12 @@ endif data: if not exist $(OBJS) mkdir $(OBJS) - for %%f in (penguin.lwo) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) + for %%f in (penguin.dxf.gz) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) $(OBJS)\penguin_penguin.o: ./penguin.cpp $(CXX) -c -o $@ $(PENGUIN_CXXFLAGS) $(CPPDEPS) $< -$(OBJS)\penguin_lw.o: ./lw.cpp +$(OBJS)\penguin_dxfrenderer.o: ./dxfrenderer.cpp $(CXX) -c -o $@ $(PENGUIN_CXXFLAGS) $(CPPDEPS) $< $(OBJS)\penguin_trackball.o: ./trackball.c diff --git a/samples/opengl/penguin/makefile.vc b/samples/opengl/penguin/makefile.vc index a0f51e19da..ee2bdd6039 100644 --- a/samples/opengl/penguin/makefile.vc +++ b/samples/opengl/penguin/makefile.vc @@ -35,7 +35,7 @@ PENGUIN_CXXFLAGS = /M$(__RUNTIME_LIBS_8)$(__DEBUGRUNTIME_3) /DWIN32 \ $(CPPFLAGS) $(CXXFLAGS) PENGUIN_OBJECTS = \ $(OBJS)\penguin_penguin.obj \ - $(OBJS)\penguin_lw.obj \ + $(OBJS)\penguin_dxfrenderer.obj \ $(OBJS)\penguin_trackball.obj \ $(OBJS)\penguin_penguin.res @@ -302,12 +302,12 @@ $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res data: if not exist $(OBJS) mkdir $(OBJS) - for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS) + for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS) $(OBJS)\penguin_penguin.obj: .\penguin.cpp $(CXX) /c /nologo /TP /Fo$@ $(PENGUIN_CXXFLAGS) $** -$(OBJS)\penguin_lw.obj: .\lw.cpp +$(OBJS)\penguin_dxfrenderer.obj: .\dxfrenderer.cpp $(CXX) /c /nologo /TP /Fo$@ $(PENGUIN_CXXFLAGS) $** $(OBJS)\penguin_trackball.obj: .\trackball.c diff --git a/samples/opengl/penguin/makefile.wat b/samples/opengl/penguin/makefile.wat index b2794d9408..32f0074fbc 100644 --- a/samples/opengl/penguin/makefile.wat +++ b/samples/opengl/penguin/makefile.wat @@ -225,7 +225,7 @@ PENGUIN_CXXFLAGS = $(__DEBUGINFO_0) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG_5) & $(__RTTIFLAG_7) $(__EXCEPTIONSFLAG_8) $(CPPFLAGS) $(CXXFLAGS) PENGUIN_OBJECTS = & $(OBJS)\penguin_penguin.obj & - $(OBJS)\penguin_lw.obj & + $(OBJS)\penguin_dxfrenderer.obj & $(OBJS)\penguin_trackball.obj @@ -260,16 +260,16 @@ $(OBJS)\penguin.exe : $(PENGUIN_OBJECTS) $(OBJS)\penguin_penguin.res data : .SYMBOLIC if not exist $(OBJS) mkdir $(OBJS) - for %f in (penguin.lwo) do if not exist $(OBJS)\%f copy .\%f $(OBJS) + for %f in (penguin.dxf.gz) do if not exist $(OBJS)\%f copy .\%f $(OBJS) $(OBJS)\penguin_penguin.obj : .AUTODEPEND .\penguin.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $< + $(CXX) -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $< -$(OBJS)\penguin_lw.obj : .AUTODEPEND .\lw.cpp - $(CXX) -bt=nt -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $< +$(OBJS)\penguin_dxfrenderer.obj : .AUTODEPEND .\dxfrenderer.cpp + $(CXX) -zq -fo=$^@ $(PENGUIN_CXXFLAGS) $< $(OBJS)\penguin_trackball.obj : .AUTODEPEND .\trackball.c - $(CC) -bt=nt -zq -fo=$^@ $(PENGUIN_CFLAGS) $< + $(CC) -zq -fo=$^@ $(PENGUIN_CFLAGS) $< $(OBJS)\penguin_penguin.res : .AUTODEPEND .\penguin.rc wrc -q -ad -bt=nt -r -fo=$^@ -d__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -i=.\..\..\..\include -i=$(SETUPHDIR) -i=. $(__DLLFLAG_p) -i=.\..\..\..\samples -dNOPCH $< diff --git a/samples/opengl/penguin/penguin.bkl b/samples/opengl/penguin/penguin.bkl index 880e4e9fd4..28b64c2bae 100644 --- a/samples/opengl/penguin/penguin.bkl +++ b/samples/opengl/penguin/penguin.bkl @@ -8,7 +8,7 @@ penguin.cpp - lw.cpp + dxfrenderer.cpp trackball.c gl @@ -19,7 +19,7 @@ - penguin.lwo + penguin.dxf.gz diff --git a/samples/opengl/penguin/penguin.cpp b/samples/opengl/penguin/penguin.cpp index 93634a4060..f753b518bc 100644 --- a/samples/opengl/penguin/penguin.cpp +++ b/samples/opengl/penguin/penguin.cpp @@ -2,7 +2,7 @@ // Name: penguin.cpp // Purpose: wxGLCanvas demo program // Author: Robert Roebling -// Modified by: +// Modified by: Sandro Sigala // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Robert Roebling @@ -37,28 +37,24 @@ #include "../../sample.xpm" -#define VIEW_ASPECT 1.3 +// --------------------------------------------------------------------------- +// MyApp +// --------------------------------------------------------------------------- // `Main program' equivalent, creating windows and returning main app frame bool MyApp::OnInit() { // Create the main frame window - MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets OpenGL Penguin Sample"), + MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets Penguin Sample"), wxDefaultPosition, wxDefaultSize); - /* Make a menubar */ - wxMenu *fileMenu = new wxMenu; - - fileMenu->Append(wxID_EXIT, wxT("E&xit")); - wxMenuBar *menuBar = new wxMenuBar; - menuBar->Append(fileMenu, wxT("&File")); - frame->SetMenuBar(menuBar); - - frame->SetCanvas( new TestGLCanvas(frame, wxID_ANY, wxDefaultPosition, - wxSize(200, 200), wxSUNKEN_BORDER) ); - - /* Load file wiht mesh data */ - frame->GetCanvas()->LoadLWO( wxT("penguin.lwo") ); +#if wxUSE_ZLIB + if (wxFileExists(wxT("penguin.dxf.gz"))) + frame->GetCanvas()->LoadDXF(wxT("penguin.dxf.gz")); +#else + if (wxFileExists(wxT("penguin.dxf"))) + frame->GetCanvas()->LoadDXF(wxT("penguin.dxf")); +#endif /* Show the frame */ frame->Show(true); @@ -68,26 +64,75 @@ bool MyApp::OnInit() IMPLEMENT_APP(MyApp) +// --------------------------------------------------------------------------- +// MyFrame +// --------------------------------------------------------------------------- + BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(wxID_EXIT, MyFrame::OnExit) + EVT_MENU(wxID_OPEN, MyFrame::OnMenuFileOpen) + EVT_MENU(wxID_EXIT, MyFrame::OnMenuFileExit) + EVT_MENU(wxID_HELP, MyFrame::OnMenuHelpAbout) END_EVENT_TABLE() -/* My frame constructor */ +// MyFrame constructor MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(frame, wxID_ANY, title, pos, size, style) { - m_canvas = NULL; SetIcon(wxIcon(sample_xpm)); + + // Make the "File" menu + wxMenu *fileMenu = new wxMenu; + fileMenu->Append(wxID_OPEN, wxT("&Open...")); + fileMenu->AppendSeparator(); + fileMenu->Append(wxID_EXIT, wxT("E&xit\tALT-X")); + // Make the "Help" menu + wxMenu *helpMenu = new wxMenu; + helpMenu->Append(wxID_HELP, wxT("&About...")); + + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(fileMenu, wxT("&File")); + menuBar->Append(helpMenu, wxT("&Help")); + SetMenuBar(menuBar); + + m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition, + wxSize(300, 300), wxSUNKEN_BORDER); } -/* Intercept menu commands */ -void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) ) +// File|Open... command +void MyFrame::OnMenuFileOpen( wxCommandEvent& WXUNUSED(event) ) +{ + wxString filename = wxFileSelector(wxT("Choose DXF Model"), wxT(""), wxT(""), wxT(""), +#if wxUSE_ZLIB + wxT("DXF Drawing (*.dxf;*.dxf.gz)|*.dxf;*.dxf.gz|All files (*.*)|*.*"), +#else + wxT("DXF Drawing (*.dxf)|*.dxf)|All files (*.*)|*.*"), +#endif + wxOPEN); + if (!filename.IsEmpty()) + { + m_canvas->LoadDXF(filename); + m_canvas->Refresh(false); + } +} + +// File|Exit command +void MyFrame::OnMenuFileExit( wxCommandEvent& WXUNUSED(event) ) { // true is to force the frame to close Close(true); } +// Help|About... command +void MyFrame::OnMenuHelpAbout( wxCommandEvent& WXUNUSED(event) ) +{ + wxMessageBox(wxT("OpenGL Penguin Sample (c) Robert Roebling, Sandro Sigala et al")); +} + +// --------------------------------------------------------------------------- +// TestGLCanvas +// --------------------------------------------------------------------------- + BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_SIZE(TestGLCanvas::OnSize) EVT_PAINT(TestGLCanvas::OnPaint) @@ -99,18 +144,22 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name) { - block = false; + m_gldata.initialized = false; + + // initialize view matrix + m_gldata.beginx = 0.0f; + m_gldata.beginy = 0.0f; + m_gldata.zoom = 45.0f; + trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f); } TestGLCanvas::~TestGLCanvas() { - /* destroy mesh */ - lw_object_free(info.lwobject); } void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) { - /* must always be here */ + // must always be here wxPaintDC dc(this); #ifndef __WXMOTIF__ @@ -120,31 +169,25 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) SetCurrent(); // Initialize OpenGL - if (info.do_init) + if (!m_gldata.initialized) { InitGL(); - info.do_init = false; + ResetProjectionMode(); + m_gldata.initialized = true; } - // View - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - gluPerspective( info.zoom, VIEW_ASPECT, 1.0, 100.0 ); - glMatrixMode( GL_MODELVIEW ); - // Clear glClearColor( 0.3f, 0.4f, 0.6f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Transformations - GLfloat m[4][4]; glLoadIdentity(); - glTranslatef( 0.0f, 0.0f, -30.0f ); - build_rotmatrix( m,info.quat ); + glTranslatef( 0.0f, 0.0f, -20.0f ); + GLfloat m[4][4]; + build_rotmatrix( m, m_gldata.quat ); glMultMatrixf( &m[0][0] ); - // Draw object - lw_object_show( info.lwobject ); + m_renderer.Render(); // Flush glFlush(); @@ -157,67 +200,61 @@ void TestGLCanvas::OnSize(wxSizeEvent& event) { // this is also necessary to update the context on some platforms wxGLCanvas::OnSize(event); - - // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...) - int w, h; - GetClientSize(&w, &h); -#ifndef __WXMOTIF__ - if ( GetContext() ) -#endif - { - SetCurrent(); - glViewport(0, 0, (GLint) w, (GLint) h); - } + // Reset the OpenGL view aspect + ResetProjectionMode(); } void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) { - /* Do nothing, to avoid flashing on MSW */ + // Do nothing, to avoid flashing on MSW } -void TestGLCanvas::LoadLWO(const wxString &filename) +// Load the DXF file. If the zlib support is compiled in wxWidgets, +// supports also the ".dxf.gz" gzip compressed files. +void TestGLCanvas::LoadDXF(const wxString& filename) { - /* test if lightwave object */ - if (!lw_is_lwobject(filename.mb_str())) return; - - /* read lightwave object */ - lwObject *lwobject = lw_object_read(filename.mb_str()); - - /* 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.0f; - info.beginy = 0.0f; - info.zoom = 45.0f; - trackball( info.quat, 0.0f, 0.0f, 0.0f, 0.0f ); + wxFileInputStream stream(filename); + if (stream.Ok()) +#if wxUSE_ZLIB + { + if (filename.Right(3).Lower() == wxT(".gz")) + { + wxZlibInputStream zstream(stream); + m_renderer.Load(zstream); + } else + { + m_renderer.Load(stream); + } + } +#else + { + m_renderer.Load(stream); + } +#endif } -void TestGLCanvas::OnMouse( wxMouseEvent& event ) +void TestGLCanvas::OnMouse(wxMouseEvent& event) { - - if ( event.Dragging() ) + if (event.Dragging()) { - wxSize sz( GetClientSize() ); + wxSize sz(GetClientSize()); /* drag in progress, simulate trackball */ float spin_quat[4]; trackball(spin_quat, - (2.0*info.beginx - sz.x) / sz.x, - ( sz.y - 2.0*info.beginy) / sz.y, - ( 2.0*event.GetX() - sz.x) / sz.x, - ( sz.y - 2.0*event.GetY()) / sz.y); + (2.0*m_gldata.beginx - sz.x) / sz.x, + (sz.y - 2.0*m_gldata.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 ); + add_quats(spin_quat, m_gldata.quat, m_gldata.quat); /* orientation has changed, redraw mesh */ Refresh(false); } - info.beginx = event.GetX(); - info.beginy = event.GetY(); + m_gldata.beginx = event.GetX(); + m_gldata.beginy = event.GetY(); } void TestGLCanvas::InitGL() @@ -255,3 +292,20 @@ void TestGLCanvas::InitGL() glEnable(GL_COLOR_MATERIAL); } +void TestGLCanvas::ResetProjectionMode() +{ + int w, h; + GetClientSize(&w, &h); +#ifndef __WXMOTIF__ + if ( GetContext() ) +#endif + { + SetCurrent(); + glViewport(0, 0, (GLint) w, (GLint) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } +} diff --git a/samples/opengl/penguin/penguin.dsp b/samples/opengl/penguin/penguin.dsp index 85e23d5f27..250346abb3 100644 --- a/samples/opengl/penguin/penguin.dsp +++ b/samples/opengl/penguin/penguin.dsp @@ -468,7 +468,7 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File -SOURCE=.\lw.cpp +SOURCE=.\dxfrenderer.cpp # End Source File # Begin Source File diff --git a/samples/opengl/penguin/penguin.dxf.gz b/samples/opengl/penguin/penguin.dxf.gz new file mode 100644 index 0000000000..9a20f6e5e4 Binary files /dev/null and b/samples/opengl/penguin/penguin.dxf.gz differ diff --git a/samples/opengl/penguin/penguin.h b/samples/opengl/penguin/penguin.h index dae7ca35e9..63efc497f4 100644 --- a/samples/opengl/penguin/penguin.h +++ b/samples/opengl/penguin/penguin.h @@ -17,35 +17,37 @@ #include "wx/app.h" #include "wx/menu.h" #include "wx/dcclient.h" +#include "wx/wfstream.h" +#if wxUSE_ZLIB +#include "wx/zstream.h" +#endif #include "wx/glcanvas.h" extern "C" { -#include "lw.h" #include "trackball.h" } -/* information needed to display lightwave mesh */ -typedef struct -{ -// gint do_init; /* true if initgl not yet called */ - bool do_init; - lwObject *lwobject; /* lightwave object mesh */ - float beginx,beginy; /* position of mouse */ - float quat[4]; /* orientation of object */ - float zoom; /* field of view in degrees */ -} mesh_info; +#include "dxfrenderer.h" +// OpenGL view data +struct GLData +{ + bool initialized; // have OpenGL been initialized? + float beginx, beginy; // position of mouse + float quat[4]; // orientation of object + float zoom; // field of view in degrees +}; -/* Define a new application type */ +// Define a new application type class MyApp: public wxApp { public: bool OnInit(); }; -/* Define a new frame type */ +// Define a new frame type class TestGLCanvas; class MyFrame: public wxFrame @@ -54,7 +56,9 @@ public: MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, long style = wxDEFAULT_FRAME_STYLE); - void OnExit(wxCommandEvent& event); + void OnMenuFileOpen(wxCommandEvent& event); + void OnMenuFileExit(wxCommandEvent& event); + void OnMenuHelpAbout(wxCommandEvent& event); #if wxUSE_GLCANVAS void SetCanvas( TestGLCanvas *canvas ) { m_canvas = canvas; } @@ -79,17 +83,21 @@ public: ~TestGLCanvas(); + void LoadDXF(const wxString& filename); + +protected: void OnPaint(wxPaintEvent& event); void OnSize(wxSizeEvent& event); void OnEraseBackground(wxEraseEvent& event); - void LoadLWO( const wxString &filename); - void OnMouse( wxMouseEvent& event ); + void OnMouse(wxMouseEvent& event); + +private: void InitGL(); + void ResetProjectionMode(); - mesh_info info; - bool block; + GLData m_gldata; + DXFRenderer m_renderer; -private: DECLARE_EVENT_TABLE() }; diff --git a/samples/opengl/penguin/penguin.lwo b/samples/opengl/penguin/penguin.lwo deleted file mode 100644 index 3f5122db82..0000000000 Binary files a/samples/opengl/penguin/penguin.lwo and /dev/null differ