textgrid.cc (2845B)
1 /* Copyright 2013 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <stdarg.h> 19 20 #include "app.h" 21 #include "util.h" 22 #include "matrix.h" 23 #include "textgrid.h" 24 25 // idx, src, dst, count, offset, stride, divisor 26 static VertexAttrDesc layout[] = { 27 { 0, SRC_FLOAT, DST_FLOAT, 2, 0, 16, 0 }, 28 { 1, SRC_FLOAT, DST_FLOAT, 2, 8, 16, 0 }, 29 { 2, SRC_UINT8, DST_INTEGER, 4, 0, 4, 1 }, 30 }; 31 32 static float unit_box_2d[] = { 33 0, 0, 0, 0, 34 0, 1, 0, 1, 35 1, 1, 1, 1, 36 1, 1, 1, 1, 37 1, 0, 1, 0, 38 0, 0, 0, 0, 39 }; 40 41 void TextGrid::resize(int columns, int rows) { 42 width = columns; 43 height = rows; 44 dirty = 1; 45 46 // TODO: bring existing character data to new grid 47 48 if (grid) 49 delete[] grid; 50 grid = new unsigned[width * height * 4]; 51 clear(); 52 } 53 54 int TextGrid::init(int cellw, int cellh, int columns, int rows) { 55 VertexBuffer *data[] = { 56 &vtx, 57 &vtx, 58 &cbuf, 59 }; 60 float box_2d[4 * 6]; 61 62 grid = nullptr; 63 resize(columns, rows); 64 65 // scale quad to character cell and texture cell size 66 for (int n = 0; n < (4 * 6); n += 4) { 67 box_2d[n + 0] = unit_box_2d[n + 0] * float(cellw); 68 box_2d[n + 1] = unit_box_2d[n + 1] * float(cellh); 69 box_2d[n + 2] = unit_box_2d[n + 2] * (1.0f / 16.0f); 70 box_2d[n + 3] = unit_box_2d[n + 3] * (1.0f / 16.0f); 71 } 72 73 if (texture.load("font-vincent-8x8.png", 0)) 74 return -1; 75 if (!(effect = Effect::load("textgrid"))) 76 return -1; 77 78 vtx.load(box_2d, sizeof(box_2d)); 79 cbuf.load(grid, width * height * sizeof(unsigned)); 80 attr.init(layout, data, sizeof(layout) / sizeof(layout[0])); 81 82 color = 0xFFFFFF00; 83 return 0; 84 } 85 86 void TextGrid::setColor(unsigned rgba) { 87 color = rgba << 8; 88 } 89 90 void TextGrid::render(void) { 91 if (dirty) { 92 dirty = 0; 93 cbuf.load(grid, width * height * sizeof(unsigned)); 94 } 95 attr.use(); 96 texture.use(0); 97 effect->apply(); 98 glDrawArraysInstanced(GL_TRIANGLES, 0, 6, width * height); 99 } 100 101 void TextGrid::clear(void) { 102 memset(grid, 0, width * height * sizeof(unsigned)); 103 } 104 105 void TextGrid::printf(int x, int y, const char *fmt, ...) { 106 char buf[128]; 107 int len; 108 va_list ap; 109 va_start(ap, fmt); 110 len = vsnprintf(buf, sizeof(buf), fmt, ap); 111 va_end(ap); 112 buf[127] = 0; 113 if (len > 127) len = 127; 114 if (y < 0) y = height + y; 115 for (int n = 0; n < len; n++) { 116 grid[y * width + x + n] = buf[n] | color; 117 } 118 dirty = 1; 119 }