diff options
| author | Josh Rahm <rahm@google.com> | 2025-12-23 12:55:48 -0700 |
|---|---|---|
| committer | Josh Rahm <rahm@google.com> | 2025-12-23 12:55:48 -0700 |
| commit | 306bb687414f54177eb37ab7cd744e491c397c31 (patch) | |
| tree | bbe456fb2cd044dcd4790849122d3b718cee0540 /slox | |
| parent | 6af9c3a9191e8a00f616ba321b2d5e407bb12ab3 (diff) | |
| download | SonsOfSol-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--------- | slox | 0 | ||||
| -rw-r--r-- | slox/Makefile | 32 | ||||
| -rw-r--r-- | slox/README.md | 6 | ||||
| -rwxr-xr-x | slox/genmake.sh | 78 | ||||
| -rw-r--r-- | slox/slox/SloxApplication.hpp | 60 | ||||
| -rw-r--r-- | slox/slox/SloxCommon.hpp | 12 | ||||
| -rw-r--r-- | slox/slox/SloxRawEventHandler.hpp | 57 | ||||
| -rw-r--r-- | slox/slox/SloxTextureFactory.hpp | 54 | ||||
| -rw-r--r-- | slox/slox/events/SloxFunctionQuitListener.hpp | 35 | ||||
| -rw-r--r-- | slox/slox/events/SloxKeyListener.hpp | 29 | ||||
| -rw-r--r-- | slox/slox/events/SloxMouseMotionListener.hpp | 25 | ||||
| -rw-r--r-- | slox/slox/events/SloxQuitListener.hpp | 25 | ||||
| -rw-r--r-- | slox/slox/events/SloxResizeListener.hpp | 21 | ||||
| -rw-r--r-- | slox/slox/loader/SloxModelObject.hpp | 34 | ||||
| -rw-r--r-- | slox/slox/loader/SloxObjectLoader.hpp | 106 | ||||
| -rw-r--r-- | slox/slox/loader/SloxObjectMaterial.hpp | 95 | ||||
| -rw-r--r-- | slox/slox/loader/private_db/SloxObjectLoader.cpp | 300 | ||||
| -rw-r--r-- | slox/slox/private_db/SloxApplication.cpp | 38 | ||||
| -rw-r--r-- | slox/slox/private_db/SloxRawEventHandler.cpp | 43 | ||||
| -rw-r--r-- | slox/slox/private_db/SloxTextureFactory.cpp | 178 |
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; +} + +} |