diff options
Diffstat (limited to 'libraries/ode-0.9/drawstuff/src')
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/Makefile.am | 21 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/Makefile.in | 507 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/drawstuff.cpp | 1597 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/internal.h | 50 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/osx.cpp | 542 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/resource.h | 28 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/resources.rc | 153 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/windows.cpp | 527 | ||||
-rw-r--r-- | libraries/ode-0.9/drawstuff/src/x11.cpp | 418 |
9 files changed, 3843 insertions, 0 deletions
diff --git a/libraries/ode-0.9/drawstuff/src/Makefile.am b/libraries/ode-0.9/drawstuff/src/Makefile.am new file mode 100644 index 0000000..ed9b2f5 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/Makefile.am | |||
@@ -0,0 +1,21 @@ | |||
1 | # We build drawstuff as a non libtool static library manually | ||
2 | # so it doesn't get installed when 'make install' is called, | ||
3 | # drawstuff is meant as an aid for testing and not as a full | ||
4 | # rendering library. | ||
5 | |||
6 | noinst_LIBRARIES = libdrawstuff.a | ||
7 | libdrawstuff_a_SOURCES = drawstuff.cpp internal.h | ||
8 | libdrawstuff_a_CXXFLAGS = @ARCHFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include | ||
9 | |||
10 | # libdrawstuff_a_LIBADD = @GL_LIBS@ | ||
11 | |||
12 | if WIN32 | ||
13 | libdrawstuff_a_SOURCES+= windows.cpp | ||
14 | endif | ||
15 | if X11 | ||
16 | libdrawstuff_a_SOURCES+= x11.cpp | ||
17 | endif | ||
18 | if OSX | ||
19 | libdrawstuff_a_SOURCES+= osx.cpp | ||
20 | endif | ||
21 | |||
diff --git a/libraries/ode-0.9/drawstuff/src/Makefile.in b/libraries/ode-0.9/drawstuff/src/Makefile.in new file mode 100644 index 0000000..0e0f633 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/Makefile.in | |||
@@ -0,0 +1,507 @@ | |||
1 | # Makefile.in generated by automake 1.10 from Makefile.am. | ||
2 | # @configure_input@ | ||
3 | |||
4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
5 | # 2003, 2004, 2005, 2006 Free Software Foundation, Inc. | ||
6 | # This Makefile.in is free software; the Free Software Foundation | ||
7 | # gives unlimited permission to copy and/or distribute it, | ||
8 | # with or without modifications, as long as this notice is preserved. | ||
9 | |||
10 | # This program is distributed in the hope that it will be useful, | ||
11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||
12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
13 | # PARTICULAR PURPOSE. | ||
14 | |||
15 | @SET_MAKE@ | ||
16 | |||
17 | # We build drawstuff as a non libtool static library manually | ||
18 | # so it doesn't get installed when 'make install' is called, | ||
19 | # drawstuff is meant as an aid for testing and not as a full | ||
20 | # rendering library. | ||
21 | |||
22 | VPATH = @srcdir@ | ||
23 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
24 | pkglibdir = $(libdir)/@PACKAGE@ | ||
25 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
26 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
27 | install_sh_DATA = $(install_sh) -c -m 644 | ||
28 | install_sh_PROGRAM = $(install_sh) -c | ||
29 | install_sh_SCRIPT = $(install_sh) -c | ||
30 | INSTALL_HEADER = $(INSTALL_DATA) | ||
31 | transform = $(program_transform_name) | ||
32 | NORMAL_INSTALL = : | ||
33 | PRE_INSTALL = : | ||
34 | POST_INSTALL = : | ||
35 | NORMAL_UNINSTALL = : | ||
36 | PRE_UNINSTALL = : | ||
37 | POST_UNINSTALL = : | ||
38 | build_triplet = @build@ | ||
39 | host_triplet = @host@ | ||
40 | target_triplet = @target@ | ||
41 | |||
42 | # libdrawstuff_a_LIBADD = @GL_LIBS@ | ||
43 | @WIN32_TRUE@am__append_1 = windows.cpp | ||
44 | @X11_TRUE@am__append_2 = x11.cpp | ||
45 | @OSX_TRUE@am__append_3 = osx.cpp | ||
46 | subdir = drawstuff/src | ||
47 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in | ||
48 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
49 | am__aclocal_m4_deps = $(top_srcdir)/configure.in | ||
50 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
51 | $(ACLOCAL_M4) | ||
52 | mkinstalldirs = $(install_sh) -d | ||
53 | CONFIG_HEADER = $(top_builddir)/include/ode/config.h | ||
54 | CONFIG_CLEAN_FILES = | ||
55 | LIBRARIES = $(noinst_LIBRARIES) | ||
56 | AR = ar | ||
57 | ARFLAGS = cru | ||
58 | libdrawstuff_a_AR = $(AR) $(ARFLAGS) | ||
59 | libdrawstuff_a_LIBADD = | ||
60 | am__libdrawstuff_a_SOURCES_DIST = drawstuff.cpp internal.h windows.cpp \ | ||
61 | x11.cpp osx.cpp | ||
62 | @WIN32_TRUE@am__objects_1 = libdrawstuff_a-windows.$(OBJEXT) | ||
63 | @X11_TRUE@am__objects_2 = libdrawstuff_a-x11.$(OBJEXT) | ||
64 | @OSX_TRUE@am__objects_3 = libdrawstuff_a-osx.$(OBJEXT) | ||
65 | am_libdrawstuff_a_OBJECTS = libdrawstuff_a-drawstuff.$(OBJEXT) \ | ||
66 | $(am__objects_1) $(am__objects_2) $(am__objects_3) | ||
67 | libdrawstuff_a_OBJECTS = $(am_libdrawstuff_a_OBJECTS) | ||
68 | DEFAULT_INCLUDES = -I. -I$(top_builddir)/include/ode@am__isrc@ | ||
69 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
70 | am__depfiles_maybe = depfiles | ||
71 | CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ | ||
72 | $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) | ||
73 | CXXLD = $(CXX) | ||
74 | CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ | ||
75 | -o $@ | ||
76 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
77 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
78 | CCLD = $(CC) | ||
79 | LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
80 | SOURCES = $(libdrawstuff_a_SOURCES) | ||
81 | DIST_SOURCES = $(am__libdrawstuff_a_SOURCES_DIST) | ||
82 | ETAGS = etags | ||
83 | CTAGS = ctags | ||
84 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
85 | ACLOCAL = @ACLOCAL@ | ||
86 | ALLOCA = @ALLOCA@ | ||
87 | AMTAR = @AMTAR@ | ||
88 | ARCHFLAGS = @ARCHFLAGS@ | ||
89 | AUTOCONF = @AUTOCONF@ | ||
90 | AUTOHEADER = @AUTOHEADER@ | ||
91 | AUTOMAKE = @AUTOMAKE@ | ||
92 | AWK = @AWK@ | ||
93 | CC = @CC@ | ||
94 | CCDEPMODE = @CCDEPMODE@ | ||
95 | CFLAGS = @CFLAGS@ | ||
96 | CPP = @CPP@ | ||
97 | CPPFLAGS = @CPPFLAGS@ | ||
98 | CXX = @CXX@ | ||
99 | CXXDEPMODE = @CXXDEPMODE@ | ||
100 | CXXFLAGS = @CXXFLAGS@ | ||
101 | CYGPATH_W = @CYGPATH_W@ | ||
102 | DEFS = @DEFS@ | ||
103 | DEPDIR = @DEPDIR@ | ||
104 | DRAWSTUFF = @DRAWSTUFF@ | ||
105 | ECHO_C = @ECHO_C@ | ||
106 | ECHO_N = @ECHO_N@ | ||
107 | ECHO_T = @ECHO_T@ | ||
108 | EGREP = @EGREP@ | ||
109 | EXEEXT = @EXEEXT@ | ||
110 | GL_LIBS = @GL_LIBS@ | ||
111 | GREP = @GREP@ | ||
112 | INSTALL = @INSTALL@ | ||
113 | INSTALL_DATA = @INSTALL_DATA@ | ||
114 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
115 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
116 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
117 | LDFLAGS = @LDFLAGS@ | ||
118 | LIBOBJS = @LIBOBJS@ | ||
119 | LIBS = @LIBS@ | ||
120 | LTLIBOBJS = @LTLIBOBJS@ | ||
121 | MAKEINFO = @MAKEINFO@ | ||
122 | MKDIR_P = @MKDIR_P@ | ||
123 | OBJEXT = @OBJEXT@ | ||
124 | ODE_AGE = @ODE_AGE@ | ||
125 | ODE_CURRENT = @ODE_CURRENT@ | ||
126 | ODE_RELEASE = @ODE_RELEASE@ | ||
127 | ODE_REVISION = @ODE_REVISION@ | ||
128 | ODE_SONAME = @ODE_SONAME@ | ||
129 | PACKAGE = @PACKAGE@ | ||
130 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
131 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
132 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
133 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
134 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
135 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
136 | RANLIB = @RANLIB@ | ||
137 | SET_MAKE = @SET_MAKE@ | ||
138 | SHARED_LDFLAGS = @SHARED_LDFLAGS@ | ||
139 | SHELL = @SHELL@ | ||
140 | STRIP = @STRIP@ | ||
141 | TOPDIR = @TOPDIR@ | ||
142 | VERSION = @VERSION@ | ||
143 | WINDRES = @WINDRES@ | ||
144 | XMKMF = @XMKMF@ | ||
145 | X_CFLAGS = @X_CFLAGS@ | ||
146 | X_EXTRA_LIBS = @X_EXTRA_LIBS@ | ||
147 | X_LIBS = @X_LIBS@ | ||
148 | X_PRE_LIBS = @X_PRE_LIBS@ | ||
149 | abs_builddir = @abs_builddir@ | ||
150 | abs_srcdir = @abs_srcdir@ | ||
151 | abs_top_builddir = @abs_top_builddir@ | ||
152 | abs_top_srcdir = @abs_top_srcdir@ | ||
153 | ac_ct_CC = @ac_ct_CC@ | ||
154 | ac_ct_CXX = @ac_ct_CXX@ | ||
155 | ac_ct_WINDRES = @ac_ct_WINDRES@ | ||
156 | am__include = @am__include@ | ||
157 | am__leading_dot = @am__leading_dot@ | ||
158 | am__quote = @am__quote@ | ||
159 | am__tar = @am__tar@ | ||
160 | am__untar = @am__untar@ | ||
161 | bindir = @bindir@ | ||
162 | build = @build@ | ||
163 | build_alias = @build_alias@ | ||
164 | build_cpu = @build_cpu@ | ||
165 | build_os = @build_os@ | ||
166 | build_vendor = @build_vendor@ | ||
167 | builddir = @builddir@ | ||
168 | datadir = @datadir@ | ||
169 | datarootdir = @datarootdir@ | ||
170 | docdir = @docdir@ | ||
171 | dvidir = @dvidir@ | ||
172 | exec_prefix = @exec_prefix@ | ||
173 | host = @host@ | ||
174 | host_alias = @host_alias@ | ||
175 | host_cpu = @host_cpu@ | ||
176 | host_os = @host_os@ | ||
177 | host_vendor = @host_vendor@ | ||
178 | htmldir = @htmldir@ | ||
179 | includedir = @includedir@ | ||
180 | infodir = @infodir@ | ||
181 | install_sh = @install_sh@ | ||
182 | libdir = @libdir@ | ||
183 | libexecdir = @libexecdir@ | ||
184 | localedir = @localedir@ | ||
185 | localstatedir = @localstatedir@ | ||
186 | mandir = @mandir@ | ||
187 | mkdir_p = @mkdir_p@ | ||
188 | oldincludedir = @oldincludedir@ | ||
189 | pdfdir = @pdfdir@ | ||
190 | prefix = @prefix@ | ||
191 | program_transform_name = @program_transform_name@ | ||
192 | psdir = @psdir@ | ||
193 | sbindir = @sbindir@ | ||
194 | sharedstatedir = @sharedstatedir@ | ||
195 | so_ext = @so_ext@ | ||
196 | srcdir = @srcdir@ | ||
197 | sysconfdir = @sysconfdir@ | ||
198 | target = @target@ | ||
199 | target_alias = @target_alias@ | ||
200 | target_cpu = @target_cpu@ | ||
201 | target_os = @target_os@ | ||
202 | target_vendor = @target_vendor@ | ||
203 | top_builddir = @top_builddir@ | ||
204 | top_srcdir = @top_srcdir@ | ||
205 | noinst_LIBRARIES = libdrawstuff.a | ||
206 | libdrawstuff_a_SOURCES = drawstuff.cpp internal.h $(am__append_1) \ | ||
207 | $(am__append_2) $(am__append_3) | ||
208 | libdrawstuff_a_CXXFLAGS = @ARCHFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include | ||
209 | all: all-am | ||
210 | |||
211 | .SUFFIXES: | ||
212 | .SUFFIXES: .cpp .o .obj | ||
213 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) | ||
214 | @for dep in $?; do \ | ||
215 | case '$(am__configure_deps)' in \ | ||
216 | *$$dep*) \ | ||
217 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ | ||
218 | && exit 0; \ | ||
219 | exit 1;; \ | ||
220 | esac; \ | ||
221 | done; \ | ||
222 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign drawstuff/src/Makefile'; \ | ||
223 | cd $(top_srcdir) && \ | ||
224 | $(AUTOMAKE) --foreign drawstuff/src/Makefile | ||
225 | .PRECIOUS: Makefile | ||
226 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | ||
227 | @case '$?' in \ | ||
228 | *config.status*) \ | ||
229 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | ||
230 | *) \ | ||
231 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ | ||
232 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ | ||
233 | esac; | ||
234 | |||
235 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||
236 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
237 | |||
238 | $(top_srcdir)/configure: $(am__configure_deps) | ||
239 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
240 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) | ||
241 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
242 | |||
243 | clean-noinstLIBRARIES: | ||
244 | -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) | ||
245 | libdrawstuff.a: $(libdrawstuff_a_OBJECTS) $(libdrawstuff_a_DEPENDENCIES) | ||
246 | -rm -f libdrawstuff.a | ||
247 | $(libdrawstuff_a_AR) libdrawstuff.a $(libdrawstuff_a_OBJECTS) $(libdrawstuff_a_LIBADD) | ||
248 | $(RANLIB) libdrawstuff.a | ||
249 | |||
250 | mostlyclean-compile: | ||
251 | -rm -f *.$(OBJEXT) | ||
252 | |||
253 | distclean-compile: | ||
254 | -rm -f *.tab.c | ||
255 | |||
256 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-drawstuff.Po@am__quote@ | ||
257 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-osx.Po@am__quote@ | ||
258 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-windows.Po@am__quote@ | ||
259 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-x11.Po@am__quote@ | ||
260 | |||
261 | .cpp.o: | ||
262 | @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
263 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
264 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
265 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
266 | @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< | ||
267 | |||
268 | .cpp.obj: | ||
269 | @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` | ||
270 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
271 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
272 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
273 | @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` | ||
274 | |||
275 | libdrawstuff_a-drawstuff.o: drawstuff.cpp | ||
276 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-drawstuff.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo -c -o libdrawstuff_a-drawstuff.o `test -f 'drawstuff.cpp' || echo '$(srcdir)/'`drawstuff.cpp | ||
277 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo $(DEPDIR)/libdrawstuff_a-drawstuff.Po | ||
278 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='drawstuff.cpp' object='libdrawstuff_a-drawstuff.o' libtool=no @AMDEPBACKSLASH@ | ||
279 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
280 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-drawstuff.o `test -f 'drawstuff.cpp' || echo '$(srcdir)/'`drawstuff.cpp | ||
281 | |||
282 | libdrawstuff_a-drawstuff.obj: drawstuff.cpp | ||
283 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-drawstuff.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo -c -o libdrawstuff_a-drawstuff.obj `if test -f 'drawstuff.cpp'; then $(CYGPATH_W) 'drawstuff.cpp'; else $(CYGPATH_W) '$(srcdir)/drawstuff.cpp'; fi` | ||
284 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo $(DEPDIR)/libdrawstuff_a-drawstuff.Po | ||
285 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='drawstuff.cpp' object='libdrawstuff_a-drawstuff.obj' libtool=no @AMDEPBACKSLASH@ | ||
286 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
287 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-drawstuff.obj `if test -f 'drawstuff.cpp'; then $(CYGPATH_W) 'drawstuff.cpp'; else $(CYGPATH_W) '$(srcdir)/drawstuff.cpp'; fi` | ||
288 | |||
289 | libdrawstuff_a-windows.o: windows.cpp | ||
290 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-windows.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-windows.Tpo -c -o libdrawstuff_a-windows.o `test -f 'windows.cpp' || echo '$(srcdir)/'`windows.cpp | ||
291 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-windows.Tpo $(DEPDIR)/libdrawstuff_a-windows.Po | ||
292 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='windows.cpp' object='libdrawstuff_a-windows.o' libtool=no @AMDEPBACKSLASH@ | ||
293 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
294 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-windows.o `test -f 'windows.cpp' || echo '$(srcdir)/'`windows.cpp | ||
295 | |||
296 | libdrawstuff_a-windows.obj: windows.cpp | ||
297 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-windows.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-windows.Tpo -c -o libdrawstuff_a-windows.obj `if test -f 'windows.cpp'; then $(CYGPATH_W) 'windows.cpp'; else $(CYGPATH_W) '$(srcdir)/windows.cpp'; fi` | ||
298 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-windows.Tpo $(DEPDIR)/libdrawstuff_a-windows.Po | ||
299 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='windows.cpp' object='libdrawstuff_a-windows.obj' libtool=no @AMDEPBACKSLASH@ | ||
300 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
301 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-windows.obj `if test -f 'windows.cpp'; then $(CYGPATH_W) 'windows.cpp'; else $(CYGPATH_W) '$(srcdir)/windows.cpp'; fi` | ||
302 | |||
303 | libdrawstuff_a-x11.o: x11.cpp | ||
304 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-x11.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-x11.Tpo -c -o libdrawstuff_a-x11.o `test -f 'x11.cpp' || echo '$(srcdir)/'`x11.cpp | ||
305 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-x11.Tpo $(DEPDIR)/libdrawstuff_a-x11.Po | ||
306 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='x11.cpp' object='libdrawstuff_a-x11.o' libtool=no @AMDEPBACKSLASH@ | ||
307 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
308 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-x11.o `test -f 'x11.cpp' || echo '$(srcdir)/'`x11.cpp | ||
309 | |||
310 | libdrawstuff_a-x11.obj: x11.cpp | ||
311 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-x11.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-x11.Tpo -c -o libdrawstuff_a-x11.obj `if test -f 'x11.cpp'; then $(CYGPATH_W) 'x11.cpp'; else $(CYGPATH_W) '$(srcdir)/x11.cpp'; fi` | ||
312 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-x11.Tpo $(DEPDIR)/libdrawstuff_a-x11.Po | ||
313 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='x11.cpp' object='libdrawstuff_a-x11.obj' libtool=no @AMDEPBACKSLASH@ | ||
314 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
315 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-x11.obj `if test -f 'x11.cpp'; then $(CYGPATH_W) 'x11.cpp'; else $(CYGPATH_W) '$(srcdir)/x11.cpp'; fi` | ||
316 | |||
317 | libdrawstuff_a-osx.o: osx.cpp | ||
318 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-osx.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-osx.Tpo -c -o libdrawstuff_a-osx.o `test -f 'osx.cpp' || echo '$(srcdir)/'`osx.cpp | ||
319 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-osx.Tpo $(DEPDIR)/libdrawstuff_a-osx.Po | ||
320 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='osx.cpp' object='libdrawstuff_a-osx.o' libtool=no @AMDEPBACKSLASH@ | ||
321 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
322 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-osx.o `test -f 'osx.cpp' || echo '$(srcdir)/'`osx.cpp | ||
323 | |||
324 | libdrawstuff_a-osx.obj: osx.cpp | ||
325 | @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-osx.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-osx.Tpo -c -o libdrawstuff_a-osx.obj `if test -f 'osx.cpp'; then $(CYGPATH_W) 'osx.cpp'; else $(CYGPATH_W) '$(srcdir)/osx.cpp'; fi` | ||
326 | @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-osx.Tpo $(DEPDIR)/libdrawstuff_a-osx.Po | ||
327 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='osx.cpp' object='libdrawstuff_a-osx.obj' libtool=no @AMDEPBACKSLASH@ | ||
328 | @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
329 | @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-osx.obj `if test -f 'osx.cpp'; then $(CYGPATH_W) 'osx.cpp'; else $(CYGPATH_W) '$(srcdir)/osx.cpp'; fi` | ||
330 | |||
331 | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||
332 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
333 | unique=`for i in $$list; do \ | ||
334 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
335 | done | \ | ||
336 | $(AWK) ' { files[$$0] = 1; } \ | ||
337 | END { for (i in files) print i; }'`; \ | ||
338 | mkid -fID $$unique | ||
339 | tags: TAGS | ||
340 | |||
341 | TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
342 | $(TAGS_FILES) $(LISP) | ||
343 | tags=; \ | ||
344 | here=`pwd`; \ | ||
345 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
346 | unique=`for i in $$list; do \ | ||
347 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
348 | done | \ | ||
349 | $(AWK) ' { files[$$0] = 1; } \ | ||
350 | END { for (i in files) print i; }'`; \ | ||
351 | if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ | ||
352 | test -n "$$unique" || unique=$$empty_fix; \ | ||
353 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
354 | $$tags $$unique; \ | ||
355 | fi | ||
356 | ctags: CTAGS | ||
357 | CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
358 | $(TAGS_FILES) $(LISP) | ||
359 | tags=; \ | ||
360 | here=`pwd`; \ | ||
361 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
362 | unique=`for i in $$list; do \ | ||
363 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
364 | done | \ | ||
365 | $(AWK) ' { files[$$0] = 1; } \ | ||
366 | END { for (i in files) print i; }'`; \ | ||
367 | test -z "$(CTAGS_ARGS)$$tags$$unique" \ | ||
368 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ | ||
369 | $$tags $$unique | ||
370 | |||
371 | GTAGS: | ||
372 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
373 | && cd $(top_srcdir) \ | ||
374 | && gtags -i $(GTAGS_ARGS) $$here | ||
375 | |||
376 | distclean-tags: | ||
377 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
378 | |||
379 | distdir: $(DISTFILES) | ||
380 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
381 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
382 | list='$(DISTFILES)'; \ | ||
383 | dist_files=`for file in $$list; do echo $$file; done | \ | ||
384 | sed -e "s|^$$srcdirstrip/||;t" \ | ||
385 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | ||
386 | case $$dist_files in \ | ||
387 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | ||
388 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | ||
389 | sort -u` ;; \ | ||
390 | esac; \ | ||
391 | for file in $$dist_files; do \ | ||
392 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | ||
393 | if test -d $$d/$$file; then \ | ||
394 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | ||
395 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | ||
396 | cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ | ||
397 | fi; \ | ||
398 | cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ | ||
399 | else \ | ||
400 | test -f $(distdir)/$$file \ | ||
401 | || cp -p $$d/$$file $(distdir)/$$file \ | ||
402 | || exit 1; \ | ||
403 | fi; \ | ||
404 | done | ||
405 | check-am: all-am | ||
406 | check: check-am | ||
407 | all-am: Makefile $(LIBRARIES) | ||
408 | installdirs: | ||
409 | install: install-am | ||
410 | install-exec: install-exec-am | ||
411 | install-data: install-data-am | ||
412 | uninstall: uninstall-am | ||
413 | |||
414 | install-am: all-am | ||
415 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
416 | |||
417 | installcheck: installcheck-am | ||
418 | install-strip: | ||
419 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | ||
420 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | ||
421 | `test -z '$(STRIP)' || \ | ||
422 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install | ||
423 | mostlyclean-generic: | ||
424 | |||
425 | clean-generic: | ||
426 | |||
427 | distclean-generic: | ||
428 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | ||
429 | |||
430 | maintainer-clean-generic: | ||
431 | @echo "This command is intended for maintainers to use" | ||
432 | @echo "it deletes files that may require special tools to rebuild." | ||
433 | clean: clean-am | ||
434 | |||
435 | clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am | ||
436 | |||
437 | distclean: distclean-am | ||
438 | -rm -rf ./$(DEPDIR) | ||
439 | -rm -f Makefile | ||
440 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
441 | distclean-tags | ||
442 | |||
443 | dvi: dvi-am | ||
444 | |||
445 | dvi-am: | ||
446 | |||
447 | html: html-am | ||
448 | |||
449 | info: info-am | ||
450 | |||
451 | info-am: | ||
452 | |||
453 | install-data-am: | ||
454 | |||
455 | install-dvi: install-dvi-am | ||
456 | |||
457 | install-exec-am: | ||
458 | |||
459 | install-html: install-html-am | ||
460 | |||
461 | install-info: install-info-am | ||
462 | |||
463 | install-man: | ||
464 | |||
465 | install-pdf: install-pdf-am | ||
466 | |||
467 | install-ps: install-ps-am | ||
468 | |||
469 | installcheck-am: | ||
470 | |||
471 | maintainer-clean: maintainer-clean-am | ||
472 | -rm -rf ./$(DEPDIR) | ||
473 | -rm -f Makefile | ||
474 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
475 | |||
476 | mostlyclean: mostlyclean-am | ||
477 | |||
478 | mostlyclean-am: mostlyclean-compile mostlyclean-generic | ||
479 | |||
480 | pdf: pdf-am | ||
481 | |||
482 | pdf-am: | ||
483 | |||
484 | ps: ps-am | ||
485 | |||
486 | ps-am: | ||
487 | |||
488 | uninstall-am: | ||
489 | |||
490 | .MAKE: install-am install-strip | ||
491 | |||
492 | .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ | ||
493 | clean-noinstLIBRARIES ctags distclean distclean-compile \ | ||
494 | distclean-generic distclean-tags distdir dvi dvi-am html \ | ||
495 | html-am info info-am install install-am install-data \ | ||
496 | install-data-am install-dvi install-dvi-am install-exec \ | ||
497 | install-exec-am install-html install-html-am install-info \ | ||
498 | install-info-am install-man install-pdf install-pdf-am \ | ||
499 | install-ps install-ps-am install-strip installcheck \ | ||
500 | installcheck-am installdirs maintainer-clean \ | ||
501 | maintainer-clean-generic mostlyclean mostlyclean-compile \ | ||
502 | mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ | ||
503 | uninstall-am | ||
504 | |||
505 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||
506 | # Otherwise a system limit (for SysV at least) may be exceeded. | ||
507 | .NOEXPORT: | ||
diff --git a/libraries/ode-0.9/drawstuff/src/drawstuff.cpp b/libraries/ode-0.9/drawstuff/src/drawstuff.cpp new file mode 100644 index 0000000..f588266 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/drawstuff.cpp | |||
@@ -0,0 +1,1597 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | /* | ||
24 | |||
25 | simple graphics. | ||
26 | |||
27 | the following command line flags can be used (typically under unix) | ||
28 | -notex Do not use any textures | ||
29 | -noshadow[s] Do not draw any shadows | ||
30 | -pause Start the simulation paused | ||
31 | |||
32 | TODO | ||
33 | ---- | ||
34 | |||
35 | manage openGL state changes better | ||
36 | |||
37 | */ | ||
38 | |||
39 | #ifdef WIN32 | ||
40 | #include <windows.h> | ||
41 | #endif | ||
42 | |||
43 | #include <ode/config.h> | ||
44 | #ifdef HAVE_APPLE_OPENGL_FRAMEWORK | ||
45 | #include <OpenGL/gl.h> | ||
46 | #include <OpenGL/glu.h> | ||
47 | #else | ||
48 | #include <GL/gl.h> | ||
49 | #include <GL/glu.h> | ||
50 | #endif | ||
51 | |||
52 | #include "drawstuff/drawstuff.h" | ||
53 | #include "internal.h" | ||
54 | |||
55 | //*************************************************************************** | ||
56 | // misc | ||
57 | |||
58 | #ifdef WIN32 | ||
59 | #define DEFAULT_PATH_TO_TEXTURES "..\\textures\\" | ||
60 | #else | ||
61 | #define DEFAULT_PATH_TO_TEXTURES "../textures/" | ||
62 | #endif | ||
63 | |||
64 | #ifndef M_PI | ||
65 | #define M_PI (3.14159265358979323846) | ||
66 | #endif | ||
67 | |||
68 | // constants to convert degrees to radians and the reverse | ||
69 | #define RAD_TO_DEG (180.0/M_PI) | ||
70 | #define DEG_TO_RAD (M_PI/180.0) | ||
71 | |||
72 | // light vector. LIGHTZ is implicitly 1 | ||
73 | #define LIGHTX (1.0f) | ||
74 | #define LIGHTY (0.4f) | ||
75 | |||
76 | // ground and sky | ||
77 | #define SHADOW_INTENSITY (0.65f) | ||
78 | #define GROUND_R (0.5f) // ground color for when there's no texture | ||
79 | #define GROUND_G (0.5f) | ||
80 | #define GROUND_B (0.3f) | ||
81 | |||
82 | const float ground_scale = 1.0f/1.0f; // ground texture scale (1/size) | ||
83 | const float ground_ofsx = 0.5; // offset of ground texture | ||
84 | const float ground_ofsy = 0.5; | ||
85 | const float sky_scale = 1.0f/4.0f; // sky texture scale (1/size) | ||
86 | const float sky_height = 1.0f; // sky height above viewpoint | ||
87 | |||
88 | //*************************************************************************** | ||
89 | // misc mathematics stuff | ||
90 | |||
91 | #define dCROSS(a,op,b,c) \ | ||
92 | (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ | ||
93 | (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ | ||
94 | (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); | ||
95 | |||
96 | |||
97 | inline float dDOT (const float *a, const float *b) | ||
98 | { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); } | ||
99 | |||
100 | |||
101 | static void normalizeVector3 (float v[3]) | ||
102 | { | ||
103 | float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; | ||
104 | if (len <= 0.0f) { | ||
105 | v[0] = 1; | ||
106 | v[1] = 0; | ||
107 | v[2] = 0; | ||
108 | } | ||
109 | else { | ||
110 | len = 1.0f / (float)sqrt(len); | ||
111 | v[0] *= len; | ||
112 | v[1] *= len; | ||
113 | v[2] *= len; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | //*************************************************************************** | ||
118 | // PPM image object | ||
119 | |||
120 | typedef unsigned char byte; | ||
121 | |||
122 | class Image { | ||
123 | int image_width,image_height; | ||
124 | byte *image_data; | ||
125 | public: | ||
126 | Image (char *filename); | ||
127 | // load from PPM file | ||
128 | ~Image(); | ||
129 | int width() { return image_width; } | ||
130 | int height() { return image_height; } | ||
131 | byte *data() { return image_data; } | ||
132 | }; | ||
133 | |||
134 | |||
135 | // skip over whitespace and comments in a stream. | ||
136 | |||
137 | static void skipWhiteSpace (char *filename, FILE *f) | ||
138 | { | ||
139 | int c,d; | ||
140 | for(;;) { | ||
141 | c = fgetc(f); | ||
142 | if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); | ||
143 | |||
144 | // skip comments | ||
145 | if (c == '#') { | ||
146 | do { | ||
147 | d = fgetc(f); | ||
148 | if (d==EOF) dsError ("unexpected end of file in \"%s\"",filename); | ||
149 | } while (d != '\n'); | ||
150 | continue; | ||
151 | } | ||
152 | |||
153 | if (c > ' ') { | ||
154 | ungetc (c,f); | ||
155 | return; | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | |||
160 | |||
161 | // read a number from a stream, this return 0 if there is none (that's okay | ||
162 | // because 0 is a bad value for all PPM numbers anyway). | ||
163 | |||
164 | static int readNumber (char *filename, FILE *f) | ||
165 | { | ||
166 | int c,n=0; | ||
167 | for(;;) { | ||
168 | c = fgetc(f); | ||
169 | if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); | ||
170 | if (c >= '0' && c <= '9') n = n*10 + (c - '0'); | ||
171 | else { | ||
172 | ungetc (c,f); | ||
173 | return n; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | |||
179 | Image::Image (char *filename) | ||
180 | { | ||
181 | FILE *f = fopen (filename,"rb"); | ||
182 | if (!f) dsError ("Can't open image file `%s'",filename); | ||
183 | |||
184 | // read in header | ||
185 | if (fgetc(f) != 'P' || fgetc(f) != '6') | ||
186 | dsError ("image file \"%s\" is not a binary PPM (no P6 header)",filename); | ||
187 | skipWhiteSpace (filename,f); | ||
188 | |||
189 | // read in image parameters | ||
190 | image_width = readNumber (filename,f); | ||
191 | skipWhiteSpace (filename,f); | ||
192 | image_height = readNumber (filename,f); | ||
193 | skipWhiteSpace (filename,f); | ||
194 | int max_value = readNumber (filename,f); | ||
195 | |||
196 | // check values | ||
197 | if (image_width < 1 || image_height < 1) | ||
198 | dsError ("bad image file \"%s\"",filename); | ||
199 | if (max_value != 255) | ||
200 | dsError ("image file \"%s\" must have color range of 255",filename); | ||
201 | |||
202 | // read either nothing, LF (10), or CR,LF (13,10) | ||
203 | int c = fgetc(f); | ||
204 | if (c == 10) { | ||
205 | // LF | ||
206 | } | ||
207 | else if (c == 13) { | ||
208 | // CR | ||
209 | c = fgetc(f); | ||
210 | if (c != 10) ungetc (c,f); | ||
211 | } | ||
212 | else ungetc (c,f); | ||
213 | |||
214 | // read in rest of data | ||
215 | image_data = new byte [image_width*image_height*3]; | ||
216 | if (fread (image_data,image_width*image_height*3,1,f) != 1) | ||
217 | dsError ("Can not read data from image file `%s'",filename); | ||
218 | fclose (f); | ||
219 | } | ||
220 | |||
221 | |||
222 | Image::~Image() | ||
223 | { | ||
224 | delete[] image_data; | ||
225 | } | ||
226 | |||
227 | //*************************************************************************** | ||
228 | // Texture object. | ||
229 | |||
230 | class Texture { | ||
231 | Image *image; | ||
232 | GLuint name; | ||
233 | public: | ||
234 | Texture (char *filename); | ||
235 | ~Texture(); | ||
236 | void bind (int modulate); | ||
237 | }; | ||
238 | |||
239 | |||
240 | Texture::Texture (char *filename) | ||
241 | { | ||
242 | image = new Image (filename); | ||
243 | glGenTextures (1,&name); | ||
244 | glBindTexture (GL_TEXTURE_2D,name); | ||
245 | |||
246 | // set pixel unpacking mode | ||
247 | glPixelStorei (GL_UNPACK_SWAP_BYTES, 0); | ||
248 | glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); | ||
249 | glPixelStorei (GL_UNPACK_ALIGNMENT, 1); | ||
250 | glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); | ||
251 | glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); | ||
252 | |||
253 | // glTexImage2D (GL_TEXTURE_2D, 0, 3, image->width(), image->height(), 0, | ||
254 | // GL_RGB, GL_UNSIGNED_BYTE, image->data()); | ||
255 | gluBuild2DMipmaps (GL_TEXTURE_2D, 3, image->width(), image->height(), | ||
256 | GL_RGB, GL_UNSIGNED_BYTE, image->data()); | ||
257 | |||
258 | // set texture parameters - will these also be bound to the texture??? | ||
259 | glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | ||
260 | glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | ||
261 | |||
262 | glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
263 | glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | ||
264 | GL_LINEAR_MIPMAP_LINEAR); | ||
265 | |||
266 | glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); | ||
267 | } | ||
268 | |||
269 | |||
270 | Texture::~Texture() | ||
271 | { | ||
272 | delete image; | ||
273 | glDeleteTextures (1,&name); | ||
274 | } | ||
275 | |||
276 | |||
277 | void Texture::bind (int modulate) | ||
278 | { | ||
279 | glBindTexture (GL_TEXTURE_2D,name); | ||
280 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, | ||
281 | modulate ? GL_MODULATE : GL_DECAL); | ||
282 | } | ||
283 | |||
284 | //*************************************************************************** | ||
285 | // the current drawing state (for when the user's step function is drawing) | ||
286 | |||
287 | static float color[4] = {0,0,0,0}; // current r,g,b,alpha color | ||
288 | static int tnum = 0; // current texture number | ||
289 | |||
290 | //*************************************************************************** | ||
291 | // OpenGL utility stuff | ||
292 | |||
293 | static void setCamera (float x, float y, float z, float h, float p, float r) | ||
294 | { | ||
295 | glMatrixMode (GL_MODELVIEW); | ||
296 | glLoadIdentity(); | ||
297 | glRotatef (90, 0,0,1); | ||
298 | glRotatef (90, 0,1,0); | ||
299 | glRotatef (r, 1,0,0); | ||
300 | glRotatef (p, 0,1,0); | ||
301 | glRotatef (-h, 0,0,1); | ||
302 | glTranslatef (-x,-y,-z); | ||
303 | } | ||
304 | |||
305 | |||
306 | // sets the material color, not the light color | ||
307 | |||
308 | static void setColor (float r, float g, float b, float alpha) | ||
309 | { | ||
310 | GLfloat light_ambient[4],light_diffuse[4],light_specular[4]; | ||
311 | light_ambient[0] = r*0.3f; | ||
312 | light_ambient[1] = g*0.3f; | ||
313 | light_ambient[2] = b*0.3f; | ||
314 | light_ambient[3] = alpha; | ||
315 | light_diffuse[0] = r*0.7f; | ||
316 | light_diffuse[1] = g*0.7f; | ||
317 | light_diffuse[2] = b*0.7f; | ||
318 | light_diffuse[3] = alpha; | ||
319 | light_specular[0] = r*0.2f; | ||
320 | light_specular[1] = g*0.2f; | ||
321 | light_specular[2] = b*0.2f; | ||
322 | light_specular[3] = alpha; | ||
323 | glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient); | ||
324 | glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse); | ||
325 | glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular); | ||
326 | glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 5.0f); | ||
327 | } | ||
328 | |||
329 | |||
330 | static void setTransform (const float pos[3], const float R[12]) | ||
331 | { | ||
332 | GLfloat matrix[16]; | ||
333 | matrix[0]=R[0]; | ||
334 | matrix[1]=R[4]; | ||
335 | matrix[2]=R[8]; | ||
336 | matrix[3]=0; | ||
337 | matrix[4]=R[1]; | ||
338 | matrix[5]=R[5]; | ||
339 | matrix[6]=R[9]; | ||
340 | matrix[7]=0; | ||
341 | matrix[8]=R[2]; | ||
342 | matrix[9]=R[6]; | ||
343 | matrix[10]=R[10]; | ||
344 | matrix[11]=0; | ||
345 | matrix[12]=pos[0]; | ||
346 | matrix[13]=pos[1]; | ||
347 | matrix[14]=pos[2]; | ||
348 | matrix[15]=1; | ||
349 | glPushMatrix(); | ||
350 | glMultMatrixf (matrix); | ||
351 | } | ||
352 | static void setTransformD (const double pos[3], const double R[12]) | ||
353 | { | ||
354 | GLdouble matrix[16]; | ||
355 | matrix[0]=R[0]; | ||
356 | matrix[1]=R[4]; | ||
357 | matrix[2]=R[8]; | ||
358 | matrix[3]=0; | ||
359 | matrix[4]=R[1]; | ||
360 | matrix[5]=R[5]; | ||
361 | matrix[6]=R[9]; | ||
362 | matrix[7]=0; | ||
363 | matrix[8]=R[2]; | ||
364 | matrix[9]=R[6]; | ||
365 | matrix[10]=R[10]; | ||
366 | matrix[11]=0; | ||
367 | matrix[12]=pos[0]; | ||
368 | matrix[13]=pos[1]; | ||
369 | matrix[14]=pos[2]; | ||
370 | matrix[15]=1; | ||
371 | glPushMatrix(); | ||
372 | glMultMatrixd (matrix); | ||
373 | } | ||
374 | |||
375 | |||
376 | // set shadow projection transform | ||
377 | |||
378 | static void setShadowTransform() | ||
379 | { | ||
380 | GLfloat matrix[16]; | ||
381 | for (int i=0; i<16; i++) matrix[i] = 0; | ||
382 | matrix[0]=1; | ||
383 | matrix[5]=1; | ||
384 | matrix[8]=-LIGHTX; | ||
385 | matrix[9]=-LIGHTY; | ||
386 | matrix[15]=1; | ||
387 | glPushMatrix(); | ||
388 | glMultMatrixf (matrix); | ||
389 | } | ||
390 | |||
391 | static void drawConvex (float *_planes,unsigned int _planecount, | ||
392 | float *_points, | ||
393 | unsigned int _pointcount, | ||
394 | unsigned int *_polygons) | ||
395 | { | ||
396 | unsigned int polyindex=0; | ||
397 | for(unsigned int i=0;i<_planecount;++i) | ||
398 | { | ||
399 | unsigned int pointcount=_polygons[polyindex]; | ||
400 | polyindex++; | ||
401 | glBegin (GL_POLYGON); | ||
402 | glNormal3f(_planes[(i*4)+0], | ||
403 | _planes[(i*4)+1], | ||
404 | _planes[(i*4)+2]); | ||
405 | for(unsigned int j=0;j<pointcount;++j) | ||
406 | { | ||
407 | glVertex3f(_points[_polygons[polyindex]*3], | ||
408 | _points[(_polygons[polyindex]*3)+1], | ||
409 | _points[(_polygons[polyindex]*3)+2]); | ||
410 | polyindex++; | ||
411 | } | ||
412 | glEnd(); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static void drawConvexD (double *_planes,unsigned int _planecount, | ||
417 | double *_points, | ||
418 | unsigned int _pointcount, | ||
419 | unsigned int *_polygons) | ||
420 | { | ||
421 | unsigned int polyindex=0; | ||
422 | for(unsigned int i=0;i<_planecount;++i) | ||
423 | { | ||
424 | unsigned int pointcount=_polygons[polyindex]; | ||
425 | polyindex++; | ||
426 | glBegin (GL_POLYGON); | ||
427 | glNormal3d(_planes[(i*4)+0], | ||
428 | _planes[(i*4)+1], | ||
429 | _planes[(i*4)+2]); | ||
430 | for(unsigned int j=0;j<pointcount;++j) | ||
431 | { | ||
432 | glVertex3d(_points[_polygons[polyindex]*3], | ||
433 | _points[(_polygons[polyindex]*3)+1], | ||
434 | _points[(_polygons[polyindex]*3)+2]); | ||
435 | polyindex++; | ||
436 | } | ||
437 | glEnd(); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | static void drawBox (const float sides[3]) | ||
442 | { | ||
443 | float lx = sides[0]*0.5f; | ||
444 | float ly = sides[1]*0.5f; | ||
445 | float lz = sides[2]*0.5f; | ||
446 | |||
447 | // sides | ||
448 | glBegin (GL_TRIANGLE_STRIP); | ||
449 | glNormal3f (-1,0,0); | ||
450 | glVertex3f (-lx,-ly,-lz); | ||
451 | glVertex3f (-lx,-ly,lz); | ||
452 | glVertex3f (-lx,ly,-lz); | ||
453 | glVertex3f (-lx,ly,lz); | ||
454 | glNormal3f (0,1,0); | ||
455 | glVertex3f (lx,ly,-lz); | ||
456 | glVertex3f (lx,ly,lz); | ||
457 | glNormal3f (1,0,0); | ||
458 | glVertex3f (lx,-ly,-lz); | ||
459 | glVertex3f (lx,-ly,lz); | ||
460 | glNormal3f (0,-1,0); | ||
461 | glVertex3f (-lx,-ly,-lz); | ||
462 | glVertex3f (-lx,-ly,lz); | ||
463 | glEnd(); | ||
464 | |||
465 | // top face | ||
466 | glBegin (GL_TRIANGLE_FAN); | ||
467 | glNormal3f (0,0,1); | ||
468 | glVertex3f (-lx,-ly,lz); | ||
469 | glVertex3f (lx,-ly,lz); | ||
470 | glVertex3f (lx,ly,lz); | ||
471 | glVertex3f (-lx,ly,lz); | ||
472 | glEnd(); | ||
473 | |||
474 | // bottom face | ||
475 | glBegin (GL_TRIANGLE_FAN); | ||
476 | glNormal3f (0,0,-1); | ||
477 | glVertex3f (-lx,-ly,-lz); | ||
478 | glVertex3f (-lx,ly,-lz); | ||
479 | glVertex3f (lx,ly,-lz); | ||
480 | glVertex3f (lx,-ly,-lz); | ||
481 | glEnd(); | ||
482 | } | ||
483 | |||
484 | |||
485 | // This is recursively subdivides a triangular area (vertices p1,p2,p3) into | ||
486 | // smaller triangles, and then draws the triangles. All triangle vertices are | ||
487 | // normalized to a distance of 1.0 from the origin (p1,p2,p3 are assumed | ||
488 | // to be already normalized). Note this is not super-fast because it draws | ||
489 | // triangles rather than triangle strips. | ||
490 | |||
491 | static void drawPatch (float p1[3], float p2[3], float p3[3], int level) | ||
492 | { | ||
493 | int i; | ||
494 | if (level > 0) { | ||
495 | float q1[3],q2[3],q3[3]; // sub-vertices | ||
496 | for (i=0; i<3; i++) { | ||
497 | q1[i] = 0.5f*(p1[i]+p2[i]); | ||
498 | q2[i] = 0.5f*(p2[i]+p3[i]); | ||
499 | q3[i] = 0.5f*(p3[i]+p1[i]); | ||
500 | } | ||
501 | float length1 = (float)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2])); | ||
502 | float length2 = (float)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2])); | ||
503 | float length3 = (float)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2])); | ||
504 | for (i=0; i<3; i++) { | ||
505 | q1[i] *= length1; | ||
506 | q2[i] *= length2; | ||
507 | q3[i] *= length3; | ||
508 | } | ||
509 | drawPatch (p1,q1,q3,level-1); | ||
510 | drawPatch (q1,p2,q2,level-1); | ||
511 | drawPatch (q1,q2,q3,level-1); | ||
512 | drawPatch (q3,q2,p3,level-1); | ||
513 | } | ||
514 | else { | ||
515 | glNormal3f (p1[0],p1[1],p1[2]); | ||
516 | glVertex3f (p1[0],p1[1],p1[2]); | ||
517 | glNormal3f (p2[0],p2[1],p2[2]); | ||
518 | glVertex3f (p2[0],p2[1],p2[2]); | ||
519 | glNormal3f (p3[0],p3[1],p3[2]); | ||
520 | glVertex3f (p3[0],p3[1],p3[2]); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | |||
525 | // draw a sphere of radius 1 | ||
526 | |||
527 | static int sphere_quality = 1; | ||
528 | |||
529 | static void drawSphere() | ||
530 | { | ||
531 | // icosahedron data for an icosahedron of radius 1.0 | ||
532 | # define ICX 0.525731112119133606f | ||
533 | # define ICZ 0.850650808352039932f | ||
534 | static GLfloat idata[12][3] = { | ||
535 | {-ICX, 0, ICZ}, | ||
536 | {ICX, 0, ICZ}, | ||
537 | {-ICX, 0, -ICZ}, | ||
538 | {ICX, 0, -ICZ}, | ||
539 | {0, ICZ, ICX}, | ||
540 | {0, ICZ, -ICX}, | ||
541 | {0, -ICZ, ICX}, | ||
542 | {0, -ICZ, -ICX}, | ||
543 | {ICZ, ICX, 0}, | ||
544 | {-ICZ, ICX, 0}, | ||
545 | {ICZ, -ICX, 0}, | ||
546 | {-ICZ, -ICX, 0} | ||
547 | }; | ||
548 | |||
549 | static int index[20][3] = { | ||
550 | {0, 4, 1}, {0, 9, 4}, | ||
551 | {9, 5, 4}, {4, 5, 8}, | ||
552 | {4, 8, 1}, {8, 10, 1}, | ||
553 | {8, 3, 10}, {5, 3, 8}, | ||
554 | {5, 2, 3}, {2, 7, 3}, | ||
555 | {7, 10, 3}, {7, 6, 10}, | ||
556 | {7, 11, 6}, {11, 0, 6}, | ||
557 | {0, 1, 6}, {6, 1, 10}, | ||
558 | {9, 0, 11}, {9, 11, 2}, | ||
559 | {9, 2, 5}, {7, 2, 11}, | ||
560 | }; | ||
561 | |||
562 | static GLuint listnum = 0; | ||
563 | if (listnum==0) { | ||
564 | listnum = glGenLists (1); | ||
565 | glNewList (listnum,GL_COMPILE); | ||
566 | glBegin (GL_TRIANGLES); | ||
567 | for (int i=0; i<20; i++) { | ||
568 | drawPatch (&idata[index[i][2]][0],&idata[index[i][1]][0], | ||
569 | &idata[index[i][0]][0],sphere_quality); | ||
570 | } | ||
571 | glEnd(); | ||
572 | glEndList(); | ||
573 | } | ||
574 | glCallList (listnum); | ||
575 | } | ||
576 | |||
577 | |||
578 | static void drawSphereShadow (float px, float py, float pz, float radius) | ||
579 | { | ||
580 | // calculate shadow constants based on light vector | ||
581 | static int init=0; | ||
582 | static float len2,len1,scale; | ||
583 | if (!init) { | ||
584 | len2 = LIGHTX*LIGHTX + LIGHTY*LIGHTY; | ||
585 | len1 = 1.0f/(float)sqrt(len2); | ||
586 | scale = (float) sqrt(len2 + 1); | ||
587 | init = 1; | ||
588 | } | ||
589 | |||
590 | // map sphere center to ground plane based on light vector | ||
591 | px -= LIGHTX*pz; | ||
592 | py -= LIGHTY*pz; | ||
593 | |||
594 | const float kx = 0.96592582628907f; | ||
595 | const float ky = 0.25881904510252f; | ||
596 | float x=radius, y=0; | ||
597 | |||
598 | glBegin (GL_TRIANGLE_FAN); | ||
599 | for (int i=0; i<24; i++) { | ||
600 | // for all points on circle, scale to elongated rotated shadow and draw | ||
601 | float x2 = (LIGHTX*x*scale - LIGHTY*y)*len1 + px; | ||
602 | float y2 = (LIGHTY*x*scale + LIGHTX*y)*len1 + py; | ||
603 | glTexCoord2f (x2*ground_scale+ground_ofsx,y2*ground_scale+ground_ofsy); | ||
604 | glVertex3f (x2,y2,0); | ||
605 | |||
606 | // rotate [x,y] vector | ||
607 | float xtmp = kx*x - ky*y; | ||
608 | y = ky*x + kx*y; | ||
609 | x = xtmp; | ||
610 | } | ||
611 | glEnd(); | ||
612 | } | ||
613 | |||
614 | |||
615 | static void drawTriangle (const float *v0, const float *v1, const float *v2, int solid) | ||
616 | { | ||
617 | float u[3],v[3],normal[3]; | ||
618 | u[0] = v1[0] - v0[0]; | ||
619 | u[1] = v1[1] - v0[1]; | ||
620 | u[2] = v1[2] - v0[2]; | ||
621 | v[0] = v2[0] - v0[0]; | ||
622 | v[1] = v2[1] - v0[1]; | ||
623 | v[2] = v2[2] - v0[2]; | ||
624 | dCROSS (normal,=,u,v); | ||
625 | normalizeVector3 (normal); | ||
626 | |||
627 | glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); | ||
628 | glNormal3fv (normal); | ||
629 | glVertex3fv (v0); | ||
630 | glVertex3fv (v1); | ||
631 | glVertex3fv (v2); | ||
632 | glEnd(); | ||
633 | } | ||
634 | |||
635 | static void drawTriangleD (const double *v0, const double *v1, const double *v2, int solid) | ||
636 | { | ||
637 | float u[3],v[3],normal[3]; | ||
638 | u[0] = float( v1[0] - v0[0] ); | ||
639 | u[1] = float( v1[1] - v0[1] ); | ||
640 | u[2] = float( v1[2] - v0[2] ); | ||
641 | v[0] = float( v2[0] - v0[0] ); | ||
642 | v[1] = float( v2[1] - v0[1] ); | ||
643 | v[2] = float( v2[2] - v0[2] ); | ||
644 | dCROSS (normal,=,u,v); | ||
645 | normalizeVector3 (normal); | ||
646 | |||
647 | glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); | ||
648 | glNormal3fv (normal); | ||
649 | glVertex3dv (v0); | ||
650 | glVertex3dv (v1); | ||
651 | glVertex3dv (v2); | ||
652 | glEnd(); | ||
653 | } | ||
654 | |||
655 | |||
656 | // draw a capped cylinder of length l and radius r, aligned along the x axis | ||
657 | |||
658 | static int capped_cylinder_quality = 3; | ||
659 | |||
660 | static void drawCapsule (float l, float r) | ||
661 | { | ||
662 | int i,j; | ||
663 | float tmp,nx,ny,nz,start_nx,start_ny,a,ca,sa; | ||
664 | // number of sides to the cylinder (divisible by 4): | ||
665 | const int n = capped_cylinder_quality*4; | ||
666 | |||
667 | l *= 0.5; | ||
668 | a = float(M_PI*2.0)/float(n); | ||
669 | sa = (float) sin(a); | ||
670 | ca = (float) cos(a); | ||
671 | |||
672 | // draw cylinder body | ||
673 | ny=1; nz=0; // normal vector = (0,ny,nz) | ||
674 | glBegin (GL_TRIANGLE_STRIP); | ||
675 | for (i=0; i<=n; i++) { | ||
676 | glNormal3d (ny,nz,0); | ||
677 | glVertex3d (ny*r,nz*r,l); | ||
678 | glNormal3d (ny,nz,0); | ||
679 | glVertex3d (ny*r,nz*r,-l); | ||
680 | // rotate ny,nz | ||
681 | tmp = ca*ny - sa*nz; | ||
682 | nz = sa*ny + ca*nz; | ||
683 | ny = tmp; | ||
684 | } | ||
685 | glEnd(); | ||
686 | |||
687 | // draw first cylinder cap | ||
688 | start_nx = 0; | ||
689 | start_ny = 1; | ||
690 | for (j=0; j<(n/4); j++) { | ||
691 | // get start_n2 = rotated start_n | ||
692 | float start_nx2 = ca*start_nx + sa*start_ny; | ||
693 | float start_ny2 = -sa*start_nx + ca*start_ny; | ||
694 | // get n=start_n and n2=start_n2 | ||
695 | nx = start_nx; ny = start_ny; nz = 0; | ||
696 | float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; | ||
697 | glBegin (GL_TRIANGLE_STRIP); | ||
698 | for (i=0; i<=n; i++) { | ||
699 | glNormal3d (ny2,nz2,nx2); | ||
700 | glVertex3d (ny2*r,nz2*r,l+nx2*r); | ||
701 | glNormal3d (ny,nz,nx); | ||
702 | glVertex3d (ny*r,nz*r,l+nx*r); | ||
703 | // rotate n,n2 | ||
704 | tmp = ca*ny - sa*nz; | ||
705 | nz = sa*ny + ca*nz; | ||
706 | ny = tmp; | ||
707 | tmp = ca*ny2- sa*nz2; | ||
708 | nz2 = sa*ny2 + ca*nz2; | ||
709 | ny2 = tmp; | ||
710 | } | ||
711 | glEnd(); | ||
712 | start_nx = start_nx2; | ||
713 | start_ny = start_ny2; | ||
714 | } | ||
715 | |||
716 | // draw second cylinder cap | ||
717 | start_nx = 0; | ||
718 | start_ny = 1; | ||
719 | for (j=0; j<(n/4); j++) { | ||
720 | // get start_n2 = rotated start_n | ||
721 | float start_nx2 = ca*start_nx - sa*start_ny; | ||
722 | float start_ny2 = sa*start_nx + ca*start_ny; | ||
723 | // get n=start_n and n2=start_n2 | ||
724 | nx = start_nx; ny = start_ny; nz = 0; | ||
725 | float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; | ||
726 | glBegin (GL_TRIANGLE_STRIP); | ||
727 | for (i=0; i<=n; i++) { | ||
728 | glNormal3d (ny,nz,nx); | ||
729 | glVertex3d (ny*r,nz*r,-l+nx*r); | ||
730 | glNormal3d (ny2,nz2,nx2); | ||
731 | glVertex3d (ny2*r,nz2*r,-l+nx2*r); | ||
732 | // rotate n,n2 | ||
733 | tmp = ca*ny - sa*nz; | ||
734 | nz = sa*ny + ca*nz; | ||
735 | ny = tmp; | ||
736 | tmp = ca*ny2- sa*nz2; | ||
737 | nz2 = sa*ny2 + ca*nz2; | ||
738 | ny2 = tmp; | ||
739 | } | ||
740 | glEnd(); | ||
741 | start_nx = start_nx2; | ||
742 | start_ny = start_ny2; | ||
743 | } | ||
744 | |||
745 | glPopMatrix(); | ||
746 | } | ||
747 | |||
748 | |||
749 | // draw a cylinder of length l and radius r, aligned along the z axis | ||
750 | |||
751 | static void drawCylinder (float l, float r, float zoffset) | ||
752 | { | ||
753 | int i; | ||
754 | float tmp,ny,nz,a,ca,sa; | ||
755 | const int n = 24; // number of sides to the cylinder (divisible by 4) | ||
756 | |||
757 | l *= 0.5; | ||
758 | a = float(M_PI*2.0)/float(n); | ||
759 | sa = (float) sin(a); | ||
760 | ca = (float) cos(a); | ||
761 | |||
762 | // draw cylinder body | ||
763 | ny=1; nz=0; // normal vector = (0,ny,nz) | ||
764 | glBegin (GL_TRIANGLE_STRIP); | ||
765 | for (i=0; i<=n; i++) { | ||
766 | glNormal3d (ny,nz,0); | ||
767 | glVertex3d (ny*r,nz*r,l+zoffset); | ||
768 | glNormal3d (ny,nz,0); | ||
769 | glVertex3d (ny*r,nz*r,-l+zoffset); | ||
770 | // rotate ny,nz | ||
771 | tmp = ca*ny - sa*nz; | ||
772 | nz = sa*ny + ca*nz; | ||
773 | ny = tmp; | ||
774 | } | ||
775 | glEnd(); | ||
776 | |||
777 | // draw top cap | ||
778 | glShadeModel (GL_FLAT); | ||
779 | ny=1; nz=0; // normal vector = (0,ny,nz) | ||
780 | glBegin (GL_TRIANGLE_FAN); | ||
781 | glNormal3d (0,0,1); | ||
782 | glVertex3d (0,0,l+zoffset); | ||
783 | for (i=0; i<=n; i++) { | ||
784 | if (i==1 || i==n/2+1) | ||
785 | setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); | ||
786 | glNormal3d (0,0,1); | ||
787 | glVertex3d (ny*r,nz*r,l+zoffset); | ||
788 | if (i==1 || i==n/2+1) | ||
789 | setColor (color[0],color[1],color[2],color[3]); | ||
790 | |||
791 | // rotate ny,nz | ||
792 | tmp = ca*ny - sa*nz; | ||
793 | nz = sa*ny + ca*nz; | ||
794 | ny = tmp; | ||
795 | } | ||
796 | glEnd(); | ||
797 | |||
798 | // draw bottom cap | ||
799 | ny=1; nz=0; // normal vector = (0,ny,nz) | ||
800 | glBegin (GL_TRIANGLE_FAN); | ||
801 | glNormal3d (0,0,-1); | ||
802 | glVertex3d (0,0,-l+zoffset); | ||
803 | for (i=0; i<=n; i++) { | ||
804 | if (i==1 || i==n/2+1) | ||
805 | setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); | ||
806 | glNormal3d (0,0,-1); | ||
807 | glVertex3d (ny*r,nz*r,-l+zoffset); | ||
808 | if (i==1 || i==n/2+1) | ||
809 | setColor (color[0],color[1],color[2],color[3]); | ||
810 | |||
811 | // rotate ny,nz | ||
812 | tmp = ca*ny + sa*nz; | ||
813 | nz = -sa*ny + ca*nz; | ||
814 | ny = tmp; | ||
815 | } | ||
816 | glEnd(); | ||
817 | } | ||
818 | |||
819 | //*************************************************************************** | ||
820 | // motion model | ||
821 | |||
822 | // current camera position and orientation | ||
823 | static float view_xyz[3]; // position x,y,z | ||
824 | static float view_hpr[3]; // heading, pitch, roll (degrees) | ||
825 | |||
826 | |||
827 | // initialize the above variables | ||
828 | |||
829 | static void initMotionModel() | ||
830 | { | ||
831 | view_xyz[0] = 2; | ||
832 | view_xyz[1] = 0; | ||
833 | view_xyz[2] = 1; | ||
834 | view_hpr[0] = 180; | ||
835 | view_hpr[1] = 0; | ||
836 | view_hpr[2] = 0; | ||
837 | } | ||
838 | |||
839 | |||
840 | static void wrapCameraAngles() | ||
841 | { | ||
842 | for (int i=0; i<3; i++) { | ||
843 | while (view_hpr[i] > 180) view_hpr[i] -= 360; | ||
844 | while (view_hpr[i] < -180) view_hpr[i] += 360; | ||
845 | } | ||
846 | } | ||
847 | |||
848 | |||
849 | // call this to update the current camera position. the bits in `mode' say | ||
850 | // if the left (1), middle (2) or right (4) mouse button is pressed, and | ||
851 | // (deltax,deltay) is the amount by which the mouse pointer has moved. | ||
852 | |||
853 | void dsMotion (int mode, int deltax, int deltay) | ||
854 | { | ||
855 | float side = 0.01f * float(deltax); | ||
856 | float fwd = (mode==4) ? (0.01f * float(deltay)) : 0.0f; | ||
857 | float s = (float) sin (view_hpr[0]*DEG_TO_RAD); | ||
858 | float c = (float) cos (view_hpr[0]*DEG_TO_RAD); | ||
859 | |||
860 | if (mode==1) { | ||
861 | view_hpr[0] += float (deltax) * 0.5f; | ||
862 | view_hpr[1] += float (deltay) * 0.5f; | ||
863 | } | ||
864 | else { | ||
865 | view_xyz[0] += -s*side + c*fwd; | ||
866 | view_xyz[1] += c*side + s*fwd; | ||
867 | if (mode==2 || mode==5) view_xyz[2] += 0.01f * float(deltay); | ||
868 | } | ||
869 | wrapCameraAngles(); | ||
870 | } | ||
871 | |||
872 | //*************************************************************************** | ||
873 | // drawing loop stuff | ||
874 | |||
875 | // the current state: | ||
876 | // 0 = uninitialized | ||
877 | // 1 = dsSimulationLoop() called | ||
878 | // 2 = dsDrawFrame() called | ||
879 | static int current_state = 0; | ||
880 | |||
881 | // textures and shadows | ||
882 | static int use_textures=1; // 1 if textures to be drawn | ||
883 | static int use_shadows=1; // 1 if shadows to be drawn | ||
884 | static Texture *sky_texture = 0; | ||
885 | static Texture *ground_texture = 0; | ||
886 | static Texture *wood_texture = 0; | ||
887 | |||
888 | |||
889 | #ifndef macintosh | ||
890 | |||
891 | void dsStartGraphics (int width, int height, dsFunctions *fn) | ||
892 | { | ||
893 | char *prefix = DEFAULT_PATH_TO_TEXTURES; | ||
894 | if (fn->version >= 2 && fn->path_to_textures) prefix = fn->path_to_textures; | ||
895 | char *s = (char*) alloca (strlen(prefix) + 20); | ||
896 | |||
897 | strcpy (s,prefix); | ||
898 | strcat (s,"/sky.ppm"); | ||
899 | sky_texture = new Texture (s); | ||
900 | |||
901 | strcpy (s,prefix); | ||
902 | strcat (s,"/ground.ppm"); | ||
903 | ground_texture = new Texture (s); | ||
904 | |||
905 | strcpy (s,prefix); | ||
906 | strcat (s,"/wood.ppm"); | ||
907 | wood_texture = new Texture (s); | ||
908 | } | ||
909 | |||
910 | #else // macintosh | ||
911 | |||
912 | void dsStartGraphics (int width, int height, dsFunctions *fn) | ||
913 | { | ||
914 | // All examples build into the same dir | ||
915 | char *prefix = "::::drawstuff:textures"; | ||
916 | char *s = (char*) alloca (strlen(prefix) + 20); | ||
917 | |||
918 | strcpy (s,prefix); | ||
919 | strcat (s,":sky.ppm"); | ||
920 | sky_texture = new Texture (s); | ||
921 | |||
922 | strcpy (s,prefix); | ||
923 | strcat (s,":ground.ppm"); | ||
924 | ground_texture = new Texture (s); | ||
925 | |||
926 | strcpy (s,prefix); | ||
927 | strcat (s,":wood.ppm"); | ||
928 | wood_texture = new Texture (s); | ||
929 | } | ||
930 | |||
931 | #endif | ||
932 | |||
933 | |||
934 | void dsStopGraphics() | ||
935 | { | ||
936 | delete sky_texture; | ||
937 | delete ground_texture; | ||
938 | delete wood_texture; | ||
939 | sky_texture = 0; | ||
940 | ground_texture = 0; | ||
941 | wood_texture = 0; | ||
942 | } | ||
943 | |||
944 | |||
945 | static void drawSky (float view_xyz[3]) | ||
946 | { | ||
947 | glDisable (GL_LIGHTING); | ||
948 | if (use_textures) { | ||
949 | glEnable (GL_TEXTURE_2D); | ||
950 | sky_texture->bind (0); | ||
951 | } | ||
952 | else { | ||
953 | glDisable (GL_TEXTURE_2D); | ||
954 | glColor3f (0,0.5,1.0); | ||
955 | } | ||
956 | |||
957 | // make sure sky depth is as far back as possible | ||
958 | glShadeModel (GL_FLAT); | ||
959 | glEnable (GL_DEPTH_TEST); | ||
960 | glDepthFunc (GL_LEQUAL); | ||
961 | glDepthRange (1,1); | ||
962 | |||
963 | const float ssize = 1000.0f; | ||
964 | static float offset = 0.0f; | ||
965 | |||
966 | float x = ssize*sky_scale; | ||
967 | float z = view_xyz[2] + sky_height; | ||
968 | |||
969 | glBegin (GL_QUADS); | ||
970 | glNormal3f (0,0,-1); | ||
971 | glTexCoord2f (-x+offset,-x+offset); | ||
972 | glVertex3f (-ssize+view_xyz[0],-ssize+view_xyz[1],z); | ||
973 | glTexCoord2f (-x+offset,x+offset); | ||
974 | glVertex3f (-ssize+view_xyz[0],ssize+view_xyz[1],z); | ||
975 | glTexCoord2f (x+offset,x+offset); | ||
976 | glVertex3f (ssize+view_xyz[0],ssize+view_xyz[1],z); | ||
977 | glTexCoord2f (x+offset,-x+offset); | ||
978 | glVertex3f (ssize+view_xyz[0],-ssize+view_xyz[1],z); | ||
979 | glEnd(); | ||
980 | |||
981 | offset = offset + 0.002f; | ||
982 | if (offset > 1) offset -= 1; | ||
983 | |||
984 | glDepthFunc (GL_LESS); | ||
985 | glDepthRange (0,1); | ||
986 | } | ||
987 | |||
988 | |||
989 | static void drawGround() | ||
990 | { | ||
991 | glDisable (GL_LIGHTING); | ||
992 | glShadeModel (GL_FLAT); | ||
993 | glEnable (GL_DEPTH_TEST); | ||
994 | glDepthFunc (GL_LESS); | ||
995 | // glDepthRange (1,1); | ||
996 | |||
997 | if (use_textures) { | ||
998 | glEnable (GL_TEXTURE_2D); | ||
999 | ground_texture->bind (0); | ||
1000 | } | ||
1001 | else { | ||
1002 | glDisable (GL_TEXTURE_2D); | ||
1003 | glColor3f (GROUND_R,GROUND_G,GROUND_B); | ||
1004 | } | ||
1005 | |||
1006 | // ground fog seems to cause problems with TNT2 under windows | ||
1007 | /* | ||
1008 | GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1}; | ||
1009 | glEnable (GL_FOG); | ||
1010 | glFogi (GL_FOG_MODE, GL_EXP2); | ||
1011 | glFogfv (GL_FOG_COLOR, fogColor); | ||
1012 | glFogf (GL_FOG_DENSITY, 0.05f); | ||
1013 | glHint (GL_FOG_HINT, GL_NICEST); // GL_DONT_CARE); | ||
1014 | glFogf (GL_FOG_START, 1.0); | ||
1015 | glFogf (GL_FOG_END, 5.0); | ||
1016 | */ | ||
1017 | |||
1018 | const float gsize = 100.0f; | ||
1019 | const float offset = 0; // -0.001f; ... polygon offsetting doesn't work well | ||
1020 | |||
1021 | glBegin (GL_QUADS); | ||
1022 | glNormal3f (0,0,1); | ||
1023 | glTexCoord2f (-gsize*ground_scale + ground_ofsx, | ||
1024 | -gsize*ground_scale + ground_ofsy); | ||
1025 | glVertex3f (-gsize,-gsize,offset); | ||
1026 | glTexCoord2f (gsize*ground_scale + ground_ofsx, | ||
1027 | -gsize*ground_scale + ground_ofsy); | ||
1028 | glVertex3f (gsize,-gsize,offset); | ||
1029 | glTexCoord2f (gsize*ground_scale + ground_ofsx, | ||
1030 | gsize*ground_scale + ground_ofsy); | ||
1031 | glVertex3f (gsize,gsize,offset); | ||
1032 | glTexCoord2f (-gsize*ground_scale + ground_ofsx, | ||
1033 | gsize*ground_scale + ground_ofsy); | ||
1034 | glVertex3f (-gsize,gsize,offset); | ||
1035 | glEnd(); | ||
1036 | |||
1037 | glDisable (GL_FOG); | ||
1038 | } | ||
1039 | |||
1040 | |||
1041 | static void drawPyramidGrid() | ||
1042 | { | ||
1043 | // setup stuff | ||
1044 | glEnable (GL_LIGHTING); | ||
1045 | glDisable (GL_TEXTURE_2D); | ||
1046 | glShadeModel (GL_FLAT); | ||
1047 | glEnable (GL_DEPTH_TEST); | ||
1048 | glDepthFunc (GL_LESS); | ||
1049 | |||
1050 | // draw the pyramid grid | ||
1051 | for (int i=-1; i<=1; i++) { | ||
1052 | for (int j=-1; j<=1; j++) { | ||
1053 | glPushMatrix(); | ||
1054 | glTranslatef ((float)i,(float)j,(float)0); | ||
1055 | if (i==1 && j==0) setColor (1,0,0,1); | ||
1056 | else if (i==0 && j==1) setColor (0,0,1,1); | ||
1057 | else setColor (1,1,0,1); | ||
1058 | const float k = 0.03f; | ||
1059 | glBegin (GL_TRIANGLE_FAN); | ||
1060 | glNormal3f (0,-1,1); | ||
1061 | glVertex3f (0,0,k); | ||
1062 | glVertex3f (-k,-k,0); | ||
1063 | glVertex3f ( k,-k,0); | ||
1064 | glNormal3f (1,0,1); | ||
1065 | glVertex3f ( k, k,0); | ||
1066 | glNormal3f (0,1,1); | ||
1067 | glVertex3f (-k, k,0); | ||
1068 | glNormal3f (-1,0,1); | ||
1069 | glVertex3f (-k,-k,0); | ||
1070 | glEnd(); | ||
1071 | glPopMatrix(); | ||
1072 | } | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | |||
1077 | void dsDrawFrame (int width, int height, dsFunctions *fn, int pause) | ||
1078 | { | ||
1079 | if (current_state < 1) dsDebug ("internal error"); | ||
1080 | current_state = 2; | ||
1081 | |||
1082 | // setup stuff | ||
1083 | glEnable (GL_LIGHTING); | ||
1084 | glEnable (GL_LIGHT0); | ||
1085 | glDisable (GL_TEXTURE_2D); | ||
1086 | glDisable (GL_TEXTURE_GEN_S); | ||
1087 | glDisable (GL_TEXTURE_GEN_T); | ||
1088 | glShadeModel (GL_FLAT); | ||
1089 | glEnable (GL_DEPTH_TEST); | ||
1090 | glDepthFunc (GL_LESS); | ||
1091 | glEnable (GL_CULL_FACE); | ||
1092 | glCullFace (GL_BACK); | ||
1093 | glFrontFace (GL_CCW); | ||
1094 | |||
1095 | // setup viewport | ||
1096 | glViewport (0,0,width,height); | ||
1097 | glMatrixMode (GL_PROJECTION); | ||
1098 | glLoadIdentity(); | ||
1099 | const float vnear = 0.1f; | ||
1100 | const float vfar = 100.0f; | ||
1101 | const float k = 0.8f; // view scale, 1 = +/- 45 degrees | ||
1102 | if (width >= height) { | ||
1103 | float k2 = float(height)/float(width); | ||
1104 | glFrustum (-vnear*k,vnear*k,-vnear*k*k2,vnear*k*k2,vnear,vfar); | ||
1105 | } | ||
1106 | else { | ||
1107 | float k2 = float(width)/float(height); | ||
1108 | glFrustum (-vnear*k*k2,vnear*k*k2,-vnear*k,vnear*k,vnear,vfar); | ||
1109 | } | ||
1110 | |||
1111 | // setup lights. it makes a difference whether this is done in the | ||
1112 | // GL_PROJECTION matrix mode (lights are scene relative) or the | ||
1113 | // GL_MODELVIEW matrix mode (lights are camera relative, bad!). | ||
1114 | static GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; | ||
1115 | static GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; | ||
1116 | static GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; | ||
1117 | glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); | ||
1118 | glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); | ||
1119 | glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); | ||
1120 | glColor3f (1.0, 1.0, 1.0); | ||
1121 | |||
1122 | // clear the window | ||
1123 | glClearColor (0.5,0.5,0.5,0); | ||
1124 | glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
1125 | |||
1126 | // snapshot camera position (in MS Windows it is changed by the GUI thread) | ||
1127 | float view2_xyz[3]; | ||
1128 | float view2_hpr[3]; | ||
1129 | memcpy (view2_xyz,view_xyz,sizeof(float)*3); | ||
1130 | memcpy (view2_hpr,view_hpr,sizeof(float)*3); | ||
1131 | |||
1132 | // go to GL_MODELVIEW matrix mode and set the camera | ||
1133 | glMatrixMode (GL_MODELVIEW); | ||
1134 | glLoadIdentity(); | ||
1135 | setCamera (view2_xyz[0],view2_xyz[1],view2_xyz[2], | ||
1136 | view2_hpr[0],view2_hpr[1],view2_hpr[2]); | ||
1137 | |||
1138 | // set the light position (for some reason we have to do this in model view. | ||
1139 | static GLfloat light_position[] = { LIGHTX, LIGHTY, 1.0, 0.0 }; | ||
1140 | glLightfv (GL_LIGHT0, GL_POSITION, light_position); | ||
1141 | |||
1142 | // draw the background (ground, sky etc) | ||
1143 | drawSky (view2_xyz); | ||
1144 | drawGround(); | ||
1145 | |||
1146 | // draw the little markers on the ground | ||
1147 | drawPyramidGrid(); | ||
1148 | |||
1149 | // leave openGL in a known state - flat shaded white, no textures | ||
1150 | glEnable (GL_LIGHTING); | ||
1151 | glDisable (GL_TEXTURE_2D); | ||
1152 | glShadeModel (GL_FLAT); | ||
1153 | glEnable (GL_DEPTH_TEST); | ||
1154 | glDepthFunc (GL_LESS); | ||
1155 | glColor3f (1,1,1); | ||
1156 | setColor (1,1,1,1); | ||
1157 | |||
1158 | // draw the rest of the objects. set drawing state first. | ||
1159 | color[0] = 1; | ||
1160 | color[1] = 1; | ||
1161 | color[2] = 1; | ||
1162 | color[3] = 1; | ||
1163 | tnum = 0; | ||
1164 | if (fn->step) fn->step (pause); | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | int dsGetShadows() | ||
1169 | { | ||
1170 | return use_shadows; | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | void dsSetShadows (int a) | ||
1175 | { | ||
1176 | use_shadows = (a != 0); | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | int dsGetTextures() | ||
1181 | { | ||
1182 | return use_textures; | ||
1183 | } | ||
1184 | |||
1185 | |||
1186 | void dsSetTextures (int a) | ||
1187 | { | ||
1188 | use_textures = (a != 0); | ||
1189 | } | ||
1190 | |||
1191 | //*************************************************************************** | ||
1192 | // C interface | ||
1193 | |||
1194 | // sets lighting and texture modes, sets current color | ||
1195 | static void setupDrawingMode() | ||
1196 | { | ||
1197 | glEnable (GL_LIGHTING); | ||
1198 | if (tnum) { | ||
1199 | if (use_textures) { | ||
1200 | glEnable (GL_TEXTURE_2D); | ||
1201 | wood_texture->bind (1); | ||
1202 | glEnable (GL_TEXTURE_GEN_S); | ||
1203 | glEnable (GL_TEXTURE_GEN_T); | ||
1204 | glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); | ||
1205 | glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); | ||
1206 | static GLfloat s_params[4] = {1.0f,1.0f,0.0f,1}; | ||
1207 | static GLfloat t_params[4] = {0.817f,-0.817f,0.817f,1}; | ||
1208 | glTexGenfv (GL_S,GL_OBJECT_PLANE,s_params); | ||
1209 | glTexGenfv (GL_T,GL_OBJECT_PLANE,t_params); | ||
1210 | } | ||
1211 | else { | ||
1212 | glDisable (GL_TEXTURE_2D); | ||
1213 | } | ||
1214 | } | ||
1215 | else { | ||
1216 | glDisable (GL_TEXTURE_2D); | ||
1217 | } | ||
1218 | setColor (color[0],color[1],color[2],color[3]); | ||
1219 | |||
1220 | if (color[3] < 1) { | ||
1221 | glEnable (GL_BLEND); | ||
1222 | glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); | ||
1223 | } | ||
1224 | else { | ||
1225 | glDisable (GL_BLEND); | ||
1226 | } | ||
1227 | } | ||
1228 | |||
1229 | |||
1230 | static void setShadowDrawingMode() | ||
1231 | { | ||
1232 | glDisable (GL_LIGHTING); | ||
1233 | if (use_textures) { | ||
1234 | glEnable (GL_TEXTURE_2D); | ||
1235 | ground_texture->bind (1); | ||
1236 | glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); | ||
1237 | glEnable (GL_TEXTURE_2D); | ||
1238 | glEnable (GL_TEXTURE_GEN_S); | ||
1239 | glEnable (GL_TEXTURE_GEN_T); | ||
1240 | glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); | ||
1241 | glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); | ||
1242 | static GLfloat s_params[4] = {ground_scale,0,0,ground_ofsx}; | ||
1243 | static GLfloat t_params[4] = {0,ground_scale,0,ground_ofsy}; | ||
1244 | glTexGenfv (GL_S,GL_EYE_PLANE,s_params); | ||
1245 | glTexGenfv (GL_T,GL_EYE_PLANE,t_params); | ||
1246 | } | ||
1247 | else { | ||
1248 | glDisable (GL_TEXTURE_2D); | ||
1249 | glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, | ||
1250 | GROUND_B*SHADOW_INTENSITY); | ||
1251 | } | ||
1252 | glDepthRange (0,0.9999); | ||
1253 | } | ||
1254 | |||
1255 | |||
1256 | extern "C" void dsSimulationLoop (int argc, char **argv, | ||
1257 | int window_width, int window_height, | ||
1258 | dsFunctions *fn) | ||
1259 | { | ||
1260 | if (current_state != 0) dsError ("dsSimulationLoop() called more than once"); | ||
1261 | current_state = 1; | ||
1262 | |||
1263 | // look for flags that apply to us | ||
1264 | int initial_pause = 0; | ||
1265 | for (int i=1; i<argc; i++) { | ||
1266 | if (strcmp(argv[i],"-notex")==0) use_textures = 0; | ||
1267 | if (strcmp(argv[i],"-noshadow")==0) use_shadows = 0; | ||
1268 | if (strcmp(argv[i],"-noshadows")==0) use_shadows = 0; | ||
1269 | if (strcmp(argv[i],"-pause")==0) initial_pause = 1; | ||
1270 | } | ||
1271 | |||
1272 | if (fn->version > DS_VERSION) | ||
1273 | dsDebug ("bad version number in dsFunctions structure"); | ||
1274 | |||
1275 | initMotionModel(); | ||
1276 | dsPlatformSimLoop (window_width,window_height,fn,initial_pause); | ||
1277 | |||
1278 | current_state = 0; | ||
1279 | } | ||
1280 | |||
1281 | |||
1282 | extern "C" void dsSetViewpoint (float xyz[3], float hpr[3]) | ||
1283 | { | ||
1284 | if (current_state < 1) dsError ("dsSetViewpoint() called before simulation started"); | ||
1285 | if (xyz) { | ||
1286 | view_xyz[0] = xyz[0]; | ||
1287 | view_xyz[1] = xyz[1]; | ||
1288 | view_xyz[2] = xyz[2]; | ||
1289 | } | ||
1290 | if (hpr) { | ||
1291 | view_hpr[0] = hpr[0]; | ||
1292 | view_hpr[1] = hpr[1]; | ||
1293 | view_hpr[2] = hpr[2]; | ||
1294 | wrapCameraAngles(); | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | |||
1299 | extern "C" void dsGetViewpoint (float xyz[3], float hpr[3]) | ||
1300 | { | ||
1301 | if (current_state < 1) dsError ("dsGetViewpoint() called before simulation started"); | ||
1302 | if (xyz) { | ||
1303 | xyz[0] = view_xyz[0]; | ||
1304 | xyz[1] = view_xyz[1]; | ||
1305 | xyz[2] = view_xyz[2]; | ||
1306 | } | ||
1307 | if (hpr) { | ||
1308 | hpr[0] = view_hpr[0]; | ||
1309 | hpr[1] = view_hpr[1]; | ||
1310 | hpr[2] = view_hpr[2]; | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | |||
1315 | extern "C" void dsSetTexture (int texture_number) | ||
1316 | { | ||
1317 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1318 | tnum = texture_number; | ||
1319 | } | ||
1320 | |||
1321 | |||
1322 | extern "C" void dsSetColor (float red, float green, float blue) | ||
1323 | { | ||
1324 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1325 | color[0] = red; | ||
1326 | color[1] = green; | ||
1327 | color[2] = blue; | ||
1328 | color[3] = 1; | ||
1329 | } | ||
1330 | |||
1331 | |||
1332 | extern "C" void dsSetColorAlpha (float red, float green, float blue, | ||
1333 | float alpha) | ||
1334 | { | ||
1335 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1336 | color[0] = red; | ||
1337 | color[1] = green; | ||
1338 | color[2] = blue; | ||
1339 | color[3] = alpha; | ||
1340 | } | ||
1341 | |||
1342 | |||
1343 | extern "C" void dsDrawBox (const float pos[3], const float R[12], | ||
1344 | const float sides[3]) | ||
1345 | { | ||
1346 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1347 | setupDrawingMode(); | ||
1348 | glShadeModel (GL_FLAT); | ||
1349 | setTransform (pos,R); | ||
1350 | drawBox (sides); | ||
1351 | glPopMatrix(); | ||
1352 | |||
1353 | if (use_shadows) { | ||
1354 | setShadowDrawingMode(); | ||
1355 | setShadowTransform(); | ||
1356 | setTransform (pos,R); | ||
1357 | drawBox (sides); | ||
1358 | glPopMatrix(); | ||
1359 | glPopMatrix(); | ||
1360 | glDepthRange (0,1); | ||
1361 | } | ||
1362 | } | ||
1363 | |||
1364 | extern "C" void dsDrawConvex (const float pos[3], const float R[12], | ||
1365 | float *_planes,unsigned int _planecount, | ||
1366 | float *_points, | ||
1367 | unsigned int _pointcount, | ||
1368 | unsigned int *_polygons) | ||
1369 | { | ||
1370 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1371 | setupDrawingMode(); | ||
1372 | glShadeModel (GL_FLAT); | ||
1373 | setTransform (pos,R); | ||
1374 | drawConvex(_planes,_planecount,_points,_pointcount,_polygons); | ||
1375 | glPopMatrix(); | ||
1376 | if (use_shadows) { | ||
1377 | setShadowDrawingMode(); | ||
1378 | setShadowTransform(); | ||
1379 | setTransform (pos,R); | ||
1380 | drawConvex(_planes,_planecount,_points,_pointcount,_polygons); | ||
1381 | glPopMatrix(); | ||
1382 | glPopMatrix(); | ||
1383 | glDepthRange (0,1); | ||
1384 | } | ||
1385 | } | ||
1386 | |||
1387 | |||
1388 | extern "C" void dsDrawSphere (const float pos[3], const float R[12], | ||
1389 | float radius) | ||
1390 | { | ||
1391 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1392 | setupDrawingMode(); | ||
1393 | glEnable (GL_NORMALIZE); | ||
1394 | glShadeModel (GL_SMOOTH); | ||
1395 | setTransform (pos,R); | ||
1396 | glScaled (radius,radius,radius); | ||
1397 | drawSphere(); | ||
1398 | glPopMatrix(); | ||
1399 | glDisable (GL_NORMALIZE); | ||
1400 | |||
1401 | // draw shadows | ||
1402 | if (use_shadows) { | ||
1403 | glDisable (GL_LIGHTING); | ||
1404 | if (use_textures) { | ||
1405 | ground_texture->bind (1); | ||
1406 | glEnable (GL_TEXTURE_2D); | ||
1407 | glDisable (GL_TEXTURE_GEN_S); | ||
1408 | glDisable (GL_TEXTURE_GEN_T); | ||
1409 | glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); | ||
1410 | } | ||
1411 | else { | ||
1412 | glDisable (GL_TEXTURE_2D); | ||
1413 | glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, | ||
1414 | GROUND_B*SHADOW_INTENSITY); | ||
1415 | } | ||
1416 | glShadeModel (GL_FLAT); | ||
1417 | glDepthRange (0,0.9999); | ||
1418 | drawSphereShadow (pos[0],pos[1],pos[2],radius); | ||
1419 | glDepthRange (0,1); | ||
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | |||
1424 | extern "C" void dsDrawTriangle (const float pos[3], const float R[12], | ||
1425 | const float *v0, const float *v1, | ||
1426 | const float *v2, int solid) | ||
1427 | { | ||
1428 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1429 | setupDrawingMode(); | ||
1430 | glShadeModel (GL_FLAT); | ||
1431 | setTransform (pos,R); | ||
1432 | drawTriangle (v0, v1, v2, solid); | ||
1433 | glPopMatrix(); | ||
1434 | } | ||
1435 | |||
1436 | |||
1437 | extern "C" void dsDrawCylinder (const float pos[3], const float R[12], | ||
1438 | float length, float radius) | ||
1439 | { | ||
1440 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1441 | setupDrawingMode(); | ||
1442 | glShadeModel (GL_SMOOTH); | ||
1443 | setTransform (pos,R); | ||
1444 | drawCylinder (length,radius,0); | ||
1445 | glPopMatrix(); | ||
1446 | |||
1447 | if (use_shadows) { | ||
1448 | setShadowDrawingMode(); | ||
1449 | setShadowTransform(); | ||
1450 | setTransform (pos,R); | ||
1451 | drawCylinder (length,radius,0); | ||
1452 | glPopMatrix(); | ||
1453 | glPopMatrix(); | ||
1454 | glDepthRange (0,1); | ||
1455 | } | ||
1456 | } | ||
1457 | |||
1458 | |||
1459 | extern "C" void dsDrawCapsule (const float pos[3], const float R[12], | ||
1460 | float length, float radius) | ||
1461 | { | ||
1462 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1463 | setupDrawingMode(); | ||
1464 | glShadeModel (GL_SMOOTH); | ||
1465 | setTransform (pos,R); | ||
1466 | drawCapsule (length,radius); | ||
1467 | glPopMatrix(); | ||
1468 | |||
1469 | if (use_shadows) { | ||
1470 | setShadowDrawingMode(); | ||
1471 | setShadowTransform(); | ||
1472 | setTransform (pos,R); | ||
1473 | drawCapsule (length,radius); | ||
1474 | glPopMatrix(); | ||
1475 | glPopMatrix(); | ||
1476 | glDepthRange (0,1); | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | |||
1481 | void dsDrawLine (const float pos1[3], const float pos2[3]) | ||
1482 | { | ||
1483 | setupDrawingMode(); | ||
1484 | glColor3f (color[0],color[1],color[2]); | ||
1485 | glDisable (GL_LIGHTING); | ||
1486 | glLineWidth (2); | ||
1487 | glShadeModel (GL_FLAT); | ||
1488 | glBegin (GL_LINES); | ||
1489 | glVertex3f (pos1[0],pos1[1],pos1[2]); | ||
1490 | glVertex3f (pos2[0],pos2[1],pos2[2]); | ||
1491 | glEnd(); | ||
1492 | } | ||
1493 | |||
1494 | |||
1495 | void dsDrawBoxD (const double pos[3], const double R[12], | ||
1496 | const double sides[3]) | ||
1497 | { | ||
1498 | int i; | ||
1499 | float pos2[3],R2[12],fsides[3]; | ||
1500 | for (i=0; i<3; i++) pos2[i]=(float)pos[i]; | ||
1501 | for (i=0; i<12; i++) R2[i]=(float)R[i]; | ||
1502 | for (i=0; i<3; i++) fsides[i]=(float)sides[i]; | ||
1503 | dsDrawBox (pos2,R2,fsides); | ||
1504 | } | ||
1505 | |||
1506 | extern "C" void dsDrawConvexD (const double pos[3], const double R[12], | ||
1507 | double *_planes,unsigned int _planecount, | ||
1508 | double *_points, | ||
1509 | unsigned int _pointcount, | ||
1510 | unsigned int *_polygons) | ||
1511 | { | ||
1512 | if (current_state != 2) dsError ("drawing function called outside simulation loop"); | ||
1513 | setupDrawingMode(); | ||
1514 | glShadeModel (GL_FLAT); | ||
1515 | setTransformD (pos,R); | ||
1516 | drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); | ||
1517 | glPopMatrix(); | ||
1518 | if (use_shadows) { | ||
1519 | setShadowDrawingMode(); | ||
1520 | setShadowTransform(); | ||
1521 | setTransformD (pos,R); | ||
1522 | drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); | ||
1523 | glPopMatrix(); | ||
1524 | glPopMatrix(); | ||
1525 | glDepthRange (0,1); | ||
1526 | } | ||
1527 | } | ||
1528 | |||
1529 | void dsDrawSphereD (const double pos[3], const double R[12], float radius) | ||
1530 | { | ||
1531 | int i; | ||
1532 | float pos2[3],R2[12]; | ||
1533 | for (i=0; i<3; i++) pos2[i]=(float)pos[i]; | ||
1534 | for (i=0; i<12; i++) R2[i]=(float)R[i]; | ||
1535 | dsDrawSphere (pos2,R2,radius); | ||
1536 | } | ||
1537 | |||
1538 | |||
1539 | void dsDrawTriangleD (const double pos[3], const double R[12], | ||
1540 | const double *v0, const double *v1, | ||
1541 | const double *v2, int solid) | ||
1542 | { | ||
1543 | int i; | ||
1544 | float pos2[3],R2[12]; | ||
1545 | for (i=0; i<3; i++) pos2[i]=(float)pos[i]; | ||
1546 | for (i=0; i<12; i++) R2[i]=(float)R[i]; | ||
1547 | |||
1548 | setupDrawingMode(); | ||
1549 | glShadeModel (GL_FLAT); | ||
1550 | setTransform (pos2,R2); | ||
1551 | drawTriangleD (v0, v1, v2, solid); | ||
1552 | glPopMatrix(); | ||
1553 | } | ||
1554 | |||
1555 | |||
1556 | void dsDrawCylinderD (const double pos[3], const double R[12], | ||
1557 | float length, float radius) | ||
1558 | { | ||
1559 | int i; | ||
1560 | float pos2[3],R2[12]; | ||
1561 | for (i=0; i<3; i++) pos2[i]=(float)pos[i]; | ||
1562 | for (i=0; i<12; i++) R2[i]=(float)R[i]; | ||
1563 | dsDrawCylinder (pos2,R2,length,radius); | ||
1564 | } | ||
1565 | |||
1566 | |||
1567 | void dsDrawCapsuleD (const double pos[3], const double R[12], | ||
1568 | float length, float radius) | ||
1569 | { | ||
1570 | int i; | ||
1571 | float pos2[3],R2[12]; | ||
1572 | for (i=0; i<3; i++) pos2[i]=(float)pos[i]; | ||
1573 | for (i=0; i<12; i++) R2[i]=(float)R[i]; | ||
1574 | dsDrawCapsule (pos2,R2,length,radius); | ||
1575 | } | ||
1576 | |||
1577 | |||
1578 | void dsDrawLineD (const double _pos1[3], const double _pos2[3]) | ||
1579 | { | ||
1580 | int i; | ||
1581 | float pos1[3],pos2[3]; | ||
1582 | for (i=0; i<3; i++) pos1[i]=(float)_pos1[i]; | ||
1583 | for (i=0; i<3; i++) pos2[i]=(float)_pos2[i]; | ||
1584 | dsDrawLine (pos1,pos2); | ||
1585 | } | ||
1586 | |||
1587 | |||
1588 | void dsSetSphereQuality (int n) | ||
1589 | { | ||
1590 | sphere_quality = n; | ||
1591 | } | ||
1592 | |||
1593 | |||
1594 | void dsSetCapsuleQuality (int n) | ||
1595 | { | ||
1596 | capped_cylinder_quality = n; | ||
1597 | } | ||
diff --git a/libraries/ode-0.9/drawstuff/src/internal.h b/libraries/ode-0.9/drawstuff/src/internal.h new file mode 100644 index 0000000..de1aa11 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/internal.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | /* functions supplied and used by the platform specific code */ | ||
24 | |||
25 | #ifndef __DS_INTERNAL_H | ||
26 | #define __DS_INTERNAL_H | ||
27 | |||
28 | #include "drawstuff/drawstuff.h" | ||
29 | |||
30 | |||
31 | // supplied by platform specific code | ||
32 | |||
33 | void dsPlatformSimLoop (int window_width, int window_height, | ||
34 | dsFunctions *fn, int initial_pause); | ||
35 | |||
36 | |||
37 | // used by platform specific code | ||
38 | |||
39 | void dsStartGraphics (int width, int height, dsFunctions *fn); | ||
40 | void dsDrawFrame (int width, int height, dsFunctions *fn, int pause); | ||
41 | void dsStopGraphics(); | ||
42 | void dsMotion (int mode, int deltax, int deltay); | ||
43 | |||
44 | int dsGetShadows(); | ||
45 | void dsSetShadows (int a); | ||
46 | |||
47 | int dsGetTextures(); | ||
48 | void dsSetTextures (int a); | ||
49 | |||
50 | #endif | ||
diff --git a/libraries/ode-0.9/drawstuff/src/osx.cpp b/libraries/ode-0.9/drawstuff/src/osx.cpp new file mode 100644 index 0000000..fcecba9 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/osx.cpp | |||
@@ -0,0 +1,542 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | // Platform-specific code for Mac OS X using Carbon+AGL | ||
24 | // | ||
25 | // Created using x11.cpp and the window-initialization -routines from GLFW | ||
26 | // as reference. | ||
27 | // Not thoroughly tested and is certain to contain deficiencies and bugs | ||
28 | |||
29 | #include <ode/config.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <string.h> | ||
32 | #include <stdarg.h> | ||
33 | |||
34 | #ifdef HAVE_SYS_TIME_H | ||
35 | #include <sys/time.h> | ||
36 | #endif | ||
37 | |||
38 | #include <drawstuff/drawstuff.h> | ||
39 | #include <drawstuff/version.h> | ||
40 | #include "internal.h" | ||
41 | |||
42 | #include <Carbon/Carbon.h> | ||
43 | #include <AGL/agl.h> | ||
44 | |||
45 | // Global variables | ||
46 | |||
47 | static bool running = true; // 1 if simulation running | ||
48 | static bool paused = false; // 1 if in `pause' mode | ||
49 | static bool singlestep = false; // 1 if single step key pressed | ||
50 | static bool writeframes = false; // 1 if frame files to be written | ||
51 | |||
52 | static int windowWidth = -1; | ||
53 | static int windowHeight = -1; | ||
54 | static UInt32 modifierMask = 0; | ||
55 | static int mouseButtonMode = 0; | ||
56 | static bool mouseWithOption = false; // Set if dragging the mouse with alt pressed | ||
57 | static bool mouseWithControl = false; // Set if dragging the mouse with ctrl pressed | ||
58 | |||
59 | static dsFunctions* functions = NULL; | ||
60 | static WindowRef windowReference; | ||
61 | static AGLContext aglContext; | ||
62 | |||
63 | static EventHandlerUPP mouseUPP = NULL; | ||
64 | static EventHandlerUPP keyboardUPP = NULL; | ||
65 | static EventHandlerUPP windowUPP = NULL; | ||
66 | |||
67 | // Describes the window-events we are interested in | ||
68 | EventTypeSpec OSX_WINDOW_EVENT_TYPES[] = { | ||
69 | { kEventClassWindow, kEventWindowBoundsChanged }, | ||
70 | { kEventClassWindow, kEventWindowClose }, | ||
71 | { kEventClassWindow, kEventWindowDrawContent } | ||
72 | }; | ||
73 | |||
74 | // Describes the mouse-events we are interested in | ||
75 | EventTypeSpec OSX_MOUSE_EVENT_TYPES[] = { | ||
76 | { kEventClassMouse, kEventMouseDown }, | ||
77 | { kEventClassMouse, kEventMouseUp }, | ||
78 | { kEventClassMouse, kEventMouseMoved }, | ||
79 | { kEventClassMouse, kEventMouseDragged } | ||
80 | }; | ||
81 | |||
82 | // Describes the key-events we are interested in | ||
83 | EventTypeSpec OSX_KEY_EVENT_TYPES[] = { | ||
84 | { kEventClassKeyboard, kEventRawKeyDown }, | ||
85 | // { kEventClassKeyboard, kEventRawKeyUp }, | ||
86 | { kEventClassKeyboard, kEventRawKeyModifiersChanged } | ||
87 | }; | ||
88 | |||
89 | //*************************************************************************** | ||
90 | // error handling for unix | ||
91 | |||
92 | static void printMessage (char *msg1, char *msg2, va_list ap) | ||
93 | { | ||
94 | fflush (stderr); | ||
95 | fflush (stdout); | ||
96 | fprintf (stderr,"\n%s: ",msg1); | ||
97 | vfprintf (stderr,msg2,ap); | ||
98 | fprintf (stderr,"\n"); | ||
99 | fflush (stderr); | ||
100 | } | ||
101 | |||
102 | extern "C" void dsError (char *msg, ...) | ||
103 | { | ||
104 | va_list ap; | ||
105 | va_start (ap,msg); | ||
106 | printMessage ("Error",msg,ap); | ||
107 | exit (1); | ||
108 | } | ||
109 | |||
110 | |||
111 | extern "C" void dsDebug (char *msg, ...) | ||
112 | { | ||
113 | va_list ap; | ||
114 | va_start (ap,msg); | ||
115 | printMessage ("INTERNAL ERROR",msg,ap); | ||
116 | // *((char *)0) = 0; ... commit SEGVicide ? | ||
117 | abort(); | ||
118 | } | ||
119 | |||
120 | extern "C" void dsPrint (char *msg, ...) | ||
121 | { | ||
122 | va_list ap; | ||
123 | va_start (ap,msg); | ||
124 | vprintf (msg,ap); | ||
125 | } | ||
126 | |||
127 | static void captureFrame( int num ){ | ||
128 | |||
129 | fprintf( stderr,"\rcapturing frame %04d", num ); | ||
130 | unsigned char buffer[windowWidth*windowHeight][3]; | ||
131 | glReadPixels( 0, 0, windowWidth, windowHeight, GL_RGB, GL_UNSIGNED_BYTE, &buffer ); | ||
132 | char s[100]; | ||
133 | sprintf (s,"frame%04d.ppm",num); | ||
134 | FILE *f = fopen (s,"wb"); | ||
135 | if( !f ){ | ||
136 | dsError( "can't open \"%s\" for writing", s ); | ||
137 | } | ||
138 | fprintf( f,"P6\n%d %d\n255\n", windowWidth, windowHeight ); | ||
139 | for( int y=windowHeight-1; y>-1; y-- ){ | ||
140 | fwrite( buffer[y*windowWidth], 3*windowWidth, 1, f ); | ||
141 | } | ||
142 | fclose (f); | ||
143 | } | ||
144 | |||
145 | extern "C" void dsStop(){ | ||
146 | |||
147 | running = false; | ||
148 | } | ||
149 | |||
150 | extern "C" double dsElapsedTime() | ||
151 | { | ||
152 | #if HAVE_GETTIMEOFDAY | ||
153 | static double prev=0.0; | ||
154 | timeval tv ; | ||
155 | |||
156 | gettimeofday(&tv, 0); | ||
157 | double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; | ||
158 | if (!prev) | ||
159 | prev=curr; | ||
160 | double retval = curr-prev; | ||
161 | prev=curr; | ||
162 | if (retval>1.0) retval=1.0; | ||
163 | if (retval<dEpsilon) retval=dEpsilon; | ||
164 | return retval; | ||
165 | #else | ||
166 | return 0.01666; // Assume 60 fps | ||
167 | #endif | ||
168 | } | ||
169 | |||
170 | OSStatus osxKeyEventHandler( EventHandlerCallRef handlerCallRef, EventRef event, void *userData ){ | ||
171 | |||
172 | UInt32 keyCode; | ||
173 | UInt32 state = 0; | ||
174 | void* KCHR = NULL; | ||
175 | char charCode = 0; | ||
176 | char uppercase = 0; | ||
177 | |||
178 | switch( GetEventKind( event ) ){ | ||
179 | case kEventRawKeyDown: | ||
180 | if( GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof( UInt32 ), NULL, &keyCode ) != noErr ){ | ||
181 | break; | ||
182 | } | ||
183 | KCHR = (void *)GetScriptVariable( smCurrentScript, smKCHRCache ); | ||
184 | charCode = (char)KeyTranslate( KCHR, keyCode, &state ); | ||
185 | uppercase = charCode; | ||
186 | UppercaseText( &uppercase, 1, smSystemScript ); | ||
187 | //printf( "Character %d [%c] [%c] modifiers [%d]\n", charCode, charCode, uppercase, modifierMask ); | ||
188 | |||
189 | if( modifierMask == 0 ){ | ||
190 | if( charCode >= ' ' && charCode <= 126 && functions -> command ){ | ||
191 | functions -> command( charCode ); | ||
192 | } | ||
193 | } | ||
194 | else if( ( modifierMask & controlKey ) ){ | ||
195 | // ctrl+key was pressed | ||
196 | switch(uppercase ){ | ||
197 | case 'T': | ||
198 | dsSetTextures( !dsGetTextures() ); | ||
199 | break; | ||
200 | case 'S': | ||
201 | dsSetShadows( !dsGetShadows() ); | ||
202 | break; | ||
203 | case 'X': | ||
204 | running = false; | ||
205 | break; | ||
206 | case 'P': | ||
207 | paused = !paused; | ||
208 | singlestep = false; | ||
209 | break; | ||
210 | case 'O': | ||
211 | if( paused ){ | ||
212 | singlestep = true; | ||
213 | } | ||
214 | break; | ||
215 | case 'V': { | ||
216 | float xyz[3],hpr[3]; | ||
217 | dsGetViewpoint( xyz,hpr ); | ||
218 | printf( "Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2] ); | ||
219 | break; | ||
220 | } | ||
221 | case 'W': | ||
222 | writeframes = !writeframes; | ||
223 | if( writeframes ){ | ||
224 | printf( "Now writing frames to PPM files\n" ); | ||
225 | } | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | } | ||
230 | return noErr; | ||
231 | case kEventRawKeyModifiersChanged: | ||
232 | if( GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof( UInt32 ), NULL, &modifierMask ) == noErr ){ | ||
233 | if( ( mouseWithOption && !( modifierMask & optionKey ) ) || ( mouseWithControl && !( modifierMask & controlKey ) ) ){ | ||
234 | // The mouse was being dragged using either the command-key or the option-key modifier to emulate | ||
235 | // the right button or both left + right. | ||
236 | // Now the modifier-key has been released so the mouseButtonMode must be changed accordingly | ||
237 | // The following releases the right-button. | ||
238 | mouseButtonMode &= (~4); | ||
239 | mouseWithOption = false; | ||
240 | mouseWithControl = false; | ||
241 | } | ||
242 | return noErr; | ||
243 | } | ||
244 | break; | ||
245 | } | ||
246 | return eventNotHandledErr; | ||
247 | } | ||
248 | |||
249 | OSStatus osxMouseEventHandler( EventHandlerCallRef handlerCallRef, EventRef event, void *userData ){ | ||
250 | |||
251 | bool buttonDown = false; | ||
252 | HIPoint mouseLocation; | ||
253 | |||
254 | switch( GetEventKind( event ) ){ | ||
255 | |||
256 | case kEventMouseDown: | ||
257 | buttonDown = true; | ||
258 | case kEventMouseUp: | ||
259 | if( GetEventParameter( event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) != noErr ){ | ||
260 | break; | ||
261 | } | ||
262 | EventMouseButton button; | ||
263 | if( GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof( EventMouseButton ), NULL, &button ) == noErr ){ | ||
264 | |||
265 | if( button == kEventMouseButtonPrimary ){ | ||
266 | if( modifierMask & controlKey ){ | ||
267 | // Ctrl+button == right | ||
268 | button = kEventMouseButtonSecondary; | ||
269 | mouseWithControl = true; | ||
270 | } | ||
271 | else if( modifierMask & optionKey ){ | ||
272 | // Alt+button == left+right | ||
273 | mouseButtonMode = 5; | ||
274 | mouseWithOption = true; | ||
275 | return noErr; | ||
276 | } | ||
277 | } | ||
278 | if( buttonDown ){ | ||
279 | if( button == kEventMouseButtonPrimary ) mouseButtonMode |= 1; // Left | ||
280 | if( button == kEventMouseButtonTertiary ) mouseButtonMode |= 2; // Middle | ||
281 | if( button == kEventMouseButtonSecondary ) mouseButtonMode |= 4; // Right | ||
282 | } | ||
283 | else{ | ||
284 | if( button == kEventMouseButtonPrimary ) mouseButtonMode &= (~1); // Left | ||
285 | if( button == kEventMouseButtonTertiary ) mouseButtonMode &= (~2); // Middle | ||
286 | if( button == kEventMouseButtonSecondary ) mouseButtonMode &= (~4);// Right | ||
287 | } | ||
288 | return noErr; | ||
289 | } | ||
290 | break; | ||
291 | case kEventMouseMoved: | ||
292 | // NO-OP | ||
293 | return noErr; | ||
294 | case kEventMouseDragged: | ||
295 | // Carbon provides mouse-position deltas, so we don't have to store the old state ourselves | ||
296 | if( GetEventParameter( event, kEventParamMouseDelta, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) == noErr ){ | ||
297 | //printf( "Mode %d\n", mouseButtonMode ); | ||
298 | dsMotion( mouseButtonMode, (int)mouseLocation.x, (int)mouseLocation.y ); | ||
299 | return noErr; | ||
300 | } | ||
301 | break; | ||
302 | case kEventMouseWheelMoved: | ||
303 | // NO-OP | ||
304 | break; | ||
305 | } | ||
306 | return eventNotHandledErr; | ||
307 | } | ||
308 | |||
309 | static void osxCloseMainWindow(){ | ||
310 | |||
311 | if( windowUPP != NULL ){ | ||
312 | DisposeEventHandlerUPP( windowUPP ); | ||
313 | windowUPP = NULL; | ||
314 | } | ||
315 | |||
316 | if( aglContext != NULL ){ | ||
317 | aglSetCurrentContext( NULL ); | ||
318 | aglSetDrawable( aglContext, NULL ); | ||
319 | aglDestroyContext( aglContext ); | ||
320 | aglContext = NULL; | ||
321 | } | ||
322 | |||
323 | if( windowReference != NULL ){ | ||
324 | ReleaseWindow( windowReference ); | ||
325 | windowReference = NULL; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | OSStatus osxWindowEventHandler( EventHandlerCallRef handlerCallRef, EventRef event, void *userData ){ | ||
330 | |||
331 | //printf( "WindowEvent\n" ); | ||
332 | switch( GetEventKind(event) ){ | ||
333 | case kEventWindowBoundsChanged: | ||
334 | WindowRef window; | ||
335 | GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window ); | ||
336 | Rect rect; | ||
337 | GetWindowPortBounds( window, &rect ); | ||
338 | windowWidth = rect.right; | ||
339 | windowHeight = rect.bottom; | ||
340 | aglUpdateContext( aglContext ); | ||
341 | break; | ||
342 | case kEventWindowClose: | ||
343 | osxCloseMainWindow(); | ||
344 | exit( 0 ); | ||
345 | return noErr; | ||
346 | case kEventWindowDrawContent: | ||
347 | // NO-OP | ||
348 | break; | ||
349 | } | ||
350 | |||
351 | return eventNotHandledErr; | ||
352 | } | ||
353 | |||
354 | static void osxCreateMainWindow( int width, int height ){ | ||
355 | |||
356 | int redbits = 4; | ||
357 | int greenbits = 4; | ||
358 | int bluebits = 4; | ||
359 | int alphabits = 4; | ||
360 | int depthbits = 16; | ||
361 | |||
362 | OSStatus error; | ||
363 | |||
364 | // create pixel format attribute list | ||
365 | |||
366 | GLint pixelFormatAttributes[256]; | ||
367 | int numAttrs = 0; | ||
368 | |||
369 | pixelFormatAttributes[numAttrs++] = AGL_RGBA; | ||
370 | pixelFormatAttributes[numAttrs++] = AGL_DOUBLEBUFFER; | ||
371 | |||
372 | pixelFormatAttributes[numAttrs++] = AGL_RED_SIZE; | ||
373 | pixelFormatAttributes[numAttrs++] = redbits; | ||
374 | pixelFormatAttributes[numAttrs++] = AGL_GREEN_SIZE; | ||
375 | pixelFormatAttributes[numAttrs++] = greenbits; | ||
376 | pixelFormatAttributes[numAttrs++] = AGL_BLUE_SIZE; | ||
377 | pixelFormatAttributes[numAttrs++] = bluebits; | ||
378 | pixelFormatAttributes[numAttrs++] = AGL_ALPHA_SIZE; | ||
379 | pixelFormatAttributes[numAttrs++] = alphabits; | ||
380 | pixelFormatAttributes[numAttrs++] = AGL_DEPTH_SIZE; | ||
381 | pixelFormatAttributes[numAttrs++] = depthbits; | ||
382 | |||
383 | pixelFormatAttributes[numAttrs++] = AGL_NONE; | ||
384 | |||
385 | // create pixel format. | ||
386 | |||
387 | AGLDevice mainMonitor = GetMainDevice(); | ||
388 | AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor, 1, pixelFormatAttributes ); | ||
389 | if( pixelFormat == NULL ){ | ||
390 | return; | ||
391 | } | ||
392 | |||
393 | aglContext = aglCreateContext( pixelFormat, NULL ); | ||
394 | |||
395 | aglDestroyPixelFormat( pixelFormat ); | ||
396 | |||
397 | if( aglContext == NULL ){ | ||
398 | osxCloseMainWindow(); | ||
399 | return; | ||
400 | } | ||
401 | |||
402 | Rect windowContentBounds; | ||
403 | windowContentBounds.left = 0; | ||
404 | windowContentBounds.top = 0; | ||
405 | windowContentBounds.right = width; | ||
406 | windowContentBounds.bottom = height; | ||
407 | |||
408 | int windowAttributes = kWindowCloseBoxAttribute | ||
409 | | kWindowFullZoomAttribute | ||
410 | | kWindowCollapseBoxAttribute | ||
411 | | kWindowResizableAttribute | ||
412 | | kWindowStandardHandlerAttribute | ||
413 | | kWindowLiveResizeAttribute; | ||
414 | |||
415 | error = CreateNewWindow( kDocumentWindowClass, windowAttributes, &windowContentBounds, &windowReference ); | ||
416 | if( ( error != noErr ) || ( windowReference == NULL ) ){ | ||
417 | osxCloseMainWindow(); | ||
418 | return; | ||
419 | } | ||
420 | |||
421 | windowUPP = NewEventHandlerUPP( osxWindowEventHandler ); | ||
422 | |||
423 | error = InstallWindowEventHandler( windowReference, windowUPP,GetEventTypeCount( OSX_WINDOW_EVENT_TYPES ), OSX_WINDOW_EVENT_TYPES, NULL, NULL ); | ||
424 | if( error != noErr ){ | ||
425 | osxCloseMainWindow(); | ||
426 | return; | ||
427 | } | ||
428 | |||
429 | // The process-type must be changed for a ForegroundApplication | ||
430 | // Unless it is a foreground-process, the application will not show in the dock or expose and the window | ||
431 | // will not behave properly. | ||
432 | ProcessSerialNumber currentProcess; | ||
433 | GetCurrentProcess( ¤tProcess ); | ||
434 | TransformProcessType( ¤tProcess, kProcessTransformToForegroundApplication ); | ||
435 | SetFrontProcess( ¤tProcess ); | ||
436 | |||
437 | SetWindowTitleWithCFString( windowReference, CFSTR( "ODE - Drawstuff" ) ); | ||
438 | RepositionWindow( windowReference, NULL, kWindowCenterOnMainScreen ); | ||
439 | |||
440 | ShowWindow( windowReference ); | ||
441 | |||
442 | if( !aglSetDrawable( aglContext, GetWindowPort( windowReference ) ) ){ | ||
443 | osxCloseMainWindow(); | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | if( !aglSetCurrentContext( aglContext ) ){ | ||
448 | osxCloseMainWindow(); | ||
449 | } | ||
450 | |||
451 | windowWidth = width; | ||
452 | windowHeight = height; | ||
453 | } | ||
454 | |||
455 | int osxInstallEventHandlers(){ | ||
456 | |||
457 | OSStatus error; | ||
458 | |||
459 | mouseUPP = NewEventHandlerUPP( osxMouseEventHandler ); | ||
460 | |||
461 | error = InstallEventHandler( GetApplicationEventTarget(), mouseUPP, GetEventTypeCount( OSX_MOUSE_EVENT_TYPES ), OSX_MOUSE_EVENT_TYPES, NULL, NULL ); | ||
462 | if( error != noErr ){ | ||
463 | return GL_FALSE; | ||
464 | } | ||
465 | |||
466 | keyboardUPP = NewEventHandlerUPP( osxKeyEventHandler ); | ||
467 | |||
468 | error = InstallEventHandler( GetApplicationEventTarget(), keyboardUPP, GetEventTypeCount( OSX_KEY_EVENT_TYPES ), OSX_KEY_EVENT_TYPES, NULL, NULL ); | ||
469 | if( error != noErr ){ | ||
470 | return GL_FALSE; | ||
471 | } | ||
472 | |||
473 | return GL_TRUE; | ||
474 | } | ||
475 | |||
476 | extern void dsPlatformSimLoop( int givenWindowWidth, int givenWindowHeight, dsFunctions *fn, int givenPause ){ | ||
477 | |||
478 | functions = fn; | ||
479 | |||
480 | paused = givenPause; | ||
481 | |||
482 | osxCreateMainWindow( givenWindowWidth, givenWindowHeight ); | ||
483 | osxInstallEventHandlers(); | ||
484 | |||
485 | dsStartGraphics( windowWidth, windowHeight, fn ); | ||
486 | |||
487 | static bool firsttime=true; | ||
488 | if( firsttime ) | ||
489 | { | ||
490 | fprintf | ||
491 | ( | ||
492 | stderr, | ||
493 | "\n" | ||
494 | "Simulation test environment v%d.%02d\n" | ||
495 | " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" | ||
496 | " Ctrl-O : single step when paused.\n" | ||
497 | " Ctrl-T : toggle textures (or say `-notex' on command line).\n" | ||
498 | " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" | ||
499 | " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" | ||
500 | " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" | ||
501 | " Ctrl-X : exit.\n" | ||
502 | "\n" | ||
503 | "Change the camera position by clicking + dragging in the window.\n" | ||
504 | " Left button - pan and tilt.\n" | ||
505 | " Right button (or Ctrl + button) - forward and sideways.\n" | ||
506 | " Left + Right button (or middle button, or Alt + button) - sideways and up.\n" | ||
507 | "\n",DS_VERSION >> 8,DS_VERSION & 0xff | ||
508 | ); | ||
509 | firsttime = false; | ||
510 | } | ||
511 | |||
512 | if( fn -> start ) fn->start(); | ||
513 | |||
514 | int frame = 1; | ||
515 | running = true; | ||
516 | while( running ){ | ||
517 | // read in and process all pending events for the main window | ||
518 | EventRef event; | ||
519 | EventTargetRef eventDispatcher = GetEventDispatcherTarget(); | ||
520 | while( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noErr ){ | ||
521 | SendEventToEventTarget( event, eventDispatcher ); | ||
522 | ReleaseEvent( event ); | ||
523 | } | ||
524 | |||
525 | dsDrawFrame( windowWidth, windowHeight, fn, paused && !singlestep ); | ||
526 | singlestep = false; | ||
527 | |||
528 | glFlush(); | ||
529 | aglSwapBuffers( aglContext ); | ||
530 | |||
531 | // capture frames if necessary | ||
532 | if( !paused && writeframes ){ | ||
533 | captureFrame( frame ); | ||
534 | frame++; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | if( fn->stop ) fn->stop(); | ||
539 | dsStopGraphics(); | ||
540 | |||
541 | osxCloseMainWindow(); | ||
542 | } | ||
diff --git a/libraries/ode-0.9/drawstuff/src/resource.h b/libraries/ode-0.9/drawstuff/src/resource.h new file mode 100644 index 0000000..15802b6 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/resource.h | |||
@@ -0,0 +1,28 @@ | |||
1 | //{{NO_DEPENDENCIES}} | ||
2 | // Microsoft Developer Studio generated include file. | ||
3 | // Used by resources.rc | ||
4 | // | ||
5 | #define IDD_MSGDLG 101 | ||
6 | #define IDR_MENU1 102 | ||
7 | #define IDD_ABOUT 103 | ||
8 | #define IDR_ACCELERATOR1 104 | ||
9 | #define IDC_LIST1 1000 | ||
10 | #define IDM_EXIT 40001 | ||
11 | #define IDM_ABOUT 40002 | ||
12 | #define IDM_PAUSE 40003 | ||
13 | #define IDM_PERF_MONITOR 40004 | ||
14 | #define IDM_SHADOWS 40005 | ||
15 | #define IDM_TEXTURES 40006 | ||
16 | #define IDM_SAVE_SETTINGS 40007 | ||
17 | #define IDM_SINGLE_STEP 40008 | ||
18 | |||
19 | // Next default values for new objects | ||
20 | // | ||
21 | #ifdef APSTUDIO_INVOKED | ||
22 | #ifndef APSTUDIO_READONLY_SYMBOLS | ||
23 | #define _APS_NEXT_RESOURCE_VALUE 108 | ||
24 | #define _APS_NEXT_COMMAND_VALUE 40009 | ||
25 | #define _APS_NEXT_CONTROL_VALUE 1001 | ||
26 | #define _APS_NEXT_SYMED_VALUE 101 | ||
27 | #endif | ||
28 | #endif | ||
diff --git a/libraries/ode-0.9/drawstuff/src/resources.rc b/libraries/ode-0.9/drawstuff/src/resources.rc new file mode 100644 index 0000000..61611f7 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/resources.rc | |||
@@ -0,0 +1,153 @@ | |||
1 | //Microsoft Developer Studio generated resource script. | ||
2 | // | ||
3 | #include "resource.h" | ||
4 | |||
5 | #define APSTUDIO_READONLY_SYMBOLS | ||
6 | ///////////////////////////////////////////////////////////////////////////// | ||
7 | // | ||
8 | // Generated from the TEXTINCLUDE 2 resource. | ||
9 | // | ||
10 | //#include "afxres.h" | ||
11 | |||
12 | // added by RLS to make this work with windres | ||
13 | #include "winresrc.h" | ||
14 | #define IDC_STATIC (-1) | ||
15 | |||
16 | ///////////////////////////////////////////////////////////////////////////// | ||
17 | #undef APSTUDIO_READONLY_SYMBOLS | ||
18 | |||
19 | ///////////////////////////////////////////////////////////////////////////// | ||
20 | // English (U.S.) resources | ||
21 | |||
22 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) | ||
23 | #ifdef _WIN32 | ||
24 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US | ||
25 | #pragma code_page(1252) | ||
26 | #endif //_WIN32 | ||
27 | |||
28 | ///////////////////////////////////////////////////////////////////////////// | ||
29 | // | ||
30 | // Dialog | ||
31 | // | ||
32 | |||
33 | IDD_ABOUT DIALOG DISCARDABLE 0, 0, 257, 105 | ||
34 | STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | ||
35 | CAPTION "About" | ||
36 | FONT 8, "MS Sans Serif" | ||
37 | BEGIN | ||
38 | DEFPUSHBUTTON "OK",IDOK,200,84,50,14 | ||
39 | LTEXT "Simulation test environment",IDC_STATIC,7,7,243,8 | ||
40 | LTEXT "Change the camera position by clicking + dragging in the main window.", | ||
41 | IDC_STATIC,7,24,243,8 | ||
42 | LTEXT "Left button - pan and tilt.",IDC_STATIC,25,37,225,8 | ||
43 | LTEXT "Right button - forward and sideways.",IDC_STATIC,25,48, | ||
44 | 225,8 | ||
45 | LTEXT "Left + Right button (or middle button) - sideways and up.", | ||
46 | IDC_STATIC,25,59,225,8 | ||
47 | END | ||
48 | |||
49 | |||
50 | #ifdef APSTUDIO_INVOKED | ||
51 | ///////////////////////////////////////////////////////////////////////////// | ||
52 | // | ||
53 | // TEXTINCLUDE | ||
54 | // | ||
55 | |||
56 | 1 TEXTINCLUDE DISCARDABLE | ||
57 | BEGIN | ||
58 | "resource.h\0" | ||
59 | END | ||
60 | |||
61 | 2 TEXTINCLUDE DISCARDABLE | ||
62 | BEGIN | ||
63 | //"#include ""afxres.h""\r\n" | ||
64 | "\0" | ||
65 | END | ||
66 | |||
67 | 3 TEXTINCLUDE DISCARDABLE | ||
68 | BEGIN | ||
69 | "\r\n" | ||
70 | "\0" | ||
71 | END | ||
72 | |||
73 | #endif // APSTUDIO_INVOKED | ||
74 | |||
75 | |||
76 | ///////////////////////////////////////////////////////////////////////////// | ||
77 | // | ||
78 | // Menu | ||
79 | // | ||
80 | |||
81 | IDR_MENU1 MENU DISCARDABLE | ||
82 | BEGIN | ||
83 | POPUP "&File" | ||
84 | BEGIN | ||
85 | MENUITEM "&Exit\tCtrl+X", IDM_EXIT | ||
86 | END | ||
87 | POPUP "&Simulation" | ||
88 | BEGIN | ||
89 | MENUITEM "&Pause\tCtrl+P", IDM_PAUSE | ||
90 | MENUITEM "Single Step\tCtrl+O", IDM_SINGLE_STEP | ||
91 | MENUITEM "Performance &Monitor", IDM_PERF_MONITOR, GRAYED | ||
92 | MENUITEM SEPARATOR | ||
93 | MENUITEM "&Shadows\tCtrl+S", IDM_SHADOWS, CHECKED | ||
94 | MENUITEM "&Textures\tCtrl+T", IDM_TEXTURES, CHECKED | ||
95 | MENUITEM SEPARATOR | ||
96 | MENUITEM "S&ave Settings", IDM_SAVE_SETTINGS, GRAYED | ||
97 | END | ||
98 | POPUP "&Help" | ||
99 | BEGIN | ||
100 | MENUITEM "&About", IDM_ABOUT | ||
101 | END | ||
102 | END | ||
103 | |||
104 | |||
105 | ///////////////////////////////////////////////////////////////////////////// | ||
106 | // | ||
107 | // DESIGNINFO | ||
108 | // | ||
109 | |||
110 | #ifdef APSTUDIO_INVOKED | ||
111 | GUIDELINES DESIGNINFO DISCARDABLE | ||
112 | BEGIN | ||
113 | IDD_ABOUT, DIALOG | ||
114 | BEGIN | ||
115 | LEFTMARGIN, 7 | ||
116 | RIGHTMARGIN, 250 | ||
117 | VERTGUIDE, 25 | ||
118 | TOPMARGIN, 7 | ||
119 | BOTTOMMARGIN, 98 | ||
120 | END | ||
121 | END | ||
122 | #endif // APSTUDIO_INVOKED | ||
123 | |||
124 | |||
125 | ///////////////////////////////////////////////////////////////////////////// | ||
126 | // | ||
127 | // Accelerator | ||
128 | // | ||
129 | |||
130 | IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE | ||
131 | BEGIN | ||
132 | "O", IDM_SINGLE_STEP, VIRTKEY, CONTROL, NOINVERT | ||
133 | "P", IDM_PAUSE, VIRTKEY, CONTROL, NOINVERT | ||
134 | "S", IDM_SHADOWS, VIRTKEY, CONTROL, NOINVERT | ||
135 | "T", IDM_TEXTURES, VIRTKEY, CONTROL, NOINVERT | ||
136 | "X", IDM_EXIT, VIRTKEY, CONTROL, NOINVERT | ||
137 | END | ||
138 | |||
139 | #endif // English (U.S.) resources | ||
140 | ///////////////////////////////////////////////////////////////////////////// | ||
141 | |||
142 | |||
143 | |||
144 | #ifndef APSTUDIO_INVOKED | ||
145 | ///////////////////////////////////////////////////////////////////////////// | ||
146 | // | ||
147 | // Generated from the TEXTINCLUDE 3 resource. | ||
148 | // | ||
149 | |||
150 | |||
151 | ///////////////////////////////////////////////////////////////////////////// | ||
152 | #endif // not APSTUDIO_INVOKED | ||
153 | |||
diff --git a/libraries/ode-0.9/drawstuff/src/windows.cpp b/libraries/ode-0.9/drawstuff/src/windows.cpp new file mode 100644 index 0000000..e2b442a --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/windows.cpp | |||
@@ -0,0 +1,527 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | #if defined(WIN32) || defined(__CYGWIN__)// this prevents warnings when dependencies built | ||
24 | #include <windows.h> | ||
25 | #endif | ||
26 | #include <ode/config.h> | ||
27 | #include <GL/gl.h> | ||
28 | |||
29 | #include "resource.h" | ||
30 | #include "internal.h" | ||
31 | |||
32 | //*************************************************************************** | ||
33 | // application globals | ||
34 | |||
35 | static HINSTANCE ghInstance = 0; | ||
36 | static int gnCmdShow = 0; | ||
37 | static HACCEL accelerators = 0; | ||
38 | static HWND main_window = 0; | ||
39 | |||
40 | //*************************************************************************** | ||
41 | // error and message handling | ||
42 | |||
43 | static void errorBox (char *title, char *msg, va_list ap) | ||
44 | { | ||
45 | char s[1000]; | ||
46 | vsprintf (s,msg,ap); | ||
47 | MessageBox (0,s,title,MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION); | ||
48 | } | ||
49 | |||
50 | |||
51 | static void dsWarning (char *msg, ...) | ||
52 | { | ||
53 | va_list ap; | ||
54 | va_start (ap,msg); | ||
55 | errorBox ("Warning",msg,ap); | ||
56 | } | ||
57 | |||
58 | |||
59 | extern "C" void dsError (char *msg, ...) | ||
60 | { | ||
61 | va_list ap; | ||
62 | va_start (ap,msg); | ||
63 | errorBox ("Error",msg,ap); | ||
64 | exit (1); | ||
65 | } | ||
66 | |||
67 | |||
68 | extern "C" void dsDebug (char *msg, ...) | ||
69 | { | ||
70 | va_list ap; | ||
71 | va_start (ap,msg); | ||
72 | errorBox ("INTERNAL ERROR",msg,ap); | ||
73 | // *((char *)0) = 0; ... commit SEGVicide ? | ||
74 | abort(); | ||
75 | exit (1); // should never get here, but just in case... | ||
76 | } | ||
77 | |||
78 | |||
79 | extern "C" void dsPrint (char *msg, ...) | ||
80 | { | ||
81 | va_list ap; | ||
82 | va_start (ap,msg); | ||
83 | vprintf (msg,ap); | ||
84 | } | ||
85 | |||
86 | //*************************************************************************** | ||
87 | // rendering thread | ||
88 | |||
89 | // globals used to communicate with rendering thread | ||
90 | |||
91 | static volatile int renderer_run = 1; | ||
92 | static volatile int renderer_pause = 0; // 0=run, 1=pause | ||
93 | static volatile int renderer_ss = 0; // single step command | ||
94 | static volatile int renderer_width = 1; | ||
95 | static volatile int renderer_height = 1; | ||
96 | static dsFunctions *renderer_fn = 0; | ||
97 | static volatile HDC renderer_dc = 0; | ||
98 | static volatile int keybuffer[16]; // fifo ring buffer for keypresses | ||
99 | static volatile int keybuffer_head = 0; // index of next key to put in (modified by GUI) | ||
100 | static volatile int keybuffer_tail = 0; // index of next key to take out (modified by renderer) | ||
101 | |||
102 | |||
103 | static void setupRendererGlobals() | ||
104 | { | ||
105 | renderer_run = 1; | ||
106 | renderer_pause = 0; | ||
107 | renderer_ss = 0; | ||
108 | renderer_width = 1; | ||
109 | renderer_height = 1; | ||
110 | renderer_fn = 0; | ||
111 | renderer_dc = 0; | ||
112 | keybuffer[16]; | ||
113 | keybuffer_head = 0; | ||
114 | keybuffer_tail = 0; | ||
115 | } | ||
116 | |||
117 | |||
118 | static DWORD WINAPI renderingThread (LPVOID lpParam) | ||
119 | { | ||
120 | // create openGL context and make it current | ||
121 | HGLRC glc = wglCreateContext (renderer_dc); | ||
122 | if (glc==NULL) dsError ("could not create OpenGL context"); | ||
123 | if (wglMakeCurrent (renderer_dc,glc) != TRUE) | ||
124 | dsError ("could not make OpenGL context current"); | ||
125 | |||
126 | // test openGL capabilities | ||
127 | int maxtsize=0; | ||
128 | glGetIntegerv (GL_MAX_TEXTURE_SIZE,&maxtsize); | ||
129 | if (maxtsize < 128) dsWarning ("max texture size too small (%dx%d)", | ||
130 | maxtsize,maxtsize); | ||
131 | |||
132 | dsStartGraphics (renderer_width,renderer_height,renderer_fn); | ||
133 | if (renderer_fn->start) renderer_fn->start(); | ||
134 | |||
135 | while (renderer_run) { | ||
136 | // need to make local copy of renderer_ss to help prevent races | ||
137 | int ss = renderer_ss; | ||
138 | dsDrawFrame (renderer_width,renderer_height,renderer_fn, | ||
139 | renderer_pause && !ss); | ||
140 | if (ss) renderer_ss = 0; | ||
141 | |||
142 | // read keys out of ring buffer and feed them to the command function | ||
143 | while (keybuffer_head != keybuffer_tail) { | ||
144 | if (renderer_fn->command) renderer_fn->command (keybuffer[keybuffer_tail]); | ||
145 | keybuffer_tail = (keybuffer_tail+1) & 15; | ||
146 | } | ||
147 | |||
148 | // swap buffers | ||
149 | SwapBuffers (renderer_dc); | ||
150 | } | ||
151 | |||
152 | if (renderer_fn->stop) renderer_fn->stop(); | ||
153 | dsStopGraphics(); | ||
154 | |||
155 | // delete openGL context | ||
156 | wglMakeCurrent (NULL,NULL); | ||
157 | wglDeleteContext (glc); | ||
158 | |||
159 | return 123; // magic value used to test for thread termination | ||
160 | } | ||
161 | |||
162 | //*************************************************************************** | ||
163 | // window handling | ||
164 | |||
165 | // callback function for "about" dialog box | ||
166 | |||
167 | static LRESULT CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, | ||
168 | LPARAM lParam) | ||
169 | { | ||
170 | switch (uMsg) { | ||
171 | case WM_INITDIALOG: | ||
172 | return TRUE; | ||
173 | case WM_COMMAND: | ||
174 | switch (wParam) { | ||
175 | case IDOK: | ||
176 | EndDialog (hDlg, TRUE); | ||
177 | return TRUE; | ||
178 | } | ||
179 | break; | ||
180 | } | ||
181 | return FALSE; | ||
182 | } | ||
183 | |||
184 | |||
185 | // callback function for the main window | ||
186 | |||
187 | static LRESULT CALLBACK mainWndProc (HWND hWnd, UINT msg, WPARAM wParam, | ||
188 | LPARAM lParam) | ||
189 | { | ||
190 | static int button=0,lastx=0,lasty=0; | ||
191 | int ctrl = int(wParam & MK_CONTROL); | ||
192 | |||
193 | switch (msg) { | ||
194 | case WM_LBUTTONDOWN: | ||
195 | case WM_MBUTTONDOWN: | ||
196 | case WM_RBUTTONDOWN: | ||
197 | if (msg==WM_LBUTTONDOWN) button |= 1; | ||
198 | else if (msg==WM_MBUTTONDOWN) button |= 2; | ||
199 | else button |= 4; | ||
200 | lastx = SHORT(LOWORD(lParam)); | ||
201 | lasty = SHORT(HIWORD(lParam)); | ||
202 | SetCapture (hWnd); | ||
203 | break; | ||
204 | |||
205 | case WM_LBUTTONUP: | ||
206 | case WM_MBUTTONUP: | ||
207 | case WM_RBUTTONUP: | ||
208 | if (msg==WM_LBUTTONUP) button &= ~1; | ||
209 | else if (msg==WM_MBUTTONUP) button &= ~2; | ||
210 | else button &= ~4; | ||
211 | if (button==0) ReleaseCapture(); | ||
212 | break; | ||
213 | |||
214 | case WM_MOUSEMOVE: { | ||
215 | int x = SHORT(LOWORD(lParam)); | ||
216 | int y = SHORT(HIWORD(lParam)); | ||
217 | if (button) dsMotion (button,x-lastx,y-lasty); | ||
218 | lastx = x; | ||
219 | lasty = y; | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | case WM_CHAR: { | ||
224 | if (wParam >= ' ' && wParam <= 126) { | ||
225 | int nexth = (keybuffer_head+1) & 15; | ||
226 | if (nexth != keybuffer_tail) { | ||
227 | keybuffer[keybuffer_head] = int(wParam); | ||
228 | keybuffer_head = nexth; | ||
229 | } | ||
230 | } | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | case WM_SIZE: | ||
235 | // lParam will contain the size of the *client* area! | ||
236 | renderer_width = LOWORD(lParam); | ||
237 | renderer_height = HIWORD(lParam); | ||
238 | break; | ||
239 | |||
240 | case WM_COMMAND: | ||
241 | switch (wParam & 0xffff) { | ||
242 | case IDM_ABOUT: | ||
243 | DialogBox (ghInstance,MAKEINTRESOURCE(IDD_ABOUT),hWnd, | ||
244 | (DLGPROC) AboutDlgProc); | ||
245 | break; | ||
246 | case IDM_PAUSE: { | ||
247 | renderer_pause ^= 1; | ||
248 | CheckMenuItem (GetMenu(hWnd),IDM_PAUSE, | ||
249 | renderer_pause ? MF_CHECKED : MF_UNCHECKED); | ||
250 | if (renderer_pause) renderer_ss = 0; | ||
251 | break; | ||
252 | } | ||
253 | case IDM_SINGLE_STEP: { | ||
254 | if (renderer_pause) | ||
255 | renderer_ss = 1; | ||
256 | else | ||
257 | SendMessage( hWnd, WM_COMMAND, IDM_PAUSE, 0 ); | ||
258 | break; | ||
259 | } | ||
260 | case IDM_PERF_MONITOR: { | ||
261 | dsWarning ("Performance monitor not yet implemented."); | ||
262 | break; | ||
263 | } | ||
264 | case IDM_TEXTURES: { | ||
265 | static int tex = 1; | ||
266 | tex ^= 1; | ||
267 | CheckMenuItem (GetMenu(hWnd),IDM_TEXTURES, | ||
268 | tex ? MF_CHECKED : MF_UNCHECKED); | ||
269 | dsSetTextures (tex); | ||
270 | break; | ||
271 | } | ||
272 | case IDM_SHADOWS: { | ||
273 | static int shadows = 1; | ||
274 | shadows ^= 1; | ||
275 | CheckMenuItem (GetMenu(hWnd),IDM_SHADOWS, | ||
276 | shadows ? MF_CHECKED : MF_UNCHECKED); | ||
277 | dsSetShadows (shadows); | ||
278 | break; | ||
279 | } | ||
280 | case IDM_SAVE_SETTINGS: { | ||
281 | dsWarning ("\"Save Settings\" not yet implemented."); | ||
282 | break; | ||
283 | } | ||
284 | case IDM_EXIT: | ||
285 | PostQuitMessage (0); | ||
286 | break; | ||
287 | } | ||
288 | break; | ||
289 | |||
290 | case WM_CLOSE: | ||
291 | PostQuitMessage (0); | ||
292 | break; | ||
293 | |||
294 | default: | ||
295 | return (DefWindowProc (hWnd, msg, wParam, lParam)); | ||
296 | } | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | |||
302 | // this comes from an MSDN example. believe it or not, this is the recommended | ||
303 | // way to get the console window handle. | ||
304 | |||
305 | static HWND GetConsoleHwnd() | ||
306 | { | ||
307 | // the console window title to a "unique" value, then find the window | ||
308 | // that has this title. | ||
309 | char title[1024]; | ||
310 | wsprintf (title,"DrawStuff:%d/%d",GetTickCount(),GetCurrentProcessId()); | ||
311 | SetConsoleTitle (title); | ||
312 | Sleep(40); // ensure window title has been updated | ||
313 | return FindWindow (NULL,title); | ||
314 | } | ||
315 | |||
316 | |||
317 | static void drawStuffStartup() | ||
318 | { | ||
319 | static int startup_called = 0; | ||
320 | if (startup_called) return; | ||
321 | startup_called = 1; | ||
322 | if (!ghInstance) | ||
323 | ghInstance = GetModuleHandleA (NULL); | ||
324 | gnCmdShow = SW_SHOWNORMAL; // @@@ fix this later | ||
325 | |||
326 | // redirect standard I/O to a new console (except on cygwin) | ||
327 | #ifndef __CYGWIN__ | ||
328 | FreeConsole(); | ||
329 | if (AllocConsole()==0) dsError ("AllocConsole() failed"); | ||
330 | if (freopen ("CONIN$","rt",stdin)==0) dsError ("could not open stdin"); | ||
331 | if (freopen ("CONOUT$","wt",stdout)==0) dsError ("could not open stdout"); | ||
332 | if (freopen ("CONOUT$","wt",stderr)==0) dsError ("could not open stderr"); | ||
333 | BringWindowToTop (GetConsoleHwnd()); | ||
334 | SetConsoleTitle ("DrawStuff Messages"); | ||
335 | #endif | ||
336 | |||
337 | // register the window class | ||
338 | WNDCLASS wc; | ||
339 | wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; | ||
340 | wc.lpfnWndProc = mainWndProc; | ||
341 | wc.cbClsExtra = 0; | ||
342 | wc.cbWndExtra = 0; | ||
343 | wc.hInstance = ghInstance; | ||
344 | wc.hIcon = LoadIcon (NULL,IDI_APPLICATION); | ||
345 | wc.hCursor = LoadCursor (NULL,IDC_ARROW); | ||
346 | wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); | ||
347 | wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); | ||
348 | wc.lpszClassName = "SimAppClass"; | ||
349 | if (RegisterClass (&wc)==0) dsError ("could not register window class"); | ||
350 | |||
351 | // load accelerators | ||
352 | accelerators = LoadAccelerators (ghInstance, | ||
353 | MAKEINTRESOURCE(IDR_ACCELERATOR1)); | ||
354 | if (accelerators==NULL) dsError ("could not load accelerators"); | ||
355 | } | ||
356 | |||
357 | |||
358 | void dsPlatformSimLoop (int window_width, int window_height, | ||
359 | dsFunctions *fn, int initial_pause) | ||
360 | { | ||
361 | drawStuffStartup(); | ||
362 | setupRendererGlobals(); | ||
363 | renderer_pause = initial_pause; | ||
364 | |||
365 | // create window - but first get window size for desired size of client area. | ||
366 | // if this adjustment isn't made then the openGL area will be shifted into | ||
367 | // the nonclient area and determining the frame buffer coordinate from the | ||
368 | // client area coordinate will be hard. | ||
369 | RECT winrect; | ||
370 | winrect.left = 50; | ||
371 | winrect.top = 80; | ||
372 | winrect.right = winrect.left + window_width; | ||
373 | winrect.bottom = winrect.top + window_height; | ||
374 | DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | ||
375 | AdjustWindowRect (&winrect,style,1); | ||
376 | char title[100]; | ||
377 | sprintf (title,"Simulation test environment v%d.%02d", | ||
378 | DS_VERSION >> 8,DS_VERSION & 0xff); | ||
379 | main_window = CreateWindow ("SimAppClass",title,style, | ||
380 | winrect.left,winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top, | ||
381 | NULL,NULL,ghInstance,NULL); | ||
382 | if (main_window==NULL) dsError ("could not create main window"); | ||
383 | ShowWindow (main_window, gnCmdShow); | ||
384 | |||
385 | HDC dc = GetDC (main_window); // get DC for this window | ||
386 | if (dc==NULL) dsError ("could not get window DC"); | ||
387 | |||
388 | // set pixel format for DC | ||
389 | |||
390 | PIXELFORMATDESCRIPTOR pfd = { | ||
391 | sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd | ||
392 | 1, // version number | ||
393 | PFD_DRAW_TO_WINDOW | // support window | ||
394 | PFD_SUPPORT_OPENGL | // support OpenGL | ||
395 | PFD_DOUBLEBUFFER, // double buffered | ||
396 | PFD_TYPE_RGBA, // RGBA type | ||
397 | 24, // 24-bit color depth | ||
398 | 0, 0, 0, 0, 0, 0, // color bits ignored | ||
399 | 0, // no alpha buffer | ||
400 | 0, // shift bit ignored | ||
401 | 0, // no accumulation buffer | ||
402 | 0, 0, 0, 0, // accum bits ignored | ||
403 | 32, // 32-bit z-buffer | ||
404 | 0, // no stencil buffer | ||
405 | 0, // no auxiliary buffer | ||
406 | PFD_MAIN_PLANE, // main layer | ||
407 | 0, // reserved | ||
408 | 0, 0, 0 // layer masks ignored | ||
409 | }; | ||
410 | // get the best available match of pixel format for the device context | ||
411 | int iPixelFormat = ChoosePixelFormat (dc,&pfd); | ||
412 | if (iPixelFormat==0) | ||
413 | dsError ("could not find a good OpenGL pixel format"); | ||
414 | // set the pixel format of the device context | ||
415 | if (SetPixelFormat (dc,iPixelFormat,&pfd)==FALSE) | ||
416 | dsError ("could not set DC pixel format for OpenGL"); | ||
417 | |||
418 | // ********** | ||
419 | // start the rendering thread | ||
420 | |||
421 | // set renderer globals | ||
422 | renderer_dc = dc; | ||
423 | renderer_width = window_width; | ||
424 | renderer_height = window_height; | ||
425 | renderer_fn = fn; | ||
426 | |||
427 | DWORD threadId, thirdParam = 0; | ||
428 | HANDLE hThread; | ||
429 | |||
430 | hThread = CreateThread( | ||
431 | NULL, // no security attributes | ||
432 | 0, // use default stack size | ||
433 | renderingThread, // thread function | ||
434 | &thirdParam, // argument to thread function | ||
435 | 0, // use default creation flags | ||
436 | &threadId); // returns the thread identifier | ||
437 | |||
438 | if (hThread==NULL) dsError ("Could not create rendering thread"); | ||
439 | |||
440 | // ********** | ||
441 | // start GUI message processing | ||
442 | |||
443 | MSG msg; | ||
444 | while (GetMessage (&msg,main_window,0,0)) { | ||
445 | if (!TranslateAccelerator (main_window,accelerators,&msg)) { | ||
446 | TranslateMessage (&msg); | ||
447 | DispatchMessage (&msg); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | // terminate rendering thread | ||
452 | renderer_run = 0; | ||
453 | DWORD ret = WaitForSingleObject (hThread,2000); | ||
454 | if (ret==WAIT_TIMEOUT) dsWarning ("Could not kill rendering thread (1)"); | ||
455 | DWORD exitcode=0; | ||
456 | if (!(GetExitCodeThread (hThread,&exitcode) && exitcode == 123)) | ||
457 | dsWarning ("Could not kill rendering thread (2)"); | ||
458 | CloseHandle (hThread); // dont need thread handle anymore | ||
459 | |||
460 | // destroy window | ||
461 | DestroyWindow (main_window); | ||
462 | } | ||
463 | |||
464 | |||
465 | extern "C" void dsStop() | ||
466 | { | ||
467 | // just calling PostQuitMessage() here wont work, as this function is | ||
468 | // typically called from the rendering thread, not the GUI thread. | ||
469 | // instead we must post the message to the GUI window explicitly. | ||
470 | |||
471 | if (main_window) PostMessage (main_window,WM_QUIT,0,0); | ||
472 | } | ||
473 | |||
474 | |||
475 | extern "C" double dsElapsedTime() | ||
476 | { | ||
477 | static double prev=0.0; | ||
478 | double curr = timeGetTime()/1000.0; | ||
479 | if (!prev) | ||
480 | prev=curr; | ||
481 | double retval = curr-prev; | ||
482 | prev=curr; | ||
483 | if (retval>1.0) retval=1.0; | ||
484 | if (retval<dEpsilon) retval=dEpsilon; | ||
485 | return retval; | ||
486 | } | ||
487 | |||
488 | |||
489 | // JPerkins: if running as a DLL, grab my module handle at load time so | ||
490 | // I can find the accelerators table later | ||
491 | |||
492 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) | ||
493 | { | ||
494 | switch (fdwReason) | ||
495 | { | ||
496 | case DLL_PROCESS_ATTACH: | ||
497 | ghInstance = hinstDLL; | ||
498 | break; | ||
499 | } | ||
500 | return TRUE; | ||
501 | } | ||
502 | |||
503 | |||
504 | // JPerkins: the new build system can set the entry point of the tests to | ||
505 | // main(); this code is no longer necessary | ||
506 | /* | ||
507 | |||
508 | //*************************************************************************** | ||
509 | // windows entry point | ||
510 | // | ||
511 | // NOTE: WinMain is not guaranteed to be called with MinGW, because MinGW | ||
512 | // always calls main if it is defined and most users of this library will | ||
513 | // define their own main. So the startup functionality is kept in | ||
514 | // zDriverStartup(), which is also called when dsSimulationLoop() is called. | ||
515 | |||
516 | extern "C" int main (int argc, char **argv); | ||
517 | |||
518 | |||
519 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, | ||
520 | LPSTR lpCmdLine, int nCmdShow) | ||
521 | { | ||
522 | drawStuffStartup(); | ||
523 | return main (0,0); // @@@ should really pass cmd line arguments | ||
524 | } | ||
525 | |||
526 | */ | ||
527 | |||
diff --git a/libraries/ode-0.9/drawstuff/src/x11.cpp b/libraries/ode-0.9/drawstuff/src/x11.cpp new file mode 100644 index 0000000..639ce7b --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/x11.cpp | |||
@@ -0,0 +1,418 @@ | |||
1 | /************************************************************************* | ||
2 | * * | ||
3 | * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * | ||
4 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * | ||
5 | * * | ||
6 | * This library is free software; you can redistribute it and/or * | ||
7 | * modify it under the terms of EITHER: * | ||
8 | * (1) The GNU Lesser General Public License as published by the Free * | ||
9 | * Software Foundation; either version 2.1 of the License, or (at * | ||
10 | * your option) any later version. The text of the GNU Lesser * | ||
11 | * General Public License is included with this library in the * | ||
12 | * file LICENSE.TXT. * | ||
13 | * (2) The BSD-style license that is included with this library in * | ||
14 | * the file LICENSE-BSD.TXT. * | ||
15 | * * | ||
16 | * This library is distributed in the hope that it will be useful, * | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * | ||
19 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * | ||
20 | * * | ||
21 | *************************************************************************/ | ||
22 | |||
23 | // main window and event handling for X11 | ||
24 | |||
25 | #include <ode/config.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <stdarg.h> | ||
29 | #include <X11/Xlib.h> | ||
30 | #include <X11/Xatom.h> | ||
31 | #include <X11/keysym.h> | ||
32 | #include <GL/glx.h> | ||
33 | |||
34 | #ifdef HAVE_SYS_TIME_H | ||
35 | #include <sys/time.h> | ||
36 | #endif | ||
37 | |||
38 | #include <drawstuff/drawstuff.h> | ||
39 | #include <drawstuff/version.h> | ||
40 | #include "internal.h" | ||
41 | |||
42 | //*************************************************************************** | ||
43 | // error handling for unix | ||
44 | |||
45 | static void printMessage (char *msg1, char *msg2, va_list ap) | ||
46 | { | ||
47 | fflush (stderr); | ||
48 | fflush (stdout); | ||
49 | fprintf (stderr,"\n%s: ",msg1); | ||
50 | vfprintf (stderr,msg2,ap); | ||
51 | fprintf (stderr,"\n"); | ||
52 | fflush (stderr); | ||
53 | } | ||
54 | |||
55 | |||
56 | extern "C" void dsError (char *msg, ...) | ||
57 | { | ||
58 | va_list ap; | ||
59 | va_start (ap,msg); | ||
60 | printMessage ("Error",msg,ap); | ||
61 | exit (1); | ||
62 | } | ||
63 | |||
64 | |||
65 | extern "C" void dsDebug (char *msg, ...) | ||
66 | { | ||
67 | va_list ap; | ||
68 | va_start (ap,msg); | ||
69 | printMessage ("INTERNAL ERROR",msg,ap); | ||
70 | // *((char *)0) = 0; ... commit SEGVicide ? | ||
71 | abort(); | ||
72 | } | ||
73 | |||
74 | |||
75 | extern "C" void dsPrint (char *msg, ...) | ||
76 | { | ||
77 | va_list ap; | ||
78 | va_start (ap,msg); | ||
79 | vprintf (msg,ap); | ||
80 | } | ||
81 | |||
82 | //*************************************************************************** | ||
83 | // openGL window | ||
84 | |||
85 | // X11 display info | ||
86 | static Display *display=0; | ||
87 | static int screen=0; | ||
88 | static XVisualInfo *visual=0; // best visual for openGL | ||
89 | static Colormap colormap=0; // window's colormap | ||
90 | static Atom wm_protocols_atom = 0; | ||
91 | static Atom wm_delete_window_atom = 0; | ||
92 | |||
93 | // window and openGL | ||
94 | static Window win=0; // X11 window, 0 if not initialized | ||
95 | static int width=0,height=0; // window size | ||
96 | static GLXContext glx_context=0; // openGL rendering context | ||
97 | static int last_key_pressed=0; // last key pressed in the window | ||
98 | static int run=1; // 1 if simulation running | ||
99 | static int pause=0; // 1 if in `pause' mode | ||
100 | static int singlestep=0; // 1 if single step key pressed | ||
101 | static int writeframes=0; // 1 if frame files to be written | ||
102 | |||
103 | |||
104 | static void createMainWindow (int _width, int _height) | ||
105 | { | ||
106 | // create X11 display connection | ||
107 | display = XOpenDisplay (NULL); | ||
108 | if (!display) dsError ("can not open X11 display"); | ||
109 | screen = DefaultScreen(display); | ||
110 | |||
111 | // get GL visual | ||
112 | static int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16, | ||
113 | GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, | ||
114 | GLX_BLUE_SIZE,4, None}; | ||
115 | visual = glXChooseVisual (display,screen,attribList); | ||
116 | if (!visual) dsError ("no good X11 visual found for OpenGL"); | ||
117 | |||
118 | // create colormap | ||
119 | colormap = XCreateColormap (display,RootWindow(display,screen), | ||
120 | visual->visual,AllocNone); | ||
121 | |||
122 | // initialize variables | ||
123 | win = 0; | ||
124 | width = _width; | ||
125 | height = _height; | ||
126 | glx_context = 0; | ||
127 | last_key_pressed = 0; | ||
128 | |||
129 | if (width < 1 || height < 1) dsDebug (0,"bad window width or height"); | ||
130 | |||
131 | // create the window | ||
132 | XSetWindowAttributes attributes; | ||
133 | attributes.background_pixel = BlackPixel(display,screen); | ||
134 | attributes.colormap = colormap; | ||
135 | attributes.event_mask = ButtonPressMask | ButtonReleaseMask | | ||
136 | KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionHintMask | | ||
137 | StructureNotifyMask; | ||
138 | win = XCreateWindow (display,RootWindow(display,screen),50,50,width,height, | ||
139 | 0,visual->depth, InputOutput,visual->visual, | ||
140 | CWBackPixel | CWColormap | CWEventMask,&attributes); | ||
141 | |||
142 | // associate a GLX context with the window | ||
143 | glx_context = glXCreateContext (display,visual,0,GL_TRUE); | ||
144 | if (!glx_context) dsError ("can't make an OpenGL context"); | ||
145 | |||
146 | // set the window title | ||
147 | XTextProperty window_name; | ||
148 | window_name.value = (unsigned char *) "Simulation"; | ||
149 | window_name.encoding = XA_STRING; | ||
150 | window_name.format = 8; | ||
151 | window_name.nitems = strlen((char *) window_name.value); | ||
152 | XSetWMName (display,win,&window_name); | ||
153 | |||
154 | // participate in the window manager 'delete yourself' protocol | ||
155 | wm_protocols_atom = XInternAtom (display,"WM_PROTOCOLS",False); | ||
156 | wm_delete_window_atom = XInternAtom (display,"WM_DELETE_WINDOW",False); | ||
157 | if (XSetWMProtocols (display,win,&wm_delete_window_atom,1)==0) | ||
158 | dsError ("XSetWMProtocols() call failed"); | ||
159 | |||
160 | // pop up the window | ||
161 | XMapWindow (display,win); | ||
162 | XSync (display,win); | ||
163 | } | ||
164 | |||
165 | |||
166 | static void destroyMainWindow() | ||
167 | { | ||
168 | glXDestroyContext (display,glx_context); | ||
169 | XDestroyWindow (display,win); | ||
170 | XSync (display,0); | ||
171 | XCloseDisplay(display); | ||
172 | display = 0; | ||
173 | win = 0; | ||
174 | glx_context = 0; | ||
175 | } | ||
176 | |||
177 | |||
178 | static void handleEvent (XEvent &event, dsFunctions *fn) | ||
179 | { | ||
180 | static int mx=0,my=0; // mouse position | ||
181 | static int mode = 0; // mouse button bits | ||
182 | |||
183 | switch (event.type) { | ||
184 | |||
185 | case ButtonPress: { | ||
186 | if (event.xbutton.button == Button1) mode |= 1; | ||
187 | if (event.xbutton.button == Button2) mode |= 2; | ||
188 | if (event.xbutton.button == Button3) mode |= 4; | ||
189 | mx = event.xbutton.x; | ||
190 | my = event.xbutton.y; | ||
191 | } | ||
192 | return; | ||
193 | |||
194 | case ButtonRelease: { | ||
195 | if (event.xbutton.button == Button1) mode &= (~1); | ||
196 | if (event.xbutton.button == Button2) mode &= (~2); | ||
197 | if (event.xbutton.button == Button3) mode &= (~4); | ||
198 | mx = event.xbutton.x; | ||
199 | my = event.xbutton.x; | ||
200 | } | ||
201 | return; | ||
202 | |||
203 | case MotionNotify: { | ||
204 | if (event.xmotion.is_hint) { | ||
205 | Window root,child; | ||
206 | unsigned int mask; | ||
207 | XQueryPointer (display,win,&root,&child,&event.xbutton.x_root, | ||
208 | &event.xbutton.y_root,&event.xbutton.x,&event.xbutton.y, | ||
209 | &mask); | ||
210 | } | ||
211 | dsMotion (mode, event.xmotion.x - mx, event.xmotion.y - my); | ||
212 | mx = event.xmotion.x; | ||
213 | my = event.xmotion.y; | ||
214 | } | ||
215 | return; | ||
216 | |||
217 | case KeyPress: { | ||
218 | KeySym key; | ||
219 | XLookupString (&event.xkey,NULL,0,&key,0); | ||
220 | if ((event.xkey.state & ControlMask) == 0) { | ||
221 | if (key >= ' ' && key <= 126 && fn->command) fn->command (key); | ||
222 | } | ||
223 | else if (event.xkey.state & ControlMask) { | ||
224 | switch (key) { | ||
225 | case 't': case 'T': | ||
226 | dsSetTextures (dsGetTextures() ^ 1); | ||
227 | break; | ||
228 | case 's': case 'S': | ||
229 | dsSetShadows (dsGetShadows() ^ 1); | ||
230 | break; | ||
231 | case 'x': case 'X': | ||
232 | run = 0; | ||
233 | break; | ||
234 | case 'p': case 'P': | ||
235 | pause ^= 1; | ||
236 | singlestep = 0; | ||
237 | break; | ||
238 | case 'o': case 'O': | ||
239 | if (pause) singlestep = 1; | ||
240 | break; | ||
241 | case 'v': case 'V': { | ||
242 | float xyz[3],hpr[3]; | ||
243 | dsGetViewpoint (xyz,hpr); | ||
244 | printf ("Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", | ||
245 | xyz[0],xyz[1],xyz[2],hpr[0],hpr[1],hpr[2]); | ||
246 | break; | ||
247 | } | ||
248 | case 'w': case 'W': | ||
249 | writeframes ^= 1; | ||
250 | if (writeframes) printf ("Now writing frames to PPM files\n"); | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | last_key_pressed = key; // a kludgy place to put this... | ||
255 | } | ||
256 | return; | ||
257 | |||
258 | case KeyRelease: { | ||
259 | // hmmmm... | ||
260 | } | ||
261 | return; | ||
262 | |||
263 | case ClientMessage: | ||
264 | if (event.xclient.message_type == wm_protocols_atom && | ||
265 | event.xclient.format == 32 && | ||
266 | Atom(event.xclient.data.l[0]) == wm_delete_window_atom) { | ||
267 | run = 0; | ||
268 | return; | ||
269 | } | ||
270 | return; | ||
271 | |||
272 | case ConfigureNotify: | ||
273 | width = event.xconfigure.width; | ||
274 | height = event.xconfigure.height; | ||
275 | return; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | |||
280 | // return the index of the highest bit | ||
281 | static int getHighBitIndex (unsigned int x) | ||
282 | { | ||
283 | int i = 0; | ||
284 | while (x) { | ||
285 | i++; | ||
286 | x >>= 1; | ||
287 | } | ||
288 | return i-1; | ||
289 | } | ||
290 | |||
291 | |||
292 | // shift x left by i, where i can be positive or negative | ||
293 | #define SHIFTL(x,i) (((i) >= 0) ? ((x) << (i)) : ((x) >> (-i))) | ||
294 | |||
295 | |||
296 | static void captureFrame (int num) | ||
297 | { | ||
298 | fprintf (stderr,"capturing frame %04d\n",num); | ||
299 | |||
300 | char s[100]; | ||
301 | sprintf (s,"frame/frame%04d.ppm",num); | ||
302 | FILE *f = fopen (s,"wb"); | ||
303 | if (!f) dsError ("can't open \"%s\" for writing",s); | ||
304 | fprintf (f,"P6\n%d %d\n255\n",width,height); | ||
305 | XImage *image = XGetImage (display,win,0,0,width,height,~0,ZPixmap); | ||
306 | |||
307 | int rshift = 7 - getHighBitIndex (image->red_mask); | ||
308 | int gshift = 7 - getHighBitIndex (image->green_mask); | ||
309 | int bshift = 7 - getHighBitIndex (image->blue_mask); | ||
310 | |||
311 | for (int y=0; y<height; y++) { | ||
312 | for (int x=0; x<width; x++) { | ||
313 | unsigned long pixel = XGetPixel (image,x,y); | ||
314 | unsigned char b[3]; | ||
315 | b[0] = SHIFTL(pixel & image->red_mask,rshift); | ||
316 | b[1] = SHIFTL(pixel & image->green_mask,gshift); | ||
317 | b[2] = SHIFTL(pixel & image->blue_mask,bshift); | ||
318 | fwrite (b,3,1,f); | ||
319 | } | ||
320 | } | ||
321 | fclose (f); | ||
322 | XDestroyImage (image); | ||
323 | } | ||
324 | |||
325 | |||
326 | void dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, | ||
327 | int initial_pause) | ||
328 | { | ||
329 | pause = initial_pause; | ||
330 | createMainWindow (window_width, window_height); | ||
331 | glXMakeCurrent (display,win,glx_context); | ||
332 | |||
333 | dsStartGraphics (window_width,window_height,fn); | ||
334 | |||
335 | static bool firsttime=true; | ||
336 | if (firsttime) | ||
337 | { | ||
338 | fprintf | ||
339 | ( | ||
340 | stderr, | ||
341 | "\n" | ||
342 | "Simulation test environment v%d.%02d\n" | ||
343 | " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" | ||
344 | " Ctrl-O : single step when paused.\n" | ||
345 | " Ctrl-T : toggle textures (or say `-notex' on command line).\n" | ||
346 | " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" | ||
347 | " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" | ||
348 | " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" | ||
349 | " Ctrl-X : exit.\n" | ||
350 | "\n" | ||
351 | "Change the camera position by clicking + dragging in the window.\n" | ||
352 | " Left button - pan and tilt.\n" | ||
353 | " Right button - forward and sideways.\n" | ||
354 | " Left + Right button (or middle button) - sideways and up.\n" | ||
355 | "\n",DS_VERSION >> 8,DS_VERSION & 0xff | ||
356 | ); | ||
357 | firsttime = false; | ||
358 | } | ||
359 | |||
360 | if (fn->start) fn->start(); | ||
361 | |||
362 | int frame = 1; | ||
363 | run = 1; | ||
364 | while (run) { | ||
365 | // read in and process all pending events for the main window | ||
366 | XEvent event; | ||
367 | while (run && XPending (display)) { | ||
368 | XNextEvent (display,&event); | ||
369 | handleEvent (event,fn); | ||
370 | } | ||
371 | |||
372 | dsDrawFrame (width,height,fn,pause && !singlestep); | ||
373 | singlestep = 0; | ||
374 | |||
375 | glFlush(); | ||
376 | glXSwapBuffers (display,win); | ||
377 | XSync (display,0); | ||
378 | |||
379 | // capture frames if necessary | ||
380 | if (pause==0 && writeframes) { | ||
381 | captureFrame (frame); | ||
382 | frame++; | ||
383 | } | ||
384 | }; | ||
385 | |||
386 | if (fn->stop) fn->stop(); | ||
387 | dsStopGraphics(); | ||
388 | |||
389 | destroyMainWindow(); | ||
390 | } | ||
391 | |||
392 | |||
393 | extern "C" void dsStop() | ||
394 | { | ||
395 | run = 0; | ||
396 | } | ||
397 | |||
398 | |||
399 | extern "C" double dsElapsedTime() | ||
400 | { | ||
401 | #if HAVE_GETTIMEOFDAY | ||
402 | static double prev=0.0; | ||
403 | timeval tv ; | ||
404 | |||
405 | gettimeofday(&tv, 0); | ||
406 | double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; | ||
407 | if (!prev) | ||
408 | prev=curr; | ||
409 | double retval = curr-prev; | ||
410 | prev=curr; | ||
411 | if (retval>1.0) retval=1.0; | ||
412 | if (retval<dEpsilon) retval=dEpsilon; | ||
413 | return retval; | ||
414 | #else | ||
415 | return 0.01666; // Assume 60 fps | ||
416 | #endif | ||
417 | } | ||
418 | |||