3 #define GL_GLEXT_PROTOTYPES
7 /* ADM3a 5x7 glyphs, displayed in a 7x9 matrix */
12 #define TEX_NROWS (ROM_CHARS / TEX_NCOLS)
14 #define TEX_WIDTH (TEX_NCOLS * 8)
15 #define TEX_HEIGHT (TEX_NROWS * 8)
17 #define UVWIDTH (1.0f / (float)TEX_NCOLS)
18 #define UVHEIGHT (1.0f / (float)TEX_NROWS)
21 unsigned int tex_font;
22 extern unsigned char rom_upper[];
23 extern unsigned char rom_lower[];
30 #define VB_NGLYPHS 128
31 #define VB_NVERTS (VB_NGLYPHS * 4)
32 static struct vertex varr[VB_NVERTS];
33 static int nglyphs, cur_vbo;
34 static unsigned int vbo[2];
37 static int transform(int c)
40 return ((~c) & 0x7f) | 0x40;
48 unsigned char img[TEX_WIDTH * TEX_HEIGHT];
49 unsigned char *src, *dest = img;
51 memset(img, 0, sizeof img);
53 for(i=0; i<ROM_CHARS; i++) {
54 glyph = transform(i + 0x20);
55 src = rom_upper + glyph * 8;
57 unsigned char row = (*src++ & 0x1f) << 2;
59 dest[k] = (row >> (7 - k)) & 1 ? 0xff : 0;
64 if((i & 0xf) == 0xf) {
65 dest -= TEX_WIDTH - 8;
67 dest = dest + 8 - TEX_WIDTH * 8;
72 FILE *fp = fopen("font.ppm", "wb");
74 fprintf(fp, "P5\n%d %d\n255\n", TEX_WIDTH, TEX_HEIGHT);
75 fwrite(img, 1, TEX_WIDTH * TEX_HEIGHT, fp);
80 glGenTextures(1, &tex_font);
81 glBindTexture(GL_TEXTURE_2D, tex_font);
82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
84 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, TEX_WIDTH, TEX_HEIGHT, 0,
85 GL_LUMINANCE, GL_UNSIGNED_BYTE, img);
92 glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
93 glBufferData(GL_ARRAY_BUFFER, sizeof varr, 0, GL_STREAM_DRAW);
95 glBindBuffer(GL_ARRAY_BUFFER, 0);
98 void text_cleanup(void)
100 glDeleteBuffers(2, vbo);
101 glDeleteTextures(1, &tex_font);
104 void text_begin(void)
111 if(nglyphs <= 0) return;
113 glBindTexture(GL_TEXTURE_2D, tex_font);
114 glEnable(GL_TEXTURE_2D);
116 glBindBuffer(GL_ARRAY_BUFFER, vbo[cur_vbo]);
117 glBufferSubData(GL_ARRAY_BUFFER, 0, nglyphs * 4 * sizeof *varr, varr);
119 glEnableClientState(GL_VERTEX_ARRAY);
120 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
122 glVertexPointer(2, GL_FLOAT, sizeof *varr, 0);
123 glTexCoordPointer(2, GL_FLOAT, sizeof *varr, (void*)(2 * sizeof(float)));
124 glBindBuffer(GL_ARRAY_BUFFER, 0);
126 glDrawArrays(GL_QUADS, 0, nglyphs * 4);
128 glDisableClientState(GL_VERTEX_ARRAY);
129 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
131 glDisable(GL_TEXTURE_2D);
134 cur_vbo = (cur_vbo + 1) & 1;
137 #define VERT(vert, vx, vy) ((vert).x = (vx), (vert).y = (vy))
138 #define TEXC(vert, vu, vv) ((vert).u = (vu), (vert).v = (vv))
140 void draw_glyph(int x, int y, int c)
144 struct vertex *vptr = varr + nglyphs++ * 4;
146 if(c < 0x20 || c >= 128) return;
150 VERT(vptr[0], x, y + 1.0 / 9.0);
151 VERT(vptr[1], x + 1, y + 1.0 / 9.0);
152 VERT(vptr[2], x + 1, y + 1);
153 VERT(vptr[3], x, y + 1);
159 voffs = row * UVHEIGHT;
160 uoffs = col * UVWIDTH;
162 TEXC(vptr[0], uoffs, voffs + UVHEIGHT);
163 TEXC(vptr[1], uoffs + 7.0 / 8.0 * UVWIDTH, voffs + UVHEIGHT);
164 TEXC(vptr[2], uoffs + 7.0 / 8.0 * UVWIDTH, voffs);
165 TEXC(vptr[3], uoffs, voffs);
167 if(nglyphs >= VB_NGLYPHS) {