tinygi
changeset 0:16fdca2a1ef5
initial tinygi commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 19 Jul 2015 18:30:29 +0300 |
parents | |
children | bc64090fe3d1 |
files | .hgignore Makefile src/dynarr.c src/dynarr.h src/logger.c src/logger.h src/main.c src/object.c src/object.h src/scene.c src/tgi_impl.h src/tinygi.h |
diffstat | 12 files changed, 370 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Sun Jul 19 18:30:29 2015 +0300 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.swp$ 1.6 +\.d$ 1.7 +^tgi$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Sun Jul 19 18:30:29 2015 +0300 2.3 @@ -0,0 +1,23 @@ 2.4 +src = $(wildcard src/*.c) 2.5 +obj = $(src:.c=.o) 2.6 +dep = $(obj:.o=.d) 2.7 + 2.8 +bin = tgi 2.9 + 2.10 +CFLAGS = -pedantic -Wall -g 2.11 + 2.12 +$(bin): $(obj) 2.13 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.14 + 2.15 +-include $(dep) 2.16 + 2.17 +%.d: %.c 2.18 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 2.19 + 2.20 +.PHONY: clean 2.21 +clean: 2.22 + rm -f $(obj) $(bin) 2.23 + 2.24 +.PHONY: cleandep 2.25 +cleandep: 2.26 + rm -f $(dep)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/dynarr.c Sun Jul 19 18:30:29 2015 +0300 3.3 @@ -0,0 +1,128 @@ 3.4 +/* dynarr - dynamic resizable C array data structure 3.5 + * author: John Tsiombikas <nuclear@member.fsf.org> 3.6 + * license: public domain 3.7 + */ 3.8 +#include <stdio.h> 3.9 +#include <stdlib.h> 3.10 +#include <string.h> 3.11 +#include "dynarr.h" 3.12 + 3.13 +/* The array descriptor keeps auxilliary information needed to manipulate 3.14 + * the dynamic array. It's allocated adjacent to the array buffer. 3.15 + */ 3.16 +struct arrdesc { 3.17 + int nelem, szelem; 3.18 + int max_elem; 3.19 + int bufsz; /* not including the descriptor */ 3.20 +}; 3.21 + 3.22 +#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) 3.23 + 3.24 +void *dynarr_alloc(int elem, int szelem) 3.25 +{ 3.26 + struct arrdesc *desc; 3.27 + 3.28 + if(!(desc = malloc(elem * szelem + sizeof *desc))) { 3.29 + return 0; 3.30 + } 3.31 + desc->nelem = desc->max_elem = elem; 3.32 + desc->szelem = szelem; 3.33 + desc->bufsz = elem * szelem; 3.34 + return (char*)desc + sizeof *desc; 3.35 +} 3.36 + 3.37 +void dynarr_free(void *da) 3.38 +{ 3.39 + if(da) { 3.40 + free(DESC(da)); 3.41 + } 3.42 +} 3.43 + 3.44 +void *dynarr_resize(void *da, int elem) 3.45 +{ 3.46 + int newsz; 3.47 + void *tmp; 3.48 + struct arrdesc *desc; 3.49 + 3.50 + if(!da) return 0; 3.51 + desc = DESC(da); 3.52 + 3.53 + newsz = desc->szelem * elem; 3.54 + 3.55 + if(!(tmp = realloc(desc, newsz + sizeof *desc))) { 3.56 + return 0; 3.57 + } 3.58 + desc = tmp; 3.59 + 3.60 + desc->nelem = desc->max_elem = elem; 3.61 + desc->bufsz = newsz; 3.62 + return (char*)desc + sizeof *desc; 3.63 +} 3.64 + 3.65 +int dynarr_empty(void *da) 3.66 +{ 3.67 + return DESC(da)->nelem ? 0 : 1; 3.68 +} 3.69 + 3.70 +int dynarr_size(void *da) 3.71 +{ 3.72 + return DESC(da)->nelem; 3.73 +} 3.74 + 3.75 + 3.76 +/* stack semantics */ 3.77 +void *dynarr_push(void *da, void *item) 3.78 +{ 3.79 + struct arrdesc *desc; 3.80 + int nelem; 3.81 + 3.82 + desc = DESC(da); 3.83 + nelem = desc->nelem; 3.84 + 3.85 + if(nelem >= desc->max_elem) { 3.86 + /* need to resize */ 3.87 + struct arrdesc *tmp; 3.88 + int newsz = desc->max_elem ? desc->max_elem * 2 : 1; 3.89 + 3.90 + if(!(tmp = dynarr_resize(da, newsz))) { 3.91 + fprintf(stderr, "failed to resize\n"); 3.92 + return da; 3.93 + } 3.94 + da = tmp; 3.95 + desc = DESC(da); 3.96 + desc->nelem = nelem; 3.97 + } 3.98 + 3.99 + if(item) { 3.100 + memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); 3.101 + } 3.102 + return da; 3.103 +} 3.104 + 3.105 +void *dynarr_pop(void *da) 3.106 +{ 3.107 + struct arrdesc *desc; 3.108 + int nelem; 3.109 + 3.110 + desc = DESC(da); 3.111 + nelem = desc->nelem; 3.112 + 3.113 + if(!nelem) return da; 3.114 + 3.115 + if(nelem <= desc->max_elem / 3) { 3.116 + /* reclaim space */ 3.117 + struct arrdesc *tmp; 3.118 + int newsz = desc->max_elem / 2; 3.119 + 3.120 + if(!(tmp = dynarr_resize(da, newsz))) { 3.121 + fprintf(stderr, "failed to resize\n"); 3.122 + return da; 3.123 + } 3.124 + da = tmp; 3.125 + desc = DESC(da); 3.126 + desc->nelem = nelem; 3.127 + } 3.128 + desc->nelem--; 3.129 + 3.130 + return da; 3.131 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/dynarr.h Sun Jul 19 18:30:29 2015 +0300 4.3 @@ -0,0 +1,20 @@ 4.4 +/* dynarr - dynamic resizable C array data structure 4.5 + * author: John Tsiombikas <nuclear@member.fsf.org> 4.6 + * license: public domain 4.7 + */ 4.8 +#ifndef DYNARR_H_ 4.9 +#define DYNARR_H_ 4.10 + 4.11 +void *dynarr_alloc(int elem, int szelem); 4.12 +void dynarr_free(void *da); 4.13 +void *dynarr_resize(void *da, int elem); 4.14 + 4.15 +int dynarr_empty(void *da); 4.16 +int dynarr_size(void *da); 4.17 + 4.18 +/* stack semantics */ 4.19 +void *dynarr_push(void *da, void *item); 4.20 +void *dynarr_pop(void *da); 4.21 + 4.22 + 4.23 +#endif /* DYNARR_H_ */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/logger.c Sun Jul 19 18:30:29 2015 +0300 5.3 @@ -0,0 +1,12 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdarg.h> 5.6 +#include "logger.h" 5.7 + 5.8 +void tgi_log(const char *fmt, ...) 5.9 +{ 5.10 + va_list ap; 5.11 + 5.12 + va_start(ap, fmt); 5.13 + vfprintf(stderr, fmt, ap); 5.14 + va_end(ap); 5.15 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/logger.h Sun Jul 19 18:30:29 2015 +0300 6.3 @@ -0,0 +1,6 @@ 6.4 +#ifndef TGI_LOGGER_H_ 6.5 +#define TGI_LOGGER_H_ 6.6 + 6.7 +void tgi_log(const char *fmt, ...); 6.8 + 6.9 +#endif /* TGI_LOGGER_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/main.c Sun Jul 19 18:30:29 2015 +0300 7.3 @@ -0,0 +1,4 @@ 7.4 +#include <stdio.h> 7.5 +#include "tinygi.h" 7.6 + 7.7 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/object.c Sun Jul 19 18:30:29 2015 +0300 8.3 @@ -0,0 +1,16 @@ 8.4 +#include <stdlib.h> 8.5 +#include <string.h> 8.6 +#include "object.h" 8.7 +#include "logger.h" 8.8 + 8.9 +struct tgi_object *tgi_create_object(const char *name) 8.10 +{ 8.11 + struct tgi_object *o; 8.12 + 8.13 + if(!(o = malloc(sizeof *o))) { 8.14 + tgi_log("failed to allocate memory\n"); 8.15 + return 0; 8.16 + } 8.17 + memset(o, 0, sizeof *o); 8.18 + return o; 8.19 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/object.h Sun Jul 19 18:30:29 2015 +0300 9.3 @@ -0,0 +1,13 @@ 9.4 +#ifndef TGI_OBJECT_H_ 9.5 +#define TGI_OBJECT_H_ 9.6 + 9.7 +#include "tinygi.h" 9.8 + 9.9 +struct tgi_object { 9.10 + char *name; 9.11 + struct tgi_shape *shape; 9.12 + 9.13 + struct tgi_object *next; /* for linking it into various lists */ 9.14 +}; 9.15 + 9.16 +#endif /* TGI_OBJECT_H_ */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/scene.c Sun Jul 19 18:30:29 2015 +0300 10.3 @@ -0,0 +1,98 @@ 10.4 +#include <stdlib.h> 10.5 +#include <string.h> 10.6 +#include <assert.h> 10.7 +#include "tgi_impl.h" 10.8 +#include "object.h" 10.9 +#include "dynarr.h" 10.10 + 10.11 +struct tinygi *tgi_init(void) 10.12 +{ 10.13 + struct tinygi *tgi; 10.14 + 10.15 + if(!(tgi = malloc(sizeof *tgi))) { 10.16 + tgi_log("failed to allocate memory\n"); 10.17 + return 0; 10.18 + } 10.19 + if(!(tgi->objects = dynarr_alloc(0, sizeof *tgi->objects))) { 10.20 + tgi_log("failed to allocate objects array\n"); 10.21 + free(tgi); 10.22 + return 0; 10.23 + } 10.24 + 10.25 + return tgi; 10.26 +} 10.27 + 10.28 +void tgi_destroy(struct tinygi *tgi) 10.29 +{ 10.30 + tgi_clear_scene(tgi); 10.31 + free(tgi); 10.32 +} 10.33 + 10.34 +void tgi_clear_scene(struct tinygi *tgi) 10.35 +{ 10.36 + int i, nobj = dynarr_size(tgi->objects); 10.37 + 10.38 + for(i=0; i<nobj; i++) { 10.39 + tgi_destroy_object(tgi->objects[i]); 10.40 + } 10.41 + tgi->objects = dynarr_resize(tgi->objects, 0); 10.42 + assert(tgi->objects); 10.43 +} 10.44 + 10.45 +int tgi_load_scene(struct tinygi *tgi, const char *fname) 10.46 +{ 10.47 + return -1; /* TODO implement later */ 10.48 +} 10.49 + 10.50 +void tgi_add_object(struct tinygi *tgi, struct tgi_object *o) 10.51 +{ 10.52 + tgi->objects = dynarr_push(tgi->objects, o); 10.53 + assert(tgi->objects); 10.54 +} 10.55 + 10.56 +int tgi_del_object(struct tinygi *tgi, struct tgi_object *o) 10.57 +{ 10.58 + int i, idx = -1, sz = dynarr_size(tgi->objects); 10.59 + 10.60 + if(!sz) return -1; 10.61 + 10.62 + for(i=0; i<sz; i++) { 10.63 + if(tgi->objects[i] == o) { 10.64 + idx = i; 10.65 + break; 10.66 + } 10.67 + } 10.68 + if(idx == -1) { 10.69 + return -1; 10.70 + } 10.71 + 10.72 + tgi->objects[idx] = tgi->objects[sz - 1]; 10.73 + tgi->objects = dynarr_pop(tgi->objects); 10.74 + assert(tgi->objects); 10.75 + return 0; 10.76 +} 10.77 + 10.78 +struct tgi_object *tgi_find_object(struct tinygi *tgi, const char *name) 10.79 +{ 10.80 + int i, sz = dynarr_size(tgi->objects); 10.81 + 10.82 + for(i=0; i<sz; i++) { 10.83 + if(strcmp(tgi->objects[i]->name, name) == 0) { 10.84 + return tgi->objects[i]; 10.85 + } 10.86 + } 10.87 + return 0; 10.88 +} 10.89 + 10.90 + 10.91 +struct tgi_object *tgi_get_object(struct tinygi *tgi, int idx) 10.92 +{ 10.93 + return tgi->objects[idx]; 10.94 +} 10.95 + 10.96 +int tgi_get_object_count(struct tinygi *tgi) 10.97 +{ 10.98 + return dynarr_size(tgi->objects); 10.99 +} 10.100 + 10.101 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/tgi_impl.h Sun Jul 19 18:30:29 2015 +0300 11.3 @@ -0,0 +1,12 @@ 11.4 +#ifndef TGI_IMPL_H_ 11.5 +#define TGI_IMPL_H_ 11.6 + 11.7 +#include "tinygi.h" 11.8 +#include "object.h" 11.9 +#include "logger.h" 11.10 + 11.11 +struct tinygi { 11.12 + struct tgi_object **objects; /* dynarr */ 11.13 +}; 11.14 + 11.15 +#endif /* TGI_IMPL_H_ */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/tinygi.h Sun Jul 19 18:30:29 2015 +0300 12.3 @@ -0,0 +1,34 @@ 12.4 +#ifndef TINYGI_H_ 12.5 +#define TINYGI_H_ 12.6 + 12.7 +struct tgi_vec3 { float x, y, z; }; 12.8 + 12.9 +struct tinygi; 12.10 +struct tgi_object; 12.11 +struct tgi_shape; 12.12 + 12.13 +struct tinygi *tgi_init(void); 12.14 +void tgi_destroy(struct tinygi *tgi); 12.15 + 12.16 +void tgi_clear_scene(struct tinygi *tgi); 12.17 +int tgi_load_scene(struct tinygi *tgi, const char *fname); 12.18 +void tgi_add_object(struct tinygi *tgi, struct tgi_object *o); 12.19 +int tgi_del_object(struct tinygi *tgi, struct tgi_object *o); 12.20 + 12.21 +struct tgi_object *tgi_find_object(struct tinygi *tgi, const char *name); 12.22 +struct tgi_object *tgi_get_object(struct tinygi *tgi, int idx); 12.23 +int tgi_get_object_count(struct tinygi *tgi); 12.24 + 12.25 +/* shapes */ 12.26 +struct tgi_shape *tgi_create_sphere(float rad); 12.27 +struct tgi_shape *tgi_create_box(float x0, float y0, float z0, float x1, float y1, float z1); 12.28 +void tgi_destroy_shape(struct tgi_shape *s); 12.29 + 12.30 +/* objects */ 12.31 +/* name can be null, in which case it's automatically generated */ 12.32 +struct tgi_object *tgi_create_object(const char *name); 12.33 +void tgi_destroy_object(struct tgi_object *o); 12.34 +void tgi_set_object_shape(struct tgi_object *o, struct tgi_shape *s); 12.35 +void tgi_set_object_mtl(struct tgi_object *o, struct tgi_material *m); 12.36 + 12.37 +#endif /* TINYGI_H_ */