void CSky::Render () { GLvector angle, position; if (!TextureReady ()) return; glDepthMask (false); glPushAttrib (GL_POLYGON_BIT | GL_FOG_BIT); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); glDisable (GL_CULL_FACE); glDisable (GL_FOG); 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); glPopMatrix (); glPopAttrib (); glDepthMask (true); glEnable (GL_COLOR_MATERIAL); }
void EntityUpdate () { const unsigned stop_time = 100; if (!TextureReady ()) { sorted = false; return; } if (!sorted) { qsort (entity_list, entity_count, sizeof (struct entity), do_compare); sorted = true; } //We want to do several cells at once. Enough to get things done, but //not so many that the program is unresponsive. if (LOADING_SCREEN) { //If we're using a loading screen, we want to build as fast as possible struct timeval then, now; gettimeofday(&then, NULL); now = then; while (!compiled && ((now.tv_sec - then.tv_sec) * 1000 + (now.tv_usec - then.tv_usec) / 1000 < stop_time)) { do_compile (); gettimeofday(&now, NULL); } } else //Take it slow do_compile (); }
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 (); }
void EntityUpdate () { int stop_time; if (!TextureReady ()) { sorted = false; return; } if (!sorted) { std::sort (entity_list.begin(), entity_list.end()); sorted = true; } //We want to do several cells at once. Enough to get things done, but //not so many that the program is unresponsive. if (LOADING_SCREEN) { //If we're using a loading screen, we want to build as fast as possible stop_time = GetTimeInMillis () + 100; while (!compiled && GetTimeInMillis () < stop_time) do_compile (); } else //Take it slow do_compile (); }
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); }
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); }
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); }