From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/b_draw.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 hacks/glx/b_draw.c (limited to 'hacks/glx/b_draw.c') diff --git a/hacks/glx/b_draw.c b/hacks/glx/b_draw.c new file mode 100644 index 0000000..977efbe --- /dev/null +++ b/hacks/glx/b_draw.c @@ -0,0 +1,239 @@ +#if 0 +static const char sccsid[] = "@(#)b_draw.c 4.11 98/06/16 xlockmore"; +#endif + +/*- + * BUBBLE3D (C) 1998 Richard W.M. Jones. + * b_draw.c: This code creates new bubbles, manages them and controls + * them as they are drawn on the screen. + */ + +#include "bubble3d.h" + +typedef struct draw_context { + /* The list of bubbles currently on the screen. */ + void **bubble_list; + int nr_bubbles; + + /* When was the last time we created a new bubble? */ + int bubble_count; + + glb_data *d; + +} draw_context; + +void * +glb_draw_init(void) +{ + draw_context *c; + + GLfloat mat_specular[] = + {1, 1, 1, 1}; + GLfloat mat_emission[] = + {0, 0, 0, 1}; + GLfloat mat_shininess[] = + {100}; + GLfloat ambient[] = + {0.5, 0.5, 0.5, 1.0}; + GLfloat light_position[][4] = + { + {0, -1, 0, 0}, + {1, 1, 0, 0}, + {-1, 0, 1, 0}}; + GLfloat light_diffuse[][4] = + { + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}}; + GLfloat light_specular[][4] = + { + {1, 1, 1, 1}, + {1, 1, 1, 1}, + {1, 1, 1, 1}}; + + /* Initialize the context. */ + c = (struct draw_context *) malloc(sizeof (struct draw_context)); + + if (c == 0) + return 0; + c->bubble_list = 0; + c->nr_bubbles = 0; + c->bubble_count = glb_config.create_bubbles_every; + + /* Do some GL initialization. */ + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, glb_config.bubble_colour); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); + + if (glb_config.transparent_p) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHT2); + + if (glb_config.transparent_p) + glEnable(GL_BLEND); + else + glEnable(GL_DEPTH_TEST); + + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + + if (glb_config.transparent_p) + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_POSITION, light_position[0]); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse[0]); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular[0]); + glLightfv(GL_LIGHT1, GL_POSITION, light_position[1]); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse[1]); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular[1]); + glLightfv(GL_LIGHT2, GL_POSITION, light_position[2]); + glLightfv(GL_LIGHT2, GL_DIFFUSE, light_diffuse[2]); + glLightfv(GL_LIGHT2, GL_SPECULAR, light_specular[2]); + + c->d = glb_sphere_init(); + + return c; +} + +static void +delete_bubble(draw_context * c, int j) +{ + int i; + + glb_bubble_delete(c->bubble_list[j]); + + for (i = j; i < c->nr_bubbles - 1; ++i) + c->bubble_list[i] = c->bubble_list[i + 1]; + + c->nr_bubbles--; +} + +void +glb_draw_end(void *cc) +{ + draw_context *c = (draw_context *) cc; + int i; + + for (i = 0; i < c->nr_bubbles; ++i) { + delete_bubble(c, i); + i--; + } + + glb_sphere_end (c->d); + + (void) free((void *) c->bubble_list); + (void) free((void *) c); +} + +static int +create_new_bubbles(draw_context * c) +{ + int n, i; + double r = glb_drand(); + GLfloat size, speed, scale_incr, x, y, z; + void *b[4]; + void **old_bubble_list; + + /* How many bubbles to make? */ + if (r < glb_config.p_bubble_group[0]) + n = 1; + else if (r < glb_config.p_bubble_group[1]) + n = 2; + else if (r < glb_config.p_bubble_group[2]) + n = 3; + else + n = 4; + + /* Initial position of top-most bubble in group. */ + x = glb_drand() * 4 - 2; + y = glb_config.screen_bottom; + z = glb_drand() * 2 - 2; + + /* What size? */ + size = glb_config.min_size + + glb_drand() * (glb_config.max_size - glb_config.min_size); + + /* What speed? */ + speed = glb_config.min_speed + + glb_drand() * (glb_config.max_speed - glb_config.min_speed); + + /* Work out the scaling increment. Bubbles should increase by scale_factor + * as they go from bottom to top of screen. + */ + scale_incr = (size * glb_config.scale_factor - size) + / ((glb_config.screen_top - glb_config.screen_bottom) / speed); + + /* Create the bubble(s). */ + for (i = 0; i < n; ++i) { + if ((b[i] = glb_bubble_new(c->d, x, y, z, size, speed, scale_incr)) == 0) { + /* Out of memory - recover. */ + i--; + while (i >= 0) + glb_bubble_delete(b[i]); + return 0; + } + /* Create the next bubble below the last bubble. */ + y -= size * 3; + } + + /* Add the bubbles to the list. */ + c->nr_bubbles += n; + old_bubble_list = c->bubble_list; + if (c->bubble_list == 0) { + c->bubble_list = (void **) malloc(c->nr_bubbles * sizeof (void *)); + } else { + c->bubble_list = (void **) realloc(c->bubble_list, + c->nr_bubbles * sizeof (void *)); + } + + if (c->bubble_list == 0) { + /* Out of memory - recover. */ + for (i = 0; i < n; ++i) + glb_bubble_delete(b[i]); + c->bubble_list = old_bubble_list; + c->nr_bubbles -= n; + return 0; + } + for (i = 0; i < n; ++i) + c->bubble_list[c->nr_bubbles - i - 1] = b[i]; + + return 1; +} + +void +glb_draw_step(void *cc) +{ + draw_context *c = (draw_context *) cc; + int i; + + /* Consider creating a new bubble or bubbles. */ + if (c->nr_bubbles < glb_config.max_bubbles && + c->bubble_count++ > glb_config.create_bubbles_every) { + if (create_new_bubbles(c)) + c->bubble_count = 0; + } + /* Clear the display. */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* XXX Draw the background here ... */ + + /* Draw all the bubbles on the display. */ + for (i = 0; i < c->nr_bubbles; ++i) { + void *b = c->bubble_list[i]; + + glb_bubble_step(b); + glb_bubble_draw(c->d, b); + + /* Has the bubble reached the top of the screen? */ + if (glb_bubble_get_y(b) >= glb_config.screen_top) { + delete_bubble(c, i); + i--; + } + } +} -- cgit v1.2.3-55-g7522