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