History

Refactoring and reformatting

Tom Szilagyi committed 6 years ago

Commit fa685731 parent 57c433a5 files · +599 −530Browse files

Showing the changes to src/charvdev.cc (1 of 5 files). Show all

Unified · Split

src/charvdev.cc+316−0
@@ -0,0 +1,316 @@
1/* This file is part of Zutty.
2 * Copyright (C) 2020 Tom Szilagyi
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * See the file LICENSE for the full license.
10 */
11
12#include "charvdev.h"
13
14#include <iostream>
15
16namespace {
17
18 static const char *computeShaderSource = R"(#version 310 es
19
20layout (local_size_x = 1, local_size_y = 1) in;
21layout (rgba32f, binding = 0) writeonly lowp uniform image2D imgOut;
22layout (binding = 1) uniform lowp sampler2D atlas;
23layout (binding = 2) uniform lowp sampler2D text;
24uniform lowp ivec2 glyphPixels;
25
26void main () {
27 vec3 color = vec3 (0.85, 0.85, 0.85);
28
29 ivec2 charPos = ivec2 (gl_GlobalInvocationID.xy);
30 ivec4 charData = ivec4 (texelFetch (text, charPos, 0) * 256.0);
31 ivec2 charCode = charData.xy; // .zw: attrs, colors
32 ivec2 atlasPos = charCode; // TODO lookup in atlas mapping
33
34 for (int j = 0; j < glyphPixels.x; j++) {
35 for (int k = 0; k < glyphPixels.y; k++) {
36 ivec2 txCoords = atlasPos * glyphPixels + ivec2 (j, k);
37 vec4 pixel = vec4 (color * texelFetch (atlas, txCoords, 0).r, 1.0);
38 ivec2 pxCoords = charPos * glyphPixels + ivec2 (j, k);
39 imageStore (imgOut, pxCoords, pixel);
40 }
41 }
42}
43)";
44
45 static const char *vertexShaderSource = R"(#version 310 es
46
47layout (location = 0) in vec2 pos;
48layout (location = 1) in lowp vec2 vertexTexCoord;
49
50out vec2 texCoord;
51
52void main () {
53 texCoord = vertexTexCoord;
54 gl_Position = vec4 (pos, 0.0, 1.0);
55}
56)";
57
58 static const char *fragmentShaderSource = R"(#version 310 es
59
60in highp vec2 texCoord;
61
62layout (rgba32f, binding = 0) readonly lowp uniform image2D imgOut;
63
64uniform highp vec2 viewPixels;
65
66layout (location = 0) out lowp vec4 outColor;
67
68void main () {
69 outColor = imageLoad (imgOut, ivec2 (texCoord * viewPixels));
70}
71)";
72
73
74 GLuint
75 createShader (GLuint type, const char* src, const char* name)
76 {
77 GLint stat;
78 GLuint shader = glCreateShader (type);
79 glShaderSource (shader, 1, &src, nullptr);
80 glCompileShader (shader);
81 glGetShaderiv (shader, GL_COMPILE_STATUS, &stat);
82 if (!stat) {
83 char log[1000];
84 GLsizei len;
85 glGetShaderInfoLog (shader, 1000, &len, log);
86 std::cerr << "Error compiling " << name << " shader:\n"
87 << log << std::endl;
88 exit (1);
89 }
90 return shader;
91 }
92
93 void
94 linkProgram (GLuint program, const char* name)
95 {
96 GLint stat;
97 glLinkProgram (program);
98 glGetProgramiv (program, GL_LINK_STATUS, &stat);
99 if (!stat) {
100 char log[1000];
101 GLsizei len;
102 glGetProgramInfoLog (program, 1000, &len, log);
103 std::cerr << "Error: linking " << name << " program:\n"
104 << log << std::endl;
105 exit (1);
106 }
107 }
108
109 void
110 setupTexture (GLuint target, GLuint& texture)
111 {
112 if (texture)
113 {
114 glDeleteTextures (1, &texture);
115 }
116 glGenTextures (1, &texture);
117 glActiveTexture (target);
118 glBindTexture (GL_TEXTURE_2D, texture);
119 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
120 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
121 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
122 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
123 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
124 }
125}
126
127namespace zutty {
128
129 CharVdev::CharVdev (const std::string& priFontPath,
130 const std::string& altFontPath)
131 : fnt (priFontPath)
132 {
133 createShaders ();
134
135 /*
136 * Setup draw program
137 */
138 glUseProgram (P_draw);
139
140 glDisable (GL_CULL_FACE);
141 glDisable (GL_DEPTH_TEST);
142 glEnable (GL_BLEND);
143 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
144 glCheckError ();
145
146 static const GLfloat verts[4][2] = {
147 { -1, 1 },
148 { 1, 1 },
149 { -1, -1 },
150 { 1, -1 }
151 };
152 static const GLfloat texCoords[4][2] = {
153 { 0, 0 },
154 { 1, 0 },
155 { 0, 1 },
156 { 1, 1 }
157 };
158 glVertexAttribPointer (A_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
159 glVertexAttribPointer (A_vertexTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
160 texCoords);
161 glCheckError ();
162
163 /*
164 * Setup compute program
165 */
166 glUseProgram (P_compute);
167 glUniform2i (compU_glyphPixels, fnt.getPx (), fnt.getPy ());
168 glCheckError ();
169
170 setupTexture (GL_TEXTURE1, T_atlas);
171 glTexImage2D (GL_TEXTURE_2D, 0, GL_RED,
172 fnt.getPx () * fnt.getNx (), fnt.getPy () * fnt.getNy (),
173 0, GL_RED, GL_UNSIGNED_BYTE, fnt.getAtlas ());
174 glCheckError ();
175 }
176
177 CharVdev::~CharVdev ()
178 {
179 }
180
181 void
182 CharVdev::resize (uint16_t pxWidth_, uint16_t pxHeight_)
183 {
184 if (pxWidth == pxWidth_ && pxHeight == pxHeight_)
185 return;
186
187 pxWidth = pxWidth_;
188 pxHeight = pxHeight_;
189 nCols = pxWidth / fnt.getPx ();
190 nRows = pxHeight / fnt.getPy ();
191
192 text_data = std::unique_ptr <uint8_t []> (new uint8_t [4 * nCols * nRows]);
193 memset (text_data.get (), 0, 4 * nCols * nRows);
194 for (uint16_t j = 0; j < nRows; ++j)
195 {
196 for (uint16_t k = 0; k < nCols; ++k)
197 {
198 text_data[4 * (j * nCols + k)] = k > 255 ? 0 : k;
199 text_data[4 * (j * nCols + k) + 1] = k > 255 ? 0 : j;
200 text_data[4 * (j * nCols + k) + 2] = 0; // color and
201 text_data[4 * (j * nCols + k) + 3] = 0; // attributes
202 }
203 }
204
205 std::cout << "resize to " << pxWidth << " x " << pxHeight
206 << " pixels, " << nCols << " x " << nRows << " chars"
207 << std::endl;
208
209 GLint viewWidth = nCols * fnt.getPx ();
210 GLint viewHeight = nRows * fnt.getPy ();
211 glViewport (0, pxHeight - viewHeight, viewWidth, viewHeight);
212
213 glUseProgram (P_draw);
214
215 glUniform2f (drawU_viewPixels, (GLfloat)viewWidth, (GLfloat)viewHeight);
216
217 glUseProgram (P_compute);
218
219 setupTexture (GL_TEXTURE0, T_output);
220 glTexStorage2D (GL_TEXTURE_2D, 1, GL_RGBA32F, viewWidth, viewHeight);
221 glBindImageTexture (0, T_output, 0, GL_FALSE, 0, GL_WRITE_ONLY,
222 GL_RGBA32F);
223 glCheckError ();
224
225 setupTexture (GL_TEXTURE2, T_text);
226 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, nCols, nRows, 0, GL_RGBA,
227 GL_UNSIGNED_BYTE, text_data.get ());
228 glCheckError ();
229 }
230
231 void
232 CharVdev::draw ()
233 {
234 {
235 uint16_t cRow = nRows - 1;
236 uint16_t cCol = nCols - 1;
237 uint32_t cnt = ++draw_count;
238 while (cnt)
239 {
240 uint32_t digit = (cnt % 10) + 18;
241 text_data[4 * (cRow * nCols + cCol)] = digit;
242 text_data[4 * (cRow * nCols + cCol) + 1] = 0;
243 cnt /= 10;
244 --cCol;
245 }
246 }
247
248 glUseProgram (P_compute);
249 glActiveTexture (GL_TEXTURE0);
250 glBindTexture (GL_TEXTURE_2D, T_output);
251 glActiveTexture (GL_TEXTURE1);
252 glBindTexture (GL_TEXTURE_2D, T_atlas);
253 glActiveTexture (GL_TEXTURE2);
254 glBindTexture (GL_TEXTURE_2D, T_text);
255 glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, nCols, nRows, GL_RGBA,
256 GL_UNSIGNED_BYTE, text_data.get ());
257 glCheckError ();
258
259 glDispatchCompute (nCols, nRows, 1);
260 glMemoryBarrier (GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
261 glCheckError ();
262
263 glUseProgram (P_draw);
264 glClear (GL_COLOR_BUFFER_BIT);
265
266 glActiveTexture (GL_TEXTURE0);
267 glBindTexture (GL_TEXTURE_2D, T_output);
268
269 glEnableVertexAttribArray (A_pos);
270 glEnableVertexAttribArray (A_vertexTexCoord);
271 glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
272 }
273
274 // private methods
275
276 void
277 CharVdev::createShaders ()
278 {
279 GLuint S_compute, S_fragment, S_vertex;
280
281 S_compute = createShader (GL_COMPUTE_SHADER, computeShaderSource,
282 "compute");
283 S_fragment = createShader (GL_FRAGMENT_SHADER, fragmentShaderSource,
284 "fragment");
285 S_vertex = createShader (GL_VERTEX_SHADER, vertexShaderSource,
286 "vertex");
287
288 P_compute = glCreateProgram ();
289 glAttachShader (P_compute, S_compute);
290 linkProgram (P_compute, "compute");
291 glUseProgram (P_compute);
292
293 compU_glyphPixels = glGetUniformLocation (P_compute, "glyphPixels");
294
295 std::cout << "compute program:"
296 << "\n uniform glyphPixels at " << compU_glyphPixels
297 << std::endl;
298
299 P_draw = glCreateProgram ();
300 glAttachShader (P_draw, S_fragment);
301 glAttachShader (P_draw, S_vertex);
302 linkProgram (P_draw, "draw");
303 glUseProgram (P_draw);
304
305 A_pos = glGetAttribLocation (P_draw, "pos");
306 A_vertexTexCoord = glGetAttribLocation (P_draw, "vertexTexCoord");
307 drawU_viewPixels = glGetUniformLocation (P_draw, "viewPixels");
308
309 std::cout << "draw program:"
310 << "\n attrib pos at " << A_pos
311 << "\n attrib vertexTexCoord at " << A_vertexTexCoord
312 << "\n uniform viewPixels at " << drawU_viewPixels
313 << std::endl;
314 }
315
316} // namespace zutty

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t