added stb, more binaryout changes"
[henge/apc.git] / stb / tests / oversample / main.c
diff --git a/stb/tests/oversample/main.c b/stb/tests/oversample/main.c
new file mode 100644 (file)
index 0000000..bc6bd0f
--- /dev/null
@@ -0,0 +1,332 @@
+#pragma warning(disable:4244; disable:4305; disable:4018)
+#include <assert.h>
+#include <ctype.h>
+
+#define STB_WINMAIN
+#include "stb_wingraph.h"
+
+#define STB_TRUETYPE_IMPLEMENTATION
+#define STB_RECT_PACK_IMPLEMENTATION
+#include "stb_rect_pack.h"
+#include "stb_truetype.h"
+
+#ifndef WINGDIAPI
+#define CALLBACK    __stdcall
+#define WINGDIAPI   __declspec(dllimport)
+#define APIENTRY    __stdcall
+#endif
+
+#include <gl/gl.h>
+#include <gl/glu.h>
+
+#define GL_FRAMEBUFFER_SRGB_EXT           0x8DB9
+
+#define SIZE_X  1024
+#define SIZE_Y  768
+
+stbtt_packedchar chardata[6][128];
+
+int sx=SIZE_X, sy=SIZE_Y;
+
+#define BITMAP_W 512
+#define BITMAP_H 512
+unsigned char temp_bitmap[BITMAP_W][BITMAP_H];
+unsigned char ttf_buffer[1 << 25];
+GLuint font_tex;
+
+float scale[2] = { 24.0f, 14.0f };
+
+int sf[6] = { 0,1,2, 0,1,2 };
+
+void load_fonts(void)
+{
+   stbtt_pack_context pc;
+   int i;
+   FILE *f;
+   char filename[256];
+   char *win = getenv("windir");
+   if (win == NULL) win = getenv("SystemRoot");
+
+   f = fopen(stb_wingraph_commandline, "rb");
+   if (!f) {
+      if (win == NULL)
+         sprintf(filename, "arial.ttf", win);
+      else
+         sprintf(filename, "%s/fonts/arial.ttf", win);
+      f = fopen(filename, "rb");
+      if (!f) exit(0);
+   }
+
+   fread(ttf_buffer, 1, 1<<25, f);
+
+   stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL);
+   for (i=0; i < 2; ++i) {
+      stbtt_PackSetOversampling(&pc, 1, 1);
+      stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+0]+32);
+      stbtt_PackSetOversampling(&pc, 2, 2);
+      stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+1]+32);
+      stbtt_PackSetOversampling(&pc, 3, 1);
+      stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+2]+32);
+   }
+   stbtt_PackEnd(&pc);
+
+   glGenTextures(1, &font_tex);
+   glBindTexture(GL_TEXTURE_2D, font_tex);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+}
+
+int black_on_white;
+
+void draw_init(void)
+{
+   glDisable(GL_CULL_FACE);
+   glDisable(GL_TEXTURE_2D);
+   glDisable(GL_LIGHTING);
+   glDisable(GL_DEPTH_TEST);
+
+   glViewport(0,0,sx,sy);
+   if (black_on_white)
+      glClearColor(255,255,255,0);
+   else
+      glClearColor(0,0,0,0);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluOrtho2D(0,sx,sy,0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+
+void drawBoxTC(float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1)
+{
+   glTexCoord2f(s0,t0); glVertex2f(x0,y0);
+   glTexCoord2f(s1,t0); glVertex2f(x1,y0);
+   glTexCoord2f(s1,t1); glVertex2f(x1,y1);
+   glTexCoord2f(s0,t1); glVertex2f(x0,y1);
+}
+
+int integer_align;
+
+void print(float x, float y, int font, char *text)
+{
+   glEnable(GL_TEXTURE_2D);
+   glBindTexture(GL_TEXTURE_2D, font_tex);
+   glBegin(GL_QUADS);
+   while (*text) {
+      stbtt_aligned_quad q;
+      stbtt_GetPackedQuad(chardata[font], BITMAP_W, BITMAP_H, *text++, &x, &y, &q, font ? 0 : integer_align);
+      drawBoxTC(q.x0,q.y0,q.x1,q.y1, q.s0,q.t0,q.s1,q.t1);
+   }
+   glEnd();
+}
+
+int font=3;
+int translating;
+int rotating=0;
+int srgb=0;
+float rotate_t, translate_t;
+int show_tex;
+
+void draw_world(void)
+{
+   int sfont = sf[font];
+   float x = 20;
+   glEnable(GL_BLEND);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+   if (black_on_white)
+      glColor3f(0,0,0);
+   else
+      glColor3f(1,1,1);
+
+
+   print(80, 30, sfont, "Controls:");
+   print(100, 60, sfont, "S: toggle font size");
+   print(100, 85, sfont, "O: toggle oversampling");
+   print(100,110, sfont, "T: toggle translation");
+   print(100,135, sfont, "R: toggle rotation");
+   print(100,160, sfont, "P: toggle pixel-snap (only non-oversampled)");
+   print(100,185, sfont, "G: toggle srgb gamma-correction");
+   if (black_on_white)
+      print(100,210, sfont, "B: toggle to white-on-black");
+   else
+      print(100,210, sfont, "B: toggle to black-on-white");
+   print(100,235, sfont, "V: view font texture");
+
+   print(80, 300, sfont, "Current font:");
+
+   if (!show_tex) {
+      if (font < 3)
+         print(100, 350, sfont, "Font height: 24 pixels");
+      else
+         print(100, 350, sfont, "Font height: 14 pixels");
+   }
+
+   if (font%3==1)
+      print(100, 325, sfont, "2x2 oversampled text at 1:1");
+   else if (font%3 == 2)
+      print(100, 325, sfont, "3x1 oversampled text at 1:1");
+   else if (integer_align)
+      print(100, 325, sfont, "1:1 text, one texel = one pixel, snapped to integer coordinates");
+   else
+      print(100, 325, sfont, "1:1 text, one texel = one pixel");
+
+   if (show_tex) {
+      glBegin(GL_QUADS);
+      drawBoxTC(200,400, 200+BITMAP_W,300+BITMAP_H, 0,0,1,1);
+      glEnd();
+   } else {
+      glMatrixMode(GL_MODELVIEW);
+      glTranslatef(200,350,0);
+
+      if (translating)
+         x += fmod(translate_t*8,30);
+
+      if (rotating) {
+         glTranslatef(100,150,0);
+         glRotatef(rotate_t*2,0,0,1);
+         glTranslatef(-100,-150,0);
+      }
+      print(x,100, font, "This is a test");
+      print(x,130, font, "Now is the time for all good men to come to the aid of their country.");
+      print(x,160, font, "The quick brown fox jumps over the lazy dog.");
+      print(x,190, font, "0123456789");
+   }
+}
+
+void draw(void)
+{
+   draw_init();
+   draw_world();
+   stbwingraph_SwapBuffers(NULL);
+}
+
+static int initialized=0;
+static float last_dt;
+
+int move[4];
+int raw_mouse_x, raw_mouse_y;
+
+int loopmode(float dt, int real, int in_client)
+{
+   float actual_dt = dt;
+
+   if (!initialized) return 0;
+
+   rotate_t += dt;
+   translate_t += dt;
+
+//   music_sim();
+   if (!real)
+      return 0;
+
+   if (dt > 0.25) dt = 0.25;
+   if (dt < 0.01) dt = 0.01;
+
+   draw();
+
+   return 0;
+}
+
+int winproc(void *data, stbwingraph_event *e)
+{
+   switch (e->type) {
+      case STBWGE_create:
+         break;
+
+      case STBWGE_char:
+         switch(e->key) {
+            case 27:
+               stbwingraph_ShowCursor(NULL,1);
+               return STBWINGRAPH_winproc_exit;
+               break;
+            case 'o': case 'O':
+               font = (font+1) % 3 + (font/3)*3;
+               break;
+            case 's': case 'S':
+               font = (font+3) % 6;
+               break;
+            case 't': case 'T':
+               translating = !translating;
+               translate_t = 0;
+               break;
+            case 'r': case 'R':
+               rotating = !rotating;
+               rotate_t = 0;
+               break;
+            case 'p': case 'P':
+               integer_align = !integer_align;
+               break;
+            case 'g': case 'G':
+               srgb = !srgb;
+               if (srgb)
+                  glEnable(GL_FRAMEBUFFER_SRGB_EXT);
+               else
+                  glDisable(GL_FRAMEBUFFER_SRGB_EXT);
+               break;
+            case 'v': case 'V':
+               show_tex = !show_tex;
+               break;
+            case 'b': case 'B':
+               black_on_white = !black_on_white;
+               break;
+         }
+         break;
+
+      case STBWGE_mousemove:
+         raw_mouse_x = e->mx;
+         raw_mouse_y = e->my;
+         break;
+
+#if 0
+      case STBWGE_mousewheel:  do_mouse(e,0,0); break;
+      case STBWGE_leftdown:    do_mouse(e, 1,0); break;
+      case STBWGE_leftup:      do_mouse(e,-1,0); break;
+      case STBWGE_rightdown:   do_mouse(e,0, 1); break;
+      case STBWGE_rightup:     do_mouse(e,0,-1); break;
+#endif
+
+      case STBWGE_keydown:
+         if (e->key == VK_RIGHT) move[0] = 1;
+         if (e->key == VK_LEFT)  move[1] = 1;
+         if (e->key == VK_UP)    move[2] = 1;
+         if (e->key == VK_DOWN)  move[3] = 1;
+         break;
+      case STBWGE_keyup:
+         if (e->key == VK_RIGHT) move[0] = 0;
+         if (e->key == VK_LEFT)  move[1] = 0;
+         if (e->key == VK_UP)    move[2] = 0;
+         if (e->key == VK_DOWN)  move[3] = 0;
+         break;
+
+      case STBWGE_size:
+         sx = e->width;
+         sy = e->height;
+         loopmode(0,1,0);
+         break;
+
+      case STBWGE_draw:
+         if (initialized)
+            loopmode(0,1,0);
+         break;
+
+      default:
+         return STBWINGRAPH_unprocessed;
+   }
+   return 0;
+}
+
+void stbwingraph_main(void)
+{
+   stbwingraph_Priority(2);
+   stbwingraph_CreateWindow(1, winproc, NULL, "tt", SIZE_X,SIZE_Y, 0, 1, 0, 0);
+   stbwingraph_ShowCursor(NULL, 0);
+   load_fonts();
+   initialized = 1;
+   stbwingraph_MainLoop(loopmode, 0.016f);   // 30 fps = 0.33
+}
+