glstuff

experiments with opengl2/ogles2/sdl
git clone http://frotz.net/git/glstuff.git
Log | Files | Refs

debugtext.cc (6417B)


      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 #include <string.h>
     20 #ifndef _WIN32
     21 #include <unistd.h>
     22 #endif
     23 
     24 #include "opengl.h"
     25 #include "util.h"
     26 #include "matrix.h"
     27 
     28 #include "debugtext.h"
     29 
     30 struct DebugTextCell {
     31 	unsigned char x;
     32 	unsigned char y;
     33 	unsigned char z;
     34 	unsigned char w;
     35 	unsigned char u;
     36 	unsigned char v;
     37 	unsigned char i;
     38 	unsigned char j;
     39 };
     40 
     41 static void dtc_init(DebugTextCell *data, int w, int h) {
     42 	int x, y;
     43 	DebugTextCell *p = data;
     44 	memset(p, 0, sizeof(DebugTextCell) * w * h * 6);
     45 	y = 1;
     46 	for (y = h; y > 0; y--) {
     47 		for (x = 0; x < w; x++) {
     48 			p->x = x+0; p->y = y+0;
     49 			p->u = 0;   p->v = 0;   p->i = x; p->j = h-y; p++;
     50 			p->x = x+0; p->y = y-1;
     51 			p->u = 0;   p->v = 1;   p->i = x; p->j = h-y; p++;
     52 			p->x = x+1; p->y = y-1;
     53 			p->u = 1;   p->v = 1;   p->i = x; p->j = h-y; p++;
     54 			p->x = x+1; p->y = y-1;
     55 			p->u = 1;   p->v = 1;   p->i = x; p->j = h-y; p++;
     56 			p->x = x+1; p->y = y+0;
     57 			p->u = 1;   p->v = 0;   p->i = x; p->j = h-y; p++;
     58 			p->x = x+0; p->y = y+0;
     59 			p->u = 0;   p->v = 0;   p->i = x; p->j = h-y; p++;
     60 		}
     61 	}
     62 }
     63 
     64 static const char *vsrc =
     65 "uniform mat4 uMVP;"
     66 "uniform sampler2D uTexture1;"
     67 "attribute vec4 aVertex;"
     68 "attribute vec4 aTexCoord;"
     69 ""
     70 "varying vec4 vTexCoord;"
     71 "const float cbw = 32.0;"
     72 "const float cbh = 32.0;"
     73 ""
     74 "void main() {"
     75 "        gl_Position = uMVP * vec4(aVertex.xy,0.0,1.0);"
     76 "        vTexCoord = aTexCoord;"
     77 "}";
     78 
     79 static const char *fsrc =
     80 "uniform sampler2D uTexture0;"
     81 "uniform sampler2D uTexture1;"
     82 ""
     83 "varying vec4 vTexCoord; /* u, v, cx, cy */"
     84 ""
     85 "/* width and height of the character buffer */"
     86 "const float cbw = 32.0;"
     87 "const float cbh = 32.0;"
     88 ""
     89 "/* cell count (h & v) for character map */"
     90 "const float cc = 16.0;"
     91 ""
     92 "void main() {"
     93 "	vec2 base, offset;"
     94 "	float ch;"
     95 ""
     96 "	/* look up characer in cbw x cbh character buffer texture */"
     97 "	ch = texture2D(uTexture1, vec2(vTexCoord.z / cbw, vTexCoord.w / cbh)).a"
     98 "		* 255.0 + 0.001953125;"
     99 ""
    100 "	/* base texcoord of ch (0..255) in cc x cc character map texture */"
    101 "	base = vec2(fract(ch / cc), -floor(ch / cc) / cc);"
    102 ""
    103 "	/* scale offset texcoord */"
    104 "	offset = vTexCoord.xy / cc;"
    105 ""
    106 "	gl_FragColor = texture2D(uTexture0, base + offset * vec2(1.0,-1.0));"
    107 "}";
    108 
    109 int DebugText::init(unsigned w, unsigned h) {
    110 	cbw = w;
    111 	cbh = h;
    112 	cx = 0;
    113 	cy = 0;
    114 	dirty = 0;
    115 
    116 	data = (DebugTextCell*) malloc(sizeof(DebugTextCell) * w * h * 6);
    117 	cbdata = (unsigned char*) malloc(sizeof(unsigned char) * w * h);
    118 
    119 	dtc_init(data, w, h);
    120 
    121 	if (!(fontdata = load_png_rgba("font-vincent-8x8.png", &fdw, &fdh, 1))) 
    122 		return -1;
    123 
    124 	if (pgm.compileStr(vsrc, fsrc))
    125 		return -1;
    126 
    127 	aVertex = pgm.getAttribID("aVertex");
    128 	aTexCoord = pgm.getAttribID("aTexCoord");
    129 	uMVP = pgm.getUniformID("uMVP");
    130 	uTex0 = pgm.getUniformID("uTexture0");
    131 	uTex1 = pgm.getUniformID("uTexture1");
    132 
    133 	glGenTextures(1, &tex0);
    134 	glGenTextures(1, &tex1);
    135 	
    136 	glBindTexture(GL_TEXTURE_2D, tex0);
    137 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fdw, fdh, 0, GL_RGBA,
    138 		GL_UNSIGNED_BYTE, fontdata);
    139 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    140 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    141 
    142 	memset(cbdata, 0, cbw * cbh);
    143 
    144 	glBindTexture(GL_TEXTURE_2D, tex1);
    145 	glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, cbw, cbh, 0, GL_ALPHA,
    146 		GL_UNSIGNED_BYTE, cbdata);
    147 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    148 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    149 
    150 	glGenBuffers(1, &vbo);
    151 	glBindBuffer(GL_ARRAY_BUFFER, vbo);
    152 	glBufferData(GL_ARRAY_BUFFER, sizeof(DebugTextCell) * cbw * cbh * 6,
    153 		data, GL_STATIC_DRAW);
    154 
    155 	return 0;
    156 }
    157 
    158 int DebugText::render(void) {
    159 	mat4 MVP;
    160 	MVP.setOrtho(0.0, cbw, 0.0, cbh, 1.0, -1.0);
    161 
    162 	pgm.use();
    163 
    164 	glActiveTexture(GL_TEXTURE0);
    165 	glBindTexture(GL_TEXTURE_2D, tex0);
    166 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    167 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    168 
    169 	glActiveTexture(GL_TEXTURE1);
    170 	glBindTexture(GL_TEXTURE_2D, tex1);
    171 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    172 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    173 
    174 	if (dirty) {
    175 		dirty = 0;
    176 		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, cbw, cbh, 0, GL_ALPHA,
    177 			GL_UNSIGNED_BYTE, cbdata);
    178 	}
    179 
    180 	glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP);
    181 	glUniform1i(uTex0, 0);
    182 	glUniform1i(uTex1, 1);
    183 
    184 	glEnable(GL_BLEND);
    185 	glDisable(GL_DEPTH_TEST);
    186 
    187 	glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);
    188 
    189 	glBindBuffer(GL_ARRAY_BUFFER, vbo);
    190 
    191 	glVertexAttribPointer(aVertex, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void*) 0);
    192 	glVertexAttribPointer(aTexCoord, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void*) 4);
    193 	
    194 	glEnableVertexAttribArray(aVertex);
    195 	glEnableVertexAttribArray(aTexCoord);
    196 
    197 	glDrawArrays(GL_TRIANGLES, 0, cbw * cbh * 6);
    198 	glDisableVertexAttribArray(aVertex);
    199 	glDisableVertexAttribArray(aTexCoord);
    200 
    201 	return 0;
    202 }
    203 
    204 void DebugText::putch(unsigned c) {
    205 	switch (c) {
    206 	case 10:
    207 		cx = 0;
    208 		if (cy < cbh - 1)
    209 			cy++;
    210 		return;
    211 	case 13:
    212 		return;
    213 	case 9:
    214 		c = ' ';
    215 		break;
    216 	}
    217 	cbdata[cx + cy * cbw] = c;
    218 
    219 	if (++cx == cbw) {
    220 		cx = 0;
    221 		if (++cy == cbh) {
    222 			cy = cbh - 1;
    223 		}
    224 	}
    225 
    226 	dirty = 1;
    227 }
    228 
    229 void DebugText::puts(const char *s) {
    230 	while (*s)
    231 		putch(*s++);
    232 }
    233 
    234 void DebugText::clear(void) {
    235 	memset(cbdata, 0, cbw * cbh);
    236 	cx = 0;
    237 	cy = 0;
    238 	dirty = 1;
    239 }
    240 
    241 void DebugText::printf(const char *fmt, ...) {
    242 	va_list ap;
    243 	char tmp[128];
    244 
    245 	va_start(ap, fmt);
    246 	vsnprintf(tmp, sizeof(tmp), fmt, ap);
    247 	va_end(ap);
    248 
    249 	puts(tmp);
    250 }
    251 
    252 #if 0
    253 DebugText DT;
    254 
    255 int scene_init(struct ctxt *c) {
    256 	glViewport(0, 0, c->width, c->height);
    257 	glClearColor(0, 0, 180, 255);
    258 	glClearDepth(1.0f);
    259 	DT.init(32, 32);
    260 	return 0;
    261 }
    262 
    263 int fr = 0;
    264 
    265 int scene_draw(struct ctxt *c) {
    266 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    267 	DT.printf("Frame #%d\n", fr++);
    268 	DT.render();
    269 	return 0;
    270 }
    271 #endif