diff options
| author | Joshua Rahm <joshua.rahm@colorado.edu> | 2013-11-23 20:27:01 -0700 |
|---|---|---|
| committer | Joshua Rahm <joshua.rahm@colorado.edu> | 2013-11-23 20:27:01 -0700 |
| commit | 7be3bda2b664068bf47404278fa9ee1ce552ea0e (patch) | |
| tree | a50683398c8f011c9aba39cab7aee6246bcc029b /sons_of_sol | |
| parent | 88d0215624de994b4456c8eac537262118ffed52 (diff) | |
| download | SonsOfSol-7be3bda2b664068bf47404278fa9ee1ce552ea0e.tar.gz SonsOfSol-7be3bda2b664068bf47404278fa9ee1ce552ea0e.tar.bz2 SonsOfSol-7be3bda2b664068bf47404278fa9ee1ce552ea0e.zip | |
Got application to a point of displaying model objects
Diffstat (limited to 'sons_of_sol')
| -rw-r--r-- | sons_of_sol/ControlMotionEvent.hpp | 65 | ||||
| -rw-r--r-- | sons_of_sol/ControlMotionListener.hpp | 20 | ||||
| -rw-r--r-- | sons_of_sol/ControlMultiplexer.hpp | 95 | ||||
| -rw-r--r-- | sons_of_sol/PlayerShip.hpp | 125 | ||||
| -rw-r--r-- | sons_of_sol/SonsOfSolApplication.hpp | 56 | ||||
| -rw-r--r-- | sons_of_sol/private_db/ControlMultiplexer.cpp | 58 | ||||
| -rw-r--r-- | sons_of_sol/private_db/PlayerShip.cpp | 103 | ||||
| -rw-r--r-- | sons_of_sol/private_db/SonsOfSolApplication.cpp | 202 |
8 files changed, 684 insertions, 40 deletions
diff --git a/sons_of_sol/ControlMotionEvent.hpp b/sons_of_sol/ControlMotionEvent.hpp new file mode 100644 index 0000000..5a93a69 --- /dev/null +++ b/sons_of_sol/ControlMotionEvent.hpp @@ -0,0 +1,65 @@ +#ifndef CONTROLMOTIONEVENT_HPP_ +#define CONTROLMOTIONEVENT_HPP_ + +/* + * Author: jrahm + * created: 2013/11/01 + * ControlMotionEvent.hpp: <description> + */ + +/* This is the class used to + * signal an event from the controller. + * + * These values have been normalized */ +class ControlMotionEvent { +public: + enum MotionEventType { + NONE + , PITCH + , ROLL + , YAW + , THROTTLE + , STRAFE_SIDE + , STRAFE_UP + , FIRE_PRIMARY + }; + + enum MotionOrigin { + JOYSTICK, + MOUSE, + BUTTON + }; + + ControlMotionEvent( MotionEventType type, double mag, MotionOrigin origin ) : + mag( mag ), type( type ), origin( origin ) {} + + inline double getMagnitude() const { + return mag; + } + + inline MotionEventType getType() const { + return type; + } + + inline MotionOrigin getOrigin() const { + return origin; + } + + inline void setMagnitude( double mag ) { + this->mag = mag; + } + + inline void setType( MotionEventType type ) { + this->type = type; + } + + inline void setOrigin( MotionOrigin origin ) { + this->origin = origin; + } +private: + double mag; + MotionEventType type; + MotionOrigin origin; +}; + +#endif /* CONTROLMOTIONEVENT_HPP_ */ diff --git a/sons_of_sol/ControlMotionListener.hpp b/sons_of_sol/ControlMotionListener.hpp new file mode 100644 index 0000000..8269ebe --- /dev/null +++ b/sons_of_sol/ControlMotionListener.hpp @@ -0,0 +1,20 @@ +#ifndef CONTROLMOTIONLISTENER_HPP_ +#define CONTROLMOTIONLISTENER_HPP_ + +/* + * Author: jrahm + * created: 2013/11/01 + * ControlMotionListener.hpp: <description> + */ + +#include "sons_of_sol/ControlMotionEvent.hpp" + +class ControlMotionListener { +public: + /* Called once there is a control motion */ + virtual inline void onControlMotion( const ControlMotionEvent& event ) { + (void) event; + } +}; + +#endif /* CONTROLMOTIONLISTENER_HPP_ */ diff --git a/sons_of_sol/ControlMultiplexer.hpp b/sons_of_sol/ControlMultiplexer.hpp new file mode 100644 index 0000000..33ae28d --- /dev/null +++ b/sons_of_sol/ControlMultiplexer.hpp @@ -0,0 +1,95 @@ +#ifndef CONTROLMULTIPLEXER_HPP_ +#define CONTROLMULTIPLEXER_HPP_ + +/* + * Author: jrahm + * created: 2013/11/01 + * ControlMultiplexer.hpp: + * + * Listens to multiple events and multiplexes them + * into a single movement event for the ship + */ + +#include "slox/events/SloxKeyListener.hpp" +#include "slox/events/SloxMouseMotionListener.hpp" + +#include "sons_of_sol/ControlMotionEvent.hpp" +#include "sons_of_sol/ControlMotionListener.hpp" + +#include <map> +#include <vector> + +class ControlMultiplexer : + public slox::SloxKeyListener, + public slox::SloxMouseMotionListener { +public: + /* Construct a new control multiplexer */ + ControlMultiplexer(); + + /* Adds a listener to this ControlMultiplexer */ + inline void addControlMotionListener( ControlMotionListener* listener ) { + m_motion_listeners.push_back( listener ); + } + + /* Called when a key is released. This event will be converted + * into ControlMotionEvent and sent */ + virtual void onKeyUp( const SDL_KeyboardEvent& evt ) ; + + /* Called when there was a key press. This event may be converted + * into ControlMotionEvent which is then sent off to all + * the listeners. If there is no mapping then the motion + * event is not sent */ + virtual void onKeyDown( const SDL_KeyboardEvent& evt ) ; + + /* Called when the mouse is moved. This + * is interpreted as a joystick event */ + virtual void onMouseMoved( const SDL_MouseMotionEvent& evt ); + + /* Called when there is an event that is called */ + void fireControlEvent( const ControlMotionEvent& evt ); + + /* Adds a mapping from a key to a MotionEventType. Keys are represented + * as a 1 for pressed and 0 for not pressed, so some normalization must + * be done with a joystick in order to received the desired results */ + inline void setKeyMapping( SDLKey key, ControlMotionEvent::MotionEventType to, float mult=1.0f ) { + m_keysym_map[ key ] = M_MapVal( to, mult );; + } + + /* Removes a mapping from this multiplexer, such that + * a key of this type pressed will no longer fire that + * event */ + inline void removeKeyMapping( SDLKey key ) { + m_keysym_map.erase( key ); + } + + /* Sets a joystick axis mapping. If the joystick_index = 255 then it + * is interpreted as the mouse */ + inline void setJoyAxisMapping( uint8_t joystick_index, uint8_t axis_index, + ControlMotionEvent::MotionEventType to, float mult=1.0f ) { + m_joy_axis_map[ joystick_index << 8 | axis_index ] = M_MapVal( to, mult ); + } + + inline void removeJoyAxisMapping( uint8_t joystick_index, uint8_t axis_index ) { + m_joy_axis_map.erase( joystick_index << axis_index ); + } + +private: + struct M_MapVal { + inline M_MapVal( ControlMotionEvent::MotionEventType typ, float mult ) : + type( typ ), multiplier( mult ) {} + inline M_MapVal( ) : type( ControlMotionEvent::NONE ), multiplier( 0.0f ) {} + ControlMotionEvent::MotionEventType type; + float multiplier; + }; + /* The listeners on this multiplexer */ + std::vector< ControlMotionListener* > m_motion_listeners; + + /* The keysym map */ + std::map< SDLKey, M_MapVal > m_keysym_map; + + /* Mapping of a bit oring of joystick index and axis index to + * an event type */ + std::map< uint16_t, M_MapVal > m_joy_axis_map; +}; + +#endif /* CONTROLMULTIPLEXER_HPP_ */ diff --git a/sons_of_sol/PlayerShip.hpp b/sons_of_sol/PlayerShip.hpp new file mode 100644 index 0000000..ea5f178 --- /dev/null +++ b/sons_of_sol/PlayerShip.hpp @@ -0,0 +1,125 @@ +#ifndef SHIP_HPP_ +#define SHIP_HPP_ + +/* + * Author: jrahm + * created: 2013/10/31 + * Ship.hpp: <description> + */ + +#include "glox/GloxPoint.hpp" +#include "glox/GloxVector3.hpp" +#include "glox/GloxLookAtPerspective.hpp" + +#include "slox/events/SloxKeyListener.hpp" + +#include "ControlMotionListener.hpp" + +/* This is a class + * for the first person + * ship */ +class PlayerShip : public ControlMotionListener { +public: + inline PlayerShip() : + m_forward( 0, 0, -1 ), m_up( 0, 1, 0 ), m_right( 1, 0, 0 ), + m_dpitch( 0 ), + m_dyaw( 0 ), + m_droll( 0 ), + m_dforward( 0 ), + m_dup( 0 ), + m_dright( 0 ) {} + + /* Draw the heads-up-display of the + * ship */ + void drawHUD(); + + /* Render the perspective of + * this ship */ + void renderPerspective(); + + /* Move the ship up and down */ + void pitch( float angle ); + + /* Roll the ship */ + void roll( float angle ); + + /* Rotate the ship side to side */ + void yaw( float angle ); + + /* Update this object */ + void update(); + + const glox::GloxStandardProjection& getPerspective( ) const { + return m_perspective; + } + + glox::GloxStandardProjection& getPerspective( ) { + return m_perspective; + } + + void setPerspective( const glox::GloxLookAtPerspective& perspective ) { + m_perspective = perspective; + } + + inline void setDPitch( float dpitch ) { + this->m_dpitch = dpitch; + } + + inline void setDRoll( float droll ) { + this->m_droll = droll; + } + + inline void setDYaw( float dyaw ) { + this->m_dyaw = dyaw; + } + + inline float getDPitch() const { + return m_dpitch; + } + + inline float getDYaw() const { + return m_dyaw; + } + + inline float getDRoll() const { + return m_droll; + } + + virtual void onControlMotion( const ControlMotionEvent& evt ); + + inline const glox::GloxPoint<> getPosition() const { + return m_position; + } + + inline void setPosition( const glox::GloxPoint<>& pos ) { + m_position = pos; + } +private: + /* The position of the ship */ + glox::GloxPoint<> m_position; + + /* The orientation of the ship */ + glox::GloxVector3<> m_forward; + glox::GloxVector3<> m_up; + glox::GloxVector3<> m_right; + + /* The perspective of the ship */ + glox::GloxLookAtPerspective m_perspective; + + float m_dpitch; + float m_dyaw; + + float m_droll; + float m_droll_to; + + float m_dforward; + float m_dforward_to; + + float m_dup; + float m_dup_to; + + float m_dright; + float m_dright_to; +}; + +#endif /* SHIP_HPP_ */ diff --git a/sons_of_sol/SonsOfSolApplication.hpp b/sons_of_sol/SonsOfSolApplication.hpp index 1faeaa4..6c1afeb 100644 --- a/sons_of_sol/SonsOfSolApplication.hpp +++ b/sons_of_sol/SonsOfSolApplication.hpp @@ -16,26 +16,42 @@ #include "glox/GloxCommon.hpp" #include "glox/GloxFirstPersonPerspective.hpp" #include "glox/objects/GloxTexturedCube.hpp" +#include "glox/objects/GloxTexturedSphere.hpp" #include "glox/GloxColor.hpp" #include "glox/GloxLookAtPerspective.hpp" #include "glox/GloxLightSourceManager.hpp" +#include "glox/objects/GloxCube.hpp" +#include "slox/loader/SloxModelObject.hpp" +#include "slox/loader/SloxObjectLoader.hpp" + +#include "sons_of_sol/PlayerShip.hpp" +#include "sons_of_sol/ControlMultiplexer.hpp" class SonsOfSolApplication : public slox::SloxApplication, slox::SloxRawEventHandler, + slox::SloxResizeListener, + slox::SloxKeyListener, slox::SloxQuitListener { public: /* Process an event */ - inline void onEvent( const SDL_Event& event ) + virtual inline void onEvent( const SDL_Event& event ) { SloxRawEventHandler::onEvent( event ); } + virtual inline void onKeyDown( const SDL_KeyboardEvent& evt ) { + if( evt.keysym.sym == SDLK_ESCAPE ) exit( 0 ); + if( evt.keysym.sym == SDLK_f ) { + setFullScreen(); + }; + } + /* Initializes this application; * returns true if initialization * succeeded, false otherwise */ - bool initialize( int argc, char** argv ); + virtual bool initialize( int argc, char** argv ); /* The main loop of the application */ - bool loop( uint32_t ticks ) { + virtual bool loop( uint32_t ticks ) { /* Update things that we might * want to */ update( ticks ); @@ -59,7 +75,7 @@ public: /* What happens when a quit event is * intercepted */ - inline void onQuit( const SDL_QuitEvent& evt ) { + virtual inline void onQuit( const SDL_QuitEvent& evt ) { (void) evt; m_quit = true; } @@ -68,19 +84,21 @@ public: } -private: - /* Resizes the perspective for OpenGL */ + inline void onResize( const SDL_ResizeEvent& evt ) { + m_screen = SDL_SetVideoMode(evt.w,evt.h,0,SDL_OPENGL|SDL_RESIZABLE|SDL_DOUBLEBUF); + reshape( evt.w, evt.h ); + } +private: + void setupControls() ; void reshape( int width, int height ); /* Sets up the lights to be used */ void enableLighting( ); - void update( uint32_t ticks ); - void display( ) ; - bool loadTextures(); + void setFullScreen(); /* perspective stuff */ glox::GloxViewport m_viewport; @@ -88,19 +106,37 @@ private: /* The sky */ glox::GloxTexturedCube* m_sky; + glox::GloxTexturedCube* m_crate; + glox::GloxTexturedSphere* m_earth; /* Textures */ glox::GloxTexture m_sky_tex; glox::GloxTexture m_leaf_tex; - glox::GloxTexture m_cube_tex; + glox::GloxTexture m_crate_tex; + glox::GloxTexture m_star_tex; + glox::GloxTexture m_earth_tex; + /* The sun */ + glox::GloxPointCollection<glox::GloxPointNormalTexture> m_star; + + /* The little test object */ + slox::SloxModelObject* m_probe; + slox::SloxModelObject* m_frigate_industrial; + + slox::SloxTextureFactory m_texture_factory; + slox::SloxObjectLoader m_object_loader; /* A boolean stating if it is time * to quit */ bool m_quit; glox::GloxLightSourceManager m_light_manager; + PlayerShip m_ship; SDL_Surface* m_screen; + ControlMultiplexer m_event_multiplexer; + + int m_screen_width; + int m_screen_height; }; #endif /* SONSOFSOLAPPLICATION_HPP_ */ diff --git a/sons_of_sol/private_db/ControlMultiplexer.cpp b/sons_of_sol/private_db/ControlMultiplexer.cpp new file mode 100644 index 0000000..97ae2f4 --- /dev/null +++ b/sons_of_sol/private_db/ControlMultiplexer.cpp @@ -0,0 +1,58 @@ +#include "sons_of_sol/ControlMultiplexer.hpp" + +ControlMultiplexer::ControlMultiplexer() { + +} + +void ControlMultiplexer::onKeyUp( const SDL_KeyboardEvent& evt ) { + std::map< SDLKey, M_MapVal >::iterator itr; + itr = m_keysym_map.find( evt.keysym.sym ); + + if( itr != m_keysym_map.end() ) { + ControlMotionEvent event( (*itr).second.type, 0, ControlMotionEvent::BUTTON ); + fireControlEvent( event ); + } +} + +void ControlMultiplexer::onKeyDown( const SDL_KeyboardEvent& evt ) { + std::map< SDLKey, M_MapVal >::iterator itr; + itr = m_keysym_map.find( evt.keysym.sym ); + + if( itr != m_keysym_map.end() ) { + ControlMotionEvent event( (*itr).second.type, 1 * (*itr).second.multiplier, ControlMotionEvent::BUTTON ); + fireControlEvent( event ); + } +} + +void ControlMultiplexer::onMouseMoved( const SDL_MouseMotionEvent& evt ) { + std::map< uint16_t, M_MapVal >::iterator itr; + /* x direction on mousepad */ + itr = m_joy_axis_map.find( 0xFF00 ); + const SDL_VideoInfo* info = SDL_GetVideoInfo(); //<-- calls SDL_GetVideoInfo(); + int screen_width = info->current_w; + int screen_height = info->current_h; + + float x_norm = (evt.x - screen_width / 2) / ((float) screen_width / 2.0); + if( itr != m_joy_axis_map.end() ) { + ControlMotionEvent event( itr->second.type, x_norm * (*itr).second.multiplier, + ControlMotionEvent::MOUSE ); + fireControlEvent( event ); + } + + /* y direction */ + float y_norm = (evt.y - screen_height / 2) / ((float) screen_height / 2.0); + itr = m_joy_axis_map.find( 0xFF01 ); + if( itr != m_joy_axis_map.end() ) { + ControlMotionEvent event( itr->second.type, y_norm * (*itr).second.multiplier, + ControlMotionEvent::MOUSE ); + fireControlEvent( event ); + } +} + +void ControlMultiplexer::fireControlEvent( const ControlMotionEvent& evt ) { + std::vector< ControlMotionListener* >::iterator itr; + + for( itr = m_motion_listeners.begin(); itr != m_motion_listeners.end() ; ++ itr ) { + (*itr)->onControlMotion( evt ); + } +} diff --git a/sons_of_sol/private_db/PlayerShip.cpp b/sons_of_sol/private_db/PlayerShip.cpp new file mode 100644 index 0000000..f8d8ec1 --- /dev/null +++ b/sons_of_sol/private_db/PlayerShip.cpp @@ -0,0 +1,103 @@ +#include "sons_of_sol/PlayerShip.hpp" + +#include "glox/GloxCommon.hpp" +#include "glox/GloxColor.hpp" + +using namespace glox; + + +void PlayerShip::pitch( float angle ) { + /* Update the forward vector */ + m_forward *= (float)GloxCos( angle ); + m_forward += ( m_up * (float)GloxSin( angle ) ); + m_forward.normalize(); + + m_up = m_right.cross( m_forward ); +} + +void PlayerShip::roll( float angle ) { + m_right *= (float)GloxCos( angle ); + m_right += m_up * GloxSin( angle ); + m_right.normalize(); + + m_up = m_right.cross( m_forward ); +} + +void PlayerShip::yaw( float angle ) { + m_right *= (float)GloxCos( angle ); + m_right += m_forward * GloxSin( angle ); + m_right.normalize(); + + m_forward = m_up.cross( m_right ); +} + +void PlayerShip::renderPerspective( ) { + m_perspective.setLookAtPoint( m_position + m_forward.toPoint() ); + m_perspective.setPosition( m_position + (m_forward.toPoint() * 0.2f) ); + m_perspective.setUpVector( m_up.toPoint() ); + + GloxColor( 255,255,255 ).render(); + GloxWith( GL_LINES, + GloxPoint<>( 0,0,0 ).plot(); + m_position.plot() ); +} + +void PlayerShip::drawHUD() { + +} + +static inline float update_val( float to, float x, int inertia ) { + return ( to + (inertia - 1) * x ) / inertia; +} + +void PlayerShip::onControlMotion( const ControlMotionEvent& evt ) { + //printf( "Event Mag: %f\n", evt.getMagnitude() ); + + if( evt.getType() == ControlMotionEvent::PITCH ) { + m_dpitch = update_val( evt.getMagnitude(), m_dpitch, 10 ); + } + + if( evt.getType() == ControlMotionEvent::THROTTLE ) { + m_dforward_to = evt.getMagnitude(); + } + + if( evt.getType() == ControlMotionEvent::YAW ) { + m_dyaw = update_val( evt.getMagnitude(), m_dyaw, 10 ); + } + + if( evt.getType() == ControlMotionEvent::ROLL ) { + m_droll_to = evt.getMagnitude(); + } + + if( evt.getType() == ControlMotionEvent::STRAFE_SIDE ) { + m_dright_to = evt.getMagnitude(); + } + + if( evt.getType() == ControlMotionEvent::STRAFE_UP ) { + m_dup_to = evt.getMagnitude(); + } +} + +void PlayerShip::update() { + // printf( "dpitch: %f, droll: %f, dyaw: %f, dforward: %f, dright: %f, dup: %f\n", + // m_dpitch, m_droll, m_dyaw, m_dforward, m_dright, m_dup ); + + pitch( m_dpitch ); + roll( m_droll ); + yaw( m_dyaw ); + + m_position += (m_forward * m_dforward).toPoint(); + m_position += (m_right * m_dright).toPoint(); + m_position += (m_up * m_dup).toPoint(); + + m_droll = update_val( m_droll_to, m_droll, 20 ); + m_dup = update_val( m_dup_to, m_dup, 20 ); + m_dright = update_val( m_dright_to, m_dright, 20 ); + m_dforward = update_val( m_dforward_to, m_dforward, 200 ); + + // This is only the case if we are using a mouse + m_dpitch = update_val( 0, m_dpitch, 100 ); + m_dyaw = update_val( 0, m_dyaw, 100 ); + // m_droll = (m_droll_to * ( 1 - exp( - m_droll_count ) ) + m_droll * ( 1 - exp( - m_droll_count ) ) )/ 2.0; + renderPerspective(); +} diff --git a/sons_of_sol/private_db/SonsOfSolApplication.cpp b/sons_of_sol/private_db/SonsOfSolApplication.cpp index f6a52c2..c49ae07 100644 --- a/sons_of_sol/private_db/SonsOfSolApplication.cpp +++ b/sons_of_sol/private_db/SonsOfSolApplication.cpp @@ -1,17 +1,74 @@ #include "sons_of_sol/SonsOfSolApplication.hpp" #include "glox/GloxLightSource.hpp" +#include "glox/GloxRotation.hpp" +#include "glox/GloxScopedRotation.hpp" + +#include <iostream> using namespace slox; using namespace glox; +using namespace std; + +void SonsOfSolApplication::setupControls() { + m_event_multiplexer.setKeyMapping( SDLK_w, ControlMotionEvent::THROTTLE, 5.0f ); + m_event_multiplexer.setKeyMapping( SDLK_s, ControlMotionEvent::THROTTLE, -5.0f ); + m_event_multiplexer.setKeyMapping( SDLK_d, ControlMotionEvent::STRAFE_SIDE ); + m_event_multiplexer.setKeyMapping( SDLK_a, ControlMotionEvent::STRAFE_SIDE, -1.0f ); + m_event_multiplexer.setKeyMapping( SDLK_z, ControlMotionEvent::STRAFE_UP, -1.0f ); + m_event_multiplexer.setKeyMapping( SDLK_x, ControlMotionEvent::STRAFE_UP, 0.3f ); + + m_event_multiplexer.setKeyMapping( SDLK_q, ControlMotionEvent::ROLL, 2.0f ); + m_event_multiplexer.setKeyMapping( SDLK_e, ControlMotionEvent::ROLL, -2.0f ); + m_event_multiplexer.setKeyMapping( SDLK_k, ControlMotionEvent::PITCH ); + m_event_multiplexer.setKeyMapping( SDLK_j, ControlMotionEvent::PITCH, -1.0f ); + m_event_multiplexer.setKeyMapping( SDLK_l, ControlMotionEvent::YAW, -1.0f ); + m_event_multiplexer.setKeyMapping( SDLK_h, ControlMotionEvent::YAW ); + + m_event_multiplexer.setJoyAxisMapping( 255, 0, ControlMotionEvent::YAW, -1.0f ); + m_event_multiplexer.setJoyAxisMapping( 255, 1, ControlMotionEvent::PITCH, -1.0f ); +} + +void SonsOfSolApplication::setFullScreen() { + m_screen = SDL_SetVideoMode(m_screen_width,m_screen_height,0, + SDL_OPENGL|SDL_RESIZABLE|SDL_DOUBLEBUF|SDL_FULLSCREEN); + reshape( m_screen_width, m_screen_height ); +} bool SonsOfSolApplication::initialize( int argc, char** argv ) { + (void) argc; + (void) argv; + + /* Use our texture factory to load textures */ + m_object_loader.setTextureFactory( &m_texture_factory ); + + setupControls(); + SDL_Init( SDL_INIT_VIDEO ); + const SDL_VideoInfo* info = SDL_GetVideoInfo(); //<-- calls SDL_GetVideoInfo(); + m_screen_width = info->current_w; + m_screen_height = info->current_h; m_screen = SDL_SetVideoMode( 600, 600, 0, SDL_OPENGL|SDL_RESIZABLE|SDL_DOUBLEBUF ); m_perspective.setPosition( GloxPoint<>( 0, 0, 10 ) ); + m_perspective.setZFar( 10000.0 ); + m_ship.setPerspective( m_perspective ); + + if( argv[1] == NULL || strcmp(argv[1],"nograb") ) { + SDL_ShowCursor( 0 ); + SDL_WM_GrabInput(SDL_GRAB_ON); + } + + /* Add some listeners */ this->addQuitListener( this ); + this->addKeyListener( this ); + + this->addKeyListener( & m_event_multiplexer ); + this->addMouseMotionListener( & m_event_multiplexer ); + this->addResizeListener( this ); + + m_event_multiplexer.addControlMotionListener( & m_ship ); if( ! m_screen ) { /* If the screen could not be initialized, print @@ -26,35 +83,77 @@ bool SonsOfSolApplication::initialize( int argc, char** argv ) { /* Load the textures into memory */ if( ! loadTextures() ) return false; - GloxTextureRepeat texrep( &m_sky_tex, 3, 3 ); - m_sky = new GloxTexturedCube( 900.0f, GloxColor( 255, 255, 255 ), + GloxTextureRepeat texrep( &m_sky_tex, 1.8, 1.8 ); + m_sky = new GloxTexturedCube( 9900.0f, GloxColor( 255, 255, 255 ), + texrep, texrep, texrep, texrep, texrep, texrep ); + + texrep = GloxTextureRepeat( &m_crate_tex, 1, 1 ); + m_crate = new GloxTexturedCube( 5.0f, GloxColor( 255, 255, 255 ), texrep, texrep, texrep, texrep, texrep, texrep ); + + m_object_loader.addToPath( "objects" ); + m_object_loader.addToPath( "objects/material" ); + m_earth = new GloxTexturedSphere( 900.0f, 5.0f, m_earth_tex ); + m_probe = m_object_loader.loadObjectFromFile( "probe.obj" ); + + if( ! m_probe ) { + cerr << "Unable to load probe: " << m_object_loader.getReason() << endl; + exit( 123 ); + } + + m_frigate_industrial = m_object_loader.loadObjectFromFile( "frigate_industrial.obj" ); + if( ! m_frigate_industrial ) { + cerr << "Unable to load frigate_industrial\n" << m_object_loader.getReason() << endl; + exit( 123 ); + } + + /* Add the points for the sun */ + m_star.add( GloxPointNormalTexture( + GloxPoint<>( -100, 100, -4500 ), GloxNormal<>(0,0,0), GloxPoint<>( 0,0 ) ) ); + m_star.add( GloxPointNormalTexture( + GloxPoint<>( 100, 100, -4500 ), GloxNormal<>(0,0,0), GloxPoint<>( 1,0 ) ) ); + m_star.add( GloxPointNormalTexture( + GloxPoint<>( 100, 300, -4500 ), GloxNormal<>(0,0,0), GloxPoint<>( 1,1 ) ) ); + m_star.add( GloxPointNormalTexture( + GloxPoint<>( -100, 300, -4500 ), GloxNormal<>(0,0,0), GloxPoint<>( 0,1 ) ) ); + + /* Move the light souce to the sun */ + GloxLightSource* source = m_light_manager.getLightSource( 0 ); + source->setPosition( GloxPointf( 0, 200, -695 ) ); m_quit = false; + + this->enableLighting(); return true; } -#define NTEX 3 +#define NTEX 5 bool SonsOfSolApplication::loadTextures() { const char* files[NTEX] = { "stars.bmp", "leaf.bmp", - "crate.bmp" + "crate.bmp", + "star.bmp", + "earth.bmp" }; GloxTexture* textures[NTEX] = { &m_sky_tex, &m_leaf_tex, - &m_cube_tex + &m_crate_tex, + &m_star_tex, + &m_earth_tex }; - unsigned int tex; + unsigned int tex = 0; + m_texture_factory.addToPath( "objects/textures/" ); + m_texture_factory.addToPath( "objects/" ); for ( int i = 0; i < NTEX; ++ i ) { - if( SloxTextureFactory::readBitmapFile( files[i], &tex ) ) { + if( m_texture_factory.readBitmapFile( files[i], &tex ) ) { /* Either there was a warning or an error, print out * either */ - fprintf( stderr, "Reading %s: %s\n", files[i], SloxTextureFactory::getMessage().c_str() ); + fprintf( stderr, "Reading %s: %s\n", files[i], m_texture_factory.getMessage().c_str() ); if( tex == 0 ) { /* If the texture hasn't changed, its an error, otherwise @@ -64,44 +163,87 @@ bool SonsOfSolApplication::loadTextures() { } } textures[i]->setId( tex ); + tex = 0; } return true; } void SonsOfSolApplication::enableLighting() { - int ambient_coef = 30; - int diffuse_coef = 100; + /* There is very little ambient light + * in space */ + // int ambient_coef = 0.5; + // int diffuse_coef = 100; int specular_coef = 0; - GloxLightSource* source = m_light_manager.getLightSource( 0 ); + GloxLightSource* sun = m_light_manager.getLightSource( 0 ); + GloxLightSource* earth = m_light_manager.getLightSource( 1 ); - GloxColor base(2,2,2); - source->setAmbient ( base * ambient_coef ); - source->setDiffuse ( base * diffuse_coef ); - source->setSpecular( base * specular_coef ); - source->setLightModelAttribute( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); - GloxTrace( "init", "Source=%p\n", source ); - source->setEnabled( true ); + GloxColor base(2,2,0); + sun->setLightModelAttribute( GL_LIGHT_MODEL_AMBIENT, GloxColor(100,100,90) ); + sun->setAmbient ( GloxColor( 0, 0, 0 ) ); + sun->setDiffuse ( GloxColor( 255, 235, 200 ) ); + sun->setSpecular( base * specular_coef ); + sun->setLightModelAttribute( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); + sun->setEnabled( true ); + + earth->setLightModelAttribute( GL_LIGHT_MODEL_AMBIENT, GloxColor(0,0,0) ); + earth->setAmbient ( GloxColor(0,0,0) ); + earth->setDiffuse ( GloxColor(130,155,155) ); + earth->setSpecular( base * specular_coef ); + earth->setLightModelAttribute( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); + earth->setPosition( GloxPoint<>( 700,-1000,0 ) ); } void SonsOfSolApplication::update( uint32_t ticks ) { - + (void) ticks; + m_ship.update(); } void SonsOfSolApplication::display() { /* Translate to the this perspective */ - m_perspective.render(); - m_sky->draw(); + m_ship.drawHUD(); + m_ship.getPerspective().render(); + + /* We don't want lighting for the skybox */ + GloxDisableFor( GL_LIGHTING, + /* Draw some stuff relative to the + * ship so the ship cannot break out + * of the skybox */ + GloxWithTranslation( m_ship.getPosition(), + /* Draw the background sky */ + m_sky->draw(); + /* Draw the star texture */ + GloxEnableFor( GL_TEXTURE_2D, + m_star_tex.bind(); + GloxWith( GL_QUADS, m_star.plot() ); + ); + ) + ); + + GloxWithTranslation( m_ship.getPosition() + GloxPoint<>( 700,-1000,0 ), + GloxRotation( -90, 0, 0, 1 ).render(); + m_earth->draw() + ) - GloxColor( 255,255,255 ).render(); - GloxWith( GL_QUADS, { - GloxPoint<>( 0,0,0 ).plot(); - GloxPoint<>( 0,5,0 ).plot(); - GloxPoint<>( 5,5,0 ).plot(); - GloxPoint<>( 5,0,0 ).plot(); - } ); + m_light_manager.getLightSource( 1 )->setEnabled( true ); + m_light_manager.render(); + + m_crate->draw(); + GloxWithTranslation( GloxPoint<>( 0,10,0 ), + m_probe->draw() ); + + GloxScale( 100, + GloxWithTranslation( GloxPoint<>( 10,10,10 ), + glPushMatrix(); + glRotatef( 90, 1.2, 1.3, 1.4 ); + m_frigate_industrial->draw(); + glPopMatrix(); + ) + ); + + GloxColor( 255,255,255 ).render(); } void SonsOfSolApplication::reshape( int width, int height ) { @@ -109,6 +251,6 @@ void SonsOfSolApplication::reshape( int width, int height ) { m_viewport.setHeight( height ); m_viewport.render(); - m_perspective.setAspectRatio( m_viewport.getAspectRatio() ); - m_perspective.project(); + m_ship.getPerspective().setAspectRatio( m_viewport.getAspectRatio() ); + m_ship.getPerspective().project(); } |