[Add] Body::OrientOnSurface for placing things on planets.

[Add] Small start on ground based starports.
[Fix] ToggleButton.
This commit is contained in:
Allanis 2018-01-20 22:37:38 +00:00
parent 47ed4bed2e
commit 4824a797b9
16 changed files with 394 additions and 33 deletions

1
.gitignore vendored
View File

@ -13,6 +13,7 @@
# Project Specific.
*Lephisto3D*
*ModelViewer*
bin/*
*Makefile
*Makefile.in

View File

@ -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

View File

@ -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);
}

View File

@ -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; }

View File

@ -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++) {

View File

@ -1,6 +1,5 @@
#include "libs.h"
#include "gui.h"
#include "l3d.h"
namespace Gui {

View File

@ -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;

View File

@ -1,7 +1,6 @@
#include "libs.h"
#include "gui.h"
#include "gui_image_button.h"
#include "l3d.h"
namespace Gui {

View File

@ -1,7 +1,6 @@
#include "libs.h"
#include "gui.h"
#include "gui_image_radio_button.h"
#include "l3d.h"
namespace Gui {

View File

@ -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) {

View File

@ -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<void, ToggleButton*> onSelect;
sigc::signal<void, ToggleButton*> onDeselect;
sigc::signal<void, ToggleButton*, bool> onChange;
private:
int m_pressed;
};

View File

@ -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;

View File

@ -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<uint16>(-1), static_cast<uint16>(-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<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 7, 11, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 8, 12, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 9, 13, static_cast<uint16>(-1), static_cast<uint16>(-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 } } };

View File

@ -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);

View File

@ -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
};

250
src/sbre_viewer.cpp Normal file
View File

@ -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, &params, 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, &params);
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 <model number> <width> <height>\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();
}