diff --git a/.gitignore b/.gitignore index e11069d..22fc997 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ # Project Specific. *Lephisto3D* +*ModelViewer* bin/* *Makefile *Makefile.in diff --git a/src/Makefile.am b/src/Makefile.am index 61058a4..4af40fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,15 +1,8 @@ ## Process this file with automake to produce Makefile.in SUBDIRS = sbre/ -bin_PROGRAMS = Lephisto3D -Lephisto3D_SOURCES = main.cpp gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cpp gui_label.cpp glfreetype.cpp \ - body.cpp space.cpp ship.cpp player.cpp gui_toggle_button.cpp gui_radio_button.cpp \ - gui_radio_group.cpp dynamic_body.cpp planet.cpp star.cpp frame.cpp gui_image_button.cpp gui_image.cpp \ - gui_image_radio_button.cpp gui_multi_state_image_button.cpp ship_cpanel.cpp gui_widget.cpp sector_view.cpp \ - mtrand.cpp world_view.cpp system_view.cpp star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp \ - gui_container.cpp date.cpp space_station.cpp space_station_view.cpp model_body.cpp ship_type.cpp \ - info_view.cpp model_coll_mesh_data.cpp object_viewer_view.cpp custom_starsystems.cpp -Lephisto3D_LDADD = sbre/libsbre.a +bin_PROGRAMS = Lephisto3D ModelViewer +noinst_LIBRARIES = libgui.a include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h gui_container.h gui_events.h gui_fixed.h \ gui.h gui_image_button.h gui_image.h gui_image_radio_button.h gui_label.h gui_multi_state_image_button.h gui_radio_button.h \ @@ -18,3 +11,18 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h model_body.h gui_iselectable.h \ ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h +libgui_a_SOURCES = gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cpp gui_label.cpp gui_toggle_button.cpp gui_radio_button.cpp \ + gui_radio_group.cpp gui_image_button.cpp gui_image.cpp gui_image_radio_button.cpp gui_multi_state_image_button.cpp gui_widget.cpp \ + gui_container.cpp + +Lephisto3D_SOURCES = main.cpp glfreetype.cpp body.cpp space.cpp ship.cpp player.cpp dynamic_body.cpp planet.cpp \ + star.cpp frame.cpp ship_cpanel.cpp sector_view.cpp mtrand.cpp world_view.cpp system_view.cpp \ + star_system.cpp sector.cpp system_info_view.cpp generic_system_view.cpp date.cpp space_station.cpp \ + space_station_view.cpp model_body.cpp ship_type.cpp info_view.cpp model_coll_mesh_data.cpp \ + object_viewer_view.cpp custom_starsystems.cpp +Lephisto3D_LDADD = sbre/libsbre.a libgui.a + +ModelViewer_SOURCES = sbre_viewer.cpp glfreetype.cpp +ModelViewer_LDADD = sbre/libsbre.a libgui.a + + diff --git a/src/body.cpp b/src/body.cpp index 7149f1d..cd3f3ef 100644 --- a/src/body.cpp +++ b/src/body.cpp @@ -27,3 +27,18 @@ const vector3d& Body::GetProjectedPos(void) const { return m_projectedPos; } +void Body::OrientOnSurface(double radius, double latitude, double longitude) { + vector3d pos = vector3d(radius*cos(latitude)*cos(longitude), + radius*sin(latitude)*cos(longitude), radius*sin(longitude)); + vector3d up = vector3d::Normalize(pos); + SetPosition(pos); + + vector3d forward = vector3d(0,0,1); + vector3d other = vector3d::Normalize(vector3d::Cross(up, forward)); + forward = vector3d::Cross(other, up); + + matrix4x4d rot = matrix4x4d::MakeRotMatrix(other, up, forward); + rot = rot.InverseOf(); + SetRotMatrix(rot); +} + diff --git a/src/body.h b/src/body.h index 6b68b6a..dd5c51b 100644 --- a/src/body.h +++ b/src/body.h @@ -29,6 +29,8 @@ public: /* Override to clear any pointers you hold to the dying body. */ virtual void NotifyDeath(const Body* const dyingBody) {} + /* For putting on planet surface, oriented +y up. */ + void OrientOnSurface(double radius, double latitude, double longitude); vector3d GetPositionRelTo(const Frame*); Frame* GetFrame(void) { return m_frame; } void SetLabel(const char* label) { m_label = label; } diff --git a/src/glfreetype.cpp b/src/glfreetype.cpp index cb0b556..111f35c 100644 --- a/src/glfreetype.cpp +++ b/src/glfreetype.cpp @@ -303,7 +303,7 @@ void FontFace::RenderString(const char* str) { void FontFace::RenderMarkup(const char* str) { glPushMatrix(); int len = strlen(str); - for(unsigned int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { if(str[i] == '#') { int hexcol; if(sscanf(str+i, "#%3x", &hexcol)==1) { @@ -331,8 +331,9 @@ void FontFace::RenderMarkup(const char* str) { FontFace::FontFace(const char* filename_ttf) { FT_Face face; - if(0 != FT_New_Face(library, filename_ttf, 0, &face)) { - fprintf(stderr, "Error: Couldn't load '%s'\n", filename_ttf); + int err; + if(0 != (err = FT_New_Face(library, filename_ttf, 0, &face))) { + fprintf(stderr, "Terrible error! Couldn't load '%s'; error %d.\n", filename_ttf, err); } else { FT_Set_Char_Size(face, 50*64, 0, 100, 0); for(int chr = 32; chr < 127; chr++) { diff --git a/src/gui_fixed.cpp b/src/gui_fixed.cpp index 0805e1c..58e0cc0 100644 --- a/src/gui_fixed.cpp +++ b/src/gui_fixed.cpp @@ -1,6 +1,5 @@ #include "libs.h" #include "gui.h" -#include "l3d.h" namespace Gui { diff --git a/src/gui_image.cpp b/src/gui_image.cpp index 9be92cd..84aa81e 100644 --- a/src/gui_image.cpp +++ b/src/gui_image.cpp @@ -1,6 +1,5 @@ #include "libs.h" #include "gui_image.h" -#include "l3d.h" namespace Gui { @@ -12,7 +11,7 @@ Image::Image(const char* filename) : Widget() { SDL_Surface* is = IMG_Load(filename); if(!is) { fprintf(stderr, "Could not load %s\n", filename); - L3D::Quit(); + exit(0); } m_imgw = is->w; m_imgh = is->h; diff --git a/src/gui_image_button.cpp b/src/gui_image_button.cpp index 652d0e5..42f4ba7 100644 --- a/src/gui_image_button.cpp +++ b/src/gui_image_button.cpp @@ -1,7 +1,6 @@ #include "libs.h" #include "gui.h" #include "gui_image_button.h" -#include "l3d.h" namespace Gui { diff --git a/src/gui_image_radio_button.cpp b/src/gui_image_radio_button.cpp index 83c5387..43ad2a5 100644 --- a/src/gui_image_radio_button.cpp +++ b/src/gui_image_radio_button.cpp @@ -1,7 +1,6 @@ #include "libs.h" #include "gui.h" #include "gui_image_radio_button.h" -#include "l3d.h" namespace Gui { diff --git a/src/gui_toggle_button.cpp b/src/gui_toggle_button.cpp index 5c6a009..2903113 100644 --- a/src/gui_toggle_button.cpp +++ b/src/gui_toggle_button.cpp @@ -15,17 +15,26 @@ bool ToggleButton::OnMouseDown(MouseButtonEvent* e) { onPress.emit(); m_pressed = !m_pressed; if(m_pressed) { - onSelect.emit(this); + onChange.emit(this, true); } else { - onDeselect.emit(this); + onChange.emit(this, false); } } return false; } -void ToggleButton::GetSizeRequested(float& w, float& h) { - w = BUTTON_SIZE; - h = BUTTON_SIZE; +void ToggleButton::OnActivate(void) { + m_pressed = !m_pressed; + if(m_pressed) { + onChange.emit(this, true); + } else { + onChange.emit(this, false); + } +} + +void ToggleButton::GetSizeRequested(float size[2]) { + size[0] = BUTTON_SIZE; + size[1] = BUTTON_SIZE; } void ToggleButton::Draw(void) { diff --git a/src/gui_toggle_button.h b/src/gui_toggle_button.h index a5ca6e9..4f152b1 100644 --- a/src/gui_toggle_button.h +++ b/src/gui_toggle_button.h @@ -8,13 +8,13 @@ namespace Gui { ToggleButton(void); virtual void Draw(void); virtual ~ToggleButton(void) {} - virtual void GetSizeRequested(float& w, float& h); + virtual void GetSizeRequested(float size[2]); virtual bool OnMouseDown(MouseButtonEvent* e); + virtual void OnActivate(void); void SetPressed(bool s) { m_pressed = s; } bool GetPressed(void) { return m_pressed; } - sigc::signal onSelect; - sigc::signal onDeselect; + sigc::signal onChange; private: int m_pressed; }; diff --git a/src/main.cpp b/src/main.cpp index 30859d1..6a36d0c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -233,13 +233,20 @@ void L3D::MainLoop(void) { station->SetPosition(vector3d(0,0,0)); Space::AddBody(station); - //player->SetFrame(stationFrame); + SpaceStation* station2 = new SpaceStation(); + station2->SetLabel("Dfighter's point"); + station2->SetFrame(*pframe->m_children.begin()); /* Rotating frame of planet. */ + station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4); + Space::AddBody(station2); + + player->SetFrame(stationFrame); + player->SetPosition(vector3d(0,0,0)); //player->SetPosition(vector3d(0,0,2000)); - player->SetFrame(pframe); + //player->SetFrame(pframe); float ang1 = L3D::rng.Double(0,M_PI); float ang2 = L3D::rng.Double(0,M_PI); double r = EARTH_RADIUS*1.0001; - player->SetPosition(vector3d(r*cos(ang1)*cos(ang2), r*sin(ang1)*cos(ang2), r*sin(ang2))); + //player->SetPosition(vector3d(r*cos(ang1)*cos(ang2), r*sin(ang1)*cos(ang2), r*sin(ang2))); //player->SetPosition(vector3d(r, 0, 0); Gui::Init(scrWidth, scrHeight, 640, 480); @@ -256,7 +263,7 @@ void L3D::MainLoop(void) { infoView = new InfoView(); SetView(worldView); - //player->SetDockedWith(station); + player->SetDockedWith(station); Uint32 last_stats = SDL_GetTicks(); int frame_stat = 0; diff --git a/src/sbre/models.cpp b/src/sbre/models.cpp index 0bb71a3..9d68bff 100644 --- a/src/sbre/models.cpp +++ b/src/sbre/models.cpp @@ -5,6 +5,10 @@ enum AxisIndex { A_X = 0, A_Y, A_Z, A_NX, A_NY, A_NZ, }; +static CompoundVertex dummyvtx2[] = { + { VTYPE_CROSS, { 0, 1, 2, static_cast(-1), static_cast(-1) } }, /* Dummy. */ +}; + static PlainVertex tetravtx1[] = { { VTYPE_PLAIN, { 0.0f, 50.0f, 0.0f } }, /* 6. */ { VTYPE_PLAIN, { -50.0f, -30.0f, 30.0f } }, @@ -1241,3 +1245,65 @@ static Thruster wing2thruster[] = { Model wing2model = { 1.0f, 25.0f, 23, wing2vtx1, 30, 0, wing2vtx2, 2, { { 0, wing2data, 0, 2, wing2thruster } } }; +static PlainVertex metalFrameTowerVtx1[] = { + { VTYPE_PLAIN, { -1, 0, 1 } }, + { VTYPE_PLAIN, { 1, 0, 1 } }, + { VTYPE_PLAIN, { 1, 0, -1 } }, + { VTYPE_PLAIN, { -1, 0, -1 } }, + { VTYPE_PLAIN, { -1, 10, 1 } }, + { VTYPE_PLAIN, { 1, 10, 1 } }, + { VTYPE_PLAIN, { 1, 10, -1 } }, + { VTYPE_PLAIN, { -1, 10, -1 } }, +}; + +static CompoundVertex metalFrameTowerVtx2[] = { + { VTYPE_ANIMLIN, { 6, 10, static_cast(-1), static_cast(-1), 0 } }, + { VTYPE_ANIMLIN, { 7, 11, static_cast(-1), static_cast(-1), 0 } }, + { VTYPE_ANIMLIN, { 8, 12, static_cast(-1), static_cast(-1), 0 } }, + { VTYPE_ANIMLIN, { 9, 13, static_cast(-1), static_cast(-1), 0 } }, +}; + +static uint16 metalFrameTowerData[] = { + PTYPE_CYLINDER, 0x8000, 4, 6, 14, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 7, 15, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 8, 16, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 9, 17, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 6, 15, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 7, 14, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 7, 16, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 8, 15, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 8, 17, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 9, 16, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 6, 17, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 9, 14, 0, 10, + PTYPE_CYLINDER, 0x8000, 4, 14, 15, 1, 10, + PTYPE_CYLINDER, 0x8000, 4, 15, 16, 1, 10, + PTYPE_CYLINDER, 0x8000, 4, 16, 17, 1, 10, + PTYPE_CYLINDER, 0x8000, 4, 17, 14, 1, 10, + PTYPE_END, +}; + +Model metalFrameTowerModel = { 0.1f, 20.0f, 14, metalFrameTowerVtx1, 14, 4, metalFrameTowerVtx2, 0, +{ { 0, metalFrameTowerData, 0, 0, 0 } } }; + +static PlainVertex starport1vtx1[] = { + { VTYPE_PLAIN, { 0, 0, 0 } }, + { VTYPE_PLAIN, { 0, .01, 0 } }, + { VTYPE_PLAIN, { -0.1, .01, -0.1 } }, +}; + +static uint16 starport1data[] = { + PTYPE_MATFIXED, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, + PTYPE_CYLINDER, 0x8000, 8, 6, 7, 0, 50, + PTYPE_MATFIXED, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, + PTYPE_ZBIAS, 6, 1, 0, + PTYPE_TEXT, 0, 10, 8, 1, 0, 0, 0, 20, + PTYPE_ZBIAS, 0x8000, 0, 0, + PTYPE_SUBOBJECT, 0x8000, 100, 0, 1, 2, 100, + PTYPE_SUBOBJECT, 0x8000, 100, 3, 1, 2, 100, + PTYPE_END, +}; + +Model starport1model = { 100.0f, 55.0f, 9, starport1vtx1, 9, 0, dummyvtx2, 1, + { { 0, starport1data, 0, 0, 0 } } }; + diff --git a/src/sbre/sbre_int.h b/src/sbre/sbre_int.h index d40ed3a..f4731df 100644 --- a/src/sbre/sbre_int.h +++ b/src/sbre/sbre_int.h @@ -172,8 +172,10 @@ enum comptype { const int pCompSize[] = { 1, 3, 5, 3, 3, 2 }; -const char pModelString[1][256] = { - "IZRILGOOD", +const char pModelString[][256] = { + "IZRILGOOD", "Rawr", "", "", "", "", "", "", "", "", + /* 10 - Landing pad messages. */ + "1" }; void RenderThrusters(RState* pState, int numThrusters, Thruster* pThrusters); diff --git a/src/sbre/sbre_models.h b/src/sbre/sbre_models.h index dcf471b..14c5ebd 100644 --- a/src/sbre/sbre_models.h +++ b/src/sbre/sbre_models.h @@ -4,7 +4,8 @@ extern Model dishmodel, nosewheelmodel, nwunitmodel, mainwheelmodel, mwunitmodel; extern Model wing1model, wing2model; extern Model ship1model, ship2model, ship3model, ship4model, ship5model; -extern Model station1model; +extern Model station1model, starport1model; +extern Model metalFrameTowerModel; /* Common subobject indices. */ const int SUB_NOSEWHEEL = 1; @@ -19,7 +20,7 @@ const int SUB_WING2 = 31; Model* const ppModel[] = { /* 0, current test object. */ - &ship5model, + &ship2model, /* 1, common subobjects. */ &nosewheelmodel, &nwunitmodel, @@ -52,5 +53,8 @@ Model* const ppModel[] = { /* 80. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90, other people's ships. */ + &starport1model, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 100, more sub-objects. */ + &metalFrameTowerModel }; diff --git a/src/sbre_viewer.cpp b/src/sbre_viewer.cpp new file mode 100644 index 0000000..f096667 --- /dev/null +++ b/src/sbre_viewer.cpp @@ -0,0 +1,250 @@ +#include "libs.h" +#include "sbre/sbre.h" +#include "glfreetype.h" +#include "gui.h" + +static SDL_Surface* g_screen; +static int g_width, g_height; +static int g_mouseMotion[2]; +static char g_keyState[SDLK_LAST]; +static int g_mouseButton[5]; +static int g_model = 0; /* sbre model number. Set with argc. */ + + +static void PollEvents(void) { + SDL_Event event; + + g_mouseMotion[0] = g_mouseMotion[1] = 0; + while(SDL_PollEvent(&event)) { + Gui::HandleSDLEvent(&event); + switch(event.type) { + case SDL_KEYDOWN: + if(event.key.keysym.sym == SDLK_ESCAPE) { SDL_Quit(); exit(0); } + if(event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(g_screen); + g_keyState[event.key.keysym.sym] = 1; + break; + case SDL_KEYUP: + g_keyState[event.key.keysym.sym] = 0; + break; + case SDL_MOUSEBUTTONDOWN: + g_mouseButton[event.button.button] = 1; + /*L3D::onMouseButtonDown.emit(event.button.button, + event.button.x, event.button.y);*/ + break; + case SDL_MOUSEBUTTONUP: + g_mouseButton[event.button.button] = 0; + /*L3D::onMouseButtonUp.emit(event.button.button, + event.button.x, event.button.y);*/ + break; + case SDL_MOUSEMOTION: + g_mouseMotion[0] += event.motion.xrel; + g_mouseMotion[1] += event.motion.yrel; + break; + case SDL_QUIT: + SDL_Quit(); + exit(0); + break; + } + } +} + +static int g_wheelMoveDir = -1; +static float g_wheelPos = 0; +static bool g_renderCollMesh = false; +static float lightCol[4] = { 1, 1, 1, 0 }; +static float lightDir[4] = { 0, 1, 0, 0 }; +static float g_frameTime; + +static ObjParams params = { + { 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, + + /* pColor[3] */ + { + { { 1.0f, 0.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 }, + { { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } + }, + + /* pText. */ + { "IR-L33T", "ME TOO!" }, +}; + +static void SetSbreParams(void) { + float gameTime = SDL_GetTicks() * 0.001; + params.pAnim[ASRC_SECFRAC] = gameTime; + params.pAnim[ASRC_MINFRAC] = gameTime / 60; + params.pAnim[ASRC_HOURFRAC] = gameTime / 3600.0f; + params.pAnim[ASRC_DAYFRAC] = gameTime/ (24*3600.0f); + if(g_wheelPos <= 0) { + params.pAnim[ASRC_GEAR] = 0; + params.pFlag[AFLAG_GEAR] = 0; + } else { + params.pAnim[ASRC_GEAR] = g_wheelPos; + params.pFlag[AFLAG_GEAR] = 1; + } + + /* Two seconds to move wheels. */ + g_wheelPos += 0.5*g_frameTime*g_wheelMoveDir; + if(g_wheelPos < 0) g_wheelPos = 0; + if(g_wheelPos > 1) g_wheelPos = 1; +} + +class Viewer: public Gui::Fixed { +public: + Viewer() : Gui::Fixed(g_width, g_height) { + Gui::Screen::AddBaseWidget(this, 0, 0); + SetTransparency(true); + { + Gui::ToggleButton* b = new Gui::ToggleButton(); + b->SetShortcut(SDLK_c, KMOD_NONE); + b->onChange.connect(sigc::mem_fun(*this, &Viewer::OnToggleCollMesh)); + Add(b, 10, 10); + Add(new Gui::Label("[c] Show collision mesh."), 30, 10); + } + { + Gui::Button* b = new Gui::SolidButton(); + b->SetShortcut(SDLK_g, KMOD_NONE); + b->onClick.connect(sigc::mem_fun(*this, &Viewer::OnToggleGearState)); + Add(b, 10, 30); + Add(new Gui::Label("[g] Toggle gear state."), 30, 30); + } + + ShowAll(); + Show(); + } + + void OnToggleGearState(void) { + if(g_wheelMoveDir == -1) g_wheelMoveDir = +1; + else g_wheelMoveDir = -1; + } + + void OnToggleCollMesh(Gui::ToggleButton* b, bool state) { + g_renderCollMesh = state; + } + + void MainLoop(); +}; + +void Viewer::MainLoop(void) { + matrix4x4d rot = matrix4x4d::Identity(); + float distance = 100; + Uint32 lastFoo = SDL_GetTicks(); + + CollMesh* cmesh = (CollMesh*)calloc(1, sizeof(CollMesh)); + sbreGenCollMesh(cmesh, g_model, ¶ms, 1.0f); + + for(;;) { + PollEvents(); + + if(g_keyState[SDLK_UP]) rot = matrix4x4d::RotateXMatrix(g_frameTime) * rot; + if(g_keyState[SDLK_DOWN]) rot = matrix4x4d::RotateXMatrix(-g_frameTime) * rot; + if(g_keyState[SDLK_LEFT]) rot = matrix4x4d::RotateYMatrix(g_frameTime) * rot; + if(g_keyState[SDLK_RIGHT]) rot = matrix4x4d::RotateYMatrix(-g_frameTime) * rot; + if(g_keyState[SDLK_EQUALS]) distance *= pow(0.5, g_frameTime); + if(g_keyState[SDLK_MINUS]) distance *= pow(2.0, g_frameTime); + if(g_mouseButton[1] || g_mouseButton[3]) { + float rx = 0.01*g_mouseMotion[1]; + float ry = 0.01*g_mouseMotion[0]; + rot = matrix4x4d::RotateXMatrix(rx) * rot; + rot = matrix4x4d::RotateYMatrix(ry) * rot; + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + float fracH = g_height / (float)g_width; + glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + SetSbreParams(); + sbreSetViewport(g_width, g_height, g_width*0.5, 1.0f, 10000.0f, 0.0f, 1.0f); + sbreSetDirLight(lightCol, lightDir); + + Matrix m; + Vector p; + m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = rot[ 8]; + m.y1 = rot[1]; m.y2 = rot[5]; m.y3 = rot[ 9]; + m.z1 = rot[2]; m.z2 = rot[6]; m.z3 = rot[10]; + p.x = 0; p.y = 0; p.z = distance; + if(g_renderCollMesh) sbreRenderCollMesh(cmesh, &p, &m); + else sbreRenderModel(&p, &m, g_model, ¶ms); + glPopAttrib(); + + Gui::Draw(); + + SDL_GL_SwapBuffers(); + g_frameTime = (SDL_GetTicks() - lastFoo) * 0.001; + lastFoo = SDL_GetTicks(); + } +} + +int main(int argc, char** argv) { + if((argc>1) && (0==strcmp(argv[1], "--help"))) { + printf("Usage:\n\nModelViewer \n"); + exit(0); + } + if(argc > 1) { + g_model = atoi(argv[1]); + } + if(argc == 4) { + g_width = atoi(argv[2]); + g_height = atoi(argv[3]); + } else { + g_width = 800; + g_height = 600; + } + + const SDL_VideoInfo* info = NULL; + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Video initialization failed: %s\n", SDL_GetError()); + exit(-1); + } + + info = SDL_GetVideoInfo(); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + sbreSetZBias(2.0/(1<<24)); + + Uint32 flags = SDL_OPENGL; + + if((g_screen = SDL_SetVideoMode(g_width, g_height, info->vfmt->BitsPerPixel, flags)) == 0) { + /* Fall back to 16-bit depth buffer. */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + sbreSetZBias(2.0/(1<<16)); + fprintf(stderr, "Failed to set video mode. (%s). Re-trying with 16-bit depth buffer.\n", SDL_GetError()); + if((g_screen = SDL_SetVideoMode(g_width, g_height, info->vfmt->BitsPerPixel, flags)) == 0) { + fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError()); + } + } + + glShadeModel(GL_SMOOTH); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glClearColor(0,0,0,0); + glViewport(0,0, g_width, g_height); + GLFTInit(); + Gui::Init(g_width, g_height, g_width, g_height); + + Viewer v; + v.MainLoop(); +} + +