added stb, more binaryout changes"
[henge/apc.git] / stb / tests / oversample / main.c
1 #pragma warning(disable:4244; disable:4305; disable:4018)
2 #include <assert.h>
3 #include <ctype.h>
4
5 #define STB_WINMAIN
6 #include "stb_wingraph.h"
7
8 #define STB_TRUETYPE_IMPLEMENTATION
9 #define STB_RECT_PACK_IMPLEMENTATION
10 #include "stb_rect_pack.h"
11 #include "stb_truetype.h"
12
13 #ifndef WINGDIAPI
14 #define CALLBACK __stdcall
15 #define WINGDIAPI __declspec(dllimport)
16 #define APIENTRY __stdcall
17 #endif
18
19 #include <gl/gl.h>
20 #include <gl/glu.h>
21
22 #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
23
24 #define SIZE_X 1024
25 #define SIZE_Y 768
26
27 stbtt_packedchar chardata[6][128];
28
29 int sx=SIZE_X, sy=SIZE_Y;
30
31 #define BITMAP_W 512
32 #define BITMAP_H 512
33 unsigned char temp_bitmap[BITMAP_W][BITMAP_H];
34 unsigned char ttf_buffer[1 << 25];
35 GLuint font_tex;
36
37 float scale[2] = { 24.0f, 14.0f };
38
39 int sf[6] = { 0,1,2, 0,1,2 };
40
41 void load_fonts(void)
42 {
43 stbtt_pack_context pc;
44 int i;
45 FILE *f;
46 char filename[256];
47 char *win = getenv("windir");
48 if (win == NULL) win = getenv("SystemRoot");
49
50 f = fopen(stb_wingraph_commandline, "rb");
51 if (!f) {
52 if (win == NULL)
53 sprintf(filename, "arial.ttf", win);
54 else
55 sprintf(filename, "%s/fonts/arial.ttf", win);
56 f = fopen(filename, "rb");
57 if (!f) exit(0);
58 }
59
60 fread(ttf_buffer, 1, 1<<25, f);
61
62 stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL);
63 for (i=0; i < 2; ++i) {
64 stbtt_PackSetOversampling(&pc, 1, 1);
65 stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+0]+32);
66 stbtt_PackSetOversampling(&pc, 2, 2);
67 stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+1]+32);
68 stbtt_PackSetOversampling(&pc, 3, 1);
69 stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+2]+32);
70 }
71 stbtt_PackEnd(&pc);
72
73 glGenTextures(1, &font_tex);
74 glBindTexture(GL_TEXTURE_2D, font_tex);
75 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
78 }
79
80 int black_on_white;
81
82 void draw_init(void)
83 {
84 glDisable(GL_CULL_FACE);
85 glDisable(GL_TEXTURE_2D);
86 glDisable(GL_LIGHTING);
87 glDisable(GL_DEPTH_TEST);
88
89 glViewport(0,0,sx,sy);
90 if (black_on_white)
91 glClearColor(255,255,255,0);
92 else
93 glClearColor(0,0,0,0);
94 glClear(GL_COLOR_BUFFER_BIT);
95
96 glMatrixMode(GL_PROJECTION);
97 glLoadIdentity();
98 gluOrtho2D(0,sx,sy,0);
99 glMatrixMode(GL_MODELVIEW);
100 glLoadIdentity();
101 }
102
103
104 void drawBoxTC(float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1)
105 {
106 glTexCoord2f(s0,t0); glVertex2f(x0,y0);
107 glTexCoord2f(s1,t0); glVertex2f(x1,y0);
108 glTexCoord2f(s1,t1); glVertex2f(x1,y1);
109 glTexCoord2f(s0,t1); glVertex2f(x0,y1);
110 }
111
112 int integer_align;
113
114 void print(float x, float y, int font, char *text)
115 {
116 glEnable(GL_TEXTURE_2D);
117 glBindTexture(GL_TEXTURE_2D, font_tex);
118 glBegin(GL_QUADS);
119 while (*text) {
120 stbtt_aligned_quad q;
121 stbtt_GetPackedQuad(chardata[font], BITMAP_W, BITMAP_H, *text++, &x, &y, &q, font ? 0 : integer_align);
122 drawBoxTC(q.x0,q.y0,q.x1,q.y1, q.s0,q.t0,q.s1,q.t1);
123 }
124 glEnd();
125 }
126
127 int font=3;
128 int translating;
129 int rotating=0;
130 int srgb=0;
131 float rotate_t, translate_t;
132 int show_tex;
133
134 void draw_world(void)
135 {
136 int sfont = sf[font];
137 float x = 20;
138 glEnable(GL_BLEND);
139 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
140
141 if (black_on_white)
142 glColor3f(0,0,0);
143 else
144 glColor3f(1,1,1);
145
146
147 print(80, 30, sfont, "Controls:");
148 print(100, 60, sfont, "S: toggle font size");
149 print(100, 85, sfont, "O: toggle oversampling");
150 print(100,110, sfont, "T: toggle translation");
151 print(100,135, sfont, "R: toggle rotation");
152 print(100,160, sfont, "P: toggle pixel-snap (only non-oversampled)");
153 print(100,185, sfont, "G: toggle srgb gamma-correction");
154 if (black_on_white)
155 print(100,210, sfont, "B: toggle to white-on-black");
156 else
157 print(100,210, sfont, "B: toggle to black-on-white");
158 print(100,235, sfont, "V: view font texture");
159
160 print(80, 300, sfont, "Current font:");
161
162 if (!show_tex) {
163 if (font < 3)
164 print(100, 350, sfont, "Font height: 24 pixels");
165 else
166 print(100, 350, sfont, "Font height: 14 pixels");
167 }
168
169 if (font%3==1)
170 print(100, 325, sfont, "2x2 oversampled text at 1:1");
171 else if (font%3 == 2)
172 print(100, 325, sfont, "3x1 oversampled text at 1:1");
173 else if (integer_align)
174 print(100, 325, sfont, "1:1 text, one texel = one pixel, snapped to integer coordinates");
175 else
176 print(100, 325, sfont, "1:1 text, one texel = one pixel");
177
178 if (show_tex) {
179 glBegin(GL_QUADS);
180 drawBoxTC(200,400, 200+BITMAP_W,300+BITMAP_H, 0,0,1,1);
181 glEnd();
182 } else {
183 glMatrixMode(GL_MODELVIEW);
184 glTranslatef(200,350,0);
185
186 if (translating)
187 x += fmod(translate_t*8,30);
188
189 if (rotating) {
190 glTranslatef(100,150,0);
191 glRotatef(rotate_t*2,0,0,1);
192 glTranslatef(-100,-150,0);
193 }
194 print(x,100, font, "This is a test");
195 print(x,130, font, "Now is the time for all good men to come to the aid of their country.");
196 print(x,160, font, "The quick brown fox jumps over the lazy dog.");
197 print(x,190, font, "0123456789");
198 }
199 }
200
201 void draw(void)
202 {
203 draw_init();
204 draw_world();
205 stbwingraph_SwapBuffers(NULL);
206 }
207
208 static int initialized=0;
209 static float last_dt;
210
211 int move[4];
212 int raw_mouse_x, raw_mouse_y;
213
214 int loopmode(float dt, int real, int in_client)
215 {
216 float actual_dt = dt;
217
218 if (!initialized) return 0;
219
220 rotate_t += dt;
221 translate_t += dt;
222
223 // music_sim();
224 if (!real)
225 return 0;
226
227 if (dt > 0.25) dt = 0.25;
228 if (dt < 0.01) dt = 0.01;
229
230 draw();
231
232 return 0;
233 }
234
235 int winproc(void *data, stbwingraph_event *e)
236 {
237 switch (e->type) {
238 case STBWGE_create:
239 break;
240
241 case STBWGE_char:
242 switch(e->key) {
243 case 27:
244 stbwingraph_ShowCursor(NULL,1);
245 return STBWINGRAPH_winproc_exit;
246 break;
247 case 'o': case 'O':
248 font = (font+1) % 3 + (font/3)*3;
249 break;
250 case 's': case 'S':
251 font = (font+3) % 6;
252 break;
253 case 't': case 'T':
254 translating = !translating;
255 translate_t = 0;
256 break;
257 case 'r': case 'R':
258 rotating = !rotating;
259 rotate_t = 0;
260 break;
261 case 'p': case 'P':
262 integer_align = !integer_align;
263 break;
264 case 'g': case 'G':
265 srgb = !srgb;
266 if (srgb)
267 glEnable(GL_FRAMEBUFFER_SRGB_EXT);
268 else
269 glDisable(GL_FRAMEBUFFER_SRGB_EXT);
270 break;
271 case 'v': case 'V':
272 show_tex = !show_tex;
273 break;
274 case 'b': case 'B':
275 black_on_white = !black_on_white;
276 break;
277 }
278 break;
279
280 case STBWGE_mousemove:
281 raw_mouse_x = e->mx;
282 raw_mouse_y = e->my;
283 break;
284
285 #if 0
286 case STBWGE_mousewheel: do_mouse(e,0,0); break;
287 case STBWGE_leftdown: do_mouse(e, 1,0); break;
288 case STBWGE_leftup: do_mouse(e,-1,0); break;
289 case STBWGE_rightdown: do_mouse(e,0, 1); break;
290 case STBWGE_rightup: do_mouse(e,0,-1); break;
291 #endif
292
293 case STBWGE_keydown:
294 if (e->key == VK_RIGHT) move[0] = 1;
295 if (e->key == VK_LEFT) move[1] = 1;
296 if (e->key == VK_UP) move[2] = 1;
297 if (e->key == VK_DOWN) move[3] = 1;
298 break;
299 case STBWGE_keyup:
300 if (e->key == VK_RIGHT) move[0] = 0;
301 if (e->key == VK_LEFT) move[1] = 0;
302 if (e->key == VK_UP) move[2] = 0;
303 if (e->key == VK_DOWN) move[3] = 0;
304 break;
305
306 case STBWGE_size:
307 sx = e->width;
308 sy = e->height;
309 loopmode(0,1,0);
310 break;
311
312 case STBWGE_draw:
313 if (initialized)
314 loopmode(0,1,0);
315 break;
316
317 default:
318 return STBWINGRAPH_unprocessed;
319 }
320 return 0;
321 }
322
323 void stbwingraph_main(void)
324 {
325 stbwingraph_Priority(2);
326 stbwingraph_CreateWindow(1, winproc, NULL, "tt", SIZE_X,SIZE_Y, 0, 1, 0, 0);
327 stbwingraph_ShowCursor(NULL, 0);
328 load_fonts();
329 initialized = 1;
330 stbwingraph_MainLoop(loopmode, 0.016f); // 30 fps = 0.33
331 }
332