# HG changeset patch # User John Tsiombikas # Date 1397086291 -10800 # Node ID 70e332156d0267d4261da69943dc928dedf40d9a # Parent fcd06a15dfdd49228ccb3e859449c8dfa6dd5e54 moving along diff -r fcd06a15dfdd -r 70e332156d02 .hgignore --- a/.hgignore Mon Apr 07 08:46:06 2014 +0300 +++ b/.hgignore Thu Apr 10 02:31:31 2014 +0300 @@ -3,3 +3,11 @@ \.swp$ \.obj$ \.exe$ +^rayzor$ +\.log$ +\.sln$ +\.vcproj$ +\.vcxproj +\.suo$ +Debug/ +Release/ diff -r fcd06a15dfdd -r 70e332156d02 GNUmakefile --- a/GNUmakefile Mon Apr 07 08:46:06 2014 +0300 +++ b/GNUmakefile Thu Apr 10 02:31:31 2014 +0300 @@ -1,8 +1,9 @@ -modelobj = src/main.o src/min3d.o src/m3drast.o src/logger.o -rendobj = src/rend.o src/vmath.o +baseobj = src/main.o src/logger.o src/screen.o src/scrman.o +modelobj = src/modeller.o src/min3d.o src/m3drast.o src/lines.o +rendobj = src/renderer.o src/vmath.o scnobj = src/scene.o src/object.o sysobj = src/dosemu/dosemu.o -obj = $(modelobj) $(rendobj) $(scnobj) $(sysobj) +obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj) dep = $(obj:.o=.d) bin = rayzor @@ -32,3 +33,7 @@ .PHONY: cleandep cleandep: rm -f $(dep) + +.PHONY: profile +profile: + $(MAKE) CFLAGS="$(CFLAGS) -O3 -pg" LDFLAGS="$(LDFLAGS) -pg" diff -r fcd06a15dfdd -r 70e332156d02 Makefile --- a/Makefile Mon Apr 07 08:46:06 2014 +0300 +++ b/Makefile Thu Apr 10 02:31:31 2014 +0300 @@ -1,8 +1,9 @@ -modelobj = main.obj min3d.obj m3drast.obj logger.obj -rendobj = rend.obj vmath.obj +baseobj = main.obj logger.obj screen.obj scrman.obj +modelobj = modeller.obj min3d.obj m3drast.obj lines.obj +rendobj = renderer.obj vmath.obj scnobj = scene.obj object.obj sysobj = gfx.obj vbe.obj dpmi.obj timer.obj mouse.obj keyb.obj -obj = $(modelobj) $(rendobj) $(scnobj) $(sysobj) +obj = $(baseobj) $(modelobj) $(rendobj) $(scnobj) $(sysobj) bin = rayzor.exe #dbg = -d2 diff -r fcd06a15dfdd -r 70e332156d02 src/dosemu/dosemu.c --- a/src/dosemu/dosemu.c Mon Apr 07 08:46:06 2014 +0300 +++ b/src/dosemu/dosemu.c Thu Apr 10 02:31:31 2014 +0300 @@ -10,10 +10,11 @@ #include "keyb.h" #include "timer.h" +static void cleanup(void); static void proc_events(void); static void capture_frame(unsigned char *frame); -static void init_sdl() +static void init_sdl(void) { const SDL_version *ver; @@ -23,9 +24,15 @@ if((ver = SDL_Linked_Version())) { printf("SDL %d.%d.%d initialized\n", ver->major, ver->minor, ver->patch); } + atexit(cleanup); } } +static void cleanup(void) +{ + SDL_Quit(); +} + /* ----- graphics (gfx.c (vbe) implementation) ----- */ static SDL_Surface *fbsurf; static int scale = 1; @@ -74,7 +81,6 @@ { SDL_ShowCursor(1); SDL_EnableKeyRepeat(0, 0); - SDL_Quit(); return 0; } @@ -178,7 +184,7 @@ } /* also print fps every second ... */ - { + /*{ static long prev_fps, num_frames; long msec, dt; @@ -193,7 +199,7 @@ } else { num_frames++; } - } + }*/ } #define spin_delay(ms) \ @@ -206,14 +212,15 @@ void wait_vsync(void) { - static int prev_msec; - int msec, dt, tleft; + /*static int prev_msec; + int msec, dt, tleft;*/ if(!copy_frame_called) { copy_frame(0); copy_frame_called = 0; } + /* msec = SDL_GetTicks(); dt = msec - prev_msec; @@ -234,6 +241,7 @@ } else { prev_msec = msec; } + */ } static int cap_count = 0; diff -r fcd06a15dfdd -r 70e332156d02 src/lines.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lines.c Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,146 @@ +#include "lines.h" + +enum { + IN = 0, + LEFT = 1, + RIGHT = 2, + TOP = 4, + BOTTOM = 8 +}; + +static int outcode(int x, int y, int minx, int miny, int maxx, int maxy) +{ + int code = 0; + + if(x < minx) { + code |= LEFT; + } else if(x > maxx) { + code |= RIGHT; + } + if(y < miny) { + code |= TOP; + } else if(y > maxy) { + code |= BOTTOM; + } + return code; +} + +#define FIXMUL(a, b) (((a) * (b)) >> 8) +#define FIXDIV(a, b) (((a) << 8) / (b)) + +#define LERP(a, b, t) ((a) + FIXMUL((b) - (a), (t))) + +int clip_line2d(int *x0, int *y0, int *x1, int *y1, const int *vp) +{ + int oc_out; + int minx = vp[0]; + int miny = vp[1]; + int maxx = vp[0] + vp[2] - 1; + int maxy = vp[1] + vp[3] - 1; + + int oc0 = outcode(*x0, *y0, minx, miny, maxx, maxy); + int oc1 = outcode(*x1, *y1, minx, miny, maxx, maxy); + + int32_t fx0, fy0, fx1, fy1, fminx, fminy, fmaxx, fmaxy; + + if(!(oc0 | oc1)) return 1; /* both points are inside */ + + fx0 = *x0 << 8; + fy0 = *y0 << 8; + fx1 = *x1 << 8; + fy1 = *y1 << 8; + fminx = minx << 8; + fminy = miny << 8; + fmaxx = maxx << 8; + fmaxy = maxy << 8; + + for(;;) { + int32_t x, y, t; + + if(oc0 & oc1) return 0; /* both have points with the same outbit, not visible */ + if(!(oc0 | oc1)) break; /* both points are inside */ + + oc_out = oc0 ? oc0 : oc1; + + if(oc_out & TOP) { + t = FIXDIV(fminy - fy0, fy1 - fy0); + x = LERP(fx0, fx1, t); + y = fminy; + } else if(oc_out & BOTTOM) { + t = FIXDIV(fmaxy - fy0, fy1 - fy0); + x = LERP(fx0, fx1, t); + y = fmaxy; + } else if(oc_out & LEFT) { + t = FIXDIV(fminx - fx0, fx1 - fx0); + x = fminx; + y = LERP(fy0, fy1, t); + } else if(oc_out & RIGHT) { + t = FIXDIV(fmaxx - fx0, fx1 - fx0); + x = fmaxx; + y = LERP(fy0, fy1, t); + } + + if(oc_out == oc0) { + fx0 = x; + fy0 = y; + oc0 = outcode(fx0 >> 8, fy0 >> 8, minx, miny, maxx, maxy); + } else { + fx1 = x; + fy1 = y; + oc1 = outcode(fx1 >> 8, fy1 >> 8, minx, miny, maxx, maxy); + } + } + + *x0 = fx0 >> 8; + *y0 = fy0 >> 8; + *x1 = fx1 >> 8; + *y1 = fy1 >> 8; + return 1; +} + +void draw_line(uint32_t *fb, int fbwidth, uint32_t col, int x0, int y0, int x1, int y1) +{ + int i, dx, dy, x_inc, y_inc, error; + + fb += y0 * fbwidth + x0; + + dx = x1 - x0; + dy = y1 - y0; + + if(dx >= 0) { + x_inc = 1; + } else { + x_inc = -1; + dx = -dx; + } + if(dy >= 0) { + y_inc = fbwidth; + } else { + y_inc = -fbwidth; + dy = -dy; + } + + if(dx > dy) { + error = dy * 2 - dx; + for(i=0; i<=dx; i++) { + *fb = col; + if(error >= 0) { + error -= dx * 2; + fb += y_inc; + } + error += dy * 2; + fb += x_inc; + } + } else { + error = dx * 2 - dy; + for(i=0; i<=dy; i++) { + *fb = col; + if(error >= 0) { + error -= dy * 2; + fb += x_inc; + } + error += dx * 2; + fb += y_inc; + } + } +} diff -r fcd06a15dfdd -r 70e332156d02 src/lines.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lines.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,9 @@ +#ifndef LINES_H_ +#define LINES_H_ + +#include "inttypes.h" + +int clip_line2d(int *x0, int *y0, int *x1, int *y1, const int *vp); +void draw_line(uint32_t *fb, int fbwidth, uint32_t col, int x0, int y0, int x1, int y1); + +#endif /* LINES_H_ */ diff -r fcd06a15dfdd -r 70e332156d02 src/m3dimpl.h --- a/src/m3dimpl.h Mon Apr 07 08:46:06 2014 +0300 +++ b/src/m3dimpl.h Thu Apr 10 02:31:31 2014 +0300 @@ -12,7 +12,7 @@ struct min3d_vertex { float pos[4]; - float color[4]; + uint32_t color; float normal[4]; float tex[2]; }; @@ -50,8 +50,10 @@ extern struct min3d_context *m3dctx; -void draw_point(struct min3d_vertex *v); -void draw_line(struct min3d_vertex *v); -void draw_poly(struct min3d_vertex *v, int numv); +#define ENABLED(x) (m3dctx->state & (1 << x)) + +void m3d_draw_point(struct min3d_vertex *v); +void m3d_draw_line(struct min3d_vertex *v); +void m3d_draw_poly(struct min3d_vertex *v, int numv); #endif /* M3DIMPL_H_ */ diff -r fcd06a15dfdd -r 70e332156d02 src/m3drast.c --- a/src/m3drast.c Mon Apr 07 08:46:06 2014 +0300 +++ b/src/m3drast.c Thu Apr 10 02:31:31 2014 +0300 @@ -1,25 +1,56 @@ #include "m3dimpl.h" +#include "lines.h" -void draw_point(struct min3d_vertex *v) +void m3d_draw_point(struct min3d_vertex *v) { int x = v->pos[0] + 0.5; int y = v->pos[1] + 0.5; int xsz = m3dctx->cbuf->xsz; - unsigned char *ptr = m3dctx->cbuf->pixels + (y * xsz + x) * 3; - - int r = (int)(v->color[0] * 255.0); - int g = (int)(v->color[1] * 255.0); - int b = (int)(v->color[2] * 255.0); - ptr[0] = r > 255 ? 255 : r; - ptr[1] = g > 255 ? 255 : g; - ptr[2] = b > 255 ? 255 : b; + m3dctx->cbuf->pixels[y * xsz + x] = v->color; } -void draw_line(struct min3d_vertex *v) +void m3d_draw_line(struct min3d_vertex *v) { + int x0, y0, x1, y1; + + x0 = v[0].pos[0]; + y0 = v[0].pos[1]; + x1 = v[1].pos[0]; + y1 = v[1].pos[1]; + + if(clip_line2d(&x0, &y0, &x1, &y1, m3dctx->vport)) { + draw_line(m3dctx->cbuf->pixels, m3dctx->cbuf->xsz, v->color, x0, y0, x1, y1); + } } -void draw_poly(struct min3d_vertex *v, int numv) +void m3d_draw_poly(struct min3d_vertex *v, int numv) { + int i; + struct min3d_vertex last[2]; + + if(ENABLED(M3D_CULL_FACE)) { + float a[2], b[2], crossz = 0; + + for(i=1; iadd_object(sph); + scene->add_object(sph); + Modeller *modeller = new Modeller; + if(!modeller->init()) { + return false; + } + add_screen(modeller); + + Renderer *renderer = new Renderer; + if(!renderer->init()) { + return false; + } + add_screen(renderer); + + activate_screen(modeller); // start the modeller screen return true; } static void cleanup() { - delete scn; + delete scene; + delete [] fb_pixels; - m3d_shutdown(); - delete [] backbuf; + destroy_screens(); if(!novideo) { set_text_mode(); @@ -144,22 +151,17 @@ } } - static void display() { - m3d_clear(M3D_COLOR_BUFFER_BIT); - - m3d_matrix_mode(M3D_MODELVIEW); - m3d_load_identity(); - m3d_translate(0, 0, -cam_dist); - m3d_rotate(cam_phi, 1, 0, 0); - m3d_rotate(cam_theta, 0, 1, 0); - - scn->draw(); + Screen *scr = active_screen(); + if(scr) { + scr->update(); + scr->draw(); + } // draw the mouse cursor if(use_mouse) { - draw_cursor(backbuf, mx, my); + draw_cursor(fb_pixels, mouse_x, mouse_y); } if(!novideo) { @@ -173,36 +175,43 @@ (((g) << gshift) & gmask) | \ (((b) << bshift) & bmask)) +#define UNPACK_RED(c) (((c) >> 16) & 0xff) +#define UNPACK_GREEN(c) (((c) >> 8) & 0xff) +#define UNPACK_BLUE(c) ((c) & 0xff) + static void swap_buffers() { - unsigned char *src = backbuf; - int num_pixels = xsz * ysz; + uint32_t *src = fb_pixels; + int num_pixels = fb_width * fb_height; - switch(bpp) { + switch(fb_bpp) { case 32: - { - uint32_t *dest = (uint32_t*)fb; - for(int i=0; i> srs, src[1] >> sgs, src[2] >> sbs); - src += 3; + uint32_t c = *src++; + unsigned char r = UNPACK_RED(c); + unsigned char g = UNPACK_GREEN(c); + unsigned char b = UNPACK_BLUE(c); + + *dest++ = PACK_RGB(r, g, b); } } break; @@ -212,104 +221,72 @@ } } -static void draw_cursor(unsigned char *buf, int mx, int my) +static void draw_cursor(uint32_t *buf, int mx, int my) { - unsigned char *cptr = buf + (my * xsz + mx) * 3; + uint32_t *cptr = buf + my * fb_width + mx; int i, cw[2] = {4, 4}, ch[2] = {4, 4}; if(mx < cw[0]) cw[0] = mx; if(my < ch[0]) ch[0] = my; - if(xsz - mx < cw[1]) cw[1] = xsz - mx - 1; - if(ysz - my < ch[1]) ch[1] = ysz - my - 1; + if(fb_width - mx < cw[1]) cw[1] = fb_width - mx - 1; + if(fb_height - my < ch[1]) ch[1] = fb_height - my - 1; for(i=1; ihandle_keyboard(key, true); // TODO also generate release events... } } static void handle_mouse() { - static int prev_mx, prev_my, prev_bnmask; - int /*mx, my,*/ bnmask; + static int prev_mx, prev_my, prev_bnmask, bndiff; + int mx, my, bnmask; + Screen *scr = active_screen(); if(!use_mouse || novideo) return; bnmask = read_mouse(&mx, &my); - if(bnmask != prev_bnmask) { - mouse_button(bnmask, mx, my); - prev_bnmask = bnmask; + if(scr && (bndiff = bnmask ^ prev_bnmask)) { + for(int i=0; i<8; i++) { + int bit = 1 << i; + if(bndiff & bit) { + scr->handle_mbutton(i, bnmask & bit, mx, my); + } + } } - if(mx != prev_mx || my != prev_my) { - mouse_motion(mx, my); - prev_mx = mx; - prev_my = my; + prev_bnmask = bnmask; + + if(scr && (mx != prev_mx || my != prev_my)) { + scr->handle_mmotion(mx, my); } + prev_mx = mx; + prev_my = my; } -static int bnstate; -static int prev_x = -1, prev_y; -static void mouse_button(int bn, int x, int y) -{ - bnstate = bn; - prev_x = x; - prev_y = y; -} - -static void mouse_motion(int x, int y) -{ - int dx = x - prev_x; - int dy = y - prev_y; - prev_x = x; - prev_y = y; - - if(bnstate & 1) { - cam_theta += dx * 0.5; - cam_phi += dy * 0.5; - - if(cam_phi < -90) cam_phi = -90; - if(cam_phi > 90) cam_phi = 90; - } - if(bnstate & 2) { - cam_dist += dy * 0.1; - if(cam_dist < 0) cam_dist = 0; - } -} static struct { int opt; @@ -353,7 +330,7 @@ switch(opt) { case 's': - if(sscanf(argv[++i], "%dx%d:%d", &xsz, &ysz, &bpp) < 2) { + if(sscanf(argv[++i], "%dx%d:%d", &fb_width, &fb_height, &fb_bpp) < 2) { fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]); return false; } @@ -383,4 +360,5 @@ { cleanup(); fprintf(stderr, "signal caught: %d\n", s); + exit(1); } diff -r fcd06a15dfdd -r 70e332156d02 src/min3d.c --- a/src/min3d.c Mon Apr 07 08:46:06 2014 +0300 +++ b/src/min3d.c Thu Apr 10 02:31:31 2014 +0300 @@ -37,9 +37,7 @@ m3dctx->cbuf = cbuf; m3dctx->zbuf = zbuf; - m3dctx->vport[0] = m3dctx->vport[1] = 0; - m3dctx->vport[2] = cbuf->xsz; - m3dctx->vport[3] = cbuf->ysz; + m3d_viewport(0, 0, cbuf->xsz, cbuf->ysz); } void m3d_clear_color(float r, float g, float b) @@ -51,9 +49,11 @@ void m3d_clear(unsigned int bmask) { - int i, num_pixels = m3dctx->cbuf->xsz * m3dctx->cbuf->ysz; + int num_pixels = m3dctx->cbuf->xsz * m3dctx->cbuf->ysz; if(bmask & M3D_COLOR_BUFFER_BIT) { - /*memset(m3dctx->cbuf->pixels, 0, num_pixels * 3);*/ + memset(m3dctx->cbuf->pixels, 0, num_pixels * 4); + /* + int i; unsigned char *ptr = m3dctx->cbuf->pixels; unsigned char r = m3dctx->clear_color[0]; unsigned char g = m3dctx->clear_color[1]; @@ -62,7 +62,7 @@ *ptr++ = r; *ptr++ = g; *ptr++ = b; - } + }*/ } if(bmask & M3D_DEPTH_BUFFER_BIT) { memset(m3dctx->zbuf, 0xff, num_pixels * sizeof *m3dctx->zbuf); @@ -80,6 +80,14 @@ m3dctx->state &= ~(1 << bit); } +void m3d_viewport(int x, int y, int xsz, int ysz) +{ + m3dctx->vport[0] = x; + m3dctx->vport[1] = y; + m3dctx->vport[2] = xsz; + m3dctx->vport[3] = ysz; +} + /* matrix stack */ void m3d_matrix_mode(int mode) @@ -275,7 +283,7 @@ res[i].pos[2] /= res[i].pos[3]; res[i].pos[0] = (res[i].pos[0] * 0.5 + 0.5) * vport[2] + vport[0]; - res[i].pos[1] = (res[i].pos[1] * 0.5 + 0.5) * vport[3] + vport[1]; + res[i].pos[1] = (-res[i].pos[1] * 0.5 + 0.5) * vport[3] + vport[1]; } return vcount; } @@ -313,37 +321,76 @@ if(!varr) return; for(i=0; iim_color[0]; - v[idx].color[1] = carr ? *carr++ : m3dctx->im_color[1]; - v[idx].color[2] = carr ? *carr++ : m3dctx->im_color[2]; + r = (carr ? *carr++ : m3dctx->im_color[0]) * 255.0; + g = (carr ? *carr++ : m3dctx->im_color[1]) * 255.0; + b = (carr ? *carr++ : m3dctx->im_color[2]) * 255.0; + v[idx].color = (r << 16) | (g << 8) | b; if(idx == prim - 1) { int resnum = proc_prim(prim, resv, v); switch(resnum) { case 1: - draw_point(resv); + m3d_draw_point(resv); break; - case '2': - draw_line(resv); + case 2: + m3d_draw_line(resv); break; default: - draw_poly(resv, resnum); + m3d_draw_poly(resv, resnum); } } } } -void m3d_draw_indexed(int prim, const int *idxarr, int icount) +void m3d_draw_indexed(int prim, const unsigned int *idxarr, int icount) { - /* TODO */ + int i, vcount = prim; + struct min3d_vertex v[4]; + struct min3d_vertex resv[16]; + const float *varr = m3dctx->vert_array; + const float *carr = m3dctx->col_array; + + if(!varr) return; + + for(i=0; iim_color[0]) * 255.0; + g = (carr ? carr[index * 3 + 1] : m3dctx->im_color[1]) * 255.0; + b = (carr ? carr[index * 3 + 2] : m3dctx->im_color[2]) * 255.0; + v[vnum].color = (r << 16) | (g << 8) | b; + + if(vnum == vcount - 1) { + int resnum = proc_prim(prim, resv, v); + switch(resnum) { + case 1: + m3d_draw_point(resv); + break; + + case 2: + m3d_draw_line(resv); + break; + + default: + m3d_draw_poly(resv, resnum); + } + } + } } void m3d_begin(int prim) diff -r fcd06a15dfdd -r 70e332156d02 src/min3d.h --- a/src/min3d.h Mon Apr 07 08:46:06 2014 +0300 +++ b/src/min3d.h Thu Apr 10 02:31:31 2014 +0300 @@ -36,7 +36,7 @@ struct m3d_image { int xsz, ysz; - unsigned char *pixels; + uint32_t *pixels; }; #ifdef __cplusplus @@ -53,6 +53,8 @@ void m3d_enable(int bit); void m3d_disable(int bit); +void m3d_viewport(int x, int y, int xsz, int ysz); + /* matrix stack */ void m3d_matrix_mode(int mode); void m3d_push_matrix(void); @@ -73,7 +75,7 @@ void m3d_texcoord_array(const float *tcarr); void m3d_draw(int prim, int vcount); -void m3d_draw_indexed(int prim, const int *idxarr, int icount); +void m3d_draw_indexed(int prim, const unsigned int *idxarr, int icount); /* immediate mode interface */ void m3d_begin(int prim); diff -r fcd06a15dfdd -r 70e332156d02 src/modeller.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/modeller.cc Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,150 @@ +#include +#include +#include "modeller.h" +#include "min3d.h" +#include "rayzor.h" +#include "scene.h" + +struct ModellerImpl { + int mx, my; + float cam_theta, cam_phi, cam_dist; + + struct m3d_image rbuf; + + bool bnstate[8]; + int prev_x, prev_y; +}; + +static void draw_grid(float size, float spacing); + +Modeller::Modeller() +{ + set_name("modeller"); +} + +Modeller::~Modeller() +{ + shutdown(); +} + +bool Modeller::init() +{ + mod = new ModellerImpl; + memset(mod, 0, sizeof *mod); + + mod->cam_phi = 25; + mod->cam_dist = 5; + + m3d_init(); + mod->rbuf.pixels = fb_pixels; + mod->rbuf.xsz = fb_width; + mod->rbuf.ysz = fb_height; + m3d_set_buffers(&mod->rbuf, 0); + + m3d_matrix_mode(M3D_PROJECTION); + m3d_load_identity(); + m3d_perspective(50.0, (float)fb_width / (float)fb_height, 0.5, 500.0); + + m3d_enable(M3D_CULL_FACE); + return true; +} + +void Modeller::shutdown() +{ + if(mod) { + m3d_shutdown(); + + delete mod; + mod = 0; + } +} + +void Modeller::draw() const +{ + m3d_clear(M3D_COLOR_BUFFER_BIT); + + m3d_matrix_mode(M3D_MODELVIEW); + m3d_load_identity(); + m3d_translate(0, 0, -mod->cam_dist); + m3d_rotate(mod->cam_phi, 1, 0, 0); + m3d_rotate(mod->cam_theta, 0, 1, 0); + + draw_grid(10.0, 1.0); + + scene->draw(); +} + + +static void draw_grid(float size, float spacing) +{ + int num_lines = size / spacing; + float dist = size / 2.0; + + m3d_disable(M3D_LIGHTING); + + m3d_begin(M3D_LINES); + m3d_color(0.4, 0.4, 0.4); + + float x = -dist; + for(int i=0; i<=num_lines; i++) { + if(i != num_lines / 2) { + m3d_vertex(-dist, 0, x); + m3d_vertex(dist, 0, x); + m3d_vertex(x, 0, -dist); + m3d_vertex(x, 0, dist); + } + x += spacing; + } + m3d_end(); + + m3d_begin(M3D_LINES); + m3d_color(1.0, 0, 0); + m3d_vertex(-dist, 0, 0); + m3d_vertex(dist, 0, 0); + m3d_color(0, 1.0, 0); + m3d_vertex(0, 0, -dist); + m3d_vertex(0, 0, dist); + m3d_end(); +} + + +void Modeller::handle_keyboard(int key, bool press) +{ + if(press) { + switch(key) { + case 27: + quit_app(); + break; + + default: + break; + } + } +} + +void Modeller::handle_mbutton(int bn, bool press, int x, int y) +{ + mod->bnstate[bn] = press; + mod->prev_x = x; + mod->prev_y = y; +} + +void Modeller::handle_mmotion(int x, int y) +{ + int dx = x - mod->prev_x; + int dy = y - mod->prev_y; + mod->prev_x = x; + mod->prev_y = y; + + if(mod->bnstate[0]) { + mod->cam_theta += dx * 0.5; + mod->cam_phi += dy * 0.5; + + if(mod->cam_phi < -90) mod->cam_phi = -90; + if(mod->cam_phi > 90) mod->cam_phi = 90; + } + if(mod->bnstate[1]) { + mod->cam_dist += dy * 0.1; + if(mod->cam_dist < 0) mod->cam_dist = 0; + } +} diff -r fcd06a15dfdd -r 70e332156d02 src/modeller.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/modeller.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,26 @@ +#ifndef MODELLER_H_ +#define MODELLER_H_ + +#include "screen.h" + +struct ModellerImpl; + +class Modeller : public Screen { +private: + ModellerImpl *mod; + +public: + Modeller(); + ~Modeller(); + + bool init(); + void shutdown(); + + void draw() const; + + void handle_keyboard(int key, bool press); + void handle_mbutton(int bn, bool press, int x, int y); + void handle_mmotion(int x, int y); +}; + +#endif // MODELLER_H_ diff -r fcd06a15dfdd -r 70e332156d02 src/object.cc --- a/src/object.cc Mon Apr 07 08:46:06 2014 +0300 +++ b/src/object.cc Thu Apr 10 02:31:31 2014 +0300 @@ -1,6 +1,7 @@ #include "object.h" #include "vmath.h" #include "min3d.h" +#include "logger.h" Object::Object() { @@ -19,37 +20,60 @@ { } -#define USUB 32 -#define VSUB 16 +#define USUB 12 +#define VSUB 6 void Sphere::draw() const { static Vector3 *varr; - static int num_verts; + static unsigned int *iarr; + static int num_verts, num_indices; if(!varr) { + int i, j; int uverts = USUB; int vverts = VSUB + 1; + num_verts = uverts * vverts; varr = new Vector3[num_verts]; Vector3 *vptr = varr; - for(int i=0; ix); - m3d_draw(M3D_POINTS, num_verts); + m3d_draw_indexed(M3D_QUADS, iarr, num_indices); m3d_vertex_array(0); } diff -r fcd06a15dfdd -r 70e332156d02 src/rayzor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rayzor.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,14 @@ +#ifndef RAYZOR_H_ +#define RAYZOR_H_ + +// global framebuffer (back buffer) +extern uint32_t *fb_pixels; +extern int fb_width, fb_height; +extern int fb_bpp; + +class Scene; +extern Scene *scene; + +void quit_app(); + +#endif /* RAYZOR_H_ */ diff -r fcd06a15dfdd -r 70e332156d02 src/rend.cc --- a/src/rend.cc Mon Apr 07 08:46:06 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#include "rend.h" - -bool rend_init() -{ - return false; -} - -void rend_shutdown() -{ -} diff -r fcd06a15dfdd -r 70e332156d02 src/rend.h --- a/src/rend.h Mon Apr 07 08:46:06 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#ifndef REND_H_ -#define REND_H_ - -bool rend_init(); -void rend_shutdown(); - -#endif // REND_H_ diff -r fcd06a15dfdd -r 70e332156d02 src/renderer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/renderer.cc Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,10 @@ +#include "renderer.h" + +Renderer::Renderer() +{ + set_name("renderer"); +} + +void Renderer::draw() const +{ +} diff -r fcd06a15dfdd -r 70e332156d02 src/renderer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/renderer.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,13 @@ +#ifndef RENDERER_H_ +#define RENDERER_H_ + +#include "screen.h" + +class Renderer : public Screen { +public: + Renderer(); + + void draw() const; +}; + +#endif // RENDERER_H_ diff -r fcd06a15dfdd -r 70e332156d02 src/screen.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/screen.cc Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,49 @@ +#include +#include "screen.h" + +Screen::Screen() +{ + name = 0; +} + +Screen::~Screen() +{ + delete [] name; +} + +bool Screen::init() +{ + return true; +} + +void Screen::shutdown() +{ +} + +void Screen::set_name(const char *name) +{ + delete [] this->name; + this->name = new char[strlen(name) + 1]; + strcpy(this->name, name); +} + +const char *Screen::get_name() const +{ + return name ? name : ""; +} + +void Screen::update() +{ +} + +void Screen::handle_keyboard(int key, bool press) +{ +} + +void Screen::handle_mbutton(int bn, bool press, int x, int y) +{ +} + +void Screen::handle_mmotion(int x, int y) +{ +} diff -r fcd06a15dfdd -r 70e332156d02 src/screen.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/screen.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,26 @@ +#ifndef SCREEN_H_ +#define SCREEN_H_ + +class Screen { +private: + char *name; + +public: + Screen(); + virtual ~Screen(); + + virtual bool init(); + virtual void shutdown(); + + virtual void set_name(const char *name); + virtual const char *get_name() const; + + virtual void update(); + virtual void draw() const = 0; + + virtual void handle_keyboard(int key, bool press); + virtual void handle_mbutton(int bn, bool press, int x, int y); + virtual void handle_mmotion(int x, int y); +}; + +#endif // SCREEN_H_ diff -r fcd06a15dfdd -r 70e332156d02 src/scrman.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/scrman.cc Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,50 @@ +#include +#include "vector.h" +#include "scrman.h" + +static vector screens; +static vector active; + +void add_screen(Screen *s) +{ + screens.push_back(s); +} + +Screen *get_screen(const char *name) +{ + for(size_t i=0; iget_name(), name) == 0) { + return screens[i]; + } + } + return 0; +} + +void destroy_screens() +{ + for(size_t i=0; ishutdown(); + delete screens[i]; + } + screens.clear(); + active.clear(); +} + +void activate_screen(Screen *s) +{ + active.push_back(s); +} + +Screen *deactivate_screen() +{ + Screen *s = active_screen(); + if(!s) return 0; + + active.pop_back(); + return s; +} + +Screen *active_screen() +{ + return active.empty() ? 0 : active.back(); +} diff -r fcd06a15dfdd -r 70e332156d02 src/scrman.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/scrman.h Thu Apr 10 02:31:31 2014 +0300 @@ -0,0 +1,16 @@ +#ifndef SCREEN_MANAGER_H_ +#define SCREEN_MANAGER_H_ + +#include "screen.h" + +void add_screen(Screen *s); +Screen *get_screen(const char *name); + +void destroy_screens(); // destroy all managed screens + +// active screen stack +void activate_screen(Screen *s); +Screen *deactivate_screen(); +Screen *active_screen(); + +#endif // SCREEN_MANAGER_H_ diff -r fcd06a15dfdd -r 70e332156d02 src/stl/vector.h --- a/src/stl/vector.h Mon Apr 07 08:46:06 2014 +0300 +++ b/src/stl/vector.h Thu Apr 10 02:31:31 2014 +0300 @@ -47,6 +47,7 @@ void clear() { delete [] data; + data = 0; max_items = num_items = 0; } @@ -89,6 +90,27 @@ data[num_items++] = item; } + void pop_back() + { + if(--num_items <= 0) { + num_items = 0; + } + + if(num_items < max_items / 3) { + resize(max_items / 2); + } + } + + T &back() + { + return data[num_items - 1]; + } + + const T &back() const + { + return data[num_items - 1]; + } + T &operator [](int idx) { return data[idx];