void CDeco::CreateRadioTower (GLvector pos, float height) { CLight* l; float offset; GLvertex v; fan f; for(int i=0; i<6; i++) f.index_list.push_back(i); 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 (f); l = new CLight (glVector (_center.x, _center.y + height + 1.0f, _center.z), glRgba (255,192,160), 1); l->Blink (); _texture = TextureId (TEXTURE_LATTICE); }
//Place a swamp static void do_swamp (int x, int y, int size) { Region r; int xx, yy; float water; r = WorldRegionGet (x, y); water = r.geo_water; for (xx = -size; xx <= size; xx++) { for (yy = -size; yy <= size; yy++) { r = WorldRegionGet (xx + x, yy + y); sprintf (r.title, "Swamp"); r.climate = CLIMATE_SWAMP; r.color_atmosphere = glRgba (0.4f, 1.0f, 0.6f); r.geo_water = water; r.moisture = 1.0f; r.geo_detail = 8.0f; r.has_flowers = false; r.flags_shape |= REGION_FLAG_NOBLEND; WorldRegionSet (x + xx, y + yy, r); } } }
//Place some plains static void do_plains (int x, int y, int size) { Region r; int xx, yy; float water; r = WorldRegionGet (x, y); water = r.geo_water; for (xx = -size; xx <= size; xx++) { for (yy = -size; yy <= size; yy++) { r = WorldRegionGet (xx + x, yy + y); sprintf (r.title, "Plains"); r.climate = CLIMATE_PLAINS; r.color_atmosphere = glRgba (0.9f, 0.9f, 0.6f); r.geo_water = water; r.geo_bias = 8.0f; r.moisture = 1.0f; r.tree_threshold = 0.1f + WorldNoisef (x + xx + (y + yy) * WORLD_GRID) * 0.2f; r.geo_detail = 1.5f + WorldNoisef (x + xx + (y + yy) * WORLD_GRID) * 2.0f; add_flowers (&r, 8); r.flags_shape |= REGION_FLAG_NOBLEND; WorldRegionSet (x + xx, y + yy, r); } } }
//Indentify regions where geo_scale is negative. These will be ocean. void TerraformOceans () { int x, y; Region r; bool is_ocean; //define the oceans at the edge of the world for (x = 0; x < WORLD_GRID; x++) { for (y = 0; y < WORLD_GRID; y++) { r = WorldRegionGet (x, y); is_ocean = false; if (r.geo_scale <= 0.0f) is_ocean = true; if (x == 0 || y == 0 || x == WORLD_GRID - 1 || y == WORLD_GRID - 1) is_ocean = true; if (is_ocean) { r.geo_bias = -10.0f; r.geo_detail = 0.3f; r.moisture = 1.0f; r.geo_water = 0.0f; r.flags_shape = REGION_FLAG_NOBLEND; r.color_atmosphere = glRgba (0.7f, 0.7f, 1.0f); r.climate = CLIMATE_OCEAN; sprintf (r.title, "%s Ocean", get_direction_name (x, y)); WorldRegionSet (x, y, r); } } } }
void TerraformPrepare () { int x, y; Region r; GLcoord from_center; GLcoord offset; //Set some defaults offset.x = RandomVal () % 1024; offset.y = RandomVal () % 1024; for (x = 0; x < WORLD_GRID; x++) { for (y = 0; y < WORLD_GRID; y++) { memset (&r, 0, sizeof (Region)); sprintf (r.title, "NOTHING"); r.geo_bias = r.geo_detail = 0; r.mountain_height = 0; r.grid_pos.x = x; r.grid_pos.y = y; r.tree_threshold = 0.15f; from_center.x = abs (x - WORLD_GRID_CENTER); from_center.y = abs (y - WORLD_GRID_CENTER); //Geo scale is a number from -1 to 1. -1 is lowest ocean. 0 is sea level. //+1 is highest elevation on the island. This is used to guide other derived numbers. r.geo_scale = glVectorLength (glVector ((float)from_center.x, (float)from_center.y)); r.geo_scale /= (WORLD_GRID_CENTER - OCEAN_BUFFER); //Create a steep drop around the edge of the world if (r.geo_scale > 1.0f) r.geo_scale = 1.0f + (r.geo_scale - 1.0f) * 4.0f; r.geo_scale = 1.0f - r.geo_scale; r.geo_scale += (Entropy ((x + offset.x), (y + offset.y)) - 0.5f); r.geo_scale += (Entropy ((x + offset.x) * FREQUENCY, (y + offset.y) * FREQUENCY) - 0.2f); r.geo_scale = clamp (r.geo_scale, -1.0f, 1.0f); if (r.geo_scale > 0.0f) r.geo_water = 1.0f + r.geo_scale * 16.0f; r.color_atmosphere = glRgba (0.0f, 0.0f, 0.0f); r.geo_bias = 0.0f; r.geo_detail = 0.0f; r.color_map = glRgba (0.0f); r.climate = CLIMATE_INVALID; WorldRegionSet (x, y, r); } } }
void CTexture::DrawHeadlight() { float radius; int i, x, y; GLvector2 pos; //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)); }
void CTexture::DrawWindows() { int x, y; int run = 0; int run_length = 2; int lit_density = 2; GLrgba color; bool lit = false; //color = glRgbaUnique (_my_id); for (y = 0; y < SEGMENTS_PER_TEXTURE; y++) { //Every few floors we change the behavior if ((y % 8) == 0) { 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--; } } }
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); }
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); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); glOrtho (0, render_width, render_height, 0, 0.1f, 2048); glDisable(GL_DEPTH_TEST); glDepthMask (false); glMatrixMode (GL_MODELVIEW); glPushMatrix (); glLoadIdentity(); glTranslatef(0, 0, -1.0f); glDisable (GL_BLEND); glDisable (GL_FOG); glDisable (GL_TEXTURE_2D); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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); }
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(); sky = this; }
//Place a desert static void do_desert (int x, int y, int size) { Region r; int xx, yy; for (xx = -size; xx <= size; xx++) { for (yy = -size; yy <= size; yy++) { r = WorldRegionGet (xx + x, yy + y); sprintf (r.title, "Desert"); r.climate = CLIMATE_DESERT; r.color_atmosphere = glRgba (0.6f, 0.3f, 0.1f); r.geo_detail = 8.0f; r.geo_bias = 4.0f; r.tree_threshold = 0.0f; WorldRegionSet (x + xx, y + yy, r); } } }
//Place a field of flowers static void do_field (int x, int y, int size) { Region r; int xx, yy; for (xx = -size; xx <= size; xx++) { for (yy = -size; yy <= size; yy++) { r = WorldRegionGet (xx + x, yy + y); sprintf (r.title, "Field"); r.climate = CLIMATE_FIELD; add_flowers (&r, 4); r.color_atmosphere = glRgba (0.8f, 0.7f, 0.2f); r.geo_detail = 8.0f; r.flags_shape |= REGION_FLAG_NOBLEND; WorldRegionSet (x + xx, y + yy, r); } } }
//Place a forest static void do_forest (int x, int y, int size) { Region r; int xx, yy; for (xx = -size; xx <= size; xx++) { for (yy = -size; yy <= size; yy++) { r = WorldRegionGet (xx + x, yy + y); sprintf (r.title, "Forest"); r.climate = CLIMATE_FOREST; r.color_atmosphere = glRgba (0.0f, 0.0f, 0.5f); r.geo_detail = 8.0f; r.tree_threshold = 0.66f; //r.flags_shape |= REGION_FLAG_NOBLEND; WorldRegionSet (x + xx, y + yy, r); } } }
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; }
static void vshader_select (int select) { VShader* s; GLvector p; Env* e; GLrgba c; float val1, val2; vshader_selected = select; if (!CVarUtils::GetCVar<bool> ("render.shaders")) return; if (select == VSHADER_NONE) { cgGLDisableProfile (cgp_vertex); return; } val1 = val2 = 0.0f; if (select == VSHADER_TREES || select == VSHADER_GRASS) val1 = wind; if (select == VSHADER_CLOUDS) val1 = wind / 5; s = &vshader_list[select]; e = EnvGet (); cgGLEnableProfile (cgp_vertex); cgGLBindProgram (s->program); cgGLSetParameter3f (s->lightpos, -e->light.x, -e->light.y, -e->light.z); c = e->color[ENV_COLOR_LIGHT]; cgGLSetParameter3f (s->lightcol, c.red, c.green, c.blue); c = e->color[ENV_COLOR_AMBIENT] * glRgba (0.2f, 0.2f, 1.0f); cgGLSetParameter3f (s->ambientcol, c.red, c.green, c.blue); p = AvatarCameraPosition (); cgGLSetParameter3f (s->eyepos, p.x, p.y, p.z); cgGLSetStateMatrixParameter(s->matrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MODELVIEW_MATRIX); cgGLSetParameter2f (s->fog, e->fog.rmin, e->fog.rmax); cgGLSetParameter4f (s->data, SceneVisibleRange (), SceneVisibleRange () * 0.05, val1, val2); glColor3f (1,1,1); }
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); }
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); }
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 RenderUpdate (void) { GLvector pos; GLvector angle; GLrgba color; int elapsed; frames++; do_fps (); glViewport (0, 0, WinWidth (), WinHeight ()); glDepthMask (true); glClearColor (0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (letterbox) glViewport (0, letterbox_offset, render_width, render_height); if (LOADING_SCREEN && TextureReady () && !EntityReady ()) { do_effects (EFFECT_NONE); SwapBuffers (hDC); return; } glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glFogi (GL_FOG_MODE, GL_LINEAR); glDepthFunc(GL_LEQUAL); 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 (1.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. glDisable (GL_FOG); SkyRender (); 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); } 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 (); if (!LOADING_SCREEN) { elapsed = 3000 - WorldSceneElapsed (); if (elapsed >= 0 && elapsed <= 3000) { RenderFogFX ((float)elapsed / 3000.0f); glDisable (GL_TEXTURE_2D); glEnable (GL_BLEND); glBlendFunc (GL_ONE, GL_ONE); EntityRender (); } } if (EntityReady ()) LightRender (); CarRender (); if (show_wireframe) { glDisable (GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); EntityRender (); } do_effects (effect); //Framerate tracker if (show_fps) RenderPrint (1, "FPS=%d : Entities=%d : polys=%d", current_fps, EntityCount () + LightCount () + CarCount (), EntityPolyCount () + LightCount () + CarCount ()); //Show the help overlay if (show_help) do_help (); SwapBuffers (hDC); }
//Determine the grass, dirt, rock, and other colors used by this region. void TerraformColors () { int x, y; Region r; GLrgba humid_air, dry_air, cold_air, warm_air; for (x = 0; x < WORLD_GRID; x++) { for (y = 0; y < WORLD_GRID; y++) { r = WorldRegionGet (x, y); r.color_grass = TerraformColorGenerate (SURFACE_COLOR_GRASS, r.moisture, r.temperature, r.grid_pos.x + r.grid_pos.y * WORLD_GRID); r.color_dirt = TerraformColorGenerate (SURFACE_COLOR_DIRT, r.moisture, r.temperature, r.grid_pos.x + r.grid_pos.y * WORLD_GRID); r.color_rock = TerraformColorGenerate (SURFACE_COLOR_ROCK, r.moisture, r.temperature, r.grid_pos.x + r.grid_pos.y * WORLD_GRID); //"atmosphere" is the overall color of the lighting & fog. warm_air = glRgba (0.0f, 0.2f, 1.0f); cold_air = glRgba (0.7f, 0.9f, 1.0f); //Only set the atmosphere color if it wasn't set elsewhere if (r.color_atmosphere == glRgba (0.0f, 0.0f, 0.0f)) r.color_atmosphere = glRgbaInterpolate (cold_air, warm_air, r.temperature); //Color the map switch (r.climate) { case CLIMATE_MOUNTAIN: r.color_map = glRgba (0.2f + (float)r.mountain_height / 4.0f); r.color_map.Normalize (); break; case CLIMATE_DESERT: r.color_map = glRgba (0.9f, 0.7f, 0.4f); case CLIMATE_COAST: if (r.flags_shape & REGION_FLAG_BEACH_CLIFF) r.color_map = glRgba (0.3f, 0.3f, 0.3f); else r.color_map = glRgba (0.9f, 0.7f, 0.4f); break; case CLIMATE_OCEAN: r.color_map = glRgba (0.0f, 1.0f + r.geo_scale * 2.0f, 1.0f + r.geo_scale); r.color_map.Clamp (); break; case CLIMATE_RIVER: case CLIMATE_LAKE: r.color_map = glRgba (0.0f, 0.0f, 0.6f); break; case CLIMATE_RIVER_BANK: r.color_map = r.color_dirt; break; case CLIMATE_FIELD: r.color_map = r.color_grass + glRgba (0.7f, 0.5f, 0.6f); r.color_map.Normalize (); break; case CLIMATE_PLAINS: r.color_map = r.color_grass + glRgba (0.5f, 0.5f, 0.5f); r.color_map.Normalize (); break; case CLIMATE_FOREST: r.color_map = r.color_grass + glRgba (0.0f, 0.3f, 0.0f); r.color_map *= 0.5f; break; case CLIMATE_SWAMP: r.color_grass *= 0.5f; r.color_map = r.color_grass * 0.5f; break; case CLIMATE_ROCKY: r.color_map = r.color_grass * 0.8f; r.color_map += r.color_rock * 0.2f; r.color_map.Normalize (); r.color_map = r.color_rock; break; case CLIMATE_CANYON: r.color_map = r.color_rock * 0.3f; break; default: r.color_map = r.color_grass; break; } if (r.geo_scale >= 0.0f) r.color_map *= (r.geo_scale * 0.5f + 0.5f); //if (r.geo_scale >= 0.0f) //r.color_map = glRgbaUnique (r.tree_type); //r.color_map = r.color_atmosphere; WorldRegionSet (x, y, r); } } }
void CTexture::Rebuild() { int i, j; int x, y; int name_num, prefix_num, suffix_num; int max_size; float radius; GLvector2 pos; bool use_framebuffer; unsigned char* bits; unsigned start; int lapsed; start = GetTickCount(); //Since we make textures by drawing into the viewport, we can't make them bigger //than the current view. _size = _desired_size; max_size = RenderMaxTextureSize(); while (_size > max_size) _size /= 2; glBindTexture(GL_TEXTURE_2D, _glid); //Set up the texture 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); glDisable(GL_FOG); 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_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, 1, 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: DrawHeadlight(); 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]); 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_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: DrawSky(); 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; }
void CTexture::DrawSky() { GLrgba color; float grey; float scale, inv_scale; int i, x, y; int width, height; int offset; int width_adjust; int height_adjust; color = WorldBloomColor(); grey = (color.red + color.green + color.blue) / 3.0f; //desaturate, slightly dim color = (color + glRgba(grey) * 2.0f) / 15.0f; glDisable(GL_BLEND); glBegin(GL_QUAD_STRIP); glColor3f(0, 0, 0); glVertex2i(0, _half); glVertex2i(_size, _half); glColor3fv(&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)); //Draw the clouds for (i = _size - 30; i > 5; i -= 2) { 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) { inv_scale = 1.0f - (scale); if (scale < 0.4f) color = WorldBloomColor() * 0.1f; else color = glRgba(0.0f); color.alpha = 0.2f; glColor4fv(&color.red); 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(); }
void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime) { GLvector pos; GLvector angle; GLrgba color; int elapsed; incrementTickCount(frameTime * 1000); CameraUpdate (); EntityUpdate (); WorldUpdate (); TextureUpdate (); VisibleUpdate (); CarUpdate (); glViewport (0, 0, render_width, render_height); glDepthMask (true); glClearColor (0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (letterbox) glViewport (0, letterbox_offset, render_width, render_height); if (LOADING_SCREEN && TextureReady () && !EntityReady ()) { do_effects (EFFECT_NONE); return; } glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glFogi (GL_FOG_MODE, GL_LINEAR); glDepthFunc(GL_LEQUAL); 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 (1.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. glDisable (GL_FOG); SkyRender (); 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); } 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 (); if (!LOADING_SCREEN) { elapsed = 3000 - WorldSceneElapsed (); if (elapsed >= 0 && elapsed <= 3000) { RenderFogFX ((float)elapsed / 3000.0f); glDisable (GL_TEXTURE_2D); glEnable (GL_BLEND); glBlendFunc (GL_ONE, GL_ONE); EntityRender (); } } if (EntityReady ()) LightRender (); CarRender (); if (show_wireframe) { glDisable (GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); EntityRender (); } do_effects (effect); }
GLrgba GLrgba::operator/ (const float& c) { return glRgba (red / c, green / c, blue / c, alpha); }
GLrgba GLrgba::operator+ (const GLrgba& c) { return glRgba (red + c.red, green + c.green, blue + c.blue, alpha); }
GLrgba TerraformColorGenerate (SurfaceColor c, float moisture, float temperature, int seed) { float fade; switch (c) { case SURFACE_COLOR_GRASS: GLrgba warm_grass, cold_grass, wet_grass, dry_grass, dead_grass; wet_grass.red = WorldNoisef (seed++) * 0.3f; wet_grass.green = 0.4f + WorldNoisef (seed++) * 0.6f; wet_grass.blue = WorldNoisef (seed++) * 0.3f; //Dry grass is mostly reds and oranges dry_grass.red = 0.7f + WorldNoisef (seed++) * 0.3f; dry_grass.green = 0.5f + WorldNoisef (seed++) * 0.5f; dry_grass.blue = 0.0f + WorldNoisef (seed++) * 0.3f; //Dead grass is pale beige dead_grass = glRgba (0.7f, 0.6f, 0.5f); dead_grass *= 0.7f + WorldNoisef (seed++) * 0.3f; if (moisture < 0.5f) { fade = moisture * 2.0f; warm_grass = glRgbaInterpolate (dead_grass, dry_grass, fade); } else { fade = (moisture - 0.5f) * 2.0f; warm_grass = glRgbaInterpolate (dry_grass, wet_grass, fade); } //cold grass is pale and a little blue cold_grass.red = 0.5f + WorldNoisef (seed++) * 0.2f; cold_grass.green = 0.8f + WorldNoisef (seed++) * 0.2f; cold_grass.blue = 0.7f + WorldNoisef (seed++) * 0.2f; if (temperature < TEMP_COLD) return glRgbaInterpolate (cold_grass, warm_grass, temperature / TEMP_COLD); return warm_grass; case SURFACE_COLOR_DIRT: GLrgba cold_dirt, warm_dirt, dry_dirt, wet_dirt; //Devise a random but plausible dirt color //Dry dirts are mostly reds, oranges, and browns dry_dirt.red = 0.4f + WorldNoisef (seed++) * 0.6f; dry_dirt.green = 0.4f + WorldNoisef (seed++) * 0.6f; dry_dirt.green = min (dry_dirt.green, dry_dirt.red); dry_dirt.green = 0.1f + WorldNoisef (seed++) * 0.5f; dry_dirt.blue = 0.2f + WorldNoisef (seed++) * 0.4f; dry_dirt.blue = min (dry_dirt.blue, dry_dirt.green); //wet dirt is various browns fade = WorldNoisef (seed++) * 0.6f; wet_dirt.red = 0.2f + fade; wet_dirt.green = 0.1f + fade; wet_dirt.blue = 0.0f + fade / 2.0f; wet_dirt.green += WorldNoisef (seed++) * 0.1f; //cold dirt is pale cold_dirt = glRgbaInterpolate (wet_dirt, glRgba (0.7f), 0.5f); //warm dirt us a fade from wet to dry warm_dirt = glRgbaInterpolate (dry_dirt, wet_dirt, moisture); fade = MathScalar (temperature, FREEZING, 1.0f); return glRgbaInterpolate (cold_dirt, warm_dirt, fade); case SURFACE_COLOR_ROCK: GLrgba warm_rock, cold_rock; //Devise a rock color fade = MathScalar (temperature, FREEZING, 1.0f); //Warm rock is red warm_rock.red = 1.0f; warm_rock.green = 1.0f - RandomFloat () * 0.6f; warm_rock.blue = 1.0f - RandomFloat () * 0.6f; //Cold rock is white or blue cold_rock.blue = 1.0f; cold_rock.green = 1.0f - RandomFloat () * 0.4f; cold_rock.red = cold_rock.green; return glRgbaInterpolate (cold_rock, warm_rock, fade); } //Shouldn't happen. Returns pink to flag the problem. return glRgba (1.0f, 0.0f, 1.0f); }
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 ()) return; //Now change projection modes so we can render full-screen effects 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); glDisable (GL_FOG); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Render full-screen effects glBlendFunc (GL_ONE, GL_ONE); glEnable (GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glDepthMask (false); 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 * 2; 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.01f; 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 if (LOADING_SCREEN) { if (fade > 0.0f) { 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); RenderPrint (1, "%s v%d.%d.%03d", APP_TITLE, VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION); } } glPopMatrix (); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); glEnable(GL_DEPTH_TEST); }