Basic 3D graphics for the MBED application-shield on-board LCD (initial/incomplete).
Diff: gfx3d.cpp
- Revision:
- 0:215c9308dc52
- Child:
- 1:f346d04ccbad
diff -r 000000000000 -r 215c9308dc52 gfx3d.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx3d.cpp Sun Oct 25 11:26:02 2015 +0000 @@ -0,0 +1,117 @@ +/* + * gfx3d.cpp -- 3D stuff for MBED (just playing!) + * Copyright (C) 2015 Fred Barnes, University of Kent <frmb@kent.ac.uk> + */ + +/** @file gfx3d.cpp */ + +/** gfx3d library + * + * This is a library for primitive 3D graphics. No classes, just C functions. + */ + + +#include "mbed.h" +#include "C12832.h" +#include "gfx3d.h" + + +/** + * rotates a base set of points into a new set (demoscene style) + */ +void gfx3d_rotate_demo (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a) +{ + float sinval = gfx3d_sin (a); + float cosval = gfx3d_cos (a); + int i; + + for (i=0; i<npnts; i++) { + float x1 = (src[i].x * cosval) + (src[i].y * sinval); + float y1 = (src[i].y * cosval) - (src[i].x * sinval); + float z1 = (src[i].z * cosval) - (x1 * sinval); + float t; + + dst[i].x = (x1 * cosval) + (src[i].z * sinval); + t = (y1 * cosval) + (z1 * sinval); + dst[i].z = (z1 * cosval) - (y1 * sinval); + dst[i].y = t; + } + +} + + +/* + * translates a set of 3D points. 'src' and 'dst' can be the same + */ +void gfx3d_translate (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const g3d_p3_t tx) +{ + int i; + + if (tx.x != 0.0f) { + for (i=0; i<npnts; i++) { + dst[i].x = src[i].x + tx.x; + } + } else if (src != dst) { + for (i=0; i<npnts; i++) { + dst[i].x = src[i].x; + } + } + if (tx.y != 0.0f) { + for (i=0; i<npnts; i++) { + dst[i].y = src[i].y + tx.y; + } + } else if (src != dst) { + for (i=0; i<npnts; i++) { + dst[i].y = src[i].y; + } + } + if (tx.z != 0.0f) { + for (i=0; i<npnts; i++) { + dst[i].z = src[i].z + tx.z; + } + } else if (src != dst) { + for (i=0; i<npnts; i++) { + dst[i].z = src[i].z; + } + } +} + + +/* + * projects a set of 3D points into a 2D space (pretty crude) + */ +void gfx3d_project (const g3d_p3_t *src, g3d_2p3_t *dst, const int npnts) +{ + int i; + + for (i=0; i<npnts; i++) { + float ez = src[i].z; + + dst[i].z = (int)(ez * G3D_ZBSCALE) + G3D_ZBADD; + ez += G3D_Z_DEPTH; + dst[i].x = (int)((src[i].x / ez) * G3D_X_SCALE) + G3D_X2_SHIFT; + dst[i].y = (int)((src[i].y / ez) * G3D_Y_SCALE) + G3D_Y2_SHIFT; + } +} + + +/* + * takes a set of 8 projected points and draws a wireframe cube on the given LCD. FIXME: only interested in the buffer ops.. + */ +void gfx3d_wirecube (const g3d_2p3_t *src, C12832 &lcd) +{ + lcd.line (src[0].x, src[0].y, src[1].x, src[1].y, 1); + lcd.line (src[1].x, src[1].y, src[2].x, src[2].y, 1); + lcd.line (src[2].x, src[2].y, src[3].x, src[3].y, 1); + lcd.line (src[3].x, src[3].y, src[0].x, src[0].y, 1); + + lcd.line (src[4].x, src[4].y, src[5].x, src[5].y, 1); + lcd.line (src[5].x, src[5].y, src[6].x, src[6].y, 1); + lcd.line (src[6].x, src[6].y, src[7].x, src[7].y, 1); + lcd.line (src[7].x, src[7].y, src[4].x, src[4].y, 1); + + lcd.line (src[0].x, src[0].y, src[4].x, src[4].y, 1); + lcd.line (src[1].x, src[1].y, src[5].x, src[5].y, 1); + lcd.line (src[2].x, src[2].y, src[6].x, src[6].y, 1); + lcd.line (src[3].x, src[3].y, src[7].x, src[7].y, 1); +} \ No newline at end of file