Demo code for basic 3D graphics on the MBED application shield's LCD (K64F). Left pot changes Z depth, joystick rotates one of the cubes.

Dependencies:   C12832 FXOS8700CQ gfx3d mbed

Revision:
3:23a93f2f8cac
Parent:
2:297b43e931d0
Child:
4:2828d6a81907
--- a/main.cpp	Sat Nov 28 01:42:18 2015 +0000
+++ b/main.cpp	Sun Nov 29 00:04:35 2015 +0000
@@ -95,6 +95,47 @@
 }
 
 
+static char *scrolly_message = "  ...  Welcome to the wonderful world of MBED and CO657 ...       ";
+
+
+/*
+ *  some grot for handling scrolling text
+ */
+static void scroll_text_update (int *firstch, int *xdelta, const char *str)
+{
+    int xoff = *xdelta;
+    int fch = *firstch;
+    int hcnt, ccnt, lxoff, hxoff;
+    
+    /* see how many characters starting with fch will fit into the buffer (allow overrun) */
+    for (hcnt=0; (str[fch + hcnt] != '\0') && (xoff < (TXBUF_WIDTH >> 1)); hcnt++) {
+        xoff += gfx3d_font04b_char_dpw (str[fch + hcnt]);
+    }
+    hxoff = xoff;
+    for (ccnt=hcnt; (str[fch + ccnt] != '\0') && (xoff < TXBUF_WIDTH); ccnt++) {
+        xoff += gfx3d_font04b_char_dpw (str[fch + ccnt]);
+    }
+    
+    /* clear and render */
+    memset (ltxbuf, 0xff, TXBUF_WIDTH * 4);
+    lxoff = *xdelta;
+    gfx3d_font04b_tx_putstrn (ltxbuf, TXBUF_WIDTH, &lxoff, 8, str + fch, ccnt, true);
+
+    if (hxoff == (TXBUF_WIDTH >> 1)) {
+        /* hit exactly */
+        *xdelta = 0;
+        *firstch = fch + hcnt;
+    } else if (hxoff > (TXBUF_WIDTH >> 1)) {
+        /* last character overshoots middle, include it next time */
+        *firstch = fch + (hcnt - 1);
+        *xdelta = (TXBUF_WIDTH >> 1) - hxoff;
+    } else {
+        /* ran out of string, redo from start */
+        *firstch = 0;
+        *xdelta = 0;
+    }
+}
+
 
 /*
  *  start here
@@ -109,7 +150,11 @@
     angle_t y_rot = 0;
     FXOSData_t fxos_data;
     uint8_t ljoybits = 0x00;            /* local joystick bits (JOY_...) */
-    static const uint8_t *std_cube_txmap[6] = {g3d_texture_face, g3d_texture_hlife, g3d_texture_ccube, g3d_texture_face, g3d_texture_hlife, g3d_texture_ccube};
+    const uint8_t *std_cube_txmap[6] = {g3d_texture_face, g3d_texture_hlife, g3d_texture_ccube, g3d_texture_hlife, g3d_texture_face, g3d_texture_ccube};
+    const uint8_t *wcube_txmap[6] = {g3d_texture_wcube, g3d_texture_wcube, g3d_texture_wcube, g3d_texture_wcube, g3d_texture_wcube, g3d_texture_wcube};
+    int ltxoffs = 0;
+    int sc_fch = 0;
+    int sc_xdt = 0;
     
     uint16_t pot1val, pot2val;
     
@@ -155,6 +200,9 @@
     /* Example data printing */
     fxos.get_data (&fxos_data);
     print_reading (&fxos_data);
+    
+    /* clear texture buffer */
+    scroll_text_update (&sc_fch, &sc_xdt, scrolly_message);
 
 #ifdef BENCHMARK
     perftimer.reset ();
@@ -178,6 +226,7 @@
             int npolys = 0;                     /* number of polygons that are meaningful */
             int i;
             uint16_t n_pot1, n_pot2;
+            const uint8_t *wrapmap[6] = {&(ltxbuf[ltxoffs + 0]), &(ltxbuf[ltxoffs + 128]), &(ltxbuf[ltxoffs + 256]), &(ltxbuf[ltxoffs + 384]), g3d_texture_check, g3d_texture_check};
             
 #ifdef BENCHMARK
             bt_start = perftimer.read_us ();
@@ -260,14 +309,15 @@
                 }
 
                 gfx3d_project (pts1, pts2, 8);
-                gfx3d_cubify_points (pts2, poly, &npolys, 0, std_cube_txmap);       /* hide backfaces */
+                if (i == 0) {
+                    gfx3d_cubify_points (pts2, poly, &npolys, 0, wrapmap);       /* hide backfaces */
+                } else if (i == 3) {
+                    gfx3d_cubify_points (pts2, poly, &npolys, 0, wcube_txmap);       /* hide backfaces */
+                } else {
+                    gfx3d_cubify_points (pts2, poly, &npolys, 0, std_cube_txmap);       /* hide backfaces */
+                }
                 for (j=0; j<npolys; j++) {
                     gfx3d_sort_poly (&poly[j]);
-                    if (i < 3) {
-                        /* nothing here for this one */
-                    } else {
-                        gfx3d_edgebuf_z (&poly[j], &pedge[j]);
-                    }
                 }
 
 #if 0
@@ -284,15 +334,11 @@
                 bt_start = bt_now;
 #endif
 
-                // gfx3d_wirecube (pts2, shld_lcd);
                 for (j=0; j<npolys; j++) {
-                    // gfx3d_wirepoly (&poly[j], shld_lcd);
-                    if (i < 2) {
-                        gfx3d_polytxmap (&poly[j], shld_lcd);
-                    } else if (i == 2) {
+                    if (i == 2) {
                         gfx3d_polynormmap (&poly[j], shld_lcd);
                     } else {
-                        gfx3d_wireedge (&pedge[j], shld_lcd);
+                        gfx3d_polytxmap (&poly[j], shld_lcd);
                     }
                 }
                 
@@ -305,17 +351,27 @@
             }
 #endif  /* (debugging what polygons to use) */
             
+            /* filled up the frame-buffer, setup things for next time */
             a++;
+            
             if (ljoybits & JOY_UP) {
                 y_rot += JOY_ANGLE_ADVANCE;
             } else if (ljoybits & JOY_DOWN) {
                 y_rot -= JOY_ANGLE_ADVANCE;
             }
+            
             if (ljoybits & JOY_LEFT) {
                 x_rot += JOY_ANGLE_ADVANCE;
             } else if (ljoybits & JOY_RIGHT) {
                 x_rot -= JOY_ANGLE_ADVANCE;
             }
+            
+            ltxoffs += 4;
+            if (ltxoffs >= 512) {
+                /* update scrolly text */
+                scroll_text_update (&sc_fch, &sc_xdt, scrolly_message);
+                ltxoffs -= 512;
+            }
 
 #ifdef BENCHMARK
             /* write bt_trans and bt_render into the display */