static void move_squid (ModeInfo *mi, squid *sq) { hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; GLfloat step = M_PI * 2 / sq->ntentacles; int i; GLfloat radius = head_radius_arg; GLfloat r; /* Move to a new position */ if (! bp->button_down_p) { sq->ratio += speed_arg * 0.01; if (sq->ratio >= 1) { sq->ratio = -(frand(2.0) + frand(2.0) + frand(2.0)); sq->from.x = sq->to.x; sq->from.y = sq->to.y; sq->from.z = sq->to.z; sq->to.x = 250 - frand(500); sq->to.y = 250 - frand(500); sq->to.z = 250 - frand(500); } r = sq->ratio > 0 ? ease_ratio (sq->ratio) : 0; sq->pos.x = sq->from.x + r * (sq->to.x - sq->from.x); sq->pos.y = sq->from.y + r * (sq->to.y - sq->from.y); sq->pos.z = sq->from.z + r * (sq->to.z - sq->from.z); } if (do_pulse) { GLfloat p = pow (sin (sq->pulse * M_PI), 18); sq->head_radius = (head_radius_arg * 0.7 + head_radius_arg * 0.3 * p); radius = sq->head_radius * 0.25; sq->pulse += sq->rate * speed_arg * 0.02; if (sq->pulse > 1) sq->pulse = 0; } for (i = 0; i < sq->ntentacles; i++) { tentacle *tt = &sq->tentacles[i]; GLfloat th = i * step; GLfloat px = cos (th) * radius; GLfloat py = sin (th) * radius; tt->th = th; tt->nodes[0].pos.x = sq->pos.x + px; tt->nodes[0].pos.y = sq->pos.y + py; tt->nodes[0].pos.z = sq->pos.z; move_tentacle (sq, tt); } }
ENTRYPOINT void draw_tentacles (ModeInfo *mi) { tentacles_configuration *tc = &tcs[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i; if (!tc->glx_context) return; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(tc->glx_context)); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glRotatef(current_device_rotation(), 0, 0, 1); # if 1 glScalef (3, 3, 3); # else glPushAttrib (GL_ENABLE_BIT); glPushMatrix(); { GLfloat s = 8.7/1600; glScalef(s,s,s); } glTranslatef(-800,-514,0); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_2D); glColor3f (1, 1, 1); glBegin(GL_LINE_LOOP); glVertex3f(0,0,0); glVertex3f(0,1028,0); glVertex3f(1600,1028,0); glVertex3f(1600,0,0); glEnd(); glPopMatrix(); glPopAttrib(); # endif gltrackball_rotate (tc->trackball); mi->polygon_count = 0; if (debug_p) { glPushAttrib (GL_ENABLE_BIT); glDisable (GL_LIGHTING); glDisable (GL_TEXTURE_1D); glDisable (GL_TEXTURE_2D); glColor3f (1, 1, 1); glLineWidth (1); glBegin(GL_LINES); glVertex3f(-0.5, 0, 0); glVertex3f(0.5, 0, 0); glVertex3f(0, -0.5, 0); glVertex3f(0, 0.5, 0); glEnd(); glPopAttrib(); } else { GLfloat rx = 45; GLfloat ry = -45; GLfloat rz = 70; if (tc->left_p) ry = -ry, rz = -rz; glRotatef (ry, 0, 1, 0); glRotatef (rx, 1, 0, 0); glRotatef (rz, 0, 0, 1); if (intersect_p) glTranslatef (0, -2.0, -4.5); else glTranslatef (0, -2.5, -5.0); } if (!tc->button_down_p) for (i = 0; i < tc->ntentacles; i++) move_tentacle (tc->tentacles[i]); #if 1 for (i = 0; i < tc->ntentacles; i++) { if (! intersect_p) glClear(GL_DEPTH_BUFFER_BIT); draw_tentacle (tc->tentacles[i], True); if (cel_p) draw_tentacle (tc->tentacles[i], False); } #else glScalef (3, 3, 3); glScalef (1, 1, 4); glColor3f(1,1,1); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); draw_sucker (tc->tentacles[0], True); if (cel_p) { glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glLineWidth (tc->line_thickness); glColor4fv (tc->outline_color); draw_sucker (tc->tentacles[0], False); } #endif glPopMatrix (); if (mi->fps_p) do_fps (mi); glFinish(); glXSwapBuffers(dpy, window); }
ENTRYPOINT void init_tentacles (ModeInfo *mi) { tentacles_configuration *tc; int wire = MI_IS_WIREFRAME(mi); int i; if (!tcs) { tcs = (tentacles_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (tentacles_configuration)); if (!tcs) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } tc = &tcs[MI_SCREEN(mi)]; tc->glx_context = init_GL(mi); reshape_tentacles (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } if (!wire && !cel_p) { glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); } tc->trackball = gltrackball_init (False); tc->left_p = !(random() % 5); if (arg_segments < 2) arg_segments = 2; if (arg_slices < 3) arg_slices = 3; if (arg_thickness < 0.1) arg_thickness = 0.1; if (arg_wiggliness < 0) arg_wiggliness = 0; if (arg_wiggliness > 1) arg_wiggliness = 1; if (arg_flexibility < 0) arg_flexibility = 0; if (arg_flexibility > 1) arg_flexibility = 1; parse_color (mi, "tentacleColor", arg_color, tc->tentacle_color); parse_color (mi, "stripeColor", arg_stripe, tc->stripe_color); parse_color (mi, "suckerColor", arg_sucker, tc->sucker_color); /* Black outlines for light colors, white outlines for dark colors. */ if (tc->tentacle_color[0] + tc->tentacle_color[1] + tc->tentacle_color[2] < 0.4) tc->outline_color[0] = 1; tc->outline_color[1] = tc->outline_color[0]; tc->outline_color[2] = tc->outline_color[0]; tc->outline_color[3] = 1; for (i = 0; i < MI_COUNT(mi); i++) move_tentacle (make_tentacle (mi, i, MI_COUNT(mi))); if (wire) texture_p = cel_p = False; if (cel_p) texture_p = False; if (texture_p || cel_p) { glGenTextures(1, &tc->texid); # ifdef HAVE_GLBINDTEXTURE glBindTexture ((cel_p ? GL_TEXTURE_1D : GL_TEXTURE_2D), tc->texid); # endif tc->texture = xpm_to_ximage (MI_DISPLAY(mi), MI_VISUAL(mi), MI_COLORMAP(mi), (cel_p ? grey_texture : scales)); if (!tc->texture) texture_p = cel_p = False; } if (texture_p) { glPixelStorei (GL_UNPACK_ALIGNMENT, 1); clear_gl_error(); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, tc->texture->width, tc->texture->height, 0, GL_RGBA, /* GL_UNSIGNED_BYTE, */ GL_UNSIGNED_INT_8_8_8_8_REV, tc->texture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); } else if (cel_p) { clear_gl_error(); glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA, tc->texture->width, 0, GL_RGBA, /* GL_UNSIGNED_BYTE, */ GL_UNSIGNED_INT_8_8_8_8_REV, tc->texture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_1D); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable (GL_LINE_SMOOTH); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); /* Dark gray instead of black, so the outlines show up */ glClearColor (0.13, 0.13, 0.13, 1.0); } compute_unit_torus (mi, 0.5, MAX(5, arg_slices/6), MAX(9, arg_slices/3)); }