glstuff

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

commit 929695158eb80dd1a6f6dc40c100ef1292a58f9e
parent c9a7313e2dee40dc47518e1c2a4d72960131c48d
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon, 28 Jan 2013 22:34:18 -0800

CPLUSPLUS ALL THE THINGS!

Diffstat:
MMakefile | 37++++++++++++-------------------------
DProgram.cc | 36------------------------------------
Dextensions.c | 58----------------------------------------------------------
Mglue.h | 7-------
Rloadfile.c -> loadfile.cc | 0
Dloadobj.c | 239-------------------------------------------------------------------------------
Aloadobj.cc | 239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dloadpng.c | 121-------------------------------------------------------------------------------
Aloadpng.cc | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmatrix.h | 2++
Dmksdf.c | 99-------------------------------------------------------------------------------
Amksdf.cc | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprogram.cc | 36++++++++++++++++++++++++++++++++++++
RProgram.h -> program.h | 0
Dsavepng.c | 86-------------------------------------------------------------------------------
Asavepng.cc | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsdlglue.c | 210-------------------------------------------------------------------------------
Asdlglue.cc | 210+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest1.c | 109-------------------------------------------------------------------------------
Atest1.cc | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest2.c | 158-------------------------------------------------------------------------------
Atest2.cc | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest3.c | 122-------------------------------------------------------------------------------
Atest3.cc | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest4.c | 154-------------------------------------------------------------------------------
Atest4.cc | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dutil.c | 169-------------------------------------------------------------------------------
Mutil.h | 51---------------------------------------------------
28 files changed, 1277 insertions(+), 1644 deletions(-)

diff --git a/Makefile b/Makefile @@ -9,36 +9,23 @@ CFLAGS := $(SDLFLAGS) -DWITH_SDL2=0 -Wall -g -O2 CXXFLAGS := $(CFLAGS) LIBS := $(SDLLIBS) -lGL -lm -lpng -COMMONOBJS := util.o sdlglue.o loadpng.o loadfile.o loadobj.o +COMMONOBJS := sdlglue.o loadpng.o loadfile.o loadobj.o program.o matrix.o -all: test1 test2 test3 test4 test5 mksdf test2d +all:: everything -mksdf: mksdf.c loadpng.c savepng.c - gcc -g -Wall -o mksdf mksdf.c loadpng.c savepng.c -lm -lpng +APPS := test1 test2 test3 test4 test5 test2d -TEST1OBJS := test1.o $(COMMONOBJS) -test1: $(TEST1OBJS) - $(CC) -o test1 $(TEST1OBJS) $(LIBS) +define build-test +$1: $1.o $(COMMONOBJS) + $(CC) -o $1 $1.o $(COMMONOBJS) $(LIBS) +endef -TEST2OBJS := test2.o $(COMMONOBJS) -test2: $(TEST2OBJS) - $(CC) -o test2 $(TEST2OBJS) $(LIBS) +$(foreach t,$(APPS),$(eval $(call build-test,$t))) -TEST2DOBJS := test2d.o $(COMMONOBJS) matrix.o -test2d: $(TEST2DOBJS) - $(CC) -o test2d $(TEST2DOBJS) $(LIBS) +mksdf: mksdf.o loadpng.o savepng.o + $(CC) -o mksdf mksdf.o loadpng.o savepng.o $(LIBS) -TEST3OBJS := test3.o $(COMMONOBJS) -test3: $(TEST3OBJS) - $(CC) -o test3 $(TEST3OBJS) $(LIBS) - -TEST4OBJS := test4.o $(COMMONOBJS) -test4: $(TEST4OBJS) - $(CC) -o test4 $(TEST4OBJS) $(LIBS) - -TEST5OBJS := test5.o $(COMMONOBJS) matrix.o -test5: $(TEST5OBJS) - $(CC) -o test5 $(TEST5OBJS) $(LIBS) +everything: $(APPS) mksdf clean:: - rm -f test1 test2 test3 test4 test5 mksdf test2d *.o + rm -f $(APPS) mksdf *.o diff --git a/Program.cc b/Program.cc @@ -1,36 +0,0 @@ -/* 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 "glue.h" -#include "util.h" -#include "Program.h" - -Program::Program() : vsrc(NULL), fsrc(NULL), status(-1) { -} - -int Program::compile(const char *vfn, const char *ffn) { - if (!(vsrc = (char*) load_file(vfn, 0))) - return -1; - if (!(fsrc = (char*) load_file(ffn, 0))) - return -1; - if (shader_compile(vsrc, fsrc, &pobj, &vobj, &fobj)) - return -1; - status = 0; - return 0; -} - diff --git a/extensions.c b/extensions.c @@ -1,58 +0,0 @@ - -/* not needed for linux */ - -static PFNGLATTACHOBJECTARBPROC glAttachObjectARB; -static PFNGLCOMPILESHADERARBPROC glCompileShaderARB; -static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB; -static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB; -static PFNGLDELETEOBJECTARBPROC glDeleteObjectARB; -static PFNGLGETINFOLOGARBPROC glGetInfoLogARB; -static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; -static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB; -static PFNGLLINKPROGRAMARBPROC glLinkProgramARB; -static PFNGLSHADERSOURCEARBPROC glShaderSourceARB; -static PFNGLUNIFORM1IARBPROC glUniform1iARB; -static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB; - -#define EFUNC(n) { (void**) &n, #n } - -#if !WITH_SDL2 -int SDL_GL_ExtensionSupported(const char *name) { - if (strstr((char*)glGetString(GL_EXTENSIONS), name)) - return 1; - else - return 0; -} -#endif - -struct { - void **func; - const char *name; -} fntb[] = { - EFUNC(glAttachObjectARB), - EFUNC(glCompileShaderARB), - EFUNC(glCreateProgramObjectARB), - EFUNC(glCreateShaderObjectARB), - EFUNC(glDeleteObjectARB), - EFUNC(glGetInfoLogARB), - EFUNC(glGetObjectParameterivARB), - EFUNC(glGetUniformLocationARB), - EFUNC(glLinkProgramARB), - EFUNC(glShaderSourceARB), - EFUNC(glUniform1iARB), - EFUNC(glUseProgramObjectARB), -}; - -void glsl_init(void) { - int n; - if (!SDL_GL_ExtensionSupported("GL_ARB_shader_objects") || - !SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") || - !SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") || - !SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) - die("missing glsl extensions"); - for (n = 0; n < sizeof(fntb)/sizeof(fntb[0]); n++) { - *fntb[n].func = SDL_GL_GetProcAddress(fntb[n].name); - if (!(*fntb[n].func)) - die("cannot find func '%s'", fntb[n].name); - } -} diff --git a/glue.h b/glue.h @@ -20,10 +20,6 @@ #include <SDL_opengl.h> -#ifdef __cplusplus -extern "C" { -#endif - struct ctxt { unsigned width; unsigned height; @@ -36,7 +32,4 @@ int scene_draw(struct ctxt *c); int shader_compile(const char *vshader, const char *fshader, GLuint *pgm, GLuint *vshd, GLuint *fshd); -#ifdef __cplusplus -} -#endif #endif diff --git a/loadfile.c b/loadfile.cc diff --git a/loadobj.c b/loadobj.c @@ -1,239 +0,0 @@ -/* 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 <string.h> - -#include "util.h" - -struct v3 { - float x; - float y; - float z; -}; - -struct v2 { - float u; - float v; -}; - -struct i3 { - unsigned v; - unsigned vt; - unsigned vn; -}; - -struct obj { - struct v3 *v; - struct v3 *vn; - struct v2 *vt; - struct i3 *f; - unsigned max_v, num_v; - unsigned max_vn, num_vn; - unsigned max_vt, num_vt; - unsigned max_f, num_f; -}; - -static void obj_destroy(struct obj *o) { - if (o->v) free(o->v); - if (o->vn) free(o->vn); - if (o->vt) free(o->vt); - if (o->f) free(o->f); - free(o); -} - -static void *resize(void *array, unsigned *max, unsigned esz) { - void *tmp; - unsigned n = *max ? *max * 2 : 32; - tmp = realloc(array, esz * n); - if (!tmp) - free(array); - *max = n; - return tmp; -} - -static int obj_add_v(struct obj *o, float x, float y, float z) { - unsigned n = o->num_v; - if (n == o->max_v) - if(!(o->v = resize(o->v, &o->max_v, sizeof(struct v3)))) - return -1; - o->v[n].x = x; - o->v[n].y = y; - o->v[n].z = z; - o->num_v = n + 1; - return 0; -} - -static int obj_add_vn(struct obj *o, float x, float y, float z) { - unsigned n = o->num_vn; - if (n == o->max_vn) - if(!(o->vn = resize(o->vn, &o->max_vn, sizeof(struct v3)))) - return -1; - o->vn[n].x = x; - o->vn[n].y = y; - o->vn[n].z = z; - o->num_vn = n + 1; - return 0; -} - -static int obj_add_vt(struct obj *o, float u, float v) { - unsigned n = o->num_vt; - if (n == o->max_vt) - if(!(o->vt = resize(o->vt, &o->max_vt, sizeof(struct v3)))) - return -1; - o->vt[n].u = u; - o->vt[n].v = v; - o->num_vt = n + 1; - return 0; -} - -static int obj_add_f(struct obj *o, int v, int vt, int vn) { - unsigned n = o->num_f; - if (n == o->max_f) - if(!(o->f = resize(o->f, &o->max_f, sizeof(struct v3)))) - return -1; - - /* XXX: range check */ - v -= 1; - vt -= 1; - vn -= 1; - - o->f[n].v = v; - o->f[n].vt = vt; - o->f[n].vn = vn; - o->num_f = n + 1; - return 0; -} - -struct obj *load_obj(const char *fn) { - char buf[128]; - FILE *fp; - struct obj *o; - float x, y, z; - int a, b, c; - - if (!(fp = fopen(fn, "r"))) - goto exit; - - o = malloc(sizeof(struct obj)); - if (!o) - goto close_and_exit; - memset(o, 0, sizeof(struct obj)); - - while (fgets(buf, sizeof(buf), fp) != 0) { - if (!strncmp(buf, "v ", 2)) { - sscanf(buf + 2, "%f %f %f", &x, &y, &z); - obj_add_v(o, x, y, z); - } else if (!strncmp(buf, "vn ", 3)) { - sscanf(buf + 3, "%f %f %f", &x, &y, &z); - obj_add_vn(o, x, y, z); - } else if (!strncmp(buf, "vt ", 3)) { - sscanf(buf + 3, "%f %f", &x, &y); - obj_add_vt(o, x, y); - } else if (!strncmp(buf, "f ", 2)) { - char *tmp = buf + 2; - /* XXX: handle non-triangles */ - while (sscanf(tmp, "%d/%d/%d", &a, &b, &c) == 3) { - obj_add_f(o, a, b, c); - tmp = strstr(tmp, " "); - if (!tmp) break; - tmp++; - } - } else { -// fprintf(stderr,"ignoring: %s", buf); - } - } - -close_and_exit: - fclose(fp); -exit: - return o; -} - -static struct model *obj_to_model(struct obj *o) { - int i, j, n; - struct model *m; - - if(!(m = malloc(sizeof(struct model)))) - return 0; - memset(m, 0, sizeof(struct model)); - - if (!(m->vdata = malloc(sizeof(float) * 8 * o->num_f))) { - free(m); - return 0; - } - if (!(m->idx = malloc(sizeof(short) * o->num_f))) { - free(m->vdata); - free(m); - return 0; - } - - for (n = 0, i = 0; i < o->num_f; i++) { - float data[8]; - data[0] = o->v[o->f[i].v].x; - data[1] = o->v[o->f[i].v].y; - data[2] = o->v[o->f[i].v].z; - data[3] = o->vn[o->f[i].vn].x; - data[4] = o->vn[o->f[i].vn].y; - data[5] = o->vn[o->f[i].vn].z; - data[6] = o->vt[o->f[i].vt].u; - data[7] = o->vt[o->f[i].vt].v; - for (j = 0; j < n; j++) - if (!memcmp(data, &m->vdata[8 * j], sizeof(float) * 8)) - goto found_it; - memcpy(&m->vdata[8 * j], data, sizeof(float) * 8); - n++; -found_it: - m->idx[i] = j; - } - - m->vcount = n; - m->icount = o->num_f; - - return m; -} - -#if 0 -void model_dump(struct model *m, FILE *fp) { - int i; - fprintf(fp, "struct model M = {\n"); - fprintf(fp, " .vdata = {\n"); - for (i = 0; i < m->vcount; i++) - fprintf(fp, " %f, %f, %f,\n %f, %f, %f, %f, %f,\n", - m->vdata[i*8+0], m->vdata[i*8+1], - m->vdata[i*8+2], m->vdata[i*8+3], - m->vdata[i*8+4], m->vdata[i*8+5], - m->vdata[i*8+6], m->vdata[i*8+7]); - fprintf(fp, " },\n .idx[] = {\n"); - for (i = 0; i < m->icount; i += 3) - fprintf(fp, " %d, %d, %d,\n", - m->idx[i+0], m->idx[i+1], m->idx[i+2]); - fprintf(fp, " },\n .vcount = %d,\n .icount = %d,\n};\n", - m->vcount, m->icount); -} -#endif - -struct model *load_wavefront_obj(const char *fn) { - struct obj *o; - struct model *m; - o = load_obj(fn); - if (!o) - return 0; - m = obj_to_model(o); - obj_destroy(o); - return m; -} - diff --git a/loadobj.cc b/loadobj.cc @@ -0,0 +1,239 @@ +/* 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 <string.h> + +#include "util.h" + +struct v3 { + float x; + float y; + float z; +}; + +struct v2 { + float u; + float v; +}; + +struct i3 { + unsigned v; + unsigned vt; + unsigned vn; +}; + +struct obj { + struct v3 *v; + struct v3 *vn; + struct v2 *vt; + struct i3 *f; + unsigned max_v, num_v; + unsigned max_vn, num_vn; + unsigned max_vt, num_vt; + unsigned max_f, num_f; +}; + +static void obj_destroy(struct obj *o) { + if (o->v) free(o->v); + if (o->vn) free(o->vn); + if (o->vt) free(o->vt); + if (o->f) free(o->f); + free(o); +} + +static void *resize(void *array, unsigned *max, unsigned esz) { + void *tmp; + unsigned n = *max ? *max * 2 : 32; + tmp = realloc(array, esz * n); + if (!tmp) + free(array); + *max = n; + return tmp; +} + +static int obj_add_v(struct obj *o, float x, float y, float z) { + unsigned n = o->num_v; + if (n == o->max_v) + if(!(o->v = (v3*) resize(o->v, &o->max_v, sizeof(struct v3)))) + return -1; + o->v[n].x = x; + o->v[n].y = y; + o->v[n].z = z; + o->num_v = n + 1; + return 0; +} + +static int obj_add_vn(struct obj *o, float x, float y, float z) { + unsigned n = o->num_vn; + if (n == o->max_vn) + if(!(o->vn = (v3*) resize(o->vn, &o->max_vn, sizeof(struct v3)))) + return -1; + o->vn[n].x = x; + o->vn[n].y = y; + o->vn[n].z = z; + o->num_vn = n + 1; + return 0; +} + +static int obj_add_vt(struct obj *o, float u, float v) { + unsigned n = o->num_vt; + if (n == o->max_vt) + if(!(o->vt = (v2*) resize(o->vt, &o->max_vt, sizeof(struct v3)))) + return -1; + o->vt[n].u = u; + o->vt[n].v = v; + o->num_vt = n + 1; + return 0; +} + +static int obj_add_f(struct obj *o, int v, int vt, int vn) { + unsigned n = o->num_f; + if (n == o->max_f) + if(!(o->f = (i3*) resize(o->f, &o->max_f, sizeof(struct v3)))) + return -1; + + /* XXX: range check */ + v -= 1; + vt -= 1; + vn -= 1; + + o->f[n].v = v; + o->f[n].vt = vt; + o->f[n].vn = vn; + o->num_f = n + 1; + return 0; +} + +struct obj *load_obj(const char *fn) { + char buf[128]; + FILE *fp; + struct obj *o = 0; + float x, y, z; + int a, b, c; + + if (!(fp = fopen(fn, "r"))) + goto exit; + + o = (obj*) malloc(sizeof(struct obj)); + if (!o) + goto close_and_exit; + memset(o, 0, sizeof(struct obj)); + + while (fgets(buf, sizeof(buf), fp) != 0) { + if (!strncmp(buf, "v ", 2)) { + sscanf(buf + 2, "%f %f %f", &x, &y, &z); + obj_add_v(o, x, y, z); + } else if (!strncmp(buf, "vn ", 3)) { + sscanf(buf + 3, "%f %f %f", &x, &y, &z); + obj_add_vn(o, x, y, z); + } else if (!strncmp(buf, "vt ", 3)) { + sscanf(buf + 3, "%f %f", &x, &y); + obj_add_vt(o, x, y); + } else if (!strncmp(buf, "f ", 2)) { + char *tmp = buf + 2; + /* XXX: handle non-triangles */ + while (sscanf(tmp, "%d/%d/%d", &a, &b, &c) == 3) { + obj_add_f(o, a, b, c); + tmp = strstr(tmp, " "); + if (!tmp) break; + tmp++; + } + } else { +// fprintf(stderr,"ignoring: %s", buf); + } + } + +close_and_exit: + fclose(fp); +exit: + return o; +} + +static struct model *obj_to_model(struct obj *o) { + int i, j, n; + struct model *m; + + if(!(m = (model*) malloc(sizeof(struct model)))) + return 0; + memset(m, 0, sizeof(struct model)); + + if (!(m->vdata = (float*) malloc(sizeof(float) * 8 * o->num_f))) { + free(m); + return 0; + } + if (!(m->idx = (unsigned short *) malloc(sizeof(short) * o->num_f))) { + free(m->vdata); + free(m); + return 0; + } + + for (n = 0, i = 0; i < o->num_f; i++) { + float data[8]; + data[0] = o->v[o->f[i].v].x; + data[1] = o->v[o->f[i].v].y; + data[2] = o->v[o->f[i].v].z; + data[3] = o->vn[o->f[i].vn].x; + data[4] = o->vn[o->f[i].vn].y; + data[5] = o->vn[o->f[i].vn].z; + data[6] = o->vt[o->f[i].vt].u; + data[7] = o->vt[o->f[i].vt].v; + for (j = 0; j < n; j++) + if (!memcmp(data, &m->vdata[8 * j], sizeof(float) * 8)) + goto found_it; + memcpy(&m->vdata[8 * j], data, sizeof(float) * 8); + n++; +found_it: + m->idx[i] = j; + } + + m->vcount = n; + m->icount = o->num_f; + + return m; +} + +#if 0 +void model_dump(struct model *m, FILE *fp) { + int i; + fprintf(fp, "struct model M = {\n"); + fprintf(fp, " .vdata = {\n"); + for (i = 0; i < m->vcount; i++) + fprintf(fp, " %f, %f, %f,\n %f, %f, %f, %f, %f,\n", + m->vdata[i*8+0], m->vdata[i*8+1], + m->vdata[i*8+2], m->vdata[i*8+3], + m->vdata[i*8+4], m->vdata[i*8+5], + m->vdata[i*8+6], m->vdata[i*8+7]); + fprintf(fp, " },\n .idx[] = {\n"); + for (i = 0; i < m->icount; i += 3) + fprintf(fp, " %d, %d, %d,\n", + m->idx[i+0], m->idx[i+1], m->idx[i+2]); + fprintf(fp, " },\n .vcount = %d,\n .icount = %d,\n};\n", + m->vcount, m->icount); +} +#endif + +struct model *load_wavefront_obj(const char *fn) { + struct obj *o; + struct model *m; + o = load_obj(fn); + if (!o) + return 0; + m = obj_to_model(o); + obj_destroy(o); + return m; +} + diff --git a/loadpng.c b/loadpng.c @@ -1,121 +0,0 @@ -/* 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 <string.h> - -#include <png.h> - -#include "util.h" - -void *_load_png(const char *fn, unsigned *_width, unsigned *_height, int ch, int inverty) { - png_structp png; - png_infop info; - png_uint_32 w, h; - int depth, ctype, itype, i; - png_byte *data = 0; - FILE *fp; - - if ((fp = fopen(fn, "rb")) == NULL) - goto exit; - - if (!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) - goto close_and_exit; - - if (!(info = png_create_info_struct(png))) { - png_destroy_read_struct(&png, NULL, NULL); - goto destroy_and_exit; - } - - if (setjmp(png->jmpbuf)) { - if (data) { - free(data); - data = 0; - } - goto destroy_and_exit; - } - - png_init_io(png, fp); - - png_read_info(png, info); - - png_get_IHDR(png, info, &w, &h, &depth, &ctype, &itype, NULL, NULL); - - if (depth < 8) - png_set_packing(png); - - if (depth > 8) - png_set_strip_16(png); - - if (ctype == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png); - - if ((ctype == PNG_COLOR_TYPE_GRAY) && (depth < 8)) - png_set_expand(png); - - if (png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_expand(png); - - if (ch == 4) { - if ((ctype == PNG_COLOR_TYPE_RGB) || - (ctype == PNG_COLOR_TYPE_GRAY)) - png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER); - - if ((ctype == PNG_COLOR_TYPE_GRAY) || - (ctype == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_set_gray_to_rgb(png); - } else if (ch == 1) { - if ((ctype == PNG_COLOR_TYPE_RGB) || - (ctype == PNG_COLOR_TYPE_RGB_ALPHA)) - png_set_rgb_to_gray_fixed(png, 1, -1, -1); - - png_set_strip_alpha(png); - } else { - png_error(png, "unsupported channel count"); - } - - if (!(data = malloc(w * h * ch))) - png_error(png, "cannot allocate image buffer"); - - if (inverty) - for (i = h-1; i >= 0; i--) - png_read_row(png, data + (i * w * ch), NULL); - else - for (i = 0; i < h; i++) - png_read_row(png, data + (i * w * ch), NULL); - - *_width = w; - *_height = h; - -destroy_and_exit: - png_destroy_read_struct(&png, &info, NULL); - -close_and_exit: - fclose(fp); -exit: - if (!data) - fprintf(stderr,"failed to load '%s'\n", fn); - return data; -} - -void *load_png_rgba(const char *fn, unsigned *_width, unsigned *_height, int texture) { - return _load_png(fn, _width, _height, 4, texture); -} - -void *load_png_gray(const char *fn, unsigned *_width, unsigned *_height, int texture) { - return _load_png(fn, _width, _height, 1, texture); -} - diff --git a/loadpng.cc b/loadpng.cc @@ -0,0 +1,121 @@ +/* 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 <string.h> + +#include <png.h> + +#include "util.h" + +void *_load_png(const char *fn, unsigned *_width, unsigned *_height, int ch, int inverty) { + png_structp png; + png_infop info; + png_uint_32 w, h; + int depth, ctype, itype, i; + png_byte *data = 0; + FILE *fp; + + if ((fp = fopen(fn, "rb")) == NULL) + goto exit; + + if (!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) + goto close_and_exit; + + if (!(info = png_create_info_struct(png))) { + png_destroy_read_struct(&png, NULL, NULL); + goto destroy_and_exit; + } + + if (setjmp(png->jmpbuf)) { + if (data) { + free(data); + data = 0; + } + goto destroy_and_exit; + } + + png_init_io(png, fp); + + png_read_info(png, info); + + png_get_IHDR(png, info, &w, &h, &depth, &ctype, &itype, NULL, NULL); + + if (depth < 8) + png_set_packing(png); + + if (depth > 8) + png_set_strip_16(png); + + if (ctype == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png); + + if ((ctype == PNG_COLOR_TYPE_GRAY) && (depth < 8)) + png_set_expand(png); + + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_expand(png); + + if (ch == 4) { + if ((ctype == PNG_COLOR_TYPE_RGB) || + (ctype == PNG_COLOR_TYPE_GRAY)) + png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER); + + if ((ctype == PNG_COLOR_TYPE_GRAY) || + (ctype == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_set_gray_to_rgb(png); + } else if (ch == 1) { + if ((ctype == PNG_COLOR_TYPE_RGB) || + (ctype == PNG_COLOR_TYPE_RGB_ALPHA)) + png_set_rgb_to_gray_fixed(png, 1, -1, -1); + + png_set_strip_alpha(png); + } else { + png_error(png, "unsupported channel count"); + } + + if (!(data = (png_byte*) malloc(w * h * ch))) + png_error(png, "cannot allocate image buffer"); + + if (inverty) + for (i = h-1; i >= 0; i--) + png_read_row(png, data + (i * w * ch), NULL); + else + for (i = 0; i < h; i++) + png_read_row(png, data + (i * w * ch), NULL); + + *_width = w; + *_height = h; + +destroy_and_exit: + png_destroy_read_struct(&png, &info, NULL); + +close_and_exit: + fclose(fp); +exit: + if (!data) + fprintf(stderr,"failed to load '%s'\n", fn); + return data; +} + +void *load_png_rgba(const char *fn, unsigned *_width, unsigned *_height, int texture) { + return _load_png(fn, _width, _height, 4, texture); +} + +void *load_png_gray(const char *fn, unsigned *_width, unsigned *_height, int texture) { + return _load_png(fn, _width, _height, 1, texture); +} + diff --git a/matrix.h b/matrix.h @@ -16,6 +16,8 @@ #ifndef _MATRIX_MATH_H_ #define _MATRIX_MATH_H_ +#include <string.h> + #define D2R(d) (((d) * M_PI) / 180.0) /* low level operations */ diff --git a/mksdf.c b/mksdf.c @@ -1,99 +0,0 @@ -/* 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 != 4) { - fprintf(stderr,"usage: mksdf <pngfile> <size> <outfile>\n"); - return -1; - } - - 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, 0); - if (!tex) { - fprintf(stderr,"cannot load source image '%s'\n", argv[1]); - return -1; - } - - generate(map, mw, mh, tw / mw); - - return save_png_gray(argv[3], map, mw, mh); -} - diff --git a/mksdf.cc b/mksdf.cc @@ -0,0 +1,98 @@ +/* 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; + + if (argc != 4) { + fprintf(stderr,"usage: mksdf <pngfile> <size> <outfile>\n"); + return -1; + } + + mw = mh = atoi(argv[2]); + + if (!(map = (unsigned char*) malloc(mw * mh))) { + fprintf(stderr,"out of memory\n"); + return -1; + } + + tex = (unsigned char*) load_png_gray(argv[1], &tw, &th, 0); + if (!tex) { + fprintf(stderr,"cannot load source image '%s'\n", argv[1]); + return -1; + } + + generate(map, mw, mh, tw / mw); + + return save_png_gray(argv[3], map, mw, mh); +} + diff --git a/program.cc b/program.cc @@ -0,0 +1,36 @@ +/* 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 "glue.h" +#include "util.h" +#include "program.h" + +Program::Program() : vsrc(NULL), fsrc(NULL), status(-1) { +} + +int Program::compile(const char *vfn, const char *ffn) { + if (!(vsrc = (char*) load_file(vfn, 0))) + return -1; + if (!(fsrc = (char*) load_file(ffn, 0))) + return -1; + if (shader_compile(vsrc, fsrc, &pobj, &vobj, &fobj)) + return -1; + status = 0; + return 0; +} + diff --git a/Program.h b/program.h diff --git a/savepng.c b/savepng.c @@ -1,86 +0,0 @@ -/* 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 <string.h> - -#include <png.h> - -#include "util.h" - -int _save_png(const char *fn, png_byte *data, unsigned w, unsigned h, int ch) { - png_structp png; - png_infop info; - FILE *fp; - int i, status = -1; - - if ((fp = fopen(fn, "wb")) == NULL) - goto exit; - - if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) - goto close_and_exit; - - if (!(info = png_create_info_struct(png))) { - png_destroy_write_struct(&png, NULL); - goto destroy_and_exit; - } - - if (setjmp(png->jmpbuf)) { - goto destroy_and_exit; - } - - png_init_io(png, fp); - - if (ch == 4) { - png_set_IHDR(png, info, w, h, 8, - PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - } else if (ch == 1) { - png_set_IHDR(png, info, w, h, 8, - PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - } else { - png_error(png, "unsupported channel count"); - } - - png_write_info(png, info); - - for (i = 0; i < h; i++) - png_write_row(png, data + (i * w * ch)); - - png_write_end(png, info); - - status = 0; - -destroy_and_exit: - png_destroy_write_struct(&png, &info); - -close_and_exit: - fclose(fp); -exit: - if (status) - fprintf(stderr,"failed to load '%s'\n", fn); - return status; -} - -int save_png_rgba(const char *fn, void *data, unsigned w, unsigned h) { - return _save_png(fn, data, w, h, 4); -} - -int save_png_gray(const char *fn, void *data, unsigned w, unsigned h) { - return _save_png(fn, data, w, h, 1); -} - diff --git a/savepng.cc b/savepng.cc @@ -0,0 +1,86 @@ +/* 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 <string.h> + +#include <png.h> + +#include "util.h" + +int _save_png(const char *fn, png_byte *data, unsigned w, unsigned h, int ch) { + png_structp png; + png_infop info; + FILE *fp; + int i, status = -1; + + if ((fp = fopen(fn, "wb")) == NULL) + goto exit; + + if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) + goto close_and_exit; + + if (!(info = png_create_info_struct(png))) { + png_destroy_write_struct(&png, NULL); + goto destroy_and_exit; + } + + if (setjmp(png->jmpbuf)) { + goto destroy_and_exit; + } + + png_init_io(png, fp); + + if (ch == 4) { + png_set_IHDR(png, info, w, h, 8, + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + } else if (ch == 1) { + png_set_IHDR(png, info, w, h, 8, + PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + } else { + png_error(png, "unsupported channel count"); + } + + png_write_info(png, info); + + for (i = 0; i < h; i++) + png_write_row(png, data + (i * w * ch)); + + png_write_end(png, info); + + status = 0; + +destroy_and_exit: + png_destroy_write_struct(&png, &info); + +close_and_exit: + fclose(fp); +exit: + if (status) + fprintf(stderr,"failed to load '%s'\n", fn); + return status; +} + +int save_png_rgba(const char *fn, void *data, unsigned w, unsigned h) { + return _save_png(fn, (png_byte*) data, w, h, 4); +} + +int save_png_gray(const char *fn, void *data, unsigned w, unsigned h) { + return _save_png(fn, (png_byte*) data, w, h, 1); +} + diff --git a/sdlglue.c b/sdlglue.c @@ -1,210 +0,0 @@ -/* 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 <SDL.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <sys/time.h> - -#include "util.h" -#include "glue.h" - -void die(const char *fmt, ...) { - fprintf(stderr,"ERROR: %s\n", fmt); - exit(-1); -} - -int check_compile_error(GLuint obj, const char *fn) { - GLint r, len; - char *buf; - - if (fn) glGetShaderiv(obj, GL_COMPILE_STATUS, &r); - else glGetProgramiv(obj, GL_LINK_STATUS, &r); - - if (r) return 0; - - if (fn) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); - else glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); - - buf = malloc(len + 1); - memset(buf, 0, len); - if (buf != 0) { - if (fn) glGetShaderInfoLog(obj, len, &len, buf); - else glGetProgramInfoLog(obj, len, &len, buf); - buf[len] = 0; - } - fprintf(stderr,"Shader %s Error:\n%s\n", - fn ? "Compile" : "Link", buf ? buf : "???"); - - free(buf); - return -1; -} - -int shader_compile(const char *vshader, const char *fshader, - GLuint *_pgm, GLuint *_vshd, GLuint *_fshd) { - GLuint pgm, vshd, fshd; - - pgm = glCreateProgram(); - vshd = glCreateShader(GL_VERTEX_SHADER); - fshd = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(vshd, 1, &vshader, NULL); - glShaderSource(fshd, 1, &fshader, NULL); - glCompileShader(vshd); - check_compile_error(vshd, vshader); - - glCompileShader(fshd); - check_compile_error(fshd, fshader); - - glAttachShader(pgm, vshd); - glAttachShader(pgm, fshd); - glLinkProgram(pgm); - if (check_compile_error(pgm, 0)) - return -1; - - *_pgm = pgm; - *_vshd = vshd; - *_fshd = fshd; - return 0; -} - -void quit(void) { - SDL_Quit(); - exit(0); -} - -unsigned char keystate[SDLK_LAST + 1] = { 0, }; - -void handle_events(void) { - SDL_Event ev; - - while (SDL_PollEvent(&ev)) { - switch (ev.type) { - case SDL_KEYDOWN: - keystate[ev.key.keysym.sym] = 1; - if (ev.key.keysym.sym == SDLK_ESCAPE) - quit(); - break; - case SDL_KEYUP: - keystate[ev.key.keysym.sym] = 0; - break; - case SDL_QUIT: - quit(); - } - } -} - -int main(int argc, char **argv) { - int vsync = 1; - struct ctxt c; - char *x; - time_t t0, t1; - int count; -#if WITH_SDL2 - SDL_Window *w; - SDL_GLContext gc; -#endif - - c.width = 640; - c.height = 480; - c.data = 0; - - argc--; - argv++; - while (argc--) { - if (!strcmp("-nosync",argv[0])) { - vsync = 0; - } else if (isdigit(argv[0][0]) && (x = strchr(argv[0],'x'))) { - c.width = atoi(argv[0]); - c.height = atoi(x + 1); - } else { - fprintf(stderr,"unknown argument '%s'\n",argv[0]); - } - argv++; - } - - if (SDL_Init(SDL_INIT_VIDEO)) - die("sdl video init failed"); - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); - -#if 0 - SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); -#endif - - /* enable vsync */ - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,vsync); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,vsync); - -#if WITH_SDL2 - if (!(w = SDL_CreateWindow("Test", 0, 0, c.width, c.height, - SDL_WINDOW_OPENGL))) - die("sdl cannot create window"); - - if (!(gc = SDL_GL_CreateContext(w))) - die("sdl cannot create gl context"); -#else - if (SDL_SetVideoMode(c.width, c.height, 32, - SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL) == NULL) - die("sdl cannot set mode"); -#endif - - if (scene_init(&c)) - return -1; - - t0 = time(0); - count = 0; - for (;;) { - handle_events(); - - if (scene_draw(&c)) - return -1; - - if (vsync) { -#if WITH_SDL2 - SDL_GL_SwapWindow(w); -#else - SDL_GL_SwapBuffers(); -#endif - } else { - glFlush(); - } - - t1 = time(0); - count++; - if (t0 != t1) { - printf("%d fps\n", count); - count = 0; - t0 = t1; - } - } - - return 0; -} - diff --git a/sdlglue.cc b/sdlglue.cc @@ -0,0 +1,210 @@ +/* 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 <SDL.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <time.h> + +#include "util.h" +#include "glue.h" + +void die(const char *fmt, ...) { + fprintf(stderr,"ERROR: %s\n", fmt); + exit(-1); +} + +int check_compile_error(GLuint obj, const char *fn) { + GLint r, len; + char *buf; + + if (fn) glGetShaderiv(obj, GL_COMPILE_STATUS, &r); + else glGetProgramiv(obj, GL_LINK_STATUS, &r); + + if (r) return 0; + + if (fn) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); + else glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); + + buf = (char*) malloc(len + 1); + memset(buf, 0, len); + if (buf != 0) { + if (fn) glGetShaderInfoLog(obj, len, &len, buf); + else glGetProgramInfoLog(obj, len, &len, buf); + buf[len] = 0; + } + fprintf(stderr,"Shader %s Error:\n%s\n", + fn ? "Compile" : "Link", buf ? buf : "???"); + + free(buf); + return -1; +} + +int shader_compile(const char *vshader, const char *fshader, + GLuint *_pgm, GLuint *_vshd, GLuint *_fshd) { + GLuint pgm, vshd, fshd; + + pgm = glCreateProgram(); + vshd = glCreateShader(GL_VERTEX_SHADER); + fshd = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(vshd, 1, &vshader, NULL); + glShaderSource(fshd, 1, &fshader, NULL); + glCompileShader(vshd); + check_compile_error(vshd, vshader); + + glCompileShader(fshd); + check_compile_error(fshd, fshader); + + glAttachShader(pgm, vshd); + glAttachShader(pgm, fshd); + glLinkProgram(pgm); + if (check_compile_error(pgm, 0)) + return -1; + + *_pgm = pgm; + *_vshd = vshd; + *_fshd = fshd; + return 0; +} + +void quit(void) { + SDL_Quit(); + exit(0); +} + +unsigned char keystate[SDLK_LAST + 1] = { 0, }; + +void handle_events(void) { + SDL_Event ev; + + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_KEYDOWN: + keystate[ev.key.keysym.sym] = 1; + if (ev.key.keysym.sym == SDLK_ESCAPE) + quit(); + break; + case SDL_KEYUP: + keystate[ev.key.keysym.sym] = 0; + break; + case SDL_QUIT: + quit(); + } + } +} + +int main(int argc, char **argv) { + int vsync = 1; + struct ctxt c; + char *x; + time_t t0, t1; + int count; +#if WITH_SDL2 + SDL_Window *w; + SDL_GLContext gc; +#endif + + c.width = 640; + c.height = 480; + c.data = 0; + + argc--; + argv++; + while (argc--) { + if (!strcmp("-nosync",argv[0])) { + vsync = 0; + } else if (isdigit(argv[0][0]) && (x = strchr(argv[0],'x'))) { + c.width = atoi(argv[0]); + c.height = atoi(x + 1); + } else { + fprintf(stderr,"unknown argument '%s'\n",argv[0]); + } + argv++; + } + + if (SDL_Init(SDL_INIT_VIDEO)) + die("sdl video init failed"); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); + +#if 0 + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8); + + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); +#endif + + /* enable vsync */ + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,vsync); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,vsync); + +#if WITH_SDL2 + if (!(w = SDL_CreateWindow("Test", 0, 0, c.width, c.height, + SDL_WINDOW_OPENGL))) + die("sdl cannot create window"); + + if (!(gc = SDL_GL_CreateContext(w))) + die("sdl cannot create gl context"); +#else + if (SDL_SetVideoMode(c.width, c.height, 32, + SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL) == NULL) + die("sdl cannot set mode"); +#endif + + if (scene_init(&c)) + return -1; + + t0 = time(0); + count = 0; + for (;;) { + handle_events(); + + if (scene_draw(&c)) + return -1; + + if (vsync) { +#if WITH_SDL2 + SDL_GL_SwapWindow(w); +#else + SDL_GL_SwapBuffers(); +#endif + } else { + glFlush(); + } + + t1 = time(0); + count++; + if (t0 != t1) { + printf("%d fps\n", count); + count = 0; + t0 = t1; + } + } + + return 0; +} + diff --git a/test1.c b/test1.c @@ -1,109 +0,0 @@ -/* 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 aVertex, aTexCoord; -GLuint uMVP, uTexture; - -mat4 MVP; - -GLfloat verts[] = { - -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_rgba("texture1.png", &texw, &texh, 1))) - return -1; - if (!(vert_src = load_file("test1.vs", 0))) - return -1; - if (!(frag_src = load_file("test1.fs", 0))) - return -1; - - mtx_identity(MVP); - mtx_ortho(MVP, -2.66, 2.66, -2, 2, 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; - - aVertex = glGetAttribLocation(pgm, "aVertex"); - aTexCoord = glGetAttribLocation(pgm, "aTexCoord"); - uMVP = glGetUniformLocation(pgm, "uMVP"); - uTexture = glGetUniformLocation(pgm, "uTexture"); - - 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_RGBA, texw, texh, 0, GL_RGBA, - GL_UNSIGNED_BYTE, texdata); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - 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(uTexture, 0); - - glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 0, verts); - glEnableVertexAttribArray(aVertex); - - glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, texcoords); - glEnableVertexAttribArray(aTexCoord); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - return 0; -} - diff --git a/test1.cc b/test1.cc @@ -0,0 +1,102 @@ +/* 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" +#include "matrix.h" +#include "program.h" + +void *texdata; +unsigned texw, texh; + +GLuint tex0; +GLuint aVertex, aTexCoord; +GLuint uMVP, uTexture; + +mat4 MVP; +Program pgm; + +GLfloat verts[] = { + -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_rgba("texture1.png", &texw, &texh, 1))) + return -1; + + MVP.setOrtho(-2.66, 2.66, -2, 2, 1, -1); + + glViewport(0, 0, c->width, c->height); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0f); + + if (pgm.compile("test1.vs","test1.fs")) + return -1; + + aVertex = pgm.getAttribID("aVertex"); + aTexCoord = pgm.getAttribID("aTexCoord"); + uMVP = pgm.getUniformID("uMVP"); + uTexture = pgm.getUniformID("uTexture"); + + if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n"); + + glEnable(GL_TEXTURE_2D); + + glGenTextures(1, &tex0); + glBindTexture(GL_TEXTURE_2D, tex0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA, + GL_UNSIGNED_BYTE, texdata); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return 0; +} + +int scene_draw(struct ctxt *c) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + pgm.use(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex0); + + glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP); + glUniform1i(uTexture, 0); + + glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 0, verts); + glEnableVertexAttribArray(aVertex); + + glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glEnableVertexAttribArray(aTexCoord); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + return 0; +} + diff --git a/test2.c b/test2.c @@ -1,158 +0,0 @@ -/* 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 <string.h> - -#include "util.h" -#include "glue.h" - -#include <math.h> - -void *texdata; -unsigned texw, texh; - -const char *vert_src, *frag_src; - -GLuint pgm, vshd, fshd, tex0; -GLuint aVertex, aTexCoord; -GLuint uMVP, uTexture; - -mat4 perspective; -mat4 MVP; - -float a = 0.0; - -GLfloat data[] = { - -0.5f, 0.5f, 0.5f, 0.25, 0.75, - -0.5f, -0.5f, 0.5f, 0.25, 0.50, - 0.5f, -0.5f, 0.5f, 0.50, 0.50, - 0.5f, 0.5f, 0.5f, 0.50, 0.75, - - 0.5f, 0.5f, 0.5f, 0.50, 0.75, - 0.5f, -0.5f, 0.5f, 0.50, 0.50, - 0.5f, -0.5f, -0.5f, 0.75, 0.50, - 0.5f, 0.5f, -0.5f, 0.75, 0.75, - - 0.5f, 0.5f, -0.5f, 0.75, 0.75, - 0.5f, -0.5f, -0.5f, 0.75, 0.50, - -0.5f, -0.5f, -0.5f, 1.00, 0.50, - -0.5f, 0.5f, -0.5f, 1.00, 0.75, - - -0.5f, 0.5f, -0.5f, 0.00, 0.75, - -0.5f, -0.5f, -0.5f, 0.00, 0.50, - -0.5f, -0.5f, 0.5f, 0.25, 0.50, - -0.5f, 0.5f, 0.5f, 0.25, 0.75, - - -0.5f, 0.5f, -0.5f, 0.25, 1.00, - -0.5f, 0.5f, 0.5f, 0.25, 0.75, - 0.5f, 0.5f, 0.5f, 0.50, 0.75, - 0.5f, 0.5f, -0.5f, 0.50, 1.00, - - -0.5f, -0.5f, 0.5f, 0.25, 0.50, - -0.5f, -0.5f, -0.5f, 0.25, 0.25, - 0.5f, -0.5f, -0.5f, 0.50, 0.25, - 0.5f, -0.5f, 0.5f, 0.50, 0.50, -}; - -GLubyte indices[] = { - 0, 1, 2, 3, 0, 2, - 4, 5, 6, 7, 4, 6, - 8, 9, 10, 11, 8, 10, - 12, 13, 14, 15, 12, 14, - 16, 17, 18, 19, 16, 18, - 20, 21, 22, 23, 20, 22, -}; - -int scene_init(struct ctxt *c) { - float aspect = ((float) c->width) / ((float) c->height); - - if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1))) - return -1; - if (!(vert_src = load_file("test1.vs", 0))) - return -1; - if (!(frag_src = load_file("test1.fs", 0))) - return -1; - - mtx_identity(MVP); - mtx_perspective(perspective, 60.0, aspect, 1.0, 10.0); - - 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; - - aVertex = glGetAttribLocation(pgm, "aVertex"); - aTexCoord = glGetAttribLocation(pgm, "aTexCoord"); - uMVP = glGetUniformLocation(pgm, "uMVP"); - uTexture = glGetUniformLocation(pgm, "uTexture"); - - if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n"); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glFrontFace(GL_CCW); -// 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_RGBA, texw, texh, 0, GL_RGBA, - GL_UNSIGNED_BYTE, texdata); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - return 0; -} - -int scene_draw(struct ctxt *c) { - mat4 camera; - - mtx_identity(camera); - mtx_rotate_y(camera, a); - mtx_rotate_x(camera, 25.0); - mtx_translate(camera, 0, 0, -3.0); - - mtx_mul_unsafe(MVP, camera, perspective); - - a += 1.0; - if (a > 360.0) a = 0.0; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(pgm); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex0); - - glUniformMatrix4fv(uMVP, 1, GL_FALSE, (void*) MVP); - glUniform1i(uTexture, 0); - - glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 5*4, data); - glEnableVertexAttribArray(aVertex); - - glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 5*4, data + 3); - glEnableVertexAttribArray(aTexCoord); - - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); - - return 0; -} - diff --git a/test2.cc b/test2.cc @@ -0,0 +1,150 @@ +/* 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 <string.h> + +#include "util.h" +#include "glue.h" +#include "program.h" +#include "matrix.h" + +#include <math.h> + +void *texdata; +unsigned texw, texh; + +GLuint tex0; +GLuint aVertex, aTexCoord; +GLuint uMVP, uTexture; + +Program pgm; +mat4 perspective; +mat4 MVP; + +float a = 0.0; + +GLfloat data[] = { + -0.5f, 0.5f, 0.5f, 0.25, 0.75, + -0.5f, -0.5f, 0.5f, 0.25, 0.50, + 0.5f, -0.5f, 0.5f, 0.50, 0.50, + 0.5f, 0.5f, 0.5f, 0.50, 0.75, + + 0.5f, 0.5f, 0.5f, 0.50, 0.75, + 0.5f, -0.5f, 0.5f, 0.50, 0.50, + 0.5f, -0.5f, -0.5f, 0.75, 0.50, + 0.5f, 0.5f, -0.5f, 0.75, 0.75, + + 0.5f, 0.5f, -0.5f, 0.75, 0.75, + 0.5f, -0.5f, -0.5f, 0.75, 0.50, + -0.5f, -0.5f, -0.5f, 1.00, 0.50, + -0.5f, 0.5f, -0.5f, 1.00, 0.75, + + -0.5f, 0.5f, -0.5f, 0.00, 0.75, + -0.5f, -0.5f, -0.5f, 0.00, 0.50, + -0.5f, -0.5f, 0.5f, 0.25, 0.50, + -0.5f, 0.5f, 0.5f, 0.25, 0.75, + + -0.5f, 0.5f, -0.5f, 0.25, 1.00, + -0.5f, 0.5f, 0.5f, 0.25, 0.75, + 0.5f, 0.5f, 0.5f, 0.50, 0.75, + 0.5f, 0.5f, -0.5f, 0.50, 1.00, + + -0.5f, -0.5f, 0.5f, 0.25, 0.50, + -0.5f, -0.5f, -0.5f, 0.25, 0.25, + 0.5f, -0.5f, -0.5f, 0.50, 0.25, + 0.5f, -0.5f, 0.5f, 0.50, 0.50, +}; + +GLubyte indices[] = { + 0, 1, 2, 3, 0, 2, + 4, 5, 6, 7, 4, 6, + 8, 9, 10, 11, 8, 10, + 12, 13, 14, 15, 12, 14, + 16, 17, 18, 19, 16, 18, + 20, 21, 22, 23, 20, 22, +}; + +int scene_init(struct ctxt *c) { + float aspect = ((float) c->width) / ((float) c->height); + + if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1))) + return -1; + + perspective.setPerspective(D2R(60.0), aspect, 1.0, 10.0); + + glViewport(0, 0, c->width, c->height); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0f); + + if (pgm.compile("test1.vs", "test1.fs")) + return -1; + + aVertex = pgm.getAttribID("aVertex"); + aTexCoord = pgm.getAttribID("aTexCoord"); + uMVP = pgm.getUniformID("uMVP"); + uTexture = pgm.getUniformID("uTexture"); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glFrontFace(GL_CCW); + + glGenTextures(1, &tex0); + + glBindTexture(GL_TEXTURE_2D, tex0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA, + GL_UNSIGNED_BYTE, texdata); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return 0; +} + +int scene_draw(struct ctxt *c) { + mat4 camera; + + camera.identity(); + camera.rotateY(D2R(a)); + camera.rotateX(D2R(25.0)); + camera.translate(0, 0, -3.0); + + MVP = camera * perspective; + + a += 1.0; + if (a > 360.0) a = 0.0; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + pgm.use(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex0); + + glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP); + glUniform1i(uTexture, 0); + + glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 5*4, data); + glEnableVertexAttribArray(aVertex); + + glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 5*4, data + 3); + glEnableVertexAttribArray(aTexCoord); + + glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); + + return 0; +} + diff --git a/test3.c b/test3.c @@ -1,122 +0,0 @@ -/* 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 <string.h> - -#include "util.h" -#include "glue.h" - -#include <math.h> - -void *texdata; -unsigned texw, texh; - -const char *vert_src, *frag_src; - -GLuint pgm, vshd, fshd, tex0; -GLuint aVertex, aTexCoord; -GLuint uMVP, uTexture; - -mat4 perspective; -mat4 MVP; - -float a = 0.0; - -struct model *m; - -int scene_init(struct ctxt *c) { - float aspect = ((float) c->width) / ((float) c->height); - - if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1))) - return -1; - if (!(vert_src = load_file("test1.vs", 0))) - return -1; - if (!(frag_src = load_file("test1.fs", 0))) - return -1; - - if (!(m = load_wavefront_obj("cube.obj"))) - return -1; - - mtx_identity(MVP); - mtx_perspective(perspective, 60.0, aspect, 1.0, 10.0); - - 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; - - aVertex = glGetAttribLocation(pgm, "aVertex"); - aTexCoord = glGetAttribLocation(pgm, "aTexCoord"); - uMVP = glGetUniformLocation(pgm, "uMVP"); - uTexture = glGetUniformLocation(pgm, "uTexture"); - - if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n"); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glFrontFace(GL_CCW); -// 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_RGBA, texw, texh, 0, GL_RGBA, - GL_UNSIGNED_BYTE, texdata); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - return 0; -} - -int scene_draw(struct ctxt *c) { - mat4 camera; - - mtx_identity(camera); - mtx_rotate_y(camera, a); - mtx_rotate_x(camera, 25.0); - mtx_translate(camera, 0, 0, -5.0); - - mtx_mul_unsafe(MVP, camera, perspective); - - a += 1.0; - if (a > 360.0) a = 0.0; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(pgm); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex0); - - glUniformMatrix4fv(uMVP, 1, GL_FALSE, (void*) MVP); - glUniform1i(uTexture, 0); - - glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata); - glEnableVertexAttribArray(aVertex); - - glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 6); - glEnableVertexAttribArray(aTexCoord); - - glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx); - - return 0; -} - diff --git a/test3.cc b/test3.cc @@ -0,0 +1,114 @@ +/* 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 <string.h> + +#include "util.h" +#include "glue.h" +#include "matrix.h" +#include "program.h" + +#include <math.h> + +void *texdata; +unsigned texw, texh; + +GLuint tex0; +GLuint aVertex, aTexCoord; +GLuint uMVP, uTexture; + +Program pgm; +mat4 perspective; +mat4 MVP; + +float a = 0.0; + +struct model *m; + +int scene_init(struct ctxt *c) { + float aspect = ((float) c->width) / ((float) c->height); + + if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh, 1))) + return -1; + + if (!(m = load_wavefront_obj("cube.obj"))) + return -1; + + perspective.setPerspective(D2R(60.0), aspect, 1.0, 10.0); + + glViewport(0, 0, c->width, c->height); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0f); + + if (pgm.compile("test1.vs","test1.fs")) + return -1; + + aVertex = pgm.getAttribID("aVertex"); + aTexCoord = pgm.getAttribID("aTexCoord"); + uMVP = pgm.getUniformID("uMVP"); + uTexture = pgm.getUniformID("uTexture"); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glFrontFace(GL_CCW); + + glGenTextures(1, &tex0); + + glBindTexture(GL_TEXTURE_2D, tex0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA, + GL_UNSIGNED_BYTE, texdata); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return 0; +} + +int scene_draw(struct ctxt *c) { + mat4 camera; + + camera.identity(); + camera.rotateY(D2R(a)); + camera.rotateX(D2R(25.0)); + camera.translate(0, 0, -5.0); + + MVP = camera * perspective; + + a += 1.0; + if (a > 360.0) a = 0.0; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + pgm.use(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex0); + + glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP); + glUniform1i(uTexture, 0); + + glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 8*4, m->vdata); + glEnableVertexAttribArray(aVertex); + + glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 8*4, m->vdata + 6); + glEnableVertexAttribArray(aTexCoord); + + glDrawElements(GL_TRIANGLES, m->icount, GL_UNSIGNED_SHORT, m->idx); + + return 0; +} + diff --git a/test4.c b/test4.c @@ -1,154 +0,0 @@ -/* 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" - -#include <sys/time.h> -#include <sys/stat.h> - -void *texdata; -unsigned texw, texh; - -char *vert_src, *frag_src; - -GLuint pgm = -1, vshd = -1, fshd = -1, tex0; -GLuint aVertex, aTexCoord; -GLuint uMVP, uTexture; - -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, -}; - -time_t vstime = 0, fstime = 0; - -void update_shaders(void) { - struct stat vsstat, fsstat; - GLuint newpgm, newvs, newfs; - - stat("test4.vs", &vsstat); - stat("test4.fs", &fsstat); - - if ((vsstat.st_mtime == vstime) && (fsstat.st_mtime == fstime)) - return; - - vstime = vsstat.st_mtime; - fstime = fsstat.st_mtime; - - if (!(vert_src = load_file("test4.vs", 0))) - goto exit; - if (!(frag_src = load_file("test4.fs", 0))) - goto free_vsrc_and_exit; - - if (shader_compile(vert_src, frag_src, &newpgm, &newvs, &newfs)) - goto free_both_and_exit; - - glDeleteShader(vshd); - glDeleteShader(fshd); - glDeleteProgram(pgm); - - pgm = newpgm; - vshd = newvs; - fshd = newfs; - - aVertex = glGetAttribLocation(pgm, "aVertex"); - aTexCoord = glGetAttribLocation(pgm, "aTexCoord"); - uMVP = glGetUniformLocation(pgm, "uMVP"); - uTexture = glGetUniformLocation(pgm, "uTexture"); - - free(frag_src); - free(vert_src); - - fprintf(stderr,"shaders updated\n"); - return; - -free_both_and_exit: - free(frag_src); -free_vsrc_and_exit: - free(vert_src); -exit: - fprintf(stderr,"failed to update shaders\n"); - return; -} - -int scene_init(struct ctxt *c) { - float aspect; - - if (!(texdata = load_png_gray("texture.sdf.png", &texw, &texh, 1))) - return -1; - - aspect = ((float)c->width) / ((float)c->height); - mtx_ortho(MVP, -aspect, aspect, -1, 1, 1, -1); - - glViewport(0, 0, c->width, c->height); - glClearColor(0, 0, 0, 0); - glClearDepth(1.0f); - - glEnable(GL_TEXTURE_2D); - - 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) { - update_shaders(); - - 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(uTexture, 0); - - glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 0, verts); - glEnableVertexAttribArray(aVertex); - - glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, texcoords); - glEnableVertexAttribArray(aTexCoord); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - return 0; -} - diff --git a/test4.cc b/test4.cc @@ -0,0 +1,107 @@ +/* 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" +#include "matrix.h" +#include "program.h" + +void *texdata; +unsigned texw, texh; + +GLuint tex0; +GLuint aVertex, aTexCoord; +GLuint uMVP, uTexture; + +Program pgm; +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) { + float aspect; + + if (!(texdata = load_png_gray("texture.sdf.png", &texw, &texh, 1))) + return -1; + + if (pgm.compile("test4.vs","test4.fs")) + return -1; + + aVertex = pgm.getAttribID("aVertex"); + aTexCoord = pgm.getAttribID("aTexCoord"); + uMVP = pgm.getUniformID("uMVP"); + uTexture = pgm.getUniformID("uTexture"); + + aspect = ((float)c->width) / ((float)c->height); + MVP.setOrtho(-aspect, aspect, -1, 1, 1, -1); + + glViewport(0, 0, c->width, c->height); + glClearColor(0, 0, 0, 0); + glClearDepth(1.0f); + + glEnable(GL_TEXTURE_2D); + + 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); + + pgm.use(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex0); + + glUniformMatrix4fv(uMVP, 1, GL_FALSE, MVP); + glUniform1i(uTexture, 0); + + glVertexAttribPointer(aVertex, 3, GL_FLOAT, GL_FALSE, 0, verts); + glEnableVertexAttribArray(aVertex); + + glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glEnableVertexAttribArray(aTexCoord); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + return 0; +} + diff --git a/util.c b/util.c @@ -1,169 +0,0 @@ -/* 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 <string.h> -#include <math.h> - -#include "util.h" - -void mtx_mul_unsafe(mat4 m, mat4 a, mat4 b) { - int i; - for (i = 0; i < 4; i++) { - float ai0 = a[i][0]; - float ai1 = a[i][1]; - float ai2 = a[i][2]; - float ai3 = a[i][3]; - m[i][0] = ai0*b[0][0] + ai1*b[1][0] + ai2*b[2][0] + ai3*b[3][0]; - m[i][1] = ai0*b[0][1] + ai1*b[1][1] + ai2*b[2][1] + ai3*b[3][1]; - m[i][2] = ai0*b[0][2] + ai1*b[1][2] + ai2*b[2][2] + ai3*b[3][2]; - m[i][3] = ai0*b[0][3] + ai1*b[1][3] + ai2*b[2][3] + ai3*b[3][3]; - } -} - -void mtx_mul(mat4 m, mat4 a, mat4 b) { - mat4 t; - mtx_mul_unsafe(t, a, b); - memcpy(m, t, sizeof(mat4)); -} - -void mtx_mul_vec4(vec4 o, mat4 m, vec4 v) { - float v0=v[0], v1=v[1], v2=v[2], v3=v[3]; - o[0] = m[0][0] * v0 + m[1][0] * v1 + m[2][0] * v2 + m[3][0] * v3; - o[1] = m[0][1] * v0 + m[1][1] * v1 + m[2][1] * v2 + m[3][1] * v3; - o[2] = m[0][2] * v0 + m[1][2] * v1 + m[2][2] * v2 + m[3][2] * v3; - o[3] = m[0][3] * v0 + m[1][3] * v1 + m[2][3] * v2 + m[3][3] * v3; -} - -void mtx_identity(mat4 m) { - memset(m, 0, sizeof(mat4)); - m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; -} - -void mtx_translation(mat4 m, float x, float y, float z) { - memset(m, 0, sizeof(mat4)); - m[3][0] = x; - m[3][1] = y; - m[3][2] = z; - m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0; -} - -void mtx_translate(mat4 m, float x, float y, float z) { - mat4 t; - mtx_translation(t, x, y, z); - mtx_mul_unsafe(m, m, t); -} - -void mtx_x_rotation(mat4 r, float angle) { - float sa,ca; - angle = angle * M_PI / 180.0; - sa = sinf(angle); - ca = cosf(angle); - memset(r, 0, sizeof(mat4)); - r[0][0] = 1; - r[1][1] = ca; - r[1][2] = -sa; - r[2][1] = sa; - r[2][2] = ca; - r[3][3] = 1; -} - -void mtx_y_rotation(mat4 r, float angle) { - float sa,ca; - angle = angle * M_PI / 180.0; - sa = sinf(angle); - ca = cosf(angle); - memset(r, 0, sizeof(mat4)); - r[0][0] = ca; - r[0][2] = sa; - r[1][1] = 1; - r[2][0] = -sa; - r[2][2] = ca; - r[3][3] = 1; -} - -void mtx_z_rotation(mat4 r, float angle) { - float sa,ca; - angle = angle * M_PI / 180.0; - sa = sinf(angle); - ca = cosf(angle); - memset(r, 0, sizeof(mat4)); - r[0][0] = ca; - r[0][1] = -sa; - r[1][0] = sa; - r[1][1] = ca; - r[2][2] = 1; - r[3][3] = 1; -} - -void mtx_rotate_x(mat4 m, float angle) { - mat4 r; - mtx_x_rotation(r, angle); - mtx_mul_unsafe(m, m, r); -} - -void mtx_rotate_y(mat4 m, float angle) { - mat4 r; - mtx_y_rotation(r, angle); - mtx_mul_unsafe(m, m, r); -} - -void mtx_rotate_z(mat4 m, float angle) { - mat4 r; - mtx_z_rotation(r, angle); - mtx_mul_unsafe(m, m, r); -} - -void mtx_frustum(mat4 m, float left, float right, float bottom, float top, float znear, float zfar) { - float znear2 = 2.0 * znear; - float width = right - left; - float height = top - bottom; - float depth = zfar - znear; - memset(m, 0, sizeof(mat4)); - m[0][0] = znear2 / width; - m[1][1] = znear2 / height; - m[2][0] = (right + left) / width; - m[2][1] = (top + bottom) / height; - m[2][2] = (-zfar - znear) / depth; - m[2][3] = -1.0; - m[3][2] = (-znear2 * zfar) / depth; -} - -void mtx_perspective(mat4 m, float fov, float aspect, float znear, float zfar) { - float ymax, xmax; - ymax = znear * tanf(fov * M_PI / 360.0); - xmax = ymax * aspect; - mtx_frustum(m, -xmax, xmax, -ymax, ymax, znear, zfar); -} - -void mtx_ortho(mat4 m, float l, float r, float b, float t, float n, float f) { - memset(m, 0, sizeof(mat4)); - m[0][0] = 2.0 / (r - l); - m[1][1] = 2.0 / (t - b); - m[2][2] = -2.0 / (f - n); - m[3][0] = -((r + l) / (r - l)); - m[3][1] = -((t + b) / (t - b)); - m[3][2] = -((f + n) / (f - n)); - m[3][3] = 1.0; -} - -void mtx_dump(const float m[16], const char *name) { - fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f | %s\n",m[0],m[4],m[8],m[12], name ? name : ""); - fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[1],m[5],m[9],m[13]); - fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[2],m[6],m[10],m[14]); - fprintf(stderr,"| %9.5f %9.5f %9.5f %9.5f |\n",m[3],m[7],m[11],m[15]); -} - - diff --git a/util.h b/util.h @@ -16,54 +16,6 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -#ifdef __cplusplus -extern "C" { -#else -typedef float mat4[4][4]; -typedef float vec4[4]; -typedef float vec3[3]; - -/* load the identity matrix */ -void mtx_identity(mat4 out); - -/* out = left * right */ -void mtx_mul(mat4 out, mat4 left, mat4 right); - -/* avoids a copy, but out and right may not be the same */ -/* mtx_mul_unsafe(a, a, b) = OK, mtx_mul_unsafe(a, b, a) = FAIL */ -void mtx_mul_unsafe(mat4 out, mat4 left, mat4 right); - -void mtx_mul_vec4(vec4 out, mat4 left, vec4 right); - -/* applies the transform to out */ -void mtx_translate(mat4 out, float x, float y, float z); -void mtx_rotate_x(mat4 out, float angle); -void mtx_rotate_y(mat4 out, float angle); -void mtx_rotate_z(mat4 out, float angle); - -/* initializes matrix out to the transform */ -void mtx_translation(mat4 out, float x, float y, float z); -void mtx_x_rotation(mat4 out, float angle); -void mtx_y_rotation(mat4 out, float angle); -void mtx_z_rotation(mat4 out, float angle); - -/* GLU-style perspective matrix helper functions */ -void mtx_ortho(mat4 out, - float left, float right, - float bottom, float top, - float near, float far); - -void mtx_frustum(mat4 out, - float left, float right, float bottom, float top, - float znear, float zfar); - -void mtx_perspective(mat4 out, - float fov_degrees, float aspect_ratio, - float znear, float zfar); -#endif - -void mtx_dump(const float m[16], const char *name); - /* file io helpers */ void *load_png_rgba(const char *fn, unsigned *width, unsigned *height, int texture); void *load_png_gray(const char *fn, unsigned *width, unsigned *height, int texture); @@ -83,8 +35,5 @@ struct model { struct model *load_wavefront_obj(const char *fn); -#ifdef __cplusplus -} -#endif #endif