glstuff

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit a27e8a2912c7ca968ef7db342f3e387a561a9d02
parent 07cb54873a82a023c14edbd94f7221f6c6f6e181
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue, 15 Jan 2013 23:03:10 -0800

add some code to generate and render signed distance field textures

Diffstat:
MMakefile | 14+++++++++-----
Amksdf.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest4.c | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest4.fragment.glsl | 11+++++++++++
Atest4.vertex.glsl | 10++++++++++
Atexture.sdf.png | 0
6 files changed, 252 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,22 +10,26 @@ LIBS := $(SDLLIBS) -lGL -lm -lpng COMMONOBJS := util.o sdlglue.o loadpng.o loadfile.o loadobj.o -all: test1 test2 test3 +all: test1 test2 test3 test4 mksdf -TEST1OBJS := test1.o $(COMMONOBJS) +mksdf: mksdf.c loadpng.c + gcc -g -Wall -o mksdf mksdf.c loadpng.c -lm -lpng +TEST1OBJS := test1.o $(COMMONOBJS) test1: $(TEST1OBJS) $(CC) -o test1 $(TEST1OBJS) $(LIBS) TEST2OBJS := test2.o $(COMMONOBJS) - test2: $(TEST2OBJS) $(CC) -o test2 $(TEST2OBJS) $(LIBS) TEST3OBJS := test3.o $(COMMONOBJS) - test3: $(TEST3OBJS) $(CC) -o test3 $(TEST3OBJS) $(LIBS) +TEST4OBJS := test4.o $(COMMONOBJS) +test4: $(TEST4OBJS) + $(CC) -o test4 $(TEST4OBJS) $(LIBS) + clean:: - rm -f test1 test2 test3 *.o + rm -f test1 test2 test3 test4 mksdf *.o diff --git a/mksdf.c b/mksdf.c @@ -0,0 +1,109 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <math.h> + +#include "util.h" + +unsigned char *tex; +unsigned tw, th; + +unsigned sample(int x, int y) { + if (x < 0) x = 0; + if (x >= tw) x = tw-1; + if (y < 0) y = 0; + if (y > th) y = th-1; + return tex[x + y * tw] >> 7; +} + +/* this is absurdly brute-force and clunky */ +unsigned distance(int cx, int cy, int d) { + int x, y; + float dn = d*d+1.0, t; + unsigned cs = sample(cx, cy); + unsigned r; + + for (y = cy - d; y <= cy + d; y++) { + for (x = cx - d; x <= cx + d; x++) { + if (sample(x, y) != cs) { + t = (cx-x)*(cx-x)+(cy-y)*(cy-y); + if (t < dn) dn = t; + } + } + } + + dn = sqrt(dn); + r = ((127.0 * dn) / ((float) d)); + if (r > 127) r = 127; + if (cs) + return 127 - r; + else + return 127 + r; +} + +/* for each texel in the output texture, find the distance from its + * corresponding texel in the input texture to the nearest pixel of + * the opposite color + */ +void generate(unsigned char *map, int mw, int mh, int d) { + int x, y; + int up = tw / mw; + int dn = up / 2; + for (y = 0; y < mh; y++) + for (x = 0; x < mh; x++) + map[y*mw+x] = distance(x * up + dn, y * up + dn, d); +} + +int main(int argc, char **argv) { + unsigned char *map; + unsigned mw, mh; + int x, y; + + if (argc < 2) { + fprintf(stderr,"usage: mksdf <pngfile> [ <size> ]\n"); + return -1; + } else if (argc < 3) { + mw = mh = 64; + } else { + mw = mh = atoi(argv[2]); + } + if (!(map = malloc(mw * mh))) { + fprintf(stderr,"out of memory\n"); + return -1; + } + + tex = load_png_gray(argv[1], &tw, &th); + if (!tex) { + fprintf(stderr,"cannot load source image '%s'\n", argv[1]); + return -1; + } + + generate(map, mw, mh, tw / mw); + + /* output an ascii PGM for now */ + printf("P2\n%d %d\n255\n", mw, mh); + for (y = mh - 1; y >= 0; y--) { + for (x = 0; x < mw; x++) + printf("%d ", map[y*mw + x]); + printf("\n"); + } + printf("\n"); + + return 0; +} + diff --git a/test4.c b/test4.c @@ -0,0 +1,113 @@ +/* Copyright 2013 Brian Swetland <swetland@frotz.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "util.h" +#include "glue.h" + +void *texdata; +unsigned texw, texh; + +const char *vert_src, *frag_src; + +GLuint pgm, vshd, fshd, tex0; +GLuint _vPosition, _vUV; +GLuint _uMVP, _uSampler; + +mat4 MVP; + +GLfloat verts[] = { + -1, -1, 0, + -1, 1, 0, + 1, -1, 0, + 1, 1, 0, + -0.5f, -0.5f, 0.0f, + -0.5f, 0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.5f, 0.5f, 0.0f, +}; + +GLfloat texcoords[] = { + 0.0, 0.0, + 0.0, 1.0, + 1.0, 0.0, + 1.0, 1.0, +}; + +int scene_init(struct ctxt *c) { + if (!(texdata = load_png_gray("texture.sdf.png", &texw, &texh))) + return -1; + if (!(vert_src = load_file("test4.vertex.glsl", 0))) + return -1; + if (!(frag_src = load_file("test4.fragment.glsl", 0))) + return -1; + + mtx_identity(MVP); + mtx_ortho(MVP, -1.333, 1.333, -1, 1, 1, -1); + + glViewport(0, 0, c->width, c->height); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0f); + + if (shader_compile(vert_src, frag_src, &pgm, &vshd, &fshd)) + return -1; + + _vPosition = glGetAttribLocation(pgm, "vPosition"); + _vUV = glGetAttribLocation(pgm, "vUV"); + _uMVP = glGetUniformLocation(pgm, "uMVP"); + _uSampler = glGetUniformLocation(pgm, "uSampler"); + + if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n"); + + glEnable(GL_TEXTURE_2D); +// glEnable(GL_BLEND); +// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glGenTextures(1, &tex0); + + glBindTexture(GL_TEXTURE_2D, tex0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texw, texh, 0, GL_ALPHA, + GL_UNSIGNED_BYTE, texdata); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + return 0; +} + +int scene_draw(struct ctxt *c) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glUseProgram(pgm); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex0); + + glUniformMatrix4fv(_uMVP, 1, GL_FALSE, (void*) MVP); + glUniform1i(_uSampler, 0); + + glVertexAttribPointer(_vPosition, 3, GL_FLOAT, GL_FALSE, 0, verts); + glEnableVertexAttribArray(_vPosition); + + glVertexAttribPointer(_vUV, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glEnableVertexAttribArray(_vUV); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + return 0; +} + diff --git a/test4.fragment.glsl b/test4.fragment.glsl @@ -0,0 +1,11 @@ +uniform sampler2D uSampler; +varying vec2 fUV; + +void main() { + float mask = texture2D(uSampler, fUV).a; + + if (mask < 0.5) + discard; + + gl_FragColor = vec4(1, 1, 0, 1); +} diff --git a/test4.vertex.glsl b/test4.vertex.glsl @@ -0,0 +1,10 @@ +uniform mat4 uMVP; +attribute vec4 vPosition; +attribute vec2 vUV; +varying vec2 fUV; + +void main() { + gl_Position = uMVP * vPosition; + fUV = vUV; +} + diff --git a/texture.sdf.png b/texture.sdf.png Binary files differ.