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_ */