glstuff

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

mksdf.cc (2282B)


      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 
     19 #include <math.h>
     20 
     21 #include "util.h"
     22 
     23 unsigned char *tex;
     24 unsigned tw, th;
     25 
     26 unsigned sample(int x, int y) {
     27 	if (x < 0) x = 0;
     28 	if (x >= tw) x = tw-1;
     29 	if (y < 0) y = 0;
     30 	if (y > th) y = th-1;
     31 	return tex[x + y * tw] >> 7;
     32 }
     33 
     34 /* this is absurdly brute-force and clunky */
     35 unsigned distance(int cx, int cy, int d) {
     36 	int x, y;
     37 	float dn = d*d+1.0, t; 
     38 	unsigned cs = sample(cx, cy);
     39 	unsigned r;
     40 
     41 	for (y = cy - d; y <= cy + d; y++) {
     42 		for (x = cx - d; x <= cx + d; x++) {
     43 			if (sample(x, y) != cs) {
     44 				t = (cx-x)*(cx-x)+(cy-y)*(cy-y);
     45 				if (t < dn) dn = t;
     46 			}
     47 		}
     48 	}
     49 
     50 	dn = sqrt(dn);
     51 	r = ((127.0 * dn) / ((float) d));
     52 	if (r > 127) r = 127;
     53 	if (cs) 
     54 		return 127 - r;
     55 	else
     56 		return 127 + r;
     57 }
     58 
     59 /* for each texel in the output texture, find the distance from its
     60  * corresponding texel in the input texture to the nearest pixel of
     61  * the opposite color 
     62  */
     63 void generate(unsigned char *map, int mw, int mh, int d) {
     64 	int x, y;
     65 	int up = tw / mw;
     66 	int dn = up / 2;
     67 	for (y = 0; y < mh; y++)
     68 		for (x = 0; x < mh; x++)
     69 			map[y*mw+x] = distance(x * up + dn, y * up + dn, d);
     70 }
     71 
     72 int main(int argc, char **argv) {
     73 	unsigned char *map;
     74 	unsigned mw, mh;
     75 
     76 	if (argc != 4) {
     77 		fprintf(stderr,"usage: mksdf <pngfile> <size> <outfile>\n");
     78 		return -1;
     79 	}
     80 
     81 	mw = mh = atoi(argv[2]);
     82 
     83 	if (!(map = (unsigned char*) malloc(mw * mh))) {
     84 		fprintf(stderr,"out of memory\n");
     85 		return -1;
     86 	}
     87 
     88 	tex = (unsigned char*) load_png_gray(argv[1], &tw, &th, 0);
     89 	if (!tex) {
     90 		fprintf(stderr,"cannot load source image '%s'\n", argv[1]);
     91 		return -1;
     92 	}
     93 
     94 	generate(map, mw, mh, tw / mw);
     95 
     96 	return save_png_gray(argv[3], map, mw, mh);
     97 }
     98