static int draw_colon (ModeInfo *mi) { splitflap_configuration *bp = &bps[MI_SCREEN(mi)]; GLfloat s = 1.0 / (bp->ascent + bp->descent); GLfloat z = 0.01; int count = 0; XCharStruct m; texture_string_metrics (bp->font_data, ":", &m, 0, 0); s *= 2; glPushMatrix(); glTranslatef (-(1 + COLON_WIDTH), 0, 0); glScalef (s, s, 1); glTranslatef (-m.lbearing - (m.rbearing - m.lbearing)/2, -(m.ascent + m.descent) / 2, 0); glEnable (GL_TEXTURE_2D); /* draw the text five times, to give it a border. */ { const XPoint offsets[] = {{ -1, -1 }, { -1, 1 }, { 1, 1 }, { 1, -1 }, { 0, 0 }}; int i; GLfloat n = 1.5; glColor3f (0, 0, 0); for (i = 0; i < countof(offsets); i++) { glPushMatrix(); if (offsets[i].x == 0) { glColor4fv (bp->text_color); glTranslatef (0, 0, z * 2); } glTranslatef (n * offsets[i].x, n * offsets[i].y, 0); print_texture_string (bp->font_data, ":"); count++; glPopMatrix(); } } glPopMatrix(); return count; }
static void loading_msg (ModeInfo *mi, int n) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); char text[100]; GLfloat scale; if (wire) return; if (n == 0) sprintf (text, "Loading images..."); else sprintf (text, "Loading images... (%d%%)", (int) (n * 100 / MI_COUNT(mi))); if (ss->loading_sw == 0) /* only do this once, so that the string doesn't move. */ ss->loading_sw = texture_string_width (ss->texfont, text, &ss->loading_sh); scale = ss->loading_sh / (GLfloat) MI_HEIGHT(mi); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi)); glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2, (MI_HEIGHT(mi) - ss->loading_sh) / 2, 0); glColor3f (1, 1, 0); glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); print_texture_string (ss->texfont, text); glEnable (GL_DEPTH_TEST); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glFinish(); glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi)); }
static void loading_msg (ModeInfo *mi) { photopile_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); const char text[] = "Loading..."; if (wire) return; if (ss->loading_sw == 0) /* only do this once */ { XCharStruct e; texture_string_metrics (ss->texfont, text, &e, 0, 0); ss->loading_sw = e.width; ss->loading_sh = e.ascent + e.descent; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1); glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2, (MI_HEIGHT(mi) - ss->loading_sh) / 2, 0); glColor3f (1, 1, 0); glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); print_texture_string (ss->texfont, text); glEnable (GL_DEPTH_TEST); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glFinish(); glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi)); }
static void draw_unichar (ModeInfo *mi) { unicrud_configuration *bp = &bps[MI_SCREEN(mi)]; char text[10]; char title[400]; XCharStruct e; int w, h, i, j; GLfloat s; i = utf8_encode (bp->unichar, text, sizeof(text) - 1); text[i] = 0; *title = 0; sprintf (title + strlen(title), "Plane:\t%s\n", bp->charplane); sprintf (title + strlen(title), "Block:\t%s\n", bp->charblock); # ifdef HAVE_JWXYZ sprintf (title + strlen(title), "Name:\t%s\n", (bp->charname ? bp->charname : "")); #endif sprintf (title + strlen(title), "Unicode:\t%04lX\n", bp->unichar); sprintf (title + strlen(title), "UTF-8:\t"); for (j = 0; j < i; j++) sprintf (title + strlen(title), "%02X ", ((unsigned char *)text)[j]); texture_string_metrics (bp->char_font, text, &e, 0, 0); w = e.width; h = e.ascent; s = 9; glScalef (s, s, s); s = 1.0 / (h > w ? h : w); /* Scale to unit */ glScalef (s, s, s); glTranslatef (-w/2, -h/2, 0); glColor4fv (bp->color); print_texture_string (bp->char_font, text); glColor3f (1, 1, 0); if (do_titles) print_texture_label (mi->dpy, bp->title_font, mi->xgwa.width, mi->xgwa.height, 1, title); }
static void draw_string (sws_configuration *sc, GLfloat x, GLfloat y, const char *s) { const char *os = s; if (!s || !*s) return; glPushMatrix (); glTranslatef (x, y, 0); if (textures_p) print_texture_string (sc->texfont, s); else while (*s) glutStrokeCharacter (GLUT_FONT, *s++); glPopMatrix (); if (debug_p) { GLfloat w; GLfloat h = sc->line_height / sc->font_scale; char c[2]; c[1]=0; s = os; if (textures_p) glDisable (GL_TEXTURE_2D); glLineWidth (1); glColor3f (0.4, 0.4, 0.4); glPushMatrix (); glTranslatef (x, y, 0); while (*s) { *c = *s++; w = string_width (sc, c); glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (w, 0, 0); glVertex3f (w, h, 0); glVertex3f (0, h, 0); glEnd(); glTranslatef (w, 0, 0); } glPopMatrix (); if (textures_p) glEnable (GL_TEXTURE_2D); } }
static void draw_frame (ModeInfo *mi, image_frame *frame, time_t now, Bool body_p) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); GLfloat texw = frame->current.geom.width / (GLfloat) frame->current.tw; GLfloat texh = frame->current.geom.height / (GLfloat) frame->current.th; GLfloat texx1 = frame->current.geom.x / (GLfloat) frame->current.tw; GLfloat texy1 = frame->current.geom.y / (GLfloat) frame->current.th; GLfloat texx2 = texx1 + texw; GLfloat texy2 = texy1 + texh; GLfloat aspect = ((GLfloat) frame->current.geom.height / (GLfloat) frame->current.geom.width); glBindTexture (GL_TEXTURE_2D, frame->current.texid); glPushMatrix(); /* Position this image on the wheel. */ glRotatef (frame->theta, 0, 1, 0); glTranslatef (0, 0, frame->r); /* Scale down the image so that all N frames fit on the wheel without bumping in to each other. */ { GLfloat t, s; switch (ss->nframes) { case 1: t = -1.0; s = 1.7; break; case 2: t = -0.8; s = 1.6; break; case 3: t = -0.4; s = 1.5; break; case 4: t = -0.2; s = 1.3; break; default: t = 0.0; s = 6.0 / ss->nframes; break; } glTranslatef (0, 0, t); glScalef (s, s, s); } /* Center this image on the wheel plane. */ glTranslatef (-0.5, -(aspect/2), 0); /* Move as per the "zoom in and out" setting. */ if (zoom_p) { double x, y, z; /* Only use the Z component of the rotator for in/out position. */ get_position (frame->rot, &x, &y, &z, !ss->button_down_p); glTranslatef (0, 0, z/2); } /* Compute the "drop in and out" state. */ switch (frame->mode) { case EARLY: abort(); break; case NORMAL: if (!ss->button_down_p && now >= frame->expires && ss->loads_in_progress == 0) /* only load one at a time */ load_image (mi, frame); break; case LOADING: break; case OUT: if (--frame->mode_tick <= 0) { image swap = frame->current; frame->current = frame->loading; frame->loading = swap; frame->mode = IN; frame->mode_tick = fade_ticks / speed; } break; case IN: if (--frame->mode_tick <= 0) frame->mode = NORMAL; break; default: abort(); } /* Now translate for current in/out state. */ if (frame->mode == OUT || frame->mode == IN) { GLfloat t = (frame->mode == OUT ? frame->mode_tick / (fade_ticks / speed) : (((fade_ticks / speed) - frame->mode_tick + 1) / (fade_ticks / speed))); t = 5 * (1 - t); if (frame->from_top_p) t = -t; glTranslatef (0, t, 0); } if (body_p) /* Draw the image quad. */ { if (! wire) { glColor3f (1, 1, 1); glNormal3f (0, 0, 1); glEnable (GL_TEXTURE_2D); glBegin (GL_QUADS); glNormal3f (0, 0, 1); glTexCoord2f (texx1, texy2); glVertex3f (0, 0, 0); glTexCoord2f (texx2, texy2); glVertex3f (1, 0, 0); glTexCoord2f (texx2, texy1); glVertex3f (1, aspect, 0); glTexCoord2f (texx1, texy1); glVertex3f (0, aspect, 0); glEnd(); } /* Draw a box around it. */ glLineWidth (2.0); glColor3f (0.5, 0.5, 0.5); glDisable (GL_TEXTURE_2D); glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (1, 0, 0); glVertex3f (1, aspect, 0); glVertex3f (0, aspect, 0); glEnd(); } else /* Draw a title under the image. */ { int sw, sh; GLfloat scale = 0.05; char *title = frame->current.title ? frame->current.title : "(untitled)"; sw = texture_string_width (ss->texfont, title, &sh); glTranslatef (0, -scale, 0); scale /= sh; glScalef (scale, scale, scale); glTranslatef (((1/scale) - sw) / 2, 0, 0); glColor3f (1, 1, 1); if (!wire) { glEnable (GL_TEXTURE_2D); print_texture_string (ss->texfont, title); } else { glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (sw, 0, 0); glVertex3f (sw, sh, 0); glVertex3f (0, sh, 0); glEnd(); } } glPopMatrix(); }
static void loading_msg (ModeInfo *mi, int n) { carousel_state *ss = &sss[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); char text[100]; if (wire) return; if (n == 0) sprintf (text, "Loading images..."); else sprintf (text, "Loading images... (%d%%)", (int) (n * 100 / MI_COUNT(mi))); if (ss->loading_sw == 0) { /* only do this once, so that the string doesn't move. */ XCharStruct e; texture_string_metrics (ss->texfont, text, &e, 0, 0); ss->loading_sw = e.width; ss->loading_sh = e.ascent + e.descent; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); /* { double rot = current_device_rotation(); glRotatef(rot, 0, 0, 1); if ((rot > 45 && rot < 135) || (rot < -45 && rot > -135)) { GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi); glScalef (s, 1/s, 1); } } */ # ifdef HAVE_MOBILE if (MI_WIDTH(mi) < MI_HEIGHT(mi)) /* portrait orientation */ { GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)); glScalef (s, s, s); glTranslatef(-s/2, 0, 0); } # endif glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1); glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2, (MI_HEIGHT(mi) - ss->loading_sh) / 2, 0); glColor3f (1, 1, 0); glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); print_texture_string (ss->texfont, text); glEnable (GL_DEPTH_TEST); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glFinish(); glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi)); }
/* The segments, numbered arbitrarily from the top left: ________ _ ________ \ /\ /\ \ |\ / \ 0 / \ / \3> | \ 5 / \ / 1 \ / 2 \| ..|4 \ /-6-.. ___________\/______\/______\/______\/______\ | /\ /\ /\ /\ /\ |7 / \ 9 / \ 11 / \ 13 / \ 15 / \ | / 8 \ / 10 \ / 12 \ / 14 \ / 16 \ |/______\/______\/______\/______\/______\ \ /\ / /\ /\ \ 17 / \ 18 / / \ 20 / \ \ / \ / / 19 \ / 21 \ \/ \/ /______\/______\ Each triangle can be connected to at most two other triangles. We start from the middle, #12, and work our way to the edges. Its centroid is 0,0. */ static void triangle (ModeInfo *mi, int which, Bool frontp, GLfloat fold_ratio, GLfloat stel_ratio) { planetstruct *gp = &planets[MI_SCREEN(mi)]; const GLfloat fg[3] = { 1, 1, 1 }; const GLfloat bg[3] = { 0.3, 0.3, 0.3 }; int a = -1, b = -1; GLfloat max = acos (sqrt(5)/3); GLfloat rot = -max * fold_ratio / (M_PI/180); Bool wire = MI_IS_WIREFRAME(mi); if (wire) glColor3fv (fg); switch (which) { case 3: /* One third of the face. */ triangle0 (mi, frontp, stel_ratio, 1<<3 | 1<<4); break; case 4: /* Two thirds of the face: convex. */ triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3 | 1<<4); break; case 6: /* One half of the face. */ triangle0 (mi, frontp, stel_ratio, 1<<1 | 1<<2 | 1<<3); break; case 7: /* One half of the face. */ triangle0 (mi, frontp, stel_ratio, 1<<2 | 1<<3 | 1<<4); break; default: /* Full face. */ triangle0 (mi, frontp, stel_ratio, 0x3F); break; } if (wire) { char tag[20]; glColor3fv (bg); sprintf (tag, "%d", which); glPushMatrix(); glTranslatef (-0.1, 0.2, 0); glScalef (0.005, 0.005, 0.005); print_texture_string (gp->font_data, tag); glPopMatrix(); mi->polygon_count++; } /* The connection hierarchy of the faces starting at the middle, #12. */ switch (which) { case 0: break; case 1: a = 0; b = -1; break; case 2: a = -1; b = 3; break; case 3: break; case 4: a = -1; b = 5; break; case 5: a = -1; b = 6; break; case 7: break; case 6: break; case 8: a = 17; b = 7; break; case 9: a = 8; b = -1; break; case 10: a = 18; b = 9; break; case 11: a = 10; b = 1; break; case 12: a = 11; b = 13; break; case 13: a = 2; b = 14; break; case 14: a = 15; b = 20; break; case 15: a = 4; b = 16; break; case 16: break; case 17: break; case 18: break; case 19: break; case 20: a = 21; b = 19; break; case 21: break; default: abort(); break; } if (a != -1) { glPushMatrix(); glTranslatef (-0.5, 0, 0); /* Move model matrix to upper left */ glRotatef (60, 0, 0, 1); glTranslatef ( 0.5, 0, 0); glMatrixMode(GL_TEXTURE); /* glPushMatrix(); */ glTranslatef (-0.5, 0, 0); /* Move texture matrix the same way */ glRotatef (60, 0, 0, 1); glTranslatef ( 0.5, 0, 0); glMatrixMode(GL_MODELVIEW); glRotatef (rot, 1, 0, 0); triangle (mi, a, frontp, fold_ratio, stel_ratio); /* This should just be a PopMatrix on the TEXTURE stack, but f*****g iOS has GL_MAX_TEXTURE_STACK_DEPTH == 4! WTF! So we have to undo our rotations and translations manually. */ glMatrixMode(GL_TEXTURE); /* glPopMatrix(); */ glTranslatef (-0.5, 0, 0); glRotatef (-60, 0, 0, 1); glTranslatef (0.5, 0, 0); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } if (b != -1) { glPushMatrix(); glTranslatef (0.5, 0, 0); /* Move model matrix to upper right */ glRotatef (-60, 0, 0, 1); glTranslatef (-0.5, 0, 0); glMatrixMode(GL_TEXTURE); /* glPushMatrix(); */ glTranslatef (0.5, 0, 0); /* Move texture matrix the same way */ glRotatef (-60, 0, 0, 1); glTranslatef (-0.5, 0, 0); glMatrixMode(GL_MODELVIEW); glRotatef (rot, 1, 0, 0); triangle (mi, b, frontp, fold_ratio, stel_ratio); /* See above. Grr. */ glMatrixMode(GL_TEXTURE); /* glPopMatrix(); */ glTranslatef (0.5, 0, 0); glRotatef (60, 0, 0, 1); glTranslatef (-0.5, 0, 0); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } }
static void draw_line (ModeInfo *mi, line *line) { int wire = MI_IS_WIREFRAME(mi); fliptext_configuration *sc = &scs[MI_SCREEN(mi)]; if (! line->text || !*line->text || line->state == NEW || line->state == HESITATE || line->state == DEAD) return; glPushMatrix(); glTranslatef (line->current.x, line->current.y, line->current.z); glRotatef (line->cth, 0, 1, 0); if (sc->alignment == 1) glTranslatef (-line->width, 0, 0); else if (sc->alignment == 0) glTranslatef (-line->width/2, 0, 0); glScalef (sc->font_scale, sc->font_scale, sc->font_scale); glColor4f (line->color[0], line->color[1], line->color[2], line->color[3]); if (!wire) print_texture_string (sc->texfont, line->text); else { int w, h; char *s = line->text; char c[2]; c[1]=0; glDisable (GL_TEXTURE_2D); glColor3f (0.4, 0.4, 0.4); while (*s) { XCharStruct e; *c = *s++; texture_string_metrics (sc->texfont, c, &e, 0, 0); w = e.width; h = e.ascent + e.descent; glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (w, 0, 0); glVertex3f (w, h, 0); glVertex3f (0, h, 0); glEnd(); glTranslatef (w, 0, 0); } } #if 0 glDisable (GL_TEXTURE_2D); glColor3f (0.4, 0.4, 0.4); glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (line->width/sc->font_scale, 0, 0); glVertex3f (line->width/sc->font_scale, line->height/sc->font_scale, 0); glVertex3f (0, line->height/sc->font_scale, 0); glEnd(); if (!wire) glEnable (GL_TEXTURE_2D); #endif glPopMatrix(); mi->polygon_count += strlen (line->text); }
static void draw_image (ModeInfo *mi, int i, GLfloat t, GLfloat s, GLfloat z) { int wire = MI_IS_WIREFRAME(mi); photopile_state *ss = &sss[MI_SCREEN(mi)]; image *frame = ss->frames + i; position pos = interpolate(t, frame->pos); GLfloat w = frame->geom.width * 0.5; GLfloat h = frame->geom.height * 0.5; GLfloat z1 = z - 0.25 / (MI_COUNT(mi) + 1); GLfloat z2 = z - 0.5 / (MI_COUNT(mi) + 1); GLfloat w1 = w; GLfloat h1 = h; GLfloat h2 = h; if (polaroid_p) { GLfloat minSize = MIN(w, h); GLfloat maxSize = MAX(w, h); /* Clip or scale image to fit in the frame. */ if (clip_p) { w = h = minSize; } else { GLfloat scale = minSize / maxSize; w *= scale; h *= scale; } w1 = minSize * 1.16; /* enlarge frame border */ h1 = minSize * 1.5; h2 = w1; s /= 1.5; /* compensate for border size */ } glPushMatrix(); /* Position and scale this image. */ glTranslatef (pos.x, pos.y, 0); glRotatef (pos.angle, 0, 0, 1); glScalef (s, s, 1); /* Draw the drop shadow. */ if (shadows_p && !wire) { glColor3f (0, 0, 0); draw_drop_shadow(ss->shadow, -w1, -h1, z2, 2.0 * w1, h1 + h2, 20.0); glDisable (GL_BLEND); } glDisable (GL_LIGHTING); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); /* Draw the retro instant-film frame. */ if (polaroid_p) { if (! wire) { glShadeModel (GL_SMOOTH); glEnable (GL_LINE_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glColor3f (1, 1, 1); glBegin (GL_QUADS); glVertex3f (-w1, -h1, z2); glVertex3f ( w1, -h1, z2); glVertex3f ( w1, h2, z2); glVertex3f (-w1, h2, z2); glEnd(); } glLineWidth (1.0); glColor3f (0.5, 0.5, 0.5); glBegin (GL_LINE_LOOP); glVertex3f (-w1, -h1, z); glVertex3f ( w1, -h1, z); glVertex3f ( w1, h2, z); glVertex3f (-w1, h2, z); glEnd(); } /* Draw the image quad. */ if (! wire) { GLfloat texw = w / frame->tw; GLfloat texh = h / frame->th; GLfloat texx = (frame->geom.x + 0.5 * frame->geom.width) / frame->tw; GLfloat texy = (frame->geom.y + 0.5 * frame->geom.height) / frame->th; glBindTexture (GL_TEXTURE_2D, frame->texid); glEnable (GL_TEXTURE_2D); glColor3f (1, 1, 1); glBegin (GL_QUADS); glTexCoord2f (texx - texw, texy + texh); glVertex3f (-w, -h, z1); glTexCoord2f (texx + texw, texy + texh); glVertex3f ( w, -h, z1); glTexCoord2f (texx + texw, texy - texh); glVertex3f ( w, h, z1); glTexCoord2f (texx - texw, texy - texh); glVertex3f (-w, h, z1); glEnd(); glDisable (GL_TEXTURE_2D); } /* Draw a box around it. */ if (! wire) { glShadeModel (GL_SMOOTH); glEnable (GL_LINE_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); } glLineWidth (1.0); glColor3f (0.5, 0.5, 0.5); glBegin (GL_LINE_LOOP); glVertex3f (-w, -h, z); glVertex3f ( w, -h, z); glVertex3f ( w, h, z); glVertex3f (-w, h, z); glEnd(); /* Draw a title under the image. */ if (titles_p) { int sw, sh, ascent, descent; GLfloat scale = 1; const char *title = frame->title ? frame->title : "(untitled)"; XCharStruct e; /* #### Highly approximate, but doing real clipping is harder... */ int max = 35; if (strlen(title) > max) title += strlen(title) - max; texture_string_metrics (ss->texfont, title, &e, &ascent, &descent); sw = e.width; sh = ascent + descent; /* Scale the text to match the pixel size of the photo */ scale *= w / 300.0; /* Move to below photo */ glTranslatef (0, -h - sh * (polaroid_p ? 2.2 : 0.5), 0); glTranslatef (-sw*scale/2, sh*scale/2, z); glScalef (scale, scale, 1); if (wire || !polaroid_p) { glColor3f (1, 1, 1); } else { glColor3f (0, 0, 0); } if (!wire) { glEnable (GL_TEXTURE_2D); glEnable (GL_BLEND); print_texture_string (ss->texfont, title); } else { glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (sw, 0, 0); glVertex3f (sw, sh, 0); glVertex3f (0, sh, 0); glEnd(); } } glPopMatrix(); }
static int draw_text (ModeInfo *mi, const char *string, GLfloat r, GLfloat th, GLfloat ttl, GLfloat size) { sonar_configuration *sp = &sps[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); int polys = 0; GLfloat font_scale = 0.001 * (size > 0 ? size : font_size) / 14.0; int lines = 0, max_w = 0, lh = 0; char *string2 = strdup (string); char *token = string2; char *line; GLfloat color[4]; if (size <= 0) /* if size not specified, draw in yellow with alpha */ { color[0] = 1; color[1] = 1; color[2] = 0; color[3] = (ttl / (M_PI * 2)) * 1.2; if (color[3] > 1) color[3] = 1; glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); if (wire) glColor3f (color[0]*color[3], color[1]*color[3], color[2]*color[3]); } while ((line = strtok (token, "\r\n"))) { int w = texture_string_width (sp->texfont, line, &lh); if (w > max_w) max_w = w; lines++; token = 0; } glPushMatrix(); glTranslatef (r * cos (th), r * sin(th), 0); glScalef (font_scale, font_scale, font_scale); if (size <= 0) /* Draw the dot */ { GLfloat s = font_size * 1.7; glDisable (GL_TEXTURE_2D); glFrontFace (GL_CW); glBegin (wire ? GL_LINE_LOOP : GL_QUADS); glVertex3f (0, s, 0); glVertex3f (s, s, 0); glVertex3f (s, 0, 0); glVertex3f (0, 0, 0); glEnd(); glTranslatef (-max_w/2, -lh, 0); } else glTranslatef (-max_w/2, -lh/2, 0); /* draw each line, centered */ if (! wire) glEnable (GL_TEXTURE_2D); free (string2); string2 = strdup (string); token = string2; while ((line = strtok (token, "\r\n"))) { int w = texture_string_width (sp->texfont, line, 0); glPushMatrix(); glTranslatef ((max_w-w)/2, 0, 0); if (wire) { glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (w, 0, 0); glVertex3f (w, lh, 0); glVertex3f (0, lh, 0); glEnd(); } else { glFrontFace (GL_CW); print_texture_string (sp->texfont, line); } glPopMatrix(); glTranslatef (0, -lh, 0); polys++; token = 0; } glPopMatrix(); free (string2); if (! wire) glEnable (GL_DEPTH_TEST); return polys; }