mirror of https://github.com/skeeto/pixelcity.git
Initial check-in of project.
This commit is contained in:
parent
92c25d37b3
commit
948502769c
|
@ -0,0 +1,848 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Building.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This module contains the class to construct the buildings.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MAX_VBUFFER 256
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "building.h"
|
||||
#include "deco.h"
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "random.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
|
||||
//This is used by the recursive roof builder to decide what items may be added.
|
||||
enum
|
||||
{
|
||||
ADDON_NONE,
|
||||
ADDON_LOGO,
|
||||
ADDON_TRIM,
|
||||
ADDON_LIGHTS,
|
||||
ADDON_COUNT
|
||||
};
|
||||
|
||||
static GLvector vector_buffer[MAX_VBUFFER];
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This is the constructor for our building constructor.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CBuilding::CBuilding (int type, int x, int y, int height, int width, int depth, int seed, GLrgba color)
|
||||
{
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
_width = width;
|
||||
_depth = depth;
|
||||
_height = height;
|
||||
_center = glVector ((float)(_x + width / 2), 0.0f, (float)(_y + depth / 2));
|
||||
_seed = seed;
|
||||
_texture_type = RandomVal ();
|
||||
_color = color;
|
||||
_color.alpha = 0.1f;
|
||||
_have_lights = false;
|
||||
_have_logo = false;
|
||||
_have_trim = false;
|
||||
_roof_tiers = 0;
|
||||
//Pick a color for logos & roof lights
|
||||
//_trim_color = WorldLightColor (seed);
|
||||
_trim_color = glRgbaFromHsl (0.5f, 1.0f, 0.9f);
|
||||
_mesh = new CMesh; //The main textured mesh for the building
|
||||
_mesh_flat = new CMesh; //Flat-color mesh for untextured detail items.
|
||||
switch (type) {
|
||||
case BUILDING_SIMPLE:
|
||||
CreateSimple ();
|
||||
break;
|
||||
case BUILDING_MODERN:
|
||||
CreateModern ();
|
||||
break;
|
||||
case BUILDING_TOWER:
|
||||
CreateTower ();
|
||||
break;
|
||||
case BUILDING_BLOCKY:
|
||||
CreateBlocky ();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CBuilding::~CBuilding ()
|
||||
{
|
||||
|
||||
if (_mesh)
|
||||
delete _mesh;
|
||||
if (_mesh_flat)
|
||||
delete _mesh_flat;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned CBuilding::Texture ()
|
||||
{
|
||||
|
||||
return TextureRandomBuilding (_texture_type);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int CBuilding::PolyCount ()
|
||||
{
|
||||
|
||||
return _mesh->PolyCount () + _mesh_flat->PolyCount ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::Render ()
|
||||
{
|
||||
|
||||
glColor3fv (&_color.red);
|
||||
_mesh->Render ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::RenderFlat (bool colored)
|
||||
{
|
||||
|
||||
if (colored)
|
||||
glColor3fv (&_color.red);
|
||||
_mesh_flat->Render ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::ConstructCube (int left, int right, int front, int back, int bottom, int top)
|
||||
{
|
||||
|
||||
GLvertex p[10];
|
||||
float x1, x2, z1, z2, y1, y2;
|
||||
int i;
|
||||
int index_list[10];
|
||||
float u, v1, v2;
|
||||
float mapping;
|
||||
int base_index;
|
||||
int height;
|
||||
|
||||
height = top - bottom;
|
||||
x1 = (float)left;
|
||||
x2 = (float)right;
|
||||
y1 = (float)bottom;
|
||||
y2 = (float)top;
|
||||
z1 = (float)front;
|
||||
z2 = (float)back;
|
||||
base_index = _mesh->VertexCount ();
|
||||
|
||||
mapping = (float)SEGMENTS_PER_TEXTURE;
|
||||
u = (float)(RandomVal () % SEGMENTS_PER_TEXTURE) / (float)SEGMENTS_PER_TEXTURE;
|
||||
v1 = (float)bottom / (float)mapping;
|
||||
v2 = (float)top / (float)mapping;
|
||||
|
||||
p[0].position = glVector (x1, y1, z1); p[0].uv = glVector (u, v1);
|
||||
p[1].position = glVector (x1, y2, z1); p[1].uv = glVector (u, v2);
|
||||
u += (float)_width / mapping;
|
||||
p[2].position = glVector (x2, y1, z1); p[2].uv = glVector (u, v1);
|
||||
p[3].position = glVector (x2, y2, z1); p[3].uv = glVector (u, v2);
|
||||
u += (float)_depth / mapping;
|
||||
p[4].position = glVector (x2, y1, z2); p[4].uv = glVector (u, v1);
|
||||
p[5].position = glVector (x2, y2, z2); p[5].uv = glVector (u, v2);
|
||||
u += (float)_width / mapping;
|
||||
p[6].position = glVector (x1, y1, z2); p[6].uv = glVector (u, v1);
|
||||
p[7].position = glVector (x1, y2, z2); p[7].uv = glVector (u, v2);
|
||||
u += (float)_width / mapping;
|
||||
p[8].position = glVector (x1, y1, z1); p[8].uv = glVector (u, v1);
|
||||
p[9].position = glVector (x1, y2, z1); p[9].uv = glVector (u, v2);
|
||||
for (i = 0; i < 10; i++) {
|
||||
p[i].uv.x = (p[i].position.x + p[i].position.z) / (float)SEGMENTS_PER_TEXTURE;
|
||||
_mesh->VertexAdd (p[i]);
|
||||
index_list[i] = base_index + i;
|
||||
}
|
||||
_mesh->CubeAdd (&index_list[0]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::ConstructCube (float left, float right, float front, float back, float bottom, float top)
|
||||
{
|
||||
|
||||
GLvertex p[10];
|
||||
float x1, x2, z1, z2, y1, y2;
|
||||
int i;
|
||||
int index_list[10];
|
||||
int base_index;
|
||||
|
||||
x1 = left;
|
||||
x2 = right;
|
||||
y1 = bottom;
|
||||
y2 = top;
|
||||
z1 = front;
|
||||
z2 = back;
|
||||
base_index = _mesh_flat->VertexCount ();
|
||||
|
||||
p[0].position = glVector (x1, y1, z1); p[0].uv = glVector (0.0f, 0.0f);
|
||||
p[1].position = glVector (x1, y2, z1); p[1].uv = glVector (0.0f, 0.0f);
|
||||
p[2].position = glVector (x2, y1, z1); p[2].uv = glVector (0.0f, 0.0f);
|
||||
p[3].position = glVector (x2, y2, z1); p[3].uv = glVector (0.0f, 0.0f);
|
||||
p[4].position = glVector (x2, y1, z2); p[4].uv = glVector (0.0f, 0.0f);
|
||||
p[5].position = glVector (x2, y2, z2); p[5].uv = glVector (0.0f, 0.0f);
|
||||
p[6].position = glVector (x1, y1, z2); p[6].uv = glVector (0.0f, 0.0f);
|
||||
p[7].position = glVector (x1, y2, z2); p[7].uv = glVector (0.0f, 0.0f);
|
||||
p[8].position = glVector (x1, y1, z1); p[8].uv = glVector (0.0f, 0.0f);
|
||||
p[9].position = glVector (x1, y2, z1); p[9].uv = glVector (0.0f, 0.0f);
|
||||
for (i = 0; i < 10; i++) {
|
||||
p[i].uv.x = (p[i].position.x + p[i].position.z) / (float)SEGMENTS_PER_TEXTURE;
|
||||
_mesh_flat->VertexAdd (p[i]);
|
||||
index_list[i] = base_index + i;
|
||||
}
|
||||
_mesh_flat->CubeAdd (&index_list[0]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This will take the given area and populate it with rooftop stuff like
|
||||
air conditioners or light towers.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::ConstructRoof (float left, float right, float front, float back, float bottom)
|
||||
{
|
||||
|
||||
int air_conditioners;
|
||||
int i;
|
||||
int width, depth, height;
|
||||
int face;
|
||||
int addon;
|
||||
int max_tiers;
|
||||
float ac_x;
|
||||
float ac_y;
|
||||
float ac_base;
|
||||
float ac_size;
|
||||
float ac_height;
|
||||
float tower_height;
|
||||
float logo_offset;
|
||||
CDeco* d;
|
||||
GLvector2 start, end;
|
||||
|
||||
_roof_tiers++;
|
||||
max_tiers = _height / 10;
|
||||
width = (int)(right - left);
|
||||
depth = (int)(back - front);
|
||||
height = 5 - _roof_tiers;
|
||||
logo_offset = 0.2f;
|
||||
//See if this building is special and worthy of fancy roof decorations.
|
||||
if (bottom > 35.0f)
|
||||
addon = RandomVal (ADDON_COUNT);
|
||||
//Build the roof slab
|
||||
ConstructCube (left, right, front, back, bottom, bottom + (float)height);
|
||||
//Consider putting a logo on the roof, if it's tall enough
|
||||
if (addon == ADDON_LOGO && !_have_logo) {
|
||||
d = new CDeco;
|
||||
if (width > depth)
|
||||
face = COIN_FLIP ? NORTH : SOUTH;
|
||||
else
|
||||
face = COIN_FLIP ? EAST : WEST;
|
||||
switch (face) {
|
||||
case NORTH:
|
||||
start = glVector ((float)left, (float)back + logo_offset);
|
||||
end = glVector ((float)right, (float)back + logo_offset);
|
||||
break;
|
||||
case SOUTH:
|
||||
start = glVector ((float)right, (float)front - logo_offset);
|
||||
end = glVector ((float)left, (float)front - logo_offset);
|
||||
break;
|
||||
case EAST:
|
||||
start = glVector ((float)right + logo_offset, (float)back);
|
||||
end = glVector ((float)right + logo_offset, (float)front);
|
||||
break;
|
||||
case WEST:
|
||||
default:
|
||||
start = glVector ((float)left - logo_offset, (float)front);
|
||||
end = glVector ((float)left - logo_offset, (float)back);
|
||||
break;
|
||||
}
|
||||
d->CreateLogo (start, end, bottom, WorldLogoIndex (), _trim_color);
|
||||
_have_logo = true;
|
||||
} else if (addon == ADDON_TRIM) {
|
||||
d = new CDeco;
|
||||
vector_buffer[0] = glVector (left, bottom, back);
|
||||
vector_buffer[1] = glVector (left, bottom, front);
|
||||
vector_buffer[2] = glVector (right, bottom, front);
|
||||
vector_buffer[3] = glVector (right, bottom, back);
|
||||
d->CreateLightTrim (vector_buffer, 4, (float)RandomVal (2) + 1.0f, _seed, _trim_color);
|
||||
} else if (addon == ADDON_LIGHTS && !_have_lights) {
|
||||
new CLight (glVector (left, (float)(bottom + 2), front), _trim_color, 2);
|
||||
new CLight (glVector (right, (float)(bottom + 2), front), _trim_color, 2);
|
||||
new CLight (glVector (right, (float)(bottom + 2), back), _trim_color, 2);
|
||||
new CLight (glVector (left, (float)(bottom + 2), back), _trim_color, 2);
|
||||
_have_lights = true;
|
||||
}
|
||||
bottom += (float)height;
|
||||
//If the roof is big enough, consider making another layer
|
||||
if (width > 7 && depth > 7 && _roof_tiers < max_tiers) {
|
||||
ConstructRoof (left + 1, right - 1, front + 1, back - 1, bottom);
|
||||
return;
|
||||
}
|
||||
//1 air conditioner block for every 15 floors sounds reasonble
|
||||
air_conditioners = _height / 15;
|
||||
for (i = 0; i < air_conditioners; i++) {
|
||||
ac_size = (float)(10 + RandomVal (30)) / 10;
|
||||
ac_height = (float)RandomVal (20) / 10 + 1.0f;
|
||||
ac_x = left + (float)RandomVal (width);
|
||||
ac_y = front + (float)RandomVal (depth);
|
||||
//make sure the unit doesn't hang off the right edge of the building
|
||||
if (ac_x + ac_size > (float)right)
|
||||
ac_x = (float)right - ac_size;
|
||||
//make sure the unit doesn't hang off the back edge of the building
|
||||
if (ac_y + ac_size > (float)back)
|
||||
ac_y = (float)back - ac_size;
|
||||
ac_base = (float)bottom;
|
||||
//make sure it doesn't hang off the edge
|
||||
ConstructCube (ac_x, ac_x + ac_size, ac_y, ac_y + ac_size, ac_base, ac_base + ac_height);
|
||||
}
|
||||
|
||||
if (_height > 45) {
|
||||
d = new CDeco;
|
||||
tower_height = (float)(12 + RandomVal (8));
|
||||
d->CreateRadioTower (glVector ((float)(left + right) / 2.0f, (float)bottom, (float)(front + back) / 2.0f), 15.0f);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::ConstructSpike (int left, int right, int front, int back, int bottom, int top)
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
int index_list[6];
|
||||
int i;
|
||||
GLvector center;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
index_list[i] = _mesh_flat->VertexCount () + i;
|
||||
index_list[5] = index_list[1];
|
||||
p.uv = glVector (0.0f, 0.0f);
|
||||
center.x = ((float)left + (float)right) / 2.0f;
|
||||
center.z = ((float)front + (float)back) / 2.0f;
|
||||
p.position = glVector (center.x, (float)top, center.z);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
|
||||
p.position = glVector ((float)left, (float)bottom, (float)back);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
|
||||
p.position = glVector ((float)right, (float)bottom, (float)back);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
|
||||
p.position = glVector ((float)right, (float)bottom, (float)front);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
|
||||
p.position = glVector ((float)left, (float)bottom, (float)front);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
|
||||
_mesh_flat->FanAdd (&index_list[0], 6);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This builds an outer wall of a building, with blank (windowless) areas
|
||||
deliberately left. It creates a chain of segments that alternate
|
||||
between windowed and windowless, and it always makes sure the wall
|
||||
is symetrical. window_groups tells it how many windows to place in a row.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float CBuilding::ConstructWall (int start_x, int start_y, int start_z, int direction, int length, int height, int window_groups, float uv_start, bool blank_corners)
|
||||
{
|
||||
|
||||
int x, z;
|
||||
int step_x, step_z;
|
||||
int i;
|
||||
int index_list[100];
|
||||
int current_index;
|
||||
int column;
|
||||
int mid;
|
||||
int odd;
|
||||
GLvertex v;
|
||||
bool blank;
|
||||
bool last_blank;
|
||||
|
||||
switch (direction) {
|
||||
case NORTH:
|
||||
step_z = 1; step_x = 0; break;
|
||||
case WEST:
|
||||
step_z = 0; step_x = -1; break;
|
||||
case SOUTH:
|
||||
step_z = -1; step_x = 0; break;
|
||||
case EAST:
|
||||
step_z = 0; step_x = 1; break;
|
||||
}
|
||||
x = start_x;;
|
||||
z = start_z;
|
||||
current_index = 0;
|
||||
mid = (length / 2) - 1;
|
||||
odd = 1 - (length % 2);
|
||||
if (length % 2)
|
||||
mid++;
|
||||
//mid = (length / 2);
|
||||
v.uv.x = (float)(x + z) / SEGMENTS_PER_TEXTURE;
|
||||
v.uv.x = uv_start;
|
||||
blank = false;
|
||||
for (i = 0; i <= length; i++) {
|
||||
//column counts up to the mid point, then back down, to make it symetrical
|
||||
if (i <= mid)
|
||||
column = i - odd;
|
||||
else
|
||||
column = (mid) - (i - (mid));
|
||||
last_blank = blank;
|
||||
blank = (column % window_groups) > window_groups / 2;
|
||||
if (blank_corners && i == 0)
|
||||
blank = true;
|
||||
if (blank_corners && i == (length - 1))
|
||||
blank = true;
|
||||
if (last_blank != blank || i == 0 || i == length) {
|
||||
v.position = glVector ((float)x, (float)start_y, (float)z);
|
||||
v.uv.y = (float)start_y / SEGMENTS_PER_TEXTURE;
|
||||
_mesh->VertexAdd (v);
|
||||
index_list[current_index] = _mesh->VertexCount () - 1;
|
||||
current_index++;
|
||||
v.position.y = (float)(start_y + height);
|
||||
v.uv.y = (float)(start_y + height) / SEGMENTS_PER_TEXTURE;;
|
||||
_mesh->VertexAdd (v);
|
||||
index_list[current_index] = _mesh->VertexCount () - 1;
|
||||
current_index++;
|
||||
}
|
||||
//if (!blank && i != 0 && i != (length - 1))
|
||||
if (!blank && i != length)
|
||||
v.uv.x += 1.0f / SEGMENTS_PER_TEXTURE;
|
||||
x += step_x;
|
||||
z += step_z;
|
||||
}
|
||||
_mesh->QuadStripAdd (&index_list[0], current_index);
|
||||
return v.uv.x;
|
||||
|
||||
}
|
||||
|
||||
static int maxt;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This makes a big chunky building of intersecting cubes.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::CreateBlocky ()
|
||||
{
|
||||
|
||||
int min_height;
|
||||
int left, right, front, back;
|
||||
int max_left, max_right, max_front, max_back;
|
||||
int height;
|
||||
int mid_x, mid_z;
|
||||
int half_depth, half_width;
|
||||
int tiers;
|
||||
int max_tiers;
|
||||
int grouping;
|
||||
float lid_height;
|
||||
float uv_start;
|
||||
bool skip;
|
||||
bool blank_corners;
|
||||
|
||||
//Choose if the corners of the building are to be windowless.
|
||||
blank_corners = COIN_FLIP;
|
||||
//Choose a random column on our texture;
|
||||
uv_start = (float)RandomVal (SEGMENTS_PER_TEXTURE) / SEGMENTS_PER_TEXTURE;
|
||||
//Choose how the windows are grouped
|
||||
grouping = 2 + RandomVal (4);
|
||||
//Choose how tall the lid should be on top of each section
|
||||
lid_height = (float)(RandomVal (3) + 1);
|
||||
//find the center of the building.
|
||||
mid_x = _x + _width / 2;
|
||||
mid_z = _y + _depth / 2;
|
||||
max_left = max_right = max_front = max_back = 1;
|
||||
height = _height;
|
||||
min_height = _height / 2;
|
||||
min_height = 3;
|
||||
half_depth = _depth / 2;
|
||||
half_width = _width / 2;
|
||||
tiers = 0;
|
||||
if (_height > 40)
|
||||
max_tiers = 15;
|
||||
else if (_height > 30)
|
||||
max_tiers = 10;
|
||||
else if (_height > 20)
|
||||
max_tiers = 5;
|
||||
else if (_height > 10)
|
||||
max_tiers = 2;
|
||||
else
|
||||
max_tiers = 1;
|
||||
max_tiers = MIN (maxt, max_tiers);
|
||||
maxt++;
|
||||
maxt %= 8;
|
||||
//We begin at the top of the building, and work our way down.
|
||||
//Viewed from above, the sections of the building are randomly sized
|
||||
//rectangles that ALWAYS include the center of the building somewhere within
|
||||
//their area.
|
||||
while (1) {
|
||||
if (height < min_height)
|
||||
break;
|
||||
if (tiers >= max_tiers)
|
||||
break;
|
||||
//pick new locationsfor our four outer walls
|
||||
left = (RandomVal () % half_width) + 1;
|
||||
right = (RandomVal () % half_width) + 1;
|
||||
front = (RandomVal () % half_depth) + 1;
|
||||
back = (RandomVal () % half_depth) + 1;
|
||||
skip = false;
|
||||
//At least ONE of the walls must reach out beyond a previous maximum.
|
||||
//Otherwise, this tier would be completely hidden within a previous one.
|
||||
if (left <= max_left && right <= max_right && front <= max_front && back <= max_back)
|
||||
skip = true;
|
||||
//If any of the four walls is in the same position as the previous max,then
|
||||
//skip this tier, or else the two walls will end up z-fightng.
|
||||
if (left == max_left || right == max_right || front == max_front || back == max_back)
|
||||
skip = true;
|
||||
if (!skip) {
|
||||
//if this is the top, then put some lights up here
|
||||
max_left = MAX (left, max_left);
|
||||
max_right = MAX (right, max_right);
|
||||
max_front = MAX (front, max_front);
|
||||
max_back = MAX (back, max_back);
|
||||
//Now build the four walls of this part
|
||||
uv_start = ConstructWall (mid_x - left, 0, mid_z + back, SOUTH, front + back, height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (mid_x - left, 0, mid_z - front, EAST, right + left, height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (mid_x + right, 0, mid_z - front, NORTH, front + back, height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (mid_x + right, 0, mid_z + back, WEST, right + left, height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
if (!tiers)
|
||||
ConstructRoof ((float)(mid_x - left), (float)(mid_x + right), (float)(mid_z - front), (float)(mid_z + back), (float)height);
|
||||
else //add a flat-color lid onto this section
|
||||
ConstructCube ((float)(mid_x - left), (float)(mid_x + right), (float)(mid_z - front), (float)(mid_z + back), (float)height, (float)height + lid_height);
|
||||
height -= (RandomVal () % 10) + 1;
|
||||
tiers++;
|
||||
}
|
||||
height--;
|
||||
}
|
||||
ConstructCube (mid_x - half_width, mid_x + half_width, mid_z - half_depth, mid_z + half_depth, 0, 2);
|
||||
_mesh->Compile ();
|
||||
_mesh_flat->Compile ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
A single-cube building. Good for low-rise buildings and stuff that will be
|
||||
far from the camera;
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::CreateSimple ()
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
float x1, x2, z1, z2, y1, y2;
|
||||
int index_list[] = {0,1,2,3,4,5,6,7,8,9,10};
|
||||
float u, v1, v2;
|
||||
float cap_height;
|
||||
float ledge;
|
||||
|
||||
//How tall the flat-color roof is
|
||||
cap_height = (float)(1 + RandomVal (4));
|
||||
//how much the ledge sticks out
|
||||
ledge = (float)RandomVal (10) / 30.0f;
|
||||
|
||||
x1 = (float)_x;
|
||||
x2 = (float)(_x + _width);
|
||||
y1 = (float)0.0f;
|
||||
y2 = (float)_height;
|
||||
z2 = (float)_y;
|
||||
z1 = (float)(_y + _depth);
|
||||
|
||||
u = (float)(RandomVal (SEGMENTS_PER_TEXTURE)) / SEGMENTS_PER_TEXTURE;
|
||||
v1 = (float)(RandomVal (SEGMENTS_PER_TEXTURE)) / SEGMENTS_PER_TEXTURE;
|
||||
v2 = v1 + (float)_height * ONE_SEGMENT;
|
||||
|
||||
p.position = glVector (x1, y1, z1); p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x1, y2, z1); p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
u += (float)_depth / SEGMENTS_PER_TEXTURE;
|
||||
|
||||
p.position = glVector (x1, y1, z2); p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x1, y2, z2); p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
u += (float)_width / SEGMENTS_PER_TEXTURE;
|
||||
|
||||
p.position = glVector (x2, y1, z2); p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x2, y2, z2); p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
u += (float)_depth / SEGMENTS_PER_TEXTURE;
|
||||
|
||||
p.position = glVector (x2, y1, z1); p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x2, y2, z1); p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
u += (float)_depth / SEGMENTS_PER_TEXTURE;
|
||||
|
||||
p.position = glVector (x1, y1, z1); p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x1, y2, z1); p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
|
||||
_mesh->QuadStripAdd (index_list, 10);
|
||||
ConstructCube (x1 - ledge, x2 + ledge, z2 - ledge, z1 + ledge, (float)_height, (float)_height + cap_height);
|
||||
_mesh->Compile ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This makes a deformed cylinder building.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::CreateModern ()
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
GLvector center;
|
||||
GLvector pos;
|
||||
GLvector2 radius;
|
||||
GLvector2 start, end;
|
||||
int angle;
|
||||
int windows;
|
||||
int cap_height;
|
||||
int half_depth, half_width;
|
||||
float dist;
|
||||
float length;
|
||||
int* index_list;
|
||||
int points;
|
||||
int skip_interval;
|
||||
int skip_counter;
|
||||
int skip_delta;
|
||||
bool logo_done;
|
||||
bool do_trim;
|
||||
CDeco* d;
|
||||
|
||||
logo_done = false;
|
||||
//How tall the windowless section on top will be.
|
||||
cap_height = 1 + RandomVal (5);
|
||||
//How many 10-degree segments to build before the next skip.
|
||||
skip_interval = 1 + RandomVal (8);
|
||||
//When a skip happens, how many degrees should be skipped
|
||||
skip_delta = (1 + RandomVal (2)) * 30; //30 60 or 90
|
||||
//See if this is eligible for fancy lighting trim on top
|
||||
if (_height > 48 && RandomVal (3) == 0)
|
||||
do_trim = true;
|
||||
else
|
||||
do_trim = false;
|
||||
//Get the center and radius of the circle
|
||||
half_depth = _depth / 2;
|
||||
half_width = _width / 2;
|
||||
center = glVector ((float)(_x + half_width), 0.0f, (float)(_y + half_depth));
|
||||
radius = glVector ((float)half_width, (float)half_depth);
|
||||
dist = 0;
|
||||
windows = 0;
|
||||
p.uv.x = 0.0f;
|
||||
points = 0;
|
||||
skip_counter = 0;
|
||||
for (angle = 0; angle <= 360; angle += 10) {
|
||||
if (skip_counter >= skip_interval && (angle + skip_delta < 360)) {
|
||||
angle += skip_delta;
|
||||
skip_counter = 0;
|
||||
}
|
||||
pos.x = center.x - sinf ((float)angle * DEGREES_TO_RADIANS) * radius.x;
|
||||
pos.z = center.z + cosf ((float)angle * DEGREES_TO_RADIANS) * radius.y;
|
||||
if (angle > 0 && skip_counter == 0) {
|
||||
length = MathDistance (p.position.x, p.position.z, pos.x, pos.z);
|
||||
windows += (int)length;
|
||||
if (length > 10 && !logo_done) {
|
||||
logo_done = true;
|
||||
start = glVector (pos.x, pos.z);
|
||||
end = glVector (p.position.x, p.position.z);
|
||||
d = new CDeco;
|
||||
d->CreateLogo (start, end, (float)_height, WorldLogoIndex (), RANDOM_COLOR);
|
||||
}
|
||||
} else if (skip_counter != 1)
|
||||
windows++;
|
||||
p.position = pos;
|
||||
p.uv.x = (float)windows / (float)SEGMENTS_PER_TEXTURE;
|
||||
p.uv.y = 0.0f;
|
||||
p.position.y = 0.0f;
|
||||
_mesh->VertexAdd (p);
|
||||
p.position.y = (float)_height;
|
||||
p.uv.y = (float)_height / (float)SEGMENTS_PER_TEXTURE;
|
||||
_mesh->VertexAdd (p);
|
||||
_mesh_flat->VertexAdd (p);
|
||||
p.position.y += (float)cap_height;
|
||||
_mesh_flat->VertexAdd (p);
|
||||
vector_buffer[points / 2] = p.position;
|
||||
vector_buffer[points / 2].y = (float)_height + cap_height / 4;
|
||||
points += 2;
|
||||
skip_counter++;
|
||||
}
|
||||
//if this is a big building and it didn't get a logo, consider giving it a light strip
|
||||
if (!logo_done && do_trim) {
|
||||
d = new CDeco;
|
||||
d->CreateLightTrim (vector_buffer, (points / 2) - 2, (float)cap_height / 2, _seed, RANDOM_COLOR);
|
||||
}
|
||||
index_list = new int[points];
|
||||
//Add the outer walls
|
||||
for (int i = 0; i < points; i++)
|
||||
index_list[i] = i;
|
||||
_mesh->QuadStripAdd (index_list, points);
|
||||
_mesh_flat->QuadStripAdd (index_list, points);
|
||||
//add the fan to cap the top of the buildings
|
||||
for (i = 0; i < points / 2; i++)
|
||||
index_list[i + 1] = points - (1 + i * 2);
|
||||
p.position.x = _center.x;
|
||||
p.position.z = _center.z;
|
||||
_mesh_flat->VertexAdd (p);
|
||||
index_list[0] = points;
|
||||
_mesh_flat->FanAdd (index_list, 1 + points / 2);
|
||||
delete index_list;
|
||||
radius /= 2.0f;
|
||||
//ConstructRoof ((int)(_center.x - radius), (int)(_center.x + radius), (int)(_center.z - radius), (int)(_center.z + radius), _height + cap_height);
|
||||
_mesh->Compile ();
|
||||
_mesh_flat->Compile ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CBuilding::CreateTower ()
|
||||
{
|
||||
|
||||
int left, right, front, back, bottom;
|
||||
int section_height, section_width, section_depth;
|
||||
int remaining_height;
|
||||
int ledge_height;
|
||||
int tier_fraction;
|
||||
int grouping;
|
||||
int foundation;
|
||||
float ledge;
|
||||
float uv_start;
|
||||
bool blank_corners;
|
||||
bool roof_spike;
|
||||
bool narrowing;
|
||||
bool tower;
|
||||
|
||||
//How much ledges protrude from the building
|
||||
ledge = (float)RandomVal (3) * 0.25f;
|
||||
//How tall the ledges are, in stories
|
||||
ledge_height = RandomVal (3) + 1;
|
||||
//How the windows are grouped
|
||||
grouping = RandomVal (3) + 2;
|
||||
//if the corners of the building have no windows
|
||||
blank_corners = COIN_FLIP;
|
||||
//if the roof is pointed or has infrastructure on it
|
||||
roof_spike = RandomVal (3) == 0;
|
||||
//What fraction of the remaining height should be given to each tier
|
||||
tier_fraction = 2 + RandomVal (3);
|
||||
//Does the tower get narrower towards the top?
|
||||
narrowing = RandomVal (3) == 0;
|
||||
//The height of the windowsless slab at the bottom
|
||||
foundation = 2 + RandomVal (3);
|
||||
//The odds that we'll have a big fancy spikey top
|
||||
tower = RandomVal (5) != 0 && _height > 40;
|
||||
//set our initial parameters
|
||||
left = _x;
|
||||
right = _x + _width;
|
||||
front = _y;
|
||||
back = _y + _depth;
|
||||
bottom = 0;
|
||||
//build the foundations.
|
||||
ConstructCube ((float)left - ledge, (float)right + ledge, (float)front - ledge, (float)back + ledge, (float)bottom, (float)foundation);
|
||||
bottom += foundation;
|
||||
//now add tiers until we reach the top
|
||||
while (1) {
|
||||
remaining_height = _height - bottom;
|
||||
section_depth = back - front;
|
||||
section_width = right - left;
|
||||
section_height = MAX (remaining_height / tier_fraction, 2);
|
||||
if (remaining_height < 10)
|
||||
section_height = remaining_height;
|
||||
//Build the four walls
|
||||
uv_start = (float)RandomVal (SEGMENTS_PER_TEXTURE) / SEGMENTS_PER_TEXTURE;
|
||||
uv_start = ConstructWall (left, bottom, back, SOUTH, section_depth, section_height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (left, bottom, front, EAST, section_width, section_height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (right, bottom, front, NORTH, section_depth, section_height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
uv_start = ConstructWall (right, bottom, back, WEST, section_width, section_height, grouping, uv_start, blank_corners) - ONE_SEGMENT;
|
||||
bottom += section_height;
|
||||
//Build the slab / ledges to cap this section.
|
||||
if (bottom + ledge_height > _height)
|
||||
break;
|
||||
ConstructCube ((float)left - ledge, (float)right + ledge, (float)front - ledge, (float)back + ledge, (float)bottom, (float)(bottom + ledge_height));
|
||||
bottom += ledge_height;
|
||||
if (bottom > _height)
|
||||
break;
|
||||
if (ledge_height > 1 && narrowing)
|
||||
ledge_height--;
|
||||
if (narrowing) {
|
||||
if (section_width > 7) {
|
||||
left+=1;
|
||||
right-=1;
|
||||
}
|
||||
if (section_depth > 7) {
|
||||
front+=1;
|
||||
back-=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ConstructRoof ((float)left, (float)right, (float)front, (float)back, (float)bottom);
|
||||
_mesh->Compile ();
|
||||
_mesh_flat->Compile ();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef ENTITY
|
||||
#include "entity.h"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
BUILDING_SIMPLE,
|
||||
BUILDING_BLOCKY,
|
||||
BUILDING_MODERN,
|
||||
BUILDING_TOWER
|
||||
};
|
||||
|
||||
class CBuilding : public CEntity
|
||||
{
|
||||
private:
|
||||
|
||||
int _x;
|
||||
int _y;
|
||||
int _width;
|
||||
int _depth;
|
||||
int _height;
|
||||
int _texture_type;
|
||||
int _seed;
|
||||
int _roof_tiers;
|
||||
GLrgba _color;
|
||||
GLrgba _trim_color;
|
||||
class CMesh* _mesh;
|
||||
class CMesh* _mesh_flat;
|
||||
bool _have_lights;
|
||||
bool _have_trim;
|
||||
bool _have_logo;
|
||||
|
||||
|
||||
void CreateSimple ();
|
||||
void CreateBlocky ();
|
||||
void CreateModern ();
|
||||
void CreateTower ();
|
||||
|
||||
float ConstructWall (int start_x, int start_y, int start_z, int direction, int length, int height, int window_groups, float uv_start, bool blank_corners);
|
||||
void ConstructSpike (int left, int right, int front, int back, int bottom, int top);
|
||||
void ConstructCube (int left, int right, int front, int back, int bottom, int top);
|
||||
void ConstructCube (float left, float right, float front, float back, float bottom, float top);
|
||||
void ConstructRoof (float left, float right, float front, float back, float bottom);
|
||||
|
||||
public:
|
||||
CBuilding (int type, int x, int y, int height, int width, int depth, int seed, GLrgba color);
|
||||
~CBuilding ();
|
||||
void Render (void);
|
||||
int PolyCount ();
|
||||
void RenderFlat (bool colored);
|
||||
unsigned Texture ();
|
||||
|
||||
};
|
|
@ -0,0 +1,403 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Camera.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This tracks the position and oritentation of the camera. In screensaver
|
||||
mode, it moves the camera around the world in order to create dramatic
|
||||
views of the hot zone.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define EYE_HEIGHT 2.0f
|
||||
#define MAX_PITCH 85
|
||||
#define FLYCAM_CIRCUT 60000
|
||||
#define FLYCAM_CIRCUT_HALF (FLYCAM_CIRCUT / 2)
|
||||
#define FLYCAM_LEG (FLYCAM_CIRCUT / 4)
|
||||
#define ONE_SECOND 1000
|
||||
#define CAMERA_CHANGE_INTERVAL 15
|
||||
#define CAMERA_CYCLE_LENGTH (CAMERA_MODES*CAMERA_CHANGE_INTERVAL)
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "glTypes.h"
|
||||
#include "ini.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "world.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CAMERA_FLYCAM1,
|
||||
CAMERA_ORBIT_INWARD,
|
||||
CAMERA_ORBIT_OUTWARD,
|
||||
CAMERA_ORBIT_ELLIPTICAL,
|
||||
CAMERA_FLYCAM2,
|
||||
CAMERA_SPEED,
|
||||
CAMERA_SPIN,
|
||||
CAMERA_FLYCAM3,
|
||||
CAMERA_MODES
|
||||
};
|
||||
|
||||
static GLvector angle;
|
||||
static GLvector position;
|
||||
static GLvector auto_angle;
|
||||
static GLvector auto_position;
|
||||
static float distance;
|
||||
static float movement;
|
||||
static bool moving;
|
||||
static bool cam_auto;
|
||||
static float tracker;
|
||||
static unsigned last_update;
|
||||
static int camera_behavior;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
static GLvector flycam_position (unsigned t)
|
||||
{
|
||||
|
||||
unsigned leg;
|
||||
float delta;
|
||||
GLvector start, end;
|
||||
GLbbox hot_zone;
|
||||
|
||||
hot_zone = WorldHotZone ();
|
||||
t %= FLYCAM_CIRCUT;
|
||||
leg = t / FLYCAM_LEG;
|
||||
delta = (float)(t % FLYCAM_LEG) / FLYCAM_LEG;
|
||||
switch (leg) {
|
||||
case 0:
|
||||
start = glVector (hot_zone.min.x, 25.0f, hot_zone.min.z);
|
||||
end = glVector (hot_zone.min.x, 60.0f, hot_zone.max.z);
|
||||
break;
|
||||
case 1:
|
||||
start = glVector (hot_zone.min.x, 60.0f, hot_zone.max.z);
|
||||
end = glVector (hot_zone.max.x, 25.0f, hot_zone.max.z);
|
||||
break;
|
||||
case 2:
|
||||
start = glVector (hot_zone.max.x, 25.0f, hot_zone.max.z);
|
||||
end = glVector (hot_zone.max.x, 60.0f, hot_zone.min.z);
|
||||
break;
|
||||
case 3:
|
||||
start = glVector (hot_zone.max.x, 60.0f, hot_zone.min.z);
|
||||
end = glVector (hot_zone.min.x, 25.0f, hot_zone.min.z);
|
||||
break;
|
||||
}
|
||||
delta = MathScalarCurve (delta);
|
||||
return glVectorInterpolate (start, end, delta);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_auto_cam ()
|
||||
{
|
||||
|
||||
float dist;
|
||||
unsigned t;
|
||||
unsigned elapsed;
|
||||
unsigned now;
|
||||
int behavior;
|
||||
GLvector target;
|
||||
|
||||
now = GetTickCount ();
|
||||
elapsed = now - last_update;
|
||||
elapsed = MIN (elapsed, 1000); //limit to 1 second worth of time
|
||||
if (elapsed == 0)
|
||||
return;
|
||||
last_update = now;
|
||||
t = time (NULL) % CAMERA_CYCLE_LENGTH;
|
||||
#if SCREENSAVER
|
||||
behavior = t / CAMERA_CHANGE_INTERVAL;
|
||||
#else
|
||||
behavior = camera_behavior;
|
||||
#endif
|
||||
tracker += (float)elapsed / 100.0f;
|
||||
//behavior = CAMERA_FLYCAM1;
|
||||
switch (behavior) {
|
||||
case CAMERA_ORBIT_INWARD:
|
||||
auto_position.x = WORLD_HALF + sinf (tracker * DEGREES_TO_RADIANS) * 150.0f;
|
||||
auto_position.y = 60.0f;
|
||||
auto_position.z = WORLD_HALF + cosf (tracker * DEGREES_TO_RADIANS) * 150.0f;
|
||||
target = glVector (WORLD_HALF, 40.0f, WORLD_HALF);
|
||||
break;
|
||||
case CAMERA_ORBIT_OUTWARD:
|
||||
auto_position.x = WORLD_HALF + sinf (tracker * DEGREES_TO_RADIANS) * 250.0f;
|
||||
auto_position.y = 60.0f;
|
||||
auto_position.z = WORLD_HALF + cosf (tracker * DEGREES_TO_RADIANS) * 250.0f;
|
||||
target = glVector (WORLD_HALF, 30.0f, WORLD_HALF);
|
||||
break;
|
||||
case CAMERA_ORBIT_ELLIPTICAL:
|
||||
dist = 150.0f + sinf (tracker * DEGREES_TO_RADIANS / 1.1f) * 50;
|
||||
auto_position.x = WORLD_HALF + sinf (tracker * DEGREES_TO_RADIANS) * dist;
|
||||
auto_position.y = 60.0f;
|
||||
auto_position.z = WORLD_HALF + cosf (tracker * DEGREES_TO_RADIANS) * dist;
|
||||
target = glVector (WORLD_HALF, 50.0f, WORLD_HALF);
|
||||
break;
|
||||
case CAMERA_FLYCAM1:
|
||||
case CAMERA_FLYCAM2:
|
||||
case CAMERA_FLYCAM3:
|
||||
auto_position = (flycam_position (now) + flycam_position (now + 4000)) / 2.0f;
|
||||
target = flycam_position (now + FLYCAM_CIRCUT_HALF - ONE_SECOND * 3);
|
||||
break;
|
||||
case CAMERA_SPEED:
|
||||
auto_position = (flycam_position (now) + flycam_position (now + 500)) / 2.0f;
|
||||
target = flycam_position (now + ONE_SECOND * 5);
|
||||
auto_position.y /= 2;
|
||||
target.y /= 2;
|
||||
break;
|
||||
case CAMERA_SPIN:
|
||||
default:
|
||||
target.x = WORLD_HALF + sinf (tracker * DEGREES_TO_RADIANS) * 300.0f;
|
||||
target.y = 30.0f;
|
||||
target.z = WORLD_HALF + cosf (tracker * DEGREES_TO_RADIANS) * 300.0f;
|
||||
auto_position.x = WORLD_HALF + sinf (tracker * DEGREES_TO_RADIANS) * 50.0f;
|
||||
auto_position.y = 60.0f;
|
||||
auto_position.z = WORLD_HALF + cosf (tracker * DEGREES_TO_RADIANS) * 50.0f;
|
||||
}
|
||||
dist = MathDistance (auto_position.x, auto_position.z, target.x, target.z);
|
||||
auto_angle.y = MathAngle (-MathAngle (auto_position.x, auto_position.z, target.x, target.z));
|
||||
auto_angle.x = 90.0f + MathAngle (0, auto_position.y, dist, target.y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraAutoToggle ()
|
||||
{
|
||||
|
||||
cam_auto = !cam_auto;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraNextBehavior ()
|
||||
{
|
||||
|
||||
camera_behavior++;
|
||||
camera_behavior %= CAMERA_MODES;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraYaw (float delta)
|
||||
{
|
||||
|
||||
moving = true;
|
||||
angle.y -= delta;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraPitch (float delta)
|
||||
{
|
||||
|
||||
moving = true;
|
||||
angle.x -= delta;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraPan (float delta)
|
||||
{
|
||||
|
||||
float move_x, move_y;
|
||||
|
||||
moving = true;
|
||||
move_x = (float)sin (-angle.y * DEGREES_TO_RADIANS) / 10.0f;
|
||||
move_y = (float)cos (-angle.y * DEGREES_TO_RADIANS) / 10.0f;
|
||||
position.x -= move_y * delta;
|
||||
position.z -= -move_x * delta;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraForward (float delta)
|
||||
{
|
||||
|
||||
float move_x, move_y;
|
||||
|
||||
moving = true;
|
||||
move_y = (float)sin (-angle.y * DEGREES_TO_RADIANS) / 10.0f;
|
||||
move_x = (float)cos (-angle.y * DEGREES_TO_RADIANS) / 10.0f;
|
||||
position.x -= move_y * delta;
|
||||
position.z -= move_x * delta;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraSelectionPitch (float delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraSelectionZoom (float delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraSelectionYaw (float delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector CameraPosition (void)
|
||||
{
|
||||
|
||||
if (cam_auto)
|
||||
return auto_position;
|
||||
return position;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraReset ()
|
||||
{
|
||||
|
||||
position.y = 50.0f;
|
||||
position.x = WORLD_HALF;
|
||||
position.z = WORLD_HALF;
|
||||
angle.x = 0.0f;
|
||||
angle.y = 0.0f;
|
||||
angle.z = 0.0f;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraPositionSet (GLvector new_pos)
|
||||
{
|
||||
|
||||
position = new_pos;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector CameraAngle (void)
|
||||
{
|
||||
|
||||
if (cam_auto)
|
||||
return auto_angle;
|
||||
return angle;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraAngleSet (GLvector new_angle)
|
||||
{
|
||||
|
||||
angle = new_angle;
|
||||
angle.x = CLAMP (angle.x, -80.0f, 80.0f);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraInit (void)
|
||||
{
|
||||
|
||||
angle = IniVector ("CameraAngle");
|
||||
position = IniVector ("CameraPosition");
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraUpdate (void)
|
||||
{
|
||||
|
||||
#if SCREENSAVER
|
||||
cam_auto = true;
|
||||
#endif
|
||||
if (cam_auto)
|
||||
do_auto_cam ();
|
||||
if (moving)
|
||||
movement *= 1.1f;
|
||||
else
|
||||
movement = 0.0f;
|
||||
movement = CLAMP (movement, 0.01f, 1.0f);
|
||||
|
||||
if (angle.y < 0.0f)
|
||||
angle.y = 360.0f - (float)fmod (fabs (angle.y), 360.0f);
|
||||
angle.y = (float)fmod (angle.y, 360.0f);
|
||||
angle.x = CLAMP (angle.x, -MAX_PITCH, MAX_PITCH);
|
||||
moving = false;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CameraTerm (void)
|
||||
{
|
||||
|
||||
//just store our most recent position in the ini
|
||||
IniVectorSet ("CameraAngle", angle);
|
||||
IniVectorSet ("CameraPosition", position);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef TYPES
|
||||
#include "glTypes.h"
|
||||
#endif
|
||||
|
||||
GLvector CameraAngle (void);
|
||||
void CameraAngleSet (GLvector new_angle);
|
||||
void CameraAutoToggle ();
|
||||
float CameraDistance (void);
|
||||
void CameraDistanceSet (float new_distance);
|
||||
void CameraInit (void);
|
||||
void CameraNextBehavior (void);
|
||||
GLvector CameraPosition (void);
|
||||
void CameraPositionSet (GLvector new_pos);
|
||||
void CameraReset ();
|
||||
void CameraUpdate (void);
|
||||
void CameraTerm (void);
|
||||
|
||||
void CameraForward (float delta);
|
||||
void CameraSelectionPitch (float delta_y);
|
||||
void CameraSelectionYaw (float delta_x);
|
||||
void CameraSelectionZoom (float delta_y);
|
||||
void CameraPan (float delta_x);
|
||||
void CameraPitch (float delta_y);
|
||||
void CameraYaw (float delta_x);
|
|
@ -0,0 +1,322 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Car.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This creates the little two-triangle cars and moves them around the map.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define DEAD_ZONE 200
|
||||
#define STUCK_TIME 230
|
||||
#define UPDATE_INTERVAL 50 //milliseconds
|
||||
#define MOVEMENT_SPEED 0.61f
|
||||
#define CAR_SIZE 3.0f
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "building.h"
|
||||
#include "car.h"
|
||||
#include "camera.h"
|
||||
#include "mesh.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
#include "visible.h"
|
||||
|
||||
static GLvector direction[] =
|
||||
{
|
||||
0.0f, 0.0f, -1.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
-1.0f, 0.0f, 0.0f,
|
||||
};
|
||||
|
||||
static int dangles[] = { 0, 90, 180, 270};
|
||||
|
||||
static GLvector2 angles[360];
|
||||
static bool angles_done;
|
||||
static unsigned char carmap[WORLD_SIZE][WORLD_SIZE];
|
||||
static CCar* head;
|
||||
static unsigned next_update;
|
||||
static int count;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int CarCount ()
|
||||
{
|
||||
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CarClear ()
|
||||
{
|
||||
|
||||
CCar* c;
|
||||
|
||||
for (c = head; c; c = c->m_next)
|
||||
c->Park ();
|
||||
ZeroMemory (carmap, sizeof (carmap));
|
||||
count = 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CarRender ()
|
||||
{
|
||||
|
||||
CCar* c;
|
||||
|
||||
if (!angles_done) {
|
||||
for (int i = 0 ;i < 360; i++) {
|
||||
angles[i].x = cosf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE;
|
||||
angles[i].y = sinf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE;
|
||||
}
|
||||
}
|
||||
glDepthMask (false);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBindTexture (GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_HEADLIGHT));
|
||||
for (c = head; c; c = c->m_next)
|
||||
c->Render ();
|
||||
glDepthMask (true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CarUpdate ()
|
||||
{
|
||||
|
||||
CCar* c;
|
||||
unsigned now;
|
||||
|
||||
if (!TextureReady () || !EntityReady ())
|
||||
return;
|
||||
now = GetTickCount ();
|
||||
if (next_update > now)
|
||||
return;
|
||||
next_update = now + UPDATE_INTERVAL;
|
||||
for (c = head; c; c = c->m_next)
|
||||
c->Update ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CCar::CCar ()
|
||||
{
|
||||
|
||||
m_ready = false;
|
||||
m_next = head;
|
||||
head = this;
|
||||
count++;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool CCar::TestPosition (int row, int col)
|
||||
{
|
||||
|
||||
//test the given position and see if it's already occupied
|
||||
if (carmap[row][col])
|
||||
return false;
|
||||
//now make sure that the lane is going the right direction
|
||||
if (WorldCell (row, col) != WorldCell (m_row, m_col))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CCar::Update (void)
|
||||
{
|
||||
|
||||
int new_row, new_col;
|
||||
GLvector old_pos;
|
||||
GLvector camera;
|
||||
|
||||
//If the car isn't ready, place it on the map and get it moving
|
||||
camera = CameraPosition ();
|
||||
if (!m_ready) {
|
||||
//if the car isn't ready, we need to place it somewhere on the map
|
||||
m_row = DEAD_ZONE + RandomVal (WORLD_SIZE - DEAD_ZONE * 2);
|
||||
m_col = DEAD_ZONE + RandomVal (WORLD_SIZE - DEAD_ZONE * 2);
|
||||
//if there is already a car here, forget it.
|
||||
if (carmap[m_row][m_col] > 0)
|
||||
return;
|
||||
//if this spot is not a road, forget it
|
||||
if (!(WorldCell (m_row, m_col) & CLAIM_ROAD))
|
||||
return;
|
||||
if (!Visible (glVector ((float)m_row, 0.0f, (float)m_col)))
|
||||
return;
|
||||
//good spot. place the car
|
||||
m_position = glVector ((float)m_row, 0.1f, (float)m_col);
|
||||
m_drive_position = m_position;
|
||||
m_ready = true;
|
||||
if (WorldCell (m_row, m_col) & MAP_ROAD_NORTH)
|
||||
m_direction = NORTH;
|
||||
if (WorldCell (m_row, m_col) & MAP_ROAD_EAST)
|
||||
m_direction = EAST;
|
||||
if (WorldCell (m_row, m_col) & MAP_ROAD_SOUTH)
|
||||
m_direction = SOUTH;
|
||||
if (WorldCell (m_row, m_col) & MAP_ROAD_WEST)
|
||||
m_direction = WEST;
|
||||
m_drive_angle = dangles[m_direction];
|
||||
m_max_speed = (float)(4 + RandomVal (6)) / 10.0f;
|
||||
m_speed = 0.0f;
|
||||
m_change = 3;
|
||||
m_stuck = 0;
|
||||
carmap[m_row][m_col]++;
|
||||
}
|
||||
//take the car off the map and move it
|
||||
carmap[m_row][m_col]--;
|
||||
old_pos = m_position;
|
||||
m_speed += m_max_speed * 0.05f;
|
||||
m_speed = MIN (m_speed, m_max_speed);
|
||||
m_position += direction[m_direction] * MOVEMENT_SPEED * m_speed;
|
||||
//If the car has moved out of view, there's no need to keep simulating it.
|
||||
if (!Visible (glVector ((float)m_row, 0.0f, (float)m_col)))
|
||||
m_ready = false;
|
||||
//if the car is far away, remove it. We use manhattan units because buildings almost always
|
||||
//block views of cars on the diagonal.
|
||||
if (fabs (camera.x - m_position.x) + fabs (camera.z - m_position.z) > RenderFogDistance ())
|
||||
m_ready = false;
|
||||
//if the car gets too close to the edge of the map, take it out of play
|
||||
if (m_position.x < DEAD_ZONE || m_position.x > (WORLD_SIZE - DEAD_ZONE))
|
||||
m_ready = false;
|
||||
if (m_position.z < DEAD_ZONE || m_position.z > (WORLD_SIZE - DEAD_ZONE))
|
||||
m_ready = false;
|
||||
if (m_stuck >= STUCK_TIME)
|
||||
m_ready = false;
|
||||
if (!m_ready)
|
||||
return;
|
||||
//Check the new position and make sure its not in another car
|
||||
new_row = (int)m_position.x;
|
||||
new_col = (int)m_position.z;
|
||||
if (new_row != m_row || new_col != m_col) {
|
||||
//see if the new position places us on top of another car
|
||||
if (carmap[new_row][new_col]) {
|
||||
m_position = old_pos;
|
||||
m_speed = 0.0f;
|
||||
m_stuck++;
|
||||
} else {
|
||||
//look at the new position and decide if we're heading towards or away from the camera
|
||||
m_row = new_row;
|
||||
m_col = new_col;
|
||||
m_change--;
|
||||
m_stuck = 0;
|
||||
if (m_direction == NORTH)
|
||||
m_front = camera.z < m_position.z;
|
||||
else if (m_direction == SOUTH)
|
||||
m_front = camera.z > m_position.z;
|
||||
else if (m_direction == EAST)
|
||||
m_front = camera.x > m_position.x;
|
||||
else
|
||||
m_front = camera.x < m_position.x;
|
||||
}
|
||||
}
|
||||
m_drive_position = (m_drive_position + m_position) / 2.0f;
|
||||
//place the car back on the map
|
||||
carmap[m_row][m_col]++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CCar::Render ()
|
||||
{
|
||||
|
||||
GLvector pos;
|
||||
int angle;
|
||||
int turn;
|
||||
|
||||
if (!m_ready)
|
||||
return;
|
||||
if (!Visible (m_drive_position))
|
||||
return;
|
||||
if (m_front)
|
||||
glColor3f (1, 1, 0.8f);
|
||||
else
|
||||
glColor3f (1, 0.2f, 0);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
angle = dangles[m_direction];
|
||||
pos = m_drive_position;//
|
||||
angle = 360 - (int)MathAngle (m_position.x, m_position.z, pos.x, pos.z);
|
||||
angle %= 360;
|
||||
turn = (int)MathAngleDifference ((float)m_drive_angle, (float)angle);
|
||||
m_drive_angle += SIGN (turn);
|
||||
pos += glVector (0.5f, 0.0f, 0.5f);
|
||||
|
||||
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex3f (pos.x + angles[angle].x, -CAR_SIZE, pos.z + angles[angle].y);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex3f (pos.x - angles[angle].x, -CAR_SIZE, pos.z - angles[angle].y);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex3f (pos.x - angles[angle].x, CAR_SIZE, pos.z - angles[angle].y);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex3f (pos.x + angles[angle].x, CAR_SIZE, pos.z + angles[angle].y);
|
||||
|
||||
|
||||
/*
|
||||
glVertex3f (m_position.x, m_position.y, m_position.z);
|
||||
glVertex3f (m_position.x, m_position.y, m_position.z + 1);
|
||||
glVertex3f (m_position.x + 1, m_position.y, m_position.z + 1);
|
||||
glVertex3f (m_position.x + 1, m_position.y, m_position.z);
|
||||
*/
|
||||
/*
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex3f (m_position.x, m_position.y, m_position.z + 0.2f);
|
||||
glTexCoord2f (0, 2);
|
||||
glVertex3f (m_position.x, m_position.y, m_position.z + 1 - 0.2f);
|
||||
glTexCoord2f (1, 2);
|
||||
glVertex3f (m_position.x + 1, m_position.y, m_position.z + 1 - 0.2f);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex3f (m_position.x + 1, m_position.y, m_position.z + 0.2f);
|
||||
|
||||
*/
|
||||
|
||||
glEnd ();
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
class CCar
|
||||
{
|
||||
GLvector m_position;
|
||||
GLvector m_drive_position;
|
||||
bool m_ready;
|
||||
bool m_front;
|
||||
int m_drive_angle;
|
||||
int m_row;
|
||||
int m_col;
|
||||
int m_direction;
|
||||
int m_change;
|
||||
int m_stuck;
|
||||
float m_speed;
|
||||
float m_max_speed;
|
||||
|
||||
public:
|
||||
CCar ();
|
||||
bool TestPosition (int row, int col);
|
||||
void Render ();
|
||||
void Update ();
|
||||
void Park () { m_ready = false;}
|
||||
class CCar* m_next;
|
||||
|
||||
};
|
||||
|
||||
void CarClear ();
|
||||
int CarCount ();
|
||||
void CarRender ();
|
||||
void CarUpdate ();
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Deco.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This handles building and rendering decoration objects - infrastructure &
|
||||
such around the city.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define LOGO_OFFSET 0.2f //How far a logo sticks out from the given surface
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "deco.h"
|
||||
#include "light.h"
|
||||
#include "mesh.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
#include "visible.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CDeco::CDeco ()
|
||||
{
|
||||
|
||||
_mesh = new CMesh ();
|
||||
_use_alpha = false;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::Render ()
|
||||
{
|
||||
|
||||
glColor3fv (&_color.red);
|
||||
_mesh->Render ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::RenderFlat (bool colored)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool CDeco::Alpha ()
|
||||
{
|
||||
|
||||
return _use_alpha;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int CDeco::PolyCount ()
|
||||
{
|
||||
|
||||
return _mesh->PolyCount ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned CDeco::Texture ()
|
||||
{
|
||||
|
||||
return _texture;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::CreateRadioTower (GLvector pos, float height)
|
||||
{
|
||||
|
||||
CLight* l;
|
||||
float offset;
|
||||
GLvertex v;
|
||||
int index_list[] = {0,1,2,3,4,5};
|
||||
|
||||
offset = height / 15.0f;
|
||||
_center = pos;
|
||||
_use_alpha = true;
|
||||
//Radio tower
|
||||
v.position = glVector (_center.x, _center.y + height, _center.z); v.uv = glVector (0,1);
|
||||
_mesh->VertexAdd (v);
|
||||
v.position = glVector (_center.x - offset, _center.y, _center.z - offset); v.uv = glVector (1,0);
|
||||
_mesh->VertexAdd (v);
|
||||
v.position = glVector (_center.x + offset, _center.y, _center.z - offset); v.uv = glVector (0,0);
|
||||
_mesh->VertexAdd (v);
|
||||
v.position = glVector (_center.x + offset, _center.y, _center.z + offset); v.uv = glVector (1,0);
|
||||
_mesh->VertexAdd (v);
|
||||
v.position = glVector (_center.x - offset, _center.y, _center.z + offset); v.uv = glVector (0,0);
|
||||
_mesh->VertexAdd (v);
|
||||
v.position = glVector (_center.x - offset, _center.y, _center.z - offset); v.uv = glVector (1,0);
|
||||
_mesh->VertexAdd (v);
|
||||
_mesh->FanAdd (&index_list[0], 6);
|
||||
l = new CLight (glVector (_center.x, _center.y + height + 1.0f, _center.z), glRgba (255,192,160), 1);
|
||||
l->Blink ();
|
||||
_texture = TextureId (TEXTURE_LATTICE);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::CreateLogo (GLvector2 start, GLvector2 end, float bottom, int seed, GLrgba color)
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
int index_list[] = {0,1,3,2};
|
||||
float u1, u2, v1, v2;
|
||||
float top;
|
||||
float height, length;
|
||||
GLvector2 center2d;
|
||||
GLvector to;
|
||||
GLvector out;
|
||||
int logo_index;
|
||||
|
||||
_use_alpha = true;
|
||||
_color = color;
|
||||
logo_index = seed % LOGO_ROWS;
|
||||
to = glVector (start.x, 0.0f, start.y) - glVector (end.x, 0.0f, end.y);
|
||||
to = glVectorNormalize (to);
|
||||
out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET;
|
||||
center2d = (start + end) / 2;
|
||||
_center = glVector (center2d.x, bottom, center2d.y);
|
||||
length = glVectorLength (start - end);
|
||||
height = (length / 8.0f) * 1.5f;
|
||||
top = bottom + height;
|
||||
u1 = 0.0f;
|
||||
u2 = 0.5f;//We actually only use the left half of the texture
|
||||
v1 = (float)logo_index / LOGO_ROWS;
|
||||
v2 = v1 + (1.0f / LOGO_ROWS);
|
||||
p.position = glVector (start.x, bottom, start.y) + out; p.uv = glVector (u1,v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (end.x, bottom, end.y) + out; p.uv = glVector (u2, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (end.x, top, end.y) + out; p.uv = glVector (u2, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (start.x, top, start.y) + out; p.uv = glVector (u1, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
_mesh->QuadStripAdd (&index_list[0], 4);
|
||||
_texture = TextureId (TEXTURE_LOGOS);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::CreateLightStrip (float x, float z, float width, float depth, float height, GLrgba color)
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
int index_list1[] = {0,1,3,2};
|
||||
int index_list2[] = {4,5,7,6};
|
||||
float u, v;
|
||||
|
||||
_color = color;
|
||||
_use_alpha = true;
|
||||
_center = glVector (x + width / 2, height, z + depth / 2);
|
||||
if (width < depth) {
|
||||
u = 1.0f;
|
||||
v = (float)((int)(depth / width));
|
||||
} else {
|
||||
v = 1.0f;
|
||||
u = (float)((int)(width / depth));
|
||||
}
|
||||
//u = MAX (width, 1);
|
||||
//v = MAX (depth, 1);
|
||||
_texture = TextureId (TEXTURE_LIGHT);
|
||||
p.position = glVector (x, height, z); p.uv = glVector (0.0f, 0.0f);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x, height, z + depth); p.uv = glVector (0.0f, v);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x + width, height, z + depth); p.uv = glVector (u, v);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x + width, height, z); p.uv = glVector (u, 0.0f);
|
||||
_mesh->VertexAdd (p);
|
||||
|
||||
p.position = glVector (x - 1, height, z - 1); p.uv = glVector (0, 0);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x - 1, height, z + depth + 1); p.uv = glVector (0, 1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x + width + 1, height, z + depth + 1); p.uv = glVector (1, 1);
|
||||
_mesh->VertexAdd (p);
|
||||
p.position = glVector (x + width + 1, height, z - 1); p.uv = glVector (1, 0);
|
||||
_mesh->VertexAdd (p);
|
||||
|
||||
_mesh->QuadStripAdd (&index_list1[0], 4);
|
||||
//_mesh->QuadStripAdd (&index_list2[0], 4);
|
||||
_mesh->Compile ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CDeco::CreateLightTrim (GLvector* chain, int count, float height, int seed, GLrgba color)
|
||||
{
|
||||
|
||||
GLvertex p;
|
||||
GLvector to;
|
||||
GLvector out;
|
||||
int i;
|
||||
int index;
|
||||
int prev, next;
|
||||
float u, v1, v2;
|
||||
float row;
|
||||
int* index_list;
|
||||
|
||||
_color = color;
|
||||
_center = glVector (0.0f, 0.0f, 0.0f);
|
||||
index_list = new int[count * 2 + 2];
|
||||
for (i = 0; i < count; i++)
|
||||
_center += chain[i];
|
||||
_center /= (float)count;
|
||||
row = (float)(seed % TRIM_ROWS);
|
||||
v1 = row * TRIM_SIZE;
|
||||
v2 = (row + 1.0f) * TRIM_SIZE;
|
||||
index = 0;
|
||||
u = 0.0f;
|
||||
for (i = 0; i < count + 1; i++) {
|
||||
if (i)
|
||||
u += glVectorLength (chain[i % count] - p.position) * 0.1f;
|
||||
//Add the bottom point
|
||||
prev = i - 1;
|
||||
if (prev < 0)
|
||||
prev = count + prev;
|
||||
next = (i + 1) % count;
|
||||
to = glVectorNormalize (chain[next] - chain[prev]);
|
||||
out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET;
|
||||
p.position = chain[i % count] + out; p.uv = glVector (u, v2);
|
||||
_mesh->VertexAdd (p);
|
||||
index_list[index] = index;
|
||||
index++;
|
||||
//Top point
|
||||
p.position.y += height;p.uv = glVector (u, v1);
|
||||
_mesh->VertexAdd (p);
|
||||
index_list[index] = index;
|
||||
index++;
|
||||
}
|
||||
_mesh->QuadStripAdd (index_list, index);
|
||||
delete index_list;
|
||||
_texture = TextureId (TEXTURE_TRIM);
|
||||
_mesh->Compile ();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef ENTITY
|
||||
#include "entity.h"
|
||||
#endif
|
||||
|
||||
class CDeco : CEntity
|
||||
{
|
||||
// CDeco* _next;
|
||||
GLrgba _color;
|
||||
class CMesh* _mesh;
|
||||
int _type;
|
||||
unsigned _texture;
|
||||
bool _use_alpha;
|
||||
|
||||
public:
|
||||
|
||||
CDeco ();
|
||||
void CreateLogo (GLvector2 start, GLvector2 end, float base, int seed, GLrgba color);
|
||||
void CreateLightStrip (float x, float z, float width, float depth, float height, GLrgba color);
|
||||
void CreateLightTrim (GLvector* chain, int count, float height, int seed, GLrgba color);
|
||||
void CreateRadioTower (GLvector pos, float height);
|
||||
void Render (void);
|
||||
void RenderFlat (bool colored);
|
||||
bool Alpha ();
|
||||
int PolyCount ();
|
||||
|
||||
unsigned Texture ();
|
||||
|
||||
};
|
|
@ -0,0 +1,412 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Entity.cpp
|
||||
|
||||
Copyright (c) 2005 Shamus Young
|
||||
All Rights Reserved
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
An entity is any renderable stationary object in the world. This is an
|
||||
abstract class. This module gathers up the Entities, sorts them by
|
||||
texture use and location, and then stores them in OpenGL render lists
|
||||
for faster rendering.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
|
||||
#include "camera.h"
|
||||
#include "entity.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
#include "visible.h"
|
||||
|
||||
struct entity
|
||||
{
|
||||
CEntity* object;
|
||||
};
|
||||
|
||||
|
||||
struct cell
|
||||
{
|
||||
unsigned list_textured;
|
||||
unsigned list_flat;
|
||||
unsigned list_flat_wireframe;
|
||||
unsigned list_alpha;
|
||||
GLvector pos;
|
||||
};
|
||||
|
||||
static cell cell_list[GRID_SIZE][GRID_SIZE];
|
||||
static int entity_count;
|
||||
static entity* entity_list;
|
||||
static bool sorted;
|
||||
static bool compiled;
|
||||
static int polycount;
|
||||
static int compile_x;
|
||||
static int compile_y;
|
||||
static int compile_count;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int do_compare (const void *arg1, const void *arg2 )
|
||||
{
|
||||
|
||||
struct entity* e1 = (struct entity*)arg1;
|
||||
struct entity* e2 = (struct entity*)arg2;
|
||||
|
||||
if (e1->object->Alpha () && !e2->object->Alpha ())
|
||||
return 1;
|
||||
if (!e1->object->Alpha () && e2->object->Alpha ())
|
||||
return -1;
|
||||
if (e1->object->Texture () > e2->object->Texture ())
|
||||
return 1;
|
||||
else if (e1->object->Texture () < e2->object->Texture ())
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void add (CEntity* b)
|
||||
{
|
||||
|
||||
entity_list = (entity*)realloc (entity_list, sizeof (entity) * (entity_count + 1));
|
||||
entity_list[entity_count].object = b;
|
||||
entity_count++;
|
||||
polycount = 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_compile ()
|
||||
{
|
||||
|
||||
int i;
|
||||
int x, y;
|
||||
|
||||
if (compiled)
|
||||
return;
|
||||
x = compile_x;
|
||||
y = compile_y;
|
||||
//Changing textures is pretty expensive, and thus sorting the entites so that
|
||||
//they are grouped by texture used can really improve framerate.
|
||||
//qsort (entity_list, entity_count, sizeof (struct entity), do_compare);
|
||||
//sorted = true;
|
||||
//Now group entites on the grid
|
||||
//make a list for the textured objects in this region
|
||||
if (!cell_list[x][y].list_textured)
|
||||
cell_list[x][y].list_textured = glGenLists(1);
|
||||
glNewList (cell_list[x][y].list_textured, GL_COMPILE);
|
||||
cell_list[x][y].pos = glVector (GRID_TO_WORLD(x), 0.0f, (float)y * GRID_RESOLUTION);
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
GLvector pos = entity_list[i].object->Center ();
|
||||
if (WORLD_TO_GRID(pos.x) == x && WORLD_TO_GRID(pos.z) == y && !entity_list[i].object->Alpha ()) {
|
||||
glBindTexture(GL_TEXTURE_2D, entity_list[i].object->Texture ());
|
||||
entity_list[i].object->Render ();
|
||||
}
|
||||
}
|
||||
glEndList();
|
||||
|
||||
//Make a list of flat-color stuff (A/C units, ledges, roofs, etc.)
|
||||
if (!cell_list[x][y].list_flat)
|
||||
cell_list[x][y].list_flat = glGenLists(1);
|
||||
glNewList (cell_list[x][y].list_flat, GL_COMPILE);
|
||||
glEnable (GL_CULL_FACE);
|
||||
cell_list[x][y].pos = glVector (GRID_TO_WORLD(x), 0.0f, (float)y * GRID_RESOLUTION);
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
GLvector pos = entity_list[i].object->Center ();
|
||||
if (WORLD_TO_GRID(pos.x) == x && WORLD_TO_GRID(pos.z) == y && !entity_list[i].object->Alpha ()) {
|
||||
entity_list[i].object->RenderFlat (false);
|
||||
}
|
||||
}
|
||||
glEndList();
|
||||
//Now a list of flat-colored stuff that will be wireframe friendly
|
||||
if (!cell_list[x][y].list_flat_wireframe)
|
||||
cell_list[x][y].list_flat_wireframe = glGenLists(1);
|
||||
glNewList (cell_list[x][y].list_flat_wireframe, GL_COMPILE);
|
||||
glEnable (GL_CULL_FACE);
|
||||
cell_list[x][y].pos = glVector (GRID_TO_WORLD(x), 0.0f, (float)y * GRID_RESOLUTION);
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
GLvector pos = entity_list[i].object->Center ();
|
||||
if (WORLD_TO_GRID(pos.x) == x && WORLD_TO_GRID(pos.z) == y && !entity_list[i].object->Alpha ()) {
|
||||
entity_list[i].object->RenderFlat (true);
|
||||
}
|
||||
}
|
||||
glEndList();
|
||||
//Now a list of stuff to be alpha-blended, and thus rendered last
|
||||
if (!cell_list[x][y].list_alpha)
|
||||
cell_list[x][y].list_alpha = glGenLists(1);
|
||||
glNewList (cell_list[x][y].list_alpha, GL_COMPILE);
|
||||
cell_list[x][y].pos = glVector (GRID_TO_WORLD(x), 0.0f, (float)y * GRID_RESOLUTION);
|
||||
glDepthMask (false);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_CULL_FACE);
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
GLvector pos = entity_list[i].object->Center ();
|
||||
if (WORLD_TO_GRID(pos.x) == x && WORLD_TO_GRID(pos.z) == y && entity_list[i].object->Alpha ()) {
|
||||
glBindTexture(GL_TEXTURE_2D, entity_list[i].object->Texture ());
|
||||
entity_list[i].object->Render ();
|
||||
}
|
||||
}
|
||||
glDepthMask (true);
|
||||
glEndList();
|
||||
|
||||
//now walk the grid
|
||||
compile_x++;
|
||||
if (compile_x == GRID_SIZE) {
|
||||
compile_x = 0;
|
||||
compile_y++;
|
||||
if (compile_y == GRID_SIZE)
|
||||
compiled = true;
|
||||
}
|
||||
compile_count++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool EntityReady ()
|
||||
{
|
||||
|
||||
return compiled;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float EntityProgress ()
|
||||
{
|
||||
|
||||
return (float)compile_count / (GRID_SIZE * GRID_SIZE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void EntityUpdate ()
|
||||
{
|
||||
|
||||
if (!TextureReady ()) {
|
||||
sorted = false;
|
||||
return;
|
||||
}
|
||||
if (!sorted) {
|
||||
qsort (entity_list, entity_count, sizeof (struct entity), do_compare);
|
||||
sorted = true;
|
||||
}
|
||||
|
||||
if (!compiled)
|
||||
for (int i = 0; i < 10; i++)
|
||||
do_compile ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void xEntityRender ()
|
||||
{
|
||||
|
||||
int i;
|
||||
bool wireframe;
|
||||
int polymode[2];
|
||||
|
||||
glGetIntegerv (GL_POLYGON_MODE, &polymode[0]);
|
||||
wireframe = polymode[0] != GL_FILL;
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
if (Visible (entity_list[i].object->Center ())) {
|
||||
glBindTexture(GL_TEXTURE_2D, entity_list[i].object->Texture ());
|
||||
entity_list[i].object->Render ();
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor3f (0,0,0);
|
||||
for (i = 0; i < entity_count; i++) {
|
||||
if (Visible (entity_list[i].object->Center ())) {
|
||||
entity_list[i].object->RenderFlat (wireframe);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void EntityRender ()
|
||||
{
|
||||
|
||||
int polymode[2];
|
||||
bool wireframe;
|
||||
int x, y;
|
||||
|
||||
//Draw all textured objects
|
||||
glGetIntegerv (GL_POLYGON_MODE, &polymode[0]);
|
||||
wireframe = polymode[0] != GL_FILL;
|
||||
if (RenderFlat ())
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
for (x = 0; x < GRID_SIZE; x++) {
|
||||
for (y = 0; y < GRID_SIZE; y++) {
|
||||
if (Visible (x,y))
|
||||
glCallList (cell_list[x][y].list_textured);
|
||||
}
|
||||
}
|
||||
//draw all flat colored objects
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor3f (0, 0, 0);
|
||||
for (x = 0; x < GRID_SIZE; x++) {
|
||||
for (y = 0; y < GRID_SIZE; y++) {
|
||||
if (Visible (x, y)) {
|
||||
if (wireframe)
|
||||
glCallList (cell_list[x][y].list_flat_wireframe);
|
||||
else
|
||||
glCallList (cell_list[x][y].list_flat);
|
||||
}
|
||||
}
|
||||
}
|
||||
//draw all alpha-blended objects
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glColor3f (0, 0, 0);
|
||||
glEnable (GL_BLEND);
|
||||
for (x = 0; x < GRID_SIZE; x++) {
|
||||
for (y = 0; y < GRID_SIZE; y++) {
|
||||
if (Visible (x,y)) {
|
||||
glCallList (cell_list[x][y].list_alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void EntityClear ()
|
||||
{
|
||||
|
||||
for (int i = 0; i < entity_count; i++) {
|
||||
delete entity_list[i].object;
|
||||
}
|
||||
if (entity_list)
|
||||
free (entity_list);
|
||||
entity_list = NULL;
|
||||
entity_count = 0;
|
||||
compile_x = 0;
|
||||
compile_y = 0;
|
||||
compile_count = 0;
|
||||
compiled = false;
|
||||
sorted = false;
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < GRID_SIZE; x++) {
|
||||
for (y = 0; y < GRID_SIZE; y++) {
|
||||
glNewList (cell_list[x][y].list_textured, GL_COMPILE);
|
||||
glEndList();
|
||||
glNewList (cell_list[x][y].list_alpha, GL_COMPILE);
|
||||
glEndList();
|
||||
glNewList (cell_list[x][y].list_flat_wireframe, GL_COMPILE);
|
||||
glEndList();
|
||||
glNewList (cell_list[x][y].list_flat, GL_COMPILE);
|
||||
glEndList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int EntityCount ()
|
||||
{
|
||||
|
||||
return entity_count;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void EntityInit (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int EntityPolyCount (void)
|
||||
{
|
||||
|
||||
if (!sorted)
|
||||
return 0;
|
||||
if (polycount)
|
||||
return polycount;
|
||||
for (int i = 0; i < entity_count; i++)
|
||||
polycount += entity_list[i].object->PolyCount ();
|
||||
return polycount;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CEntity::CEntity (void)
|
||||
{
|
||||
|
||||
add (this);
|
||||
|
||||
}
|
||||
|
||||
void CEntity::Render (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CEntity::RenderFlat (bool wireframe)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CEntity::Update (void)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef TYPES
|
||||
#include "glTypes.h"
|
||||
#endif
|
||||
|
||||
#ifndef ENTITY
|
||||
|
||||
#define ENTITY
|
||||
|
||||
class CEntity
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
|
||||
GLvector _center;
|
||||
|
||||
public:
|
||||
CEntity (void);
|
||||
GLvector Center () { return _center; }
|
||||
virtual void Render (void);
|
||||
virtual void RenderFlat (bool wirefame);
|
||||
virtual unsigned Texture () { return 0; }
|
||||
virtual void Update (void);
|
||||
virtual bool Alpha () { return false; }
|
||||
virtual int PolyCount () { return 0; }
|
||||
|
||||
};
|
||||
|
||||
void EntityClear ();
|
||||
int EntityCount (void);
|
||||
float EntityProgress ();
|
||||
bool EntityReady ();
|
||||
void EntityRender (void);
|
||||
void EntityUpdate (void);
|
||||
int EntityPolyCount (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,137 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Ini.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This takes various types of data and dumps them into a predefined ini file.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define FORMAT_VECTOR "%f %f %f"
|
||||
#define MAX_RESULT 256
|
||||
#define FORMAT_FLOAT "%1.2f"
|
||||
#define INI_FILE ".\\" APP ".ini"
|
||||
#define SECTION "Settings"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "ini.h"
|
||||
#include "win.h"
|
||||
|
||||
static char result[MAX_RESULT];
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int IniInt (char* entry)
|
||||
{
|
||||
|
||||
int result;
|
||||
|
||||
result = GetPrivateProfileInt (SECTION, entry, 0, INI_FILE);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void IniIntSet (char* entry, int val)
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
|
||||
sprintf (buf, "%d", val);
|
||||
WritePrivateProfileString (SECTION, entry, buf, INI_FILE);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float IniFloat (char* entry)
|
||||
{
|
||||
|
||||
float f;
|
||||
|
||||
GetPrivateProfileString (SECTION, entry, "", result, MAX_RESULT, INI_FILE);
|
||||
f = (float)atof (result);
|
||||
return f;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void IniFloatSet (char* entry, float val)
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
|
||||
sprintf (buf, FORMAT_FLOAT, val);
|
||||
WritePrivateProfileString (SECTION, entry, buf, INI_FILE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
char* IniString (char* entry)
|
||||
{
|
||||
|
||||
GetPrivateProfileString (SECTION, entry, "", result, MAX_RESULT, INI_FILE);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void IniStringSet (char* entry, char* val)
|
||||
{
|
||||
|
||||
WritePrivateProfileString (SECTION, entry, val, INI_FILE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void IniVectorSet (char* entry, GLvector v)
|
||||
{
|
||||
|
||||
sprintf (result, FORMAT_VECTOR, v.x, v.y, v.z);
|
||||
WritePrivateProfileString (SECTION, entry, result, INI_FILE);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector IniVector (char* entry)
|
||||
{
|
||||
|
||||
GLvector v;
|
||||
|
||||
v.x = v.y = v.z = 0.0f;
|
||||
GetPrivateProfileString (SECTION, entry, "0 0 0", result, MAX_RESULT, INI_FILE);
|
||||
sscanf (result, FORMAT_VECTOR, &v.x, &v.y, &v.z);
|
||||
return v;
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
int IniInt (char* entry);
|
||||
void IniIntSet (char* entry, int val);
|
||||
float IniFloat (char* entry);
|
||||
void IniFloatSet (char* entry, float val);
|
||||
char* IniString (char* entry);
|
||||
void IniStringSet (char* entry, char* val);
|
||||
void IniVectorSet (char* entry, GLvector v);
|
||||
GLvector IniVector (char* entry);
|
|
@ -0,0 +1,174 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Light.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This tracks and renders the light sources. (Note that they do not really
|
||||
CAST light in the OpenGL sense of the world, these are just simple panels.)
|
||||
These are NOT subclassed to entities because these are dynamic. Some lights
|
||||
blink, and thus they can't go into the fixed render lists managed by
|
||||
Entity.cpp.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MAX_SIZE 5
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "camera.h"
|
||||
#include "light.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include "visible.h"
|
||||
|
||||
static GLvector2 angles[5][360];
|
||||
static CLight* head;
|
||||
static bool angles_done;
|
||||
static int count;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void LightClear ()
|
||||
{
|
||||
|
||||
CLight* l;
|
||||
|
||||
while (head) {
|
||||
l = head;
|
||||
head = l->_next;
|
||||
delete l;
|
||||
}
|
||||
count = 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int LightCount ()
|
||||
{
|
||||
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void LightRender ()
|
||||
{
|
||||
|
||||
CLight* l;
|
||||
|
||||
if (!angles_done) {
|
||||
for (int size = 0; size < MAX_SIZE; size++) {
|
||||
for (int i = 0 ;i < 360; i++) {
|
||||
angles[size][i].x = cosf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f);
|
||||
angles[size][i].y = sinf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
glDepthMask (false);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LIGHT));
|
||||
glDisable (GL_CULL_FACE);
|
||||
glBegin (GL_QUADS);
|
||||
for (l = head; l; l = l->_next)
|
||||
l->Render ();
|
||||
glEnd ();
|
||||
glDepthMask (true);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CLight::CLight (GLvector pos, GLrgba color, int size)
|
||||
{
|
||||
|
||||
_position = pos;
|
||||
_color = color * 0.5f;
|
||||
_size = CLAMP (size, 0, (MAX_SIZE - 1));
|
||||
_vert_size = (float)_size + 0.5f;
|
||||
_flat_size = _vert_size + 0.5f;
|
||||
_blink = false;
|
||||
_cell_x = WORLD_TO_GRID(pos.x);
|
||||
_cell_z = WORLD_TO_GRID(pos.z);
|
||||
_next = head;
|
||||
head = this;
|
||||
count++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CLight::Blink ()
|
||||
{
|
||||
|
||||
_blink = true;
|
||||
//we don't want blinkers to be in sync, so have them blink at
|
||||
//slightly different rates. (Milliseconds)
|
||||
_blink_interval = 1500 + RandomVal (500);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CLight::Render ()
|
||||
{
|
||||
|
||||
int angle;
|
||||
GLvector pos;
|
||||
GLvector camera;
|
||||
GLvector camera_position;
|
||||
GLvector2 offset;
|
||||
|
||||
if (!Visible (_cell_x, _cell_z))
|
||||
return;
|
||||
camera = CameraAngle ();
|
||||
camera_position = CameraPosition ();
|
||||
if (fabs (camera_position.x - _position.x) > RenderFogDistance ())
|
||||
return;
|
||||
if (fabs (camera_position.z - _position.z) > RenderFogDistance ())
|
||||
return;
|
||||
if (_blink && (GetTickCount () % _blink_interval) > 200)
|
||||
return;
|
||||
angle = (int)MathAngle (camera.y);
|
||||
offset = angles[_size][angle];
|
||||
pos = _position;
|
||||
//m_color.alpha = 0.25f;
|
||||
glColor4fv (&_color.red);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex3f (pos.x + offset.x, pos.y - _vert_size, pos.z + offset.y);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex3f (pos.x - offset.x, pos.y - _vert_size, pos.z - offset.y);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex3f (pos.x - offset.x, pos.y + _vert_size, pos.z - offset.y);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex3f (pos.x + offset.x, pos.y + _vert_size, pos.z + offset.y);
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
class CLight
|
||||
{
|
||||
GLvector _position;
|
||||
GLrgba _color;
|
||||
int _size;
|
||||
float _vert_size;
|
||||
float _flat_size;
|
||||
bool _blink;
|
||||
unsigned _blink_interval;
|
||||
int _cell_x;
|
||||
int _cell_z;
|
||||
|
||||
public:
|
||||
CLight(GLvector pos, GLrgba color, int size);
|
||||
class CLight* _next;
|
||||
void Render ();
|
||||
void Blink ();
|
||||
|
||||
};
|
||||
|
||||
void LightRender ();
|
||||
void LightClear ();
|
||||
int LightCount ();
|
|
@ -0,0 +1,15 @@
|
|||
#define LIMIT_INTERVAL(interval) { static unsigned next_update; if (next_update > GetTickCount ()) return; next_update = GetTickCount () + interval;}
|
||||
#define DEGREES_TO_RADIANS .017453292F
|
||||
#define RADIANS_TO_DEGREES 57.29577951F
|
||||
#define PI ((double)3.1415926535F)
|
||||
#define PI2 PI*PI
|
||||
#define GRAVITY 9.5f
|
||||
#define CLAMP(a,b,c) (a < b ? b : (a > c ? c : a))
|
||||
#define WRAP(x,y) ((unsigned)x % y)
|
||||
#define SIGN(x) (((x) > 0) ? 1 : ((x) < 0) ? -1 : 0)
|
||||
#define ABS(x) (((x) < 0 ? (-x) : (x)))
|
||||
#define SMALLEST(x,y) (ABS(x) < ABS(y) ? 0 : x)
|
||||
#define MIN(x,y) ((x) < (y) ? x : y)
|
||||
#define MAX(x,y) ((x) > (y) ? x : y)
|
||||
#define POW(x,y) (float)pow(x,y)
|
||||
#define SWAP(a,b) {int temp = a;a = b; b = temp;}
|
|
@ -0,0 +1,181 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Math.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Various useful math functions.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Keep an angle between 0 and 360
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathAngle (float angle)
|
||||
{
|
||||
|
||||
if (angle < 0.0f)
|
||||
angle = 360.0f - (float)fmod (fabs (angle), 360.0f);
|
||||
else
|
||||
angle = (float)fmod (angle, 360.0f);
|
||||
return angle;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Get an angle between two given points on a grid
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathAngle (float x1, float y1, float x2, float y2)
|
||||
{
|
||||
|
||||
float x_delta;
|
||||
float z_delta;
|
||||
float angle;
|
||||
|
||||
z_delta = (y1 - y2);
|
||||
x_delta = (x1 - x2);
|
||||
if (x_delta == 0) {
|
||||
if (z_delta > 0)
|
||||
return 0.0f;
|
||||
else
|
||||
return 180.0f;
|
||||
}
|
||||
if (fabs (x_delta) < fabs (z_delta)) {
|
||||
angle = 90 - (float)atan (z_delta / x_delta) * RADIANS_TO_DEGREES;
|
||||
if (x_delta < 0)
|
||||
angle -= 180.0f;
|
||||
} else {
|
||||
angle = (float)atan (x_delta / z_delta) * RADIANS_TO_DEGREES;
|
||||
if (z_delta < 0.0f)
|
||||
angle += 180.0f;
|
||||
}
|
||||
if (angle< 0.0f)
|
||||
angle += 360.0f;
|
||||
return angle;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Get distance (squared) between 2 points on a plane
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathDistance2 (float x1, float y1, float x2, float y2)
|
||||
{
|
||||
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
dx = x1 - x2;
|
||||
dy = y1 - y2;
|
||||
return dx * dx + dy * dy;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Get distance between 2 points on a plane. This is slightly slower than
|
||||
MathDistance2 ()
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathDistance (float x1, float y1, float x2, float y2)
|
||||
{
|
||||
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
dx = x1 - x2;
|
||||
dy = y1 - y2;
|
||||
return (float)sqrt (dx * dx + dy * dy);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
difference between two angles
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathAngleDifference (float a1, float a2)
|
||||
|
||||
{
|
||||
|
||||
float result;
|
||||
|
||||
result = (float)fmod (a1 - a2, 360.0);
|
||||
if (result > 180.0)
|
||||
return result - 360.0F;
|
||||
if (result < -180.0)
|
||||
return result + 360.0F;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
interpolate between two values
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathInterpolate (float n1, float n2, float delta)
|
||||
{
|
||||
|
||||
return n1 * (1.0f - delta) + n2 * delta;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
return a scalar of 0.0 to 1.0, based an the given values position within a range
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathSmoothStep (float val, float a, float b)
|
||||
{
|
||||
|
||||
if (b == a)
|
||||
return 0.0f;
|
||||
val -= a;
|
||||
val /= (b - a);
|
||||
return CLAMP (val, 0.0f, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Average two values
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathAverage (float n1, float n2)
|
||||
{
|
||||
|
||||
return (n1 + n2) / 2.0f;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
This will take linear input values from 0.0 to 1.0 and convert them to
|
||||
values along a curve. This could also be acomplished with sin (), but this
|
||||
way avoids converting to radians and back.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float MathScalarCurve (float val)
|
||||
{
|
||||
|
||||
float sign;
|
||||
|
||||
val = (val - 0.5f) * 2.0f;
|
||||
if (val < 0.0f)
|
||||
sign = -1.0f;
|
||||
else
|
||||
sign = 1.0f;
|
||||
if (val < 0.0f)
|
||||
val = -val;
|
||||
val = 1.0f - val;
|
||||
val *= val;
|
||||
val = 1.0f - val;
|
||||
val *= sign;
|
||||
val = (val + 1.0f) / 2.0f;
|
||||
return val;
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
float MathAngle (float angle);
|
||||
float MathAngle (float x1, float y1, float x2, float y2);
|
||||
float MathAngleDifference (float a1, float a2);
|
||||
float MathAverage (float n1, float n2);
|
||||
float MathInterpolate (float n1, float n2, float delta);
|
||||
float MathLine_distance (float x1, float y1, float x2, float y2, float px, float py);
|
||||
float MathDistance (float x1, float y1, float x2, float y2);
|
||||
float MathDistance2 (float x1, float y1, float x2, float y2);
|
||||
float MathSmoothStep (float val, float a, float b);
|
||||
float MathScalarCurve (float val);
|
|
@ -0,0 +1,216 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Mesh.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This class is used to make constructing objects easier. It handles
|
||||
allocating vertex lists, polygon lists, and suchlike.
|
||||
|
||||
If you were going to implement vertex buffers, this would be the place to
|
||||
do it. Take away the _vertex member variable and store verts for ALL meshes
|
||||
in a common list, which could then be unloaded onto the good 'ol GPU.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
#include "glTypes.h"
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CMesh::CMesh ()
|
||||
{
|
||||
|
||||
_vertex_count = 0;
|
||||
_triangle_count = 0;
|
||||
_quad_strip_count = 0;
|
||||
_fan_count = 0;
|
||||
_cube_count = 0;
|
||||
_polycount = 0;
|
||||
_list = 0;
|
||||
_compiled = false;
|
||||
_vertex = NULL;
|
||||
_normal = NULL;
|
||||
_triangle = NULL;
|
||||
_cube = NULL;
|
||||
_quad_strip = NULL;
|
||||
_fan = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CMesh::~CMesh ()
|
||||
{
|
||||
|
||||
unsigned i;
|
||||
|
||||
if (_vertex)
|
||||
free (_vertex);
|
||||
if (_normal)
|
||||
free (_normal);
|
||||
if (_triangle)
|
||||
free (_triangle);
|
||||
if (_cube)
|
||||
free (_cube);
|
||||
for (i = 0; i < _quad_strip_count; i++)
|
||||
delete _quad_strip[i].index_list;
|
||||
delete _quad_strip;
|
||||
for (i = 0; i < _fan_count; i++)
|
||||
delete _fan[i].index_list;
|
||||
delete _fan;
|
||||
if (_list)
|
||||
glDeleteLists (_list, 1);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::VertexAdd (GLvertex v)
|
||||
{
|
||||
|
||||
_vertex = (GLvertex*)realloc (_vertex, sizeof (GLvertex) * (_vertex_count + 1));
|
||||
_vertex[_vertex_count] = v;
|
||||
_vertex_count++;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::CubeAdd (int* index)
|
||||
{
|
||||
|
||||
_cube = (cube*)realloc (_cube, sizeof (cube) * (_cube_count + 1));
|
||||
memcpy (&_cube[_cube_count].index_list[0], index, sizeof (int) * 10);
|
||||
_cube_count++;
|
||||
_polycount += 5;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::QuadStripAdd (int* index, int count)
|
||||
{
|
||||
|
||||
_quad_strip = (quad_strip*)realloc (_quad_strip, sizeof (quad_strip) * (_quad_strip_count + 1));
|
||||
_quad_strip[_quad_strip_count].index_list = (int*)malloc (sizeof (int) * count);
|
||||
_quad_strip[_quad_strip_count].count = count;
|
||||
memcpy (&_quad_strip[_quad_strip_count].index_list[0], &index[0], sizeof (int) * count);
|
||||
_quad_strip_count++;
|
||||
_polycount += (count - 2) / 2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::FanAdd (int* index, int count)
|
||||
{
|
||||
|
||||
_fan = (fan*)realloc (_fan, sizeof (fan) * (_fan_count + 1));
|
||||
_fan[_fan_count].index_list = (int*)malloc (sizeof (int) * count);
|
||||
_fan[_fan_count].count = count;
|
||||
memcpy (&_fan[_fan_count].index_list[0], &index[0], sizeof (int) * count);
|
||||
_fan_count++;
|
||||
_polycount += count - 2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::Render ()
|
||||
{
|
||||
|
||||
unsigned i, n;
|
||||
int* index;
|
||||
|
||||
if (_compiled) {
|
||||
glCallList (_list);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < _quad_strip_count; i++) {
|
||||
index = &_quad_strip[i].index_list[0];
|
||||
glBegin (GL_QUAD_STRIP);
|
||||
for (n = 0; n < _quad_strip[i].count; n++) {
|
||||
glTexCoord2fv (&_vertex[index[n]].uv.x);
|
||||
glVertex3fv (&_vertex[index[n]].position.x);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
for (i = 0; i < _cube_count; i++) {
|
||||
index = &_cube[i].index_list[0];
|
||||
glBegin (GL_QUAD_STRIP);
|
||||
for (n = 0; n < 10; n++) {
|
||||
glTexCoord2fv (&_vertex[index[n]].uv.x);
|
||||
glVertex3fv (&_vertex[index[n]].position.x);
|
||||
}
|
||||
glEnd ();
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2fv (&_vertex[index[7]].uv.x);
|
||||
glVertex3fv (&_vertex[index[7]].position.x);
|
||||
glVertex3fv (&_vertex[index[5]].position.x);
|
||||
glVertex3fv (&_vertex[index[3]].position.x);
|
||||
glVertex3fv (&_vertex[index[1]].position.x);
|
||||
glEnd ();
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2fv (&_vertex[index[6]].uv.x);
|
||||
glVertex3fv (&_vertex[index[0]].position.x);
|
||||
glVertex3fv (&_vertex[index[2]].position.x);
|
||||
glVertex3fv (&_vertex[index[4]].position.x);
|
||||
glVertex3fv (&_vertex[index[6]].position.x);
|
||||
glEnd ();
|
||||
|
||||
|
||||
}
|
||||
for (i = 0; i < _fan_count; i++) {
|
||||
index = &_fan[i].index_list[0];
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
for (n = 0; n < _fan[i].count; n++) {
|
||||
glTexCoord2fv (&_vertex[index[n]].uv.x);
|
||||
glVertex3fv (&_vertex[index[n]].position.x);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CMesh::Compile ()
|
||||
{
|
||||
|
||||
if (!_list)
|
||||
_list = glGenLists(1);
|
||||
glNewList (_list, GL_COMPILE);
|
||||
Render ();
|
||||
glEndList();
|
||||
_compiled = true;
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
|
||||
struct cube
|
||||
{
|
||||
int index_list[10];
|
||||
};
|
||||
|
||||
struct quad_strip
|
||||
{
|
||||
int* index_list;
|
||||
unsigned count;
|
||||
};
|
||||
|
||||
struct fan
|
||||
{
|
||||
int* index_list;
|
||||
unsigned count;
|
||||
};
|
||||
|
||||
class CMesh
|
||||
{
|
||||
public:
|
||||
CMesh ();
|
||||
~CMesh ();
|
||||
unsigned _vertex_count;
|
||||
unsigned _triangle_count;
|
||||
unsigned _cube_count;
|
||||
unsigned _quad_strip_count;
|
||||
unsigned _fan_count;
|
||||
unsigned _normal_count;
|
||||
unsigned _list;
|
||||
int _polycount;
|
||||
GLvertex* _vertex;
|
||||
GLvector* _normal;
|
||||
GLtriangle* _triangle;
|
||||
cube* _cube;
|
||||
quad_strip* _quad_strip;
|
||||
fan* _fan;
|
||||
bool _compiled;
|
||||
|
||||
//void TriangleRender (unsigned n);
|
||||
//GLtriangle* TriangleAdd (unsigned v1, int unsigned, int unsigned);
|
||||
//GLtriangle* TriangleAdd (GLtriangle c);
|
||||
void NormalAdd (GLvector n);
|
||||
void VertexAdd (GLvertex v);
|
||||
int VertexCount () { return _vertex_count; }
|
||||
int PolyCount () { return _polycount; }
|
||||
void CubeAdd (int* index);
|
||||
void QuadStripAdd (int* index, int count);
|
||||
void FanAdd (int* index, int count);
|
||||
void Render ();
|
||||
void Compile ();
|
||||
|
||||
};
|
|
@ -0,0 +1,266 @@
|
|||
# Microsoft Developer Studio Project File - Name="PixelCity" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=PixelCity - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "PixelCity.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "PixelCity.mak" CFG="PixelCity - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "PixelCity - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "PixelCity - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "PixelCity"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "PixelCity - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/PixelCity.scr"
|
||||
|
||||
!ELSEIF "$(CFG)" == "PixelCity - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "PixelCity - Win32 Release"
|
||||
# Name "PixelCity - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Group "glTypes"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glBbox.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glMatrix.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glQuat.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glRgba.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glVector2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glVector3.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Building.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Camera.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Car.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Deco.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Entity.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ini.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Light.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Math.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Mesh.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Random.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Render.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Sky.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Texture.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Visible.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Win.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\World.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Building.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Camera.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Car.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Deco.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Entity.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\glTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ini.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Light.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Macro.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Math.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Mesh.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Random.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Render.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Sky.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Texture.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Visible.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Win.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\World.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,93 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
r a n d o m
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
The Mersenne Twister by Matsumoto and Nishimura <matumoto@math.keio.ac.jp>.
|
||||
It sets new standards for the period, quality and speed of random number
|
||||
generators. The incredible period is 2^19937 - 1, a number with about 6000
|
||||
digits; the 32-bit random numbers exhibit best possible equidistribution
|
||||
properties in dimensions up to 623; and it's fast, very fast.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define LOWER_MASK 0x7fffffff
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0df
|
||||
#define N 624
|
||||
#define TEMPERING_MASK_B 0x9d2c5680
|
||||
#define TEMPERING_MASK_C 0xefc60000
|
||||
#define TEMPERING_SHIFT_L(y) (y >> 18)
|
||||
#define TEMPERING_SHIFT_S(y) (y << 7)
|
||||
#define TEMPERING_SHIFT_T(y) (y << 15)
|
||||
#define TEMPERING_SHIFT_U(y) (y >> 11)
|
||||
#define UPPER_MASK 0x80000000
|
||||
|
||||
#include <memory.h>
|
||||
#include "random.h"
|
||||
|
||||
static int k = 1;
|
||||
static unsigned long mag01[2] = {0x0, MATRIX_A};
|
||||
static unsigned long ptgfsr[N];
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned long RandomVal (void)
|
||||
{
|
||||
|
||||
int kk;
|
||||
unsigned long y;
|
||||
|
||||
if (k == N) {
|
||||
for (kk = 0; kk < N - M; kk++) {
|
||||
y = (ptgfsr[kk] & UPPER_MASK) | (ptgfsr[kk + 1] & LOWER_MASK);
|
||||
ptgfsr[kk] = ptgfsr[kk + M] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
for (; kk < N - 1; kk++) {
|
||||
y = (ptgfsr[kk] & UPPER_MASK) | (ptgfsr[kk + 1] & LOWER_MASK);
|
||||
ptgfsr[kk] = ptgfsr[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
y = (ptgfsr[N - 1] & UPPER_MASK) | (ptgfsr[0] & LOWER_MASK);
|
||||
ptgfsr[N - 1] = ptgfsr[M - 1] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
k = 0;
|
||||
}
|
||||
y = ptgfsr[k++];
|
||||
y ^= TEMPERING_SHIFT_U (y);
|
||||
y ^= TEMPERING_SHIFT_S (y) & TEMPERING_MASK_B;
|
||||
y ^= TEMPERING_SHIFT_T (y) & TEMPERING_MASK_C;
|
||||
return y ^= TEMPERING_SHIFT_L (y);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned long RandomVal (int range)
|
||||
{
|
||||
|
||||
return range ? (RandomVal () % range) : 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RandomInit (unsigned long seed)
|
||||
{
|
||||
|
||||
//int k;
|
||||
|
||||
//memset (ptgfsr, 0, sizeof (ptgfsr));
|
||||
//mag01[0] = 0x0;
|
||||
//mag01[1] = MATRIX_A;
|
||||
ptgfsr[0] = seed;
|
||||
for (k = 1; k < N; k++)
|
||||
ptgfsr[k] = 69069 * ptgfsr[k - 1];
|
||||
k = 1;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#define COIN_FLIP (RandomVal (2) == 0)
|
||||
|
||||
unsigned long RandomVal (int range);
|
||||
unsigned long RandomVal (void);
|
||||
void RandomInit (unsigned long seed);
|
|
@ -0,0 +1,777 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Render.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This is the core of the gl rendering functions. This contains the main
|
||||
rendering function RenderUpdate (), which initiates the various
|
||||
other renders in the other modules.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define RENDER_DISTANCE 1280
|
||||
#define MAX_TEXT 256
|
||||
#define YOUFAIL(message) {WinPopup (message);return;}
|
||||
#define HELP_SIZE sizeof(help)
|
||||
#define COLOR_CYCLE_TIME 10000 //milliseconds
|
||||
#define COLOR_CYCLE (COLOR_CYCLE_TIME / 4)
|
||||
#define FONT_COUNT (sizeof (fonts) / sizeof (struct glFont))
|
||||
#define FONT_SIZE (LOGO_PIXELS - LOGO_PIXELS / 8)
|
||||
#define BLOOM_SCALING 0.07f
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "entity.h"
|
||||
#include "car.h"
|
||||
#include "camera.h"
|
||||
#include "ini.h"
|
||||
#include "light.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "render.h"
|
||||
#include "sky.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
#include "win.h"
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd =
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
1, // Version Number
|
||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
||||
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
||||
PFD_TYPE_RGBA, // Request An RGBA Format
|
||||
32, // Select Our glRgbaDepth
|
||||
0, 0, 0, 0, 0, 0, // glRgbaBits Ignored
|
||||
0, // No Alpha Buffer
|
||||
0, // Shift Bit Ignored
|
||||
0, // Accumulation Buffers
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
16, // Z-Buffer (Depth Buffer) bits
|
||||
0, // Stencil Buffers
|
||||
1, // Auxiliary Buffers
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
0, // Reserved
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
};
|
||||
|
||||
static char help[] =
|
||||
"ESC - Exit!\n"
|
||||
"F1 - Show this help screen\n"
|
||||
"R - Rebuild city\n"
|
||||
"L - Toggle 'letterbox' mode\n"
|
||||
"F - Show Framecounter\n"
|
||||
"W - Toggle Wireframe\n"
|
||||
"E - Change full-scene effects\n"
|
||||
"T - Toggle Textures\n"
|
||||
"G - Toggle Fog\n"
|
||||
;
|
||||
|
||||
struct glFont
|
||||
{
|
||||
char* name;
|
||||
unsigned base_char;
|
||||
} fonts[] =
|
||||
{
|
||||
"Courier New", 0,
|
||||
"Arial", 0,
|
||||
"Times New Roman", 0,
|
||||
"Arial Black", 0,
|
||||
"Impact", 0,
|
||||
"Agency FB", 0,
|
||||
"Book Antiqua", 0,
|
||||
};
|
||||
|
||||
#if SCREENSAVER
|
||||
enum
|
||||
{
|
||||
EFFECT_NONE,
|
||||
EFFECT_BLOOM,
|
||||
EFFECT_BLOOM_RADIAL,
|
||||
EFFECT_COLOR_CYCLE,
|
||||
EFFECT_GLASS_CITY,
|
||||
EFFECT_DEBUG,
|
||||
EFFECT_DEBUG_OVERBLOOM,
|
||||
EFFECT_COUNT
|
||||
};
|
||||
#else
|
||||
enum
|
||||
{
|
||||
EFFECT_NONE,
|
||||
EFFECT_BLOOM,
|
||||
EFFECT_COUNT,
|
||||
EFFECT_DEBUG,
|
||||
EFFECT_DEBUG_OVERBLOOM,
|
||||
EFFECT_BLOOM_RADIAL,
|
||||
EFFECT_COLOR_CYCLE,
|
||||
EFFECT_GLASS_CITY,
|
||||
};
|
||||
#endif
|
||||
|
||||
static HDC hDC;
|
||||
static HGLRC hRC;
|
||||
static float render_aspect;
|
||||
static float fog_distance;
|
||||
static int render_width;
|
||||
static int render_height;
|
||||
static bool letterbox;
|
||||
static int letterbox_offset;
|
||||
static int effect;
|
||||
static int max_texture;
|
||||
static unsigned next_fps;
|
||||
static unsigned current_fps;
|
||||
static unsigned frames;
|
||||
static bool show_wireframe;
|
||||
static bool bloom;
|
||||
static bool flat;
|
||||
static bool show_fps;
|
||||
static bool show_fog;
|
||||
static bool show_help;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Draw a clock-ish progress.. widget... thing. It's cute.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_progress (float center_x, float center_y, float radius, float opacity, float progress)
|
||||
{
|
||||
|
||||
int i;
|
||||
int end_angle;
|
||||
float inner, outer;
|
||||
float angle;
|
||||
float s, c;
|
||||
float gap;
|
||||
|
||||
//Outer Ring
|
||||
gap = radius * 0.05f;
|
||||
outer = radius;
|
||||
inner = radius - gap * 2;
|
||||
glColor4f (1,1,1, opacity);
|
||||
glBegin (GL_QUAD_STRIP);
|
||||
for (i = 0; i <= 360; i+= 15) {
|
||||
//GLrgba col = glRgbaUnique (i);
|
||||
//glColor3fv (&col.red);
|
||||
angle = (float)i * DEGREES_TO_RADIANS;
|
||||
s = sinf (angle);
|
||||
c = -cosf (angle);
|
||||
glVertex2f (center_x + s * outer, center_y + c * outer);
|
||||
glVertex2f (center_x + s * inner, center_y + c * inner);
|
||||
}
|
||||
glEnd ();
|
||||
//Progress indicator
|
||||
glColor4f (1,1,1, opacity);
|
||||
end_angle = (int)(360 * progress);
|
||||
outer = radius - gap * 3;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glVertex2f (center_x, center_y);
|
||||
for (i = 0; i <= end_angle; i+= 3) {
|
||||
angle = (float)i * DEGREES_TO_RADIANS;
|
||||
s = sinf (angle);
|
||||
c = -cosf (angle);
|
||||
glVertex2f (center_x + s * outer, center_y + c * outer);
|
||||
}
|
||||
glEnd ();
|
||||
//Tic lines
|
||||
glLineWidth (2.0f);
|
||||
outer = radius - gap * 1;
|
||||
inner = radius - gap * 2;
|
||||
glColor4f (0,0,0, opacity);
|
||||
glBegin (GL_LINES);
|
||||
for (i = 0; i <= 360; i+= 15) {
|
||||
angle = (float)i * DEGREES_TO_RADIANS;
|
||||
s = sinf (angle);
|
||||
c = -cosf (angle);
|
||||
glVertex2f (center_x + s * outer, center_y + c * outer);
|
||||
glVertex2f (center_x + s * inner, center_y + c * inner);
|
||||
}
|
||||
glEnd ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_effects (int type)
|
||||
{
|
||||
|
||||
float hue1, hue2, hue3, hue4;
|
||||
GLrgba color;
|
||||
float fade;
|
||||
int radius;
|
||||
int x, y;
|
||||
int i;
|
||||
int bloom_radius;
|
||||
int bloom_step;
|
||||
|
||||
fade = WorldFade ();
|
||||
bloom_radius = 15;
|
||||
bloom_step = bloom_radius / 3;
|
||||
if (!TextureReady () && fade == 0.0f)
|
||||
return;
|
||||
//Now change projection modes so we can render full-screen effects
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, render_width, render_height, 0, 0.1f, 2048);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, -1.0f);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
//Render full-screen effects
|
||||
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_BLOOM));
|
||||
switch (type) {
|
||||
case EFFECT_DEBUG:
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LOGOS));
|
||||
glDisable (GL_BLEND);
|
||||
glBegin (GL_QUADS);
|
||||
glColor3f (1, 1, 1);
|
||||
glTexCoord2f (0, 0); glVertex2i (0, render_height / 4);
|
||||
glTexCoord2f (0, 1); glVertex2i (0, 0);
|
||||
glTexCoord2f (1, 1); glVertex2i (render_width / 4, 0);
|
||||
glTexCoord2f (1, 0); glVertex2i (render_width / 4, render_height / 4);
|
||||
|
||||
glTexCoord2f (0, 0); glVertex2i (0, 512);
|
||||
glTexCoord2f (0, 1); glVertex2i (0, 0);
|
||||
glTexCoord2f (1, 1); glVertex2i (512, 0);
|
||||
glTexCoord2f (1, 0); glVertex2i (512, 512);
|
||||
glEnd ();
|
||||
break;
|
||||
case EFFECT_BLOOM_RADIAL:
|
||||
//Psychedelic bloom
|
||||
glEnable (GL_BLEND);
|
||||
glBegin (GL_QUADS);
|
||||
color = WorldBloomColor () * BLOOM_SCALING;
|
||||
glColor3fv (&color.red);
|
||||
for (i = 0; i <= 100; i+=10) {
|
||||
glTexCoord2f (0, 0); glVertex2i (-i, i + render_height);
|
||||
glTexCoord2f (0, 1); glVertex2i (-i, -i);
|
||||
glTexCoord2f (1, 1); glVertex2i (i + render_width, -i);
|
||||
glTexCoord2f (1, 0); glVertex2i (i + render_width, i + render_height);
|
||||
}
|
||||
glEnd ();
|
||||
break;
|
||||
case EFFECT_COLOR_CYCLE:
|
||||
//Oooh. Pretty colors. Tint the scene according to screenspace.
|
||||
hue1 = (float)(GetTickCount () % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
|
||||
hue2 = (float)((GetTickCount () + COLOR_CYCLE) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
|
||||
hue3 = (float)((GetTickCount () + COLOR_CYCLE * 2) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
|
||||
hue4 = (float)((GetTickCount () + COLOR_CYCLE * 3) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
|
||||
glBegin (GL_QUADS);
|
||||
color = glRgbaFromHsl (hue1, 1.0f, 0.6f);
|
||||
glColor3fv (&color.red);
|
||||
glTexCoord2f (0, 0); glVertex2i (0, render_height);
|
||||
color = glRgbaFromHsl (hue2, 1.0f, 0.6f);
|
||||
glColor3fv (&color.red);
|
||||
glTexCoord2f (0, 1); glVertex2i (0, 0);
|
||||
color = glRgbaFromHsl (hue3, 1.0f, 0.6f);
|
||||
glColor3fv (&color.red);
|
||||
glTexCoord2f (1, 1); glVertex2i (render_width, 0);
|
||||
color = glRgbaFromHsl (hue4, 1.0f, 0.6f);
|
||||
glColor3fv (&color.red);
|
||||
glTexCoord2f (1, 0); glVertex2i (render_width, render_height);
|
||||
glEnd ();
|
||||
break;
|
||||
case EFFECT_BLOOM:
|
||||
//Simple bloom effect
|
||||
glBegin (GL_QUADS);
|
||||
color = WorldBloomColor () * BLOOM_SCALING;
|
||||
glColor3fv (&color.red);
|
||||
for (x = -bloom_radius; x <= bloom_radius; x += bloom_step) {
|
||||
for (y = -bloom_radius; y <= bloom_radius; y += bloom_step) {
|
||||
if (abs (x) == abs (y) && x)
|
||||
continue;
|
||||
glTexCoord2f (0, 0); glVertex2i (x, y + render_height);
|
||||
glTexCoord2f (0, 1); glVertex2i (x, y);
|
||||
glTexCoord2f (1, 1); glVertex2i (x + render_width, y);
|
||||
glTexCoord2f (1, 0); glVertex2i (x + render_width, y + render_height);
|
||||
}
|
||||
}
|
||||
glEnd ();
|
||||
break;
|
||||
case EFFECT_DEBUG_OVERBLOOM:
|
||||
//This will punish that uppity GPU. Good for testing low frame rate behavior.
|
||||
glBegin (GL_QUADS);
|
||||
color = WorldBloomColor () * 0.06f;
|
||||
glColor3fv (&color.red);
|
||||
for (x = -50; x <= 50; x+=5) {
|
||||
for (y = -50; y <= 50; y+=5) {
|
||||
glTexCoord2f (0, 0); glVertex2i (x, y + render_height);
|
||||
glTexCoord2f (0, 1); glVertex2i (x, y);
|
||||
glTexCoord2f (1, 1); glVertex2i (x + render_width, y);
|
||||
glTexCoord2f (1, 0); glVertex2i (x + render_width, y + render_height);
|
||||
}
|
||||
}
|
||||
glEnd ();
|
||||
break;
|
||||
}
|
||||
//Do the fade to / from darkness used to hide scene transitions
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glColor4f (0, 0, 0, fade);
|
||||
glBegin (GL_QUADS);
|
||||
glVertex2i (0, 0);
|
||||
glVertex2i (0, render_height);
|
||||
glVertex2i (render_width, render_height);
|
||||
glVertex2i (render_width, 0);
|
||||
glEnd ();
|
||||
if (TextureReady () && !EntityReady () && fade != 0.0f) {
|
||||
radius = render_width / 16;
|
||||
do_progress ((float)render_width / 2, (float)render_height / 2, (float)radius, fade, EntityProgress ());
|
||||
RenderPrint (render_width / 2 - LOGO_PIXELS, render_height / 2 + LOGO_PIXELS, 0, glRgba (0.5f), "%1.2f%%", EntityProgress () * 100.0f);
|
||||
}
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderPrint (int x, int y, int font, GLrgba color, const char *fmt, ...)
|
||||
{
|
||||
|
||||
char text[MAX_TEXT];
|
||||
va_list ap;
|
||||
|
||||
text[0] = 0;
|
||||
if (fmt == NULL)
|
||||
return;
|
||||
va_start(ap, fmt);
|
||||
vsprintf(text, fmt, ap);
|
||||
va_end(ap);
|
||||
glPushAttrib(GL_LIST_BIT);
|
||||
glListBase(fonts[font % FONT_COUNT].base_char - 32);
|
||||
glColor3fv (&color.red);
|
||||
glRasterPos2i (x, y);
|
||||
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderPrint (int line, const char *fmt, ...)
|
||||
{
|
||||
|
||||
char text[MAX_TEXT];
|
||||
va_list ap;
|
||||
|
||||
text[0] = 0;
|
||||
if (fmt == NULL)
|
||||
return;
|
||||
va_start (ap, fmt);
|
||||
vsprintf (text, fmt, ap);
|
||||
va_end (ap);
|
||||
glDepthMask (false);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, render_width, render_height, 0, 0.1f, 2048);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity();
|
||||
glTranslatef(0, 0, -1.0f);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
RenderPrint (0, line * FONT_SIZE - 2, 0, glRgba (0.0f), text);
|
||||
RenderPrint (4, line * FONT_SIZE + 2, 0, glRgba (0.0f), text);
|
||||
RenderPrint (2, line * FONT_SIZE, 0, glRgba (1.0f), text);
|
||||
glPopAttrib();
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void static do_help (void)
|
||||
{
|
||||
|
||||
char* text;
|
||||
int line;
|
||||
char parse[HELP_SIZE];
|
||||
int x;
|
||||
|
||||
strcpy (parse, help);
|
||||
line = 0;
|
||||
text = strtok (parse, "\n");
|
||||
x = 10;
|
||||
while (text) {
|
||||
RenderPrint (line + 1, text);
|
||||
text = strtok (NULL, "\n");
|
||||
line++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderResize (void)
|
||||
{
|
||||
|
||||
float fovy;
|
||||
|
||||
render_width = WinWidth ();
|
||||
render_height = WinHeight ();
|
||||
if (letterbox) {
|
||||
letterbox_offset = render_height / 6;
|
||||
render_height = render_height - letterbox_offset * 2;
|
||||
} else
|
||||
letterbox_offset = 0;
|
||||
//render_aspect = (float)render_height / (float)render_width;
|
||||
glViewport (0, letterbox_offset, render_width, render_height);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
render_aspect = (float)render_width / (float)render_height;
|
||||
fovy = 60.0f;
|
||||
if (render_aspect > 1.0f)
|
||||
fovy /= render_aspect;
|
||||
gluPerspective (fovy, render_aspect, 0.1f, RENDER_DISTANCE);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderTerm (void)
|
||||
{
|
||||
|
||||
if (!hRC)
|
||||
return;
|
||||
wglDeleteContext (hRC);
|
||||
hRC = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderInit (void)
|
||||
{
|
||||
|
||||
HWND hWnd;
|
||||
unsigned PixelFormat;
|
||||
HFONT font;
|
||||
HFONT oldfont;
|
||||
|
||||
hWnd = WinHwnd ();
|
||||
if (!(hDC = GetDC (hWnd)))
|
||||
YOUFAIL ("Can't Create A GL Device Context.") ;
|
||||
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd)))
|
||||
YOUFAIL ("Can't Find A Suitable PixelFormat.") ;
|
||||
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
|
||||
YOUFAIL ("Can't Set The PixelFormat.");
|
||||
if (!(hRC = wglCreateContext (hDC)))
|
||||
YOUFAIL ("Can't Create A GL Rendering Context.");
|
||||
if(!wglMakeCurrent(hDC,hRC))
|
||||
YOUFAIL ("Can't Activate The GL Rendering Context.");
|
||||
//Load the fonts for printing debug info to the window.
|
||||
for (int i = 0; i < FONT_COUNT; i++) {
|
||||
fonts[i].base_char = glGenLists(96);
|
||||
font = CreateFont (FONT_SIZE, 0, 0, 0,
|
||||
FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_TT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE|DEFAULT_PITCH,
|
||||
fonts[i].name);
|
||||
oldfont = (HFONT)SelectObject(hDC, font);
|
||||
wglUseFontBitmaps(hDC, 32, 96, fonts[i].base_char);
|
||||
SelectObject(hDC, oldfont);
|
||||
DeleteObject(font);
|
||||
}
|
||||
//load in our settings
|
||||
letterbox = IniInt ("Letterbox") != 0;
|
||||
show_wireframe = IniInt ("Wireframe") != 0;
|
||||
show_fps = IniInt ("ShowFPS") != 0;
|
||||
show_fog = IniInt ("ShowFog") != 0;
|
||||
bloom = IniInt ("Bloom") != 0;
|
||||
effect = IniInt ("Effect");
|
||||
flat = IniInt ("Flat") != 0;
|
||||
fog_distance = WORLD_HALF;
|
||||
//clear the viewport so the user isn't looking at trash while the program starts
|
||||
glViewport (0, 0, WinWidth (), WinHeight ());
|
||||
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
SwapBuffers (hDC);
|
||||
RenderResize ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderFPSToggle ()
|
||||
{
|
||||
|
||||
show_fps = !show_fps;
|
||||
IniIntSet ("ShowFPS", show_fps ? 1 : 0);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool RenderFog ()
|
||||
{
|
||||
|
||||
return show_fog;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderFogToggle ()
|
||||
{
|
||||
|
||||
show_fog = !show_fog;
|
||||
IniIntSet ("ShowFog", show_fog ? 1 : 0);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderLetterboxToggle ()
|
||||
{
|
||||
|
||||
letterbox = !letterbox;
|
||||
IniIntSet ("Letterbox", letterbox ? 1 : 0);
|
||||
RenderResize ();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderWireframeToggle ()
|
||||
{
|
||||
|
||||
show_wireframe = !show_wireframe;
|
||||
IniIntSet ("Wireframe", show_wireframe ? 1 : 0);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool RenderWireframe ()
|
||||
{
|
||||
|
||||
return show_wireframe;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderEffectCycle ()
|
||||
{
|
||||
|
||||
effect = (effect + 1) % EFFECT_COUNT;
|
||||
IniIntSet ("Effect", effect);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool RenderBloom ()
|
||||
{
|
||||
|
||||
return effect == EFFECT_BLOOM || effect == EFFECT_BLOOM_RADIAL
|
||||
|| effect == EFFECT_DEBUG_OVERBLOOM || effect == EFFECT_COLOR_CYCLE;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool RenderFlat ()
|
||||
{
|
||||
|
||||
return flat;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderFlatToggle ()
|
||||
{
|
||||
|
||||
flat = !flat;
|
||||
IniIntSet ("Flat", flat ? 1 : 0);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderHelpToggle ()
|
||||
{
|
||||
|
||||
show_help = !show_help;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float RenderFogDistance ()
|
||||
{
|
||||
|
||||
return fog_distance;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void RenderUpdate (void)
|
||||
{
|
||||
|
||||
GLvector pos;
|
||||
GLvector angle;
|
||||
GLrgba color;
|
||||
|
||||
glViewport (0, 0, WinWidth (), WinHeight ());
|
||||
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
|
||||
if (letterbox)
|
||||
glViewport (0, letterbox_offset, render_width, render_height);
|
||||
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glFogi (GL_FOG_MODE, GL_LINEAR);
|
||||
if (show_fog) {
|
||||
glEnable (GL_FOG);
|
||||
glFogf (GL_FOG_START, fog_distance - 100);
|
||||
glFogf (GL_FOG_END, fog_distance);
|
||||
color = glRgba (0.0f);
|
||||
glFogfv (GL_FOG_COLOR, &color.red);
|
||||
} else
|
||||
glDisable (GL_FOG);
|
||||
//glEnable (GL_COLOR_MATERIAL);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable (GL_CULL_FACE);
|
||||
glCullFace (GL_BACK);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glMatrixMode (GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
glLoadIdentity();
|
||||
glLineWidth (2.0f);
|
||||
pos = CameraPosition ();
|
||||
angle = CameraAngle ();
|
||||
glRotatef (angle.x, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef (angle.y, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef (angle.z, 0.0f, 0.0f, 1.0f);
|
||||
glTranslatef (-pos.x, -pos.y, -pos.z);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
//Render all the stuff in the whole entire world.
|
||||
SkyRender ();
|
||||
WorldRender ();
|
||||
if (effect == EFFECT_GLASS_CITY) {
|
||||
glDisable (GL_CULL_FACE);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glDepthFunc (false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glMatrixMode (GL_TEXTURE);
|
||||
glTranslatef ((pos.x + pos.z) / SEGMENTS_PER_TEXTURE, 0, 0);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
} else {
|
||||
glEnable (GL_CULL_FACE);
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
EntityRender ();
|
||||
LightRender ();
|
||||
CarRender ();
|
||||
if (show_wireframe) {
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
EntityRender ();
|
||||
}
|
||||
//do_effects (EntityReady () ? effect : -1);
|
||||
do_effects (effect);
|
||||
//Framerate tracker
|
||||
if (GetTickCount () > next_fps) {
|
||||
current_fps = frames;
|
||||
frames = 0;
|
||||
next_fps = GetTickCount () + 1000;
|
||||
}
|
||||
if (show_fps && !show_help) {
|
||||
RenderPrint (1, "FPS=%d", current_fps);
|
||||
RenderPrint (2, "Entities=%d", EntityCount () + LightCount () + CarCount ());
|
||||
RenderPrint (3, "Lights=%d", LightCount ());
|
||||
RenderPrint (4, "Polys=%d", EntityPolyCount () + LightCount () + CarCount ());
|
||||
RenderPrint (5, "Building=%1.2f", EntityProgress () * 100);
|
||||
}
|
||||
//Show the help overlay
|
||||
if (show_help)
|
||||
do_help ();
|
||||
glDepthMask (true);
|
||||
frames++;
|
||||
SwapBuffers (hDC);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
bool RenderBloom ();
|
||||
void RenderEffectCycle ();
|
||||
bool RenderFlat ();
|
||||
void RenderFlatToggle ();
|
||||
float RenderFogDistance ();
|
||||
bool RenderFog ();
|
||||
void RenderFogToggle ();
|
||||
void RenderFPSToggle ();
|
||||
void RenderInit ();
|
||||
void RenderLetterboxToggle ();
|
||||
void RenderResize ();
|
||||
void RenderTerm ();
|
||||
void RenderUpdate ();
|
||||
bool RenderWireframe ();
|
||||
void RenderWireframeToggle ();
|
||||
void RenderHelpToggle ();
|
||||
void RenderPrint (int x, int y, int font, GLrgba color, const char *fmt, ...);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Sky.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Did this need to be written as a class? It did not. There will never be
|
||||
more than one sky in play, so the whole class structure here is superflous,
|
||||
but harmless.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define SKYPOINTS 24
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
|
||||
#include "camera.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "sky.h"
|
||||
#include "texture.h"
|
||||
#include "glTypes.h"
|
||||
#include "world.h"
|
||||
|
||||
static CSky* sky;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void SkyRender ()
|
||||
{
|
||||
|
||||
if (sky && !RenderFlat ())
|
||||
sky->Render ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void SkyClear ()
|
||||
{
|
||||
|
||||
if(sky)
|
||||
delete sky;
|
||||
sky = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CSky::Render ()
|
||||
{
|
||||
|
||||
GLvector angle, position;
|
||||
|
||||
if (!RenderFog ())
|
||||
return;
|
||||
glDepthMask (false);
|
||||
glPushAttrib (GL_POLYGON_BIT | GL_FOG_BIT);
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable (GL_FOG);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity();
|
||||
angle = CameraAngle ();
|
||||
position = CameraPosition ();
|
||||
glRotatef (angle.x, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef (angle.y, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef (angle.z, 0.0f, 0.0f, 1.0f);
|
||||
glTranslatef (0.0f, -position.y / 100.0f, 0.0f);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_SKY));
|
||||
glCallList (m_list);
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_CLOUDS));
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glCallList (m_list);
|
||||
glPopMatrix ();
|
||||
glPopAttrib ();
|
||||
glDepthMask (true);
|
||||
glEnable (GL_COLOR_MATERIAL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CSky::CSky ()
|
||||
{
|
||||
|
||||
GLvertex circle[SKYPOINTS];
|
||||
GLvector pos;
|
||||
float angle;
|
||||
int i;
|
||||
float size;
|
||||
float rad;
|
||||
float lum;
|
||||
|
||||
size = 10.0f;
|
||||
for (i = 0; i < SKYPOINTS; i++) {
|
||||
angle = (float)i / (float)(SKYPOINTS - 1);
|
||||
angle *= 360;
|
||||
angle *= DEGREES_TO_RADIANS;
|
||||
circle[i].position.x = sinf (angle) * size;
|
||||
circle[i].position.y = 0.1f;
|
||||
circle[i].position.z = cosf (angle) * size;
|
||||
circle[i].uv.x = ((float)i / (float)(SKYPOINTS - 1)) * 5.0f;
|
||||
circle[i].uv.y = 0.5f;
|
||||
rad = ((float)i / (SKYPOINTS - 1)) * 180.0f * DEGREES_TO_RADIANS;
|
||||
lum = sinf (rad);
|
||||
lum = (float)pow (lum, 5);
|
||||
circle[i].color = glRgba (lum);
|
||||
}
|
||||
m_list = glGenLists(1);
|
||||
glNewList (m_list, GL_COMPILE);
|
||||
glColor3f (1, 1, 1);
|
||||
|
||||
glBegin (GL_QUAD_STRIP);
|
||||
for (i = 0; i < SKYPOINTS; i++) {
|
||||
glTexCoord2f (circle[i].uv.x, 0.0f);
|
||||
glVertex3fv (&circle[i].position.x);
|
||||
pos = circle[i].position;
|
||||
pos.y = size / 3.5f;
|
||||
glTexCoord2f (circle[i].uv.x, 1.0f);
|
||||
glVertex3fv (&pos.x);
|
||||
}
|
||||
glEnd ();
|
||||
glEndList();
|
||||
glEndList();
|
||||
sky = this;
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#define SKY_GRID 21
|
||||
#define SKY_HALF (SKY_GRID / 2)
|
||||
|
||||
struct sky_point
|
||||
{
|
||||
GLrgba color;
|
||||
GLvector position;
|
||||
};
|
||||
|
||||
class CSky
|
||||
{
|
||||
private:
|
||||
int m_list;
|
||||
int m_stars_list;
|
||||
sky_point m_grid[SKY_GRID][SKY_GRID];
|
||||
|
||||
public:
|
||||
CSky ();
|
||||
void Render (void);
|
||||
|
||||
};
|
||||
|
||||
void SkyRender ();
|
||||
void SkyClear ();
|
|
@ -0,0 +1,887 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Texture.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This procedurally builds all of the textures.
|
||||
|
||||
I apologize in advance for the apalling state of this module. It's the victim
|
||||
of iterative and experimental development. It has cruft, poorly named
|
||||
functions, obscure code, poorly named variables, a is poorly organized. Even
|
||||
the formatting sucks in places. Its only saving grace is that it works.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define RANDOM_COLOR_SHIFT ((float)(RandomVal (10)) / 50.0f)
|
||||
#define RANDOM_COLOR_VAL ((float)(RandomVal (256)) / 256.0f)
|
||||
#define RANDOM_COLOR_LIGHT ((float)(200 + RandomVal (56)) / 256.0f)
|
||||
#define SKY_BANDS (sizeof (sky_pos) / sizeof (int))
|
||||
#define PREFIX_COUNT (sizeof (prefix) / sizeof (char*))
|
||||
#define SUFFIX_COUNT (sizeof (suffix) / sizeof (char*))
|
||||
#define NAME_COUNT (sizeof (name) / sizeof (char*))
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
|
||||
#include "gltypes.h"
|
||||
#include "building.h"
|
||||
#include "camera.h"
|
||||
#include "car.h"
|
||||
#include "light.h"
|
||||
#include "macro.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "sky.h"
|
||||
#include "texture.h"
|
||||
#include "world.h"
|
||||
|
||||
static char* prefix[] =
|
||||
{
|
||||
"i",
|
||||
"Green ",
|
||||
"Mega",
|
||||
"Super ",
|
||||
"Omni",
|
||||
"e",
|
||||
"Hyper",
|
||||
"Global ",
|
||||
"Vital",
|
||||
"Next ",
|
||||
"Pacific ",
|
||||
"Metro",
|
||||
"Unity ",
|
||||
"G-",
|
||||
"Trans",
|
||||
"Infinity ",
|
||||
"Superior ",
|
||||
"Monolith ",
|
||||
"Best ",
|
||||
"Atlantic ",
|
||||
"First ",
|
||||
"Union ",
|
||||
"National ",
|
||||
};
|
||||
|
||||
static char* name[] =
|
||||
{
|
||||
"Biotic",
|
||||
"Info",
|
||||
"Data",
|
||||
"Solar",
|
||||
"Aerospace",
|
||||
"Motors",
|
||||
"Nano",
|
||||
"Online",
|
||||
"Circuits",
|
||||
"Energy",
|
||||
"Med",
|
||||
"Robotic",
|
||||
"Exports",
|
||||
"Security",
|
||||
"Systems",
|
||||
"Financial",
|
||||
"Industrial",
|
||||
"Media",
|
||||
"Materials",
|
||||
"Foods",
|
||||
"Networks",
|
||||
"Shipping",
|
||||
"Tools",
|
||||
"Medical",
|
||||
"Publishing",
|
||||
"Enterprises",
|
||||
"Audio",
|
||||
"Health",
|
||||
"Bank",
|
||||
"Imports",
|
||||
"Apparel",
|
||||
"Petroleum",
|
||||
"Studios",
|
||||
};
|
||||
|
||||
static char* suffix[] =
|
||||
{
|
||||
"Corp",
|
||||
" Inc.",
|
||||
"Co",
|
||||
"World",
|
||||
".Com",
|
||||
" USA",
|
||||
" Ltd.",
|
||||
"Net",
|
||||
" Tech",
|
||||
" Labs",
|
||||
" Mfg.",
|
||||
" UK",
|
||||
" Unlimited",
|
||||
" One",
|
||||
};
|
||||
|
||||
class CTexture
|
||||
{
|
||||
public:
|
||||
int _my_id;
|
||||
unsigned _glid;
|
||||
int _size;
|
||||
int _half;
|
||||
int _segment_size;
|
||||
bool _ready;
|
||||
bool _masked;
|
||||
bool _mipmap;
|
||||
bool _clamp;
|
||||
public:
|
||||
CTexture* _next;
|
||||
CTexture (int id, int size, bool mipmap, bool clamp, bool masked);
|
||||
void Clear () { _ready = false; }
|
||||
void Rebuild ();
|
||||
void DrawWindows ();
|
||||
};
|
||||
|
||||
static CTexture* head;
|
||||
static bool textures_done;
|
||||
static GLrgba horizon_color;
|
||||
static GLrgba cloud_color;
|
||||
static bool prefix_used[PREFIX_COUNT];
|
||||
static bool name_used[NAME_COUNT];
|
||||
static bool suffix_used[SUFFIX_COUNT];
|
||||
static int build_time;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void drawrect_simple (int left, int top, int right, int bottom, GLrgba color)
|
||||
{
|
||||
|
||||
glColor3fv (&color.red);
|
||||
glBegin (GL_QUADS);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (right, top);
|
||||
glVertex2i (right, bottom);
|
||||
glVertex2i (left, bottom);
|
||||
glEnd ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void drawrect_simple (int left, int top, int right, int bottom, GLrgba color1, GLrgba color2)
|
||||
{
|
||||
|
||||
glColor3fv (&color1.red);
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glVertex2i ((left + right) / 2, (top + bottom) / 2);
|
||||
glColor3fv (&color2.red);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (right, top);
|
||||
glVertex2i (right, bottom);
|
||||
glVertex2i (left, bottom);
|
||||
glVertex2i (left, top);
|
||||
glEnd ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void drawrect (int left, int top, int right, int bottom, GLrgba color)
|
||||
{
|
||||
|
||||
float average;
|
||||
float hue;
|
||||
int potential;
|
||||
int repeats;
|
||||
int height;
|
||||
int i, j;
|
||||
bool bright;
|
||||
GLrgba color_noise;
|
||||
|
||||
glDisable (GL_CULL_FACE);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_BLEND);
|
||||
glLineWidth (1.0f);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glColor3fv (&color.red);
|
||||
|
||||
if (left == right) { //in low resolution, a "rect" might be 1 pixel wide
|
||||
glBegin (GL_LINES);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (left, bottom);
|
||||
glEnd ();
|
||||
} if (top == bottom) { //in low resolution, a "rect" might be 1 pixel wide
|
||||
glBegin (GL_LINES);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (right, top);
|
||||
glEnd ();
|
||||
} else { // draw one of those fancy 2-dimensional rectangles
|
||||
glBegin (GL_QUADS);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (right, top);
|
||||
glVertex2i (right, bottom);
|
||||
glVertex2i (left, bottom);
|
||||
glEnd ();
|
||||
|
||||
|
||||
average = (color.red + color.blue + color.green) / 3.0f;
|
||||
bright = average > 0.5f;
|
||||
potential = (int)(average * 255.0f);
|
||||
|
||||
if (bright) {
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBegin (GL_POINTS);
|
||||
for (i = left + 1; i < right - 1; i++) {
|
||||
for (j = top + 1; j < bottom - 1; j++) {
|
||||
glColor4i (255, 0, RandomVal (potential), 255);
|
||||
hue = 0.2f + (float)RandomVal (100) / 300.0f + (float)RandomVal (100) / 300.0f + (float)RandomVal (100) / 300.0f;
|
||||
color_noise = glRgbaFromHsl (hue, 0.3f, 0.5f);
|
||||
color_noise.alpha = (float)RandomVal (potential) / 144.0f;
|
||||
glColor4f (RANDOM_COLOR_VAL, RANDOM_COLOR_VAL, RANDOM_COLOR_VAL, (float)RandomVal (potential) / 144.0f);
|
||||
glColor4fv (&color_noise.red);
|
||||
glVertex2i (i, j);
|
||||
}
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
repeats = RandomVal (6) + 1;
|
||||
height = (bottom - top) + (RandomVal (3) - 1) + (RandomVal(3) - 1);
|
||||
for (i = left; i < right; i++) {
|
||||
if (RandomVal (3) == 0)
|
||||
repeats = RandomVal (4) + 1;
|
||||
if (RandomVal (6) == 0) {
|
||||
height = bottom - top;
|
||||
height = RandomVal (height);
|
||||
height = RandomVal (height);
|
||||
height = RandomVal (height);
|
||||
height = ((bottom - top) + height) / 2;
|
||||
}
|
||||
for (j = 0; j < 1; j++) {
|
||||
glBegin (GL_LINES);
|
||||
glColor4f (0, 0, 0, (float)RandomVal (256) / 256.0f);
|
||||
glVertex2i (i, bottom - height);
|
||||
glColor4f (0, 0, 0, (float)RandomVal (256) / 256.0f);
|
||||
glVertex2i (i, bottom);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void window (int x, int y, int size, int id, GLrgba color)
|
||||
{
|
||||
|
||||
int margin;
|
||||
int half;
|
||||
int i;
|
||||
|
||||
margin = size / 3;
|
||||
half = size / 2;
|
||||
//color = (color * 0.9f) + glRgba (RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT);
|
||||
//glColor3fv (&color.red);
|
||||
switch (id) {
|
||||
case TEXTURE_BUILDING1: //filled, 1-pixel frame
|
||||
drawrect (x + 1, y + 1, x + size - 1, y + size - 1, color);
|
||||
break;
|
||||
case TEXTURE_BUILDING2: //vertical
|
||||
drawrect (x + margin, y + 1, x + size - margin, y + size - 1, color);
|
||||
break;
|
||||
case TEXTURE_BUILDING3: //side-by-side pair
|
||||
drawrect (x + 1, y + 1, x + half - 1, y + size - margin, color);
|
||||
drawrect (x + half + 1, y + 1, x + size - 1, y + size - margin, color);
|
||||
break;
|
||||
case TEXTURE_BUILDING4: //windows with blinds
|
||||
drawrect (x + 1, y + 1, x + size - 1, y + size - 1, color);
|
||||
i = RandomVal (size - 2);
|
||||
drawrect (x + 1, y + 1, x + size - 1, y + i + 1, color * 0.3f);
|
||||
|
||||
break;
|
||||
case TEXTURE_BUILDING5: //vert stripes
|
||||
drawrect (x + 1, y + 1, x + size - 1, y + size - 1, color);
|
||||
drawrect (x + margin, y + 1, x + margin, y + size - 1, color * 0.7f);
|
||||
drawrect (x + size - margin - 1, y + 1, x + size - margin - 1, y + size - 1, color * 0.3f);
|
||||
break;
|
||||
case TEXTURE_BUILDING6: //wide horz line
|
||||
drawrect (x + 1, y + 1, x + size - 1, y + size - margin, color);
|
||||
break;
|
||||
case TEXTURE_BUILDING7: //4-pane
|
||||
drawrect (x + 2, y + 1, x + size - 1, y + size - 1, color);
|
||||
drawrect (x + 2, y + half, x + size - 1, y + half, color * 0.2f);
|
||||
drawrect (x + half, y + 1, x + half, y + size - 1, color * 0.2f);
|
||||
break;
|
||||
case TEXTURE_BUILDING8: // Single narrow window
|
||||
drawrect (x + half - 1, y + 1, x + half + 1, y + size - margin, color);
|
||||
break;
|
||||
case TEXTURE_BUILDING9: //horizontal
|
||||
drawrect (x + 1, y + margin, x + size - 1, y + size - margin - 1, color);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_bloom (CTexture* t)
|
||||
{
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glViewport(0, 0, t->_size , t->_size);
|
||||
glCullFace (GL_BACK);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask (true);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable (GL_CULL_FACE);
|
||||
glCullFace (GL_BACK);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable (GL_FOG);
|
||||
glFogf (GL_FOG_START, RenderFogDistance () / 2);
|
||||
glFogf (GL_FOG_END, RenderFogDistance ());
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
WorldRender ();
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
EntityRender ();
|
||||
CarRender ();
|
||||
LightRender ();
|
||||
glBindTexture(GL_TEXTURE_2D, t->_glid);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, t->_size, t->_size, 0);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
CTexture::CTexture (int id, int size, bool mipmap, bool clamp, bool masked)
|
||||
{
|
||||
|
||||
glGenTextures (1, &_glid);
|
||||
_my_id = id;
|
||||
_mipmap = mipmap;
|
||||
_clamp = clamp;
|
||||
_masked = masked;
|
||||
_size = size;
|
||||
_half = size / 2;
|
||||
_segment_size = size / SEGMENTS_PER_TEXTURE;
|
||||
_ready = false;
|
||||
_next = head;
|
||||
head = this;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This draws all of the windows on a building texture. lit_density controls
|
||||
how many lights are on. (1 in n chance that the light is on. Higher values
|
||||
mean less lit windows. run_length controls how often it will consider
|
||||
changing the lit / unlit status. 1 produces a complete scatter, higher
|
||||
numbers make long strings of lights.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CTexture::DrawWindows ()
|
||||
{
|
||||
|
||||
|
||||
int x, y;
|
||||
int run;
|
||||
int run_length;
|
||||
int lit_density;
|
||||
GLrgba color;
|
||||
bool lit;
|
||||
|
||||
//color = glRgbaUnique (_my_id);
|
||||
for (y = 0; y < SEGMENTS_PER_TEXTURE; y++) {
|
||||
//Every few floors we change the behavior
|
||||
if (!(y % 8)) {
|
||||
run = 0;
|
||||
run_length = RandomVal (9) + 2;
|
||||
lit_density = 2 + RandomVal(2) + RandomVal(2);
|
||||
lit = false;
|
||||
}
|
||||
for (x = 0; x < SEGMENTS_PER_TEXTURE; x++) {
|
||||
//if this run is over reroll lit and start a new one
|
||||
if (run < 1) {
|
||||
run = RandomVal (run_length);
|
||||
lit = RandomVal (lit_density) == 0;
|
||||
//if (lit)
|
||||
//color = glRgba (0.5f + (float)(RandomVal () % 128) / 256.0f) + glRgba (RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT);
|
||||
}
|
||||
if (lit)
|
||||
color = glRgba (0.5f + (float)(RandomVal () % 128) / 256.0f) + glRgba (RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT, RANDOM_COLOR_SHIFT);
|
||||
else
|
||||
color = glRgba ((float)(RandomVal () % 40) / 256.0f);
|
||||
window (x * _segment_size, y * _segment_size, _segment_size, _my_id, color);
|
||||
run--;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Here is where ALL of the procedural textures are created. It's filled with
|
||||
obscure logic, magic numbers, and messy code. Part of this is because
|
||||
there is a lot of "art" being done here, and lots of numbers that could be
|
||||
endlessly tweaked. Also because I'm lazy.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CTexture::Rebuild ()
|
||||
{
|
||||
|
||||
int i, j;
|
||||
int x, y;
|
||||
int name_num, prefix_num, suffix_num;
|
||||
float radius;
|
||||
GLvector2 pos;
|
||||
GLrgba color;
|
||||
bool use_framebuffer;
|
||||
unsigned char* bits;
|
||||
unsigned start;
|
||||
int lapsed;
|
||||
|
||||
start = GetTickCount ();
|
||||
glBindTexture(GL_TEXTURE_2D, _glid);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, _size, _size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
if (_clamp) {
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
//Set up our viewport so that drawing into our texture will be as easy
|
||||
//as possible. We make the viewport and projection simply match the given
|
||||
//texture size.
|
||||
glViewport(0, 0, _size , _size);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, _size, _size, 0, 0.1f, 2048);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity();
|
||||
glDisable (GL_CULL_FACE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glTranslatef(0, 0, -10.0f);
|
||||
glClearColor (0, 0, 0, _masked ? 0.0f : 1.0f);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
use_framebuffer = true;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
switch (_my_id) {
|
||||
case TEXTURE_GROUND:
|
||||
unsigned char icolor[4];
|
||||
char cell;
|
||||
|
||||
//memset (buffer, 0, 1024 * 1024 * 4);
|
||||
bits = new unsigned char[_size * _size * 4];
|
||||
ZeroMemory (bits, sizeof (bits));
|
||||
icolor[3] = 255;
|
||||
for (x = 0; x < _size; x++) {
|
||||
for (y = 0; y < _size; y++) {
|
||||
cell = WorldCell (x, y);
|
||||
memset (icolor, 0, 3);
|
||||
if (cell & CLAIM_ROAD)
|
||||
icolor[0] = icolor[1] = icolor[2] = 12;
|
||||
if (cell == CLAIM_WALK)
|
||||
icolor[0] = icolor[1] = icolor[2] = 64;
|
||||
icolor[0] += (unsigned char)RandomVal (4);
|
||||
icolor[1] += (unsigned char)RandomVal (4);
|
||||
icolor[2] += (unsigned char)RandomVal (4);
|
||||
if (1) { //use this to make the road lanes visible
|
||||
if (cell & MAP_ROAD_EAST)
|
||||
icolor[0] += 128;
|
||||
if (cell & MAP_ROAD_WEST)
|
||||
icolor[1] += 128;
|
||||
if (cell & MAP_ROAD_NORTH)
|
||||
icolor[2] += 128;
|
||||
if (cell & MAP_ROAD_SOUTH) {
|
||||
icolor[1] += 64;
|
||||
icolor[2] += 64;
|
||||
}
|
||||
}
|
||||
memcpy (&bits[(x + y * _size) * 4], &icolor[0], 4);
|
||||
}
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, _glid);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, _size, _size, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
|
||||
use_framebuffer = false;
|
||||
delete bits;
|
||||
break;
|
||||
case TEXTURE_LATTICE:
|
||||
glLineWidth (2.0f);
|
||||
|
||||
glColor3f (0,0,0);
|
||||
glBegin (GL_LINES);
|
||||
glVertex2i (0, 0); glVertex2i (_size, _size);//diagonal
|
||||
glVertex2i (0, 0); glVertex2i (0, _size);//vertical
|
||||
glVertex2i (0, 0); glVertex2i (_size, 0);//vertical
|
||||
glEnd ();
|
||||
glBegin (GL_LINE_STRIP);
|
||||
glVertex2i (0, 0);
|
||||
for (i = 0; i < _size; i += 9) {
|
||||
if (i % 2)
|
||||
glVertex2i (0, i);
|
||||
else
|
||||
glVertex2i (i, i);
|
||||
}
|
||||
for (i = 0; i < _size; i += 9) {
|
||||
if (i % 2)
|
||||
glVertex2i (i, 0);
|
||||
else
|
||||
glVertex2i (i, i);
|
||||
}
|
||||
glEnd ();
|
||||
break;
|
||||
case TEXTURE_SOFT_CIRCLE:
|
||||
//Make a simple circle of light, bright in the center and fading out
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
radius = ((float)_half) - 3;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glColor4f (1, 1, 1, 1);
|
||||
glVertex2i (_half, _half);
|
||||
glColor4f (0, 0, 0, 0);
|
||||
for (i = 0; i <= 360; i++) {
|
||||
pos.x = sinf ((float)i * DEGREES_TO_RADIANS) * radius;
|
||||
pos.y = cosf ((float)i * DEGREES_TO_RADIANS) * radius;
|
||||
glVertex2i (_half + (int)pos.x, _half + (int)pos.y);
|
||||
}
|
||||
glEnd ();
|
||||
break;
|
||||
case TEXTURE_LIGHT:
|
||||
//
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
radius = ((float)_half) - 3;
|
||||
for (j = 0; j < 2; j++) {
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glColor4f (1, 1, 1, 1);
|
||||
glVertex2i (_half, _half);
|
||||
if (!j)
|
||||
radius = ((float)_half / 2);
|
||||
else
|
||||
radius = 8;
|
||||
glColor4f (1, 1, 0, 0);
|
||||
for (i = 0; i <= 360; i++) {
|
||||
pos.x = sinf ((float)i * DEGREES_TO_RADIANS) * radius;
|
||||
pos.y = cosf ((float)i * DEGREES_TO_RADIANS) * radius;
|
||||
glVertex2i (_half + (int)pos.x, _half + (int)pos.y);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
break;
|
||||
case TEXTURE_HEADLIGHT:
|
||||
//Make a simple circle of light, bright in the center and fading out
|
||||
radius = ((float)_half) - 20;
|
||||
x = _half - 20;
|
||||
y = _half;
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glColor4f (0.8f, 0.8f, 0.8f, 0.6f);
|
||||
glVertex2i (_half - 5, y);
|
||||
glColor4f (0, 0, 0, 0);
|
||||
for (i = 0; i <= 360; i += 36) {
|
||||
pos.x = sinf ((float)(i % 360) * DEGREES_TO_RADIANS) * radius;
|
||||
pos.y = cosf ((float)(i % 360) * DEGREES_TO_RADIANS) * radius;
|
||||
glVertex2i (x + (int)pos.x, _half + (int)pos.y);
|
||||
}
|
||||
glEnd ();
|
||||
x = _half + 20;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glColor4f (0.8f, 0.8f, 0.8f, 0.6f);
|
||||
glVertex2i (_half + 5, y);
|
||||
glColor4f (0, 0, 0, 0);
|
||||
for (i = 0; i <= 360; i += 36) {
|
||||
pos.x = sinf ((float)(i % 360) * DEGREES_TO_RADIANS) * radius;
|
||||
pos.y = cosf ((float)(i % 360) * DEGREES_TO_RADIANS) * radius;
|
||||
glVertex2i (x + (int)pos.x, _half + (int)pos.y);
|
||||
}
|
||||
glEnd ();
|
||||
x = _half - 6;
|
||||
drawrect_simple (x - 3, y - 2, x + 2, y + 2, glRgba (1.0f));
|
||||
x = _half + 6;
|
||||
drawrect_simple (x - 2, y - 2, x + 3, y + 2, glRgba (1.0f));
|
||||
break;
|
||||
case TEXTURE_LOGOS:
|
||||
i = 0;
|
||||
glDepthMask (false);
|
||||
glDisable (GL_BLEND);
|
||||
name_num = RandomVal (NAME_COUNT);
|
||||
prefix_num = RandomVal (PREFIX_COUNT);
|
||||
suffix_num = RandomVal (SUFFIX_COUNT);
|
||||
glColor3f (1,1,1);
|
||||
while (i < _size) {
|
||||
//randomly use a prefix OR suffix, but not both. Too verbose.
|
||||
/*
|
||||
if (COIN_FLIP)
|
||||
RenderPrint (2, _size - i - LOGO_PIXELS / 4, RandomVal(), glRgba (1.0f), "%s%s", prefix[prefix_num], name[name_num]);
|
||||
else
|
||||
RenderPrint (2, _size - i - LOGO_PIXELS / 4, RandomVal(), glRgba (1.0f), "%s%s", name[name_num], suffix[suffix_num]);
|
||||
*/
|
||||
RenderPrint (2, _size - i - LOGO_PIXELS / 4, RandomVal(), glRgba (1.0f), "Pixel City");
|
||||
name_num = (name_num + 1) % NAME_COUNT;
|
||||
prefix_num = (prefix_num + 1) % PREFIX_COUNT;
|
||||
suffix_num = (suffix_num + 1) % SUFFIX_COUNT;
|
||||
i += LOGO_PIXELS;
|
||||
}
|
||||
break;
|
||||
case TEXTURE_CLOUDS:
|
||||
int width, height;
|
||||
int offset;
|
||||
float scale;
|
||||
|
||||
for (i = _size - 30; i > 5; i -= 1) {
|
||||
x = RandomVal (_size);
|
||||
y = i;
|
||||
|
||||
scale = 1.0f - ((float)y / (float)_size);
|
||||
width = RandomVal (_half / 2) + (int)((float)_half * scale) / 2;
|
||||
scale = 1.0f - (float)y / (float)_size;
|
||||
height = (int)((float)(width) * scale);
|
||||
height = MAX (height, 4);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBindTexture (GL_TEXTURE_2D, TextureId (TEXTURE_SOFT_CIRCLE));
|
||||
glDepthMask (false);
|
||||
glBegin (GL_QUADS);
|
||||
for (offset = -_size; offset <= _size; offset += _size) {
|
||||
for (scale = 1.0f; scale > 0.0f; scale -= 0.25f) {
|
||||
int width_adjust;
|
||||
int height_adjust;
|
||||
float inv_scale;
|
||||
|
||||
inv_scale = 1.0f - (scale);
|
||||
|
||||
if (scale < 0.4f)
|
||||
color = cloud_color;
|
||||
else
|
||||
color = glRgba (0.0f);
|
||||
color.alpha = 1.0f;
|
||||
glColor4fv (&color.red);
|
||||
//width_adjust = (int)((1.0f - scale) * ((float)width / 2.0f));
|
||||
width_adjust = (int)((float)width / 2.0f + (int)(inv_scale * ((float)width / 2.0f)));
|
||||
height_adjust = height + (int)(scale * (float)height * 0.99f);
|
||||
|
||||
glTexCoord2f (0, 0); glVertex2i (offset + x - width_adjust, y + height - height_adjust);
|
||||
glTexCoord2f (0, 1); glVertex2i (offset + x - width_adjust, y + height);
|
||||
glTexCoord2f (1, 1); glVertex2i (offset + x + width_adjust, y + height);
|
||||
glTexCoord2f (1, 0); glVertex2i (offset + x + width_adjust, y + height - height_adjust);
|
||||
}
|
||||
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
break;
|
||||
case TEXTURE_TRIM:
|
||||
int margin;
|
||||
y = 0;
|
||||
margin = MAX (TRIM_PIXELS / 4, 1);
|
||||
for (x = 0; x < _size; x += TRIM_PIXELS)
|
||||
drawrect_simple (x + margin, y + margin, x + TRIM_PIXELS - margin, y + TRIM_PIXELS - margin, glRgba (1.0f), glRgba (0.5f));
|
||||
y += TRIM_PIXELS;
|
||||
for (x = 0; x < _size; x += TRIM_PIXELS * 2)
|
||||
drawrect_simple (x + margin, y + margin, x + TRIM_PIXELS - margin, y + TRIM_PIXELS - margin, glRgba (1.0f), glRgba (0.5f));
|
||||
y += TRIM_PIXELS;
|
||||
for (x = 0; x < _size; x += TRIM_PIXELS * 3)
|
||||
drawrect_simple (x + margin, y + margin, x + TRIM_PIXELS - margin, y + TRIM_PIXELS - margin, glRgba (1.0f), glRgba (0.5f));
|
||||
y += TRIM_PIXELS;
|
||||
for (x = 0; x < _size; x += TRIM_PIXELS)
|
||||
drawrect_simple (x + margin, y + margin * 2, x + TRIM_PIXELS - margin, y + TRIM_PIXELS - margin, glRgba (1.0f), glRgba (0.5f));
|
||||
break;
|
||||
case TEXTURE_SKY:
|
||||
glDisable (GL_BLEND);
|
||||
glBegin (GL_QUAD_STRIP);
|
||||
glColor3f (0,0,0);
|
||||
glVertex2i (0, _half);
|
||||
glVertex2i (_size, _half);
|
||||
glColor3fv (&horizon_color.red);
|
||||
glVertex2i (0, _size - 2);
|
||||
glVertex2i (_size, _size - 2);
|
||||
glEnd ();
|
||||
//Draw a bunch of little faux-buildings on the horizon.
|
||||
for (i = 0; i < _size; i += 5)
|
||||
drawrect (i, _size - RandomVal (8) - RandomVal (8) - RandomVal (8), i + RandomVal (9), _size, glRgba (0.0f));
|
||||
break;
|
||||
default: //building textures
|
||||
DrawWindows ();
|
||||
break;
|
||||
}
|
||||
glPopMatrix ();
|
||||
//Now blit the finished image into our texture
|
||||
if (use_framebuffer) {
|
||||
glBindTexture(GL_TEXTURE_2D, _glid);
|
||||
glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, _size, _size, 0);
|
||||
}
|
||||
if (_mipmap) {
|
||||
bits = (unsigned char*)malloc (_size * _size * 4);
|
||||
glGetTexImage (GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, _size, _size, GL_RGBA, GL_UNSIGNED_BYTE, bits);
|
||||
free (bits);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
} else
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
//cleanup and restore the viewport
|
||||
RenderResize ();
|
||||
_ready = true;
|
||||
lapsed = GetTickCount () - start;
|
||||
build_time += lapsed;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned TextureId (int id)
|
||||
{
|
||||
|
||||
for (CTexture* t = head; t; t = t->_next) {
|
||||
if (t->_my_id == id)
|
||||
return t->_glid;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
unsigned TextureRandomBuilding (int index)
|
||||
{
|
||||
|
||||
index = abs (index) % BUILDING_COUNT;
|
||||
return TextureId (TEXTURE_BUILDING1 + index);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void TextureReset (void)
|
||||
{
|
||||
|
||||
float hue, sat;
|
||||
|
||||
textures_done = false;
|
||||
build_time = 0;
|
||||
for (CTexture* t = head; t; t = t->_next)
|
||||
t->Clear ();
|
||||
hue = 0.5f + (float)RandomVal (20) / 100.0f;
|
||||
sat = 0.1f + (float)RandomVal (80) / 100.0f;
|
||||
horizon_color = glRgbaFromHsl (hue, sat, 0.15f);
|
||||
cloud_color = glRgbaFromHsl (hue, 0.15f, 0.1f);
|
||||
ZeroMemory (prefix_used, sizeof (prefix_used));
|
||||
ZeroMemory (name_used, sizeof (name_used));
|
||||
ZeroMemory (suffix_used, sizeof (suffix_used));
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool TextureReady ()
|
||||
{
|
||||
|
||||
return textures_done;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void TextureUpdate (void)
|
||||
{
|
||||
|
||||
if (textures_done) {
|
||||
if (!RenderBloom ())
|
||||
return;
|
||||
CTexture* t;
|
||||
|
||||
for (t = head; t; t = t->_next) {
|
||||
if (t->_my_id != TEXTURE_BLOOM)
|
||||
continue;
|
||||
do_bloom (t);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (CTexture* t = head; t; t = t->_next) {
|
||||
if (!t->_ready) {
|
||||
t->Rebuild();
|
||||
return;
|
||||
}
|
||||
}
|
||||
textures_done = true;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void TextureTerm (void)
|
||||
{
|
||||
|
||||
CTexture* t;
|
||||
|
||||
while (head) {
|
||||
t = head->_next;
|
||||
free (head);
|
||||
head = t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void TextureInit (void)
|
||||
{
|
||||
|
||||
new CTexture (TEXTURE_SKY, 512, true, false, false);
|
||||
new CTexture (TEXTURE_CLOUDS, 256, true, false, true);
|
||||
new CTexture (TEXTURE_LATTICE, 128, true, true, true);
|
||||
new CTexture (TEXTURE_LIGHT, 128, false, false, true);
|
||||
new CTexture (TEXTURE_SOFT_CIRCLE, 128, false, false, true);
|
||||
new CTexture (TEXTURE_HEADLIGHT, 128, false, false, true);
|
||||
new CTexture (TEXTURE_TRIM, TRIM_RESOLUTION, true, false, false);
|
||||
if (SHOW_DEBUG_GROUND)
|
||||
new CTexture (TEXTURE_GROUND, 1024, false, false, false);
|
||||
new CTexture (TEXTURE_LOGOS, LOGO_RESOLUTION, true, false, true);
|
||||
for (int i = TEXTURE_BUILDING1; i <= TEXTURE_BUILDING9; i++)
|
||||
new CTexture (i, 512, true, false, false);
|
||||
new CTexture (TEXTURE_BLOOM, 512, true, false, false);
|
||||
int names = PREFIX_COUNT * NAME_COUNT + SUFFIX_COUNT * NAME_COUNT;
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#define SEGMENTS_PER_TEXTURE 64
|
||||
#define ONE_SEGMENT (1.0f / SEGMENTS_PER_TEXTURE)
|
||||
#define LANES_PER_TEXTURE 8
|
||||
#define LANE_SIZE (1.0f / LANES_PER_TEXTURE)
|
||||
#define LANE_PIXELS (_size / LANES_PER_TEXTURE)
|
||||
#define TRIM_RESOLUTION 256
|
||||
#define TRIM_ROWS 4
|
||||
#define TRIM_SIZE (1.0f / TRIM_ROWS)
|
||||
#define TRIM_PIXELS (TRIM_RESOLUTION / TRIM_ROWS)
|
||||
#define LOGO_RESOLUTION 512
|
||||
#define LOGO_ROWS 16
|
||||
#define LOGO_SIZE (1.0f / LOGO_ROWS)
|
||||
#define LOGO_PIXELS (LOGO_RESOLUTION / LOGO_ROWS)
|
||||
|
||||
enum
|
||||
{
|
||||
TEXTURE_GROUND,
|
||||
TEXTURE_LIGHT,
|
||||
TEXTURE_SOFT_CIRCLE,
|
||||
TEXTURE_SKY,
|
||||
TEXTURE_CLOUDS,
|
||||
TEXTURE_LOGOS,
|
||||
TEXTURE_TRIM,
|
||||
TEXTURE_BLOOM,
|
||||
TEXTURE_HEADLIGHT,
|
||||
TEXTURE_LATTICE,
|
||||
TEXTURE_BUILDING1,
|
||||
TEXTURE_BUILDING2,
|
||||
TEXTURE_BUILDING3,
|
||||
TEXTURE_BUILDING4,
|
||||
TEXTURE_BUILDING5,
|
||||
TEXTURE_BUILDING6,
|
||||
TEXTURE_BUILDING7,
|
||||
TEXTURE_BUILDING8,
|
||||
TEXTURE_BUILDING9,
|
||||
TEXTURE_COUNT,
|
||||
};
|
||||
|
||||
#define BUILDING_COUNT ((TEXTURE_BUILDING9 - TEXTURE_BUILDING1) + 1)
|
||||
|
||||
unsigned TextureFromName (char* name);
|
||||
unsigned TextureId (int id);
|
||||
void TextureInit (void);
|
||||
void TextureTerm (void);
|
||||
unsigned TextureRandomBuilding (int index);
|
||||
bool TextureReady ();
|
||||
void TextureReset (void);
|
||||
void TextureUpdate (void);
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Visible.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This module runs the visibility grid, a 2-dimensional array that aids in
|
||||
culling objects during rendering.
|
||||
|
||||
There are many ways this could be refined or sped up, although tests indicate
|
||||
it's not a huge drain on performance.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "glTypes.h"
|
||||
#include "camera.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "visible.h"
|
||||
#include "world.h"
|
||||
|
||||
static bool vis_grid[GRID_SIZE][GRID_SIZE];
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool Visible (GLvector pos)
|
||||
{
|
||||
|
||||
return vis_grid[WORLD_TO_GRID(pos.x)][WORLD_TO_GRID(pos.z)];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool Visible (int x, int z)
|
||||
{
|
||||
|
||||
return vis_grid[x][z];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void VisibleUpdate (void)
|
||||
{
|
||||
|
||||
GLvector angle;
|
||||
GLvector position;
|
||||
int x, y, grid_x, grid_z;
|
||||
int left, right, front, back;
|
||||
float angle_to;
|
||||
float angle_diff;
|
||||
float target_x, target_z;
|
||||
|
||||
LIMIT_INTERVAL (50);
|
||||
//Clear the visibility table
|
||||
ZeroMemory (vis_grid, sizeof (vis_grid));
|
||||
//Calculate which cell the camera is in
|
||||
angle = CameraAngle ();
|
||||
position = CameraPosition ();
|
||||
grid_x = WORLD_TO_GRID(position.x);
|
||||
grid_z = WORLD_TO_GRID(position.z);
|
||||
//Cells directly adjactent to the camera might technically fall out of the fov,
|
||||
//but still have a few objects poking into screenspace when looking up or down.
|
||||
//Rather than obsess over sorting those objects properly, it's more efficient to
|
||||
//just mark them visible.
|
||||
left = right = front = back = 3;
|
||||
//Looking north, can't see south.
|
||||
if (angle.y < 45.0f || angle.y > 315.0f)
|
||||
front = 0;
|
||||
//Looking south, can't see north
|
||||
if (angle.y > 135.0f && angle.y < 225.0f)
|
||||
back = 0;
|
||||
//Looking east, can't see west
|
||||
if (angle.y > 45.0f && angle.y < 135.0f)
|
||||
left = 0;
|
||||
//Looking west, can't see east
|
||||
if (angle.y > 225.0f && angle.y < 315.0f)
|
||||
right = 0;
|
||||
//Now mark the block around us the might be visible
|
||||
for (x = grid_x - left; x <= grid_x + right; x++) {
|
||||
if (x < 0 || x >= WORLD_SIZE) //just in case the camera leaves the world map
|
||||
continue;
|
||||
for (y = grid_z - back; y <= grid_z + front; y++) {
|
||||
if (y < 0 || y >= WORLD_SIZE) //just in case the camera leaves the world map
|
||||
continue;
|
||||
vis_grid[x][y] = true;
|
||||
}
|
||||
}
|
||||
//Doesn't matter where we are facing, objects in current cell are always visible
|
||||
vis_grid[grid_x][grid_z] = true;
|
||||
//Here, we look at the angle from the current camera position to the cell
|
||||
//on the grid, and how much that angle deviates from the current view angle.
|
||||
for (x = 0; x < GRID_SIZE; x++) {
|
||||
for (y = 0; y < GRID_SIZE; y++) {
|
||||
//if we marked it visible earlier, skip all this math
|
||||
if (vis_grid[x][y])
|
||||
continue;
|
||||
//if the camera is to the left of this cell, use the left edge
|
||||
if (grid_x < x)
|
||||
target_x = (float)x * GRID_RESOLUTION;
|
||||
else
|
||||
target_x = (float)(x + 1) * GRID_RESOLUTION;
|
||||
if (grid_z < y)
|
||||
target_z = (float)y * GRID_RESOLUTION;
|
||||
else
|
||||
target_z = (float)(y + 1) * GRID_RESOLUTION;
|
||||
angle_to = 180 - MathAngle (target_x, target_z, position.x, position.z);
|
||||
//Store how many degrees the cell is to the
|
||||
angle_diff = (float)fabs (MathAngleDifference (angle.y, angle_to));
|
||||
vis_grid[x][y] = angle_diff < 45;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#define GRID_RESOLUTION 32
|
||||
#define GRID_CELL (GRID_RESOLUTION / 2)
|
||||
#define GRID_SIZE (WORLD_SIZE / GRID_RESOLUTION)
|
||||
#define WORLD_TO_GRID(x) (int)(x / GRID_RESOLUTION)
|
||||
#define GRID_TO_WORLD(x) ((float)x * GRID_RESOLUTION)
|
||||
|
||||
|
||||
|
||||
void VisibleUpdate (void);
|
||||
bool Visible (GLvector pos);
|
||||
bool Visible (int x, int z);
|
|
@ -0,0 +1,608 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Win.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Create the main window and make it go.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MOUSE_MOVEMENT 0.5f
|
||||
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <scrnsave.h>
|
||||
|
||||
#include "camera.h"
|
||||
#include "car.h"
|
||||
#include "entity.h"
|
||||
#include "glTypes.h"
|
||||
#include "ini.h"
|
||||
#include "macro.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include "win.h"
|
||||
#include "world.h"
|
||||
#include "visible.h"
|
||||
|
||||
|
||||
#pragma comment (lib, "opengl32.lib")
|
||||
#pragma comment (lib, "glu32.lib")
|
||||
#pragma comment (lib, "GLaux.lib")
|
||||
#if SCREENSAVER
|
||||
#pragma comment (lib, "scrnsave.lib")
|
||||
#endif
|
||||
|
||||
static HWND hwnd;
|
||||
static HINSTANCE module;
|
||||
static int width;
|
||||
static int height;
|
||||
static int half_width;
|
||||
static int half_height;
|
||||
static bool lmb;
|
||||
static bool rmb;
|
||||
static bool mouse_forced;
|
||||
static POINT select_pos;
|
||||
static POINT mouse_pos;
|
||||
|
||||
static bool quit;
|
||||
static HINSTANCE instance;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void CenterCursor ()
|
||||
{
|
||||
|
||||
int center_x;
|
||||
int center_y;
|
||||
RECT rect;
|
||||
|
||||
SetCursor (NULL);
|
||||
mouse_forced = true;
|
||||
GetWindowRect (hwnd, &rect);
|
||||
center_x = rect.left + (rect.right - rect.left) / 2;
|
||||
center_y = rect.top + (rect.bottom - rect.top) / 2;
|
||||
SetCursorPos (center_x, center_y);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void MoveCursor (int x, int y)
|
||||
{
|
||||
|
||||
int center_x;
|
||||
int center_y;
|
||||
RECT rect;
|
||||
|
||||
SetCursor (NULL);
|
||||
mouse_forced = true;
|
||||
GetWindowRect (hwnd, &rect);
|
||||
center_x = rect.left + x;
|
||||
center_y = rect.top + y;
|
||||
SetCursorPos (center_x, center_y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
|
||||
RECT r;
|
||||
float delta_x, delta_y;
|
||||
POINT p;
|
||||
int param;
|
||||
int key;
|
||||
|
||||
switch (message) {
|
||||
case WM_SIZE:
|
||||
param = wParam; // resizing flag
|
||||
width = LOWORD(lParam); // width of client area
|
||||
height = HIWORD(lParam); // height of client area
|
||||
|
||||
if (param == SIZE_RESTORED)
|
||||
IniIntSet ("WindowMaximized", 0);
|
||||
if (param == SIZE_MAXIMIZED) {
|
||||
IniIntSet ("WindowMaximized", 1);
|
||||
} else {
|
||||
IniIntSet ("WindowWidth", width);
|
||||
IniIntSet ("WindowHeight", height);
|
||||
}
|
||||
return 0;
|
||||
case WM_MOVE:
|
||||
GetClientRect (hwnd, &r);
|
||||
height = r.bottom - r.top;
|
||||
width = r.right - r.left;
|
||||
IniIntSet ("WindowX", r.left);
|
||||
IniIntSet ("WindowY", r.top);
|
||||
IniIntSet ("WindowWidth", width);
|
||||
IniIntSet ("WindowHeight", height);
|
||||
half_width = width / 2;
|
||||
half_height = height / 2;
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
key = (int) wParam;
|
||||
|
||||
if (key == 'R')
|
||||
WorldReset ();
|
||||
if (key == 'C')
|
||||
CameraAutoToggle ();
|
||||
if (key == 'W')
|
||||
RenderWireframeToggle ();
|
||||
if (key == 'E')
|
||||
RenderEffectCycle ();
|
||||
if (key == 'L')
|
||||
RenderLetterboxToggle ();
|
||||
if (key == 'F')
|
||||
RenderFPSToggle ();
|
||||
if (key == 'G')
|
||||
RenderFogToggle ();
|
||||
if (key == 'T')
|
||||
RenderFlatToggle ();
|
||||
if (key == VK_F1)
|
||||
RenderHelpToggle ();
|
||||
if (key == 'B')
|
||||
CameraNextBehavior ();
|
||||
if (key == VK_ESCAPE)
|
||||
quit = true;
|
||||
if (key == VK_F5)
|
||||
CameraReset ();
|
||||
return 0;
|
||||
case WM_LBUTTONDOWN:
|
||||
lmb = true;
|
||||
SetCapture (hwnd);
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
rmb = true;
|
||||
SetCapture (hwnd);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
lmb = false;
|
||||
if (!rmb) {
|
||||
ReleaseCapture ();
|
||||
MoveCursor (select_pos.x, select_pos.y);
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
rmb = false;
|
||||
if (!lmb) {
|
||||
ReleaseCapture ();
|
||||
MoveCursor (select_pos.x, select_pos.y);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
p.x = LOWORD(lParam); // horizontal position of cursor
|
||||
p.y = HIWORD(lParam); // vertical position of cursor
|
||||
if (p.x < 0 || p.x > width)
|
||||
break;
|
||||
if (p.y < 0 || p.y > height)
|
||||
break;
|
||||
if (!mouse_forced && !lmb && !rmb) {
|
||||
select_pos = p;
|
||||
}
|
||||
if (mouse_forced) {
|
||||
mouse_forced = false;
|
||||
} else if (rmb || lmb) {
|
||||
CenterCursor ();
|
||||
delta_x = (float)(mouse_pos.x - p.x) * MOUSE_MOVEMENT;
|
||||
delta_y = (float)(mouse_pos.y - p.y) * MOUSE_MOVEMENT;
|
||||
if (rmb && lmb) {
|
||||
GLvector pos;
|
||||
CameraPan (delta_x);
|
||||
pos = CameraPosition ();
|
||||
pos.y += delta_y;
|
||||
CameraPositionSet (pos);
|
||||
} else if (rmb) {
|
||||
CameraPan (delta_x);
|
||||
CameraForward (delta_y);
|
||||
} else if (lmb) {
|
||||
GLvector angle;
|
||||
angle = CameraAngle ();
|
||||
angle.y -= delta_x;
|
||||
angle.x += delta_y;
|
||||
CameraAngleSet (angle);
|
||||
}
|
||||
}
|
||||
mouse_pos = p;
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
quit = true;
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
HINSTANCE WinInstance ()
|
||||
{
|
||||
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
n o t e
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WinPopup (char* message, ...)
|
||||
{
|
||||
|
||||
va_list marker;
|
||||
char buf[1024];
|
||||
|
||||
va_start (marker, message);
|
||||
vsprintf (buf, message, marker);
|
||||
va_end (marker);
|
||||
MessageBox (NULL, buf, APP_TITLE, MB_ICONSTOP | MB_OK |
|
||||
MB_TASKMODAL);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int WinWidth (void)
|
||||
{
|
||||
|
||||
return width;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WinMousePosition (int* x, int* y)
|
||||
{
|
||||
|
||||
*x = select_pos.x;
|
||||
*y = select_pos.y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int WinHeight (void)
|
||||
{
|
||||
|
||||
return height;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WinTerm (void)
|
||||
{
|
||||
#if !SCREENAVER
|
||||
DestroyWindow (hwnd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
HWND WinHwnd (void)
|
||||
{
|
||||
|
||||
return hwnd;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool WinInit (void)
|
||||
{
|
||||
|
||||
WNDCLASSEX wcex;
|
||||
int x, y;
|
||||
int style;
|
||||
bool max;
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = (WNDPROC)WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = instance;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = APP_TITLE;
|
||||
wcex.hIconSm = NULL;
|
||||
if (!RegisterClassEx(&wcex)) {
|
||||
WinPopup ("Cannot create window class");
|
||||
return false;
|
||||
}
|
||||
x = IniInt ("WindowX");
|
||||
y = IniInt ("WindowY");
|
||||
style = WS_TILEDWINDOW;
|
||||
style |= WS_MAXIMIZE;
|
||||
width = IniInt ("WindowWidth");
|
||||
height = IniInt ("WindowHeight");
|
||||
width = CLAMP (width, 800, 2048);
|
||||
height = CLAMP (height, 600, 2048);
|
||||
half_width = width / 2;
|
||||
half_height = height / 2;
|
||||
max = IniInt ("WindowMaximized") == 1;
|
||||
if (!(hwnd = CreateWindowEx (0, APP_TITLE, APP_TITLE, style,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, instance, NULL))) {
|
||||
WinPopup ("Cannot create window");
|
||||
return false;
|
||||
}
|
||||
if (max)
|
||||
ShowWindow (hwnd, SW_MAXIMIZE);
|
||||
else
|
||||
ShowWindow (hwnd, SW_SHOW);
|
||||
UpdateWindow (hwnd);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void AppQuit ()
|
||||
{
|
||||
|
||||
quit = true;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void AppInit (void)
|
||||
{
|
||||
|
||||
RandomInit (1);
|
||||
CameraInit ();
|
||||
RenderInit ();
|
||||
TextureInit ();
|
||||
WorldInit ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void AppUpdate ()
|
||||
{
|
||||
|
||||
CameraUpdate ();
|
||||
WorldUpdate ();
|
||||
TextureUpdate ();
|
||||
VisibleUpdate ();
|
||||
CarUpdate ();
|
||||
EntityUpdate ();
|
||||
RenderUpdate ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
W i n M a i n
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void AppTerm (void)
|
||||
{
|
||||
|
||||
TextureTerm ();
|
||||
WorldTerm ();
|
||||
RenderTerm ();
|
||||
CameraTerm ();
|
||||
WinTerm ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
W i n M a i n
|
||||
-----------------------------------------------------------------------------*/
|
||||
#if !SCREENSAVER
|
||||
|
||||
int PASCAL WinMain (HINSTANCE instance_in, HINSTANCE previous_instance,
|
||||
LPSTR command_line, int show_style)
|
||||
{
|
||||
|
||||
MSG msg;
|
||||
|
||||
instance = instance_in;
|
||||
WinInit ();
|
||||
AppInit ();
|
||||
while (!quit) {
|
||||
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT)
|
||||
quit = true;
|
||||
else {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
} else {
|
||||
AppUpdate ();
|
||||
}
|
||||
}
|
||||
AppTerm ();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool terminated;
|
||||
|
||||
LONG WINAPI ScreenSaverProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
RECT r;
|
||||
float delta_x, delta_y;
|
||||
POINT p;
|
||||
int param;
|
||||
int key;
|
||||
|
||||
if (terminated)
|
||||
return DefScreenSaverProc (hWnd, msg, wParam, lParam);
|
||||
switch (msg) {
|
||||
case WM_CREATE:
|
||||
hwnd = hWnd;
|
||||
AppInit ();
|
||||
return 0;
|
||||
case WM_CLOSE:
|
||||
case WM_DESTROY:
|
||||
AppTerm ();
|
||||
terminated = true;
|
||||
return 0;
|
||||
case WM_PAINT:
|
||||
AppUpdate ();
|
||||
return 0;
|
||||
case WM_SIZE:
|
||||
param = wParam; // resizing flag
|
||||
width = LOWORD(lParam); // width of client area
|
||||
height = HIWORD(lParam); // height of client area
|
||||
|
||||
if (param == SIZE_MAXIMIZED) {
|
||||
IniIntSet ("WindowMaximized", 1);
|
||||
} else {
|
||||
IniIntSet ("WindowWidth", width);
|
||||
IniIntSet ("WindowHeight", height);
|
||||
}
|
||||
return 0;
|
||||
case WM_MOVE:
|
||||
GetClientRect (hwnd, &r);
|
||||
height = r.bottom - r.top;
|
||||
width = r.right - r.left;
|
||||
IniIntSet ("WindowX", r.left);
|
||||
IniIntSet ("WindowY", r.top);
|
||||
IniIntSet ("WindowWidth", width);
|
||||
IniIntSet ("WindowHeight", height);
|
||||
half_width = width / 2;
|
||||
half_height = height / 2;
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
key = (int) wParam;
|
||||
|
||||
if (key == 'R')
|
||||
WorldReset ();
|
||||
else if (key == 'C')
|
||||
CameraAutoToggle ();
|
||||
else if (key == 'W')
|
||||
RenderWireframeToggle ();
|
||||
else if (key == 'E')
|
||||
RenderEffectCycle ();
|
||||
else if (key == 'L')
|
||||
RenderLetterboxToggle ();
|
||||
else if (key == 'F')
|
||||
RenderFPSToggle ();
|
||||
else if (key == 'G')
|
||||
RenderFogToggle ();
|
||||
else if (key == 'T')
|
||||
RenderFlatToggle ();
|
||||
else if (key == VK_F1)
|
||||
RenderHelpToggle ();
|
||||
else if (key == VK_ESCAPE)
|
||||
break;
|
||||
else if (key == VK_F5)
|
||||
CameraReset ();
|
||||
else
|
||||
break;
|
||||
return 0;
|
||||
case WM_LBUTTONDOWN:
|
||||
lmb = true;
|
||||
SetCapture (hwnd);
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
rmb = true;
|
||||
SetCapture (hwnd);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
lmb = false;
|
||||
if (!rmb) {
|
||||
ReleaseCapture ();
|
||||
MoveCursor (select_pos.x, select_pos.y);
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
rmb = false;
|
||||
if (!lmb) {
|
||||
ReleaseCapture ();
|
||||
MoveCursor (select_pos.x, select_pos.y);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
p.x = LOWORD(lParam); // horizontal position of cursor
|
||||
p.y = HIWORD(lParam); // vertical position of cursor
|
||||
if (p.x < 0 || p.x > width)
|
||||
break;
|
||||
if (p.y < 0 || p.y > height)
|
||||
break;
|
||||
if (!mouse_forced && !lmb && !rmb) {
|
||||
select_pos = p;
|
||||
}
|
||||
if (mouse_forced) {
|
||||
mouse_forced = false;
|
||||
} else if (rmb || lmb) {
|
||||
CenterCursor ();
|
||||
delta_x = (float)(mouse_pos.x - p.x) * MOUSE_MOVEMENT;
|
||||
delta_y = (float)(mouse_pos.y - p.y) * MOUSE_MOVEMENT;
|
||||
if (rmb && lmb) {
|
||||
GLvector pos;
|
||||
CameraPan (delta_x);
|
||||
pos = CameraPosition ();
|
||||
pos.y += delta_y;
|
||||
CameraPositionSet (pos);
|
||||
} else if (rmb) {
|
||||
CameraPan (delta_x);
|
||||
CameraForward (delta_y);
|
||||
} else if (lmb) {
|
||||
GLvector angle;
|
||||
angle = CameraAngle ();
|
||||
angle.y -= delta_x;
|
||||
angle.x += delta_y;
|
||||
CameraAngleSet (angle);
|
||||
}
|
||||
}
|
||||
mouse_pos = p;
|
||||
break;
|
||||
|
||||
}
|
||||
return DefScreenSaverProc (hWnd, msg, wParam, lParam);
|
||||
|
||||
}
|
||||
|
||||
BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { return FALSE; }
|
||||
BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
#define APP_TITLE "PixelCity"
|
||||
#define APP "pixelcity"
|
||||
#define SCREENSAVER 0
|
||||
|
||||
|
||||
HWND WinHwnd (void);
|
||||
void WinPopup (char* message, ...);
|
||||
void WinTerm (void);
|
||||
bool WinInit (void);
|
||||
int WinWidth (void);
|
||||
int WinHeight (void);
|
||||
void WinMousePosition (int* x, int* y);
|
|
@ -0,0 +1,745 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
World.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This holds a bunch of variables used by the other modules. It has the
|
||||
claim system, which tracks all of the "property" is being used: As roads,
|
||||
buildings, etc.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define HUE_COUNT (sizeof(hue_list)/sizeof(float))
|
||||
#define LIGHT_COLOR_COUNT (sizeof(light_colors)/sizeof(HSL))
|
||||
#define CARS 600
|
||||
#define WORLD_EDGE 200
|
||||
#if SCREENSAVER
|
||||
#define RESET_INTERVAL 120 //seconds
|
||||
#define FADE_TIME 500 //milliseconds
|
||||
#else
|
||||
#define RESET_INTERVAL 999 //seconds
|
||||
#define FADE_TIME 1500 //milliseconds
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
#include <gl\glaux.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "glTypes.h"
|
||||
#include "building.h"
|
||||
#include "car.h"
|
||||
#include "deco.h"
|
||||
#include "camera.h"
|
||||
#include "light.h"
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "mesh.h"
|
||||
#include "random.h"
|
||||
#include "render.h"
|
||||
#include "sky.h"
|
||||
#include "texture.h"
|
||||
#include "visible.h"
|
||||
#include "world.h"
|
||||
|
||||
struct plot
|
||||
{
|
||||
int x;
|
||||
int z;
|
||||
int width;
|
||||
int depth;
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
FADE_IDLE,
|
||||
FADE_OUT,
|
||||
FADE_WAIT,
|
||||
FADE_IN,
|
||||
};
|
||||
|
||||
struct HSL
|
||||
{
|
||||
float hue;
|
||||
float sat;
|
||||
float lum;
|
||||
};
|
||||
|
||||
class CStreet
|
||||
{
|
||||
public:
|
||||
int _x;
|
||||
int _y;
|
||||
int _width;
|
||||
int _depth;
|
||||
CMesh* _mesh;
|
||||
|
||||
CStreet (int x, int y, int width, int depth);
|
||||
~CStreet();
|
||||
void Render ();
|
||||
|
||||
};
|
||||
|
||||
static HSL light_colors[] =
|
||||
{
|
||||
0.04f, 0.9f, 0.93f, //Amber / pink
|
||||
0.055f, 0.95f, 0.93f, //Slightly brighter amber
|
||||
0.08f, 0.7f, 0.93f, //Very pale amber
|
||||
0.07f, 0.9f, 0.93f, //Very pale orange
|
||||
0.1f, 0.9f, 0.85f, //Peach
|
||||
0.13f, 0.9f, 0.93f, //Pale Yellow
|
||||
0.15f, 0.9f, 0.93f, //Yellow
|
||||
0.17f, 1.0f, 0.85f, //Saturated Yellow
|
||||
0.55f, 0.9f, 0.93f, //Cyan
|
||||
0.55f, 0.9f, 0.93f, //Cyan - pale, almost white
|
||||
0.6f, 0.9f, 0.93f, //Pale blue
|
||||
0.65f, 0.9f, 0.93f, //Pale Blue II, The Palening
|
||||
0.65f, 0.4f, 0.99f, //Pure white. Bo-ring.
|
||||
0.65f, 0.0f, 0.8f, //Dimmer white.
|
||||
0.65f, 0.0f, 0.6f, //Dimmest white.
|
||||
};
|
||||
|
||||
static float hue_list[] = { 0.04f, 0.07f, 0.1f, 0.5f, 0.6f }; //Yellows and blues - good for lights
|
||||
static GLrgba bloom_color;
|
||||
static long last_update;
|
||||
static char world[WORLD_SIZE][WORLD_SIZE];
|
||||
static CSky* sky;
|
||||
static int fade_state;
|
||||
static unsigned fade_start;
|
||||
static float fade_current;
|
||||
static int modern_count;
|
||||
static int tower_count;
|
||||
static int blocky_count;
|
||||
static bool reset_needed;
|
||||
static int skyscrapers;
|
||||
static GLbbox hot_zone;
|
||||
static unsigned start_time;
|
||||
static int logo_index;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static GLrgba get_light_color (float sat, float lum)
|
||||
{
|
||||
|
||||
int index;
|
||||
|
||||
index = RandomVal (LIGHT_COLOR_COUNT);
|
||||
return glRgbaFromHsl (light_colors[index].hue, sat, lum);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void claim (int x, int y, int width, int depth, int val)
|
||||
{
|
||||
|
||||
int xx, yy;
|
||||
|
||||
for (xx = x; xx < (x + width); xx++) {
|
||||
for (yy = y; yy < (y + depth); yy++) {
|
||||
world[CLAMP (xx,0,WORLD_SIZE - 1)][CLAMP (yy,0,WORLD_SIZE - 1)] |= val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static bool claimed (int x, int y, int width, int depth)
|
||||
{
|
||||
|
||||
int xx, yy;
|
||||
|
||||
for (xx = x; xx < x + width; xx++) {
|
||||
for (yy = y; yy < y + depth; yy++) {
|
||||
if (world[CLAMP (xx,0,WORLD_SIZE - 1)][CLAMP (yy,0,WORLD_SIZE - 1)])
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void build_road (int x1, int y1, int width, int depth)
|
||||
{
|
||||
|
||||
int lanes;
|
||||
int divider;
|
||||
int sidewalk;
|
||||
|
||||
//the given rectangle defines a street and its sidewalk. See which way it goes.
|
||||
if (width > depth)
|
||||
lanes = depth;
|
||||
else
|
||||
lanes = width;
|
||||
//if we dont have room for both lanes and sidewalk, abort
|
||||
if (lanes < 4)
|
||||
return;
|
||||
//if we have an odd number of lanes, give the extra to a divider.
|
||||
if (lanes % 2) {
|
||||
lanes--;
|
||||
divider = 1;
|
||||
} else
|
||||
divider = 0;
|
||||
//no more than 10 traffic lanes, give the rest to sidewalks
|
||||
sidewalk = MAX (2, (lanes - 10));
|
||||
lanes -= sidewalk;
|
||||
sidewalk /= 2;
|
||||
//take the remaining space and give half to each direction
|
||||
lanes /= 2;
|
||||
//Mark the entire rectangle as used
|
||||
claim (x1, y1, width, depth, CLAIM_WALK);
|
||||
//now place the directional roads
|
||||
if (width > depth) {
|
||||
claim (x1, y1 + sidewalk, width, lanes, CLAIM_ROAD | MAP_ROAD_WEST);
|
||||
claim (x1, y1 + sidewalk + lanes + divider, width, lanes, CLAIM_ROAD | MAP_ROAD_EAST);
|
||||
} else {
|
||||
claim (x1 + sidewalk, y1, lanes, depth, CLAIM_ROAD | MAP_ROAD_SOUTH);
|
||||
claim (x1 + sidewalk + lanes + divider, y1, lanes, depth, CLAIM_ROAD | MAP_ROAD_NORTH);
|
||||
}
|
||||
//new CStreet (x1, y1, width, depth);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static plot find_plot (int x, int z)
|
||||
{
|
||||
|
||||
plot p;
|
||||
int x1, x2, z1, z2;
|
||||
|
||||
//We've been given the location of an open bit of land, but we have no
|
||||
//idea how big it is. Find the boundary.
|
||||
x1 = x2 = x;
|
||||
while (!claimed (x1 - 1, z, 1, 1) && x1 > 0)
|
||||
x1--;
|
||||
while (!claimed (x2 + 1, z, 1, 1) && x2 < WORLD_SIZE)
|
||||
x2++;
|
||||
z1 = z2 = z;
|
||||
while (!claimed (x, z1 - 1, 1, 1) && z1 > 0)
|
||||
z1--;
|
||||
while (!claimed (x, z2 + 1, 1, 1) && z2 < WORLD_SIZE)
|
||||
z2++;
|
||||
p.width = (x2 - x1);
|
||||
p.depth = (z2 - z1);
|
||||
p.x = x1;
|
||||
p.z = z1;
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static plot make_plot (int x, int z, int width, int depth)
|
||||
{
|
||||
|
||||
plot p = {x, z, width, depth};
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void do_building (plot p)
|
||||
{
|
||||
|
||||
int height;
|
||||
int seed;
|
||||
int area;
|
||||
int type;
|
||||
GLrgba color;
|
||||
bool square;
|
||||
|
||||
//now we know how big the rectangle plot is.
|
||||
area = p.width * p.depth;
|
||||
color = WorldLightColor (RandomVal ());
|
||||
seed = RandomVal ();
|
||||
//Make sure the plot is big enough for a building
|
||||
if (p.width < 10 || p.depth < 10)
|
||||
return;
|
||||
//If the area is too big for one building, sub-divide it.
|
||||
if (area > 600) {
|
||||
if (p.width > p.depth) {
|
||||
p.width /= 2;
|
||||
if (COIN_FLIP)
|
||||
do_building (make_plot (p.x, p.z, p.width, p.depth));
|
||||
else
|
||||
do_building (make_plot (p.x + p.width, p.z, p.width, p.depth));
|
||||
return;
|
||||
} else {
|
||||
p.depth /= 2;
|
||||
if (COIN_FLIP)
|
||||
do_building (make_plot (p.x, p.z, p.width, p.depth));
|
||||
else
|
||||
do_building (make_plot (p.x, p.z + p.depth, p.width, p.depth));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (area < 100)
|
||||
return;
|
||||
//The plot is "square" if width & depth are close
|
||||
square = abs (p.width - p.depth) < 10;
|
||||
//mark the land as used so other buildings don't appear here, even if we don't use it all.
|
||||
claim (p.x, p.z, p.width, p.depth, CLAIM_BUILDING);
|
||||
//The roundy mod buildings look best on square plots.
|
||||
if (square && p.width > 20) {
|
||||
height = 45 + RandomVal (10);
|
||||
modern_count++;
|
||||
skyscrapers++;
|
||||
new CBuilding (BUILDING_MODERN, p.x, p.z, height, p.width, p.depth, seed, color);
|
||||
return;
|
||||
}
|
||||
//This spot isn't ideal for any particular building, but try to keep a good mix
|
||||
if (tower_count < modern_count && tower_count < blocky_count) {
|
||||
type = BUILDING_TOWER;
|
||||
tower_count++;
|
||||
} else if (blocky_count < modern_count) {
|
||||
type = BUILDING_BLOCKY;
|
||||
blocky_count++;
|
||||
} else {
|
||||
type = BUILDING_MODERN;
|
||||
modern_count++;
|
||||
}
|
||||
height = 45 + RandomVal (10);
|
||||
new CBuilding (type, p.x, p.z, height, p.width, p.depth, seed, color);
|
||||
skyscrapers++;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static int build_light_strip (int x1, int z1, int direction)
|
||||
{
|
||||
|
||||
CDeco* d;
|
||||
GLrgba color;
|
||||
int x2, z2;
|
||||
int length;
|
||||
int width, depth;
|
||||
int dir_x, dir_z;
|
||||
float size_adjust;
|
||||
|
||||
//We adjust the size of the lights with this.
|
||||
size_adjust = 2.5f;
|
||||
color = glRgbaFromHsl (0.09f, 0.99f, 0.85f);
|
||||
switch (direction) {
|
||||
case NORTH:
|
||||
dir_z = 1; dir_x = 0;break;
|
||||
case SOUTH:
|
||||
dir_z = 1; dir_x = 0;break;
|
||||
case EAST:
|
||||
dir_z = 0; dir_x = 1;break;
|
||||
case WEST:
|
||||
dir_z = 0; dir_x = 1;break;
|
||||
}
|
||||
//So we know we're on the corner of an intersection
|
||||
//look in the given until we reach the end of the sidewalk
|
||||
x2 = x1;
|
||||
z2 = z1;
|
||||
length = 0;
|
||||
while (x2 > 0 && x2 < WORLD_SIZE && z2 > 0 && z2 < WORLD_SIZE) {
|
||||
if ((world[x2][z2] & CLAIM_ROAD))
|
||||
break;
|
||||
length++;
|
||||
x2 += dir_x;
|
||||
z2 += dir_z;
|
||||
}
|
||||
if (length < 10)
|
||||
return length;
|
||||
width = MAX (abs(x2 - x1), 1);
|
||||
depth = MAX (abs(z2 - z1), 1);
|
||||
d = new CDeco;
|
||||
if (direction == EAST)
|
||||
d->CreateLightStrip ((float)x1, (float)z1 - size_adjust, (float)width, (float)depth + size_adjust, 2, color);
|
||||
else if (direction == WEST)
|
||||
d->CreateLightStrip ((float)x1, (float)z1, (float)width, (float)depth + size_adjust, 2, color);
|
||||
else if (direction == NORTH)
|
||||
d->CreateLightStrip ((float)x1, (float)z1, (float)width + size_adjust, (float)depth, 2, color);
|
||||
else
|
||||
d->CreateLightStrip ((float)x1 - size_adjust, (float)z1, (float)width + size_adjust, (float)depth, 2, color);
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
static void do_reset (void)
|
||||
{
|
||||
|
||||
int x, y;
|
||||
int width, depth, height;
|
||||
int attempts;
|
||||
bool broadway_done;
|
||||
bool road_left, road_right;
|
||||
GLrgba light_color;
|
||||
GLrgba building_color;
|
||||
float west_street, north_street, east_street, south_street;
|
||||
|
||||
//RandomInit (6);
|
||||
reset_needed = false;
|
||||
broadway_done = false;
|
||||
skyscrapers = 0;
|
||||
logo_index = 0;
|
||||
tower_count = blocky_count = modern_count = 0;
|
||||
hot_zone = glBboxClear ();
|
||||
EntityClear ();
|
||||
LightClear ();
|
||||
CarClear ();
|
||||
TextureReset ();
|
||||
//Pick a tint for the bloom
|
||||
bloom_color = get_light_color(0.5f + (float)RandomVal (10) / 20.0f, 0.75f);
|
||||
light_color = glRgbaFromHsl (0.11f, 1.0f, 0.65f);
|
||||
ZeroMemory (world, WORLD_SIZE * WORLD_SIZE);
|
||||
for (y = WORLD_EDGE; y < WORLD_SIZE - WORLD_EDGE; y += RandomVal (30) + 20) {
|
||||
if (!broadway_done && y > WORLD_HALF - 20) {
|
||||
build_road (0, y, WORLD_SIZE, 19);
|
||||
y += 20;
|
||||
broadway_done = true;
|
||||
} else {
|
||||
depth = 6 + RandomVal (6);
|
||||
if (y < WORLD_HALF / 2)
|
||||
north_street = (float)(y + depth / 2);
|
||||
if (y < (WORLD_SIZE - WORLD_HALF / 2))
|
||||
south_street = (float)(y + depth / 2);
|
||||
build_road (0, y, WORLD_SIZE, depth);
|
||||
}
|
||||
}
|
||||
|
||||
broadway_done = false;
|
||||
for (x = WORLD_EDGE; x < WORLD_SIZE - WORLD_EDGE; x += RandomVal (30) + 20) {
|
||||
if (!broadway_done && x > WORLD_HALF - 20) {
|
||||
build_road (x, 0, 19, WORLD_SIZE);
|
||||
x += 20;
|
||||
broadway_done = true;
|
||||
} else {
|
||||
width = 6 + RandomVal (6);
|
||||
if (x <= WORLD_HALF / 2)
|
||||
west_street = (float)(x + width / 2);
|
||||
if (x <= WORLD_HALF + WORLD_HALF / 2)
|
||||
east_street = (float)(x + width / 2);
|
||||
build_road (x, 0, width, WORLD_SIZE);
|
||||
}
|
||||
}
|
||||
//We kept track of the positions of streets that will outline the high-detail hot zone
|
||||
//in the middle of the world. Save this in a bounding box so that later we can
|
||||
//have the camera fly around without clipping through buildings.
|
||||
hot_zone = glBboxContainPoint (hot_zone, glVector (west_street, 0.0f, north_street));
|
||||
hot_zone = glBboxContainPoint (hot_zone, glVector (east_street, 0.0f, south_street));
|
||||
|
||||
//Scan for places to put runs of streetlights on the east & west side of the road
|
||||
for (x = 1; x < WORLD_SIZE - 1; x++) {
|
||||
for (y = 0; y < WORLD_SIZE; y++) {
|
||||
//if this isn't a bit of sidewalk, then keep looking
|
||||
if (!(world[x][y] & CLAIM_WALK))
|
||||
continue;
|
||||
//If it's used as a road, skip it.
|
||||
if ((world[x][y] & CLAIM_ROAD))
|
||||
continue;
|
||||
road_left = (world[x + 1][y] & CLAIM_ROAD) != 0;
|
||||
road_right = (world[x - 1][y] & CLAIM_ROAD) != 0;
|
||||
//if the cells to our east and west are not road, then we're not on a corner.
|
||||
if (!road_left && !road_right)
|
||||
continue;
|
||||
//if the cell to our east AND west is road, then we're on a median. skip it
|
||||
if (road_left && road_right)
|
||||
continue;
|
||||
y += build_light_strip (x, y, road_right ? SOUTH : NORTH);
|
||||
}
|
||||
}
|
||||
//Scan for places to put runs of streetlights on the north & south side of the road
|
||||
for (y = 1; y < WORLD_SIZE - 1; y++) {
|
||||
for (x = 1; x < WORLD_SIZE - 1; x++) {
|
||||
//if this isn't a bit of sidewalk, then keep looking
|
||||
if (!(world[x][y] & CLAIM_WALK))
|
||||
continue;
|
||||
//If it's used as a road, skip it.
|
||||
if ((world[x][y] & CLAIM_ROAD))
|
||||
continue;
|
||||
road_left = (world[x][y + 1] & CLAIM_ROAD) != 0;
|
||||
road_right = (world[x][y - 1] & CLAIM_ROAD) != 0;
|
||||
//if the cell to our east AND west is road, then we're on a median. skip it
|
||||
if (road_left && road_right)
|
||||
continue;
|
||||
//if the cells to our north and south are not road, then we're not on a corner.
|
||||
if (!road_left && !road_right)
|
||||
continue;
|
||||
x += build_light_strip (x, y, road_right ? EAST : WEST);
|
||||
}
|
||||
}
|
||||
|
||||
//Scan over the center area of the map and place the big buildings
|
||||
attempts = 0;
|
||||
while (skyscrapers < 50 && attempts < 350) {
|
||||
x = (WORLD_HALF / 2) + (RandomVal () % WORLD_HALF);
|
||||
y = (WORLD_HALF / 2) + (RandomVal () % WORLD_HALF);
|
||||
if (!claimed (x, y, 1,1)) {
|
||||
do_building (find_plot (x, y));
|
||||
skyscrapers++;
|
||||
}
|
||||
attempts++;
|
||||
}
|
||||
//now blanket the rest of the world with lesser buildings
|
||||
for (x = 0; x < WORLD_SIZE; x ++) {
|
||||
for (y = 0; y < WORLD_SIZE; y ++) {
|
||||
if (world[CLAMP (x,0,WORLD_SIZE)][CLAMP (y,0,WORLD_SIZE)])
|
||||
continue;
|
||||
width = 12 + RandomVal (20);
|
||||
depth = 12 + RandomVal (20);
|
||||
height = MIN (width, depth);
|
||||
if (x < 30 || y < 30 || x > WORLD_SIZE - 30 || y > WORLD_SIZE - 30)
|
||||
height = RandomVal (15) + 20;
|
||||
else if (x < WORLD_HALF / 2)
|
||||
height /= 2;
|
||||
while (width > 8 && depth > 8) {
|
||||
if (!claimed (x, y, width, depth)) {
|
||||
claim (x, y, width, depth,CLAIM_BUILDING);
|
||||
building_color = WorldLightColor (RandomVal ());
|
||||
//if we're out of the hot zone, use simple buildings
|
||||
if (x < hot_zone.min.x || x > hot_zone.max.x || y < hot_zone.min.z || y > hot_zone.max.z) {
|
||||
height = 5 + RandomVal (height) + RandomVal (height);
|
||||
new CBuilding (BUILDING_SIMPLE, x + 1, y + 1, height, width - 2, depth - 2, RandomVal (), building_color);
|
||||
} else { //use fancy buildings.
|
||||
height = 15 + RandomVal (15);
|
||||
width -=2;
|
||||
depth -=2;
|
||||
if (COIN_FLIP)
|
||||
new CBuilding (BUILDING_TOWER, x + 1, y + 1, height, width, depth, RandomVal (), building_color);
|
||||
else
|
||||
new CBuilding (BUILDING_BLOCKY, x + 1, y + 1, height, width, depth, RandomVal (), building_color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
width--;
|
||||
depth--;
|
||||
}
|
||||
//leave big gaps near the edge of the map, no need to pack detail there.
|
||||
if (y < WORLD_EDGE || y > WORLD_SIZE - WORLD_EDGE)
|
||||
y += 32;
|
||||
}
|
||||
//leave big gaps near the edge of the map
|
||||
if (x < WORLD_EDGE || x > WORLD_SIZE - WORLD_EDGE)
|
||||
x += 28;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
This will return a random color which is suitible for light sources, taken
|
||||
from a narrow group of hues. (Yellows, oranges, blues.)
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba WorldLightColor (unsigned index)
|
||||
{
|
||||
|
||||
index %= LIGHT_COLOR_COUNT;
|
||||
return glRgbaFromHsl (light_colors[index].hue, light_colors[index].sat, light_colors[index].lum);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
char WorldCell (int x, int y)
|
||||
{
|
||||
|
||||
return world[CLAMP (x, 0,WORLD_SIZE - 1)][CLAMP (y, 0, WORLD_SIZE - 1)];
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba WorldBloomColor ()
|
||||
{
|
||||
|
||||
return bloom_color;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
int WorldLogoIndex ()
|
||||
{
|
||||
|
||||
return logo_index++;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLbbox WorldHotZone ()
|
||||
{
|
||||
|
||||
return hot_zone;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WorldTerm (void)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WorldReset (void)
|
||||
{
|
||||
|
||||
//If we're already fading out, then this is the developer hammering on the
|
||||
//"rebuild" button. Let's hurry things up for the nice man...
|
||||
if (fade_state == FADE_OUT)
|
||||
do_reset ();
|
||||
//If reset is called but the world isn't ready, then don't bother fading out.
|
||||
//The program probably just started.
|
||||
fade_state = FADE_OUT;
|
||||
fade_start = GetTickCount ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WorldRender ()
|
||||
{
|
||||
|
||||
//Cheap - render the crappy one-texture streets
|
||||
if (!SHOW_DEBUG_GROUND)
|
||||
return;
|
||||
glDepthMask (false);
|
||||
glDisable (GL_CULL_FACE);
|
||||
glDisable (GL_BLEND);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glColor3f (1,1,1);
|
||||
glBindTexture (GL_TEXTURE_2D, TextureId (TEXTURE_GROUND));
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0, 0); glVertex3f ( 0., 0, 0);
|
||||
glTexCoord2f (0, 1); glVertex3f ( 0, 0, 1024);
|
||||
glTexCoord2f (1, 1); glVertex3f ( 1024, 0, 1024);
|
||||
glTexCoord2f (1, 0); glVertex3f ( 1024, 0, 0);
|
||||
glEnd ();
|
||||
glDepthMask (true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float WorldFade (void)
|
||||
{
|
||||
|
||||
return fade_current;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WorldUpdate (void)
|
||||
{
|
||||
|
||||
unsigned fade_delta;
|
||||
unsigned now, elapsed;
|
||||
|
||||
now = GetTickCount ();
|
||||
if (reset_needed) {
|
||||
do_reset (); //Now we've faded out the scene, rebuild it
|
||||
}
|
||||
if (fade_state != FADE_IDLE) {
|
||||
if (fade_state == FADE_WAIT && TextureReady () && EntityReady ()) {
|
||||
fade_state = FADE_IN;
|
||||
fade_start = now;
|
||||
fade_current = 1.0f;
|
||||
}
|
||||
fade_delta = now - fade_start;
|
||||
//See if we're done fading in or out
|
||||
if (fade_delta > FADE_TIME && fade_state != FADE_WAIT) {
|
||||
if (fade_state == FADE_OUT) {
|
||||
reset_needed = true;
|
||||
fade_state = FADE_WAIT;
|
||||
fade_current = 1.0f;
|
||||
} else {
|
||||
fade_state = FADE_IDLE;
|
||||
fade_current = 0.0f;
|
||||
start_time = time (NULL);
|
||||
}
|
||||
} else {
|
||||
fade_current = (float)fade_delta / FADE_TIME;
|
||||
if (fade_state == FADE_IN)
|
||||
fade_current = 1.0f - fade_current;
|
||||
if (fade_state == FADE_WAIT)
|
||||
fade_current = 1.0f;
|
||||
}
|
||||
if (!TextureReady ())
|
||||
fade_current = 1.0f;
|
||||
}
|
||||
if (fade_state == FADE_IDLE && !TextureReady ()) {
|
||||
fade_state = FADE_IN;
|
||||
fade_start = now;
|
||||
}
|
||||
elapsed = time (NULL) - start_time;
|
||||
if (fade_state == FADE_IDLE && elapsed > RESET_INTERVAL)
|
||||
WorldReset ();
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void WorldInit (void)
|
||||
{
|
||||
|
||||
last_update = GetTickCount ();
|
||||
for (int i = 0; i < CARS; i++)
|
||||
new CCar ();
|
||||
sky = new CSky ();
|
||||
WorldReset ();
|
||||
fade_state = FADE_OUT;
|
||||
fade_start = 0;
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#define SHOW_DEBUG_GROUND 0
|
||||
|
||||
#define WORLD_SIZE 1024
|
||||
#define WORLD_HALF (WORLD_SIZE / 2)
|
||||
|
||||
#define CLAIM_ROAD 1
|
||||
#define CLAIM_WALK 2
|
||||
#define CLAIM_BUILDING 4
|
||||
#define MAP_ROAD_NORTH 8
|
||||
#define MAP_ROAD_SOUTH 16
|
||||
#define MAP_ROAD_EAST 32
|
||||
#define MAP_ROAD_WEST 64
|
||||
#define RANDOM_COLOR (glRgbaFromHsl ((float)RandomVal (255)/255,1.0f, 0.75f))
|
||||
|
||||
enum
|
||||
{
|
||||
NORTH,
|
||||
EAST,
|
||||
SOUTH,
|
||||
WEST
|
||||
};
|
||||
|
||||
GLrgba WorldBloomColor ();
|
||||
char WorldCell (int x, int y);
|
||||
GLrgba WorldLightColor (unsigned index);
|
||||
int WorldLogoIndex ();
|
||||
GLbbox WorldHotZone ();
|
||||
void WorldInit (void);
|
||||
float WorldFade (void);
|
||||
void WorldRender ();
|
||||
void WorldReset (void);
|
||||
void WorldTerm (void);
|
||||
void WorldUpdate (void);
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
i
|
||||
Green
|
||||
Mega
|
||||
Super
|
||||
Omni
|
||||
e
|
||||
Hyper
|
||||
Global
|
||||
Vital
|
||||
Next
|
||||
Pacific
|
||||
Metro
|
||||
Unity
|
||||
G-
|
||||
Trans
|
||||
Infinity
|
||||
Superior
|
||||
Monolith
|
||||
Best
|
||||
Atlantic
|
||||
First
|
||||
Union
|
||||
National
|
||||
|
||||
|
||||
Biotic
|
||||
Info
|
||||
Data
|
||||
Solar
|
||||
Aerospace
|
||||
Motors
|
||||
Nano
|
||||
Online
|
||||
Circuits
|
||||
Energy
|
||||
Med
|
||||
Robotic
|
||||
Exports
|
||||
Security
|
||||
Systems
|
||||
Financial
|
||||
Industrial
|
||||
Media
|
||||
Materials
|
||||
Foods
|
||||
Networks
|
||||
Shipping
|
||||
Tools
|
||||
Medical
|
||||
Publishing
|
||||
Enterpise
|
||||
Audio
|
||||
Health
|
||||
Bank
|
||||
Imports
|
||||
Apparel
|
||||
Petroleum
|
||||
Studios
|
||||
|
||||
|
||||
Corp
|
||||
Inc.
|
||||
Co
|
||||
World
|
||||
.Com
|
||||
USA
|
||||
Ltd.
|
||||
Net
|
||||
Tech
|
||||
Labs
|
||||
Mfg.
|
||||
UK
|
||||
Unlimited
|
||||
One
|
|
@ -0,0 +1,70 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
glBbox.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This module has a few functions useful for manipulating the bounding-box
|
||||
structs.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MAX_VALUE 999999999999999.9f
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "glTypes.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Does the given point fall within the given Bbox?
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
bool glBboxTestPoint (GLbbox box, GLvector point)
|
||||
{
|
||||
|
||||
if (point.x > box.max.x || point.x < box.min.x)
|
||||
return false;
|
||||
if (point.y > box.max.y || point.y < box.min.y)
|
||||
return false;
|
||||
if (point.z > box.max.z || point.z < box.min.z)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Expand Bbox (if needed) to contain given point
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLbbox glBboxContainPoint (GLbbox box, GLvector point)
|
||||
{
|
||||
|
||||
box.min.x = MIN (box.min.x, point.x);
|
||||
box.min.y = MIN (box.min.y, point.y);
|
||||
box.min.z = MIN (box.min.z, point.z);
|
||||
box.max.x = MAX (box.max.x, point.x);
|
||||
box.max.y = MAX (box.max.y, point.y);
|
||||
box.max.z = MAX (box.max.z, point.z);
|
||||
return box;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
This will invalidate the bbox.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLbbox glBboxClear (void)
|
||||
{
|
||||
|
||||
GLbbox result;
|
||||
|
||||
result.max = glVector (-MAX_VALUE, -MAX_VALUE, -MAX_VALUE);
|
||||
result.min = glVector ( MAX_VALUE, MAX_VALUE, MAX_VALUE);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
glMatrix.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Functions useful for manipulating the Matrix struct
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define M(e,x,y) (e.elements[x][y])
|
||||
|
||||
/*** Order type constants, constructors, extractors ***/
|
||||
|
||||
/* There are 24 possible conventions, designated by: */
|
||||
/* o EulAxI = axis used initially */
|
||||
/* o EulPar = parity of axis permutation */
|
||||
/* o EulRep = repetition of initial axis as last */
|
||||
/* o EulFrm = frame from which axes are taken */
|
||||
/* Axes I,J,K will be a permutation of X,Y,Z. */
|
||||
/* Axis H will be either I or K, depending on EulRep. */
|
||||
/* Frame S takes axes from initial static frame. */
|
||||
/* If ord = (AxI=X, Par=Even, Rep=No, Frm=S), then */
|
||||
/* {a,b,c,ord} means Rz(c)Ry(b)Rx(a), where Rz(c)v */
|
||||
/* rotates v around Z by c radians. */
|
||||
|
||||
#define EulFrmS 0
|
||||
#define EulFrmR 1
|
||||
#define EulFrm(ord) ((unsigned)(ord)&1)
|
||||
#define EulRepNo 0
|
||||
#define EulRepYes 1
|
||||
#define EulRep(ord) (((unsigned)(ord)>>1)&1)
|
||||
#define EulParEven 0
|
||||
#define EulParOdd 1
|
||||
#define EulPar(ord) (((unsigned)(ord)>>2)&1)
|
||||
#define EulSafe "\000\001\002\000"
|
||||
#define EulNext "\001\002\000\001"
|
||||
#define EulAxI(ord) ((int)(EulSafe[(((unsigned)(ord)>>3)&3)]))
|
||||
#define EulAxJ(ord) ((int)(EulNext[EulAxI(ord)+(EulPar(ord)==EulParOdd)]))
|
||||
#define EulAxK(ord) ((int)(EulNext[EulAxI(ord)+(EulPar(ord)!=EulParOdd)]))
|
||||
#define EulAxH(ord) ((EulRep(ord)==EulRepNo)?EulAxK(ord):EulAxI(ord))
|
||||
/* EulGetOrd unpacks all useful information about order simultaneously. */
|
||||
#define EulGetOrd(ord,i,j,k,h,n,s,f) {unsigned o=ord;f=o&1;o>>=1;s=o&1;o>>=1;\
|
||||
n=o&1;o>>=1;i=EulSafe[o&3];j=EulNext[i+n];k=EulNext[i+1-n];h=s?k:i;}
|
||||
/* EulOrd creates an order value between 0 and 23 from 4-tuple choices. */
|
||||
#define EulOrd(i,p,r,f) (((((((i)<<1)+(p))<<1)+(r))<<1)+(f))
|
||||
/* Static axes */
|
||||
#define EulOrdXYZs EulOrd(X,EulParEven,EulRepNo,EulFrmS)
|
||||
#define EulOrdXYXs EulOrd(X,EulParEven,EulRepYes,EulFrmS)
|
||||
#define EulOrdXZYs EulOrd(X,EulParOdd,EulRepNo,EulFrmS)
|
||||
#define EulOrdXZXs EulOrd(X,EulParOdd,EulRepYes,EulFrmS)
|
||||
#define EulOrdYZXs EulOrd(Y,EulParEven,EulRepNo,EulFrmS)
|
||||
#define EulOrdYZYs EulOrd(Y,EulParEven,EulRepYes,EulFrmS)
|
||||
#define EulOrdYXZs EulOrd(Y,EulParOdd,EulRepNo,EulFrmS)
|
||||
#define EulOrdYXYs EulOrd(Y,EulParOdd,EulRepYes,EulFrmS)
|
||||
#define EulOrdZXYs EulOrd(Z,EulParEven,EulRepNo,EulFrmS)
|
||||
#define EulOrdZXZs EulOrd(Z,EulParEven,EulRepYes,EulFrmS)
|
||||
#define EulOrdZYXs EulOrd(Z,EulParOdd,EulRepNo,EulFrmS)
|
||||
#define EulOrdZYZs EulOrd(Z,EulParOdd,EulRepYes,EulFrmS)
|
||||
/* Rotating axes */
|
||||
#define EulOrdZYXr EulOrd(X,EulParEven,EulRepNo,EulFrmR)
|
||||
#define EulOrdXYXr EulOrd(X,EulParEven,EulRepYes,EulFrmR)
|
||||
#define EulOrdYZXr EulOrd(X,EulParOdd,EulRepNo,EulFrmR)
|
||||
#define EulOrdXZXr EulOrd(X,EulParOdd,EulRepYes,EulFrmR)
|
||||
#define EulOrdXZYr EulOrd(Y,EulParEven,EulRepNo,EulFrmR)
|
||||
#define EulOrdYZYr EulOrd(Y,EulParEven,EulRepYes,EulFrmR)
|
||||
#define EulOrdZXYr EulOrd(Y,EulParOdd,EulRepNo,EulFrmR)
|
||||
#define EulOrdYXYr EulOrd(Y,EulParOdd,EulRepYes,EulFrmR)
|
||||
#define EulOrdYXZr EulOrd(Z,EulParEven,EulRepNo,EulFrmR)
|
||||
#define EulOrdZXZr EulOrd(Z,EulParEven,EulRepYes,EulFrmR)
|
||||
#define EulOrdXYZr EulOrd(Z,EulParOdd,EulRepNo,EulFrmR)
|
||||
#define EulOrdZYZr EulOrd(Z,EulParOdd,EulRepYes,EulFrmR)
|
||||
|
||||
//EulerAngles Eul_(float ai, float aj, float ah, int order);
|
||||
//Quat Eul_ToQuat(EulerAngles ea);
|
||||
//void Eul_ToHMatrix(EulerAngles ea, HMatrix M);
|
||||
//EulerAngles Eul_FromHMatrix(HMatrix M, int order);
|
||||
//EulerAngles Eul_FromQuat(Quat q, int order);
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "glTypes.h"
|
||||
|
||||
static float identity[4][4] =
|
||||
{
|
||||
{1.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 1.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void* glMatrixCreate (void)
|
||||
{
|
||||
|
||||
GLmatrix* m;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
m = new GLmatrix;
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 4; y++) {
|
||||
m -> elements[x][y] = identity[x][y];
|
||||
}
|
||||
}
|
||||
return (void*)m;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLmatrix glMatrixIdentity (void)
|
||||
{
|
||||
|
||||
GLmatrix m;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 4; y++) {
|
||||
M(m, x, y) = identity[x][y];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
void glMatrixElementsSet (GLmatrix* m, float* in)
|
||||
{
|
||||
|
||||
m -> elements[0][0] = in[0];
|
||||
m -> elements[0][1] = in[1];
|
||||
m -> elements[0][2] = in[2];
|
||||
m -> elements[0][3] = in[3];
|
||||
|
||||
m -> elements[1][0] = in[4];
|
||||
m -> elements[1][1] = in[5];
|
||||
m -> elements[1][2] = in[6];
|
||||
m -> elements[1][3] = in[7];
|
||||
|
||||
m -> elements[2][0] = in[8];
|
||||
m -> elements[2][1] = in[9];
|
||||
m -> elements[2][2] = in[10];
|
||||
m -> elements[2][3] = in[11];
|
||||
|
||||
m -> elements[3][0] = in[12];
|
||||
m -> elements[3][1] = in[13];
|
||||
m -> elements[3][2] = in[14];
|
||||
m -> elements[3][3] = in[15];
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
A matrix multiplication (dot product) of two 4x4 matrices.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
GLmatrix glMatrixMultiply (GLmatrix a, GLmatrix b)
|
||||
{
|
||||
|
||||
GLmatrix result;
|
||||
|
||||
M(result, 0,0) = M(a, 0,0) * M(b, 0, 0) + M(a, 1,0) * M(b, 0, 1) + M(a, 2,0) * M(b, 0, 2);
|
||||
M(result, 1,0) = M(a, 0,0) * M(b, 1, 0) + M(a, 1,0) * M(b, 1, 1) + M(a, 2,0) * M(b, 1, 2);
|
||||
M(result, 2,0) = M(a, 0,0) * M(b, 2, 0) + M(a, 1,0) * M(b, 2, 1) + M(a, 2,0) * M(b, 2, 2);
|
||||
M(result, 3,0) = M(a, 0,0) * M(b, 3, 0) + M(a, 1,0) * M(b, 3, 1) + M(a, 2,0) * M(b, 3, 2) + M(a, 3,0);
|
||||
|
||||
M(result, 0,1) = M(a, 0,1) * M(b, 0, 0) + M(a, 1,1) * M(b, 0, 1) + M(a, 2,1) * M(b, 0, 2);
|
||||
M(result, 1,1) = M(a, 0,1) * M(b, 1, 0) + M(a, 1,1) * M(b, 1, 1) + M(a, 2,1) * M(b, 1, 2);
|
||||
M(result, 2,1) = M(a, 0,1) * M(b, 2, 0) + M(a, 1,1) * M(b, 2, 1) + M(a, 2,1) * M(b, 2, 2);
|
||||
M(result, 3,1) = M(a, 0,1) * M(b, 3, 0) + M(a, 1,1) * M(b, 3, 1) + M(a, 2,1) * M(b, 3, 2) + M(a, 3,1);
|
||||
|
||||
M(result, 0,2) = M(a, 0,2) * M(b, 0, 0) + M(a, 1,2) * M(b, 0, 1) + M(a, 2,2) * M(b, 0, 2);
|
||||
M(result, 1,2) = M(a, 0,2) * M(b, 1, 0) + M(a, 1,2) * M(b, 1, 1) + M(a, 2,2) * M(b, 1, 2);
|
||||
M(result, 2,2) = M(a, 0,2) * M(b, 2, 0) + M(a, 1,2) * M(b, 2, 1) + M(a, 2,2) * M(b, 2, 2);
|
||||
M(result, 3,2) = M(a, 0,2) * M(b, 3, 0) + M(a, 1,2) * M(b, 3, 1) + M(a, 2,2) * M(b, 3, 2) + M(a, 3,2);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector glMatrixTransformPoint (GLmatrix m, GLvector in)
|
||||
{
|
||||
|
||||
GLvector out;
|
||||
|
||||
out.x = M(m,0,0) * in.x + M(m,1,0) * in.y + M(m,2,0) * in.z + M(m,3,0);
|
||||
out.y = M(m,0,1) * in.x + M(m,1,1) * in.y + M(m,2,1) * in.z + M(m,3,1);
|
||||
out.z = M(m,0,2) * in.x + M(m,1,2) * in.y + M(m,2,2) * in.z + M(m,3,2);
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLmatrix glMatrixTranslate (GLmatrix m, GLvector in)
|
||||
{
|
||||
|
||||
GLvector old;
|
||||
|
||||
old.x = M(m,3,0);
|
||||
old.y = M(m,3,1);
|
||||
old.z = M(m,3,2);
|
||||
M(m, 3, 0) = 0.0f;
|
||||
M(m, 3, 1) = 0.0f;
|
||||
M(m, 3, 2) = 0.0f;
|
||||
in = glMatrixTransformPoint (m, in);
|
||||
M(m, 3, 0) = old.x;
|
||||
M(m, 3, 1) = old.y;
|
||||
M(m, 3, 2) = old.z;
|
||||
M(m,3,0) += in.x;
|
||||
M(m,3,1) += in.y;
|
||||
M(m,3,2) += in.z;
|
||||
return m;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLmatrix glMatrixRotate (GLmatrix m, float theta, float x, float y, float z)
|
||||
{
|
||||
|
||||
GLmatrix r;
|
||||
float length;
|
||||
float s, c, t;
|
||||
GLvector in;
|
||||
|
||||
theta *= DEGREES_TO_RADIANS;
|
||||
r = glMatrixIdentity ();
|
||||
length = (float)sqrt (x * x + y * y + z * z);
|
||||
if (length < 0.00001f)
|
||||
return m;
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
s = (float)sin (theta);
|
||||
c = (float)cos (theta);
|
||||
t = 1.0f - c;
|
||||
|
||||
in.x = in.y = in.z = 1.0f;
|
||||
M(r, 0,0) = t*x*x + c;
|
||||
M(r, 1,0) = t*x*y - s*z;
|
||||
M(r, 2,0) = t*x*z + s*y;
|
||||
M(r, 3,0) = 0;
|
||||
|
||||
M(r, 0,1) = t*x*y + s*z;
|
||||
M(r, 1,1) = t*y*y + c;
|
||||
M(r, 2,1) = t*y*z - s*x;
|
||||
M(r, 3,1) = 0;
|
||||
|
||||
M(r, 0,2) = t*x*z - s*y;
|
||||
M(r, 1,2) = t*y*z + s*x;
|
||||
M(r, 2,2) = t*z*z + c;
|
||||
M(r, 3,2) = 0;
|
||||
|
||||
m = glMatrixMultiply (m, r);
|
||||
return m;
|
||||
|
||||
}
|
||||
|
||||
/* Convert matrix to Euler angles (in radians). */
|
||||
GLvector glMatrixToEuler (GLmatrix mat, int order)
|
||||
{
|
||||
GLvector ea;
|
||||
int i,j,k,h,n,s,f;
|
||||
|
||||
EulGetOrd (order,i,j,k,h,n,s,f);
|
||||
if (s==EulRepYes) {
|
||||
float sy = (float)sqrt(mat.elements[i][j]*mat.elements[i][j] + mat.elements[i][k]*mat.elements[i][k]);
|
||||
if (sy > 16 * FLT_EPSILON) {
|
||||
ea.x = (float)atan2(mat.elements[i][j], mat.elements[i][k]);
|
||||
ea.y = (float)atan2(sy, mat.elements[i][i]);
|
||||
ea.z = (float)atan2(mat.elements[j][i], -mat.elements[k][i]);
|
||||
} else {
|
||||
ea.x = (float)atan2(-mat.elements[j][k], mat.elements[j][j]);
|
||||
ea.y = (float)atan2(sy, mat.elements[i][i]);
|
||||
ea.z = 0;
|
||||
}
|
||||
} else {
|
||||
float cy = (float)sqrt(mat.elements[i][i]*mat.elements[i][i] + mat.elements[j][i]*mat.elements[j][i]);
|
||||
if (cy > 16*FLT_EPSILON) {
|
||||
ea.x = (float)atan2(mat.elements[k][j], mat.elements[k][k]);
|
||||
ea.y = (float)atan2(-mat.elements[k][i], cy);
|
||||
ea.z = (float)atan2(mat.elements[j][i], mat.elements[i][i]);
|
||||
} else {
|
||||
ea.x = (float)atan2(-mat.elements[j][k], mat.elements[j][j]);
|
||||
ea.y = (float)atan2(-mat.elements[k][i], cy);
|
||||
ea.z = 0;
|
||||
}
|
||||
}
|
||||
if (n==EulParOdd) {
|
||||
ea.x = -ea.x;
|
||||
ea.y = - ea.y;
|
||||
ea.z = -ea.z;
|
||||
}
|
||||
if (f==EulFrmR) {
|
||||
float t = ea.x;
|
||||
ea.x = ea.z;
|
||||
ea.z = t;
|
||||
}
|
||||
//ea.w = order;
|
||||
return (ea);
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
glQuat.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Functions for dealing with Quaternions
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
|
||||
#include "math.h"
|
||||
#include "glTypes.h"
|
||||
|
||||
enum QuatPart {X, Y, Z, W};
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLquat glQuat (float x, float y, float z, float w)
|
||||
{
|
||||
|
||||
GLquat result;
|
||||
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.z = z;
|
||||
result.w = w;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Convert quaternion to Euler angles (in radians). */
|
||||
/*
|
||||
EulerAngles Eul_FromQuat(Quat q, int order)
|
||||
{
|
||||
HMatrix M;
|
||||
double Nq = q.x*q.x+q.y*q.y+q.z*q.z+q.w*q.w;
|
||||
double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
|
||||
double xs = q.x*s, ys = q.y*s, zs = q.z*s;
|
||||
double wx = q.w*xs, wy = q.w*ys, wz = q.w*zs;
|
||||
double xx = q.x*xs, xy = q.x*ys, xz = q.x*zs;
|
||||
double yy = q.y*ys, yz = q.y*zs, zz = q.z*zs;
|
||||
M[X][X] = 1.0 - (yy + zz); M[X][Y] = xy - wz; M[X][Z] = xz + wy;
|
||||
M[Y][X] = xy + wz; M[Y][Y] = 1.0 - (xx + zz); M[Y][Z] = yz - wx;
|
||||
M[Z][X] = xz - wy; M[Z][Y] = yz + wx; M[Z][Z] = 1.0 - (xx + yy);
|
||||
M[W][X]=M[W][Y]=M[W][Z]=M[X][W]=M[Y][W]=M[Z][W]=0.0; M[W][W]=1.0;
|
||||
return (Eul_FromHMatrix(M, order));
|
||||
}
|
||||
*/
|
||||
|
||||
GLvector glQuatToEuler (GLquat q, int order)
|
||||
{
|
||||
GLmatrix M;
|
||||
|
||||
float Nq = q.x*q.x+q.y*q.y+q.z*q.z+q.w*q.w;
|
||||
float s = (Nq > 0.0f) ? (2.0f / Nq) : 0.0f;
|
||||
float xs = q.x*s, ys = q.y*s, zs = q.z*s;
|
||||
float wx = q.w*xs, wy = q.w*ys, wz = q.w*zs;
|
||||
float xx = q.x*xs, xy = q.x*ys, xz = q.x*zs;
|
||||
float yy = q.y*ys, yz = q.y*zs, zz = q.z*zs;
|
||||
M.elements[X][X] = 1.0f - (yy + zz); M.elements[X][Y] = xy - wz; M.elements[X][Z] = xz + wy;
|
||||
M.elements[Y][X] = xy + wz; M.elements[Y][Y] = 1.0f - (xx + zz); M.elements[Y][Z] = yz - wx;
|
||||
M.elements[Z][X] = xz - wy; M.elements[Z][Y] = yz + wx; M.elements[Z][Z] = 1.0f - (xx + yy);
|
||||
M.elements[W][X] = M.elements[W][Y] =
|
||||
M.elements[W][Z] = M.elements[X][W] =
|
||||
M.elements[Y][W] = M.elements[Z][W] = 0.0f;
|
||||
M.elements[W][W] = 1.0f;
|
||||
return (glMatrixToEuler(M, order));
|
||||
}
|
|
@ -0,0 +1,401 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
glRgba.cpp
|
||||
|
||||
2009 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Functions for dealing with RGBA color values.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <gl\gl.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "math.h"
|
||||
#include "glTypes.h"
|
||||
#include "macro.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaFromHsl (float h, float sl, float l)
|
||||
{
|
||||
|
||||
float v;
|
||||
float r,g,b;
|
||||
|
||||
|
||||
r = l; // default to gray
|
||||
g = l;
|
||||
b = l;
|
||||
v = (l <= 0.5f) ? (l * (1.0f + sl)) : (l + sl - l * sl);
|
||||
if (v > 0) {
|
||||
float m;
|
||||
float sv;
|
||||
int sextant;
|
||||
float fract, vsf, mid1, mid2;
|
||||
|
||||
m = l + l - v;
|
||||
sv = (v - m ) / v;
|
||||
h *= 6.0f;
|
||||
sextant = (int)h;
|
||||
fract = h - sextant;
|
||||
vsf = v * sv * fract;
|
||||
mid1 = m + vsf;
|
||||
mid2 = v - vsf;
|
||||
switch (sextant) {
|
||||
case 0:
|
||||
r = v; g = mid1; b = m;
|
||||
break;
|
||||
case 1:
|
||||
r = mid2; g = v; b = m;
|
||||
break;
|
||||
case 2:
|
||||
r = m; g = v; b = mid1;
|
||||
break;
|
||||
case 3:
|
||||
r = m; g = mid2; b = v;
|
||||
break;
|
||||
case 4:
|
||||
r = mid1; g = m; b = v;
|
||||
break;
|
||||
case 5:
|
||||
r = v; g = m; b = mid2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return glRgba (r, g, b);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaInterpolate (GLrgba c1, GLrgba c2, float delta)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = MathInterpolate (c1.red, c2.red, delta);
|
||||
result.green = MathInterpolate (c1.green, c2.green, delta);
|
||||
result.blue = MathInterpolate (c1.blue, c2.blue, delta);
|
||||
result.alpha = MathInterpolate (c1.alpha, c2.alpha, delta);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaAdd (GLrgba c1, GLrgba c2)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = c1.red + c2.red;
|
||||
result.green = c1.green + c2.green;
|
||||
result.blue = c1.blue + c2.blue;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaSubtract (GLrgba c1, GLrgba c2)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = c1.red - c2.red;
|
||||
result.green = c1.green - c2.green;
|
||||
result.blue = c1.blue - c2.blue;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaMultiply (GLrgba c1, GLrgba c2)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = c1.red * c2.red;
|
||||
result.green = c1.green * c2.green;
|
||||
result.blue = c1.blue * c2.blue;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaScale (GLrgba c, float scale)
|
||||
{
|
||||
|
||||
c.red *= scale;
|
||||
c.green *= scale;
|
||||
c.blue *= scale;
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (char* string)
|
||||
{
|
||||
|
||||
long color;
|
||||
char buffer[10];
|
||||
char* pound;
|
||||
GLrgba result;
|
||||
|
||||
strncmp (buffer, string, 10);
|
||||
if (pound = strchr (buffer, '#'))
|
||||
pound[0] = ' ';
|
||||
if (sscanf (string, "%x", &color) != 1)
|
||||
return glRgba (0.0f);
|
||||
result.red = (float)GetBValue (color) / 255.0f;
|
||||
result.green = (float)GetGValue (color) / 255.0f;
|
||||
result.blue = (float)GetRValue (color) / 255.0f;
|
||||
result.alpha = 1.0f;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (int red, int green, int blue)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = (float)red / 255.0f;
|
||||
result.green = (float)green / 255.0f;
|
||||
result.blue = (float)blue / 255.0f;
|
||||
result.alpha = 1.0f;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (float red, float green, float blue)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = red;
|
||||
result.green = green;
|
||||
result.blue = blue;
|
||||
result.alpha = 1.0f;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (float red, float green, float blue, float alpha)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = red;
|
||||
result.green = green;
|
||||
result.blue = blue;
|
||||
result.alpha = alpha;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (long c)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = (float)GetRValue (c) / 255.0f;
|
||||
result.green = (float)GetGValue (c) / 255.0f;
|
||||
result.blue = (float)GetBValue (c) / 255.0f;
|
||||
result.alpha = 1.0f;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgba (float luminance)
|
||||
{
|
||||
|
||||
GLrgba result;
|
||||
|
||||
result.red = luminance;
|
||||
result.green = luminance;
|
||||
result.blue = luminance;
|
||||
result.alpha = 1.0f;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Takes the given index and returns a "random" color unique for that index.
|
||||
512 Unique values: #0 and #512 will be the same, as will #1 and #513, etc
|
||||
Useful for visual debugging in some situations.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba glRgbaUnique (int i)
|
||||
{
|
||||
|
||||
GLrgba c;
|
||||
|
||||
c.alpha = 1.0f;
|
||||
c.red = 0.4f + ((i & 1) ? 0.2f : 0.0f) + ((i & 8) ? 0.3f : 0.0f) - ((i & 64) ? 0.3f : 0.0f);
|
||||
c.green = 0.4f + ((i & 2) ? 0.2f : 0.0f) + ((i & 32) ? 0.3f : 0.0f) - ((i & 128) ? 0.3f : 0.0f);
|
||||
c.blue = 0.4f + ((i & 4) ? 0.2f : 0.0f) + ((i & 16) ? 0.3f : 0.0f) - ((i & 256) ? 0.3f : 0.0f);
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
+ operator
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba GLrgba::operator+ (const GLrgba& c)
|
||||
{
|
||||
return glRgba (red + c.red, green + c.green, blue + c.blue, alpha);
|
||||
}
|
||||
|
||||
GLrgba GLrgba::operator+ (const float& c)
|
||||
{
|
||||
return glRgba (red + c, green + c, blue + c, alpha);
|
||||
}
|
||||
|
||||
void GLrgba::operator+= (const GLrgba& c)
|
||||
{
|
||||
red += c.red;
|
||||
green += c.green;
|
||||
blue += c.blue;
|
||||
}
|
||||
|
||||
void GLrgba::operator+= (const float& c)
|
||||
{
|
||||
red += c;
|
||||
green += c;
|
||||
blue += c;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
- operator
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba GLrgba::operator- (const GLrgba& c)
|
||||
{
|
||||
return glRgba (red - c.red, green - c.green, blue - c.blue);
|
||||
}
|
||||
|
||||
GLrgba GLrgba::operator- (const float& c)
|
||||
{
|
||||
return glRgba (red - c, green - c, blue - c, alpha);
|
||||
}
|
||||
|
||||
void GLrgba::operator-= (const GLrgba& c)
|
||||
{
|
||||
red -= c.red;
|
||||
green -= c.green;
|
||||
blue -= c.blue;
|
||||
}
|
||||
|
||||
void GLrgba::operator-= (const float& c)
|
||||
{
|
||||
red -= c;
|
||||
green -= c;
|
||||
blue -= c;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* operator
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba GLrgba::operator* (const GLrgba& c)
|
||||
{
|
||||
return glRgba (red * c.red, green * c.green, blue * c.blue);
|
||||
}
|
||||
|
||||
GLrgba GLrgba::operator* (const float& c)
|
||||
{
|
||||
return glRgba (red * c, green * c, blue * c, alpha);
|
||||
}
|
||||
|
||||
void GLrgba::operator*= (const GLrgba& c)
|
||||
{
|
||||
red *= c.red;
|
||||
green *= c.green;
|
||||
blue *= c.blue;
|
||||
}
|
||||
|
||||
void GLrgba::operator*= (const float& c)
|
||||
{
|
||||
red *= c;
|
||||
green *= c;
|
||||
blue *= c;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
/ operator
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLrgba GLrgba::operator/ (const GLrgba& c)
|
||||
{
|
||||
return glRgba (red / c.red, green / c.green, blue / c.blue);
|
||||
}
|
||||
|
||||
GLrgba GLrgba::operator/ (const float& c)
|
||||
{
|
||||
return glRgba (red / c, green / c, blue / c, alpha);
|
||||
}
|
||||
|
||||
void GLrgba::operator/= (const GLrgba& c)
|
||||
{
|
||||
red /= c.red;
|
||||
green /= c.green;
|
||||
blue /= c.blue;
|
||||
}
|
||||
|
||||
void GLrgba::operator/= (const float& c)
|
||||
{
|
||||
red /= c;
|
||||
green /= c;
|
||||
blue /= c;
|
||||
}
|
||||
|
||||
bool GLrgba::operator== (const GLrgba& c)
|
||||
{
|
||||
return (red == c.red && green == c.green && blue == c.blue);
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
#ifndef glTYPES
|
||||
#define glTYPES
|
||||
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
|
||||
#define OPERATORS(type) \
|
||||
type operator+ (const type& c); \
|
||||
type operator+ (const float& c);\
|
||||
void operator+= (const type& c);\
|
||||
void operator+= (const float& c);\
|
||||
type operator- (const type& c);\
|
||||
type operator- (const float& c);\
|
||||
void operator-= (const type& c);\
|
||||
void operator-= (const float& c);\
|
||||
type operator* (const type& c);\
|
||||
type operator* (const float& c);\
|
||||
void operator*= (const type& c);\
|
||||
void operator*= (const float& c);\
|
||||
type operator/ (const type& c);\
|
||||
type operator/ (const float& c);\
|
||||
void operator/= (const type& c);\
|
||||
void operator/= (const float& c);\
|
||||
bool operator== (const type& c);
|
||||
|
||||
|
||||
#define JOINT_MAX_CHILDREN 8
|
||||
|
||||
struct GLquat
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct GLvector
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
OPERATORS(GLvector);
|
||||
};
|
||||
|
||||
typedef GLvector GLvector3;
|
||||
|
||||
struct GLvector2
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
OPERATORS(GLvector2);
|
||||
};
|
||||
|
||||
struct GLrgba
|
||||
{
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float alpha;
|
||||
OPERATORS(GLrgba);
|
||||
};
|
||||
|
||||
struct GLmatrix
|
||||
{
|
||||
float elements[4][4];
|
||||
};
|
||||
|
||||
struct GLbbox
|
||||
{
|
||||
GLvector3 min;
|
||||
GLvector3 max;
|
||||
};
|
||||
|
||||
struct GLvertex
|
||||
{
|
||||
GLvector3 position;
|
||||
GLvector2 uv;
|
||||
GLrgba color;
|
||||
int bone;
|
||||
};
|
||||
|
||||
struct GLrect
|
||||
{
|
||||
float left;
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
};
|
||||
|
||||
struct GLtriangle
|
||||
{
|
||||
int v1;
|
||||
int v2;
|
||||
int v3;
|
||||
int normal1;
|
||||
int normal2;
|
||||
int normal3;
|
||||
};
|
||||
|
||||
/*
|
||||
class GLmodel
|
||||
{
|
||||
public:
|
||||
unsigned vertex_count;
|
||||
unsigned triangle_count;
|
||||
unsigned normal_count;
|
||||
GLvertex* vertex;
|
||||
GLvector* normal;
|
||||
GLtriangle* triangle;
|
||||
|
||||
void TriangleRender (unsigned n);
|
||||
GLtriangle* TriangleAdd (unsigned v1, int unsigned, int unsigned);
|
||||
GLtriangle* TriangleAdd (GLtriangle c);
|
||||
void NormalAdd (GLvector n);
|
||||
void VertexAdd (GLvertex v);
|
||||
GLmodel ();
|
||||
~GLmodel ();
|
||||
void Render ();
|
||||
GLbbox BBox ();
|
||||
private:
|
||||
GLbbox m_bbox;
|
||||
|
||||
};
|
||||
|
||||
struct GLkeyframe
|
||||
{
|
||||
float time;
|
||||
GLvector offset;
|
||||
GLvector rotation;
|
||||
};
|
||||
|
||||
struct GLsegment
|
||||
{
|
||||
int index;
|
||||
GLvector rotation;
|
||||
GLvector offset;
|
||||
GLkeyframe keyframes[255];
|
||||
int frame_count;
|
||||
};
|
||||
|
||||
class GLanimate
|
||||
{
|
||||
public:
|
||||
GLanimate ();
|
||||
void KeyframeAdd (int joint, float time, GLquat q);
|
||||
void TimeSet (float time);
|
||||
void PositionSet (float pos);
|
||||
GLvector Rotation (int);
|
||||
GLvector Offset (int);
|
||||
|
||||
private:
|
||||
GLsegment* m_segments;
|
||||
int m_segment_count;
|
||||
float m_length;
|
||||
};
|
||||
*/
|
||||
|
||||
GLbbox glBboxClear (void);
|
||||
GLbbox glBboxContainPoint (GLbbox box, GLvector point);
|
||||
bool glBboxTestPoint (GLbbox box, GLvector point);
|
||||
|
||||
GLrgba glRgba (char* string);
|
||||
GLrgba glRgba (float red, float green, float blue);
|
||||
GLrgba glRgba (float luminance);
|
||||
GLrgba glRgba (float red, float green, float blue, float alpha);
|
||||
GLrgba glRgba (long c);
|
||||
GLrgba glRgba (int red, int green, int blue);
|
||||
GLrgba glRgbaAdd (GLrgba c1, GLrgba c2);
|
||||
GLrgba glRgbaSubtract (GLrgba c1, GLrgba c2);
|
||||
GLrgba glRgbaInterpolate (GLrgba c1, GLrgba c2, float delta);
|
||||
GLrgba glRgbaScale (GLrgba c, float scale);
|
||||
GLrgba glRgbaMultiply (GLrgba c1, GLrgba c2);
|
||||
GLrgba glRgbaUnique (int i);
|
||||
GLrgba glRgbaFromHsl (float h, float s, float l);
|
||||
|
||||
GLmatrix glMatrixIdentity (void);
|
||||
void glMatrixElementsSet (GLmatrix* m, float* in);
|
||||
GLmatrix glMatrixMultiply (GLmatrix a, GLmatrix b);
|
||||
GLvector glMatrixTransformPoint (GLmatrix m, GLvector in);
|
||||
GLmatrix glMatrixTranslate (GLmatrix m, GLvector in);
|
||||
GLmatrix glMatrixRotate (GLmatrix m, float theta, float x, float y, float z);
|
||||
GLvector glMatrixToEuler (GLmatrix mat, int order);
|
||||
|
||||
GLquat glQuat (float x, float y, float z, float w);
|
||||
GLvector glQuatToEuler (GLquat q, int order);
|
||||
|
||||
GLvector glVector (float x, float y, float z);
|
||||
GLvector glVectorCrossProduct (GLvector v1, GLvector v2);
|
||||
float glVectorDotProduct (GLvector v1, GLvector v2);
|
||||
void glVectorGl (GLvector v);
|
||||
GLvector glVectorInterpolate (GLvector v1, GLvector v2, float scalar);
|
||||
float glVectorLength (GLvector v);
|
||||
GLvector glVectorNormalize (GLvector v);
|
||||
GLvector glVectorReflect (GLvector3 ray, GLvector3 normal);
|
||||
|
||||
GLvector2 glVector (float x, float y);
|
||||
GLvector2 glVectorAdd (GLvector2 val1, GLvector2 val2);
|
||||
GLvector2 glVectorSubtract (GLvector2 val1, GLvector2 val2);
|
||||
GLvector2 glVectorNormalize (GLvector2 v);
|
||||
GLvector2 glVectorInterpolate (GLvector2 v1, GLvector2 v2, float scalar);
|
||||
GLvector2 glVectorSinCos (float angle);
|
||||
float glVectorLength (GLvector2 v);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
Vector2.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Functions for dealing with 2d (usually texture mapping) values.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
|
||||
#include "glTypes.h"
|
||||
#include "math.h"
|
||||
#include "macro.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVectorNormalize (GLvector2 v)
|
||||
{
|
||||
|
||||
float length;
|
||||
|
||||
length = glVectorLength (v);
|
||||
if (length < 0.000001f)
|
||||
return v;
|
||||
return v * (1.0f / length);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float glVectorLength (GLvector2 v)
|
||||
{
|
||||
|
||||
return (float)sqrt (v.x * v.x + v.y * v.y);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVectorSinCos (float a)
|
||||
{
|
||||
|
||||
GLvector2 val;
|
||||
|
||||
a *= DEGREES_TO_RADIANS;
|
||||
val.x = sinf (a);
|
||||
val.y = cosf (a);
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVector (float x, float y)
|
||||
{
|
||||
|
||||
GLvector2 val;
|
||||
|
||||
val.x = x;
|
||||
val.y = y;
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVectorAdd (GLvector2 val1, GLvector2 val2)
|
||||
{
|
||||
|
||||
GLvector2 result;
|
||||
|
||||
result.x = val1.x + val2.x;
|
||||
result.y = val1.y + val2.y;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVectorInterpolate (GLvector2 v1, GLvector2 v2, float scalar)
|
||||
{
|
||||
|
||||
GLvector2 result;
|
||||
|
||||
result.x = MathInterpolate (v1.x, v2.x, scalar);
|
||||
result.y = MathInterpolate (v1.y, v2.y, scalar);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 glVectorSubtract (GLvector2 val1, GLvector2 val2)
|
||||
{
|
||||
|
||||
GLvector2 result;
|
||||
|
||||
result.x = val1.x - val2.x;
|
||||
result.y = val1.y - val2.y;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
+
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector2 GLvector2::operator+ (const GLvector2& c)
|
||||
{
|
||||
return glVector (x + c.x, y + c.y);
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator+ (const float& c)
|
||||
{
|
||||
return glVector (x + c, y + c);
|
||||
}
|
||||
|
||||
void GLvector2::operator+= (const GLvector2& c)
|
||||
{
|
||||
x += c.x;
|
||||
y += c.y;
|
||||
}
|
||||
|
||||
void GLvector2::operator+= (const float& c)
|
||||
{
|
||||
x += c;
|
||||
y += c;
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator- (const GLvector2& c)
|
||||
{
|
||||
return glVector (x - c.x, y - c.y);
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator- (const float& c)
|
||||
{
|
||||
return glVector (x - c, y - c);
|
||||
}
|
||||
|
||||
void GLvector2::operator-= (const GLvector2& c)
|
||||
{
|
||||
x -= c.x;
|
||||
y -= c.y;
|
||||
}
|
||||
|
||||
void GLvector2::operator-= (const float& c)
|
||||
{
|
||||
x -= c;
|
||||
y -= c;
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator* (const GLvector2& c)
|
||||
{
|
||||
return glVector (x * c.x, y * c.y);
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator* (const float& c)
|
||||
{
|
||||
return glVector (x * c, y * c);
|
||||
}
|
||||
|
||||
void GLvector2::operator*= (const GLvector2& c)
|
||||
{
|
||||
x *= c.x;
|
||||
y *= c.y;
|
||||
}
|
||||
|
||||
void GLvector2::operator*= (const float& c)
|
||||
{
|
||||
x *= c;
|
||||
y *= c;
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator/ (const GLvector2& c)
|
||||
{
|
||||
return glVector (x / c.x, y / c.y);
|
||||
}
|
||||
|
||||
GLvector2 GLvector2::operator/ (const float& c)
|
||||
{
|
||||
return glVector (x / c, y / c);
|
||||
}
|
||||
|
||||
void GLvector2::operator/= (const GLvector2& c)
|
||||
{
|
||||
x /= c.x;
|
||||
y /= c.y;
|
||||
}
|
||||
|
||||
void GLvector2::operator/= (const float& c)
|
||||
{
|
||||
x /= c;
|
||||
y /= c;
|
||||
}
|
||||
|
||||
bool GLvector2::operator== (const GLvector2& c)
|
||||
{
|
||||
if (x == c.x && y == c.y)
|
||||
return true;
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
|
||||
glVector3.cpp
|
||||
|
||||
2006 Shamus Young
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Functions for dealing with 3d vectors.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <gl\gl.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "math.h"
|
||||
#include "glTypes.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector glVectorReflect (GLvector3 ray, GLvector3 normal)
|
||||
{
|
||||
|
||||
float dot;
|
||||
|
||||
dot = glVectorDotProduct (ray, normal);
|
||||
//return glVectorSubtract (ray, glVectorScale (normal, 2.0f * dot));
|
||||
return ray - (normal * (2.0f * dot));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVector (float x, float y, float z)
|
||||
{
|
||||
|
||||
GLvector3 result;
|
||||
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.z = z;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVectorInterpolate (GLvector3 v1, GLvector3 v2, float scalar)
|
||||
{
|
||||
|
||||
GLvector3 result;
|
||||
|
||||
result.x = MathInterpolate (v1.x, v2.x, scalar);
|
||||
result.y = MathInterpolate (v1.y, v2.y, scalar);
|
||||
result.z = MathInterpolate (v1.z, v2.z, scalar);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float glVectorLength (GLvector3 v)
|
||||
{
|
||||
|
||||
return (float)sqrt (v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
float glVectorDotProduct (GLvector3 v1, GLvector3 v2)
|
||||
{
|
||||
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVectorCrossProduct (GLvector3 v1, GLvector3 v2)
|
||||
{
|
||||
|
||||
GLvector3 result;
|
||||
|
||||
result.x = v1.y * v2.z - v2.y * v1.z;
|
||||
result.y = v1.z * v2.x - v2.z * v1.x;
|
||||
result.z = v1.x * v2.y - v2.x * v1.y;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVectorInvert (GLvector3 v)
|
||||
{
|
||||
|
||||
v.x *= -v.x;
|
||||
v.y *= -v.y;
|
||||
v.z *= -v.z;
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVectorScale (GLvector3 v, float scale)
|
||||
{
|
||||
|
||||
v.x *= scale;
|
||||
v.y *= scale;
|
||||
v.z *= scale;
|
||||
return v;
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector3 glVectorNormalize (GLvector3 v)
|
||||
{
|
||||
|
||||
float length;
|
||||
|
||||
length = glVectorLength (v);
|
||||
if (length < 0.000001f)
|
||||
return v;
|
||||
return glVectorScale (v, 1.0f / length);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
+
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
GLvector GLvector::operator+ (const GLvector& c)
|
||||
{
|
||||
return glVector (x + c.x, y + c.y, z + c.z);
|
||||
}
|
||||
|
||||
GLvector GLvector::operator+ (const float& c)
|
||||
{
|
||||
return glVector (x + c, y + c, z + c);
|
||||
}
|
||||
|
||||
void GLvector::operator+= (const GLvector& c)
|
||||
{
|
||||
x += c.x;
|
||||
y += c.y;
|
||||
z += c.z;
|
||||
}
|
||||
|
||||
void GLvector::operator+= (const float& c)
|
||||
{
|
||||
x += c;
|
||||
y += c;
|
||||
z += c;
|
||||
}
|
||||
|
||||
GLvector GLvector::operator- (const GLvector& c)
|
||||
{
|
||||
return glVector (x - c.x, y - c.y, z - c.z);
|
||||
}
|
||||
|
||||
GLvector GLvector::operator- (const float& c)
|
||||
{
|
||||
return glVector (x - c, y - c, z - c);
|
||||
}
|
||||
|
||||
void GLvector::operator-= (const GLvector& c)
|
||||
{
|
||||
x -= c.x;
|
||||
y -= c.y;
|
||||
z -= c.z;
|
||||
}
|
||||
|
||||
void GLvector::operator-= (const float& c)
|
||||
{
|
||||
x -= c;
|
||||
y -= c;
|
||||
z -= c;
|
||||
}
|
||||
|
||||
GLvector GLvector::operator* (const GLvector& c)
|
||||
{
|
||||
return glVector (x * c.x, y * c.y, z * c.z);
|
||||
}
|
||||
|
||||
GLvector GLvector::operator* (const float& c)
|
||||
{
|
||||
return glVector (x * c, y * c, z * c);
|
||||
}
|
||||
|
||||
void GLvector::operator*= (const GLvector& c)
|
||||
{
|
||||
x *= c.x;
|
||||
y *= c.y;
|
||||
z *= c.z;
|
||||
}
|
||||
|
||||
void GLvector::operator*= (const float& c)
|
||||
{
|
||||
x *= c;
|
||||
y *= c;
|
||||
z *= c;
|
||||
}
|
||||
|
||||
GLvector GLvector::operator/ (const GLvector& c)
|
||||
{
|
||||
return glVector (x / c.x, y / c.y, z / c.z);
|
||||
}
|
||||
|
||||
GLvector GLvector::operator/ (const float& c)
|
||||
{
|
||||
return glVector (x / c, y / c, z / c);
|
||||
}
|
||||
|
||||
void GLvector::operator/= (const GLvector& c)
|
||||
{
|
||||
x /= c.x;
|
||||
y /= c.y;
|
||||
z /= c.z;
|
||||
}
|
||||
|
||||
void GLvector::operator/= (const float& c)
|
||||
{
|
||||
x /= c;
|
||||
y /= c;
|
||||
z /= c;
|
||||
}
|
||||
|
||||
bool GLvector::operator== (const GLvector& c)
|
||||
{
|
||||
if (x == c.x && y == c.y && z == c.z)
|
||||
return true;
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue