diff options
Diffstat (limited to 'libs/ode-0.16.1/drawstuff/src')
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/Makefile.am | 26 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/Makefile.in | 655 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/drawstuff.cpp | 1671 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/internal.h | 50 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/osx.cpp | 347 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/resource.h | 28 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/resources.rc | 153 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/windows.cpp | 536 | ||||
-rw-r--r-- | libs/ode-0.16.1/drawstuff/src/x11.cpp | 459 |
9 files changed, 3925 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/drawstuff/src/Makefile.am b/libs/ode-0.16.1/drawstuff/src/Makefile.am new file mode 100644 index 0000000..911f4fd --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/Makefile.am @@ -0,0 +1,26 @@ +# Drawstuff is meant as an aid for testing and not as a full +# rendering library. + +noinst_LTLIBRARIES = libdrawstuff.la +libdrawstuff_la_SOURCES = drawstuff.cpp internal.h +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -DDEFAULT_PATH_TO_TEXTURES='"$(top_srcdir)/drawstuff/textures/"' \ + $(X11_CFLAGS) + +if WIN32 +libdrawstuff_la_SOURCES+= windows.cpp resource.h resources.rc +libdrawstuff_la_LIBADD = -lwinmm -lgdi32 +libdrawstuff_la_LDFLAGS = -no-undefined +endif + +if X11 +libdrawstuff_la_SOURCES+= x11.cpp +libdrawstuff_la_LIBADD = $(X11_LIBS) +endif + +if OSX +libdrawstuff_la_SOURCES+= osx.cpp +endif + diff --git a/libs/ode-0.16.1/drawstuff/src/Makefile.in b/libs/ode-0.16.1/drawstuff/src/Makefile.in new file mode 100644 index 0000000..4fb86f7 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/Makefile.in @@ -0,0 +1,655 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Drawstuff is meant as an aid for testing and not as a full +# rendering library. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WIN32_TRUE@am__append_1 = windows.cpp resource.h resources.rc +@X11_TRUE@am__append_2 = x11.cpp +@OSX_TRUE@am__append_3 = osx.cpp +subdir = drawstuff/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +@X11_TRUE@libdrawstuff_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__libdrawstuff_la_SOURCES_DIST = drawstuff.cpp internal.h \ + windows.cpp resource.h resources.rc x11.cpp osx.cpp +@WIN32_TRUE@am__objects_1 = windows.lo +@X11_TRUE@am__objects_2 = x11.lo +@OSX_TRUE@am__objects_3 = osx.lo +am_libdrawstuff_la_OBJECTS = drawstuff.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) +libdrawstuff_la_OBJECTS = $(am_libdrawstuff_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libdrawstuff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libdrawstuff_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdrawstuff_la_SOURCES) +DIST_SOURCES = $(am__libdrawstuff_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libdrawstuff.la +libdrawstuff_la_SOURCES = drawstuff.cpp internal.h $(am__append_1) \ + $(am__append_2) $(am__append_3) +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -DDEFAULT_PATH_TO_TEXTURES='"$(top_srcdir)/drawstuff/textures/"' \ + $(X11_CFLAGS) + +@WIN32_TRUE@libdrawstuff_la_LIBADD = -lwinmm -lgdi32 +@X11_TRUE@libdrawstuff_la_LIBADD = $(X11_LIBS) +@WIN32_TRUE@libdrawstuff_la_LDFLAGS = -no-undefined +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign drawstuff/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign drawstuff/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdrawstuff.la: $(libdrawstuff_la_OBJECTS) $(libdrawstuff_la_DEPENDENCIES) $(EXTRA_libdrawstuff_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libdrawstuff_la_LINK) $(libdrawstuff_la_OBJECTS) $(libdrawstuff_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drawstuff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windows.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp b/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp new file mode 100644 index 0000000..351be93 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp @@ -0,0 +1,1671 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +simple graphics. + +the following command line flags can be used (typically under unix) + -notex Do not use any textures + -noshadow[s] Do not draw any shadows + -pause Start the simulation paused + -texturepath <path> Inform an alternative textures path + +TODO +---- + +manage openGL state changes better + +*/ + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <ode/ode.h> +#include "config.h" + +#ifdef HAVE_APPLE_OPENGL_FRAMEWORK +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif + +#include "drawstuff/drawstuff.h" +#include "internal.h" + +//*************************************************************************** +// misc + +#ifndef DEFAULT_PATH_TO_TEXTURES +#if 0 +#define DEFAULT_PATH_TO_TEXTURES "..\\textures\\" +#else +#define DEFAULT_PATH_TO_TEXTURES "../textures/" +#endif +#endif + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +// constants to convert degrees to radians and the reverse +#define RAD_TO_DEG (180.0/M_PI) +#define DEG_TO_RAD (M_PI/180.0) + +// light vector. LIGHTZ is implicitly 1 +#define LIGHTX (1.0f) +#define LIGHTY (0.4f) + +// ground and sky +#define SHADOW_INTENSITY (0.65f) +#define GROUND_R (0.5f) // ground color for when there's no texture +#define GROUND_G (0.5f) +#define GROUND_B (0.3f) + +const float ground_scale = 1.0f/1.0f; // ground texture scale (1/size) +const float ground_ofsx = 0.5; // offset of ground texture +const float ground_ofsy = 0.5; +const float sky_scale = 1.0f/4.0f; // sky texture scale (1/size) +const float sky_height = 1.0f; // sky height above viewpoint + +//*************************************************************************** +// misc mathematics stuff + +static void normalizeVector3 (float v[3]) +{ + float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; + if (len <= 0.0f) { + v[0] = 1; + v[1] = 0; + v[2] = 0; + } + else { + len = 1.0f / (float)sqrt(len); + v[0] *= len; + v[1] *= len; + v[2] *= len; + } +} + +static void crossProduct3(float res[3], const float a[3], const float b[3]) +{ + float res_0 = a[1]*b[2] - a[2]*b[1]; + float res_1 = a[2]*b[0] - a[0]*b[2]; + float res_2 = a[0]*b[1] - a[1]*b[0]; + // Only assign after all the calculations are over to avoid incurring memory aliasing + res[0] = res_0; + res[1] = res_1; + res[2] = res_2; +} + +//*************************************************************************** +// PPM image object + +typedef unsigned char byte; + +class Image { + int image_width,image_height; + byte *image_data; +public: + Image (char *filename); + // load from PPM file + ~Image(); + int width() { return image_width; } + int height() { return image_height; } + byte *data() { return image_data; } +}; + + +// skip over whitespace and comments in a stream. + +static void skipWhiteSpace (char *filename, FILE *f) +{ + int c,d; + for(;;) { + c = fgetc(f); + if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); + + // skip comments + if (c == '#') { + do { + d = fgetc(f); + if (d==EOF) dsError ("unexpected end of file in \"%s\"",filename); + } while (d != '\n'); + continue; + } + + if (c > ' ') { + ungetc (c,f); + return; + } + } +} + + +// read a number from a stream, this return 0 if there is none (that's okay +// because 0 is a bad value for all PPM numbers anyway). + +static int readNumber (char *filename, FILE *f) +{ + int c,n=0; + for(;;) { + c = fgetc(f); + if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); + if (c >= '0' && c <= '9') n = n*10 + (c - '0'); + else { + ungetc (c,f); + return n; + } + } +} + + +Image::Image (char *filename) +{ + FILE *f = fopen (filename,"rb"); + if (!f) dsError ("Can't open image file `%s'",filename); + + // read in header + if (fgetc(f) != 'P' || fgetc(f) != '6') + dsError ("image file \"%s\" is not a binary PPM (no P6 header)",filename); + skipWhiteSpace (filename,f); + + // read in image parameters + image_width = readNumber (filename,f); + skipWhiteSpace (filename,f); + image_height = readNumber (filename,f); + skipWhiteSpace (filename,f); + int max_value = readNumber (filename,f); + + // check values + if (image_width < 1 || image_height < 1) + dsError ("bad image file \"%s\"",filename); + if (max_value != 255) + dsError ("image file \"%s\" must have color range of 255",filename); + + // read either nothing, LF (10), or CR,LF (13,10) + int c = fgetc(f); + if (c == 10) { + // LF + } + else if (c == 13) { + // CR + c = fgetc(f); + if (c != 10) ungetc (c,f); + } + else ungetc (c,f); + + // read in rest of data + image_data = new byte [image_width*image_height*3]; + if (fread (image_data,image_width*image_height*3,1,f) != 1) + dsError ("Can not read data from image file `%s'",filename); + fclose (f); +} + + +Image::~Image() +{ + delete[] image_data; +} + +//*************************************************************************** +// Texture object. + +class Texture { + Image *image; + GLuint name; +public: + Texture (char *filename); + ~Texture(); + void bind (int modulate); +}; + + +Texture::Texture (char *filename) +{ + image = new Image (filename); + glGenTextures (1,&name); + glBindTexture (GL_TEXTURE_2D,name); + + // set pixel unpacking mode + glPixelStorei (GL_UNPACK_SWAP_BYTES, 0); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + + // glTexImage2D (GL_TEXTURE_2D, 0, 3, image->width(), image->height(), 0, + // GL_RGB, GL_UNSIGNED_BYTE, image->data()); + gluBuild2DMipmaps (GL_TEXTURE_2D, 3, image->width(), image->height(), + GL_RGB, GL_UNSIGNED_BYTE, image->data()); + + // set texture parameters - will these also be bound to the texture??? + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +} + + +Texture::~Texture() +{ + delete image; + glDeleteTextures (1,&name); +} + + +void Texture::bind (int modulate) +{ + glBindTexture (GL_TEXTURE_2D,name); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, + modulate ? GL_MODULATE : GL_DECAL); +} + +//*************************************************************************** +// the current drawing state (for when the user's step function is drawing) + +static float color[4] = {0,0,0,0}; // current r,g,b,alpha color +static int tnum = 0; // current texture number + +//*************************************************************************** +// OpenGL utility stuff + +static void setCamera (float x, float y, float z, float h, float p, float r) +{ + glMatrixMode (GL_MODELVIEW); + glLoadIdentity(); + glRotatef (90, 0,0,1); + glRotatef (90, 0,1,0); + glRotatef (r, 1,0,0); + glRotatef (p, 0,1,0); + glRotatef (-h, 0,0,1); + glTranslatef (-x,-y,-z); +} + + +// sets the material color, not the light color + +static void setColor (float r, float g, float b, float alpha) +{ + GLfloat light_ambient[4],light_diffuse[4],light_specular[4]; + light_ambient[0] = r*0.3f; + light_ambient[1] = g*0.3f; + light_ambient[2] = b*0.3f; + light_ambient[3] = alpha; + light_diffuse[0] = r*0.7f; + light_diffuse[1] = g*0.7f; + light_diffuse[2] = b*0.7f; + light_diffuse[3] = alpha; + light_specular[0] = r*0.2f; + light_specular[1] = g*0.2f; + light_specular[2] = b*0.2f; + light_specular[3] = alpha; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient); + glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse); + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular); + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 5.0f); +} + + +static void setTransform (const float pos[3], const float R[12]) +{ + GLfloat matrix[16]; + matrix[0]=R[0]; + matrix[1]=R[4]; + matrix[2]=R[8]; + matrix[3]=0; + matrix[4]=R[1]; + matrix[5]=R[5]; + matrix[6]=R[9]; + matrix[7]=0; + matrix[8]=R[2]; + matrix[9]=R[6]; + matrix[10]=R[10]; + matrix[11]=0; + matrix[12]=pos[0]; + matrix[13]=pos[1]; + matrix[14]=pos[2]; + matrix[15]=1; + glPushMatrix(); + glMultMatrixf (matrix); +} +static void setTransformD (const double pos[3], const double R[12]) +{ + GLdouble matrix[16]; + matrix[0]=R[0]; + matrix[1]=R[4]; + matrix[2]=R[8]; + matrix[3]=0; + matrix[4]=R[1]; + matrix[5]=R[5]; + matrix[6]=R[9]; + matrix[7]=0; + matrix[8]=R[2]; + matrix[9]=R[6]; + matrix[10]=R[10]; + matrix[11]=0; + matrix[12]=pos[0]; + matrix[13]=pos[1]; + matrix[14]=pos[2]; + matrix[15]=1; + glPushMatrix(); + glMultMatrixd (matrix); +} + + +// set shadow projection transform + +static void setShadowTransform() +{ + GLfloat matrix[16]; + for (int i=0; i<16; i++) matrix[i] = 0; + matrix[0]=1; + matrix[5]=1; + matrix[8]=-LIGHTX; + matrix[9]=-LIGHTY; + matrix[15]=1; + glPushMatrix(); + glMultMatrixf (matrix); +} + +static void drawConvex (const float *_planes, unsigned int _planecount, + const float *_points, unsigned int /*_pointcount*/, + const unsigned int *_polygons) +{ + unsigned int polyindex=0; + for(unsigned int i=0;i<_planecount;++i) + { + unsigned int pointcount=_polygons[polyindex]; + polyindex++; + glBegin (GL_POLYGON); + glNormal3f(_planes[(i*4)+0], + _planes[(i*4)+1], + _planes[(i*4)+2]); + for(unsigned int j=0;j<pointcount;++j) + { + glVertex3f(_points[_polygons[polyindex]*3], + _points[(_polygons[polyindex]*3)+1], + _points[(_polygons[polyindex]*3)+2]); + polyindex++; + } + glEnd(); + } +} + +static void drawConvexD (const double *_planes, unsigned int _planecount, + const double *_points, unsigned int /*_pointcount*/, + const unsigned int *_polygons) +{ + unsigned int polyindex=0; + for(unsigned int i=0;i<_planecount;++i) + { + unsigned int pointcount=_polygons[polyindex]; + polyindex++; + glBegin (GL_POLYGON); + glNormal3d(_planes[(i*4)+0], + _planes[(i*4)+1], + _planes[(i*4)+2]); + for(unsigned int j=0;j<pointcount;++j) + { + glVertex3d(_points[_polygons[polyindex]*3], + _points[(_polygons[polyindex]*3)+1], + _points[(_polygons[polyindex]*3)+2]); + polyindex++; + } + glEnd(); + } +} + +static void drawBox (const float sides[3]) +{ + float lx = sides[0]*0.5f; + float ly = sides[1]*0.5f; + float lz = sides[2]*0.5f; + + // sides + glBegin (GL_TRIANGLE_STRIP); + glNormal3f (-1,0,0); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,-ly,lz); + glVertex3f (-lx,ly,-lz); + glVertex3f (-lx,ly,lz); + glNormal3f (0,1,0); + glVertex3f (lx,ly,-lz); + glVertex3f (lx,ly,lz); + glNormal3f (1,0,0); + glVertex3f (lx,-ly,-lz); + glVertex3f (lx,-ly,lz); + glNormal3f (0,-1,0); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,-ly,lz); + glEnd(); + + // top face + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,0,1); + glVertex3f (-lx,-ly,lz); + glVertex3f (lx,-ly,lz); + glVertex3f (lx,ly,lz); + glVertex3f (-lx,ly,lz); + glEnd(); + + // bottom face + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,0,-1); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,ly,-lz); + glVertex3f (lx,ly,-lz); + glVertex3f (lx,-ly,-lz); + glEnd(); +} + + +// This is recursively subdivides a triangular area (vertices p1,p2,p3) into +// smaller triangles, and then draws the triangles. All triangle vertices are +// normalized to a distance of 1.0 from the origin (p1,p2,p3 are assumed +// to be already normalized). Note this is not super-fast because it draws +// triangles rather than triangle strips. + +static void drawPatch (float p1[3], float p2[3], float p3[3], int level) +{ + int i; + if (level > 0) { + float q1[3],q2[3],q3[3]; // sub-vertices + for (i=0; i<3; i++) { + q1[i] = 0.5f*(p1[i]+p2[i]); + q2[i] = 0.5f*(p2[i]+p3[i]); + q3[i] = 0.5f*(p3[i]+p1[i]); + } + float length1 = (float)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2])); + float length2 = (float)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2])); + float length3 = (float)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2])); + for (i=0; i<3; i++) { + q1[i] *= length1; + q2[i] *= length2; + q3[i] *= length3; + } + drawPatch (p1,q1,q3,level-1); + drawPatch (q1,p2,q2,level-1); + drawPatch (q1,q2,q3,level-1); + drawPatch (q3,q2,p3,level-1); + } + else { + glNormal3f (p1[0],p1[1],p1[2]); + glVertex3f (p1[0],p1[1],p1[2]); + glNormal3f (p2[0],p2[1],p2[2]); + glVertex3f (p2[0],p2[1],p2[2]); + glNormal3f (p3[0],p3[1],p3[2]); + glVertex3f (p3[0],p3[1],p3[2]); + } +} + + +// draw a sphere of radius 1 + +static int sphere_quality = 1; + +static void drawSphere() +{ + // icosahedron data for an icosahedron of radius 1.0 +# define ICX 0.525731112119133606f +# define ICZ 0.850650808352039932f + static GLfloat idata[12][3] = { + {-ICX, 0, ICZ}, + {ICX, 0, ICZ}, + {-ICX, 0, -ICZ}, + {ICX, 0, -ICZ}, + {0, ICZ, ICX}, + {0, ICZ, -ICX}, + {0, -ICZ, ICX}, + {0, -ICZ, -ICX}, + {ICZ, ICX, 0}, + {-ICZ, ICX, 0}, + {ICZ, -ICX, 0}, + {-ICZ, -ICX, 0} + }; + + static int index[20][3] = { + {0, 4, 1}, {0, 9, 4}, + {9, 5, 4}, {4, 5, 8}, + {4, 8, 1}, {8, 10, 1}, + {8, 3, 10}, {5, 3, 8}, + {5, 2, 3}, {2, 7, 3}, + {7, 10, 3}, {7, 6, 10}, + {7, 11, 6}, {11, 0, 6}, + {0, 1, 6}, {6, 1, 10}, + {9, 0, 11}, {9, 11, 2}, + {9, 2, 5}, {7, 2, 11}, + }; + + static GLuint listnum = 0; + if (listnum==0) { + listnum = glGenLists (1); + glNewList (listnum,GL_COMPILE); + glBegin (GL_TRIANGLES); + for (int i=0; i<20; i++) { + drawPatch (&idata[index[i][2]][0],&idata[index[i][1]][0], + &idata[index[i][0]][0],sphere_quality); + } + glEnd(); + glEndList(); + } + glCallList (listnum); +} + + +static void drawSphereShadow (float px, float py, float pz, float radius) +{ + // calculate shadow constants based on light vector + static int init=0; + static float len2,len1,scale; + if (!init) { + len2 = LIGHTX*LIGHTX + LIGHTY*LIGHTY; + len1 = 1.0f/(float)sqrt(len2); + scale = (float) sqrt(len2 + 1); + init = 1; + } + + // map sphere center to ground plane based on light vector + px -= LIGHTX*pz; + py -= LIGHTY*pz; + + const float kx = 0.96592582628907f; + const float ky = 0.25881904510252f; + float x=radius, y=0; + + glBegin (GL_TRIANGLE_FAN); + for (int i=0; i<24; i++) { + // for all points on circle, scale to elongated rotated shadow and draw + float x2 = (LIGHTX*x*scale - LIGHTY*y)*len1 + px; + float y2 = (LIGHTY*x*scale + LIGHTX*y)*len1 + py; + glTexCoord2f (x2*ground_scale+ground_ofsx,y2*ground_scale+ground_ofsy); + glVertex3f (x2,y2,0); + + // rotate [x,y] vector + float xtmp = kx*x - ky*y; + y = ky*x + kx*y; + x = xtmp; + } + glEnd(); +} + + +static void drawTriangle (const float *v0, const float *v1, const float *v2, int solid) +{ + float u[3],v[3],normal[3]; + u[0] = v1[0] - v0[0]; + u[1] = v1[1] - v0[1]; + u[2] = v1[2] - v0[2]; + v[0] = v2[0] - v0[0]; + v[1] = v2[1] - v0[1]; + v[2] = v2[2] - v0[2]; + crossProduct3(normal,u,v); + normalizeVector3 (normal); + + glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); + glNormal3fv (normal); + glVertex3fv (v0); + glVertex3fv (v1); + glVertex3fv (v2); + glEnd(); +} + +static void drawTriangleD (const double *v0, const double *v1, const double *v2, int solid) +{ + float u[3],v[3],normal[3]; + u[0] = float( v1[0] - v0[0] ); + u[1] = float( v1[1] - v0[1] ); + u[2] = float( v1[2] - v0[2] ); + v[0] = float( v2[0] - v0[0] ); + v[1] = float( v2[1] - v0[1] ); + v[2] = float( v2[2] - v0[2] ); + crossProduct3(normal,u,v); + normalizeVector3 (normal); + + glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); + glNormal3fv (normal); + glVertex3dv (v0); + glVertex3dv (v1); + glVertex3dv (v2); + glEnd(); +} + + +// draw a capped cylinder of length l and radius r, aligned along the x axis + +static int capped_cylinder_quality = 3; + +static void drawCapsule (float l, float r) +{ + int i,j; + float tmp,nx,ny,nz,start_nx,start_ny,a,ca,sa; + // number of sides to the cylinder (divisible by 4): + const int n = capped_cylinder_quality*4; + + l *= 0.5; + a = float(M_PI*2.0)/float(n); + sa = (float) sin(a); + ca = (float) cos(a); + + // draw cylinder body + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,l); + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,-l); + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw first cylinder cap + start_nx = 0; + start_ny = 1; + for (j=0; j<(n/4); j++) { + // get start_n2 = rotated start_n + float start_nx2 = ca*start_nx + sa*start_ny; + float start_ny2 = -sa*start_nx + ca*start_ny; + // get n=start_n and n2=start_n2 + nx = start_nx; ny = start_ny; nz = 0; + float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny2,nz2,nx2); + glVertex3d (ny2*r,nz2*r,l+nx2*r); + glNormal3d (ny,nz,nx); + glVertex3d (ny*r,nz*r,l+nx*r); + // rotate n,n2 + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + tmp = ca*ny2- sa*nz2; + nz2 = sa*ny2 + ca*nz2; + ny2 = tmp; + } + glEnd(); + start_nx = start_nx2; + start_ny = start_ny2; + } + + // draw second cylinder cap + start_nx = 0; + start_ny = 1; + for (j=0; j<(n/4); j++) { + // get start_n2 = rotated start_n + float start_nx2 = ca*start_nx - sa*start_ny; + float start_ny2 = sa*start_nx + ca*start_ny; + // get n=start_n and n2=start_n2 + nx = start_nx; ny = start_ny; nz = 0; + float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,nx); + glVertex3d (ny*r,nz*r,-l+nx*r); + glNormal3d (ny2,nz2,nx2); + glVertex3d (ny2*r,nz2*r,-l+nx2*r); + // rotate n,n2 + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + tmp = ca*ny2- sa*nz2; + nz2 = sa*ny2 + ca*nz2; + ny2 = tmp; + } + glEnd(); + start_nx = start_nx2; + start_ny = start_ny2; + } +} + + +// draw a cylinder of length l and radius r, aligned along the z axis + +static void drawCylinder (float l, float r, float zoffset) +{ + int i; + float tmp,ny,nz,a,ca,sa; + const int n = 24; // number of sides to the cylinder (divisible by 4) + + l *= 0.5; + a = float(M_PI*2.0)/float(n); + sa = (float) sin(a); + ca = (float) cos(a); + + // draw cylinder body + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,l+zoffset); + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,-l+zoffset); + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw top cap + glShadeModel (GL_FLAT); + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,1); + glVertex3d (0,0,l+zoffset); + for (i=0; i<=n; i++) { + if (i==1 || i==n/2+1) + setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); + glNormal3d (0,0,1); + glVertex3d (ny*r,nz*r,l+zoffset); + if (i==1 || i==n/2+1) + setColor (color[0],color[1],color[2],color[3]); + + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw bottom cap + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,-1); + glVertex3d (0,0,-l+zoffset); + for (i=0; i<=n; i++) { + if (i==1 || i==n/2+1) + setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); + glNormal3d (0,0,-1); + glVertex3d (ny*r,nz*r,-l+zoffset); + if (i==1 || i==n/2+1) + setColor (color[0],color[1],color[2],color[3]); + + // rotate ny,nz + tmp = ca*ny + sa*nz; + nz = -sa*ny + ca*nz; + ny = tmp; + } + glEnd(); +} + +//*************************************************************************** +// motion model + +// current camera position and orientation +static float view_xyz[3]; // position x,y,z +static float view_hpr[3]; // heading, pitch, roll (degrees) + + +// initialize the above variables + +static void initMotionModel() +{ + view_xyz[0] = 2; + view_xyz[1] = 0; + view_xyz[2] = 1; + view_hpr[0] = 180; + view_hpr[1] = 0; + view_hpr[2] = 0; +} + + +static void wrapCameraAngles() +{ + for (int i=0; i<3; i++) { + while (view_hpr[i] > 180) view_hpr[i] -= 360; + while (view_hpr[i] < -180) view_hpr[i] += 360; + } +} + + +// call this to update the current camera position. the bits in `mode' say +// if the left (1), middle (2) or right (4) mouse button is pressed, and +// (deltax,deltay) is the amount by which the mouse pointer has moved. + +void dsMotion (int mode, int deltax, int deltay) +{ + float side = 0.01f * float(deltax); + float fwd = (mode==4) ? (0.01f * float(deltay)) : 0.0f; + float s = (float) sin (view_hpr[0]*DEG_TO_RAD); + float c = (float) cos (view_hpr[0]*DEG_TO_RAD); + + if (mode==1) { + view_hpr[0] += float (deltax) * 0.5f; + view_hpr[1] += float (deltay) * 0.5f; + } + else { + view_xyz[0] += -s*side + c*fwd; + view_xyz[1] += c*side + s*fwd; + if (mode==2 || mode==5) view_xyz[2] += 0.01f * float(deltay); + } + wrapCameraAngles(); +} + +//*************************************************************************** +// drawing loop stuff + +// the current state: +// 0 = uninitialized +// 1 = dsSimulationLoop() called +// 2 = dsDrawFrame() called +static int current_state = 0; + +// textures and shadows +static int use_textures=1; // 1 if textures to be drawn +static int use_shadows=1; // 1 if shadows to be drawn +static Texture *sky_texture = 0; +static Texture *ground_texture = 0; +static Texture *wood_texture = 0; +static Texture *checkered_texture = 0; + +static Texture *texture[4+1]; // +1 since index 0 is not used + + + +#if !defined(macintosh) || defined(ODE_PLATFORM_OSX) + +void dsStartGraphics (int /*width*/, int /*height*/, dsFunctions *fn) +{ + + const char *prefix = DEFAULT_PATH_TO_TEXTURES; + if (fn->version >= 2 && fn->path_to_textures) prefix = fn->path_to_textures; + char *s = (char*) alloca (strlen(prefix) + 20); + + strcpy (s,prefix); + strcat (s,"/sky.ppm"); + texture[DS_SKY] = sky_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/ground.ppm"); + texture[DS_GROUND] = ground_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/wood.ppm"); + texture[DS_WOOD] = wood_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/checkered.ppm"); + texture[DS_CHECKERED] = checkered_texture = new Texture (s); +} + +#else // macintosh + +void dsStartGraphics (int width, int height, dsFunctions *fn) +{ + + // All examples build into the same dir + char *prefix = "::::drawstuff:textures"; + char *s = (char*) alloca (strlen(prefix) + 20); + + strcpy (s,prefix); + strcat (s,":sky.ppm"); + sky_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,":ground.ppm"); + ground_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,":wood.ppm"); + wood_texture = new Texture (s); +} + +#endif + + +void dsStopGraphics() +{ + delete sky_texture; + delete ground_texture; + delete wood_texture; + sky_texture = 0; + ground_texture = 0; + wood_texture = 0; +} + + +static void drawSky (float view_xyz[3]) +{ + glDisable (GL_LIGHTING); + if (use_textures) { + glEnable (GL_TEXTURE_2D); + sky_texture->bind (0); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (0,0.5,1.0); + } + + // make sure sky depth is as far back as possible + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LEQUAL); + glDepthRange (1,1); + + const float ssize = 1000.0f; + static float offset = 0.0f; + + float x = ssize*sky_scale; + float z = view_xyz[2] + sky_height; + + glBegin (GL_QUADS); + glNormal3f (0,0,-1); + glTexCoord2f (-x+offset,-x+offset); + glVertex3f (-ssize+view_xyz[0],-ssize+view_xyz[1],z); + glTexCoord2f (-x+offset,x+offset); + glVertex3f (-ssize+view_xyz[0],ssize+view_xyz[1],z); + glTexCoord2f (x+offset,x+offset); + glVertex3f (ssize+view_xyz[0],ssize+view_xyz[1],z); + glTexCoord2f (x+offset,-x+offset); + glVertex3f (ssize+view_xyz[0],-ssize+view_xyz[1],z); + glEnd(); + + offset = offset + 0.002f; + if (offset > 1) offset -= 1; + + glDepthFunc (GL_LESS); + glDepthRange (0,1); +} + + +static void drawGround() +{ + glDisable (GL_LIGHTING); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + // glDepthRange (1,1); + + if (use_textures) { + glEnable (GL_TEXTURE_2D); + ground_texture->bind (0); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R,GROUND_G,GROUND_B); + } + + // ground fog seems to cause problems with TNT2 under windows + /* + GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1}; + glEnable (GL_FOG); + glFogi (GL_FOG_MODE, GL_EXP2); + glFogfv (GL_FOG_COLOR, fogColor); + glFogf (GL_FOG_DENSITY, 0.05f); + glHint (GL_FOG_HINT, GL_NICEST); // GL_DONT_CARE); + glFogf (GL_FOG_START, 1.0); + glFogf (GL_FOG_END, 5.0); + */ + + const float gsize = 100.0f; + const float offset = 0; // -0.001f; ... polygon offsetting doesn't work well + + glBegin (GL_QUADS); + glNormal3f (0,0,1); + glTexCoord2f (-gsize*ground_scale + ground_ofsx, + -gsize*ground_scale + ground_ofsy); + glVertex3f (-gsize,-gsize,offset); + glTexCoord2f (gsize*ground_scale + ground_ofsx, + -gsize*ground_scale + ground_ofsy); + glVertex3f (gsize,-gsize,offset); + glTexCoord2f (gsize*ground_scale + ground_ofsx, + gsize*ground_scale + ground_ofsy); + glVertex3f (gsize,gsize,offset); + glTexCoord2f (-gsize*ground_scale + ground_ofsx, + gsize*ground_scale + ground_ofsy); + glVertex3f (-gsize,gsize,offset); + glEnd(); + + glDisable (GL_FOG); +} + + +static void drawPyramidGrid() +{ + // setup stuff + glEnable (GL_LIGHTING); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + + // draw the pyramid grid + for (int i=-1; i<=1; i++) { + for (int j=-1; j<=1; j++) { + glPushMatrix(); + glTranslatef ((float)i,(float)j,(float)0); + if (i==1 && j==0) setColor (1,0,0,1); + else if (i==0 && j==1) setColor (0,0,1,1); + else setColor (1,1,0,1); + const float k = 0.03f; + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,-1,1); + glVertex3f (0,0,k); + glVertex3f (-k,-k,0); + glVertex3f ( k,-k,0); + glNormal3f (1,0,1); + glVertex3f ( k, k,0); + glNormal3f (0,1,1); + glVertex3f (-k, k,0); + glNormal3f (-1,0,1); + glVertex3f (-k,-k,0); + glEnd(); + glPopMatrix(); + } + } +} + + +void dsDrawFrame (int width, int height, dsFunctions *fn, int pause) +{ + if (current_state < 1) dsDebug ("internal error"); + current_state = 2; + + // setup stuff + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glDisable (GL_TEXTURE_2D); + glDisable (GL_TEXTURE_GEN_S); + glDisable (GL_TEXTURE_GEN_T); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + glEnable (GL_CULL_FACE); + glCullFace (GL_BACK); + glFrontFace (GL_CCW); + + // setup viewport + glViewport (0,0,width,height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + const float vnear = 0.1f; + const float vfar = 100.0f; + const float k = 0.8f; // view scale, 1 = +/- 45 degrees + if (width >= height) { + float k2 = float(height)/float(width); + glFrustum (-vnear*k,vnear*k,-vnear*k*k2,vnear*k*k2,vnear,vfar); + } + else { + float k2 = float(width)/float(height); + glFrustum (-vnear*k*k2,vnear*k*k2,-vnear*k,vnear*k,vnear,vfar); + } + + // setup lights. it makes a difference whether this is done in the + // GL_PROJECTION matrix mode (lights are scene relative) or the + // GL_MODELVIEW matrix mode (lights are camera relative, bad!). + static GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; + static GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + static GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); + glColor3f (1.0, 1.0, 1.0); + + // clear the window + glClearColor (0.5,0.5,0.5,0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // snapshot camera position (in MS Windows it is changed by the GUI thread) + float view2_xyz[3]; + float view2_hpr[3]; + memcpy (view2_xyz,view_xyz,sizeof(float)*3); + memcpy (view2_hpr,view_hpr,sizeof(float)*3); + + // go to GL_MODELVIEW matrix mode and set the camera + glMatrixMode (GL_MODELVIEW); + glLoadIdentity(); + setCamera (view2_xyz[0],view2_xyz[1],view2_xyz[2], + view2_hpr[0],view2_hpr[1],view2_hpr[2]); + + // set the light position (for some reason we have to do this in model view. + static GLfloat light_position[] = { LIGHTX, LIGHTY, 1.0, 0.0 }; + glLightfv (GL_LIGHT0, GL_POSITION, light_position); + + // draw the background (ground, sky etc) + drawSky (view2_xyz); + drawGround(); + + // draw the little markers on the ground + drawPyramidGrid(); + + // leave openGL in a known state - flat shaded white, no textures + glEnable (GL_LIGHTING); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + glColor3f (1,1,1); + setColor (1,1,1,1); + + // draw the rest of the objects. set drawing state first. + color[0] = 1; + color[1] = 1; + color[2] = 1; + color[3] = 1; + tnum = 0; + if (fn->step) fn->step (pause); +} + + +int dsGetShadows() +{ + return use_shadows; +} + + +void dsSetShadows (int a) +{ + use_shadows = (a != 0); +} + + +int dsGetTextures() +{ + return use_textures; +} + + +void dsSetTextures (int a) +{ + use_textures = (a != 0); +} + +//*************************************************************************** +// C interface + +// sets lighting and texture modes, sets current color +static void setupDrawingMode() +{ + glEnable (GL_LIGHTING); + if (tnum) { + if (use_textures) { + glEnable (GL_TEXTURE_2D); + texture[tnum]->bind (1); + glEnable (GL_TEXTURE_GEN_S); + glEnable (GL_TEXTURE_GEN_T); + glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + static GLfloat s_params[4] = {1.0f,1.0f,0.0f,1}; + static GLfloat t_params[4] = {0.817f,-0.817f,0.817f,1}; + glTexGenfv (GL_S,GL_OBJECT_PLANE,s_params); + glTexGenfv (GL_T,GL_OBJECT_PLANE,t_params); + } + else { + glDisable (GL_TEXTURE_2D); + } + } + else { + glDisable (GL_TEXTURE_2D); + } + setColor (color[0],color[1],color[2],color[3]); + + if (color[3] < 1) { + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + } + else { + glDisable (GL_BLEND); + } +} + + +static void setShadowDrawingMode() +{ + glDisable (GL_LIGHTING); + if (use_textures) { + glEnable (GL_TEXTURE_2D); + ground_texture->bind (1); + glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); + glEnable (GL_TEXTURE_2D); + glEnable (GL_TEXTURE_GEN_S); + glEnable (GL_TEXTURE_GEN_T); + glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); + glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); + static GLfloat s_params[4] = {ground_scale,0,0,ground_ofsx}; + static GLfloat t_params[4] = {0,ground_scale,0,ground_ofsy}; + glTexGenfv (GL_S,GL_EYE_PLANE,s_params); + glTexGenfv (GL_T,GL_EYE_PLANE,t_params); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, + GROUND_B*SHADOW_INTENSITY); + } + glDepthRange (0,0.9999); +} + + +extern "C" void dsSimulationLoop (int argc, char **argv, + int window_width, int window_height, + dsFunctions *fn) +{ + if (current_state != 0) dsError ("dsSimulationLoop() called more than once"); + current_state = 1; + + // look for flags that apply to us + int initial_pause = 0; + for (int i=1; i<argc; i++) { + if (strcmp(argv[i],"-notex")==0) use_textures = 0; + if (strcmp(argv[i],"-noshadow")==0) use_shadows = 0; + if (strcmp(argv[i],"-noshadows")==0) use_shadows = 0; + if (strcmp(argv[i],"-pause")==0) initial_pause = 1; + if (strcmp(argv[i],"-texturepath")==0) + if (++i < argc) + fn->path_to_textures = argv[i]; + } + + if (fn->version > DS_VERSION) + dsDebug ("bad version number in dsFunctions structure"); + + initMotionModel(); + dsPlatformSimLoop (window_width,window_height,fn,initial_pause); + + current_state = 0; +} + + +extern "C" void dsSetViewpoint (float xyz[3], float hpr[3]) +{ + if (current_state < 1) dsError ("dsSetViewpoint() called before simulation started"); + if (xyz) { + view_xyz[0] = xyz[0]; + view_xyz[1] = xyz[1]; + view_xyz[2] = xyz[2]; + } + if (hpr) { + view_hpr[0] = hpr[0]; + view_hpr[1] = hpr[1]; + view_hpr[2] = hpr[2]; + wrapCameraAngles(); + } +} + + +extern "C" void dsGetViewpoint (float xyz[3], float hpr[3]) +{ + if (current_state < 1) dsError ("dsGetViewpoint() called before simulation started"); + if (xyz) { + xyz[0] = view_xyz[0]; + xyz[1] = view_xyz[1]; + xyz[2] = view_xyz[2]; + } + if (hpr) { + hpr[0] = view_hpr[0]; + hpr[1] = view_hpr[1]; + hpr[2] = view_hpr[2]; + } +} + + +extern "C" void dsSetTexture (int texture_number) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + tnum = texture_number; +} + + +extern "C" void dsSetColor (float red, float green, float blue) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = 1; +} + + +extern "C" void dsSetColorAlpha (float red, float green, float blue, + float alpha) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = alpha; +} + + +extern "C" void dsDrawBox (const float pos[3], const float R[12], + const float sides[3]) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawBox (sides); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawBox (sides); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + +extern "C" void dsDrawConvex (const float pos[3], const float R[12], + const float *_planes,unsigned int _planecount, + const float *_points, unsigned int _pointcount, + const unsigned int *_polygons) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawConvex(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawConvex(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawSphere (const float pos[3], const float R[12], + float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glEnable (GL_NORMALIZE); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + glScaled (radius,radius,radius); + drawSphere(); + glPopMatrix(); + glDisable (GL_NORMALIZE); + + // draw shadows + if (use_shadows) { + glDisable (GL_LIGHTING); + if (use_textures) { + ground_texture->bind (1); + glEnable (GL_TEXTURE_2D); + glDisable (GL_TEXTURE_GEN_S); + glDisable (GL_TEXTURE_GEN_T); + glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, + GROUND_B*SHADOW_INTENSITY); + } + glShadeModel (GL_FLAT); + glDepthRange (0,0.9999); + drawSphereShadow (pos[0],pos[1],pos[2],radius); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawTriangle (const float pos[3], const float R[12], + const float *v0, const float *v1, + const float *v2, int solid) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawTriangle (v0, v1, v2, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawTriangles (const float pos[3], const float R[12], + const float *v, int n, int solid) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + int i; + for (i = 0; i < n; ++i, v += 9) + drawTriangle (v, v + 3, v + 6, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawCylinder (const float pos[3], const float R[12], + float length, float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + drawCylinder (length,radius,0); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawCylinder (length,radius,0); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawCapsule (const float pos[3], const float R[12], + float length, float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + drawCapsule (length,radius); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawCapsule (length,radius); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +static void drawLine(const float pos1[3], const float pos2[3]) +{ + glDisable (GL_LIGHTING); + glLineWidth (2); + glShadeModel (GL_FLAT); + glBegin (GL_LINES); + glVertex3f (pos1[0],pos1[1],pos1[2]); + glVertex3f (pos2[0],pos2[1],pos2[2]); + glEnd(); +} + + +extern "C" void dsDrawLine (const float pos1[3], const float pos2[3]) +{ + setupDrawingMode(); + glColor4f(color[0], color[1], color[2], color[3]); + drawLine(pos1, pos2); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + + drawLine(pos1, pos2); + + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawBoxD (const double pos[3], const double R[12], + const double sides[3]) +{ + int i; + float pos2[3],R2[12],fsides[3]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + for (i=0; i<3; i++) fsides[i]=(float)sides[i]; + dsDrawBox (pos2,R2,fsides); +} + +extern "C" void dsDrawConvexD (const double pos[3], const double R[12], + const double *_planes, unsigned int _planecount, + const double *_points, unsigned int _pointcount, + const unsigned int *_polygons) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransformD (pos,R); + drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransformD (pos,R); + drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + +void dsDrawSphereD (const double pos[3], const double R[12], float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawSphere (pos2,R2,radius); +} + + +void dsDrawTriangleD (const double pos[3], const double R[12], + const double *v0, const double *v1, + const double *v2, int solid) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos2,R2); + drawTriangleD (v0, v1, v2, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawTrianglesD (const double pos[3], const double R[12], + const double *v, int n, int solid) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos2,R2); + for (i = 0; i < n; ++i, v += 9) + drawTriangleD (v, v + 3, v + 6, solid); + glPopMatrix(); +} + + +void dsDrawCylinderD (const double pos[3], const double R[12], + float length, float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawCylinder (pos2,R2,length,radius); +} + + +void dsDrawCapsuleD (const double pos[3], const double R[12], + float length, float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawCapsule (pos2,R2,length,radius); +} + + +void dsDrawLineD (const double _pos1[3], const double _pos2[3]) +{ + int i; + float pos1[3],pos2[3]; + for (i=0; i<3; i++) pos1[i]=(float)_pos1[i]; + for (i=0; i<3; i++) pos2[i]=(float)_pos2[i]; + dsDrawLine (pos1,pos2); +} + + +void dsSetSphereQuality (int n) +{ + sphere_quality = n; +} + + +void dsSetCapsuleQuality (int n) +{ + capped_cylinder_quality = n; +} + +void dsSetDrawMode(int mode) +{ + switch(mode) + { + case DS_POLYFILL: + glPolygonMode(GL_FRONT,GL_FILL); + break; + case DS_WIREFRAME: + glPolygonMode(GL_FRONT,GL_LINE); + break; + } +} diff --git a/libs/ode-0.16.1/drawstuff/src/internal.h b/libs/ode-0.16.1/drawstuff/src/internal.h new file mode 100644 index 0000000..de1aa11 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/internal.h @@ -0,0 +1,50 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* functions supplied and used by the platform specific code */ + +#ifndef __DS_INTERNAL_H +#define __DS_INTERNAL_H + +#include "drawstuff/drawstuff.h" + + +// supplied by platform specific code + +void dsPlatformSimLoop (int window_width, int window_height, + dsFunctions *fn, int initial_pause); + + +// used by platform specific code + +void dsStartGraphics (int width, int height, dsFunctions *fn); +void dsDrawFrame (int width, int height, dsFunctions *fn, int pause); +void dsStopGraphics(); +void dsMotion (int mode, int deltax, int deltay); + +int dsGetShadows(); +void dsSetShadows (int a); + +int dsGetTextures(); +void dsSetTextures (int a); + +#endif diff --git a/libs/ode-0.16.1/drawstuff/src/osx.cpp b/libs/ode-0.16.1/drawstuff/src/osx.cpp new file mode 100644 index 0000000..bc69bfe --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/osx.cpp @@ -0,0 +1,347 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Platform-specific code for Mac OS X using Carbon+AGL +// +// Created using x11.cpp and the window-initialization -routines from GLFW +// as reference. +// Not thoroughly tested and is certain to contain deficiencies and bugs + +#include <ode/odeconfig.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "config.h" +#include "common.h" + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#include <drawstuff/drawstuff.h> +#include <drawstuff/version.h> +#include "internal.h" + +#include <OpenGL/gl.h> +#include <GLUT/glut.h> + +// Global variables + +static bool paused = false; // 1 if in `pause' mode +static bool singlestep = false; // 1 if single step key pressed +static bool writeframes = false; // 1 if frame files to be written + +static int windowWidth = -1; +static int windowHeight = -1; +static int mouseButtonMode = 0; +static bool mouseWithOption = false; // Set if dragging the mouse with alt pressed +static bool mouseWithControl = false; // Set if dragging the mouse with ctrl pressed + +static dsFunctions* functions = NULL; +static int windowReference; +static int frame = 1; +static int prev_x = 0; +static int prev_y = 0; + +//*************************************************************************** +// error handling for unix + +static void printMessage (const char *msg1, const char *msg2, va_list ap) +{ + fflush (stderr); + fflush (stdout); + fprintf (stderr,"\n%s: ",msg1); + vfprintf (stderr,msg2,ap); + fprintf (stderr,"\n"); + fflush (stderr); +} + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +static void captureFrame( int num ){ + + fprintf( stderr,"\rcapturing frame %04d", num ); + unsigned char buffer[windowWidth*windowHeight][3]; + glReadPixels( 0, 0, windowWidth, windowHeight, GL_RGB, GL_UNSIGNED_BYTE, &buffer ); + char s[100]; + sprintf (s,"frame%04d.ppm",num); + FILE *f = fopen (s,"wb"); + if( !f ){ + dsError( "can't open \"%s\" for writing", s ); + } + fprintf( f,"P6\n%d %d\n255\n", windowWidth, windowHeight ); + for( int y=windowHeight-1; y>-1; y-- ){ + fwrite( buffer[y*windowWidth], 3*windowWidth, 1, f ); + } + fclose (f); +} + +extern "C" void dsStop() +{ +} + +extern "C" double dsElapsedTime() +{ +#if HAVE_GETTIMEOFDAY + static double prev=0.0; + timeval tv ; + + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +#else + return 0.01666; // Assume 60 fps +#endif +} + +int osxGetModifierMask() +{ + return glutGetModifiers() & ~GLUT_ACTIVE_SHIFT; +} + +void osxKeyEventHandler( unsigned char key, int x, int y ) +{ + unsigned char uppercase; + if (key >= 'a' && key <= 'z') + uppercase = key - ('a' - 'A'); + else + uppercase = key; + + int modifierMask = osxGetModifierMask(); + if (modifierMask == 0) + { + if( key >= ' ' && key <= 126 && functions -> command ) + functions -> command( key ); + } + else if (modifierMask & GLUT_ACTIVE_CTRL) + { + // ctrl+key was pressed + uppercase += 'A' - 1; + switch(uppercase ){ + case 'T': + dsSetTextures( !dsGetTextures() ); + break; + case 'S': + dsSetShadows( !dsGetShadows() ); + break; + case 'X': + exit(0); + break; + case 'P': + paused = !paused; + singlestep = false; + break; + case 'O': + if( paused ){ + singlestep = true; + } + break; + case 'V': { + float xyz[3],hpr[3]; + dsGetViewpoint( xyz,hpr ); + printf( "Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2] ); + break; + } + case 'W': + writeframes = !writeframes; + if( writeframes ){ + printf( "Now writing frames to PPM files\n" ); + } + break; + } + } +} + +void osxMouseEventHandler(int button, int state, int x, int y) +{ + prev_x = x; + prev_y = y; + bool buttonDown = false; + switch( state ){ + case GLUT_DOWN: + buttonDown = true; + case GLUT_UP: + if( button == GLUT_LEFT_BUTTON ){ + int modifierMask = osxGetModifierMask(); + if( modifierMask & GLUT_ACTIVE_CTRL ){ + // Ctrl+button == right + button = GLUT_RIGHT_BUTTON; + mouseWithControl = true; + } + else if( modifierMask & GLUT_ACTIVE_ALT ){ + // Alt+button == left+right + mouseButtonMode = 5; + mouseWithOption = true; + return; + } + } + if( buttonDown ){ + if( button == GLUT_LEFT_BUTTON ) mouseButtonMode |= 1; // Left + if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode |= 2; // Middle + if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode |= 4; // Right + } + else{ + if( button == GLUT_LEFT_BUTTON ) mouseButtonMode &= (~1); // Left + if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode &= (~2); // Middle + if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode &= (~4); // Right + } + return; + } +} + +void osxMotionEventHandler(int x, int y) +{ + dsMotion( mouseButtonMode, x - prev_x, y - prev_y ); + prev_x = x; + prev_y = y; +} + +void osxWindowReshapeEventHandler(int width, int height) +{ + windowWidth = width; + windowHeight = height; +} + +static void osxCreateMainWindow( int width, int height ) +{ + int argc = 1; + char* argv[2]; + argv[0] = (char*)""; + argv[1] = NULL; + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); + glutInitWindowSize(width, height); + + windowReference = glutCreateWindow("ODE - Drawstuff"); + windowWidth = width; + windowHeight = height; +} + +void osxRedisplayEventHandler() +{ + dsDrawFrame( windowWidth, windowHeight, functions, paused && !singlestep ); + singlestep = false; + glutSwapBuffers(); + + // capture frames if necessary + if( !paused && writeframes ){ + captureFrame( frame ); + frame++; + } +} + +void osxTimerEventHandler(int); + +void osxInstallTimerHandler() +{ + glutTimerFunc(1000/60, osxTimerEventHandler, 0); +} + +void osxTimerEventHandler(int) +{ + glutPostRedisplay(); + osxInstallTimerHandler(); +} + +int osxInstallEventHandlers() +{ + glutKeyboardFunc(osxKeyEventHandler); + glutMouseFunc(osxMouseEventHandler); + glutMotionFunc(osxMotionEventHandler); + glutDisplayFunc(osxRedisplayEventHandler); + glutReshapeFunc(osxWindowReshapeEventHandler); + osxInstallTimerHandler(); + return GL_TRUE; +} + +extern void dsPlatformSimLoop( int givenWindowWidth, int givenWindowHeight, dsFunctions *fn, int givenPause ){ + + functions = fn; + + paused = givenPause; + + osxCreateMainWindow( givenWindowWidth, givenWindowHeight ); + osxInstallEventHandlers(); + + dsStartGraphics( windowWidth, windowHeight, fn ); + + static bool firsttime=true; + if( firsttime ) + { + fprintf + ( + stderr, + "\n" + "Simulation test environment v%d.%02d\n" + " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" + " Ctrl-O : single step when paused.\n" + " Ctrl-T : toggle textures (or say `-notex' on command line).\n" + " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" + " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" + " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" + " Ctrl-X : exit.\n" + "\n" + "Change the camera position by clicking + dragging in the window.\n" + " Left button - pan and tilt.\n" + " Right button (or Ctrl + button) - forward and sideways.\n" + " Left + Right button (or middle button, or Alt + button) - sideways and up.\n" + "\n",DS_VERSION >> 8,DS_VERSION & 0xff + ); + firsttime = false; + } + + if( fn -> start ) fn->start(); + + glutMainLoop(); +} diff --git a/libs/ode-0.16.1/drawstuff/src/resource.h b/libs/ode-0.16.1/drawstuff/src/resource.h new file mode 100644 index 0000000..15802b6 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/resource.h @@ -0,0 +1,28 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDD_MSGDLG 101 +#define IDR_MENU1 102 +#define IDD_ABOUT 103 +#define IDR_ACCELERATOR1 104 +#define IDC_LIST1 1000 +#define IDM_EXIT 40001 +#define IDM_ABOUT 40002 +#define IDM_PAUSE 40003 +#define IDM_PERF_MONITOR 40004 +#define IDM_SHADOWS 40005 +#define IDM_TEXTURES 40006 +#define IDM_SAVE_SETTINGS 40007 +#define IDM_SINGLE_STEP 40008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40009 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/libs/ode-0.16.1/drawstuff/src/resources.rc b/libs/ode-0.16.1/drawstuff/src/resources.rc new file mode 100644 index 0000000..61611f7 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/resources.rc @@ -0,0 +1,153 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +// added by RLS to make this work with windres +#include "winresrc.h" +#define IDC_STATIC (-1) + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 257, 105 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,200,84,50,14 + LTEXT "Simulation test environment",IDC_STATIC,7,7,243,8 + LTEXT "Change the camera position by clicking + dragging in the main window.", + IDC_STATIC,7,24,243,8 + LTEXT "Left button - pan and tilt.",IDC_STATIC,25,37,225,8 + LTEXT "Right button - forward and sideways.",IDC_STATIC,25,48, + 225,8 + LTEXT "Left + Right button (or middle button) - sideways and up.", + IDC_STATIC,25,59,225,8 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + //"#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Exit\tCtrl+X", IDM_EXIT + END + POPUP "&Simulation" + BEGIN + MENUITEM "&Pause\tCtrl+P", IDM_PAUSE + MENUITEM "Single Step\tCtrl+O", IDM_SINGLE_STEP + MENUITEM "Performance &Monitor", IDM_PERF_MONITOR, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Shadows\tCtrl+S", IDM_SHADOWS, CHECKED + MENUITEM "&Textures\tCtrl+T", IDM_TEXTURES, CHECKED + MENUITEM SEPARATOR + MENUITEM "S&ave Settings", IDM_SAVE_SETTINGS, GRAYED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 250 + VERTGUIDE, 25 + TOPMARGIN, 7 + BOTTOMMARGIN, 98 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "O", IDM_SINGLE_STEP, VIRTKEY, CONTROL, NOINVERT + "P", IDM_PAUSE, VIRTKEY, CONTROL, NOINVERT + "S", IDM_SHADOWS, VIRTKEY, CONTROL, NOINVERT + "T", IDM_TEXTURES, VIRTKEY, CONTROL, NOINVERT + "X", IDM_EXIT, VIRTKEY, CONTROL, NOINVERT +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/libs/ode-0.16.1/drawstuff/src/windows.cpp b/libs/ode-0.16.1/drawstuff/src/windows.cpp new file mode 100644 index 0000000..b136ddc --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/windows.cpp @@ -0,0 +1,536 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#if defined(WIN32) || defined(__CYGWIN__)// this prevents warnings when dependencies built +#include <windows.h> +#endif +#include <process.h> +#include <ode/odeconfig.h> +#include <GL/gl.h> + +#include "config.h" +#include "common.h" +#include "resource.h" +#include "internal.h" + +//*************************************************************************** +// application globals + +static HINSTANCE ghInstance = 0; +static int gnCmdShow = 0; +static HACCEL accelerators = 0; +static HWND main_window = 0; + +//*************************************************************************** +// error and message handling + +static void errorBox (const char *title, const char *msg, va_list ap) +{ + char s[1000]; + vsprintf (s,msg,ap); + MessageBox (0,s,title,MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION); +} + + +static void dsWarning (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Warning",msg,ap); + va_end (ap); +} + + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); + exit (1); // should never get here, but just in case... +} + + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +//*************************************************************************** +// rendering thread + +// globals used to communicate with rendering thread + +static volatile int renderer_run = 1; +static volatile int renderer_pause = 0; // 0=run, 1=pause +static volatile int renderer_ss = 0; // single step command +static volatile int renderer_width = 1; +static volatile int renderer_height = 1; +static dsFunctions *renderer_fn = 0; +static volatile HDC renderer_dc = 0; +static volatile int keybuffer[16]; // fifo ring buffer for keypresses +static volatile int keybuffer_head = 0; // index of next key to put in (modified by GUI) +static volatile int keybuffer_tail = 0; // index of next key to take out (modified by renderer) + + +static void setupRendererGlobals() +{ + renderer_run = 1; + renderer_pause = 0; + renderer_ss = 0; + renderer_width = 1; + renderer_height = 1; + renderer_fn = 0; + renderer_dc = 0; + keybuffer[16]; + keybuffer_head = 0; + keybuffer_tail = 0; +} + + +static unsigned CALLBACK renderingThread (LPVOID lpParam) +{ + // create openGL context and make it current + HGLRC glc = wglCreateContext (renderer_dc); + if (glc==NULL) dsError ("could not create OpenGL context"); + if (wglMakeCurrent (renderer_dc,glc) != TRUE) + dsError ("could not make OpenGL context current"); + + // test openGL capabilities + int maxtsize=0; + glGetIntegerv (GL_MAX_TEXTURE_SIZE,&maxtsize); + if (maxtsize < 128) dsWarning ("max texture size too small (%dx%d)", + maxtsize,maxtsize); + + dsStartGraphics (renderer_width,renderer_height,renderer_fn); + if (renderer_fn->start) renderer_fn->start(); + + while (renderer_run) { + // need to make local copy of renderer_ss to help prevent races + int ss = renderer_ss; + dsDrawFrame (renderer_width,renderer_height,renderer_fn, + renderer_pause && !ss); + if (ss) renderer_ss = 0; + + // read keys out of ring buffer and feed them to the command function + while (keybuffer_head != keybuffer_tail) { + if (renderer_fn->command) renderer_fn->command (keybuffer[keybuffer_tail]); + keybuffer_tail = (keybuffer_tail+1) & 15; + } + + // swap buffers + SwapBuffers (renderer_dc); + } + + if (renderer_fn->stop) renderer_fn->stop(); + dsStopGraphics(); + + // delete openGL context + wglMakeCurrent (NULL,NULL); + wglDeleteContext (glc); + + return 123; // magic value used to test for thread termination +} + +//*************************************************************************** +// window handling + +// callback function for "about" dialog box + +static LRESULT CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) { + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + switch (wParam) { + case IDOK: + EndDialog (hDlg, TRUE); + return TRUE; + } + break; + } + return FALSE; +} + + +// callback function for the main window + +static LRESULT CALLBACK mainWndProc (HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + static int button=0,lastx=0,lasty=0; + int ctrl = int(wParam & MK_CONTROL); + + switch (msg) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + if (msg==WM_LBUTTONDOWN) button |= 1; + else if (msg==WM_MBUTTONDOWN) button |= 2; + else button |= 4; + lastx = SHORT(LOWORD(lParam)); + lasty = SHORT(HIWORD(lParam)); + SetCapture (hWnd); + break; + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + if (msg==WM_LBUTTONUP) button &= ~1; + else if (msg==WM_MBUTTONUP) button &= ~2; + else button &= ~4; + if (button==0) ReleaseCapture(); + break; + + case WM_MOUSEMOVE: { + int x = SHORT(LOWORD(lParam)); + int y = SHORT(HIWORD(lParam)); + if (button) dsMotion (button,x-lastx,y-lasty); + lastx = x; + lasty = y; + break; + } + + case WM_CHAR: { + if (wParam >= ' ' && wParam <= 126) { + int nexth = (keybuffer_head+1) & 15; + if (nexth != keybuffer_tail) { + keybuffer[keybuffer_head] = int(wParam); + keybuffer_head = nexth; + } + } + break; + } + + case WM_SIZE: + // lParam will contain the size of the *client* area! + renderer_width = LOWORD(lParam); + renderer_height = HIWORD(lParam); + break; + + case WM_COMMAND: + switch (wParam & 0xffff) { + case IDM_ABOUT: + DialogBox (ghInstance,MAKEINTRESOURCE(IDD_ABOUT),hWnd, + (DLGPROC) AboutDlgProc); + break; + case IDM_PAUSE: { + renderer_pause ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_PAUSE, + renderer_pause ? MF_CHECKED : MF_UNCHECKED); + if (renderer_pause) renderer_ss = 0; + break; + } + case IDM_SINGLE_STEP: { + if (renderer_pause) + renderer_ss = 1; + else + SendMessage( hWnd, WM_COMMAND, IDM_PAUSE, 0 ); + break; + } + case IDM_PERF_MONITOR: { + dsWarning ("Performance monitor not yet implemented."); + break; + } + case IDM_TEXTURES: { + static int tex = 1; + tex ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_TEXTURES, + tex ? MF_CHECKED : MF_UNCHECKED); + dsSetTextures (tex); + break; + } + case IDM_SHADOWS: { + static int shadows = 1; + shadows ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_SHADOWS, + shadows ? MF_CHECKED : MF_UNCHECKED); + dsSetShadows (shadows); + break; + } + case IDM_SAVE_SETTINGS: { + dsWarning ("\"Save Settings\" not yet implemented."); + break; + } + case IDM_EXIT: + PostQuitMessage (0); + break; + } + break; + + case WM_CLOSE: + PostQuitMessage (0); + break; + + default: + return (DefWindowProc (hWnd, msg, wParam, lParam)); + } + + return 0; +} + + +// this comes from an MSDN example. believe it or not, this is the recommended +// way to get the console window handle. + +static HWND GetConsoleHwnd() +{ + // the console window title to a "unique" value, then find the window + // that has this title. + char title[1024]; + wsprintf (title,"DrawStuff:%d/%d",GetTickCount(),GetCurrentProcessId()); + SetConsoleTitle (title); + Sleep(40); // ensure window title has been updated + return FindWindow (NULL,title); +} + + +static void drawStuffStartup() +{ + static int startup_called = 0; + if (startup_called) return; + startup_called = 1; + if (!ghInstance) + ghInstance = GetModuleHandleA (NULL); + gnCmdShow = SW_SHOWNORMAL; // @@@ fix this later + + // redirect standard I/O to a new console (except on cygwin and mingw) +#if !defined(__CYGWIN__) && !defined(__MINGW32__) + FreeConsole(); + if (AllocConsole()==0) dsError ("AllocConsole() failed"); + if (freopen ("CONIN$","rt",stdin)==0) dsError ("could not open stdin"); + if (freopen ("CONOUT$","wt",stdout)==0) dsError ("could not open stdout"); + if (freopen ("CONOUT$","wt",stderr)==0) dsError ("could not open stderr"); + BringWindowToTop (GetConsoleHwnd()); + SetConsoleTitle ("DrawStuff Messages"); +#endif + + // register the window class + WNDCLASS wc; + wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; + wc.lpfnWndProc = mainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = LoadIcon (NULL,IDI_APPLICATION); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); + wc.lpszClassName = "SimAppClass"; + if (RegisterClass (&wc)==0) dsError ("could not register window class"); + + // load accelerators + accelerators = LoadAccelerators (ghInstance, + MAKEINTRESOURCE(IDR_ACCELERATOR1)); + if (accelerators==NULL) dsError ("could not load accelerators"); +} + + +void dsPlatformSimLoop (int window_width, int window_height, + dsFunctions *fn, int initial_pause) +{ + drawStuffStartup(); + setupRendererGlobals(); + renderer_pause = initial_pause; + + // create window - but first get window size for desired size of client area. + // if this adjustment isn't made then the openGL area will be shifted into + // the nonclient area and determining the frame buffer coordinate from the + // client area coordinate will be hard. + RECT winrect; + winrect.left = 50; + winrect.top = 80; + winrect.right = winrect.left + window_width; + winrect.bottom = winrect.top + window_height; + DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + AdjustWindowRect (&winrect,style,1); + char title[100]; + sprintf (title,"Simulation test environment v%d.%02d", + DS_VERSION >> 8,DS_VERSION & 0xff); + main_window = CreateWindow ("SimAppClass",title,style, + winrect.left,winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top, + NULL,NULL,ghInstance,NULL); + if (main_window==NULL) dsError ("could not create main window"); + ShowWindow (main_window, gnCmdShow); + + HDC dc = GetDC (main_window); // get DC for this window + if (dc==NULL) dsError ("could not get window DC"); + + // set pixel format for DC + + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + // get the best available match of pixel format for the device context + int iPixelFormat = ChoosePixelFormat (dc,&pfd); + if (iPixelFormat==0) + dsError ("could not find a good OpenGL pixel format"); + // set the pixel format of the device context + if (SetPixelFormat (dc,iPixelFormat,&pfd)==FALSE) + dsError ("could not set DC pixel format for OpenGL"); + + // ********** + // start the rendering thread + + // set renderer globals + renderer_dc = dc; + renderer_width = window_width; + renderer_height = window_height; + renderer_fn = fn; + + unsigned threadId; + HANDLE hThread; + + hThread = (HANDLE)_beginthreadex( + NULL, // no security attributes + 0, // use default stack size + &renderingThread, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &threadId); // returns the thread identifier + + if (hThread==NULL) dsError ("Could not create rendering thread"); + + // ********** + // start GUI message processing + + MSG msg; + while (GetMessage (&msg,main_window,0,0)) { + if (!TranslateAccelerator (main_window,accelerators,&msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + + // terminate rendering thread + renderer_run = 0; + DWORD ret = WaitForSingleObject (hThread,2000); + if (ret==WAIT_TIMEOUT) dsWarning ("Could not kill rendering thread (1)"); + DWORD exitcode=0; + if (!(GetExitCodeThread (hThread,&exitcode) && exitcode == 123)) + dsWarning ("Could not kill rendering thread (2)"); + CloseHandle (hThread); // dont need thread handle anymore + + // destroy window + DestroyWindow (main_window); +} + + +extern "C" void dsStop() +{ + // just calling PostQuitMessage() here wont work, as this function is + // typically called from the rendering thread, not the GUI thread. + // instead we must post the message to the GUI window explicitly. + + if (main_window) PostMessage (main_window,WM_QUIT,0,0); +} + + +extern "C" double dsElapsedTime() +{ + static double prev=0.0; + double curr = timeGetTime()/1000.0; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +} + + +// JPerkins: if running as a DLL, grab my module handle at load time so +// I can find the accelerators table later + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + ghInstance = hinstDLL; + break; + } + return TRUE; +} + + +// JPerkins: the new build system can set the entry point of the tests to +// main(); this code is no longer necessary +/* + +//*************************************************************************** +// windows entry point +// +// NOTE: WinMain is not guaranteed to be called with MinGW, because MinGW +// always calls main if it is defined and most users of this library will +// define their own main. So the startup functionality is kept in +// zDriverStartup(), which is also called when dsSimulationLoop() is called. + +extern "C" int main (int argc, char **argv); + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + drawStuffStartup(); + return main (0,0); // @@@ should really pass cmd line arguments +} + +*/ + + + diff --git a/libs/ode-0.16.1/drawstuff/src/x11.cpp b/libs/ode-0.16.1/drawstuff/src/x11.cpp new file mode 100644 index 0000000..2d6d313 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/x11.cpp @@ -0,0 +1,459 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// main window and event handling for X11 + +#include <ode/odeconfig.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <GL/glx.h> +#include "config.h" +#include "common.h" + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <drawstuff/drawstuff.h> +#include <drawstuff/version.h> +#include "internal.h" + +//*************************************************************************** +// error handling for unix + +static void printMessage (const char *msg1, const char *msg2, va_list ap) +{ + fflush (stderr); + fflush (stdout); + fprintf (stderr,"\n%s: ",msg1); + vfprintf (stderr,msg2,ap); + fprintf (stderr,"\n"); + fflush (stderr); +} + + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +//*************************************************************************** +// openGL window + +// X11 display info +static Display *display=0; +static int screen=0; +static XVisualInfo *visual=0; // best visual for openGL +static Colormap colormap=0; // window's colormap +static Atom wm_protocols_atom = 0; +static Atom wm_delete_window_atom = 0; + +// window and openGL +static Window win=0; // X11 window, 0 if not initialized +static int width=0,height=0; // window size +static GLXContext glx_context=0; // openGL rendering context +static int last_key_pressed=0; // last key pressed in the window +static int run=1; // 1 if simulation running +static int pausemode=0; // 1 if in `pause' mode +static int singlestep=0; // 1 if single step key pressed +static int writeframes=0; // 1 if frame files to be written + + +static void createMainWindow (int _width, int _height) +{ + // create X11 display connection + display = XOpenDisplay (NULL); + if (!display) dsError ("can not open X11 display"); + screen = DefaultScreen(display); + + // get GL visual + static int attribListDblBuf[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16, + GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, GLX_BLUE_SIZE,4, None}; + static int attribList[] = {GLX_RGBA, GLX_DEPTH_SIZE,16, + GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, GLX_BLUE_SIZE,4, None}; + visual = glXChooseVisual (display,screen,attribListDblBuf); + if (!visual) visual = glXChooseVisual (display,screen,attribList); + if (!visual) dsError ("no good X11 visual found for OpenGL"); + + // create colormap + colormap = XCreateColormap (display,RootWindow(display,screen), + visual->visual,AllocNone); + + // initialize variables + win = 0; + width = _width; + height = _height; + glx_context = 0; + last_key_pressed = 0; + + if (width < 1 || height < 1) dsDebug (0,"bad window width or height"); + + // create the window + XSetWindowAttributes attributes; + attributes.background_pixel = BlackPixel(display,screen); + attributes.colormap = colormap; + attributes.event_mask = ButtonPressMask | ButtonReleaseMask | + KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionHintMask | + StructureNotifyMask; + win = XCreateWindow (display,RootWindow(display,screen),50,50,width,height, + 0,visual->depth, InputOutput,visual->visual, + CWBackPixel | CWColormap | CWEventMask,&attributes); + + // associate a GLX context with the window + glx_context = glXCreateContext (display,visual,0,GL_TRUE); + if (!glx_context) dsError ("can't make an OpenGL context"); + + // set the window title + XTextProperty window_name; + window_name.value = (unsigned char *) "Simulation"; + window_name.encoding = XA_STRING; + window_name.format = 8; + window_name.nitems = strlen((char *) window_name.value); + XSetWMName (display,win,&window_name); + + // participate in the window manager 'delete yourself' protocol + wm_protocols_atom = XInternAtom (display,"WM_PROTOCOLS",False); + wm_delete_window_atom = XInternAtom (display,"WM_DELETE_WINDOW",False); + if (XSetWMProtocols (display,win,&wm_delete_window_atom,1)==0) + dsError ("XSetWMProtocols() call failed"); + + // pop up the window + XMapWindow (display,win); + XSync (display,win); +} + + +static void destroyMainWindow() +{ + glXDestroyContext (display,glx_context); + XDestroyWindow (display,win); + XSync (display,0); + XCloseDisplay(display); + display = 0; + win = 0; + glx_context = 0; +} + + +static void handleEvent (XEvent &event, dsFunctions *fn) +{ + static int mx=0,my=0; // mouse position + static int mode = 0; // mouse button bits + + switch (event.type) { + + case ButtonPress: { + if (event.xbutton.button == Button1) mode |= 1; + if (event.xbutton.button == Button2) mode |= 2; + if (event.xbutton.button == Button3) mode |= 4; + mx = event.xbutton.x; + my = event.xbutton.y; + } + return; + + case ButtonRelease: { + if (event.xbutton.button == Button1) mode &= (~1); + if (event.xbutton.button == Button2) mode &= (~2); + if (event.xbutton.button == Button3) mode &= (~4); + mx = event.xbutton.x; + my = event.xbutton.x; + } + return; + + case MotionNotify: { + if (event.xmotion.is_hint) { + Window root,child; + unsigned int mask; + XQueryPointer (display,win,&root,&child,&event.xbutton.x_root, + &event.xbutton.y_root,&event.xbutton.x,&event.xbutton.y, + &mask); + } + dsMotion (mode, event.xmotion.x - mx, event.xmotion.y - my); + mx = event.xmotion.x; + my = event.xmotion.y; + } + return; + + case KeyPress: { + KeySym key; + XLookupString (&event.xkey,NULL,0,&key,0); + if ((event.xkey.state & ControlMask) == 0) { + if (key >= ' ' && key <= 126 && fn->command) fn->command (key); + } + else if (event.xkey.state & ControlMask) { + switch (key) { + case 't': case 'T': + dsSetTextures (dsGetTextures() ^ 1); + break; + case 's': case 'S': + dsSetShadows (dsGetShadows() ^ 1); + break; + case 'x': case 'X': + run = 0; + break; + case 'p': case 'P': + pausemode ^= 1; + singlestep = 0; + break; + case 'o': case 'O': + if (pausemode) singlestep = 1; + break; + case 'v': case 'V': { + float xyz[3],hpr[3]; + dsGetViewpoint (xyz,hpr); + printf ("Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", + xyz[0],xyz[1],xyz[2],hpr[0],hpr[1],hpr[2]); + break; + } + case 'w': case 'W': + writeframes ^= 1; + if (writeframes) printf ("Now writing frames to PPM files\n"); + break; + } + } + last_key_pressed = key; // a kludgy place to put this... + } + return; + + case KeyRelease: { + // hmmmm... + } + return; + + case ClientMessage: + if (event.xclient.message_type == wm_protocols_atom && + event.xclient.format == 32 && + Atom(event.xclient.data.l[0]) == wm_delete_window_atom) { + run = 0; + return; + } + return; + + case ConfigureNotify: + width = event.xconfigure.width; + height = event.xconfigure.height; + return; + } +} + + +// return the index of the highest bit +static int getHighBitIndex (unsigned int x) +{ + int i = 0; + while (x) { + i++; + x >>= 1; + } + return i-1; +} + + +// shift x left by i, where i can be positive or negative +#define SHIFTL(x,i) (((i) >= 0) ? ((x) << (i)) : ((x) >> (-i))) + + +static void captureFrame (int num) +{ + fprintf (stderr,"capturing frame %04d\n",num); + + char s[100]; + sprintf (s,"frame/frame%04d.ppm",num); + FILE *f = fopen (s,"wb"); + if (!f) dsError ("can't open \"%s\" for writing",s); + fprintf (f,"P6\n%d %d\n255\n",width,height); + XImage *image = XGetImage (display,win,0,0,width,height,~0,ZPixmap); + + int rshift = 7 - getHighBitIndex (image->red_mask); + int gshift = 7 - getHighBitIndex (image->green_mask); + int bshift = 7 - getHighBitIndex (image->blue_mask); + + for (int y=0; y<height; y++) { + for (int x=0; x<width; x++) { + unsigned long pixel = XGetPixel (image,x,y); + unsigned char b[3]; + b[0] = SHIFTL(pixel & image->red_mask,rshift); + b[1] = SHIFTL(pixel & image->green_mask,gshift); + b[2] = SHIFTL(pixel & image->blue_mask,bshift); + fwrite (b,3,1,f); + } + } + fclose (f); + XDestroyImage (image); +} + +void processDrawFrame(int *frame, dsFunctions *fn) +{ + dsDrawFrame (width,height,fn,pausemode && !singlestep); + singlestep = 0; + + glFlush(); + glXSwapBuffers (display,win); + XSync (display,0); + + // capture frames if necessary + if (pausemode==0 && writeframes) { + captureFrame (*frame); + (*frame)++; + } +} + +void microsleep(int usecs) +{ +#ifdef HAVE_UNISTD_H + usleep(usecs); +#endif +} + +void dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, + int initial_pause) +{ + pausemode = initial_pause; + createMainWindow (window_width, window_height); + glXMakeCurrent (display,win,glx_context); + + dsStartGraphics (window_width,window_height,fn); + + static bool firsttime=true; + if (firsttime) + { + fprintf + ( + stderr, + "\n" + "Simulation test environment v%d.%02d\n" + " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" + " Ctrl-O : single step when paused.\n" + " Ctrl-T : toggle textures (or say `-notex' on command line).\n" + " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" + " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" + " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" + " Ctrl-X : exit.\n" + "\n" + "Change the camera position by clicking + dragging in the window.\n" + " Left button - pan and tilt.\n" + " Right button - forward and sideways.\n" + " Left + Right button (or middle button) - sideways and up.\n" + "\n",DS_VERSION >> 8,DS_VERSION & 0xff + ); + firsttime = false; + } + + if (fn->start) fn->start(); + +#if HAVE_GETTIMEOFDAY + timeval tv; + gettimeofday(&tv, 0); + double prev = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; +#endif + + int frame = 1; + run = 1; + while (run) { + // read in and process all pending events for the main window + XEvent event; + while (run && XPending (display)) { + XNextEvent (display,&event); + handleEvent (event,fn); + } + +#if HAVE_GETTIMEOFDAY + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (curr-prev >= 1.0/60.0) + { + prev = curr; + processDrawFrame(&frame, fn); + } + else + microsleep(1000); +#else + processDrawFrame(&frame, fn); +#endif + }; + + if (fn->stop) fn->stop(); + dsStopGraphics(); + + destroyMainWindow(); +} + + +extern "C" void dsStop() +{ + run = 0; +} + + +extern "C" double dsElapsedTime() +{ +#if HAVE_GETTIMEOFDAY + static double prev=0.0; + timeval tv ; + + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +#else + return 0.01666; // Assume 60 fps +#endif +} + + + |