nuclear@0: #include nuclear@0: #include "min3d.h" nuclear@0: #include "m3dimpl.h" nuclear@0: nuclear@0: #ifndef M_PI nuclear@0: #define M_PI 3.141592653 nuclear@0: #endif nuclear@0: nuclear@0: int m3d_init(void) nuclear@0: { nuclear@0: if(!(m3dctx = malloc(sizeof *m3dctx))) { nuclear@0: return -1; nuclear@0: } nuclear@0: memset(m3dctx, 0, sizeof *m3dctx); nuclear@0: nuclear@0: m3d_matrix_mode(M3D_PROJECTION); nuclear@0: m3d_load_identity(); nuclear@0: m3d_matrix_mode(M3D_MODELVIEW); nuclear@0: m3d_load_identity(); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void m3d_shutdown(void) nuclear@0: { nuclear@0: free(m3dctx); nuclear@0: } nuclear@0: nuclear@0: void m3d_set_buffers(struct m3d_image *cbuf, uint16_t *zbuf) nuclear@0: { nuclear@0: m3dctx->cbuf = cbuf; nuclear@0: m3dctx->zbuf = zbuf; nuclear@0: } nuclear@0: nuclear@0: void m3d_clear(unsigned int bmask) nuclear@0: { nuclear@0: int num_pixels = m3dctx->cbuf->xsz * m3dctx->cbuf->ysz; nuclear@0: if(bmask & M3D_COLOR_BUFFER_BIT) { nuclear@0: memset(m3dctx->cbuf->pixels, 0, num_pixels * 3); nuclear@0: } nuclear@0: if(bmask & M3D_DEPTH_BUFFER_BIT) { nuclear@0: memset(m3dctx->zbuf, 0xff, num_pixels * sizeof *m3dctx->zbuf); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void m3d_enable(int bit) nuclear@0: { nuclear@0: m3dctx->state |= (1 << bit); nuclear@0: } nuclear@0: nuclear@0: void m3d_disable(int bit) nuclear@0: { nuclear@0: m3dctx->state &= ~(1 << bit); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: /* matrix stack */ nuclear@0: void m3d_matrix_mode(int mode) nuclear@0: { nuclear@0: m3dctx->mmode = mode; nuclear@0: } nuclear@0: nuclear@0: void m3d_load_identity(void) nuclear@0: { nuclear@0: static const float mid[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@0: m3d_load_matrix(mid); nuclear@0: } nuclear@0: nuclear@0: void m3d_load_matrix(const float *m) nuclear@0: { nuclear@0: int top = m3dctx->mstack[m3dctx->mmode].top; nuclear@0: memcpy(m3dctx->mstack[m3dctx->mmode].m[top], m, 16 * sizeof *m); nuclear@0: } nuclear@0: nuclear@0: #define M(i,j) (((i) << 2) + (j)) nuclear@0: void m3d_mult_matrix(const float *m2) nuclear@0: { nuclear@0: int i, j, top = m3dctx->mstack[m3dctx->mmode].top; nuclear@0: float m1[16]; nuclear@0: float *dest = m3dctx->mstack[m3dctx->mmode].m[top]; nuclear@0: nuclear@0: memcpy(m1, dest, sizeof m1); nuclear@0: nuclear@0: for(i=0; i<4; i++) { nuclear@0: for(j=0; j<4; j++) { nuclear@0: dest[M(i,j)] = m1[M(0,j)] * m2[M(i,0)] + nuclear@0: m1[M(1,j)] * m2[M(i,1)] + nuclear@0: m1[M(2,j)] * m2[M(i,2)] + nuclear@0: m1[M(3,j)] * m2[M(i,3)]; nuclear@0: } nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: void m3d_translate(float x, float y, float z) nuclear@0: { nuclear@0: float m[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@0: m[12] = x; nuclear@0: m[13] = y; nuclear@0: m[14] = z; nuclear@0: m3d_mult_matrix(m); nuclear@0: } nuclear@0: nuclear@0: void m3d_rotate(float deg, float x, float y, float z) nuclear@0: { nuclear@0: float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@0: nuclear@0: float angle = M_PI * deg / 180.0f; nuclear@0: float sina = sin(angle); nuclear@0: float cosa = cos(angle); nuclear@0: float one_minus_cosa = 1.0f - cosa; nuclear@0: float nxsq = x * x; nuclear@0: float nysq = y * y; nuclear@0: float nzsq = z * z; nuclear@0: nuclear@0: xform[0] = nxsq + (1.0f - nxsq) * cosa; nuclear@0: xform[4] = x * y * one_minus_cosa - z * sina; nuclear@0: xform[8] = x * z * one_minus_cosa + y * sina; nuclear@0: xform[1] = x * y * one_minus_cosa + z * sina; nuclear@0: xform[5] = nysq + (1.0 - nysq) * cosa; nuclear@0: xform[9] = y * z * one_minus_cosa - x * sina; nuclear@0: xform[2] = x * z * one_minus_cosa - y * sina; nuclear@0: xform[6] = y * z * one_minus_cosa + x * sina; nuclear@0: xform[10] = nzsq + (1.0 - nzsq) * cosa; nuclear@0: nuclear@0: m3d_mult_matrix(xform); nuclear@0: } nuclear@0: nuclear@0: void m3d_scale(float x, float y, float z) nuclear@0: { nuclear@0: static float m[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@0: m[0] = x; nuclear@0: m[5] = y; nuclear@0: m[10] = z; nuclear@0: m3d_mult_matrix(m); nuclear@0: } nuclear@0: nuclear@0: void m3d_frustum(float left, float right, float bottom, float top, float nr, float fr) nuclear@0: { nuclear@0: float xform[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@0: nuclear@0: float dx = right - left; nuclear@0: float dy = top - bottom; nuclear@0: float dz = fr - nr; nuclear@0: nuclear@0: float a = (right + left) / dx; nuclear@0: float b = (top + bottom) / dy; nuclear@0: float c = -(fr + nr) / dz; nuclear@0: float d = -2.0 * fr * nr / dz; nuclear@0: nuclear@0: xform[0] = 2.0 * nr / dx; nuclear@0: xform[5] = 2.0 * nr / dy; nuclear@0: xform[8] = a; nuclear@0: xform[9] = b; nuclear@0: xform[10] = c; nuclear@0: xform[11] = -1.0f; nuclear@0: xform[14] = d; nuclear@0: nuclear@0: m3d_mult_matrix(xform); nuclear@0: } nuclear@0: nuclear@0: void m3d_perspective(float vfov, float aspect, float nr, float fr) nuclear@0: { nuclear@0: float vfov_rad = M_PI * vfov / 180.0; nuclear@0: float x = nr * tan(vfov_rad / 2.0); nuclear@0: m3d_frustum(-aspect * x, aspect * x, -x, x, nr, fr); nuclear@0: } nuclear@0: nuclear@0: /* drawing */ nuclear@0: void m3d_draw(int prim, const float *varr, int vcount) nuclear@0: { nuclear@0: /* TODO */ nuclear@0: } nuclear@0: nuclear@0: void m3d_draw_indexed(int prim, const float *varr, const int *idxarr, int icount) nuclear@0: { nuclear@0: /* TODO */ nuclear@0: } nuclear@0: