Jelajahi Sumber

opengl stb_truetype demo app

Sean Barrett 4 tahun lalu
induk
melakukan
3a1174060a
1 mengubah file dengan 184 tambahan dan 0 penghapusan
  1. 184 0
      tests/truetype_test_win32.c

+ 184 - 0
tests/truetype_test_win32.c

@@ -0,0 +1,184 @@
+// tested in VC6 (1998) and VS 2019
+#define _CRT_SECURE_NO_WARNINGS
+#define WIN32_MEAN_AND_LEAN
+#include <windows.h>
+
+#include <stdio.h>
+#include <tchar.h>
+
+#define STB_TRUETYPE_IMPLEMENTATION
+#include "stb_truetype.h"
+
+#include <gl/gl.h>
+#include <gl/glu.h>
+
+int screen_x=1024, screen_y=768;
+GLuint tex;
+
+unsigned char ttf_buffer[1<<20];
+unsigned char temp_bitmap[1024*1024];
+stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
+
+void init(void)
+{
+   fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
+   stbtt_BakeFontBitmap(ttf_buffer,0, 64.0, temp_bitmap,1024,1024, 32,96, cdata);
+   glGenTextures(1, &tex);
+   glBindTexture(GL_TEXTURE_2D, tex);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1024,1024,0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+}
+
+void print(float x, float y, char *text)
+{
+   // assume orthographic projection with units = screen pixels, origin at top left
+   glBindTexture(GL_TEXTURE_2D, tex);
+   glBegin(GL_QUADS);
+   while (*text) {
+      if (*text >= 32 && *text < 128) {
+         stbtt_aligned_quad q;
+         stbtt_GetBakedQuad(cdata, 1024,1024, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
+         glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
+         glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
+         glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
+         glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
+      }
+      ++text;
+   }
+   glEnd();
+}
+
+void draw(void)
+{
+   glViewport(0,0,screen_x,screen_y);
+   glClearColor(0.45f,0.45f,0.75f,0);
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glDisable(GL_CULL_FACE);
+   glDisable(GL_DEPTH_TEST);
+   glDisable(GL_BLEND);
+
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0,screen_x,screen_y,0,-1,1);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+
+   glEnable(GL_TEXTURE_2D);
+   glEnable(GL_BLEND);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   glColor3f(1,1,1);
+
+   print(100,150, "This is a simple test!");
+
+   // show font bitmap
+   glBegin(GL_QUADS);
+      glTexCoord2f(0,0); glVertex2f(256,200+0);
+      glTexCoord2f(1,0); glVertex2f(768,200+0);
+      glTexCoord2f(1,1); glVertex2f(768,200+512);
+      glTexCoord2f(0,1); glVertex2f(256,200+512);
+   glEnd();
+}
+
+///////////////////////////////////////////////////////////////////////
+///
+///
+///  Windows OpenGL setup
+///
+///
+
+HINSTANCE app;
+HWND  window;
+HGLRC rc;
+HDC   dc;
+
+#pragma comment(lib, "opengl32.lib")
+#pragma comment(lib, "glu32.lib")
+#pragma comment(lib, "winmm.lib")
+
+int mySetPixelFormat(HWND win)
+{
+   PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1, PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA };
+   int                   pixel_format;
+   pfd.dwLayerMask  = PFD_MAIN_PLANE;
+   pfd.cColorBits   = 24;
+   pfd.cAlphaBits   = 8;
+   pfd.cDepthBits   = 24;
+   pfd.cStencilBits = 8;
+   pixel_format = ChoosePixelFormat(dc, &pfd);
+   if (!pixel_format) return FALSE;
+   if (!DescribePixelFormat(dc, pixel_format, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
+      return FALSE;
+   SetPixelFormat(dc, pixel_format, &pfd);
+   return TRUE;
+}
+
+static int WINAPI WinProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+   switch (msg) {
+      case WM_CREATE: {
+         LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lparam;
+         dc = GetDC(wnd);
+         if (mySetPixelFormat(wnd)) {
+            rc = wglCreateContext(dc);
+            if (rc) {
+               wglMakeCurrent(dc, rc);
+               return 0;
+            }
+         }
+         return -1;
+      }
+
+      case WM_DESTROY:
+         wglMakeCurrent(NULL, NULL); 
+         if (rc) wglDeleteContext(rc);
+         PostQuitMessage (0);
+         return 0;
+
+      default:
+         return DefWindowProc (wnd, msg, wparam, lparam);
+   }
+
+   return DefWindowProc (wnd, msg, wparam, lparam);
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+   DWORD dwstyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+   WNDCLASSEX  wndclass;
+   wndclass.cbSize        = sizeof(wndclass);
+   wndclass.style         = CS_OWNDC;
+   wndclass.lpfnWndProc   = (WNDPROC) WinProc;
+   wndclass.cbClsExtra    = 0;
+   wndclass.cbWndExtra    = 0;
+   wndclass.hInstance     = hInstance;
+   wndclass.hIcon         = LoadIcon(hInstance, _T("appicon"));
+   wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
+   wndclass.hbrBackground = GetStockObject(NULL_BRUSH);
+   wndclass.lpszMenuName  = _T("truetype-test");
+   wndclass.lpszClassName = _T("truetype-test");
+   wndclass.hIconSm       = NULL;
+   app = hInstance;
+
+   if (!RegisterClassEx(&wndclass))
+      return 0;
+
+   window = CreateWindow(_T("truetype-test"), _T("truetype test"), dwstyle,
+                      CW_USEDEFAULT,0, screen_x, screen_y,
+                      NULL, NULL, app,  NULL);
+   ShowWindow(window, SW_SHOWNORMAL);
+   init();
+
+   for(;;) {
+      MSG msg;
+      if (GetMessage(&msg, NULL, 0, 0)) {
+         TranslateMessage(&msg);
+         DispatchMessage(&msg);
+      } else {
+         return 1;   // WM_QUIT
+      }
+      wglMakeCurrent(dc, rc);
+      draw();
+      SwapBuffers(dc);
+   }
+   return 0;
+}