aboutsummaryrefslogtreecommitdiff
path: root/slox
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2025-12-23 12:55:48 -0700
committerJosh Rahm <rahm@google.com>2025-12-23 12:55:48 -0700
commit306bb687414f54177eb37ab7cd744e491c397c31 (patch)
treebbe456fb2cd044dcd4790849122d3b718cee0540 /slox
parent6af9c3a9191e8a00f616ba321b2d5e407bb12ab3 (diff)
downloadSonsOfSol-306bb687414f54177eb37ab7cd744e491c397c31.tar.gz
SonsOfSol-306bb687414f54177eb37ab7cd744e491c397c31.tar.bz2
SonsOfSol-306bb687414f54177eb37ab7cd744e491c397c31.zip
Inline submodules. Slox and Glox are not used anywhere else anymore
Diffstat (limited to 'slox')
m---------slox0
-rw-r--r--slox/Makefile32
-rw-r--r--slox/README.md6
-rwxr-xr-xslox/genmake.sh78
-rw-r--r--slox/slox/SloxApplication.hpp60
-rw-r--r--slox/slox/SloxCommon.hpp12
-rw-r--r--slox/slox/SloxRawEventHandler.hpp57
-rw-r--r--slox/slox/SloxTextureFactory.hpp54
-rw-r--r--slox/slox/events/SloxFunctionQuitListener.hpp35
-rw-r--r--slox/slox/events/SloxKeyListener.hpp29
-rw-r--r--slox/slox/events/SloxMouseMotionListener.hpp25
-rw-r--r--slox/slox/events/SloxQuitListener.hpp25
-rw-r--r--slox/slox/events/SloxResizeListener.hpp21
-rw-r--r--slox/slox/loader/SloxModelObject.hpp34
-rw-r--r--slox/slox/loader/SloxObjectLoader.hpp106
-rw-r--r--slox/slox/loader/SloxObjectMaterial.hpp95
-rw-r--r--slox/slox/loader/private_db/SloxObjectLoader.cpp300
-rw-r--r--slox/slox/private_db/SloxApplication.cpp38
-rw-r--r--slox/slox/private_db/SloxRawEventHandler.cpp43
-rw-r--r--slox/slox/private_db/SloxTextureFactory.cpp178
20 files changed, 1228 insertions, 0 deletions
diff --git a/slox b/slox
deleted file mode 160000
-Subproject d0d589ce3752600b5e0b59bf6deb1153f7c625a
diff --git a/slox/Makefile b/slox/Makefile
new file mode 100644
index 0000000..67282f0
--- /dev/null
+++ b/slox/Makefile
@@ -0,0 +1,32 @@
+CPPC?=g++
+AR?=ar
+OPTFLAGS?=-g3 -ggdb
+CFLAGS= -Wall -Wextra -I. $(OPTFLAGS) -D DEBUG_LEVEL_TRACE -Islox -I../glox
+LDFLAGS=
+OBJECTS=obs/SloxObjectLoader.o obs/SloxApplication.o obs/SloxRawEventHandler.o obs/SloxTextureFactory.o
+BINARY=libslox.a
+all: setup $(OBJECTS)
+ $(AR) -r $(BINARY) $(OBJECTS)
+
+setup:
+ mkdir -p obs/
+
+clean:
+ - rm -rf obs $(BINARY)
+
+obs/SloxObjectLoader.o: ./slox/loader/private_db/SloxObjectLoader.cpp \
+ slox/loader/SloxObjectLoader.hpp
+ $(CPPC) $(CFLAGS) -o $@ -c $<
+
+obs/SloxApplication.o: ./slox/private_db/SloxApplication.cpp \
+ slox/SloxApplication.hpp
+ $(CPPC) $(CFLAGS) -o $@ -c $<
+
+obs/SloxRawEventHandler.o: ./slox/private_db/SloxRawEventHandler.cpp \
+ slox/SloxRawEventHandler.hpp
+ $(CPPC) $(CFLAGS) -o $@ -c $<
+
+obs/SloxTextureFactory.o: ./slox/private_db/SloxTextureFactory.cpp \
+ slox/SloxTextureFactory.hpp
+ $(CPPC) $(CFLAGS) -o $@ -c $<
+
diff --git a/slox/README.md b/slox/README.md
new file mode 100644
index 0000000..57f127f
--- /dev/null
+++ b/slox/README.md
@@ -0,0 +1,6 @@
+slox
+====
+
+SDL / Glox => Slox
+
+My library for writing apps in a more OO way on top of the Simple DirectMedia Layer
diff --git a/slox/genmake.sh b/slox/genmake.sh
new file mode 100755
index 0000000..d4cc997
--- /dev/null
+++ b/slox/genmake.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# Makefile for the SDL Object eXtensions library
+
+# This bash file is used to generate the makefile
+# to produce the library for the graphics library
+#
+
+cd $(dirname $0)
+
+BINARY_NAME="libslox.a"
+
+obs=()
+src=()
+
+function generate_depends {
+ # get the dependencies of the dependencies
+ next=$(cat $1 | gawk 'match($0, /#include "(.*)"/, m) { print m[1] }')
+ deps=$1
+ for i in $next ; do
+ for canidate in $(generate_depends $i) ; do
+ if [[ ! $deps =~ $i ]] && [[ -f $i ]] ; then
+ deps="$deps \\$(echo -ne '\n ')$i"
+ fi
+ done
+ if [[ $? -ne 0 ]] ; then
+ echo "Failed to generate depends">&2
+ return 1;
+ fi
+ done
+ echo "$deps"
+}
+
+# Iterate through and find the
+# c++ source files
+for i in $(find . | egrep '.*\.c(pp|xx)?$') ; do
+ # add this file to the list of
+ # sources
+ echo "Generating from source file: $i"
+ deps="$(generate_depends $i)"
+
+ # add the resulting object file to
+ # the objects
+ src[$cnt]=$deps
+ obs+=("obs/`basename $i | sed 's/\.c\(pp\|xx\)\?$/.o/g'`")
+ cnt=$[cnt + 1]
+done
+
+# remove the Makefile if it exists
+rm -f Makefile || true
+
+# open Makefile
+exec 3<> Makefile
+
+# some commonly used files to generate
+echo 'CPPC?=g++'>&3
+echo 'AR?=ar'>&3
+echo 'OPTFLAGS?=-g3 -ggdb'>&3
+echo "CFLAGS=$CFLAGS -Wall -Wextra -I. "'$(OPTFLAGS)'" -D DEBUG_LEVEL_TRACE -Islox -I../glox">&3
+echo "LDFLAGS=$LDFLAGS">&3
+echo 'OBJECTS='${obs[@]}>&3
+echo 'BINARY='$BINARY_NAME>&3
+
+# Add all, setup and clean rules
+echo -e 'all: setup $(OBJECTS)\n\t$(AR) -r $(BINARY) $(OBJECTS)\n'>&3
+echo -e 'setup:\n\tmkdir -p obs/\n'>&3
+echo -e 'clean:\n\t- rm -rf obs $(BINARY)\n'>&3
+
+# iterate through all of the objects and
+# add a rule for the binary
+for ((i=0;i<${#obs[@]};i++)) ; do
+ echo "Object file: ${obs[$i]}"
+ # add a rule for the new binary
+ echo -e "${obs[$i]}: ${src[$i]}\n\t"'$(CPPC) $(CFLAGS) -o $@ -c $<\n'>&3
+done
+
+# close Makefile
+exec 3>&-
diff --git a/slox/slox/SloxApplication.hpp b/slox/slox/SloxApplication.hpp
new file mode 100644
index 0000000..ea2b8d8
--- /dev/null
+++ b/slox/slox/SloxApplication.hpp
@@ -0,0 +1,60 @@
+#ifndef SLOXAPPLICATION_HPP_
+#define SLOXAPPLICATION_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/30
+ * SloxApplication.hpp: <description>
+ */
+
+#include <string>
+
+#include <SDL/SDL.h>
+
+namespace slox {
+
+/* This is the base class for all applications
+ * using the Slox framework */
+class SloxApplication {
+public:
+ /* initializes the application. This function
+ * is responsible for almost all of the initialization
+ * of the application */
+ virtual bool initialize(int argc, char** argv) = 0;
+
+ /* This is called whenever there
+ * is an event that is raised */
+ virtual void onEvent( const SDL_Event& event ) = 0;
+
+ /* This is called for every iteration
+ * in the event loop. Returns
+ * true if the application is to
+ * continue running */
+ virtual bool loop( uint32_t ticks ) = 0;
+
+ /* Runs this application. This
+ * is the only implemented method
+ * in this class */
+ virtual void run( int argc=0, char** argv=NULL ) ;
+
+ /* Clean up the application */
+ virtual inline ~SloxApplication() {}
+
+ /* Sets a useful error message for the
+ * user to make it easier to debug problems */
+ virtual inline void setError( const std::string& error ) {
+ m_error = error;
+ }
+
+ /* Returns the error message */
+ virtual inline const std::string& getError() const {
+ return m_error;
+ }
+
+private:
+ std::string m_error;
+};
+
+}
+
+#endif /* SLOXAPPLICATION_HPP_ */
diff --git a/slox/slox/SloxCommon.hpp b/slox/slox/SloxCommon.hpp
new file mode 100644
index 0000000..ef741e6
--- /dev/null
+++ b/slox/slox/SloxCommon.hpp
@@ -0,0 +1,12 @@
+#ifndef SLOXCOMMON_HPP_
+#define SLOXCOMMON_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/30
+ * SloxCommon.hpp: <description>
+ */
+
+#include <SDL/SDL.h>
+
+#endif /* SLOXCOMMON_HPP_ */
diff --git a/slox/slox/SloxRawEventHandler.hpp b/slox/slox/SloxRawEventHandler.hpp
new file mode 100644
index 0000000..39c4677
--- /dev/null
+++ b/slox/slox/SloxRawEventHandler.hpp
@@ -0,0 +1,57 @@
+#ifndef SLOXRAWEVENTLISTENTER_HPP_
+#define SLOXRAWEVENTLISTENTER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/31
+ * SloxRawEventListenter.hpp:
+ *
+ * This is a raw event listening demultiplexer.
+ * This will take many different SDL events
+ * and route them to a list of event handlers
+ */
+
+#include <vector>
+
+#include "slox/SloxCommon.hpp"
+
+#include "slox/events/SloxKeyListener.hpp"
+#include "slox/events/SloxQuitListener.hpp"
+#include "slox/events/SloxResizeListener.hpp"
+#include "slox/events/SloxMouseMotionListener.hpp"
+
+namespace slox {
+
+class SloxRawEventHandler {
+public:
+ void onEvent( const SDL_Event& event );
+
+ /* Add a key listener to this event handler */
+ inline void addKeyListener( SloxKeyListener* listener ) {
+ keyListeners.push_back( listener );
+ }
+
+ inline void addQuitListener( SloxQuitListener* listener ) {
+ quitListeners.push_back( listener );
+ }
+
+ inline void addResizeListener( SloxResizeListener* listener ) {
+ resizeListeners.push_back( listener );
+ }
+
+ inline void addMouseMotionListener( SloxMouseMotionListener* listener ) {
+ mouseMotionListeners.push_back( listener );
+ }
+
+private:
+ std::vector<SloxKeyListener*> keyListeners;
+ std::vector<SloxQuitListener*> quitListeners;
+ std::vector<SloxResizeListener*> resizeListeners;
+ std::vector<SloxMouseMotionListener*> mouseMotionListeners;
+
+ // TODO: more to add
+};
+
+}
+
+#endif /* SLOXRAWEVENTLISTENTER_HPP_ */
diff --git a/slox/slox/SloxTextureFactory.hpp b/slox/slox/SloxTextureFactory.hpp
new file mode 100644
index 0000000..883e956
--- /dev/null
+++ b/slox/slox/SloxTextureFactory.hpp
@@ -0,0 +1,54 @@
+#ifndef SLOXTEXTUREFACTORY_HPP_
+#define SLOXTEXTUREFACTORY_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/30
+ * SloxTextureFactory.hpp: <description>
+ */
+
+#ifndef NO_OPENGL
+
+#include <string>
+#include <GL/gl.h>
+#include "slox/SloxCommon.hpp"
+#include <vector>
+
+#include <SDL/SDL_image.h>
+
+namespace slox {
+
+/* has dependencies on OpenGL */
+class SloxTextureFactory {
+public:
+ inline SloxTextureFactory( ) {
+ m_path.push_back( "." );
+ m_path.push_back( "" );
+ }
+
+ /* returns 0 if ok, 1 if warning, -1 if error */
+ int readBitmapFile( const char* filename, unsigned int* texture ) ;
+
+ int readImageFile( const char* filename, unsigned int* texture ) ;
+
+ const std::string& getMessage() ;
+
+ inline void addToPath( const char* path ) {
+ m_path.push_back( path );
+ }
+
+private:
+ int getFileFromPath( const char* basename, std::string& into );
+
+ std::vector<std::string> m_path;
+
+ std::string m_message;
+};
+
+}
+
+#else
+#warn "SloxTextureFactory is not available when compiling with -D NO_OPENGL"
+#endif
+
+#endif /* SLOXTEXTUREFACTORY_HPP_ */
diff --git a/slox/slox/events/SloxFunctionQuitListener.hpp b/slox/slox/events/SloxFunctionQuitListener.hpp
new file mode 100644
index 0000000..9df189d
--- /dev/null
+++ b/slox/slox/events/SloxFunctionQuitListener.hpp
@@ -0,0 +1,35 @@
+#ifndef SLOXFUNCTIONQUITLISTENER_CPP_
+#define SLOXFUNCTIONQUITLISTENER_CPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/31
+ * SloxFunctionQuitListener.cpp:
+ *
+ * Simple implementation of QuitListener
+ * that just takes a function as an argument
+ */
+
+#include "slox/events/SloxQuitListener.hpp"
+
+namespace slox {
+
+class SloxFunctionQuitListener : public SloxQuitListener {
+public:
+ inline SloxFunctionQuitListener( void (*func)( const SDL_QuitEvent& evt ) ) {
+ m_function_ptr = func;
+ }
+
+ virtual inline void onQuit( const SDL_QuitEvent& event ) {
+ m_function_ptr( event );
+ }
+
+private:
+ void (*m_function_ptr)( const SDL_QuitEvent& evt );
+};
+
+}
+
+
+
+#endif /* SLOXFUNCTIONQUITLISTENER_CPP_ */
diff --git a/slox/slox/events/SloxKeyListener.hpp b/slox/slox/events/SloxKeyListener.hpp
new file mode 100644
index 0000000..422c1bf
--- /dev/null
+++ b/slox/slox/events/SloxKeyListener.hpp
@@ -0,0 +1,29 @@
+#ifndef SLOXKEYLISTENER_HPP_
+#define SLOXKEYLISTENER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/31
+ * SloxKeyListener.hpp:
+ *
+ * This is a class that is called
+ * for key events
+ */
+
+#include "slox/SloxCommon.hpp"
+
+namespace slox {
+
+class SloxKeyListener {
+public:
+ /* Called when a key was pressed or
+ * repeated */
+ virtual inline void onKeyDown( const SDL_KeyboardEvent& event ) { (void) event; }
+
+ /* Called when a key was released */
+ virtual inline void onKeyUp ( const SDL_KeyboardEvent& event ) { (void) event; }
+};
+
+}
+
+#endif /* SLOXKEYLISTENER_HPP_ */
diff --git a/slox/slox/events/SloxMouseMotionListener.hpp b/slox/slox/events/SloxMouseMotionListener.hpp
new file mode 100644
index 0000000..1994886
--- /dev/null
+++ b/slox/slox/events/SloxMouseMotionListener.hpp
@@ -0,0 +1,25 @@
+#ifndef SLOXMOUSEMOTIONLISTENER_HPP_
+#define SLOXMOUSEMOTIONLISTENER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/11/01
+ * SloxMouseMotionListener.hpp: <description>
+ */
+
+#include "slox/SloxCommon.hpp"
+
+namespace slox {
+
+/* A class that listens for mouse motion */
+class SloxMouseMotionListener {
+public:
+ /* Called when the mouse is moved */
+ virtual inline void onMouseMoved( const SDL_MouseMotionEvent& event ) {
+ (void) event;
+ };
+};
+
+}
+
+#endif /* SLOXMOUSEMOTIONLISTENER_HPP_ */
diff --git a/slox/slox/events/SloxQuitListener.hpp b/slox/slox/events/SloxQuitListener.hpp
new file mode 100644
index 0000000..fe5e368
--- /dev/null
+++ b/slox/slox/events/SloxQuitListener.hpp
@@ -0,0 +1,25 @@
+#ifndef SLOXQUITLISTENER_HPP_
+#define SLOXQUITLISTENER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/10/31
+ * SloxQuitListener.hpp:
+ *
+ * An interface that is called when there
+ * is a quit event in SDL
+ */
+
+#include "slox/SloxCommon.hpp"
+
+namespace slox {
+
+class SloxQuitListener {
+public:
+ /* Called when there was a quit event */
+ virtual inline void onQuit( const SDL_QuitEvent& event ) { (void) event; };
+};
+
+}
+
+#endif /* SLOXQUITLISTENER_HPP_ */
diff --git a/slox/slox/events/SloxResizeListener.hpp b/slox/slox/events/SloxResizeListener.hpp
new file mode 100644
index 0000000..e24aa51
--- /dev/null
+++ b/slox/slox/events/SloxResizeListener.hpp
@@ -0,0 +1,21 @@
+#ifndef SLOXRESIZELISTENER_HPP_
+#define SLOXRESIZELISTENER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/11/01
+ * SloxResizeListener.hpp: <description>
+ */
+
+#include "slox/SloxCommon.hpp"
+
+namespace slox {
+
+class SloxResizeListener {
+public:
+ inline virtual void onResize( const SDL_ResizeEvent& event ) { (void)event; }
+};
+
+}
+
+#endif /* SLOXRESIZELISTENER_HPP_ */
diff --git a/slox/slox/loader/SloxModelObject.hpp b/slox/slox/loader/SloxModelObject.hpp
new file mode 100644
index 0000000..5171589
--- /dev/null
+++ b/slox/slox/loader/SloxModelObject.hpp
@@ -0,0 +1,34 @@
+#ifndef GLOXMODELOBJECT_HPP_
+#define GLOXMODELOBJECT_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/11/20
+ * SloxModelObject.hpp: <description>
+ */
+
+#include "glox/GloxCommon.hpp"
+#include "glox/GloxObject.hpp"
+
+#include "slox/loader/SloxObjectMaterial.hpp"
+
+namespace slox {
+
+class SloxModelObject : public glox::GloxObject {
+
+public:
+ inline SloxModelObject( int disp ) : m_display_list( disp ) {}
+
+ inline int getDisplayList() const { return m_display_list; }
+
+ inline virtual void draw() const { glCallList( m_display_list ); }
+
+ inline virtual ~SloxModelObject() {
+ }
+private:
+ int m_display_list;
+};
+
+}
+
+#endif /* GLOXMODELOBJECT_HPP_ */
diff --git a/slox/slox/loader/SloxObjectLoader.hpp b/slox/slox/loader/SloxObjectLoader.hpp
new file mode 100644
index 0000000..e662f4e
--- /dev/null
+++ b/slox/slox/loader/SloxObjectLoader.hpp
@@ -0,0 +1,106 @@
+#ifndef GLOXOBJECTLOADER_HPP_
+#define GLOXOBJECTLOADER_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/11/20
+ * SloxObjectLoader.hpp: <description>
+ */
+
+#include "slox/loader/SloxModelObject.hpp"
+#include "slox/SloxTextureFactory.hpp"
+
+#include <vector>
+#include <fstream>
+#include <iostream>
+#include <cerrno>
+
+namespace slox {
+
+/* This class is used to load obj files and
+ * return an object that when drawn will appear
+ * as the object depicted by the obj file
+ * loaded */
+class SloxObjectLoader {
+public:
+ inline SloxObjectLoader( SloxTextureFactory* textureFactory = NULL ) {
+ m_path.push_back( "." );
+ m_path.push_back( "" );
+ m_texture_factory = textureFactory;
+ }
+
+ inline void setTextureFactory( SloxTextureFactory* factory ) {
+ m_texture_factory = factory;
+ }
+
+ /* loads an object from an input stream.
+ * The stream should have the contents of an
+ * obj file */
+ SloxModelObject* loadObjectFromStream( std::istream& input );
+
+ /* Loads an object from a file, this
+ * is a humble wrapper around the loadOBjectFromStream
+ * declared above that opens the file with a
+ * standard istream */
+ inline SloxModelObject* loadObjectFromFile( const std::string& filename ) {
+ std::ifstream stream;
+ SloxModelObject* ret = NULL;
+
+ /* Try to open the stream, load the object
+ * from that stream and close the
+ * stream */
+ if( openFileFromPath( filename.c_str(), stream ) ) {
+ object_loader_reason = filename + ": not found on path";
+ return NULL;
+ }
+
+ ret = loadObjectFromStream( stream );
+ stream.close();
+ return ret;
+ }
+
+ /* If the object loading fails and returns
+ * NULL, calling this function will return
+ * a string describing the reason */
+ const char* getReason() const ;
+
+ /* Add a path to the path variable so
+ * the factory will look in this folder
+ * for a texture */
+ inline void addToPath( const char* path ) {
+ m_path.push_back( path );
+ }
+private:
+ void loadMaterial( const char* file );
+
+ /* Returns the file from the path */
+ int openFileFromPath( const char* basename, std::ifstream& into );
+
+ /* This is a string that describes the current
+ * filename that is being parsed.
+ *
+ * This name will take the name of *.obj or *.mtl
+ */
+ const char* object_loader_filename;
+
+ /*
+ * This is a string that depicts the reason
+ * for failure. This should not be accessed
+ * directly, use SloxObjectLoader::getReason()
+ * instead, I'm just being lazy */
+ std::string object_loader_reason;
+
+ /*
+ * The places on the filesystem where this object
+ * loader will look for objects to load
+ */
+ std::vector< std::string > m_path;
+
+ /* The texture factory used to load
+ * the textures into the program */
+ SloxTextureFactory* m_texture_factory;
+};
+
+}
+
+#endif /* GLOXOBJECTLOADER_HPP_ */
diff --git a/slox/slox/loader/SloxObjectMaterial.hpp b/slox/slox/loader/SloxObjectMaterial.hpp
new file mode 100644
index 0000000..e1e6eb8
--- /dev/null
+++ b/slox/slox/loader/SloxObjectMaterial.hpp
@@ -0,0 +1,95 @@
+#ifndef GLOXOBJECTMATERIAL_HPP_
+#define GLOXOBJECTMATERIAL_HPP_
+
+/*
+ * Author: jrahm
+ * created: 2013/11/20
+ * glox::GloxObjectMaterial.hpp: <description>
+ */
+
+#include <string>
+#include <algorithm>
+
+#include "glox/GloxColor.hpp"
+#include "glox/GloxTexture.hpp"
+
+namespace slox {
+
+class SloxObjectMaterial {
+public:
+ SloxObjectMaterial( const std::string name = ""
+ , const glox::GloxColor& ka = glox::GloxColor()
+ , const glox::GloxColor& kd = glox::GloxColor()
+ , const glox::GloxColor& ks = glox::GloxColor()
+ , float ns = 0
+ , const glox::GloxTexture& tex = glox::GloxTexture() ) :
+ m_name( name ), m_Ka( ka ), m_Kd( kd ),
+ m_Ks( ks ), m_Ns( ns ), m_tex( tex ) {}
+
+ inline void setNs( float ns ) {
+ m_Ns = ns;
+ }
+
+ inline void setTransparency( float trans ) {
+ m_trans = trans;
+ }
+
+ inline void setKa( const glox::GloxColor& ka ) {
+ m_Ka = ka;
+ }
+
+ inline void setKd( const glox::GloxColor& kd ) {
+ m_Kd = kd;
+ }
+
+ inline void setKs( const glox::GloxColor& ks ) {
+ m_Ks = ks;
+ }
+
+ inline void setName( const std::string name ) {
+ m_name = name;
+ }
+
+ inline const std::string getName() const {
+ return m_name ;
+ }
+
+ inline const glox::GloxColor& getKa() const {
+ return m_Ka;
+ }
+
+ inline const glox::GloxColor& getKd() const {
+ return m_Kd;
+ }
+
+ inline const glox::GloxColor& getKs() const {
+ return m_Ks;
+ }
+
+ inline const glox::GloxTexture& getTexture() const {
+ return m_tex;
+ }
+
+ inline float getNs() const {
+ return m_Ns;
+ }
+
+ inline void setTexture( const glox::GloxTexture& tex ) {
+ m_tex = tex;
+ }
+
+private:
+ std::string m_name;
+ glox::GloxColor m_Ka;
+ glox::GloxColor m_Kd;
+ glox::GloxColor m_Ks;
+
+ float m_Ns;
+ float m_trans;
+
+ glox::GloxTexture m_tex;
+};
+
+}
+
+#endif /* GLOXOBJECTMATERIAL_HPP_ */
diff --git a/slox/slox/loader/private_db/SloxObjectLoader.cpp b/slox/slox/loader/private_db/SloxObjectLoader.cpp
new file mode 100644
index 0000000..3ad5f45
--- /dev/null
+++ b/slox/slox/loader/private_db/SloxObjectLoader.cpp
@@ -0,0 +1,300 @@
+#include <vector>
+#include <map>
+#include <sstream>
+#include <cstdio>
+#include <fstream>
+
+#include "slox/loader/SloxObjectLoader.hpp"
+
+#include "glox/GloxScopedAttributes.hpp"
+#include "glox/GloxScopedBegin.hpp"
+#include "glox/GloxPoint.hpp"
+#include "glox/GloxNormal.hpp"
+#include "glox/GloxCommon.hpp"
+#include "glox/GloxTextureFactory.hpp"
+#include <sys/stat.h>
+
+using namespace std;
+using namespace glox;
+
+namespace slox {
+
+int SloxObjectLoader::openFileFromPath( const char* basename, std::ifstream& into ) {
+ struct stat st;
+ char buf[4096];
+ into.clear();
+ for( vector<string>::iterator itr = m_path.begin(); itr < m_path.end(); ++ itr ) {
+ snprintf( buf, 4096, "%s/%s", (*itr).c_str(), basename );
+ if( ! stat( buf, & st ) ) {
+ into.open( buf, ios::in );
+ return 0;
+ }
+ }
+
+ /* Nothing was found */
+ return 1;
+}
+
+/* The reason the loading failed
+ * if it did */
+std::string object_loader_reason;
+
+/* The map of material names to their
+ * respective materials */
+static map< string, SloxObjectMaterial > materials;
+
+/* The current line number of the stream */
+int linenum = 0;
+
+/* The current filename being parsed */
+const char* object_loader_filename = NULL;
+
+/* Helper function that trims the whitespace from
+ * a string */
+static inline std::string &trim(std::string &s) {
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
+ s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
+ return s;
+};
+
+/* Simple function that returns the reason
+ * why the loader failed */
+const char* SloxObjectLoader::getReason() const {
+ return object_loader_reason.c_str();
+}
+
+/* Typedef a texture point to a pair
+ * of floats */
+typedef pair<float,float> TexPointT;
+
+/* Read n number of floats into a float
+ * array */
+void p_read_n_floats__( const char* line, float* floats, size_t n ) {
+ stringstream linestream( line );
+
+ for( size_t i = 0; i < n; ++ i ) {
+ if( linestream.eof() ) throw "Premature EOF while reading floats!";
+ linestream >> floats[i];
+ }
+}
+
+/* read a point in the for "%f %f %f" from a
+ * line */
+inline GloxPointf p_read_point__( const char* line ) {
+ float xyz[3];
+ p_read_n_floats__( line, xyz, 3 );
+ return GloxPointf( xyz[0], xyz[1], xyz[2] );
+}
+
+/* Read a color in the save format as mentioned above */
+inline GloxColor p_read_color__( const char* line ) {
+ float xyz[3];
+ p_read_n_floats__( line, xyz, 3 );
+ return GloxColor( xyz[0], xyz[1], xyz[2] );
+}
+
+/* read a normal in the same format as mentioned
+ * above */
+inline GloxNormal<> p_read_normal__( const char* line ) {
+ float xyz[3];
+ p_read_n_floats__( line, xyz, 3 );
+ return GloxNormal<>( xyz[0], xyz[1], xyz[2] );
+}
+
+/* Read a texture point in the form
+ * "%f %f" as above */
+inline TexPointT p_read_tex_point__( const char* line ) {
+ float xy[2];
+ p_read_n_floats__( line, xy, 2 );
+ return TexPointT( xy[0], xy[1] );
+}
+
+/* Have OpenGL set the material to the
+ * material as referenced by 'name'
+ */
+void setMaterial( const char* name ) {
+ if( materials.find( name ) == materials.end() ) {
+ cerr << "Unable to set the material " << name << "; The material was never loaded\n" << endl;
+ throw "Unable to set material; never loaded";
+ }
+
+ const SloxObjectMaterial& material = materials[ name ];
+ float fvec[4];
+ material.getKa().toVector( fvec, 4 );
+ // cout << "Material KA: " << material.getKa().toString() << endl;
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,fvec);
+ material.getKd().toVector( fvec, 4 );
+ glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,fvec);
+ material.getKs().toVector( fvec, 4 );
+ glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR ,fvec);
+ fvec[0] = material.getNs();
+ glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS, &fvec[0]);
+
+ // cout << "Reading Texture with id of: " << material.getTexture().getId() << endl;
+ if( material.getTexture().getId() > 0 ) {
+ glEnable( GL_TEXTURE_2D );
+ material.getTexture().bind();
+ } else {
+ glDisable( GL_TEXTURE_2D );
+ }
+}
+
+/* Load a material from the file 'file' */
+void SloxObjectLoader::loadMaterial( const char* file ) {
+ ifstream instream;
+ const char* oldobject_loader_filename = object_loader_filename;
+ object_loader_filename = file;
+
+ string line;
+ string word;
+
+ SloxObjectMaterial* material = NULL;
+
+ if( openFileFromPath( file, instream ) ) {
+ throw "Unable to open material file!";
+ }
+
+ linenum = 0;
+ while( ! instream.eof() ) {
+ getline( instream, line ) ;
+ ++ linenum;
+ stringstream linestream( line );
+ linestream >> word;
+ if( word == "newmtl" ) {
+ linestream >> word;
+ material = & materials[ word ];
+ material->setName( word );
+ } else if ( material == NULL ) {
+ /* Do Nothing */
+ } else if ( ! line.compare( 0, 2, "Ka" ) ) {
+ material->setKa( p_read_color__( line.c_str() + 2 ) );
+ } else if ( ! line.compare( 0, 2, "Kd" ) ) {
+ material->setKd( p_read_color__( line.c_str() + 2 ) );
+ } else if ( ! line.compare( 0, 2, "Ks" ) ) {
+ material->setKs( p_read_color__( line.c_str() + 2 ) );
+ } else if ( ! line.compare( 0, 2, "Ns" ) ) {
+ float tmp;
+ linestream >> tmp;
+ material->setNs( tmp );
+ } else if( word == "map_Kd" ) {
+ linestream >> word;
+ unsigned int tex;
+ int ret;
+
+ if ( word[0] == '/' ) {
+ cerr << "Warning: absolute path being used for texture!" << endl ;
+ exit( 1 );
+ }
+
+ ret = m_texture_factory->readImageFile( word.c_str(), &tex );
+ if( ret < 0 ) {
+ cerr << "Can't read texture: " << m_texture_factory->getMessage() << endl;
+ throw "Unable to open texture file!";
+ }
+ GloxTexture tmp( tex );
+ // cout << "Crated texture with id of: " << tmp.getId() << endl;
+ material->setTexture( tmp );
+ }
+ }
+
+ instream.close();
+ object_loader_filename = oldobject_loader_filename;
+}
+
+SloxModelObject* SloxObjectLoader::loadObjectFromStream( istream& input ) {
+ int display_list = glGenLists( 1 );
+ vector< GloxPointf > verts;
+ vector< GloxNormal<> > norms;
+ vector< TexPointT > tex_points;
+
+ string line;
+
+ glNewList( display_list, GL_COMPILE );
+ GloxScopedAttributes p_gsa__( GL_TEXTURE_BIT );
+
+ try {
+ while( ! input.eof() ) {
+ getline( input, line );
+ if( input.fail() ) {
+ /* If we fail to read, break */
+ break ;
+ }
+ trim( line );
+
+ /* handle the case for points/normals/texture points */
+ if( ! line.compare( 0, 2, "v " ) ) {
+ verts.push_back( p_read_point__( line.c_str() + 2 ) );
+ } else if ( ! line.compare( 0, 2, "vn" ) ) {
+ norms.push_back( p_read_normal__( line.c_str() + 2 ) );
+ } else if ( ! line.compare( 0, 2, "vt" ) ) {
+ tex_points.push_back( p_read_tex_point__( line.c_str() + 2 ) );
+ }
+
+ /* build the face */
+ else if( line[0] == 'f' ) {
+ const char* lineptr = line.c_str() + 1;
+ { GloxScopedBegin p_gsb__( GL_POLYGON );
+ stringstream linestream( lineptr );
+ std::string word;
+ while( ! linestream.eof() ) {
+ unsigned int Kv = 0;
+ unsigned int Kt = 0;
+ unsigned int Kn = 0;
+
+ linestream >> word;
+
+ if( ! (sscanf( word.c_str(), "%u/%u/%u", &Kv, &Kt, &Kn ) == 3 ||
+ sscanf( word.c_str(), "%u//%u", &Kv, &Kn ) == 2 ||
+ sscanf( word.c_str(), "%u", &Kv ) == 1 ) ){
+ throw "Invalid facet!";
+ }
+
+ if ( Kv > verts.size() ) throw "Vertex out of range!";
+ if ( Kn > norms.size() ) throw "Normal out of range!";
+ if ( Kt > tex_points.size() ) throw "Texture out of range!";
+
+ float arr[4];
+ // cout << "face (" << Kv << ", " << Kt << ", " << Kn << ")" << endl;
+ if ( Kt ) {
+ arr[0] = tex_points[Kt-1].first;
+ arr[1] = tex_points[Kt-1].second;
+ glTexCoord2fv( arr );
+ }
+ if( Kn ) {
+ norms[Kn - 1].plot();
+ } if( Kv ) {
+ verts[Kv - 1].plot();
+ }
+
+ }} /* End GloxScopedBegin */
+
+ } else {
+ stringstream linestream( line );
+ string word;
+ linestream >> word;
+
+ if( word == "usemtl" ) {
+ /* use the material in the next word */
+ linestream >> word;
+ setMaterial( word.c_str() );
+ } else if ( word == "mtllib" ) {
+ linestream >> word;
+ loadMaterial( word.c_str() );
+ }
+ }
+
+ }
+ } catch( const char * reason ) {
+ glEndList();
+ char buf[512];
+ snprintf( buf, 512, "%s file: %s line: %d", reason, object_loader_filename, linenum );
+ object_loader_reason = buf;
+ object_loader_filename = NULL;
+ return NULL;
+ }
+
+ glEndList();
+ return new SloxModelObject( display_list );
+}
+
+}
diff --git a/slox/slox/private_db/SloxApplication.cpp b/slox/slox/private_db/SloxApplication.cpp
new file mode 100644
index 0000000..1ab905a
--- /dev/null
+++ b/slox/slox/private_db/SloxApplication.cpp
@@ -0,0 +1,38 @@
+#include "slox/SloxApplication.hpp"
+
+#include <cstdio>
+#include <cstdlib>
+
+namespace slox {
+
+void SloxApplication::run( int argc, char** argv ) {
+ SDL_Event event;
+ memset( & event, 0, sizeof( event ) );
+ bool run = true;
+
+ /* Initialize the application */
+ if( !this->initialize( argc, argv ) ) {
+ fprintf( stderr, "Error initializing SloxApplication: %s\n", this->getError().c_str() );
+ return ;
+ }
+
+ while( run ) {
+ /* While we are continuing to
+ * run */
+ while( SDL_PollEvent( & event ) ) {
+ /* Iterate through the events
+ * and call the applications
+ * raw evetn handler */
+ this->onEvent( event );
+ }
+
+ /* Call the main meat of this
+ * loop */
+ run = this->loop( SDL_GetTicks() );
+ }
+
+ /* The cleanup should be handled by
+ * the destructor */
+}
+
+}
diff --git a/slox/slox/private_db/SloxRawEventHandler.cpp b/slox/slox/private_db/SloxRawEventHandler.cpp
new file mode 100644
index 0000000..825d1d9
--- /dev/null
+++ b/slox/slox/private_db/SloxRawEventHandler.cpp
@@ -0,0 +1,43 @@
+#include "slox/SloxRawEventHandler.hpp"
+
+using namespace std;
+
+namespace slox {
+
+void SloxRawEventHandler::onEvent( const SDL_Event& event ) {
+ switch( event.type ) {
+ case SDL_VIDEORESIZE:
+ for( vector<SloxResizeListener*>::iterator itr = resizeListeners.begin();
+ itr != resizeListeners.end(); ++ itr ) {
+ (*itr)->onResize( event.resize );
+ }
+ break;
+ case SDL_KEYDOWN:
+ for( vector<SloxKeyListener*>::iterator itr = keyListeners.begin();
+ itr != keyListeners.end(); ++ itr ) {
+ (*itr)->onKeyDown( event.key );
+ }
+ break;
+
+ case SDL_KEYUP:
+ for( vector<SloxKeyListener*>::iterator itr = keyListeners.begin();
+ itr != keyListeners.end(); ++ itr ) {
+ (*itr)->onKeyUp( event.key );
+ }
+ break;
+
+ case SDL_QUIT:
+ for( vector<SloxQuitListener*>::iterator itr = quitListeners.begin();
+ itr != quitListeners.end(); ++ itr ) {
+ (*itr)->onQuit( event.quit );
+ }
+ case SDL_MOUSEMOTION:
+ for( vector<SloxMouseMotionListener*>::iterator itr = mouseMotionListeners.begin();
+ itr != mouseMotionListeners.end(); ++ itr ) {
+ (*itr)->onMouseMoved( event.motion );
+ }
+
+ }
+}
+
+}
diff --git a/slox/slox/private_db/SloxTextureFactory.cpp b/slox/slox/private_db/SloxTextureFactory.cpp
new file mode 100644
index 0000000..58bda0e
--- /dev/null
+++ b/slox/slox/private_db/SloxTextureFactory.cpp
@@ -0,0 +1,178 @@
+#include "slox/SloxTextureFactory.hpp"
+#include <sys/stat.h>
+
+using namespace std;
+
+namespace slox {
+
+const std::string& SloxTextureFactory::getMessage() {
+ return m_message;
+}
+
+int SloxTextureFactory::getFileFromPath( const char* basename, std::string& into ) {
+ struct stat st;
+ char buf[4096];
+ into.clear();
+ for( vector<string>::iterator itr = m_path.begin(); itr < m_path.end(); ++ itr ) {
+ snprintf( buf, 4096, "%s/%s", (*itr).c_str(), basename );
+ if( ! stat( buf, & st ) ) {
+ /* We found a file on the path */
+ into = buf;
+ return 0;
+ }
+ }
+
+ /* Nothing was found */
+ return 1;
+}
+
+int SloxTextureFactory::readImageFile( const char* filename, unsigned int* texture_r ) {
+ int ret = 0 ;
+ unsigned int texture ;
+ SDL_Surface* surface ;
+ int nOfColors ;
+ GLenum texture_format ;
+ std::string realpath ;
+
+ *texture_r = 0;
+ if( getFileFromPath( filename, realpath ) ) {
+ m_message = string( "File ") + filename + " does not exist on the path!" ;
+ return -1 ;
+ }
+
+ if( (surface = IMG_Load( realpath.c_str() ) ) ) {
+ if ( surface->w & (surface->w - 1) ) {
+ m_message = "Warning: width not power of 2" ;
+ ret = 1 ;
+ }
+
+ if ( surface->h & (surface->h - 1) ) {
+ m_message = "Warning: height not power of 2" ;
+ ret = 1 ;
+ }
+
+ nOfColors = surface->format->BytesPerPixel ;
+ if (nOfColors == 4) // contains an alpha channel
+ {
+ if (surface->format->Rmask == 0x000000ff)
+ texture_format = GL_RGBA;
+ else
+ texture_format = GL_BGRA;
+ } else if (nOfColors == 3) // no alpha channel
+ {
+ if (surface->format->Rmask == 0x000000ff)
+ texture_format = GL_RGB;
+ else
+ texture_format = GL_BGR;
+ } else {
+ m_message = "warning: image not truecolor\n";
+ ret = 1;
+ }
+
+ // Have OpenGL generate a texture object handle for us
+ glGenTextures( 1, &texture );
+
+ // Bind the texture object
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ // Set the texture's stretching properties
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ // Edit the texture object's image data using the information SDL_Surface gives us
+ glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
+ texture_format, GL_UNSIGNED_BYTE, surface->pixels );
+ }
+ else {
+ char error[ 256 ];
+ snprintf( error, 256, "Error: could not load image: %s\n", SDL_GetError() );
+ m_message = error;
+ return -1;
+ }
+
+ // Free the SDL_Surface only if it was successfully created
+ if ( surface ) {
+ SDL_FreeSurface( surface );
+ }
+
+ *texture_r = texture;
+ return ret ;
+}
+
+int SloxTextureFactory::readBitmapFile( const char* filename, unsigned int* texture_r ) {
+ int ret = 0;
+ unsigned int texture;
+ SDL_Surface* surface;
+ int nOfColors;
+ GLenum texture_format;
+ std::string realpath;
+
+ if( getFileFromPath( filename, realpath ) ) {
+ m_message = string("File ") + filename + " does not exist on the path!";
+ return -1;
+ }
+
+ if ( (surface = SDL_LoadBMP( realpath.c_str() )) ) {
+
+ // Check that the image's width is a power of 2
+ if ( (surface->w & (surface->w - 1)) != 0 ) {
+ m_message = "Warning: width not power of 2" ;
+ ret = 1;
+ }
+
+ // Also check if the height is a power of 2
+ if ( (surface->h & (surface->h - 1)) != 0 ) {
+ m_message = "Warning: height not power of 2";
+ ret = 1;
+ }
+
+ // get the number of channels in the SDL surface
+ nOfColors = surface->format->BytesPerPixel;
+ if (nOfColors == 4) // contains an alpha channel
+ {
+ if (surface->format->Rmask == 0x000000ff)
+ texture_format = GL_RGBA;
+ else
+ texture_format = GL_BGRA;
+ } else if (nOfColors == 3) // no alpha channel
+ {
+ if (surface->format->Rmask == 0x000000ff)
+ texture_format = GL_RGB;
+ else
+ texture_format = GL_BGR;
+ } else {
+ m_message = "warning: image not truecolor\n";
+ // this error should not go unhandled
+ }
+
+ // Have OpenGL generate a texture object handle for us
+ glGenTextures( 1, &texture );
+
+ // Bind the texture object
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ // Set the texture's stretching properties
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ // Edit the texture object's image data using the information SDL_Surface gives us
+ glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
+ texture_format, GL_UNSIGNED_BYTE, surface->pixels );
+ }
+ else {
+ char error[ 256 ];
+ snprintf( error, 256, "Error: could not load image: %s\n", SDL_GetError() );
+ m_message = error;
+ return -1;
+ }
+
+ // Free the SDL_Surface only if it was successfully created
+ if ( surface ) {
+ SDL_FreeSurface( surface );
+ }
+
+ *texture_r = texture;
+ return ret;
+}
+
+}