Basic 3D graphics for the MBED application-shield on-board LCD (initial/incomplete).
gfx3d.cpp@2:f62652cae975, 2015-10-27 (annotated)
- Committer:
- co657_frmb
- Date:
- Tue Oct 27 10:28:53 2015 +0000
- Revision:
- 2:f62652cae975
- Parent:
- 1:f346d04ccbad
- Child:
- 3:2d8982c06eee
Minor updates, very much under construction still.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
co657_frmb | 0:215c9308dc52 | 1 | /* |
co657_frmb | 0:215c9308dc52 | 2 | * gfx3d.cpp -- 3D stuff for MBED (just playing!) |
co657_frmb | 0:215c9308dc52 | 3 | * Copyright (C) 2015 Fred Barnes, University of Kent <frmb@kent.ac.uk> |
co657_frmb | 0:215c9308dc52 | 4 | */ |
co657_frmb | 0:215c9308dc52 | 5 | |
co657_frmb | 0:215c9308dc52 | 6 | /** gfx3d library |
co657_frmb | 0:215c9308dc52 | 7 | * |
co657_frmb | 0:215c9308dc52 | 8 | * This is a library for primitive 3D graphics. No classes, just C functions. |
co657_frmb | 0:215c9308dc52 | 9 | */ |
co657_frmb | 0:215c9308dc52 | 10 | |
co657_frmb | 0:215c9308dc52 | 11 | |
co657_frmb | 0:215c9308dc52 | 12 | #include "mbed.h" |
co657_frmb | 0:215c9308dc52 | 13 | #include "C12832.h" |
co657_frmb | 0:215c9308dc52 | 14 | #include "gfx3d.h" |
co657_frmb | 0:215c9308dc52 | 15 | |
co657_frmb | 0:215c9308dc52 | 16 | |
co657_frmb | 1:f346d04ccbad | 17 | /** rotates a base set of points into a new set (demoscene style) |
co657_frmb | 1:f346d04ccbad | 18 | * |
co657_frmb | 1:f346d04ccbad | 19 | * @param src Source points. |
co657_frmb | 1:f346d04ccbad | 20 | * @param dst Destination points. |
co657_frmb | 1:f346d04ccbad | 21 | * @param npnts Number of points. |
co657_frmb | 1:f346d04ccbad | 22 | * @param a Angle to rotate by (0-255). |
co657_frmb | 0:215c9308dc52 | 23 | */ |
co657_frmb | 0:215c9308dc52 | 24 | void gfx3d_rotate_demo (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const angle_t a) |
co657_frmb | 0:215c9308dc52 | 25 | { |
co657_frmb | 0:215c9308dc52 | 26 | float sinval = gfx3d_sin (a); |
co657_frmb | 0:215c9308dc52 | 27 | float cosval = gfx3d_cos (a); |
co657_frmb | 0:215c9308dc52 | 28 | int i; |
co657_frmb | 0:215c9308dc52 | 29 | |
co657_frmb | 0:215c9308dc52 | 30 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 31 | float x1 = (src[i].x * cosval) + (src[i].y * sinval); |
co657_frmb | 0:215c9308dc52 | 32 | float y1 = (src[i].y * cosval) - (src[i].x * sinval); |
co657_frmb | 0:215c9308dc52 | 33 | float z1 = (src[i].z * cosval) - (x1 * sinval); |
co657_frmb | 0:215c9308dc52 | 34 | float t; |
co657_frmb | 0:215c9308dc52 | 35 | |
co657_frmb | 0:215c9308dc52 | 36 | dst[i].x = (x1 * cosval) + (src[i].z * sinval); |
co657_frmb | 0:215c9308dc52 | 37 | t = (y1 * cosval) + (z1 * sinval); |
co657_frmb | 0:215c9308dc52 | 38 | dst[i].z = (z1 * cosval) - (y1 * sinval); |
co657_frmb | 0:215c9308dc52 | 39 | dst[i].y = t; |
co657_frmb | 0:215c9308dc52 | 40 | } |
co657_frmb | 0:215c9308dc52 | 41 | |
co657_frmb | 0:215c9308dc52 | 42 | } |
co657_frmb | 0:215c9308dc52 | 43 | |
co657_frmb | 0:215c9308dc52 | 44 | |
co657_frmb | 0:215c9308dc52 | 45 | /* |
co657_frmb | 0:215c9308dc52 | 46 | * translates a set of 3D points. 'src' and 'dst' can be the same |
co657_frmb | 0:215c9308dc52 | 47 | */ |
co657_frmb | 0:215c9308dc52 | 48 | void gfx3d_translate (const g3d_p3_t *src, g3d_p3_t *dst, const int npnts, const g3d_p3_t tx) |
co657_frmb | 0:215c9308dc52 | 49 | { |
co657_frmb | 0:215c9308dc52 | 50 | int i; |
co657_frmb | 0:215c9308dc52 | 51 | |
co657_frmb | 0:215c9308dc52 | 52 | if (tx.x != 0.0f) { |
co657_frmb | 0:215c9308dc52 | 53 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 54 | dst[i].x = src[i].x + tx.x; |
co657_frmb | 0:215c9308dc52 | 55 | } |
co657_frmb | 0:215c9308dc52 | 56 | } else if (src != dst) { |
co657_frmb | 0:215c9308dc52 | 57 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 58 | dst[i].x = src[i].x; |
co657_frmb | 0:215c9308dc52 | 59 | } |
co657_frmb | 0:215c9308dc52 | 60 | } |
co657_frmb | 0:215c9308dc52 | 61 | if (tx.y != 0.0f) { |
co657_frmb | 0:215c9308dc52 | 62 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 63 | dst[i].y = src[i].y + tx.y; |
co657_frmb | 0:215c9308dc52 | 64 | } |
co657_frmb | 0:215c9308dc52 | 65 | } else if (src != dst) { |
co657_frmb | 0:215c9308dc52 | 66 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 67 | dst[i].y = src[i].y; |
co657_frmb | 0:215c9308dc52 | 68 | } |
co657_frmb | 0:215c9308dc52 | 69 | } |
co657_frmb | 0:215c9308dc52 | 70 | if (tx.z != 0.0f) { |
co657_frmb | 0:215c9308dc52 | 71 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 72 | dst[i].z = src[i].z + tx.z; |
co657_frmb | 0:215c9308dc52 | 73 | } |
co657_frmb | 0:215c9308dc52 | 74 | } else if (src != dst) { |
co657_frmb | 0:215c9308dc52 | 75 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 76 | dst[i].z = src[i].z; |
co657_frmb | 0:215c9308dc52 | 77 | } |
co657_frmb | 0:215c9308dc52 | 78 | } |
co657_frmb | 0:215c9308dc52 | 79 | } |
co657_frmb | 0:215c9308dc52 | 80 | |
co657_frmb | 0:215c9308dc52 | 81 | |
co657_frmb | 0:215c9308dc52 | 82 | /* |
co657_frmb | 0:215c9308dc52 | 83 | * projects a set of 3D points into a 2D space (pretty crude) |
co657_frmb | 0:215c9308dc52 | 84 | */ |
co657_frmb | 0:215c9308dc52 | 85 | void gfx3d_project (const g3d_p3_t *src, g3d_2p3_t *dst, const int npnts) |
co657_frmb | 0:215c9308dc52 | 86 | { |
co657_frmb | 0:215c9308dc52 | 87 | int i; |
co657_frmb | 0:215c9308dc52 | 88 | |
co657_frmb | 0:215c9308dc52 | 89 | for (i=0; i<npnts; i++) { |
co657_frmb | 0:215c9308dc52 | 90 | float ez = src[i].z; |
co657_frmb | 0:215c9308dc52 | 91 | |
co657_frmb | 0:215c9308dc52 | 92 | dst[i].z = (int)(ez * G3D_ZBSCALE) + G3D_ZBADD; |
co657_frmb | 0:215c9308dc52 | 93 | ez += G3D_Z_DEPTH; |
co657_frmb | 0:215c9308dc52 | 94 | dst[i].x = (int)((src[i].x / ez) * G3D_X_SCALE) + G3D_X2_SHIFT; |
co657_frmb | 0:215c9308dc52 | 95 | dst[i].y = (int)((src[i].y / ez) * G3D_Y_SCALE) + G3D_Y2_SHIFT; |
co657_frmb | 0:215c9308dc52 | 96 | } |
co657_frmb | 0:215c9308dc52 | 97 | } |
co657_frmb | 0:215c9308dc52 | 98 | |
co657_frmb | 0:215c9308dc52 | 99 | |
co657_frmb | 0:215c9308dc52 | 100 | /* |
co657_frmb | 0:215c9308dc52 | 101 | * takes a set of 8 projected points and draws a wireframe cube on the given LCD. FIXME: only interested in the buffer ops.. |
co657_frmb | 0:215c9308dc52 | 102 | */ |
co657_frmb | 0:215c9308dc52 | 103 | void gfx3d_wirecube (const g3d_2p3_t *src, C12832 &lcd) |
co657_frmb | 0:215c9308dc52 | 104 | { |
co657_frmb | 0:215c9308dc52 | 105 | lcd.line (src[0].x, src[0].y, src[1].x, src[1].y, 1); |
co657_frmb | 0:215c9308dc52 | 106 | lcd.line (src[1].x, src[1].y, src[2].x, src[2].y, 1); |
co657_frmb | 0:215c9308dc52 | 107 | lcd.line (src[2].x, src[2].y, src[3].x, src[3].y, 1); |
co657_frmb | 0:215c9308dc52 | 108 | lcd.line (src[3].x, src[3].y, src[0].x, src[0].y, 1); |
co657_frmb | 0:215c9308dc52 | 109 | |
co657_frmb | 0:215c9308dc52 | 110 | lcd.line (src[4].x, src[4].y, src[5].x, src[5].y, 1); |
co657_frmb | 0:215c9308dc52 | 111 | lcd.line (src[5].x, src[5].y, src[6].x, src[6].y, 1); |
co657_frmb | 0:215c9308dc52 | 112 | lcd.line (src[6].x, src[6].y, src[7].x, src[7].y, 1); |
co657_frmb | 0:215c9308dc52 | 113 | lcd.line (src[7].x, src[7].y, src[4].x, src[4].y, 1); |
co657_frmb | 0:215c9308dc52 | 114 | |
co657_frmb | 0:215c9308dc52 | 115 | lcd.line (src[0].x, src[0].y, src[4].x, src[4].y, 1); |
co657_frmb | 0:215c9308dc52 | 116 | lcd.line (src[1].x, src[1].y, src[5].x, src[5].y, 1); |
co657_frmb | 0:215c9308dc52 | 117 | lcd.line (src[2].x, src[2].y, src[6].x, src[6].y, 1); |
co657_frmb | 0:215c9308dc52 | 118 | lcd.line (src[3].x, src[3].y, src[7].x, src[7].y, 1); |
co657_frmb | 0:215c9308dc52 | 119 | } |