rayzor

changeset 6:a68dbf80d547

finally showing something ... :)
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 07 Apr 2014 06:04:11 +0300
parents 5fcf72837b69
children 75bc89c2abc4
files Makefile src/gfx.c src/logger.c src/logger.h src/m3dimpl.h src/main.cc src/min3d.c src/min3d.h src/object.cc src/object.h src/scene.cc src/scene.h
diffstat 12 files changed, 371 insertions(+), 71 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Sun Apr 06 02:43:24 2014 +0300
     1.2 +++ b/Makefile	Mon Apr 07 06:04:11 2014 +0300
     1.3 @@ -5,15 +5,17 @@
     1.4  obj = $(modelobj) $(rendobj) $(scnobj) $(sysobj)
     1.5  bin = rayzor.exe
     1.6  
     1.7 +#dbg = -d2
     1.8 +
     1.9  CC = wcc386
    1.10  CXX = wpp386
    1.11 -CFLAGS = -5 -fp5 -otexan -zq -bt=dos -Isrc\stl
    1.12 +CFLAGS = $(dbg) -5 -fp5 -otexan -zq -bt=dos -Isrc\stl
    1.13  CXXFLAGS = $(CFLAGS)
    1.14  LD = wlink
    1.15  
    1.16  $(bin): $(obj)
    1.17  	%write objects.lnk file { $(obj) }
    1.18 -	$(LD) name $@ @objects $(LDFLAGS)
    1.19 +	$(LD) debug all name $@ @objects $(LDFLAGS)
    1.20  
    1.21  .c: src\
    1.22  .cc: src\
     2.1 --- a/src/gfx.c	Sun Apr 06 02:43:24 2014 +0300
     2.2 +++ b/src/gfx.c	Mon Apr 07 06:04:11 2014 +0300
     2.3 @@ -5,6 +5,7 @@
     2.4  #include <stdlib.h>
     2.5  #include <string.h>
     2.6  #include "vbe.h"
     2.7 +#include "logger.h"
     2.8  
     2.9  #define REALPTR(s, o)	(void*)(((uint32_t)(s) << 4) + (uint32_t)(o))
    2.10  #define VBEPTR(x)		REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff)
    2.11 @@ -33,15 +34,15 @@
    2.12  			return 0;
    2.13  		}
    2.14  
    2.15 -		printf("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
    2.16 +		printlog("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
    2.17  		if(vbe_info->version < 0x200) {
    2.18  			fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n");
    2.19  			return 0;
    2.20  		}
    2.21  
    2.22 -		printf("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr),
    2.23 +		printlog("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr),
    2.24  				VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr));
    2.25 -		printf("Video memory: %dmb\n", vbe_info->total_mem << 6);
    2.26 +		printlog("Video memory: %dmb\n", vbe_info->total_mem << 6);
    2.27  
    2.28  		modes = VBEPTR(vbe_info->vid_mode_ptr);
    2.29  	}
    2.30 @@ -75,7 +76,7 @@
    2.31  	/* attempt to set 8 bits of color per component in palettized modes */
    2.32  	if(bpp <= 8) {
    2.33  		pal_bits = vbe_set_palette_bits(8);
    2.34 -		printf("palette bits per color primary: %d\n", pal_bits);
    2.35 +		printlog("palette bits per color primary: %d\n", pal_bits);
    2.36  	}
    2.37  
    2.38  	fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT);
     3.1 --- a/src/logger.c	Sun Apr 06 02:43:24 2014 +0300
     3.2 +++ b/src/logger.c	Mon Apr 07 06:04:11 2014 +0300
     3.3 @@ -6,6 +6,12 @@
     3.4  
     3.5  static FILE *logfile;
     3.6  
     3.7 +void logger_output(FILE *fp)
     3.8 +{
     3.9 +	if(logfile) fclose(logfile);
    3.10 +	logfile = fp;
    3.11 +}
    3.12 +
    3.13  void printlog(const char *fmt, ...)
    3.14  {
    3.15  	va_list ap;
     4.1 --- a/src/logger.h	Sun Apr 06 02:43:24 2014 +0300
     4.2 +++ b/src/logger.h	Mon Apr 07 06:04:11 2014 +0300
     4.3 @@ -1,10 +1,13 @@
     4.4  #ifndef LOGGER_H_
     4.5  #define LOGGER_H_
     4.6  
     4.7 +#include <stdio.h>
     4.8 +
     4.9  #ifdef __cplusplus
    4.10  extern "C" {
    4.11  #endif
    4.12  
    4.13 +void logger_output(FILE *fp);
    4.14  void printlog(const char *fmt, ...);
    4.15  
    4.16  #ifdef __cplusplus
     5.1 --- a/src/m3dimpl.h	Sun Apr 06 02:43:24 2014 +0300
     5.2 +++ b/src/m3dimpl.h	Mon Apr 07 06:04:11 2014 +0300
     5.3 @@ -17,24 +17,35 @@
     5.4  	float tex[2];
     5.5  };
     5.6  
     5.7 +#define IM_VBSIZE	4
     5.8 +
     5.9  struct min3d_context {
    5.10  	struct m3d_image *cbuf;
    5.11  	uint16_t *zbuf;
    5.12  
    5.13  	unsigned long state;
    5.14 +	int clear_color[3];
    5.15  
    5.16  	int mmode;	/* matrix mode */
    5.17  	struct min3d_mstack mstack[2];
    5.18  
    5.19 -	const float *vert_array;
    5.20 -	const float *norm_array;
    5.21 -	const float *col_array;
    5.22 -	const float *tc_array;
    5.23 +	int vport[4];
    5.24 +
    5.25 +	float *vert_array;
    5.26 +	float *norm_array;
    5.27 +	float *col_array;
    5.28 +	float *tc_array;
    5.29  
    5.30  	/* immediate mode state */
    5.31 -	float cur_color[4];
    5.32 -	float cur_normal[3];
    5.33 -	float cur_texcoord[2];
    5.34 +	float im_varr[IM_VBSIZE * 3];
    5.35 +	float im_narr[IM_VBSIZE * 3];
    5.36 +	float im_carr[IM_VBSIZE * 3];
    5.37 +	float im_tarr[IM_VBSIZE * 2];
    5.38 +
    5.39 +	int im_prim, im_idx;
    5.40 +	float im_color[4];
    5.41 +	float im_normal[3];
    5.42 +	float im_texcoord[2];
    5.43  };
    5.44  
    5.45  extern struct min3d_context *m3dctx;
     6.1 --- a/src/main.cc	Sun Apr 06 02:43:24 2014 +0300
     6.2 +++ b/src/main.cc	Mon Apr 07 06:04:11 2014 +0300
     6.3 @@ -7,17 +7,22 @@
     6.4  #include "keyb.h"
     6.5  #include "mouse.h"
     6.6  #include "logger.h"
     6.7 +#include "min3d.h"
     6.8 +#include "scene.h"
     6.9  
    6.10 +static bool init();
    6.11 +static void cleanup();
    6.12  static void display();
    6.13  static void swap_buffers();
    6.14  static void handle_keyboard();
    6.15  static void handle_mouse();
    6.16  static bool parse_args(int argc, char **argv);
    6.17  
    6.18 -static int xsz = 800;
    6.19 -static int ysz = 600;
    6.20 +static int xsz = 640;
    6.21 +static int ysz = 480;
    6.22  static int bpp = 16;
    6.23  static int bytespp;
    6.24 +static bool novideo;
    6.25  static unsigned char *fb;
    6.26  static unsigned char *backbuf;
    6.27  static int rbits, gbits, bbits;
    6.28 @@ -26,31 +31,17 @@
    6.29  
    6.30  static bool quit;
    6.31  
    6.32 +struct m3d_image rbuf;
    6.33 +static Scene *scn;
    6.34 +
    6.35  int main(int argc, char **argv)
    6.36  {
    6.37  	if(!parse_args(argc, argv)) {
    6.38  		return 1;
    6.39  	}
    6.40 -	if(kb_init(32) == -1) {
    6.41 -		fprintf(stderr, "failed to initialize keyboard driver\n");
    6.42 +	if(!init()) {
    6.43  		return 1;
    6.44  	}
    6.45 -	if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) {
    6.46 -		set_text_mode();
    6.47 -		fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp);
    6.48 -		return 1;
    6.49 -	}
    6.50 -	bpp = get_color_depth();
    6.51 -	get_color_bits(&rbits, &gbits, &bbits);
    6.52 -	get_color_shift(&rshift, &gshift, &bshift);
    6.53 -	get_color_mask(&rmask, &gmask, &bmask);
    6.54 -	bytespp = (int)ceil(bpp / 8.0);
    6.55 -
    6.56 -	printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
    6.57 -	printlog("shift: %d %d %d\n", rshift, gshift, bshift);
    6.58 -	printlog("mask: %x %x %x\n", rmask, gmask, bmask);
    6.59 -
    6.60 -	backbuf = new unsigned char[xsz * ysz * 3];
    6.61  
    6.62  	// main loop
    6.63  	for(;;) {
    6.64 @@ -59,33 +50,96 @@
    6.65  		if(quit) break;
    6.66  
    6.67  		display();
    6.68 +
    6.69 +		if(novideo) break;
    6.70  	}
    6.71  
    6.72 -	delete [] backbuf;
    6.73 -
    6.74 -	set_text_mode();
    6.75 -	kb_shutdown();
    6.76 -
    6.77 +	cleanup();
    6.78  	printf("Thank you for using Rayzor!\n");
    6.79  	return 0;
    6.80  }
    6.81  
    6.82 +static bool init()
    6.83 +{
    6.84 +	if(!novideo) {
    6.85 +		if(kb_init(32) == -1) {
    6.86 +			fprintf(stderr, "failed to initialize keyboard driver\n");
    6.87 +			return false;
    6.88 +		}
    6.89 +
    6.90 +		if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) {
    6.91 +			set_text_mode();
    6.92 +			fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp);
    6.93 +			return false;
    6.94 +		}
    6.95 +		bpp = get_color_depth();
    6.96 +		get_color_bits(&rbits, &gbits, &bbits);
    6.97 +		get_color_shift(&rshift, &gshift, &bshift);
    6.98 +		get_color_mask(&rmask, &gmask, &bmask);
    6.99 +		bytespp = (int)ceil(bpp / 8.0);
   6.100 +
   6.101 +		printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
   6.102 +		printlog("shift: %d %d %d\n", rshift, gshift, bshift);
   6.103 +		printlog("mask: %x %x %x\n", rmask, gmask, bmask);
   6.104 +	} else {
   6.105 +		logger_output(stdout);
   6.106 +		printlog("novideo (debug) mode\n");
   6.107 +		bpp = 24;
   6.108 +		rbits = gbits = bbits = 8;
   6.109 +		bytespp = 3;
   6.110 +	}
   6.111 +
   6.112 +	backbuf = new unsigned char[xsz * ysz * 3];
   6.113 +	if(!backbuf) {
   6.114 +		return false;
   6.115 +	}
   6.116 +
   6.117 +	m3d_init();
   6.118 +	rbuf.pixels = backbuf;
   6.119 +	rbuf.xsz = xsz;
   6.120 +	rbuf.ysz = ysz;
   6.121 +	m3d_set_buffers(&rbuf, 0);
   6.122 +
   6.123 +	m3d_matrix_mode(M3D_PROJECTION);
   6.124 +	m3d_load_identity();
   6.125 +	m3d_perspective(50.0, (float)xsz / (float)ysz, 0.5, 500.0);
   6.126 +
   6.127 +	scn = new Scene;
   6.128 +
   6.129 +	Sphere *sph = new Sphere;
   6.130 +	scn->add_object(sph);
   6.131 +
   6.132 +	return true;
   6.133 +}
   6.134 +
   6.135 +static void cleanup()
   6.136 +{
   6.137 +	delete scn;
   6.138 +
   6.139 +	m3d_shutdown();
   6.140 +	delete [] backbuf;
   6.141 +
   6.142 +	if(!novideo) {
   6.143 +		set_text_mode();
   6.144 +		kb_shutdown();
   6.145 +	}
   6.146 +}
   6.147 +
   6.148 +
   6.149  static void display()
   6.150  {
   6.151 -	unsigned char *fbptr = backbuf;
   6.152 +	m3d_clear(M3D_COLOR_BUFFER_BIT);
   6.153  
   6.154 -	for(int i=0; i<ysz; i++) {
   6.155 -		for(int j=0; j<xsz; j++) {
   6.156 -			bool chess = ((i / 16) & 1) == ((j / 16) & 1);
   6.157 -			fbptr[chess ? 0 : 2] = 255;
   6.158 -			fbptr[1] = 128;
   6.159 -			fbptr[chess ? 2 : 0] = 32;
   6.160 -			fbptr += 3;
   6.161 -		}
   6.162 +	m3d_matrix_mode(M3D_MODELVIEW);
   6.163 +	m3d_load_identity();
   6.164 +	m3d_translate(0, 0, -10);
   6.165 +
   6.166 +	scn->draw();
   6.167 +
   6.168 +	if(!novideo) {
   6.169 +		swap_buffers();
   6.170 +		wait_vsync();
   6.171  	}
   6.172 -
   6.173 -	swap_buffers();
   6.174 -	wait_vsync();
   6.175  }
   6.176  
   6.177  #define PACK_RGB(r, g, b) \
   6.178 @@ -136,6 +190,8 @@
   6.179  {
   6.180  	int key;
   6.181  
   6.182 +	if(novideo) return;
   6.183 +
   6.184  	while((key = kb_getkey()) != -1) {
   6.185  		switch(key) {
   6.186  		case 27:
   6.187 @@ -155,6 +211,7 @@
   6.188  	const char *desc;
   6.189  } options[] = {
   6.190  	{'s', "size", "resolution <xres>x<yres>[:bpp]"},
   6.191 +	{'n', "novid", "don't switch video mode (for debugging)"},
   6.192  	{'h', "help", "print usage information and exit"},
   6.193  	{-1, 0, 0}
   6.194  };
   6.195 @@ -196,6 +253,10 @@
   6.196  				}
   6.197  				break;
   6.198  
   6.199 +			case 'n':
   6.200 +				novideo = true;
   6.201 +				break;
   6.202 +
   6.203  			case 'h':
   6.204  				print_usage(argv[0]);	// doesn't return
   6.205  				break;
     7.1 --- a/src/min3d.c	Sun Apr 06 02:43:24 2014 +0300
     7.2 +++ b/src/min3d.c	Mon Apr 07 06:04:11 2014 +0300
     7.3 @@ -3,6 +3,7 @@
     7.4  #include <math.h>
     7.5  #include "min3d.h"
     7.6  #include "m3dimpl.h"
     7.7 +#include "logger.h"
     7.8  
     7.9  #ifndef M_PI
    7.10  #define M_PI	3.141592653
    7.11 @@ -21,6 +22,8 @@
    7.12  	m3d_load_identity();
    7.13  	m3d_matrix_mode(M3D_MODELVIEW);
    7.14  	m3d_load_identity();
    7.15 +
    7.16 +	m3d_color(1, 1, 1);
    7.17  	return 0;
    7.18  }
    7.19  
    7.20 @@ -33,13 +36,33 @@
    7.21  {
    7.22  	m3dctx->cbuf = cbuf;
    7.23  	m3dctx->zbuf = zbuf;
    7.24 +
    7.25 +	m3dctx->vport[0] = m3dctx->vport[1] = 0;
    7.26 +	m3dctx->vport[2] = cbuf->xsz;
    7.27 +	m3dctx->vport[3] = cbuf->ysz;
    7.28 +}
    7.29 +
    7.30 +void m3d_clear_color(float r, float g, float b)
    7.31 +{
    7.32 +	m3dctx->clear_color[0] = (int)((r > 1.0 ? 1.0 : r) * 255.0);
    7.33 +	m3dctx->clear_color[1] = (int)((g > 1.0 ? 1.0 : g) * 255.0);
    7.34 +	m3dctx->clear_color[2] = (int)((b > 1.0 ? 1.0 : b) * 255.0);
    7.35  }
    7.36  
    7.37  void m3d_clear(unsigned int bmask)
    7.38  {
    7.39 -	int num_pixels = m3dctx->cbuf->xsz * m3dctx->cbuf->ysz;
    7.40 +	int i, num_pixels = m3dctx->cbuf->xsz * m3dctx->cbuf->ysz;
    7.41  	if(bmask & M3D_COLOR_BUFFER_BIT) {
    7.42 -		memset(m3dctx->cbuf->pixels, 0, num_pixels * 3);
    7.43 +		/*memset(m3dctx->cbuf->pixels, 0, num_pixels * 3);*/
    7.44 +		unsigned char *ptr = m3dctx->cbuf->pixels;
    7.45 +		unsigned char r = m3dctx->clear_color[0];
    7.46 +		unsigned char g = m3dctx->clear_color[1];
    7.47 +		unsigned char b = m3dctx->clear_color[2];
    7.48 +		for(i=0; i<num_pixels; i++) {
    7.49 +			*ptr++ = r;
    7.50 +			*ptr++ = g;
    7.51 +			*ptr++ = b;
    7.52 +		}
    7.53  	}
    7.54  	if(bmask & M3D_DEPTH_BUFFER_BIT) {
    7.55  		memset(m3dctx->zbuf, 0xff, num_pixels * sizeof *m3dctx->zbuf);
    7.56 @@ -64,6 +87,25 @@
    7.57  	m3dctx->mmode = mode;
    7.58  }
    7.59  
    7.60 +void m3d_push_matrix(void)
    7.61 +{
    7.62 +	int mm = m3dctx->mmode;
    7.63 +	int top = m3dctx->mstack[mm].top;
    7.64 +	if(top < MSTACK_SIZE) {
    7.65 +		float *cur = m3dctx->mstack[mm].m[top++];
    7.66 +		memcpy(m3dctx->mstack[mm].m[top], cur, 16 * sizeof *cur);
    7.67 +		m3dctx->mstack[mm].top = top;
    7.68 +	}
    7.69 +}
    7.70 +
    7.71 +void m3d_pop_matrix(void)
    7.72 +{
    7.73 +	int mm = m3dctx->mmode;
    7.74 +	if(m3dctx->mstack[mm].top > 0) {
    7.75 +		--m3dctx->mstack[mm].top;
    7.76 +	}
    7.77 +}
    7.78 +
    7.79  void m3d_load_identity(void)
    7.80  {
    7.81  	static const float mid[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
    7.82 @@ -171,10 +213,10 @@
    7.83  
    7.84  static void xform4(float *mat, float *vec)
    7.85  {
    7.86 -	float x = mat[0] * vec[0] + mat[1] * vec[1] + mat[2] * vec[2] + mat[3];
    7.87 -	float y = mat[4] * vec[0] + mat[5] * vec[1] + mat[6] * vec[2] + mat[7];
    7.88 -	float z = mat[8] * vec[0] + mat[9] * vec[1] + mat[10] * vec[2] + mat[11];
    7.89 -	float w = mat[12] * vec[0] + mat[13] * vec[1] + mat[14] * vec[2] + mat[15];
    7.90 +	float x = mat[0] * vec[0] + mat[4] * vec[1] + mat[8] * vec[2] + mat[12];
    7.91 +	float y = mat[1] * vec[0] + mat[5] * vec[1] + mat[9] * vec[2] + mat[13];
    7.92 +	float z = mat[2] * vec[0] + mat[6] * vec[1] + mat[10] * vec[2] + mat[14];
    7.93 +	float w = mat[3] * vec[0] + mat[7] * vec[1] + mat[11] * vec[2] + mat[15];
    7.94  
    7.95  	vec[0] = x;
    7.96  	vec[1] = y;
    7.97 @@ -188,6 +230,7 @@
    7.98  	int vcount = prim;
    7.99  	int mvtop, ptop;
   7.100  	float *mvmat, *pmat;
   7.101 +	int *vport = m3dctx->vport;
   7.102  
   7.103  	mvtop = m3dctx->mstack[M3D_MODELVIEW].top;
   7.104  	mvmat = m3dctx->mstack[M3D_MODELVIEW].m[mvtop];
   7.105 @@ -225,11 +268,14 @@
   7.106  		break;	/* TODO */
   7.107  	}
   7.108  
   7.109 -	/* perspective division */
   7.110 +	/* perspective division & viewport */
   7.111  	for(i=0; i<vcount; i++) {
   7.112 -		res[i].pos[0] = res[i].pos[3];
   7.113 -		res[i].pos[1] = res[i].pos[3];
   7.114 -		res[i].pos[2] = res[i].pos[3];
   7.115 +		res[i].pos[0] /= res[i].pos[3];
   7.116 +		res[i].pos[1] /= res[i].pos[3];
   7.117 +		res[i].pos[2] /= res[i].pos[3];
   7.118 +
   7.119 +		res[i].pos[0] = (res[i].pos[0] * 0.5 + 0.5) * vport[2] + vport[0];
   7.120 +		res[i].pos[1] = (res[i].pos[1] * 0.5 + 0.5) * vport[3] + vport[1];
   7.121  	}
   7.122  	return vcount;
   7.123  }
   7.124 @@ -237,22 +283,22 @@
   7.125  /* drawing */
   7.126  void m3d_vertex_array(const float *varr)
   7.127  {
   7.128 -	m3dctx->vert_array = varr;
   7.129 +	m3dctx->vert_array = (float*)varr;
   7.130  }
   7.131  
   7.132  void m3d_normal_array(const float *narr)
   7.133  {
   7.134 -	m3dctx->norm_array = narr;
   7.135 +	m3dctx->norm_array = (float*)narr;
   7.136  }
   7.137  
   7.138  void m3d_color_array(const float *carr)
   7.139  {
   7.140 -	m3dctx->col_array = carr;
   7.141 +	m3dctx->col_array = (float*)carr;
   7.142  }
   7.143  
   7.144  void m3d_texcoord_array(const float *tcarr)
   7.145  {
   7.146 -	m3dctx->tc_array = tcarr;
   7.147 +	m3dctx->tc_array = (float*)tcarr;
   7.148  }
   7.149  
   7.150  
   7.151 @@ -272,9 +318,10 @@
   7.152  		v[idx].pos[0] = *varr++;
   7.153  		v[idx].pos[1] = *varr++;
   7.154  		v[idx].pos[2] = *varr++;
   7.155 -		v[idx].color[0] = carr ? *carr++ : m3dctx->cur_color[0];
   7.156 -		v[idx].color[1] = carr ? *carr++ : m3dctx->cur_color[1];
   7.157 -		v[idx].color[2] = carr ? *carr++ : m3dctx->cur_color[2];
   7.158 +		v[idx].pos[3] = 1.0;
   7.159 +		v[idx].color[0] = carr ? *carr++ : m3dctx->im_color[0];
   7.160 +		v[idx].color[1] = carr ? *carr++ : m3dctx->im_color[1];
   7.161 +		v[idx].color[2] = carr ? *carr++ : m3dctx->im_color[2];
   7.162  
   7.163  		if(idx == prim - 1) {
   7.164  			int resnum = proc_prim(prim, resv, v);
   7.165 @@ -299,3 +346,73 @@
   7.166  	/* TODO */
   7.167  }
   7.168  
   7.169 +void m3d_begin(int prim)
   7.170 +{
   7.171 +	m3dctx->im_prim = prim;
   7.172 +	m3dctx->im_idx = 0;
   7.173 +
   7.174 +	m3dctx->vert_array = m3dctx->im_varr;
   7.175 +	m3dctx->norm_array = 0;
   7.176 +	m3dctx->col_array = 0;
   7.177 +	m3dctx->tc_array = 0;
   7.178 +}
   7.179 +
   7.180 +void m3d_end(void)
   7.181 +{
   7.182 +}
   7.183 +
   7.184 +void m3d_vertex(float x, float y, float z)
   7.185 +{
   7.186 +	int nverts = m3dctx->im_prim;
   7.187 +	int idx = m3dctx->im_idx;
   7.188 +	float *v = m3dctx->vert_array + idx * 3;
   7.189 +
   7.190 +	v[0] = x;
   7.191 +	v[1] = y;
   7.192 +	v[2] = z;
   7.193 +
   7.194 +	if(m3dctx->norm_array) {
   7.195 +		float *ptr = m3dctx->im_narr + idx * 3;
   7.196 +		ptr[0] = m3dctx->im_normal[0];
   7.197 +		ptr[1] = m3dctx->im_normal[1];
   7.198 +		ptr[2] = m3dctx->im_normal[2];
   7.199 +	}
   7.200 +	if(m3dctx->col_array) {
   7.201 +		float *ptr = m3dctx->im_carr + idx * 3;
   7.202 +		ptr[0] = m3dctx->im_color[0];
   7.203 +		ptr[1] = m3dctx->im_color[1];
   7.204 +		ptr[2] = m3dctx->im_color[2];
   7.205 +	}
   7.206 +	if(m3dctx->tc_array) {
   7.207 +		float *ptr = m3dctx->im_texcoord + idx * 2;
   7.208 +		ptr[0] = m3dctx->im_texcoord[0];
   7.209 +		ptr[1] = m3dctx->im_texcoord[1];
   7.210 +	}
   7.211 +
   7.212 +	if(++idx == nverts) {
   7.213 +		m3d_draw(m3dctx->im_prim, nverts);
   7.214 +		idx = 0;
   7.215 +	}
   7.216 +
   7.217 +	m3dctx->im_idx = idx;
   7.218 +}
   7.219 +
   7.220 +void m3d_normal(float x, float y, float z)
   7.221 +{
   7.222 +	m3dctx->im_normal[0] = x;
   7.223 +	m3dctx->im_normal[1] = y;
   7.224 +	m3dctx->im_normal[2] = z;
   7.225 +}
   7.226 +
   7.227 +void m3d_color(float x, float y, float z)
   7.228 +{
   7.229 +	m3dctx->im_color[0] = x;
   7.230 +	m3dctx->im_color[1] = y;
   7.231 +	m3dctx->im_color[2] = z;
   7.232 +}
   7.233 +
   7.234 +void m3d_texcoord(float x, float y)
   7.235 +{
   7.236 +	m3dctx->im_texcoord[0] = x;
   7.237 +	m3dctx->im_texcoord[1] = y;
   7.238 +}
     8.1 --- a/src/min3d.h	Sun Apr 06 02:43:24 2014 +0300
     8.2 +++ b/src/min3d.h	Mon Apr 07 06:04:11 2014 +0300
     8.3 @@ -43,7 +43,11 @@
     8.4  extern "C" {
     8.5  #endif
     8.6  
     8.7 +int m3d_init(void);
     8.8 +void m3d_shutdown(void);
     8.9 +
    8.10  void m3d_set_buffers(struct m3d_image *cbuf, uint16_t *zbuf);
    8.11 +void m3d_clear_color(float r, float g, float b);
    8.12  void m3d_clear(unsigned int bmask);
    8.13  
    8.14  void m3d_enable(int bit);
    8.15 @@ -51,6 +55,8 @@
    8.16  
    8.17  /* matrix stack */
    8.18  void m3d_matrix_mode(int mode);
    8.19 +void m3d_push_matrix(void);
    8.20 +void m3d_pop_matrix(void);
    8.21  void m3d_load_identity(void);
    8.22  void m3d_load_matrix(const float *m);
    8.23  void m3d_mult_matrix(const float *m);
    8.24 @@ -69,7 +75,13 @@
    8.25  void m3d_draw(int prim, int vcount);
    8.26  void m3d_draw_indexed(int prim, const int *idxarr, int icount);
    8.27  
    8.28 -/* TODO immediate mode */
    8.29 +/* immediate mode interface */
    8.30 +void m3d_begin(int prim);
    8.31 +void m3d_end(void);
    8.32 +void m3d_vertex(float x, float y, float z);
    8.33 +void m3d_normal(float x, float y, float z);
    8.34 +void m3d_color(float x, float y, float z);
    8.35 +void m3d_texcoord(float x, float y);
    8.36  
    8.37  #ifdef __cplusplus
    8.38  }
     9.1 --- a/src/object.cc	Sun Apr 06 02:43:24 2014 +0300
     9.2 +++ b/src/object.cc	Mon Apr 07 06:04:11 2014 +0300
     9.3 @@ -19,8 +19,8 @@
     9.4  {
     9.5  }
     9.6  
     9.7 -#define USUB	16
     9.8 -#define VSUB	8
     9.9 +#define USUB	32
    9.10 +#define VSUB	16
    9.11  
    9.12  void Sphere::draw() const
    9.13  {
    10.1 --- a/src/object.h	Sun Apr 06 02:43:24 2014 +0300
    10.2 +++ b/src/object.h	Mon Apr 07 06:04:11 2014 +0300
    10.3 @@ -9,7 +9,7 @@
    10.4  	virtual void draw() const = 0;
    10.5  };
    10.6  
    10.7 -class Sphere {
    10.8 +class Sphere : public Object {
    10.9  public:
   10.10  	Sphere();
   10.11  	~Sphere();
    11.1 --- a/src/scene.cc	Sun Apr 06 02:43:24 2014 +0300
    11.2 +++ b/src/scene.cc	Mon Apr 07 06:04:11 2014 +0300
    11.3 @@ -4,6 +4,7 @@
    11.4  Scene::Scene()
    11.5  {
    11.6  	name = 0;
    11.7 +	active_cam = 0;
    11.8  }
    11.9  
   11.10  Scene::~Scene()
   11.11 @@ -39,6 +40,76 @@
   11.12  	return name ? name : "<unknown>";
   11.13  }
   11.14  
   11.15 +void Scene::add_object(Object *obj)
   11.16 +{
   11.17 +	objects.push_back(obj);
   11.18 +}
   11.19 +
   11.20 +void Scene::add_light(Light *lt)
   11.21 +{
   11.22 +	lights.push_back(lt);
   11.23 +}
   11.24 +
   11.25 +void Scene::add_camera(Camera *cam)
   11.26 +{
   11.27 +	cameras.push_back(cam);
   11.28 +}
   11.29 +
   11.30 +
   11.31 +int Scene::get_object_count() const
   11.32 +{
   11.33 +	return (int)objects.size();
   11.34 +}
   11.35 +
   11.36 +int Scene::get_light_count() const
   11.37 +{
   11.38 +	return (int)lights.size();
   11.39 +}
   11.40 +
   11.41 +int Scene::get_camera_count() const
   11.42 +{
   11.43 +	return (int)cameras.size();
   11.44 +}
   11.45 +
   11.46 +
   11.47 +Object *Scene::get_object(int idx)
   11.48 +{
   11.49 +	return objects[idx];
   11.50 +}
   11.51 +
   11.52 +const Object *Scene::get_object(int idx) const
   11.53 +{
   11.54 +	return objects[idx];
   11.55 +}
   11.56 +
   11.57 +Light *Scene::get_light(int idx)
   11.58 +{
   11.59 +	return lights[idx];
   11.60 +}
   11.61 +
   11.62 +const Light *Scene::get_light(int idx) const
   11.63 +{
   11.64 +	return lights[idx];
   11.65 +}
   11.66 +
   11.67 +Camera *Scene::get_camera(int idx)
   11.68 +{
   11.69 +	return cameras[idx];
   11.70 +}
   11.71 +
   11.72 +const Camera *Scene::get_camera(int idx) const
   11.73 +{
   11.74 +	return cameras[idx];
   11.75 +}
   11.76 +
   11.77  void Scene::draw() const
   11.78  {
   11.79 +	if(active_cam) {
   11.80 +		// TODO
   11.81 +	}
   11.82 +
   11.83 +	int nobj = get_object_count();
   11.84 +	for(int i=0; i<nobj; i++) {
   11.85 +		objects[i]->draw();
   11.86 +	}
   11.87  }
    12.1 --- a/src/scene.h	Sun Apr 06 02:43:24 2014 +0300
    12.2 +++ b/src/scene.h	Mon Apr 07 06:04:11 2014 +0300
    12.3 @@ -13,6 +13,7 @@
    12.4  	vector<Object*> objects;
    12.5  	vector<Light*> lights;
    12.6  	vector<Camera*> cameras;
    12.7 +	Camera *active_cam;
    12.8  
    12.9  public:
   12.10  	Scene();
   12.11 @@ -23,6 +24,21 @@
   12.12  	void set_name(const char *name);
   12.13  	const char *get_name() const;
   12.14  
   12.15 +	void add_object(Object *obj);
   12.16 +	void add_light(Light *lt);
   12.17 +	void add_camera(Camera *cam);
   12.18 +
   12.19 +	int get_object_count() const;
   12.20 +	int get_light_count() const;
   12.21 +	int get_camera_count() const;
   12.22 +
   12.23 +	Object *get_object(int idx);
   12.24 +	const Object *get_object(int idx) const;
   12.25 +	Light *get_light(int idx);
   12.26 +	const Light *get_light(int idx) const;
   12.27 +	Camera *get_camera(int idx);
   12.28 +	const Camera *get_camera(int idx) const;
   12.29 +
   12.30  	void draw() const;
   12.31  };
   12.32