parent
a0a939058c
commit
3a1174060a
1 changed files with 184 additions and 0 deletions
@ -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; |
||||
} |
Loading…
Reference in New Issue