Line data Source code
1 : //
2 : // Copyright (c) 2009-2013 Mikko Mononen memon@inside.org
3 : //
4 : // This software is provided 'as-is', without any express or implied
5 : // warranty. In no event will the authors be held liable for any damages
6 : // arising from the use of this software.
7 : // Permission is granted to anyone to use this software for any purpose,
8 : // including commercial applications, and to alter it and redistribute it
9 : // freely, subject to the following restrictions:
10 : // 1. The origin of this software must not be misrepresented; you must not
11 : // claim that you wrote the original software. If you use this software
12 : // in a product, an acknowledgment in the product documentation would be
13 : // appreciated but is not required.
14 : // 2. Altered source versions must be plainly marked as such, and must not be
15 : // misrepresented as being the original software.
16 : // 3. This notice may not be removed or altered from any source distribution.
17 : //
18 : #ifndef GLFONTSTASH_H
19 : #define GLFONTSTASH_H
20 :
21 : FONScontext* glfonsCreate(int width, int height, int flags);
22 : void glfonsDelete(FONScontext* ctx);
23 :
24 : unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
25 :
26 : #endif
27 :
28 : #ifdef GLFONTSTASH_IMPLEMENTATION
29 :
30 : struct GLFONScontext {
31 : GLuint tex;
32 : int width, height;
33 : };
34 : typedef struct GLFONScontext GLFONScontext;
35 :
36 6584 : static int glfons__renderCreate(void* userPtr, int width, int height)
37 : {
38 : GLFONScontext* gl = (GLFONScontext*)userPtr;
39 : // Create may be called multiple times, delete existing texture.
40 6584 : if (gl->tex != 0) {
41 0 : glDeleteTextures(1, &gl->tex);
42 0 : gl->tex = 0;
43 : }
44 6584 : glGenTextures(1, &gl->tex);
45 6584 : if (!gl->tex) return 0;
46 6584 : gl->width = width;
47 6584 : gl->height = height;
48 6584 : glBindTexture(GL_TEXTURE_2D, gl->tex);
49 6584 : glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gl->width, gl->height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
50 6584 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
51 6584 : return 1;
52 : }
53 :
54 0 : static int glfons__renderResize(void* userPtr, int width, int height)
55 : {
56 : // Reuse create to resize too.
57 0 : return glfons__renderCreate(userPtr, width, height);
58 : }
59 :
60 13243 : static void glfons__renderUpdate(void* userPtr, int* rect, const unsigned char* data)
61 : {
62 : GLFONScontext* gl = (GLFONScontext*)userPtr;
63 13243 : int w = rect[2] - rect[0];
64 13243 : int h = rect[3] - rect[1];
65 :
66 13243 : if (gl->tex == 0) return;
67 13243 : glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
68 13243 : glBindTexture(GL_TEXTURE_2D, gl->tex);
69 13243 : glPixelStorei(GL_UNPACK_ALIGNMENT,1);
70 13243 : glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->width);
71 13243 : glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect[0]);
72 13243 : glPixelStorei(GL_UNPACK_SKIP_ROWS, rect[1]);
73 13243 : glTexSubImage2D(GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, GL_ALPHA,GL_UNSIGNED_BYTE, data);
74 13243 : glPopClientAttrib();
75 : }
76 :
77 1083244 : static void glfons__renderDraw(void* userPtr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts)
78 : {
79 : GLFONScontext* gl = (GLFONScontext*)userPtr;
80 1083244 : if (gl->tex == 0) return;
81 1083244 : glBindTexture(GL_TEXTURE_2D, gl->tex);
82 1083244 : glEnable(GL_TEXTURE_2D);
83 1083244 : glEnableClientState(GL_VERTEX_ARRAY);
84 1083244 : glEnableClientState(GL_TEXTURE_COORD_ARRAY);
85 1083244 : glEnableClientState(GL_COLOR_ARRAY);
86 :
87 1083244 : glVertexPointer(2, GL_FLOAT, sizeof(float)*2, verts);
88 1083244 : glTexCoordPointer(2, GL_FLOAT, sizeof(float)*2, tcoords);
89 1083244 : glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(unsigned int), colors);
90 :
91 1083244 : glDrawArrays(GL_TRIANGLES, 0, nverts);
92 :
93 1083244 : glDisable(GL_TEXTURE_2D);
94 1083244 : glDisableClientState(GL_VERTEX_ARRAY);
95 1083244 : glDisableClientState(GL_TEXTURE_COORD_ARRAY);
96 1083244 : glDisableClientState(GL_COLOR_ARRAY);
97 : }
98 :
99 6568 : static void glfons__renderDelete(void* userPtr)
100 : {
101 : GLFONScontext* gl = (GLFONScontext*)userPtr;
102 6568 : if (gl->tex != 0)
103 6568 : glDeleteTextures(1, &gl->tex);
104 : gl->tex = 0;
105 6568 : free(gl);
106 6568 : }
107 :
108 :
109 6584 : FONScontext* glfonsCreate(int width, int height, int flags)
110 : {
111 : FONSparams params;
112 : GLFONScontext* gl;
113 :
114 6584 : gl = (GLFONScontext*)malloc(sizeof(GLFONScontext));
115 6584 : if (gl == NULL) goto error;
116 : memset(gl, 0, sizeof(GLFONScontext));
117 :
118 : memset(¶ms, 0, sizeof(params));
119 6584 : params.width = width;
120 6584 : params.height = height;
121 6584 : params.flags = (unsigned char)flags;
122 6584 : params.renderCreate = glfons__renderCreate;
123 6584 : params.renderResize = glfons__renderResize;
124 6584 : params.renderUpdate = glfons__renderUpdate;
125 6584 : params.renderDraw = glfons__renderDraw;
126 6584 : params.renderDelete = glfons__renderDelete;
127 6584 : params.userPtr = gl;
128 :
129 6584 : return fonsCreateInternal(¶ms);
130 :
131 : error:
132 : if (gl != NULL) free(gl);
133 0 : return NULL;
134 : }
135 :
136 22130 : void glfonsDelete(FONScontext* ctx)
137 : {
138 22130 : fonsDeleteInternal(ctx);
139 22130 : }
140 :
141 1083244 : unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
142 : {
143 1083244 : return (r) | (g << 8) | (b << 16) | (a << 24);
144 : }
145 :
146 : #endif
|