Selaa lähdekoodia

stbtt_Pack* documentation
oversample test tweaks

Sean Barrett 10 vuotta sitten
vanhempi
commit
22dbcffef7
5 muutettua tiedostoa jossa 145 lisäystä ja 40 poistoa
  1. 6 2
      stb_rect_pack.h
  2. 47 9
      stb_truetype.h
  3. 89 29
      tests/oversample/main.c
  4. BIN
      tests/oversample/oversample.exe
  5. 3 0
      tests/oversample/stb_wingraph.h

+ 6 - 2
stb_rect_pack.h

@@ -1,4 +1,4 @@
-// stb_rect_pack.h - v0.03 - public domain - rectangle packing
+// stb_rect_pack.h - v0.04 - public domain - rectangle packing
 // Sean Barrett 2014
 //
 // Useful for e.g. packing rectangular textures into an atlas.
@@ -19,7 +19,11 @@
 // Please note: better rectangle packers are welcome! Please
 // implement them to the same API, but with a different init
 // function.
-
+//
+// Version history:
+//
+//     0.04:  fixed minor bug in STBRP_LARGE_RECTS support
+//     0.01:  initial release
 
 //////////////////////////////////////////////////////////////////////////////
 //

+ 47 - 9
stb_truetype.h

@@ -1,4 +1,4 @@
-// stb_truetype.h - v0.99 - public domain
+// stb_truetype.h - v1.00 - public domain
 // authored from 2009-2014 by Sean Barrett / RAD Game Tools
 //
 //   This library processes TrueType files:
@@ -40,6 +40,7 @@
 //
 // VERSION HISTORY
 //
+//   1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
 //   0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
 //   0.9  (2014-08-07) support certain mac/iOS fonts without an MS platformID
 //   0.8b (2014-07-07) fix a warning
@@ -61,7 +62,7 @@
 //                    updated Hello World! sample to use kerning and subpixel
 //                    fixed some warnings
 //   0.3  (2009-06-24) cmap fmt=12, compound shapes (MM)
-//                    userdata, malloc-from-userdata, non-zero fill (STB)
+//                    userdata, malloc-from-userdata, non-zero fill (stb)
 //   0.2  (2009-03-11) Fix unsigned/signed char warnings
 //   0.1  (2009-03-09) First public release
 //
@@ -79,11 +80,18 @@
 //   before the #include of this file. This expands out the actual
 //   implementation into that C/C++ file.
 //
-//   Simple 3D API (don't ship this, but it's fine for tools and quick start,
-//                  and you can cut and paste from it to move to more advanced)
+//   Simple 3D API (don't ship this, but it's fine for tools and quick start)
 //           stbtt_BakeFontBitmap()               -- bake a font to a bitmap for use as texture
 //           stbtt_GetBakedQuad()                 -- compute quad to draw for a given char
 //
+//   Improved 3D API (more shippable):
+//           #include "stb_rect_pack.h"           -- optional, but you really want it
+//           stbtt_PackBegin()
+//           stbtt_PackSetOversample()            -- for improved quality on small fonts
+//           stbtt_PackFontRanges()
+//           stbtt_PackEnd()
+//           stbtt_GetPackedQuad()
+//
 //   "Load" a font file from a memory buffer (you have to keep the buffer loaded)
 //           stbtt_InitFont()
 //           stbtt_GetFontOffsetForIndex()        -- use for TTC font collections
@@ -484,21 +492,51 @@ typedef struct
 typedef struct stbtt_pack_context stbtt_pack_context;
 typedef struct
 {
-   float font_size;                     // if positive, pixel height; if negative, points
+   float font_size;
    int first_unicode_char_in_range;
    int num_chars_in_range;
    stbtt_packedchar *chardata_for_range; // output
 } stbtt_pack_range;
 
-extern int  stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context);
-// returns 0 if the allocations fail
+extern int  stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
+// Initializes a packing context stored in the passed-in stbtt_pack_context.
+// Future calls using this context will pack characters into the bitmap passed
+// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
+// the distance from one row to the next (or 0 to mean they are packed tightly
+// together). "padding" is // the amount of padding to leave between each
+// character (normally you want '1' for bitmaps you'll use as textures with
+// bilinear filtering).
+//
+// Returns 0 on failure, 1 on success.
 
-extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
 extern void stbtt_PackEnd  (stbtt_pack_context *spc);
-extern int  stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
+// Cleans up the packing context and frees all memory.
+
+extern int  stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float pixel_height,
                                 int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
+// Creates character bitmaps from the font_index'th font found in fontdata (use
+// font_index=0 if you don't know what that is). It creates num_chars_in_range
+// bitmaps for characters with unicode values starting at first_unicode_char_in_range
+// and increasing. Data for how to render them is stored in chardata_for_range;
+// pass these to stbtt_GetPackedQuad to get back renderable quads.
+
 extern int  stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
+// Creates character bitmaps from multiple ranges of characters stored in
+// ranges. This will usually create a better-packed bitmap than multiple
+// calls to stbtt_PackFontRange.
+
 
+extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
+// Oversampling a font increases the quality by allowing higher-quality subpixel
+// positioning, and is especially valuable at smaller text sizes.
+//
+// This function sets the amount of oversampling for all following calls to
+// stbtt_PackFontRange(s). The default (no oversampling) is achieved by
+// h_oversample=1, v_oversample=1. The total number of pixels required is
+// h_oversample*v_oversample larger than the default; for example, 2x2
+// oversampling requires 4x the storage of 1x1. For best results, render
+// oversampled textures with bilinear filtering. Look at the readme in
+// stb/tests/oversample for information about oversampled fonts
 
 extern void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph,  // same data as above
                                int char_index,             // character to display

+ 89 - 29
tests/oversample/main.c

@@ -2,11 +2,8 @@
 #include <assert.h>
 #include <ctype.h>
 
-#define STB_DEFINE
 #define STB_WINMAIN
-#define STB_NO_REGISTRY
 #include "stb_wingraph.h"
-#include "stb.h"
 
 #define STB_TRUETYPE_IMPLEMENTATION
 #define STB_RECT_PACK_IMPLEMENTATION
@@ -22,11 +19,12 @@
 #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[3][128];
+stbtt_packedchar chardata[6][128];
 
 int sx=SIZE_X, sy=SIZE_Y;
 
@@ -36,19 +34,40 @@ 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;
-   FILE *f = fopen("c:/windows/fonts/times.ttf", "rb");
-   if (!f) exit(0);
+   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);
-   stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[0]+32);
-   stbtt_PackSetOversampling(&pc, 2, 2);
-   stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[1]+32);
-   stbtt_PackSetOversampling(&pc, 3, 1);
-   stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[2]+32);
+   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);
@@ -58,6 +77,8 @@ void load_fonts(void)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 }
 
+int black_on_white;
+
 void draw_init(void)
 {
    glDisable(GL_CULL_FACE);
@@ -66,7 +87,10 @@ void draw_init(void)
    glDisable(GL_DEPTH_TEST);
 
    glViewport(0,0,sx,sy);
-   glClearColor(0,0,0,0);
+   if (black_on_white)
+      glClearColor(255,255,255,0);
+   else
+      glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT);
 
    glMatrixMode(GL_PROJECTION);
@@ -100,41 +124,64 @@ void print(float x, float y, int font, char *text)
    glEnd();
 }
 
-int font=0;
+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);
-   glColor3f(1,1,1);
 
-   if (font==1)
-      print(100, 50, font, "2x2 oversampled text at 1:1");
-   else if (font == 2)
-      print(100, 50, font, "3x1 oversampled text at 1:1");
-   else if (integer_align)
-      print(100, 50, font, "1:1 text, one texel = one pixel, snapped to integer coordinates");
+   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, 50, font, "1:1 text, one texel = one pixel");
+      print(100,210, sfont, "B: toggle to black-on-white");
+   print(100,235, sfont, "V: view font texture");
 
-   print(100, 80, font, "O: toggle oversampling");
-   print(100,105, font, "T: toggle translation");
-   print(100,130, font, "R: toggle rotation");
-   print(100,155, font, "P: toggle pixel-snap (only non-oversampled)");
-   print(100,180, font, "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,200, 200+BITMAP_W,200+BITMAP_H, 0,0,1,1);
+      drawBoxTC(200,400, 200+BITMAP_W,300+BITMAP_H, 0,0,1,1);
       glEnd();
    } else {
       glMatrixMode(GL_MODELVIEW);
-      glTranslatef(200,250,0);
+      glTranslatef(200,350,0);
 
       if (translating)
          x += fmod(translate_t*8,30);
@@ -198,7 +245,10 @@ int winproc(void *data, stbwingraph_event *e)
                return STBWINGRAPH_winproc_exit;
                break;
             case 'o': case 'O':
-               font = (font+1) % 3;
+               font = (font+1) % 3 + (font/3)*3;
+               break;
+            case 's': case 'S':
+               font = (font+3) % 6;
                break;
             case 't': case 'T':
                translating = !translating;
@@ -211,9 +261,19 @@ int winproc(void *data, stbwingraph_event *e)
             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;
 

BIN
tests/oversample/oversample.exe


+ 3 - 0
tests/oversample/stb_wingraph.h

@@ -791,6 +791,8 @@ void stbwingraph_SwapBuffers(void *win)
 #ifdef STB_WINMAIN    
 void stbwingraph_main(void);
 
+char *stb_wingraph_commandline;
+
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
    {
@@ -808,6 +810,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
       else if (strstr(buffer, " -full ") || strstr(buffer, " -fullscreen "))
          stbwingraph_request_fullscreen = TRUE;
    }
+   stb_wingraph_commandline = lpCmdLine;
 
    stbwingraph_DefineClass(hInstance, "appicon");
    stbwingraph_main();