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 | |
| 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
73 files changed, 4634 insertions, 6 deletions
diff --git a/.gitmodules b/.gitmodules index f1226c5..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "glox"] - path = glox - url = git@github.com:joshuarahm/glox.git -[submodule "slox"] - path = slox - url = git@github.com:joshuarahm/slox.git diff --git a/glox b/glox deleted file mode 160000 -Subproject f095e4f1231278a2e5937500dfc72d393c3ed45 diff --git a/glox/Makefile b/glox/Makefile new file mode 100644 index 0000000..262a94b --- /dev/null +++ b/glox/Makefile @@ -0,0 +1,66 @@ +CPPC?=g++ +AR?=ar +OPTFLAGS?=-g3 -ggdb +CFLAGS= -Wall -Wextra -Icompat -I. $(OPTFLAGS) -D DEBUG_LEVEL_TRACE -Islox -Iglox +LDFLAGS= +OBJECTS=obs/GloxCube.o obs/GloxFirstPersonPerspective.o obs/GloxTexturedCube.o obs/GloxShader.o obs/GloxCylinder.o obs/GloxProgram.o obs/GloxLightSource.o obs/GloxTexturedSphere.o obs/GloxLightSourceManager.o obs/GloxTextureFactory.o +BINARY=libglox.a +all: setup $(OBJECTS) + $(AR) -r $(BINARY) $(OBJECTS) + +setup: + mkdir -p obs/ + +clean: + - rm -rf obs $(BINARY) + +obs/GloxCube.o: ./glox/src/GloxCube.cpp \ + glox/GloxScopedBegin.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxFirstPersonPerspective.o: ./glox/src/GloxFirstPersonPerspective.cpp \ + glox/GloxCommon.hpp \ + glox/GloxFirstPersonPerspective.hpp \ + glox/GloxState.hpp \ + glox/GloxDebug.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxTexturedCube.o: ./glox/src/GloxTexturedCube.cpp \ + glox/GloxScopedBegin.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxShader.o: ./glox/src/GloxShader.cpp \ + glox/GloxShader.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxCylinder.o: ./glox/src/GloxCylinder.cpp \ + glox/GloxDebug.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxProgram.o: ./glox/src/GloxProgram.cpp \ + glox/GloxProgram.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxLightSource.o: ./glox/src/GloxLightSource.cpp \ + glox/GloxDebug.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxTexturedSphere.o: ./glox/src/GloxTexturedSphere.cpp \ + glox/GloxCommon.hpp \ + glox/GloxPoint.hpp \ + glox/GloxNormal.hpp \ + glox/GloxPointNormalTexture.hpp \ + glox/GloxScopedAttributes.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxLightSourceManager.o: ./glox/src/GloxLightSourceManager.cpp \ + glox/GloxState.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + +obs/GloxTextureFactory.o: ./glox/src/GloxTextureFactory.cpp \ + glox/GloxTextureFactory.hpp \ + glox/GloxTexture.hpp \ + glox/GloxCommon.hpp \ + glox/GloxDebug.hpp + $(CPPC) $(CFLAGS) -o $@ -c $< + diff --git a/glox/README.txt b/glox/README.txt new file mode 100644 index 0000000..895b44c --- /dev/null +++ b/glox/README.txt @@ -0,0 +1,39 @@ +LibGlox - GL Object eXtension +----------------------------- + +LibGlox is an extension to OpenGL which wraps the +API in a friendlier, object-oriented framework which +abstracts away much of the OpenGL state machine to +make it harder to shoot yourself in the foot. + +Much of library is inlined, which means that the performance +hit from the abstraction layer is minimal. + +In order to build LibGlox, you must first generate the Makfile; this +is easy, just run ./genmake.sh from terminal then run make. + +This will produce a static library to statically link against, unfortunately +as of now, there is no shared library :-( It should, however, be trivial to change +the makefile to build one. + + +Developer Stuff +--------------- + +There are 3 main types of "drawable" objects in Glox. + +The first class is Plottable (GloxPlottable) objects. These +objects will simply and dumbly plot, they effect the OpenGL state +machine minimally; mostly restricted to points and normals. +However; plottable objects are very dependent +on the state of the state machine before they plot. Examples +of plottable objects are GloxPoint and GloxNormal. + +The second class is Renderable (GloxRenderable) objects. These +objects will change the state of the GL state machine. Examples +of renderable objects are GloxPerspective and GloxColor. + +Finally, the third class is full blown objects (GloxObjects) they are +similar to plottable, however they should not depend on the +original state of the StateMachine and ideally should restore +the StateMachine to the state it was in if possible diff --git a/glox/compat/glox/GloxLightSource.hpp b/glox/compat/glox/GloxLightSource.hpp new file mode 100644 index 0000000..59331f9 --- /dev/null +++ b/glox/compat/glox/GloxLightSource.hpp @@ -0,0 +1,95 @@ +#ifndef GLOXLIGHT_HPP_ +#define GLOXLIGHT_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxLight.hpp: <description> + */ + +#include "glox/GloxPoint.hpp" +#include "glox/GloxColor.hpp" +#include "glox/GloxRenderable.hpp" + +#include <map> + +namespace glox { + +class GloxLightSource { +public: + /* Create a new light source using the light_id + * that is to be used in OpenGl */ + inline GloxLightSource( GLenum light_id ) : + m_light( light_id ) {} + + /* Sets the color of this light + * source */; + void setColor( const GloxColor& color ); + + /* Sets the position of a point */ + void setPosition( const GloxPoint<>& position, bool directional=false ) { + m_pos = position; + this->directional = directional; + } + + inline const GloxPointf& getPosition() { return m_pos ; } + + /* Sets whether this light is + * enabled or not */ + inline void setEnabled( bool enabled ) { + this->enabled = enabled; + } + + /* True if this light is enabled */ + inline bool isEnabled() const { + return this->enabled; + } + + inline void setAmbient( const GloxColor& color ) { + this->ambient = color; + } + + inline void setDiffuse( const GloxColor& color ) { + this->diffuse = color; + } + + inline void setSpecular( const GloxColor& color ) { + this->specular = color; + } + + inline void setLightModelAttribute( GLenum attr, float value ) { + lightModelsAttrs[attr] = value; + } + + inline void setLightModelAttribute( GLenum attr, const GloxColor& color ) { + lightModelsAttrs_vectors[attr] = color; + } + + /* Reder this light source */ + void render() const ; + +private: + typedef std::map<GLenum,float> M_lm_map_t; + typedef std::map< GLenum,GloxColor > M_lm_map_vec_t; + + GLenum m_light; + + GloxPoint<> m_pos; + bool directional; + + /* The index of this light source */ + int index; + bool enabled; + + /* Colors for different attributes */ + GloxColor ambient; + GloxColor diffuse; + GloxColor specular; + + M_lm_map_t lightModelsAttrs; + M_lm_map_vec_t lightModelsAttrs_vectors; +}; + +} + +#endif /* GLOXLIGHT_HPP_ */ diff --git a/glox/compat/glox/GloxLightSourceManager.hpp b/glox/compat/glox/GloxLightSourceManager.hpp new file mode 100644 index 0000000..27037c5 --- /dev/null +++ b/glox/compat/glox/GloxLightSourceManager.hpp @@ -0,0 +1,50 @@ +#ifndef GLOXLIGHTSOURCEMANAGER_HPP_ +#define GLOXLIGHTSOURCEMANAGER_HPP_ + +#define GLOX_MAX_NUM_LIGHTS 8 + +/* + * Author: jrahm + * created: 2013/10/23 + * GloxLightSourceManager.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxLightSource.hpp" +#include "glox/GloxRenderable.hpp" + +namespace glox { + +/* Since there are a finite number of light + * sources in OpenGL, they must be managed + * and allocated through this GloxLightSourceManager + */ +class GloxLightSourceManager : public GloxRenderable { +public: + inline GloxLightSourceManager() { + /* Initialize the arry of LightSources to + * NULL */ + for( size_t i = 0; i < GLOX_MAX_NUM_LIGHTS; ++ i ) { + m_sources[i] = NULL; + } + } + + /* Renders the lighting for this GloxLightSourceManager. + * This will render the scene with the lights in this + * manager and only the lights in this manager */ + void render() const ; + + /* Returns the light source with + * the ID `id'. Valid ID's are + * 0-7. An invalid id will return + * NULL. */ + GloxLightSource* getLightSource( int id ) ; + +private: + /* The sources of light */ + GloxLightSource* m_sources[ GLOX_MAX_NUM_LIGHTS ]; +}; + +} + +#endif /* GLOXLIGHTSOURCEMANAGER_HPP_ */ diff --git a/glox/compat/glox/objects/GloxCube.hpp b/glox/compat/glox/objects/GloxCube.hpp new file mode 100644 index 0000000..f0e8f51 --- /dev/null +++ b/glox/compat/glox/objects/GloxCube.hpp @@ -0,0 +1,56 @@ +#ifndef GLOXCUBE_HPP_ +#define GLOXCUBE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/28 + * GloxCube.hpp: This header contains the header for a cube class. + * This cube class does not have textures. For a textured cube, use + * GloxTexturedCube in GloxTexturedCube.hpp + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxNormal.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxObject.hpp" +#include "glox/GloxColor.hpp" +#include "glox/GloxPointCollection.hpp" +#include "glox/GloxScopedAttributes.hpp" + +namespace glox { + +class GloxCube : public GloxObject { +public: + /* Creates a new cube with the size + * `size`. The size is the length of + * each side of the cube */ + GloxCube( float x, float y, float z, const GloxColor& color ); + + inline GloxCube( const GloxCube& other ) { + m_disp_list = other.m_disp_list ; + m_color = other.m_color; + } + + /* Draw this cube */ + void draw() const ; + + /* Sets the color of this cube */ + inline void setColor( const GloxColor& color ) { + m_color = color; + } + + /* Returns the color of this cube */ + inline const GloxColor& getColor() const { + return m_color; + } + +private: + int m_disp_list ; + /* The color of this cube */ + GloxColor m_color; +}; + +} + +#endif /* GLOXCUBE_HPP_ */ + diff --git a/glox/compat/glox/objects/GloxSphere.hpp b/glox/compat/glox/objects/GloxSphere.hpp new file mode 100644 index 0000000..cd1a97a --- /dev/null +++ b/glox/compat/glox/objects/GloxSphere.hpp @@ -0,0 +1,20 @@ +#ifndef GLOXSPHERE_HPP_ +#define GLOXSPHERE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxSphere.hpp: Better implemenation of + * the Sphere.hpp + */ + +#include "glox/GloxObject" + +class GloxSphere : public GloxObject { +public: + GloxSphere( float radius, float res=2 ); + + void setTexture( const GloxTexture* texture ); +} + +#endif /* GLOXSPHERE_HPP_ */ diff --git a/glox/compat/glox/objects/GloxTexturedCube.hpp b/glox/compat/glox/objects/GloxTexturedCube.hpp new file mode 100644 index 0000000..c162fde --- /dev/null +++ b/glox/compat/glox/objects/GloxTexturedCube.hpp @@ -0,0 +1,125 @@ +#ifndef GLOXTEXTUREDCUBE_HPP_ +#define GLOXTEXTUREDCUBE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/28 + * GloxTexturedCube.hpp: This header contains the header for a cube class. + * This cube class does not have textures. For a textured cube, use + * GloxTexturedCube in GloxTexturedCube.hpp + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxNormal.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxObject.hpp" +#include "glox/GloxColor.hpp" +#include "glox/GloxPointCollection.hpp" +#include "glox/GloxScopedAttributes.hpp" +#include "glox/GloxTextureRepeat.hpp" +#include "glox/GloxPointNormalTexture.hpp" +#include "glox/GloxDebug.hpp" + +namespace glox { + +class GloxTexturedCube : public GloxObject { +public: + /* Creates a new cube with the size + * `size`. The size is the length of + * each side of the cube */ + GloxTexturedCube( float size, const GloxColor& color, + const GloxTextureRepeat& topTex = GloxTextureRepeat(NULL), + const GloxTextureRepeat& botTex = GloxTextureRepeat(NULL), + const GloxTextureRepeat& frontTex = GloxTextureRepeat(NULL), + const GloxTextureRepeat& backTex = GloxTextureRepeat(NULL), + const GloxTextureRepeat& leftTex = GloxTextureRepeat(NULL), + const GloxTextureRepeat& rightTex = GloxTextureRepeat(NULL) ); + + /* Draw this cube */ + void draw() const ; + + /* Sets the color of this cube */ + inline void setColor( const GloxColor& color ) { + m_color = color; + } + + /* Returns the color of this cube */ + inline const GloxColor& getColor() const { + return m_color; + } + + inline void setTopTexture( const GloxTextureRepeat& top_tex ) { + m_top_tex = top_tex; + update_top(); + } + + inline void setBottomTexture( const GloxTextureRepeat& tex ) { + m_bottom_tex = tex; + update_bottom(); + } + + inline void setFrontTexture( const GloxTextureRepeat& tex ) { + m_front_tex = tex; + update_front(); + } + + inline void setBackTexture( const GloxTextureRepeat& tex ) { + m_back_tex = tex; + update_back(); + } + + inline void setRightTexture( const GloxTextureRepeat& tex ) { + m_right_tex = tex; + update_right(); + } + + inline void setLeftTexture( const GloxTextureRepeat& tex ) { + m_left_tex = tex; + update_left(); + } + +private: + void update_top(); + void update_bottom(); + void update_front(); + void update_back(); + void update_right(); + void update_left(); + + /* A typedef to make my life easier */ + typedef GloxPointCollection< GloxPointNormalTexture > _M_Square; + + inline void plot_with( const _M_Square& face, const GloxTextureRepeat& tex ) const; + + /* +/- y axis */ + _M_Square m_top; + _M_Square m_bottom; + + /* -/+ z axis */ + _M_Square m_front; + _M_Square m_back; + + /* -/+ x axis */ + _M_Square m_left; + _M_Square m_right; + + /* The textures for the various faces of + * the cube */ + GloxTextureRepeat m_top_tex; + GloxTextureRepeat m_bottom_tex; + GloxTextureRepeat m_front_tex; + GloxTextureRepeat m_back_tex; + GloxTextureRepeat m_left_tex; + GloxTextureRepeat m_right_tex; + + /* The color of this cube */ + GloxColor m_color; + + + float m_half; +}; + +} + +#endif /* GLOXTEXTUREDCUBE_HPP_ */ + diff --git a/glox/compat/glox/objects/GloxTexturedSphere.hpp b/glox/compat/glox/objects/GloxTexturedSphere.hpp new file mode 100644 index 0000000..d7a17e8 --- /dev/null +++ b/glox/compat/glox/objects/GloxTexturedSphere.hpp @@ -0,0 +1,52 @@ +#ifndef GLOXTEXTUREDSPHERE_HPP_ +#define GLOXTEXTUREDSPHERE_HPP_ + +/* + * Author: jrahm + * created: 2013/11/07 + * GloxTexturedSphere.hpp: <description> + */ + +#include "glox/GloxTexture.hpp" +#include "glox/GloxObject.hpp" + +namespace glox { + +/* A sphere that has a texture mapped to it. + * The texture is mapped using a mercader projection + */ +class GloxTexturedSphere : public GloxObject { +public: + /* Create a new GloxTexturedSphere + * radius: the radius of the sphere + * res: the resolution of the sphere. Should + * be a factor of 360 + * */ + GloxTexturedSphere( float radius, float res, const GloxTexture& texture ); + + /* Draw this sphere */ + void draw() const; + + /* Returns teh radius of the sphere */ + inline float getRadius() const { return m_radius; } + + /* Set the radius of this sphere */ + inline void setRadius( float radius ) { m_radius = radius; } + + /* Returns the texture */ + inline const GloxTexture& getTexture() const { return m_texture; } + +private: + /* The texture of the sphere */ + GloxTexture m_texture; + + /* The radius */ + float m_radius; + + /* The display list of this sphere */ + int m_disp_list; +}; + +} + +#endif /* GLOXTEXTUREDSPHERE_HPP_ */ diff --git a/glox/compat/glox/objects/examples/GloxCylinder.hpp b/glox/compat/glox/objects/examples/GloxCylinder.hpp new file mode 100644 index 0000000..7436f8e --- /dev/null +++ b/glox/compat/glox/objects/examples/GloxCylinder.hpp @@ -0,0 +1,83 @@ +#ifndef GLOXCYLINDER_HPP_ +#define GLOXCYLINDER_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxCylinder.hpp: <description> + */ + +#include "glox/GloxObject.hpp" +#include "glox/GloxPointNormalTexture.hpp" + +#include "glox/GloxTexture.hpp" +#include "glox/GloxQuadStrip.hpp" + +#include "glox/GloxScopedTranslation.hpp" +#include "glox/GloxColor.hpp" + +#include "glox/GloxPoint.hpp" + +#ifndef COMPILING_CYLINDER +#warn "Do Not Use This Class, it is broken!" +#endif + +namespace glox { + +/* This is an example object that draws + * a cylinder. This object supports lighting + * and texturing */ +class GloxCylinder : public GloxObject { +public: + /* Creates a cylinder with the radius r and the height + * h. th_res specifies the radial resolution of this + * cylinder */ + GloxCylinder( const GloxPoint<float>& pos, float r, float h, + float th_res=6, const GloxTexture* texture=NULL, bool normals=true, float rep=1, float repy=1 ); + + /* Get the position of this + * Cylinder */ + inline const GloxPoint<float>& getPosition() const { + return m_position; + } + + /* Sets the position of this Cylinder */ + inline void setPosition( const GloxPoint<float>& new_pos ) { + m_position = new_pos; + } + + inline void draw() const { + if( m_texture ) { + glEnable(GL_TEXTURE_2D); + m_texture->bind(); + } else { + glDisable(GL_TEXTURE_2D); + } + /* Color of the tree without a texture */ + static const GloxColor brown( 139, 69, 19 ); + /* Translate to the position of + * this object */ + GloxScopedTranslation trans( m_position ); + + /* Set the OpenGL state machine to + * use brown as the color */ + m_body.plot(); + glDisable(GL_TEXTURE_2D); + } + +private: + /* The position of this cylinder */ + GloxPoint<float> m_position; + + /* the cylinder is basically just a quad + * strip. This object supports lighting, + * so the components are PointNormals */ + GloxQuadStrip< GloxPointNormalTexture > m_body; + + /* the texture used for ths cylinder */ + const GloxTexture* m_texture; +}; + +}; + +#endif /* GLOXCYLINDER_HPP_ */ diff --git a/glox/genmake.sh b/glox/genmake.sh new file mode 100755 index 0000000..3bf4b89 --- /dev/null +++ b/glox/genmake.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# Makefile for the GL 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="libglox.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 ]] && [[ -e $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 -Icompat -I. "'$(OPTFLAGS)'" -D DEBUG_LEVEL_TRACE -Islox -Iglox">&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/glox/glox/GloxColor.hpp b/glox/glox/GloxColor.hpp new file mode 100644 index 0000000..11775d8 --- /dev/null +++ b/glox/glox/GloxColor.hpp @@ -0,0 +1,112 @@ +#ifndef GLOXCOLOR_HPP_ +#define GLOXCOLOR_HPP_ + +/* + * Author: jrahm + * created: 2013/10/23 + * GloxColor.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxRenderable.hpp" +#include "glox/GloxVectorizable.hpp" + +#include <string> +#include <sstream> + +namespace glox { + +/* This is a color class, it is for + * convinience */ +class GloxColor : public GloxRenderable,GloxVectorizable<uint8_t>,GloxVectorizable<float> { +public: + /* Creates a new color that is defined + * from the float values for r, g, b. The + * default value is an opaque black color */ + inline GloxColor( uint8_t r=0, uint8_t g=0, uint8_t b=0, uint8_t a=255 ) : + r( r ), g( g ), b( b ), a( a ) {} + + inline GloxColor( const GloxColor& color ) : + r( color.r ), g( color.g ), b( color.b ), a( color.a ) {} + + + + /* Get the components of this + * color */ + inline uint8_t getR() const { return r; } + inline uint8_t getG() const { return g; } + inline uint8_t getB() const { return b; } + inline uint8_t getA() const { return a; } + + inline void render() const { + if( a < 255 ) { + glColor4ub( r, g, b, a ); + } else { + glColor3ub( r, g, b ); + } + } + + + inline void scale( float f ) { scale2( f ); } + inline void scale( uint8_t f ) { scale2( f ); } + + virtual int toVector( float* arr, size_t len ) const { + if( len < 3 ) return -1; + arr[0] = r / 255.0; + arr[1] = g / 255.0; + arr[2] = b / 255.0; + if( len > 3 ) { + arr[3] = a / 255.0; + return 4; + } + return 3; + } + + virtual int toVector( uint8_t* arr, size_t len ) const { + if( len < 3 ) return -1; + arr[0] = r; + arr[1] = g; + arr[2] = b; + if( len > 3 ) { + arr[3] = a; + return 4; + } + return 3; + } + + inline GloxColor operator*( float value ) const { + GloxColor ret( * this ); + ret.scale2( value ); + return ret; + } + + inline std::string toString( ) const { + char buf[ 32 ]; + snprintf( buf, 32, "( %d, %d, %d, %d )\n", r, g, b, a ); + return std::string( buf ); + } + + inline GloxColor operator*( int value ) const { return (*this) * ((float)value); } + +private: + template <class NumT> + inline void scale2( NumT f ) { + int r1 = (int)(f * r); + int g1 = (int)(f * r); + int b1 = (int)(f * r); + int a1 = (int)(f * r); + r = r1 & 0xFF; + g = g1 & 0xFF; + b = b1 & 0xFF; + a = a1 & 0xFF; + } + + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +}; + +} + +#endif /* GLOXCOLOR_HPP_ */ diff --git a/glox/glox/GloxCommon.hpp b/glox/glox/GloxCommon.hpp new file mode 100644 index 0000000..77b1e82 --- /dev/null +++ b/glox/glox/GloxCommon.hpp @@ -0,0 +1,73 @@ +#ifndef GLOXCOMMON_HPP_ +#define GLOXCOMMON_HPP_ + +#include <inttypes.h> +#include <cstdio> +#include <math.h> +#include <algorithm> +#include <cstdlib> + +/* Include the OpenGL stuff */ + +#ifdef NO_USE_GLEW +#include <GL/gl.h> +#else +#include <GL/glew.h> +#endif + +/* + * Author: jrahm + * created: 2013/10/23 + * GloxCommon.hpp: <description> + */ + +namespace glox { + #define GloxWith( en, code ) \ + { glBegin( en ) ; \ + code ;\ + glEnd(); } + + #define GloxEnableFor( en, code ) \ + { glEnable( en ) ; code ; glDisable( en ); } + + #define GloxDisableFor( en, code ) \ + { glDisable( en ) ; code ; glEnable( en ) ; } + + #define GloxWithTranslation( point, code ) \ + { \ + glox::GloxState::pushMatrix(); \ + glox::GloxState::translate( (point) ); \ + code; \ + glox::GloxState::popMatrix(); \ + } + #define GloxScale( amt, code ) \ + { \ + glox::GloxState::pushMatrix(); \ + glScalef( amt,amt,amt ); \ + code; \ + glox::GloxState::popMatrix(); \ + } + + typedef long long Glox64; + typedef unsigned long long Glox64u; + typedef int Glox32; + typedef unsigned int Glox32u; + typedef unsigned char Glox8u; + typedef signed char Glox8; + typedef unsigned short Glox16u; + typedef signed short Glox16; + + inline double GloxCos( double th ) { + return cos(3.1415927/180*(th)); + } + + inline double GloxSin( double th ) { + return sin(3.1415927/180*(th)); + } + + #define GloxToDegrees( th ) \ + ((180 * (th)) / 3.14159927) + +}; + +#endif /* GLOXCOMMON_HPP_ */ diff --git a/glox/glox/GloxDebug.hpp b/glox/glox/GloxDebug.hpp new file mode 100644 index 0000000..8b3f964 --- /dev/null +++ b/glox/glox/GloxDebug.hpp @@ -0,0 +1,74 @@ +#ifndef GLOXDEBUG_HPP_ +#define GLOXDEBUG_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxDebug.hpp: <description> + */ + +extern FILE* log_file; + +#ifdef DEBUG_LEVEL_TRACE +#define DEBUG_LEVEL 6 +#endif +#ifdef DEBUG_LEVEL_DEBUG +#define DEBUG_LEVEL 5 +#endif +#ifdef DEBUG_LEVEL_INFO +#define DEBUG_LEVEL 4 +#endif +#ifdef DEBUG_LEVEL_WARN +#define DEBUG_LEVEL 3 +#endif +#ifdef DEBUG_LEVEL_ERROR +#define DEBUG_LEVEL 2 +#endif +#ifdef DEBUG_LEVEL_FATAL +#define DEBUG_LEVEL 1 +#endif +#ifdef DEBUG_LEVEL_SILENT +#define DEBUG_LEVEL 0 +#endif + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL 4 +#endif + +#if DEBUG_LEVEL > 5 +#define GloxTrace( category, fmt, ... ) if(1){ printf("[TRACE] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxTrace( category, fmt, ... ) +#endif + +#if DEBUG_LEVEL > 4 +#define GloxDebug( category, fmt, ... ) if(1){ printf("[DEBUG] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxDebug( category, fmt, ... ) +#endif + +#if DEBUG_LEVEL > 3 +#define GloxInfo( category, fmt, ... ) if(1){ printf("[INFO] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxInfo ( category, fmt, ... ) +#endif + +#if DEBUG_LEVEL > 2 +#define GloxWarn( category, fmt, ... ) if(1){ printf("[WARN] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxWarn( category, fmt, ... ) +#endif + +#if DEBUG_LEVEL > 1 +#define GloxError( category, fmt, ... ) if(1){ printf("[ERROR] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxError( category, fmt, ... ) +#endif + +#if DEBUG_LEVEL > 0 +#define GloxFatal( category, fmt, ... ) if(1){ printf("[FATAL] (%s) - " fmt, category, ##__VA_ARGS__ ); } +#else +#define GloxFatal( category, fmt, ... ) +#endif + +#endif /* GLOXDEBUG_HPP_ */ diff --git a/glox/glox/GloxFirstPersonPerspective.hpp b/glox/glox/GloxFirstPersonPerspective.hpp new file mode 100644 index 0000000..6effa3a --- /dev/null +++ b/glox/glox/GloxFirstPersonPerspective.hpp @@ -0,0 +1,64 @@ +#ifndef GLOXFIRSTPERSONPERSPECTIVE_HPP_ +#define GLOXFIRSTPERSONPERSPECTIVE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxFirstPersonPerspective.hpp: <description> + */ + +#include "glox/GloxPerspective.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxStandardProjection.hpp" +#include "glox/GloxVector3.hpp" + +namespace glox { + +class GloxFirstPersonPerspective : public GloxStandardProjection { +public: + inline GloxFirstPersonPerspective( + const GloxPoint<>& pos=GloxPoint<>(), + float roll=0, float pitch=0, float yaw=0, + float fov=50.0, float asp=1.8, float znear=0.1, float zfar=500.0 ) : + GloxStandardProjection( pos, fov, asp, znear, zfar ), + m_yaw( yaw ), m_pitch( pitch ), m_roll( roll ) {} + + inline void setYaw( float yaw ) { + m_yaw = yaw; + } + + inline void setPitch( float pitch ) { + m_pitch = pitch; + } + + inline void setRoll( float roll ) { + m_roll = roll; + } + + inline float getYaw() const { return m_yaw; } + inline float getPitch() const { return m_pitch; } + inline float getRoll() const { return m_roll; } + + /* adds a vector of rotations, expressed in + * terms or roll, pitch and yaw */ + inline void addRotationVector( const GloxVector3<float>& vec ) { + m_roll += vec.get0(); + m_pitch += GloxCos( m_roll )*vec.get1() + GloxSin( m_roll )*vec.get2(); + m_yaw += GloxSin( m_roll )*vec.get1() + GloxCos( m_roll ) * vec.get2(); + } + + virtual void render() const; + + inline GloxPoint<> forward( float rad ) { + return GloxPoint<>::fromSpherical( rad, m_yaw, m_pitch ) + this->getPosition(); + } +private: + /* Rotations */ + float m_yaw; /* Horizontal rotation */ + float m_pitch; /* Up or down */ + float m_roll; +}; + +} + +#endif /* GLOXFIRSTPERSONPERSPECTIVE_HPP_ */ diff --git a/glox/glox/GloxLookAtPerspective.hpp b/glox/glox/GloxLookAtPerspective.hpp new file mode 100644 index 0000000..67d197b --- /dev/null +++ b/glox/glox/GloxLookAtPerspective.hpp @@ -0,0 +1,62 @@ +#ifndef GLOXLOOKATPERSPECTIVE_HPP_ +#define GLOXLOOKATPERSPECTIVE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxLookAtPerspective.hpp: <description> + */ + +#include <GL/glu.h> + +#include "glox/GloxPerspective.hpp" +#include "glox/GloxState.hpp" +#include "glox/GloxStandardProjection.hpp" +#include "glox/GloxDebug.hpp" + +namespace glox { + +/* This is a projection which is a thin + * layer around gluLookAt */ +class GloxLookAtPerspective : public GloxStandardProjection { +public: + inline GloxLookAtPerspective( const GloxPoint<>& pos=GloxPoint<>(), + const GloxPoint<>& lookAt=GloxPoint<>(), const GloxPoint<>& upVec=GloxPoint<>( 0.0f, 1.0f, 0.0f ), + float fov=50.0, float asp=1.8, float zn=0.1, float zfar=500.0) : + GloxStandardProjection( pos, fov, asp, zn, zfar ), + m_LookAtPoint( lookAt ), m_UpVector( upVec ) {} + + inline virtual void render() const { +// GloxTrace( "GloxLookAtPerspective", "gluLookAt: %s %s %s\n", +// getPosition().toString().c_str(), m_LookAtPoint.toString().c_str(), +// m_UpVector.toString().c_str() ); + + gluLookAt( getPosition().getX(), getPosition().getY(), getPosition().getZ(), + m_LookAtPoint.getX(), m_LookAtPoint.getY(), m_LookAtPoint.getZ(), + m_UpVector.getX() , m_UpVector.getY() , m_UpVector.getZ() ); + } + + inline void setLookAtPoint( const GloxPoint<>& point ) { + m_LookAtPoint = point; + } + + inline const GloxPoint<>& getLookAtPoint() { + return m_LookAtPoint; + } + + inline void setUpVector( const GloxPoint<>& point ) { + m_UpVector = point; + } + + inline const GloxPoint<>& getUpVector() { + return m_UpVector; + } + +private: + GloxPoint<> m_LookAtPoint; + GloxPoint<> m_UpVector; +}; + +} + +#endif /* GLOXLOOKATPERSPECTIVE_HPP_ */ diff --git a/glox/glox/GloxNormal.hpp b/glox/glox/GloxNormal.hpp new file mode 100644 index 0000000..18fb709 --- /dev/null +++ b/glox/glox/GloxNormal.hpp @@ -0,0 +1,138 @@ +#ifndef GLOXNORMAL_HPP_ +#define GLOXNORMAL_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxNormal.hpp: <description> + */ + +#include "glox/GloxPlottable.hpp" + +#include <string> +#include <sstream> + +namespace glox { + +/* Type that the GloxNormal holds, + * defaults to an integer */ +template <class NumT=float> + +/* A normal in 3D space. This class + * implements Plottable which provides + * the `plot` function which calles + * glVertex on the components */ +class GloxNormal : public GloxPlottable { +public: + /* Creates a new GloxNormal from the components + * specified */ + inline GloxNormal( const NumT& x=0, const NumT& y=0, const NumT& z=0 ): + x(x), y(y), z(z) {} + + /* Copies the glox normal other */ + inline GloxNormal( const GloxNormal<NumT>& other ) : + x(other.x), y(other.y), z(other.z) {} + + /* Returns the X componet of this + * normal */ + inline const NumT& getX() const { + return x; + } + + /* Returns the Y component of this + * normal */ + inline const NumT& getY() const { + return y; + } + + /* Returns the Z component of this + * normal */ + inline const NumT& getZ() const { + return z; + } + + /* Sets the X component of this + * normal */ + inline void setX( const NumT& x ) { + this->x = x; + } + + /* Sets the Y component of this normal */ + inline void setY( const NumT& y ) { + this->y = y; + } + + /* Sets the Z component of this + * normal */ + inline void setZ( const NumT& z ) { + this->z = z; + } + + /* Copy the normal `normal` into this + * normal */ + inline const GloxNormal<NumT>& operator=( const GloxNormal<NumT>& normal ) { + this->x = normal.x; + this->y = normal.y; + this->z = normal.z; + + return * this; + } + + /* Add the components of `normal` to this */ + inline GloxNormal<NumT>& operator+=( const GloxNormal<NumT>& normal ) { + this->x += normal.x; + this->y += normal.y; + this->z += normal.z; + + return * this; + } + + /* Returns a new GloxNormal that is the sum + * of this and `normal` */ + inline GloxNormal<NumT> operator+( const GloxNormal<NumT>& normal ) const { + GloxNormal<NumT> ret; + ret += normal; + return ret; + } + + inline std::string toString() const { + std::stringstream stream; + stream << "( " << x << ", " << y << ", " << z << " )"; + return stream.str(); + } + + /* Plot this normal. This function depends on the + * number provided */ + inline void plot( ) const; + + /* Does exactly the same thing that plot does, but + * sometimes it is better to be more explicit about + * what plot is actually doing */ + inline void glNormal() const { plot() ; } +private: + NumT x; + NumT y; + NumT z; +}; + +/* Implementations of the plot functions for + * different template arguments */ +template <> +inline void GloxNormal<int>::plot() const { + glNormal3i( this->getX(), this->getY(), this->getZ() ); +} +template <> +inline void GloxNormal<float>::plot() const { + glNormal3f( this->getX(), this->getY(), this->getZ() ); +} +template <> +inline void GloxNormal<short>::plot() const { + glNormal3s( this->getX(), this->getY(), this->getZ() ); +} +template <class T> +inline void GloxNormal<T>::plot() const { + glNormal3d( this->getX(), this->getY(), this->getZ() ); +} + +} +#endif /* GLOXNORMAL_HPP_ */ diff --git a/glox/glox/GloxObject.hpp b/glox/glox/GloxObject.hpp new file mode 100644 index 0000000..3a9ef6e --- /dev/null +++ b/glox/glox/GloxObject.hpp @@ -0,0 +1,29 @@ +#ifndef GLOXOBJECT_HPP_ +#define GLOXOBJECT_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxObject.hpp: <description> + */ + +namespace glox { + +/* Similar to Plottable, but more strict. + * This object knows how to draw itself and that + * is all. + * + * An object should be all-inclusive, that is, + * unlike Plottable, GloxObject implies that + * the Object itself will only depend on the + * transformations of the OpenGL state machine + */ +class GloxObject { +public: + /* Draws this object */ + virtual void draw() const = 0; +}; + +} + +#endif /* GLOXOBJECT_HPP_ */ diff --git a/glox/glox/GloxPerspective.hpp b/glox/glox/GloxPerspective.hpp new file mode 100644 index 0000000..c22631e --- /dev/null +++ b/glox/glox/GloxPerspective.hpp @@ -0,0 +1,51 @@ +#ifndef GLOXPERSPECTIVE_HPP_ +#define GLOXPERSPECTIVE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxPerspective.hpp: <description> + */ + +#include "glox/GloxRenderable.hpp" +#include "glox/GloxPoint.hpp" + +namespace glox { + +/* This is an interface which describes + * what makes a camera perspective. The + * render() function will render the world + * from this perspective */ +class GloxPerspective : public GloxRenderable { +public: + /* Create a new Perspective at the location + * 'pos' */ + inline GloxPerspective( const GloxPoint<>& pos ) : + m_position( pos ) {} + + /* set the position of the perspective */ + inline void setPosition( const GloxPoint<>& pos ) { + m_position = pos; + } + + /* Returns the position of the Perspective */ + inline const GloxPoint<>& getPosition() const { + return m_position; + } + + /* This is called everytime the display + * function is called */ + virtual void render() const = 0; + + /* This renders a projection. This + * should be called if parameters + * change */ + virtual void project() const = 0; + +private: + GloxPoint<> m_position; +}; + +} + +#endif /* GLOXPERSPECTIVE_HPP_ */ diff --git a/glox/glox/GloxPlottable.hpp b/glox/glox/GloxPlottable.hpp new file mode 100644 index 0000000..15d5560 --- /dev/null +++ b/glox/glox/GloxPlottable.hpp @@ -0,0 +1,23 @@ +#ifndef PLOTTABLE_HPP_ +#define PLOTTABLE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * PointType.hpp: Holds the interface for al P + */ + +namespace glox { + +/* A plottable object is an object which + * can plot itself */ +class GloxPlottable { +public: + /* Plot this object on the + * space */ + virtual void plot() const = 0; +}; + +} + +#endif /* PLOTTABLE_HPP_ */ diff --git a/glox/glox/GloxPoint.hpp b/glox/glox/GloxPoint.hpp new file mode 100644 index 0000000..866d6ab --- /dev/null +++ b/glox/glox/GloxPoint.hpp @@ -0,0 +1,231 @@ +#ifndef GLOXPOINT_HPP_ +#define GLOXPOINT_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxPoint.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxPlottable.hpp" +#include "glox/GloxVectorizable.hpp" +#include "glox/GloxVector4.hpp" + +#include <iostream> +#include <string> +#include <sstream> + +#include <cmath> + +namespace glox { + +/* Type that the GloxPoint holds, + * defaults to an integer */ +template <class NumT=float> + +/* A point in 3D space. This class + * implements Plottable which provides + * the `plot` function which calles + * glVertex on the components */ +class GloxPoint : public GloxPlottable,GloxVectorizable<NumT> { +public: + inline static GloxPoint<> fromSpherical( NumT r, NumT th, NumT ph ) { + // double Ex = -2*dim*Sin(th)*Cos(ph); + // double Ey = +2*dim *Sin(ph); + // double Ez = +2*dim*Cos(th)*Cos(ph); + return GloxPoint<>( -r * GloxSin( th ) * GloxCos( ph ), + r * GloxSin( ph ), + r * GloxCos( th ) * GloxCos( ph ) ) ; + } + + inline static GloxPoint<> fromSpherical( const GloxVector4<NumT>& vec ) { + return fromSpherical( vec.getX(), vec.getY(), vec.getZ() ); + } + + /* Creates a new GloxPoint from the components + * specified */ + inline GloxPoint( const NumT& x=0, const NumT& y=0, const NumT& z=0 ): + x(x), y(y), z(z) {} + + /* Copies the glox point other */ + inline GloxPoint( const GloxPoint<NumT>& other ) : + x(other.x), y(other.y), z(other.z) {} + + /* Returns the X componet of this + * point */ + inline const NumT& getX() const { + return x; + } + + /* Returns the Y component of this + * point */ + inline const NumT& getY() const { + return y; + } + + /* Returns the Z component of this + * point */ + inline const NumT& getZ() const { + return z; + } + + /* Sets the X component of this + * point */ + inline void setX( const NumT& x ) { + this->x = x; + } + + /* Sets the Y component of this point */ + inline void setY( const NumT& y ) { + this->y = y; + } + + /* Sets the Z component of this + * point */ + inline void setZ( const NumT& z ) { + this->z = z; + } + + inline float getMagnitude() const { + return sqrt( x * x + y * y + z * z ) ; + } + + /* Copy the point `point` into this + * point */ + inline const GloxPoint<NumT>& operator=( const GloxPoint<NumT>& point ) { + this->x = point.x; + this->y = point.y; + this->z = point.z; + + return * this; + } + + /* Add the components of `point` to this */ + inline GloxPoint<NumT>& operator+=( const GloxPoint<NumT>& point ) { + this->x += point.x; + this->y += point.y; + this->z += point.z; + + return * this; + } + + /* Add the components of `point` to this */ + inline GloxPoint<NumT>& operator-=( const GloxPoint<NumT>& point ) { + this->x -= point.x; + this->y -= point.y; + this->z -= point.z; + + return * this; + } + + /* Returns a new GloxPoint that is the sum + * of this and `point` */ + inline GloxPoint<NumT> operator+( const GloxPoint<NumT>& point ) const { + GloxPoint<NumT> ret = *this; + ret += point; + return ret; + } + + /* Returns a new GloxPoint that is the sum + * of this and `point` */ + inline GloxPoint<NumT> operator-( const GloxPoint<NumT>& point ) const { + GloxPoint<NumT> ret = *this; + ret -= point; + return ret; + } + + inline GloxPoint<NumT>& operator*=( NumT scalar ) { + x *= scalar; + y *= scalar; + z *= scalar; + return * this; + } + + inline GloxPoint<NumT> operator*(NumT scalar) const { + GloxPoint<NumT> ret = * this; + ret *= scalar; + return ret; + } + + inline NumT dot( const GloxPoint<NumT>& other ) { + GloxPoint<> tmp1 = *this; + GloxPoint<> tmp2 = other; + + // std::cout << "Orig: " << this->toString() << ", " << other.toString() << std::endl; + tmp1.normalize(); + tmp2.normalize(); + + // std::cout << "Norm: " << this->toString() << ", " << other.toString() << std::endl;; + return tmp1.x * tmp2.x + + tmp1.y * tmp2.y + + tmp1.z * tmp2.z ; + } + + inline GloxPoint<NumT> cross( const GloxPoint<NumT>& other ) { + return GloxPoint( + y * other.z - z * other.y + , z * other.x - x * other.z + , x * other.y - y * other.x + ); + } + + inline void normalize() { + float mag = getMagnitude(); + + x = x / mag; + y = y / mag; + z = z / mag; + } + + inline std::string toString() const { + std::stringstream stream; + stream << "( " << x << ", " << y << ", " << z << " )"; + return stream.str(); + } + + virtual inline void scale( NumT amt ) { + x *= amt; y *= amt; z *= amt; + } + + int toVector( NumT* arr, size_t len ) const { + if( len < 3 ) return -1; + arr[0] = x; + arr[1] = y; + arr[2] = z; + return 3; + } + + /* Plot this point. This function depends on the + * number provided */ + inline void plot( ) const; +private: + NumT x; + NumT y; + NumT z; +}; + +typedef GloxPoint<> GloxPointf; + +/* Implementations of the plot functions for + * different template arguments */ +template <> +inline void GloxPoint<int>::plot() const { + glVertex3i( this->getX(), this->getY(), this->getZ() ); +} +template <> +inline void GloxPoint<float>::plot() const { + glVertex3f( this->getX(), this->getY(), this->getZ() ); +} +template <> +inline void GloxPoint<short>::plot() const { + glVertex3s( this->getX(), this->getY(), this->getZ() ); +} +template <class T> +inline void GloxPoint<T>::plot() const { + glVertex3d( this->getX(), this->getY(), this->getZ() ); +} + +} + +#endif /* GLOXPOINT_HPP_ */ diff --git a/glox/glox/GloxPointCollection.hpp b/glox/glox/GloxPointCollection.hpp new file mode 100644 index 0000000..f6a209a --- /dev/null +++ b/glox/glox/GloxPointCollection.hpp @@ -0,0 +1,103 @@ +#ifndef GLOXPOINTCOLLECTION_HPP_ +#define GLOXPOINTCOLLECTION_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxPointCollection.hpp: <description> + */ + +#include "glox/GloxPlottable.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxDebug.hpp" + +#include <vector> +#include <string> +#include <sstream> + +namespace glox { + +template < class PlottableT=GloxPoint<float> > + +/* GloxPointCollection: a collection of Plottable that + * may be plotted in bulk */ +class GloxPointCollection : public GloxPlottable { +public: + /* Shorter vector term */ + typedef std::vector< PlottableT > m_Vec_t; + typedef typename m_Vec_t::iterator iterator; + typedef typename m_Vec_t::const_iterator const_iterator; + + /* Constructs a new GloxPointCollection with + * no Points */ + inline GloxPointCollection( ) { + // Nothing here for now + } + + /* Creates a new GloxPointCollection with the + * initial starting points `points` + */ + inline GloxPointCollection( const m_Vec_t& points ) { + this->points = points; + } + + /* Iterate through the vector of Plottable + * and call their plot functions */ + virtual void plot() const { + // GloxTrace( "GloxPointCollection", "plot(): this = %s\n", this->toString().c_str() ); + + for( const_iterator itr = this->begin(); itr != this->end(); ++ itr ) { + (*itr).plot(); + } + } + + /* Appends a point to this collection */ + virtual void add( const PlottableT& point ) { + this->points.push_back( point ); + } + + /* Returns an iterator for this + * GloxPointCollection */ + inline iterator begin() { + return points.begin(); + } + + /* Returns then end of the iterator */ + inline iterator end() { + return points.end(); + } + + inline void clear() { + points.clear(); + } + + /* Returns an iterator for this + * GloxPointCollection */ + inline const_iterator begin() const { + return points.begin(); + } + + /* Returns then end of the const_iterator */ + inline const_iterator end() const { + return points.end(); + } + + inline std::string toString() const { + std::stringstream stream; + stream << "[ "; + for( const_iterator itr = this->begin(); itr != this->end(); ++ itr ) { + stream << (*itr).toString() << ", "; + } + stream << "]"; + return stream.str(); + } + +private: + + /* The points to plot */ + m_Vec_t points; +}; + +}; + +#endif /* GLOXPOINTCOLLECTION_HPP_ */ diff --git a/glox/glox/GloxPointNormal.hpp b/glox/glox/GloxPointNormal.hpp new file mode 100644 index 0000000..256db75 --- /dev/null +++ b/glox/glox/GloxPointNormal.hpp @@ -0,0 +1,73 @@ +#ifndef GLOXPOINTNORMAL_HPP_ +#define GLOXPOINTNORMAL_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxPointNormal.hpp: <description> + */ + +#include "glox/GloxPlottable.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxNormal.hpp" + +#include <string> +#include <sstream> + +namespace glox { + +/* The number type used by both + * the point and the normal to use */ +template <class NumT=float> + +/* A class that couples a point with a normal. This + * is a useful wrapper over both a glVertex and glNormal + * functions */ +class GloxPointNormal : public GloxPlottable{ +public: + /* Creates a new point at the + * origin with no normal */ + GloxPointNormal( ) : + m_point(), m_normal() {} + + /* Creates a new GloxPointNormal at the point `point` + * and with the normal `normal` */ + GloxPointNormal( const GloxPoint<NumT>& point, const GloxNormal<NumT>& normal ) : + m_point( point ), m_normal( normal ) {} + + /* Plots a point and sets the + * normal for that point */ + inline void plot( ) const { + m_normal.plot(); + m_point.plot(); + } + + inline void setPoint( const GloxPoint<NumT>& point ) { + m_point = point; + } + + inline void setNormal( const GloxNormal<NumT>& normal ) { + m_normal = normal; + } + + inline const GloxPoint<NumT>& getPoint () { + return m_point; + } + + inline const GloxNormal<NumT>& getNormal() { + return m_normal; + } + + inline const std::string toString() const { + std::stringstream ret; + ret << "GloxPointNormal{ " << m_point.toString() << ", " << m_normal.toString() << " }" ; + return ret.str(); + } +private: + GloxPoint<NumT> m_point; + GloxNormal<NumT> m_normal; +}; + +} + +#endif /* GLOXPOINTNORMAL_HPP_ */ diff --git a/glox/glox/GloxPointNormalTexture.hpp b/glox/glox/GloxPointNormalTexture.hpp new file mode 100644 index 0000000..6bed16f --- /dev/null +++ b/glox/glox/GloxPointNormalTexture.hpp @@ -0,0 +1,50 @@ +#ifndef GLOXPOINTNORMALTEXTURE_HPP_ +#define GLOXPOINTNORMALTEXTURE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxPointNormalTexture.hpp: <description> + */ + +#include "glox/GloxPlottable.hpp" +#include "glox/GloxPointNormal.hpp" +#include "glox/GloxTexture.hpp" +#include "glox/GloxPoint.hpp" + +namespace glox { + +/* + * An aggregation of all of the following: + * A point, + * that points normal, + * the mapping of a texture to + * that point + */ +class GloxPointNormalTexture : public GloxPlottable { +public: + inline GloxPointNormalTexture( const GloxPointNormal<>& pointNormal, const GloxPoint<>& texPoint ) : + m_PointNormal( pointNormal ), m_TextureMap( texPoint ) { + } + + inline GloxPointNormalTexture( const GloxPoint<>& point, const GloxNormal<>& normal, const GloxPoint<>& texPoint ) : + m_PointNormal( point, normal ), m_TextureMap( texPoint ) {} + + inline void plot() const { + glTexCoord2f( m_TextureMap.getX(), m_TextureMap.getY() ); + m_PointNormal.plot(); + } + + inline const GloxPointNormal<>& getPointNormal() const { return m_PointNormal; } + inline const GloxPoint<>& getTexturePoint() const { return m_TextureMap; } + + inline GloxPointNormal<>& getPointNormal() { return m_PointNormal; } + inline GloxPoint<>& getTexturePoint() { return m_TextureMap; } +private: + GloxPointNormal<> m_PointNormal; + GloxPoint<> m_TextureMap; +}; + +} + +#endif /* GLOXPOINTNORMALTEXTURE_HPP_ */ diff --git a/glox/glox/GloxProgram.hpp b/glox/glox/GloxProgram.hpp new file mode 100644 index 0000000..e10f7ca --- /dev/null +++ b/glox/glox/GloxProgram.hpp @@ -0,0 +1,86 @@ +#ifndef GLOXPROGRAM_HPP_ +#define GLOXPROGRAM_HPP_ + +/* + * Author: jrahm + * created: 2013/12/09 + * GloxProgram.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxShader.hpp" +#include "glox/GloxVector3.hpp" +#include "glox/GloxVector4.hpp" +#include "glox/GloxPoint.hpp" + +#include <vector> + +namespace glox { + +class GloxProgram { +public: + GloxProgram( ) ; + + unsigned int getId() { + return id ; + } + + int attachShader( const GloxShader& shader ) ; + + int attachShaderFromFile( const char* filename, GLenum type ) ; + + int getUniformLocation( const char* uniform ) ; + + inline void setUniformFloat( int uniform, float fl ) { + glUniform1f( uniform, fl ) ; + } + + inline void setUniformInteger( int uniform, float i ) { + glUniform1f( uniform, i ) ; + } + + template <class Vectorizable3> + inline void setUniformVector3( int uniform, const Vectorizable3& point ) { + glUniform3f( uniform, point.getX(), point.getY(), point.getZ() ) ; + } + + template <class Vectorizable4> + inline void setUniformVector4( int uniform, const Vectorizable4& point ) { + float arr[4] ; + point.toVector( arr, 4 ) ; + glUniform4fv( uniform, 1, arr ) ; + } + + template <class Vectorizable3> + inline void setUniformVector3FromList( int uniform, const std::vector<Vectorizable3>& vecs ) { + int len = vecs.size() * 3 ; + float* arr = new float[len] ; + + for ( size_t i = 0; i < vecs.size() ; ++ i ) { + vecs[i].toVector( arr + (i * 3), 3 ) ; + } + } + + template <class Vectorizable4> + inline void setUniformVector4FromList( int uniform, const std::vector<Vectorizable4>& vecs ) { + int len = vecs.size() * 4 ; + float* arr = new float[len] ; + + for ( size_t i = 0; i < vecs.size() ; ++ i ) { + vecs[i].toVector( arr + (i * 3), 3 ) ; + } + }; + + void render() const ; + + int link(); + + static void unloadPrograms() ; +private: + + unsigned int id ; +}; + +} + +#endif /* GLOXPROGRAM_HPP_ */ diff --git a/glox/glox/GloxQuadStrip.hpp b/glox/glox/GloxQuadStrip.hpp new file mode 100644 index 0000000..6eb283e --- /dev/null +++ b/glox/glox/GloxQuadStrip.hpp @@ -0,0 +1,61 @@ +#ifndef QUADSTRIP_HPP_ +#define QUADSTRIP_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * QuadStrip.hpp: + */ + +#include <GL/gl.h> +#include <GL/glu.h> + +#include "glox/GloxPointCollection.hpp" + +namespace glox { + +template <class PlottableT /* extends Plottable */ = GloxPoint<float> > + +/* This class represents a quad strip + * for OpenGL. This will draw a collection + * of points using GL_QUAD_STRIP + * + * This class extends Plottable wich + * means that it may be plotted, but + * that it IS dependent on state + * of the OpenGL machine */ +class GloxQuadStrip : public GloxPlottable { +public: + inline GloxQuadStrip() : + points() {} + /* Creates a new GloxQuadStrip with the points + * given as a vector as it's initial points */ + inline GloxQuadStrip( const std::vector< PlottableT >& points ) : + points( points ) {} + + /* Creates a new GloxQuadStrip with the points + * given as a collection of points */ + inline GloxQuadStrip( const GloxPointCollection<PlottableT>& collection ) : + points( collection ) {} + + /* Plots the points as a GL_QUAD_STRIP */ + inline virtual void plot() const { + glBegin( GL_QUAD_STRIP ); + points.plot(); + glEnd(); + } + + /* Appends a point to the collection + * of points to plot */ + inline void addPoint( const PlottableT& point ) { + points.add( point ); + } + +private: + /* The points that make up this + * quad strip */ + GloxPointCollection<PlottableT> points; +}; + +} +#endif /* QUADSTRIP_HPP_ */ diff --git a/glox/glox/GloxRenderable.hpp b/glox/glox/GloxRenderable.hpp new file mode 100644 index 0000000..cf1265b --- /dev/null +++ b/glox/glox/GloxRenderable.hpp @@ -0,0 +1,19 @@ +#ifndef GLOXRENDERABLE_HPP_ +#define GLOXRENDERABLE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/23 + * GloxRenderable.hpp: <description> + */ + +namespace glox { + +class GloxRenderable { +public: + virtual void render() const = 0; +}; + +} + +#endif /* GLOXRENDERABLE_HPP_ */ diff --git a/glox/glox/GloxRotation.hpp b/glox/glox/GloxRotation.hpp new file mode 100644 index 0000000..3dd9966 --- /dev/null +++ b/glox/glox/GloxRotation.hpp @@ -0,0 +1,39 @@ +#ifndef GLOXROTATION_HPP_ +#define GLOXROTATION_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxRotation.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" + +namespace glox { + +class GloxRotation { +public: + inline GloxRotation( double ang, double x, double y, double z ) : + m_ang( ang ), m_x( x ), m_y( y ), m_z( z ) {} + + inline void render() const { glRotatef( m_ang, m_x, m_y, m_z ); } + + inline double getAngle() const { return m_ang; } + inline double getX() const { return m_x; } + inline double getY() const { return m_y; } + inline double getZ() const { return m_z; } + + inline void setAngle( double ang ) { m_ang = ang ; } + inline void setX( double x ) { m_x = x; } + inline void setY( double y ) { m_y = y; } + inline void setZ( double z ) { m_z = z; } +private: + double m_ang; + double m_x; + double m_y; + double m_z; +}; + +} + +#endif /* GLOXROTATION_HPP_ */ diff --git a/glox/glox/GloxScopedAttributes.hpp b/glox/glox/GloxScopedAttributes.hpp new file mode 100644 index 0000000..7491ad8 --- /dev/null +++ b/glox/glox/GloxScopedAttributes.hpp @@ -0,0 +1,38 @@ +#ifndef GLOXSCOPEDATTRIBUTES_HPP_ +#define GLOXSCOPEDATTRIBUTES_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxScopedAttributes.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" + +namespace glox { + +/* A class, which on creation + * will push the specified attributes + * to the GL stack, and upon deletion + * will restore those attributes + * + * NOTE: When using this class, one should + * be wary of manually pushing and popping + * attributes from the GL stack. + */ +class GloxScopedAttributes { +public: + /* Push the attributes on the GL stack */ + inline GloxScopedAttributes( GLbitfield fields ) { + glPushAttrib( fields ); + } + + /* Restore the attributes */ + inline ~GloxScopedAttributes( ) { + glPopAttrib() ; + } +}; + +} + +#endif /* GLOXSCOPEDATTRIBUTES_HPP_ */ diff --git a/glox/glox/GloxScopedBegin.hpp b/glox/glox/GloxScopedBegin.hpp new file mode 100644 index 0000000..15459be --- /dev/null +++ b/glox/glox/GloxScopedBegin.hpp @@ -0,0 +1,30 @@ +#ifndef GLOXSCOPEDBEGIN_HPP_ +#define GLOXSCOPEDBEGIN_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxScopedBegin.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" + +namespace glox { + +/* In keeping with the philosophy of Glox, + * this class scopes a begin so GlEnd is + * automatically called when leaving scope */ +class GloxScopedBegin { +public: + inline GloxScopedBegin( GLenum to_begin ) { + glBegin( to_begin ); + } + + inline ~GloxScopedBegin( ) { + glEnd(); + } +}; + +} + +#endif /* GLOXSCOPEDBEGIN_HPP_ */ diff --git a/glox/glox/GloxScopedRotation.hpp b/glox/glox/GloxScopedRotation.hpp new file mode 100644 index 0000000..4c95c27 --- /dev/null +++ b/glox/glox/GloxScopedRotation.hpp @@ -0,0 +1,32 @@ +/* + * Author: jrahm + * created: 2013/10/24 + * GloxScopedTranslation.hpp: <description> + */ + +#include "glox/GloxState.hpp" +#include "glox/GloxRotation.hpp" + +namespace glox { + +/* A translation that endures for + * the current scope */ +class GloxScopedRotation { +public: + inline GloxScopedRotation( double angle, double x, double y, double z ) { + GloxState::pushMatrix(); + GloxState::rotate( angle, x, y, z ); + } + + inline GloxScopedRotation( const GloxRotation& rotation ) { + GloxState::pushMatrix(); + GloxState::rotate( rotation.getAngle(), rotation.getX(), + rotation.getY(), rotation.getZ() ); + } + + inline ~GloxScopedRotation( ) { + GloxState::popMatrix(); + } +}; + +} diff --git a/glox/glox/GloxScopedTranslation.hpp b/glox/glox/GloxScopedTranslation.hpp new file mode 100644 index 0000000..4dc14c2 --- /dev/null +++ b/glox/glox/GloxScopedTranslation.hpp @@ -0,0 +1,31 @@ +#ifndef GLOXSCOPEDTRANSLATION_HPP_ +#define GLOXSCOPEDTRANSLATION_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxScopedTranslation.hpp: <description> + */ + +#include "glox/GloxPoint.hpp" +#include "glox/GloxState.hpp" + +namespace glox { + +/* A translation that endures for + * the current scope */ +class GloxScopedTranslation { +public: + inline GloxScopedTranslation( const GloxPoint<>& point ) { + GloxState::pushMatrix(); + GloxState::translate( point ); + } + + inline ~GloxScopedTranslation( ) { + GloxState::popMatrix(); + } +}; + +} + +#endif /* GLOXSCOPEDTRANSLATION_HPP_ */ diff --git a/glox/glox/GloxShader.hpp b/glox/glox/GloxShader.hpp new file mode 100644 index 0000000..98e42a0 --- /dev/null +++ b/glox/glox/GloxShader.hpp @@ -0,0 +1,47 @@ +#ifndef GLOXSHADER_HPP_ +#define GLOXSHADER_HPP_ + +/* + * Author: jrahm + * created: 2013/12/09 + * GloxShader.hpp: <description> + */ + + +#include "glox/GloxCommon.hpp" +#include <string> + +namespace glox { + +class GloxShader { +public: + inline GloxShader( GLenum type ) { + this->type = type ; + } + + static inline const std::string& getMessage() { + return message ; + } + + inline GLenum getType() const { + return type ; + } + + inline unsigned int getId() const { + return m_shader ; + } + + int load( const char* filename ) ; + + ~GloxShader() ; +private: + unsigned int m_shader ; + GLenum type ; + + static int readFile( const char* filename, std::string& into ) ; + static std::string message ; +} ; + +} + +#endif /* GLOXSHADER_HPP_ */ diff --git a/glox/glox/GloxStandardProjection.hpp b/glox/glox/GloxStandardProjection.hpp new file mode 100644 index 0000000..1ca0416 --- /dev/null +++ b/glox/glox/GloxStandardProjection.hpp @@ -0,0 +1,60 @@ +#ifndef GLOXSTANDARDPROJECTION_HPP_ +#define GLOXSTANDARDPROJECTION_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxStandardProjection.hpp: <description> + */ + +#include <GL/glu.h> + +#include "glox/GloxPerspective.hpp" +#include "glox/GloxState.hpp" + +namespace glox { + +class GloxStandardProjection : public GloxPerspective { +public: + +inline GloxStandardProjection( const GloxPoint<>& pos, float fov=50.0, float asp=1.8, float znear=0.1, float zfar=500.0 ) : + GloxPerspective( pos ), + m_FieldOfView( fov ), m_AspectRatio( asp ), m_ZNear( znear ), m_ZFar( zfar ) { +} + +/* Set up the projection */ +inline virtual void project() const { + GloxState::matrixMode(GL_PROJECTION); + GloxState::loadIdentity(); + + gluPerspective( m_FieldOfView, m_AspectRatio, m_ZNear, m_ZFar ); + + GloxState::matrixMode(GL_MODELVIEW); + GloxState::loadIdentity(); +} + +/* This class only helps with + * projections, it still needs to + * have render implemented */ +virtual void render() const = 0; + +float getFieldOfView() const { return m_FieldOfView; } +float getAspectRatio() const { return m_AspectRatio; } +float getZNear() const { return m_ZNear; } +float getZFar() const { return m_ZFar; } + +void setFieldOfView( float fieldOfView) { m_FieldOfView = fieldOfView; } +void setAspectRatio( float aspectRatio) { m_AspectRatio = aspectRatio; } +void setZNear( float zNear) { m_ZNear = zNear; } +void setZFar ( float zFar) { m_ZFar = zFar; } + +private: + float m_FieldOfView; + float m_AspectRatio; + float m_ZNear; + float m_ZFar; +}; + +} + +#endif /* GLOXSTANDARDPROJECTION_HPP_ */ diff --git a/glox/glox/GloxState.hpp b/glox/glox/GloxState.hpp new file mode 100644 index 0000000..3725bbc --- /dev/null +++ b/glox/glox/GloxState.hpp @@ -0,0 +1,75 @@ +#ifndef GLOXSTATE_HPP_ +#define GLOXSTATE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxState.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" +#include "glox/GloxPoint.hpp" + +namespace glox { + +class GloxState { +public: + inline static void pushMatrix() { glPushMatrix(); } + inline static void popMatrix() { glPopMatrix(); } + + template <class T> + inline static void translate( const GloxPoint<T>& point ) ; + + inline static void matrixMode( GLenum val ) { glMatrixMode( val ) ; } + inline static void loadIdentity() { glLoadIdentity(); } + + inline static void rotate( float amt, const GloxPoint<>& vector ) { + glRotatef( amt, vector.getX(), vector.getY(), vector.getZ() ); + } + + inline static void clear( GLbitfield val ) { + glClear(val); + } + + inline static void enable( GLenum e ) { + glEnable( e ); + } + + inline static void disable( GLenum e ) { + glDisable( e ); + } + + inline static void flush() { + glFlush(); + } + + inline static void lightModel( GLenum key, int val ) { + glLightModeli( key, val ); + } + + inline static void colorMaterial( GLenum key, GLenum val ) { + glColorMaterial(key,val); + } + + inline static void rotate( double ang, double x, double y, double z ) { + glRotated( ang, x, y, z ); + } +}; + +template <> +/* Floats are a special case, so translate to + * them like normal */ +inline void GloxState::translate( const GloxPoint<float>& point ) { + glTranslatef( point.getX(), point.getY(), point.getZ() ); +} + +template <class T> +/* Everything else should be implicity cast + * to a double and send to glTranslated */ +inline void GloxState::translate( const GloxPoint<T>& point ) { + glTranslated( point.getX(), point.getY(), point.getZ() ); +} + +} + +#endif /* GLOXSTATE_HPP_ */ diff --git a/glox/glox/GloxTexture.hpp b/glox/glox/GloxTexture.hpp new file mode 100644 index 0000000..1427c6a --- /dev/null +++ b/glox/glox/GloxTexture.hpp @@ -0,0 +1,29 @@ +#ifndef GLOXTEXTURE_HPP_ +#define GLOXTEXTURE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxTexture.hpp: <description> + */ + +#include "glox/GloxCommon.hpp" + +namespace glox { + +class GloxTexture { +public: + GloxTexture( unsigned int id=0 ) : + m_id( id ) {} + + unsigned int getId() const { return m_id ; } + void bind() const { glBindTexture( GL_TEXTURE_2D, m_id ) ; } + + void setId( unsigned int id ) { m_id = id; } +private: + unsigned int m_id; +}; + +} + +#endif /* GLOXTEXTURE_HPP_ */ diff --git a/glox/glox/GloxTextureFactory.hpp b/glox/glox/GloxTextureFactory.hpp new file mode 100644 index 0000000..32ddb1c --- /dev/null +++ b/glox/glox/GloxTextureFactory.hpp @@ -0,0 +1,48 @@ +#ifndef GLOXTEXTUREFACTORY_HPP_ +#define GLOXTEXTUREFACTORY_HPP_ + +/* + * Author: jrahm + * created: 2013/10/22 + * GloxTextureFactory.hpp: <description> + */ + +#include "glox/GloxTexture.hpp" + +#include <iostream> +#include <fstream> +#include <string> + +namespace glox { + +/* This is a static class that builds + * texture objects. The textures can then + * be pinned onto objects */ +class GloxTextureFactory { +public: + /* Creates a new texture from a bitmap + * image. If there is an error, NULL is + * returned */ + static GloxTexture* textureFromBitmap( std::istream& stream ); + static inline GloxTexture* textureFromBitmapFile( const char* filename ) { + std::ifstream ifs; + ifs.open( filename, std::ifstream::binary ); + + if( ! ifs.is_open() ) { return NULL; } + return textureFromBitmap( ifs ); + } + +#ifndef NO_JPG_SUPPORT + static GloxTexture* buildTextureFromJpg( std::istream& stream ); +#endif + +#ifndef NO_PNG_SUPPORT + static GloxTexture* buildTextureFromPng( std::istream& stream ); +#endif + + static const std::string& getErrorMessage(); +}; + +} + +#endif /* GLOXTEXTUREFACTORY_HPP_ */ diff --git a/glox/glox/GloxTextureRepeat.hpp b/glox/glox/GloxTextureRepeat.hpp new file mode 100644 index 0000000..e9bd526 --- /dev/null +++ b/glox/glox/GloxTextureRepeat.hpp @@ -0,0 +1,59 @@ +#ifndef GLOXTEXTUREREPEAT_HPP_ +#define GLOXTEXTUREREPEAT_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxTextureRepeat.hpp: <description> + */ + +/* This class abstracts a teaxture that may repeat + * several times */ + +#include "glox/GloxTexture.hpp" + +namespace glox { + +class GloxTextureRepeat { +public: + inline GloxTextureRepeat( const GloxTexture* texture, float xreps=1.0f, float yreps=1.0 ): + m_texture( texture ), m_xreps( xreps ), m_yreps( yreps ) {} + + inline const GloxTexture* getTexture() const { + return m_texture ; + } + + inline bool isNull() const { + return m_texture == NULL; + } + + inline float getXReps() const { + return m_xreps; + } + + inline float getYReps() const { + return m_yreps; + } + + inline void setYReps( float yreps) { + m_yreps = yreps; + } + + inline void setXReps( float xreps ) { + m_xreps = xreps; + } +private: + /* The texture this class + * is repeating */ + const GloxTexture* m_texture; + + /* The number of times to repeat + * this texture */ + float m_xreps; + float m_yreps; +}; + +} + + +#endif /* GLOXTEXTUREREPEAT_HPP_ */ diff --git a/glox/glox/GloxVector3.hpp b/glox/glox/GloxVector3.hpp new file mode 100644 index 0000000..390a820 --- /dev/null +++ b/glox/glox/GloxVector3.hpp @@ -0,0 +1,86 @@ +#ifndef GLOXVECTOR3_HPP_ +#define GLOXVECTOR3_HPP_ + +/* + * Author: jrahm + * created: 2013/10/29 + * GloxVector3.hpp: <description> + */ + +#include "glox/GloxPoint.hpp" + +#include <string> +#include <sstream> + +#include <cmath> + +namespace glox { +template <class NumT=float> + +class GloxVector3 { +public: + inline GloxVector3( const NumT& x=0, const NumT& y=0, const NumT& z=0 ) : + x( x ), y( y ), z( z ) {} + + inline const NumT& get0() const { return x; } + inline const NumT& get1() const { return y; } + inline const NumT& get2() const { return z; } + + inline void set0( const NumT& x ) { this->x = x; } + inline void set1( const NumT& y ) { this->y = y; } + inline void set2( const NumT& z ) { this->z = z; } + + inline bool isZero() { + return x == 0 && y == 0 && z == 0 ; + } + + inline void operator+=(const GloxVector3& other ) { + x += other.x; + y += other.y; + z += other.z; + } + + inline void operator*=( NumT scalar ) { + x *= scalar; + y *= scalar; + z *= scalar; + } + + inline GloxVector3<NumT> operator*( NumT scalar ) { + GloxVector3 tmp = *this; + tmp *= scalar; + return tmp; + } + + inline GloxVector3<NumT> cross( const GloxVector3<NumT>& v ) { + return GloxVector3<NumT>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + } + + inline double getMagnitude() const { + return sqrt( x*x + y*y + z*z ); + } + + void normalize() { + double mag = getMagnitude(); + x = x / mag; + y = y / mag; + z = z / mag; + } + + inline GloxPoint<NumT> toPoint() { + return GloxPoint<NumT>( x, y, z ); + } + + inline std::string toString() const { + std::stringstream stream; + stream << "( " << x << ", " << y << ", " << z << " )"; + return stream.str(); + } +private: + NumT x; + NumT y; + NumT z; +}; +} + +#endif /* GLOXVECTOR3_HPP_ */ diff --git a/glox/glox/GloxVector4.hpp b/glox/glox/GloxVector4.hpp new file mode 100644 index 0000000..6aeecfc --- /dev/null +++ b/glox/glox/GloxVector4.hpp @@ -0,0 +1,60 @@ +#ifndef GLOXVECTOR4_HPP_ +#define GLOXVECTOR4_HPP_ + +/* + * Author: jrahm + * created: 2013/10/23 + * GloxVector4.hpp: <description> + */ + +#include <string> +#include <sstream> + +namespace glox { +template <class NumT=float> + +class GloxVector4 { +public: + inline GloxVector4( const NumT& x=0, const NumT& y=0, const NumT& z=0, const NumT& w=0 ) : + x( x ), y( y ), z( z ), w( w ) {} + + inline const NumT& getX() const { return x; } + inline const NumT& getY() const { return y; } + inline const NumT& getZ() const { return z; } + inline const NumT& getW() const { return w; } + + inline const NumT& get0() const { return x; } + inline const NumT& get1() const { return y; } + inline const NumT& get2() const { return z; } + inline const NumT& get3() const { return w; } + + inline void setX( const NumT& x ) { this->x = x; } + inline void setY( const NumT& y ) { this->y = y; } + inline void setZ( const NumT& z ) { this->z = z; } + inline void setW( const NumT& w ) { this->w = w; } + + inline bool isZero() { + return x == 0 && y == 0 && z == 0 && w == 0 ; + } + + inline void operator+=(const GloxVector4& other ) { + x += other.x; + y += other.y; + z += other.z; + w += other.w; + } + + inline std::string toString() const { + std::stringstream stream; + stream << "( " << x << ", " << y << ", " << z << ", " << w << " )"; + return stream.str(); + } +private: + NumT x; + NumT y; + NumT z; + NumT w; +}; +} + +#endif /* GLOXVECTOR4_HPP_ */ diff --git a/glox/glox/GloxVectorizable.hpp b/glox/glox/GloxVectorizable.hpp new file mode 100644 index 0000000..5f84cd0 --- /dev/null +++ b/glox/glox/GloxVectorizable.hpp @@ -0,0 +1,33 @@ +#ifndef GLOXVECTORIZABLE_HPP_ +#define GLOXVECTORIZABLE_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxVectorizable.hpp: This class is an interface for types + * that may be considered vectors and therefore can do + * some simple operations. + */ + +#include "glox/GloxCommon.hpp" + +namespace glox { + +template <class NumT=float> +class GloxVectorizable { +public: + /* All vectors must be able to be multiplied + * by a scalar */ + virtual void scale( NumT amt ) = 0; + inline GloxVectorizable<NumT>& operator*=( NumT amt ) { scale( amt ); }; + + /* Creates a primitive vector and returns + * the number of elements stored */ + virtual int toVector( NumT* arr, size_t len ) const = 0; +}; + +} + + + +#endif /* GLOXVECTORIZABLE_HPP_ */ diff --git a/glox/glox/GloxViewport.hpp b/glox/glox/GloxViewport.hpp new file mode 100644 index 0000000..785e315 --- /dev/null +++ b/glox/glox/GloxViewport.hpp @@ -0,0 +1,37 @@ +#ifndef GLOXVIEWPORT_HPP_ +#define GLOXVIEWPORT_HPP_ + +/* + * Author: jrahm + * created: 2013/10/24 + * GloxViewport.hpp: <description> + */ + +#include "glox/GloxRenderable.hpp" + +namespace glox { + class GloxViewport : public GloxRenderable { + public: + inline GloxViewport( int x=0, int y=0, int width=0, int height=0 ) : + m_x( x ), m_y( y ), m_width( width ), m_height( height ) {} + + inline void render() const { + glViewport( m_x, m_y, m_width, m_height ); + } + + inline void setX( int x ) { m_x = x ; } + inline void setY( int y ) { m_y = y ; } + + inline void setWidth( int width ) { m_width = width; } + inline void setHeight( int height ) { m_height = height; } + + inline double getAspectRatio() { return (double)m_width / (double)m_height ; } + private: + int m_x; + int m_y; + int m_width; + int m_height; + }; +} + +#endif /* GLOXVIEWPORT_HPP_ */ diff --git a/glox/glox/src/GloxCube.cpp b/glox/glox/src/GloxCube.cpp new file mode 100644 index 0000000..91204ef --- /dev/null +++ b/glox/glox/src/GloxCube.cpp @@ -0,0 +1,82 @@ +#include "glox/objects/GloxCube.hpp" +#include "glox/GloxScopedBegin.hpp" + +namespace glox { + +GloxCube::GloxCube( float x, float y, float z, const GloxColor& color ) : + m_color( color ) { + float halfx = x / 2; + float halfy = y / 2; + float halfz = z / 2; + + m_disp_list = glGenLists( 1 ); + GloxNormal<> normal(0,0,0); + glNewList( m_disp_list, GL_COMPILE ); + /* The points for the top */ + normal.setY( 1 ); + normal.plot(); + GloxPoint<> ( -halfx, halfy, halfz ).plot(); + GloxPoint<> ( halfx, halfy, halfz ).plot(); + GloxPoint<> ( halfx, halfy,-halfz ).plot(); + GloxPoint<> ( -halfx, halfy,-halfz ).plot(); + + /* The points for the bottom */ + normal.setY( -1 ); + normal.plot(); + GloxPoint<> ( -halfx,-halfy, halfz ).plot(); + GloxPoint<> ( halfx,-halfy, halfz ).plot(); + GloxPoint<> ( halfx,-halfy,-halfz ).plot(); + GloxPoint<> ( -halfx,-halfy,-halfz ).plot(); + normal.setY( 0 ) ; + + /* The points for the front */ + normal.setZ( 1 ); + normal.plot(); + GloxPoint<> ( -halfx, halfy, halfz ).plot(); + GloxPoint<> ( halfx, halfy, halfz ).plot(); + GloxPoint<> ( halfx,-halfy, halfz ).plot(); + GloxPoint<> ( -halfx,-halfy, halfz ).plot(); + + /* The points for the back */ + normal.setZ( -1 ); + normal.plot(); + GloxPoint<> ( -halfx, halfy,-halfz ).plot(); + GloxPoint<> ( halfx, halfy,-halfz ).plot(); + GloxPoint<> ( halfx,-halfy,-halfz ).plot(); + GloxPoint<> ( -halfx,-halfy,-halfz ).plot(); + normal.setZ( 0 ); + + /* The points for the right */ + normal.setX( 1 ); + normal.plot(); + GloxPoint<> ( halfx, -halfy, halfz ).plot(); + GloxPoint<> ( halfx, halfy, halfz ).plot(); + GloxPoint<> ( halfx, halfy,-halfz ).plot(); + GloxPoint<> ( halfx, -halfy,-halfz ).plot(); + + /* The points for the right */ + normal.setX( -1 ); + normal.plot(); + GloxPoint<> ( -halfx, -halfy, halfz ).plot(); + GloxPoint<> ( -halfx, halfy, halfz ).plot(); + GloxPoint<> ( -halfx, halfy,-halfz ).plot(); + GloxPoint<> ( -halfx, -halfy,-halfz ).plot(); + + glEndList(); +} + +void GloxCube::draw() const { + /* Save current attributes for this scope */ + GloxScopedAttributes __sca( GL_CURRENT_BIT ); + GloxScopedBegin __sbgn( GL_QUADS ); + + /* The normal to use for plotting */ + GloxNormal<> normal(0,0,0); + + /* Render this color */ + m_color.render(); + + glCallList( m_disp_list ); +} + +} diff --git a/glox/glox/src/GloxCylinder.cpp b/glox/glox/src/GloxCylinder.cpp new file mode 100644 index 0000000..3eb9840 --- /dev/null +++ b/glox/glox/src/GloxCylinder.cpp @@ -0,0 +1,56 @@ +#define COMPILING_CYLINDER +#include "glox/objects/examples/GloxCylinder.hpp" +#include "glox/GloxDebug.hpp" + +namespace glox { + +GloxCylinder::GloxCylinder( const GloxPoint<float>& pos, float r, float h, float th_res, const GloxTexture* texture, bool normals, float rep, float repy ) : + m_position( pos ) { + float th = 0; + m_texture = texture; + + GloxPoint<> point; + GloxNormal<> normal; + GloxPoint<> texPoint; + + float texStep; + + /* The position in the texture */ + float texPos = 0; + + if( m_texture ) { + /* We want the texture to map exactly + * to the sphere */ + texStep = th_res / 360 * rep; + } + + for( ; th <= 360; th += th_res, texPos += texStep ) { + point.setX( r * GloxCos( th ) ); + point.setZ( r * GloxSin( th ) ); + point.setY( 0 ); + + if( normals ) { + normal.setX( point.getX() ); + normal.setY( 0 ); + normal.setZ( point.getZ() ); + } + + texPoint.setX( texPos ); + texPoint.setY( repy ); + texPoint.setZ( 0 ); + + /* Add the new PointNormal to the + * body */ + m_body.addPoint( GloxPointNormalTexture( point, normal, texPoint ) ); + + /* The upper portion of the + * cylinder */ + point.setY( h ); + texPoint.setY( 0 ); + + // The normal remains the same + m_body.addPoint( GloxPointNormalTexture( point, normal, texPoint ) ); + } +} + +} diff --git a/glox/glox/src/GloxFirstPersonPerspective.cpp b/glox/glox/src/GloxFirstPersonPerspective.cpp new file mode 100644 index 0000000..6459286 --- /dev/null +++ b/glox/glox/src/GloxFirstPersonPerspective.cpp @@ -0,0 +1,31 @@ +#include "glox/GloxCommon.hpp" +#include "glox/GloxFirstPersonPerspective.hpp" +#include "glox/GloxState.hpp" +#include "glox/GloxDebug.hpp" + +#include <GL/glu.h> + +namespace glox { + +void GloxFirstPersonPerspective::render() const { + /* The point we are going to look at in first + * person mode */ + GloxPoint<> lookat = GloxPoint<>::fromSpherical( 1.0f, m_yaw, m_pitch ); + + /* translate the lookat to this + * position */ + const GloxPoint<>& pos = this->getPosition(); + GloxPoint<> upvec = GloxPoint<>::fromSpherical( 1.0f, GloxSin(m_roll) * m_yaw, GloxCos(m_roll) * m_pitch + 90 ); + lookat += pos; + + GloxTrace( "GloxFirstPersonPerspective", "gluLookAt %s %s %s\n", pos.toString().c_str(), lookat.toString().c_str(), upvec.toString().c_str() ); + GloxTrace( "GloxFirstPersonPerspective", "(%f, %f, %f)\n", m_roll, m_pitch, m_yaw ); + /* Deal with roll */ + + gluLookAt( pos.getX(), pos.getY(), pos.getZ(), + lookat.getX(), lookat.getY(), lookat.getZ(), + 0, 1, 0 ); + +} + +} diff --git a/glox/glox/src/GloxLightSource.cpp b/glox/glox/src/GloxLightSource.cpp new file mode 100644 index 0000000..9917d71 --- /dev/null +++ b/glox/glox/src/GloxLightSource.cpp @@ -0,0 +1,48 @@ +#include "glox/GloxLightSource.hpp" +#include "glox/GloxDebug.hpp" +namespace glox { + +void GloxLightSource::render() const { + if( ! this->isEnabled() ) { + GloxTrace( "GloxLightSource", "Light %d Disabled\n", index ); + return ; + } + + for( M_lm_map_t::const_iterator itr = lightModelsAttrs.begin(); + /* Set all of the attributes in the map */ + itr != lightModelsAttrs.end() ; ++ itr ) { + glLightModelf( (*itr).first, (*itr).second ); + } + + float vec[4]; + for( M_lm_map_vec_t::const_iterator itr = lightModelsAttrs_vectors.begin(); + /* Set all of the attributes in the map */ + itr != lightModelsAttrs_vectors.end() ; ++ itr ) { + (*itr).second.toVector( vec, 4 ); + glLightModelfv( (*itr).first, vec ); + } + + glEnable( m_light ); + + this->ambient.toVector( vec, 4 ); + //GloxTrace( "GloxLightSource", "ambient: {%f, %f, %f, %f}\n", vec[0], vec[1], vec[2], vec[3] ); + glLightfv(m_light,GL_AMBIENT, vec); + + this->diffuse.toVector( vec, 4 ); + //GloxTrace( "GloxLightSource", "diffuse: %s\n", this->diffuse.toString().c_str() ); + //GloxTrace( "GloxLightSource", "diffuse: {%f, %f, %f, %f}\n", vec[0], vec[1], vec[2], vec[3] ); + glLightfv(m_light,GL_DIFFUSE ,vec); + + this->specular.toVector( vec, 4 ); + //GloxTrace( "GloxLightSource", "specular: {%f, %f, %f, %f}\n", vec[0], vec[1], vec[2], vec[3] ); + glLightfv(m_light,GL_SPECULAR,vec); + + + /* enable this light */ + glEnable( this->m_light ); + this->m_pos.toVector( vec, 4 ); + + glLightfv(m_light,GL_POSITION,vec); +} + +} diff --git a/glox/glox/src/GloxLightSourceManager.cpp b/glox/glox/src/GloxLightSourceManager.cpp new file mode 100644 index 0000000..5ce2c0d --- /dev/null +++ b/glox/glox/src/GloxLightSourceManager.cpp @@ -0,0 +1,44 @@ +#include "glox/GloxLightSourceManager.hpp" +#include "glox/GloxState.hpp" +#include <iostream> + +using namespace std; +namespace glox { + +int light_source_gl[] = { + GL_LIGHT0, + GL_LIGHT1, + GL_LIGHT2, + GL_LIGHT2, + GL_LIGHT3, + GL_LIGHT4, + GL_LIGHT5, + GL_LIGHT6, + GL_LIGHT7, +}; + +void GloxLightSourceManager::render() const { + GloxState::enable( GL_NORMALIZE ); + GloxState::enable( GL_LIGHTING ); + GloxState::colorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); + GloxState::enable(GL_COLOR_MATERIAL); + + for ( size_t i = 0 ; i < GLOX_MAX_NUM_LIGHTS; ++ i ) { + if( m_sources[i] && m_sources[i]->isEnabled() ) { + m_sources[i]->render(); + } + } +} + +GloxLightSource* GloxLightSourceManager::getLightSource( int id ) { + if( m_sources[id] ) { + return m_sources[id]; + } + + GloxLightSource* lightSource = new GloxLightSource( light_source_gl[id] ); + m_sources[id] = lightSource; + + return lightSource; +} + +} diff --git a/glox/glox/src/GloxProgram.cpp b/glox/glox/src/GloxProgram.cpp new file mode 100644 index 0000000..df79bf0 --- /dev/null +++ b/glox/glox/src/GloxProgram.cpp @@ -0,0 +1,89 @@ +#include "glox/GloxProgram.hpp" + +#include <iostream> + +using namespace glox ; +using namespace std ; + +GloxProgram::GloxProgram( ) { + // cout << "Creating program2" << endl; + this->id = glCreateProgram() ; + // cout << "Done making program" << endl ; +} + +int GloxProgram::attachShader( const GloxShader& shader ) { + int shader_id = shader.getId() ; + glAttachShader( this->id, shader_id ) ; + return 0 ; +} + +int GloxProgram::attachShaderFromFile( const char* filename, GLenum type ) { + GloxShader shader( type ) ; + int ret = shader.load( filename ) ; + if( ! ret ) { + return this->attachShader( shader ); + } + return ret ; +} + +int GloxProgram::getUniformLocation( const char* uniform ) { + return glGetUniformLocation(this->id, uniform); +} + +void GloxProgram::render() const { + glUseProgram( this->id ); +} + +void setUniformVector3( int uniform, const std::vector< GloxVector3<> >& vec ) { + int len = vec.size() * 3 ; + float* arr = new float[len] ; + + for( size_t i = 0 ; i < vec.size() ; ++ i ) { + arr[i * 3 + 0] = vec[i].get0(); + arr[i * 3 + 1] = vec[i].get1(); + arr[i * 3 + 2] = vec[i].get2(); + } + + glUniform3fv(uniform, vec.size(), arr); +} + +void setUniformVector3( int uniform, const std::vector< GloxVector4<> >& vec ) { + int len = vec.size() * 4 ; + float* arr = new float[len] ; + + for( size_t i = 0 ; i < vec.size() ; ++ i ) { + arr[i * 4 + 0] = vec[i].get0(); + arr[i * 4 + 1] = vec[i].get1(); + arr[i * 4 + 2] = vec[i].get2(); + } + + glUniform4fv(uniform, vec.size(), arr); +} + +void GloxProgram::unloadPrograms() { + glUseProgram( 0 ) ; +} + +int GloxProgram::link() { + int result ; + glLinkProgram( id ); + glGetProgramiv( id , GL_LINK_STATUS, &result); + + if(result == GL_FALSE) { + GLint length; + char *log; + + /* get the program info log */ + glGetProgramiv( id , GL_INFO_LOG_LENGTH, &length); + log = new char[length]; + glGetProgramInfoLog( id , length, &result, log); + + /* print an error message and the info log */ + fprintf(stderr, "Program linking failed: %s\n", log); + free(log); + + return -1 ; + } + + return 0 ; +} diff --git a/glox/glox/src/GloxShader.cpp b/glox/glox/src/GloxShader.cpp new file mode 100644 index 0000000..3516189 --- /dev/null +++ b/glox/glox/src/GloxShader.cpp @@ -0,0 +1,71 @@ +#include "glox/GloxShader.hpp" + +#include <iostream> +#include <fstream> + +#include <sstream> + +using namespace glox ; +using namespace std ; + +string GloxShader::message ; + +int GloxShader::readFile( const char* filename, string& into ) { + ifstream stream ; + stream.open( filename ) ; + stringstream sstream ; + + std::string line ; + + if( ! stream ) { + message = string( "Unable to open file ") + filename + " for read" ; + return -1 ; + } + + while ( ! stream.eof() ) { + getline( stream, line ) ; + sstream << line << "\n" ; + } + + into = sstream.str(); + + return 0 ; +} + +int GloxShader::load( const char* filename) { + std::string contents ; + + if( readFile( filename, contents ) < 0 ) { + return -1 ; + } + + m_shader = glCreateShader( this->type ) ; + const char* source = contents.c_str(); + int len = contents.length(); + glShaderSource( m_shader, 1, & source, &len ) ; + glCompileShader( m_shader ) ; + + int result, length ; + glGetShaderiv(m_shader, GL_COMPILE_STATUS, &result); + if( result == GL_FALSE ) { + char *log; + + glGetShaderiv(m_shader, GL_INFO_LOG_LENGTH, &length); + log = new char[length]; + glGetShaderInfoLog(m_shader, length, &result, log); + + fprintf(stderr, "shaderCompileFromFile(): Unable to compile %s: %s\n", filename, log); + free(log); + + glDeleteShader(m_shader); + + cerr << "Returning with error code -1" << endl ; + return -1 ; + } + + return 0 ; +} + +GloxShader::~GloxShader() { + glDeleteShader( m_shader ) ; +} diff --git a/glox/glox/src/GloxTextureFactory.cpp b/glox/glox/src/GloxTextureFactory.cpp new file mode 100644 index 0000000..4cb5904 --- /dev/null +++ b/glox/glox/src/GloxTextureFactory.cpp @@ -0,0 +1,142 @@ +#include "glox/GloxTextureFactory.hpp" +#include "glox/GloxTexture.hpp" +#include "glox/GloxCommon.hpp" + +#include "glox/GloxDebug.hpp" + +#include <sstream> +#include <GL/glu.h> + +#define BMP_MAGIC_LE 0x4D42 +#define BMP_MAGIC_BE 0x424D + +using namespace std; + +namespace glox { + +static void revendian(void* x,const int n) { + int k; + char* ch = (char*)x; + for (k=0;k<n/2;k++) + { + char tmp = ch[k]; + ch[k] = ch[n-1-k]; + ch[n-1-k] = tmp; + } +} + +std::string error_str; + +const std::string& GloxTextureFactory::getErrorMessage() { + return error_str; +} + +GloxTexture* GloxTextureFactory::textureFromBitmap( std::istream& stream ) { + unsigned int texture; + unsigned short magic; + unsigned int dx,dy,size; + unsigned short nbp,bpp; + unsigned char* image; + unsigned int k; + int max; + + stream.read( (char*)&magic, 2 ); + + if( magic != BMP_MAGIC_LE && magic != BMP_MAGIC_BE ) { + error_str = "Bad magic number for bitmap\n"; + return NULL; + } + + stream.seekg( 16, stream.cur ); + stream.read( (char*)&dx, 4 ); + stream.read( (char*)&dy, 4 ); + stream.read( (char*)&nbp, 2 ); + stream.read( (char*)&bpp, 2 ); + stream.read( (char*)&k, 4 ); + + GloxTrace( "GloxTextureFactory", "dx = %d, dy = %d, nbp = %d, bpp = %d, k = %d\n", + dx, dy, nbp, bpp, k ); + + if( magic == BMP_MAGIC_BE ) { + revendian( &dx, sizeof( dx ) ); + revendian( &dy, sizeof( dy ) ); + revendian( &nbp, sizeof( nbp ) ); + revendian( &bpp, sizeof( bpp ) ); + revendian( &k, sizeof( k ) ); + } + + glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max ); + + stringstream error; + + if ( dx < 1 || dx > (unsigned int)max) { + error << "Image width " << dx << " out of range 1-" << max << "\n"; + error_str = error.str(); + return NULL; + } + if ( dy < 1 || dy > (unsigned int)max) { + error << "Image height " << dy << " out of range 1-" << max << "\n"; + error_str = error.str(); + return NULL; + } + if ( nbp != 1) { + error << "Bit planes is not 1: " << nbp << "\n"; + error_str = error.str(); + return NULL; + } + if ( bpp != 24) { + error << "Bits per pixel is not 24: " << bpp << "\n"; + error_str = error.str(); + return NULL; + } + if ( k != 0) { + error_str = "Compressed files not supported\n"; + return NULL; + } + + size = 3 * dx * dy; + image = new uint8_t[size]; + + if( ! image ) { + error_str = "Not enough memory for image\n"; + return NULL; + } + + stream.seekg( 20, stream.cur ); + stream.read( (char*)image, size ); + for( k = 0; k < size; k += 3 ) { + uint8_t temp = image[k]; + image[k] = image[k+2]; + image[k+2] = temp; + } + + int err = glGetError(); + if (err){ + error_str = std::string((char*)gluErrorString(err)); + delete[] image; + return NULL; + } + + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_2D, texture ); + glTexImage2D( GL_TEXTURE_2D, 0, 3, dx, dy, 0, GL_RGB, GL_UNSIGNED_BYTE, image ); + + err = glGetError(); + if( err ) { + error_str = std::string((char*)gluErrorString(err)); + delete[] image; + return NULL; + } + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + GloxDebug( "GloxTextureFactory", "Loaded Texture. First pixel: (%d, %d, %d)\n", + image[0], image[1], image[2] ); + + delete[] image; + + return new GloxTexture( texture ); +} + +}; diff --git a/glox/glox/src/GloxTexturedCube.cpp b/glox/glox/src/GloxTexturedCube.cpp new file mode 100644 index 0000000..f56e146 --- /dev/null +++ b/glox/glox/src/GloxTexturedCube.cpp @@ -0,0 +1,175 @@ +#include "glox/objects/GloxTexturedCube.hpp" +#include "glox/GloxScopedBegin.hpp" + +namespace glox { + +void GloxTexturedCube::update_top() { + m_top.clear(); + + GloxNormal<> normal( 0, 1, 0 ); + + /* The points for the top */ + m_top.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half,-m_half), + normal, GloxPoint<>(0,0)) ); + + m_top.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half,-m_half), + normal, GloxPoint<>(m_top_tex.getXReps(),0)) ); + + m_top.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half, m_half), + normal, GloxPoint<>(m_top_tex.getXReps(),m_top_tex.getYReps())) ); + + m_top.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half, m_half), + normal, GloxPoint<>(0,m_top_tex.getYReps())) ); +} + +void GloxTexturedCube::update_bottom() { + m_bottom.clear(); + + GloxNormal<> normal( 0, -1, 0 ); + + /* The points for the top */ + m_bottom.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half, m_half), + normal, GloxPoint<>(0,0)) ); + + m_bottom.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half, m_half), + normal, GloxPoint<>(m_bottom_tex.getXReps(),0)) ); + + m_bottom.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half,-m_half), + normal, GloxPoint<>(m_bottom_tex.getXReps(),m_bottom_tex.getYReps())) ); + + m_bottom.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half,-m_half), + normal, GloxPoint<>(0,m_bottom_tex.getYReps())) ); +} + +void GloxTexturedCube::update_front() { + m_front.clear(); + + GloxNormal<> normal( 0, 0, 1 ); + + /* The points for the top */ + m_front.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half, m_half), + normal, GloxPoint<>(0,0)) ); + + m_front.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half, m_half), + normal, GloxPoint<>(m_front_tex.getXReps(),0)) ); + + m_front.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half, m_half), + normal, GloxPoint<>(m_front_tex.getXReps(),m_front_tex.getYReps())) ); + + m_front.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half, m_half), + normal, GloxPoint<>(0,m_front_tex.getYReps())) ); +} + +void GloxTexturedCube::update_back() { + m_back.clear(); + + GloxNormal<> normal( 0, 0, -1 ); + + /* The points for the back */ + m_back.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half,-m_half), + normal, GloxPoint<>(0,0)) ); + + m_back.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half,-m_half), + normal, GloxPoint<>(m_back_tex.getXReps(),0)) ); + + m_back.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half,-m_half), + normal, GloxPoint<>(m_back_tex.getXReps(),m_front_tex.getYReps())) ); + + m_back.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half,-m_half), + normal, GloxPoint<>(0,m_back_tex.getYReps())) ); +} + +void GloxTexturedCube::update_right() { + m_right.clear(); + + GloxNormal<> normal( 1, 0, 0 ); + + /* The points for the right */ + m_right.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half, m_half), + normal, GloxPoint<>(0,0)) ); + + m_right.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half, m_half), + normal, GloxPoint<>(m_right_tex.getXReps(),0)) ); + + m_right.add( GloxPointNormalTexture( GloxPoint<>( m_half, m_half,-m_half), + normal, GloxPoint<>(m_right_tex.getXReps(),m_front_tex.getYReps())) ); + + m_right.add( GloxPointNormalTexture( GloxPoint<>( m_half,-m_half,-m_half), + normal, GloxPoint<>(0,m_right_tex.getYReps())) ); +} + +void GloxTexturedCube::update_left() { + m_left.clear(); + + GloxNormal<> normal( -1, 0, 0 ); + + /* The points for the left */ + m_left.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half, m_half), + normal, GloxPoint<>(0,0)) ); + + m_left.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half, m_half), + normal, GloxPoint<>(m_left_tex.getXReps(),0)) ); + + m_left.add( GloxPointNormalTexture( GloxPoint<>(-m_half, m_half,-m_half), + normal, GloxPoint<>(m_left_tex.getXReps(),m_front_tex.getYReps())) ); + + m_left.add( GloxPointNormalTexture( GloxPoint<>(-m_half,-m_half,-m_half), + normal, GloxPoint<>(0,m_left_tex.getYReps())) ); +} + +GloxTexturedCube::GloxTexturedCube( float size, const GloxColor& color, + const GloxTextureRepeat& topTex , + const GloxTextureRepeat& botTex , + const GloxTextureRepeat& frontTex , + const GloxTextureRepeat& backTex , + const GloxTextureRepeat& leftTex , + const GloxTextureRepeat& rightTex ) : + + m_top_tex( topTex ) , m_bottom_tex( botTex ), m_front_tex( frontTex ), + m_back_tex( backTex ), m_left_tex( leftTex ), m_right_tex( rightTex ), + m_color( color ) { + m_half = size / 2; + + update_top(); + update_bottom(); + update_front(); + update_back(); + update_left(); + update_right(); +} + +inline void GloxTexturedCube::plot_with( const _M_Square& face, const GloxTextureRepeat& tex ) const { + if( tex.isNull() ) { + glDisable( GL_TEXTURE_2D ); + } else { + tex.getTexture()->bind(); + glEnable( GL_TEXTURE_2D ); + } + + glBegin( GL_QUADS ); + face.plot(); + glEnd(); + + glDisable( GL_TEXTURE_2D ); +} + +void GloxTexturedCube::draw() const { + /* Save current attributes for this scope */ + GloxScopedAttributes __sca( GL_CURRENT_BIT ); + //GloxScopedBegin __sbgn( GL_QUADS ); + + /* The normal to use for plotting */ + GloxNormal<> normal(0,0,0); + + /* Render this color */ + m_color.render(); + + plot_with(m_right, m_right_tex); + plot_with(m_left, m_left_tex); + plot_with(m_top, m_top_tex); + plot_with(m_bottom, m_bottom_tex); + plot_with(m_front, m_front_tex); + plot_with(m_back, m_back_tex); +} + +} diff --git a/glox/glox/src/GloxTexturedSphere.cpp b/glox/glox/src/GloxTexturedSphere.cpp new file mode 100644 index 0000000..f718497 --- /dev/null +++ b/glox/glox/src/GloxTexturedSphere.cpp @@ -0,0 +1,52 @@ +#include "glox/objects/GloxTexturedSphere.hpp" +#include "glox/GloxCommon.hpp" +#include "glox/GloxPoint.hpp" +#include "glox/GloxNormal.hpp" +#include "glox/GloxPointNormalTexture.hpp" +#include "glox/GloxScopedAttributes.hpp" + +namespace glox { + +static void m_vertex( float th, float ph ) { + GloxPoint<> point = GloxPoint<>::fromSpherical( 1, th, ph ); + GloxNormal<> normal( point.getX(), point.getY(), point.getZ() ); + GloxPoint<> texPoint( th/360.0, ph/180.0 + 0.5 ); + + GloxPointNormalTexture( point, normal, texPoint ).plot(); +} + +GloxTexturedSphere::GloxTexturedSphere( float radius, float res, const GloxTexture& texture ) { + m_radius = radius; + m_texture = texture; + + /* Generate the display list */ + m_disp_list = glGenLists( 1 ); + glNewList( m_disp_list, GL_COMPILE ); + + float ph, th; + for ( ph = -90 ; ph < 90 ; ph += res ) { + GloxWith( GL_QUAD_STRIP, + for ( th = 0 ; th <= 360 ; th += res ) { + m_vertex(th,ph); + m_vertex(th,ph+res); + } + ); + } + + glEndList(); +} + +void GloxTexturedSphere::draw() const { + glPushMatrix(); + GloxEnableFor( GL_TEXTURE_2D, + glScalef( m_radius, m_radius, m_radius ); + /* Bind the texture */ + m_texture.bind(); + + /* Call the display list */ + glCallList( m_disp_list ); + ); + glPopMatrix(); +} + +} 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; +} + +} |