# HG changeset patch # User John Tsiombikas # Date 1437319829 -10800 # Node ID 16fdca2a1ef51c880ce453ae112477e438b84114 initial tinygi commit diff -r 000000000000 -r 16fdca2a1ef5 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,4 @@ +\.o$ +\.swp$ +\.d$ +^tgi$ diff -r 000000000000 -r 16fdca2a1ef5 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,23 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) + +bin = tgi + +CFLAGS = -pedantic -Wall -g + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) + +.PHONY: cleandep +cleandep: + rm -f $(dep) diff -r 000000000000 -r 16fdca2a1ef5 src/dynarr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dynarr.c Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,128 @@ +/* dynarr - dynamic resizable C array data structure + * author: John Tsiombikas + * license: public domain + */ +#include +#include +#include +#include "dynarr.h" + +/* The array descriptor keeps auxilliary information needed to manipulate + * the dynamic array. It's allocated adjacent to the array buffer. + */ +struct arrdesc { + int nelem, szelem; + int max_elem; + int bufsz; /* not including the descriptor */ +}; + +#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) + +void *dynarr_alloc(int elem, int szelem) +{ + struct arrdesc *desc; + + if(!(desc = malloc(elem * szelem + sizeof *desc))) { + return 0; + } + desc->nelem = desc->max_elem = elem; + desc->szelem = szelem; + desc->bufsz = elem * szelem; + return (char*)desc + sizeof *desc; +} + +void dynarr_free(void *da) +{ + if(da) { + free(DESC(da)); + } +} + +void *dynarr_resize(void *da, int elem) +{ + int newsz; + void *tmp; + struct arrdesc *desc; + + if(!da) return 0; + desc = DESC(da); + + newsz = desc->szelem * elem; + + if(!(tmp = realloc(desc, newsz + sizeof *desc))) { + return 0; + } + desc = tmp; + + desc->nelem = desc->max_elem = elem; + desc->bufsz = newsz; + return (char*)desc + sizeof *desc; +} + +int dynarr_empty(void *da) +{ + return DESC(da)->nelem ? 0 : 1; +} + +int dynarr_size(void *da) +{ + return DESC(da)->nelem; +} + + +/* stack semantics */ +void *dynarr_push(void *da, void *item) +{ + struct arrdesc *desc; + int nelem; + + desc = DESC(da); + nelem = desc->nelem; + + if(nelem >= desc->max_elem) { + /* need to resize */ + struct arrdesc *tmp; + int newsz = desc->max_elem ? desc->max_elem * 2 : 1; + + if(!(tmp = dynarr_resize(da, newsz))) { + fprintf(stderr, "failed to resize\n"); + return da; + } + da = tmp; + desc = DESC(da); + desc->nelem = nelem; + } + + if(item) { + memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); + } + return da; +} + +void *dynarr_pop(void *da) +{ + struct arrdesc *desc; + int nelem; + + desc = DESC(da); + nelem = desc->nelem; + + if(!nelem) return da; + + if(nelem <= desc->max_elem / 3) { + /* reclaim space */ + struct arrdesc *tmp; + int newsz = desc->max_elem / 2; + + if(!(tmp = dynarr_resize(da, newsz))) { + fprintf(stderr, "failed to resize\n"); + return da; + } + da = tmp; + desc = DESC(da); + desc->nelem = nelem; + } + desc->nelem--; + + return da; +} diff -r 000000000000 -r 16fdca2a1ef5 src/dynarr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dynarr.h Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,20 @@ +/* dynarr - dynamic resizable C array data structure + * author: John Tsiombikas + * license: public domain + */ +#ifndef DYNARR_H_ +#define DYNARR_H_ + +void *dynarr_alloc(int elem, int szelem); +void dynarr_free(void *da); +void *dynarr_resize(void *da, int elem); + +int dynarr_empty(void *da); +int dynarr_size(void *da); + +/* stack semantics */ +void *dynarr_push(void *da, void *item); +void *dynarr_pop(void *da); + + +#endif /* DYNARR_H_ */ diff -r 000000000000 -r 16fdca2a1ef5 src/logger.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/logger.c Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,12 @@ +#include +#include +#include "logger.h" + +void tgi_log(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} diff -r 000000000000 -r 16fdca2a1ef5 src/logger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/logger.h Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,6 @@ +#ifndef TGI_LOGGER_H_ +#define TGI_LOGGER_H_ + +void tgi_log(const char *fmt, ...); + +#endif /* TGI_LOGGER_H_ */ diff -r 000000000000 -r 16fdca2a1ef5 src/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.c Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,4 @@ +#include +#include "tinygi.h" + + diff -r 000000000000 -r 16fdca2a1ef5 src/object.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/object.c Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,16 @@ +#include +#include +#include "object.h" +#include "logger.h" + +struct tgi_object *tgi_create_object(const char *name) +{ + struct tgi_object *o; + + if(!(o = malloc(sizeof *o))) { + tgi_log("failed to allocate memory\n"); + return 0; + } + memset(o, 0, sizeof *o); + return o; +} diff -r 000000000000 -r 16fdca2a1ef5 src/object.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/object.h Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,13 @@ +#ifndef TGI_OBJECT_H_ +#define TGI_OBJECT_H_ + +#include "tinygi.h" + +struct tgi_object { + char *name; + struct tgi_shape *shape; + + struct tgi_object *next; /* for linking it into various lists */ +}; + +#endif /* TGI_OBJECT_H_ */ diff -r 000000000000 -r 16fdca2a1ef5 src/scene.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/scene.c Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,98 @@ +#include +#include +#include +#include "tgi_impl.h" +#include "object.h" +#include "dynarr.h" + +struct tinygi *tgi_init(void) +{ + struct tinygi *tgi; + + if(!(tgi = malloc(sizeof *tgi))) { + tgi_log("failed to allocate memory\n"); + return 0; + } + if(!(tgi->objects = dynarr_alloc(0, sizeof *tgi->objects))) { + tgi_log("failed to allocate objects array\n"); + free(tgi); + return 0; + } + + return tgi; +} + +void tgi_destroy(struct tinygi *tgi) +{ + tgi_clear_scene(tgi); + free(tgi); +} + +void tgi_clear_scene(struct tinygi *tgi) +{ + int i, nobj = dynarr_size(tgi->objects); + + for(i=0; iobjects[i]); + } + tgi->objects = dynarr_resize(tgi->objects, 0); + assert(tgi->objects); +} + +int tgi_load_scene(struct tinygi *tgi, const char *fname) +{ + return -1; /* TODO implement later */ +} + +void tgi_add_object(struct tinygi *tgi, struct tgi_object *o) +{ + tgi->objects = dynarr_push(tgi->objects, o); + assert(tgi->objects); +} + +int tgi_del_object(struct tinygi *tgi, struct tgi_object *o) +{ + int i, idx = -1, sz = dynarr_size(tgi->objects); + + if(!sz) return -1; + + for(i=0; iobjects[i] == o) { + idx = i; + break; + } + } + if(idx == -1) { + return -1; + } + + tgi->objects[idx] = tgi->objects[sz - 1]; + tgi->objects = dynarr_pop(tgi->objects); + assert(tgi->objects); + return 0; +} + +struct tgi_object *tgi_find_object(struct tinygi *tgi, const char *name) +{ + int i, sz = dynarr_size(tgi->objects); + + for(i=0; iobjects[i]->name, name) == 0) { + return tgi->objects[i]; + } + } + return 0; +} + + +struct tgi_object *tgi_get_object(struct tinygi *tgi, int idx) +{ + return tgi->objects[idx]; +} + +int tgi_get_object_count(struct tinygi *tgi) +{ + return dynarr_size(tgi->objects); +} + + diff -r 000000000000 -r 16fdca2a1ef5 src/tgi_impl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tgi_impl.h Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,12 @@ +#ifndef TGI_IMPL_H_ +#define TGI_IMPL_H_ + +#include "tinygi.h" +#include "object.h" +#include "logger.h" + +struct tinygi { + struct tgi_object **objects; /* dynarr */ +}; + +#endif /* TGI_IMPL_H_ */ diff -r 000000000000 -r 16fdca2a1ef5 src/tinygi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tinygi.h Sun Jul 19 18:30:29 2015 +0300 @@ -0,0 +1,34 @@ +#ifndef TINYGI_H_ +#define TINYGI_H_ + +struct tgi_vec3 { float x, y, z; }; + +struct tinygi; +struct tgi_object; +struct tgi_shape; + +struct tinygi *tgi_init(void); +void tgi_destroy(struct tinygi *tgi); + +void tgi_clear_scene(struct tinygi *tgi); +int tgi_load_scene(struct tinygi *tgi, const char *fname); +void tgi_add_object(struct tinygi *tgi, struct tgi_object *o); +int tgi_del_object(struct tinygi *tgi, struct tgi_object *o); + +struct tgi_object *tgi_find_object(struct tinygi *tgi, const char *name); +struct tgi_object *tgi_get_object(struct tinygi *tgi, int idx); +int tgi_get_object_count(struct tinygi *tgi); + +/* shapes */ +struct tgi_shape *tgi_create_sphere(float rad); +struct tgi_shape *tgi_create_box(float x0, float y0, float z0, float x1, float y1, float z1); +void tgi_destroy_shape(struct tgi_shape *s); + +/* objects */ +/* name can be null, in which case it's automatically generated */ +struct tgi_object *tgi_create_object(const char *name); +void tgi_destroy_object(struct tgi_object *o); +void tgi_set_object_shape(struct tgi_object *o, struct tgi_shape *s); +void tgi_set_object_mtl(struct tgi_object *o, struct tgi_material *m); + +#endif /* TINYGI_H_ */