Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This demo shows a number of dots projected on a rotating sphere.

Dependencies:   EALib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GlobeDemo.cpp Source File

GlobeDemo.cpp

00001 /******************************************************************************
00002  * Includes
00003  *****************************************************************************/
00004 
00005 #include "mbed.h"
00006 
00007 #include "LcdController.h"
00008 #include "EaLcdBoard.h"
00009 #include "GlobeDemo.h"
00010 
00011 #include <math.h>
00012 
00013 //#include "wchar.h"
00014 
00015 /******************************************************************************
00016  * Typedefs and defines
00017  *****************************************************************************/
00018 
00019 #define NUM_OF_DOTS 50
00020 
00021 /******************************************************************************
00022  * Local variables
00023  *****************************************************************************/
00024 
00025 
00026 /******************************************************************************
00027  * External variables
00028  *****************************************************************************/
00029 
00030 /******************************************************************************
00031  * Local functions
00032  *****************************************************************************/
00033 
00034 // Vertex structure
00035 typedef struct
00036 {
00037 #ifdef USE_FLOAT
00038   float x, y, z;
00039 #else
00040   long x, y, z;
00041 #endif
00042 }tVertex;
00043 
00044 // Transformed vertices
00045 tVertex *gRVtx;
00046 
00047 #ifdef USE_FLOAT
00048 // Original vertices
00049 static tVertex *gVtx;
00050 #else
00051 static const tVertex gVtx[NUM_OF_DOTS] = {
00052 {-21585, 17597, -17265},
00053 {28493, -7790, 14183},
00054 {13031, 27845, 11338},
00055 {10822, 29162, -10304},
00056 {19517, -25865, -4876},
00057 {1283, 30949, -10687},
00058 {-23097, 12297, 19723},
00059 {-17162, 1188, 27888},
00060 {-29007, -1547, 15163},
00061 {-8182, -31729, -197},
00062 {11599, -28575, -11073},
00063 {25963, 12182, 15850},
00064 {106, 10547, -31023},
00065 {-24312, 3053, -21755},
00066 {9966, -18803, -24916},
00067 {17598, -6037, -26973},
00068 {23321, 17149, -15353},
00069 {-3265, 8867, -31376},
00070 {-23639, 13701, 18087},
00071 {-2433, -22123, -24049},
00072 {21284, -11349, -22179},
00073 {-21407, 24683, -2486},
00074 {-32011, -4336, 5495},
00075 {-20191, 22605, 12450},
00076 {14752, -23540, 17376},
00077 {-8961, -17292, -26351},
00078 {-18078, 13561, -23727},
00079 {10730, -23639, 19994},
00080 {-18718, 17555, 20376},
00081 {13626, -22837, 19144},
00082 {-24695, -19036, -10073},
00083 {11935, 22275, 20859},
00084 {-2182, -28801, -15474},
00085 {21428, -21867, -11678},
00086 {-19601, 21558, -14991},
00087 {24512, 10876, -18830},
00088 {12385, 27881, 11956},
00089 {26982, 15618, -10088},
00090 {-16954, 19591, 20061},
00091 {-6027, 22699, -22850},
00092 {5453, 28825, -14598},
00093 {-20155, -16252, -20083},
00094 {-15962, 11757, -26089},
00095 {-29175, -11289, -9750},
00096 {-15370, 604, -28933},
00097 {26009, 19868, -1575},
00098 {24722, -17277, -12806},
00099 {-4527, 25836, -19639},
00100 {-22224, 10442, 21697},
00101 {-10388, 24393, -19255}};
00102 #endif
00103 
00104 unsigned short GlobeDemo::isqrt(unsigned long a) const {
00105     unsigned long temp;
00106     long e;
00107     unsigned long x = 0;
00108     if((a & 0xffff0000) != 0)
00109         x = 444 + a / 26743;
00110     else if((a & 0xff00) != 0)
00111         x = 21 + a / 200;
00112     else
00113         x = 1 + a / 12;
00114     do{
00115         temp = a / x;
00116         e = (x - temp) / 2;
00117         x = (x + temp) / 2;
00118     }
00119     while(e != 0);
00120     return (unsigned short)x;
00121 }
00122 
00123 short GlobeDemo::_sin(short y) const {
00124     static short s1 = 0x6487;
00125     static short s3 = 0x2951;
00126     static short s5 = 0x4f6;
00127     long z, prod, sum;
00128 
00129     z = ((long)y * y) >> 12;
00130     prod = (z * s5) >> 16;
00131     sum = s3 - prod;
00132     prod = (z * sum) >> 16;
00133     sum = s1 - prod;
00134 
00135     // for better accuracy, round here
00136     return (short)((y * sum) >> 13);
00137  }
00138 
00139 short GlobeDemo::_cos(short y) const {
00140     static short c0 = 0x7fff;
00141     static short c2 = 0x4eea;
00142     static short c4 = 0x0fc4;
00143     long z, prod, sum;
00144     z = ((long)y * y) >> 12;
00145     prod = (z * c4) >> 16;
00146     sum = c2 - prod;
00147 
00148     // for better accuracy, round here
00149     prod = (z * sum) >> 15;
00150     return (short)(c0 - prod);
00151 }
00152 
00153 short GlobeDemo::isine(short x) const {
00154     unsigned short n = (((unsigned short)x + 0x2000) >> 14) & 0x3;
00155     x -= n * 0x4000;
00156     switch(n){
00157         case 0:
00158             return _sin(x);
00159         case 1:
00160             return _cos(x);
00161         case 2:
00162             return - _sin(x);
00163         case 3:
00164             return  - _cos(x);
00165     }
00166     return 0;
00167  }
00168 
00169 
00170 short GlobeDemo::icosine(short x) const {
00171     return isine(x + 0x4000);
00172  }
00173 
00174 void GlobeDemo::initialize()
00175 {
00176 //  gVtx = (tVertex*)malloc(sizeof(tVertex) * NUM_OF_DOTS);
00177   gRVtx = (tVertex*)malloc(sizeof(tVertex) * NUM_OF_DOTS);
00178 
00179 #ifdef USE_FLOAT
00180   int i;
00181   for (i = 0; i < NUM_OF_DOTS; i++)
00182   {
00183     gVtx[i].x = (rand() % 32768) - 16384.0f;
00184     gVtx[i].y = (rand() % 32768) - 16384.0f;
00185     gVtx[i].z = (rand() % 32768) - 16384.0f;
00186     float len = (float)sqrt(gVtx[i].x * gVtx[i].x + 
00187                             gVtx[i].y * gVtx[i].y + 
00188                             gVtx[i].z * gVtx[i].z);
00189     if (len != 0)
00190     {
00191       gVtx[i].x /= len;
00192       gVtx[i].y /= len;
00193       gVtx[i].z /= len;
00194     }
00195   }
00196 #endif
00197 }
00198 
00199 #ifdef USE_FLOAT
00200 void GlobeDemo::rotate_z(float angle)
00201 {
00202   float ca = (float)cos(angle);
00203   float sa = (float)sin(angle);
00204   int i;
00205   for (i = 0; i < NUM_OF_DOTS; i++)
00206   {
00207     float x = gRVtx[i].x * ca - gRVtx[i].y * sa;
00208     float y = gRVtx[i].x * sa + gRVtx[i].y * ca;
00209     gRVtx[i].x = x;
00210     gRVtx[i].y = y;
00211   }
00212 }
00213 
00214 void GlobeDemo::rotate_y(float angle)
00215 {
00216   float ca = (float)cos(angle);
00217   float sa = (float)sin(angle);
00218   int i
00219   for (i = 0; i < NUM_OF_DOTS; i++)
00220   {
00221     float z = gRVtx[i].z * ca - gRVtx[i].x * sa;
00222     float x = gRVtx[i].z * sa + gRVtx[i].x * ca;
00223     gRVtx[i].z = z;
00224     gRVtx[i].x = x;
00225   }
00226 }
00227 #else
00228 void GlobeDemo::rotate_z(uint32_t angle)
00229 {
00230   uint32_t i;
00231   long x,y,ca,sa;
00232 
00233   ca = icosine(angle);
00234   sa = isine(angle);
00235   for (i = 0; i < NUM_OF_DOTS; i++)
00236   {
00237     x = (gRVtx[i].x * ca - gRVtx[i].y * sa) / 0x7fff;
00238     y = (gRVtx[i].x * sa + gRVtx[i].y * ca) / 0x7fff;
00239     gRVtx[i].x = x;
00240     gRVtx[i].y = y;
00241   }
00242 }
00243 
00244 void GlobeDemo::rotate_y(uint32_t angle)
00245 {
00246   uint32_t i;
00247   long x,z,ca,sa;
00248 
00249   ca = icosine(angle);
00250   sa = isine(angle);
00251   for (i = 0; i < NUM_OF_DOTS; i++)
00252   {
00253     z = (gRVtx[i].z * ca - gRVtx[i].x * sa) / 0x7fff;
00254     x = (gRVtx[i].z * sa + gRVtx[i].x * ca) / 0x7fff;
00255     gRVtx[i].z = z;
00256     gRVtx[i].x = x;
00257   }
00258 }
00259 #endif
00260 
00261 #if 0
00262 void GlobeDemo::rotate_x(float angle)
00263 {
00264   float ca = (float)cos(angle);
00265   float sa = (float)sin(angle);
00266   int i;
00267   for (i = 0; i < NUM_OF_DOTS; i++)
00268   {
00269     float y = gRVtx[i].y * ca - gRVtx[i].z * sa;
00270     float z = gRVtx[i].y * sa + gRVtx[i].z * ca;
00271     gRVtx[i].y = y;
00272     gRVtx[i].z = z;
00273   }
00274 }
00275 #endif
00276 
00277 void GlobeDemo::render(uint32_t idx)
00278 {
00279   uint32_t i;
00280 #ifdef USE_FLOAT
00281   float rotz;
00282   float roty;
00283 #else
00284   uint32_t rotz;
00285   uint32_t roty;
00286 #endif
00287 
00288  static uint8_t cnt=0;
00289 
00290   if (cnt == 0)
00291   {
00292     cnt = 1;
00293     pFrmBuf = pFrmBuf1;
00294   }
00295   else if (cnt == 1)
00296   {
00297     cnt = 2;
00298     pFrmBuf = pFrmBuf2;
00299   }
00300   else
00301   {
00302     cnt = 0;
00303     pFrmBuf = pFrmBuf3;
00304   }
00305 
00306   graphics.setFrameBuffer(pFrmBuf);
00307 
00308   // rendering here
00309   memset((void*)(pFrmBuf), BACKGROUND_COLOR, this->windowX * this->windowY * 2);
00310 
00311 //  lcd_fillcircle(myLcdHnd, WIDTH / 2, HEIGHT / 2, HEIGHT / 4, LARGE_CIRCLE_COLOR);
00312   graphics.put_circle(this->windowX / 2, this->windowY / 2, LARGE_CIRCLE_COLOR, this->windowY / 4, 1);
00313 
00314   memcpy(gRVtx, gVtx, sizeof(tVertex) * NUM_OF_DOTS);
00315 
00316 #ifdef USE_FLOAT
00317   rotz = idx /*tick*/ * 0.0005f;
00318   roty = idx /*tick*/ * 0.0020f;
00319 #else
00320   rotz = idx /*tick*/ * 50*5;
00321   roty = idx /*tick*/ * 200*5;
00322 #endif
00323   rotate_y(roty);
00324   rotate_z(rotz);
00325 
00326   for (i = 0; i < NUM_OF_DOTS; i++)
00327   {
00328     uint16_t c = SMALL_CIRCLE_FRONT_COLOR;
00329 
00330     if (gRVtx[i].z < 0)
00331       c = SMALL_CIRCLE_BACK_COLOR;
00332 #if 0
00333     lcd_point(myLcdHnd,
00334               (int)((gRVtx[i].x * (HEIGHT / 4)) / 0x7fff + WIDTH  / 2),
00335               (int)((gRVtx[i].y * (HEIGHT / 4)) / 0x7fff + HEIGHT / 2),
00336               c);
00337 #else
00338 //    lcd_fillcircle(myLcdHnd,
00339 //                   (int)((gRVtx[i].x * (HEIGHT / 4)) / 0x7fff + WIDTH / 2),
00340 //                   (int)((gRVtx[i].y * (HEIGHT / 4)) / 0x7fff + HEIGHT / 2),
00341 //                   2,
00342 //                   c);
00343     graphics.put_circle((int)((gRVtx[i].x * (this->windowY / 4)) / 0x7fff + this->windowX / 2), (int)((gRVtx[i].y * (this->windowY / 4)) / 0x7fff + this->windowY / 2), c, 2, 1);
00344 
00345 #endif
00346   } 
00347 #ifdef USE_FLOAT
00348   lcd_fillcircle(myLcdHnd,
00349                  (int)((WIDTH / 3) * cos(rotz) + WIDTH / 2),
00350                  (int)((WIDTH / 3) * sin(rotz) + HEIGHT / 2),
00351                  6,
00352                  SMALL_CIRCLE_FRONT_COLOR);
00353 #else
00354 //  lcd_fillcircle(myLcdHnd,
00355 //                 (int)(((HEIGHT / 3) * icosine(rotz))/0x7fff + WIDTH / 2),
00356 //                 (int)(((HEIGHT / 3) * isine(rotz))  /0x7fff + HEIGHT / 2),
00357 //                 7,
00358 //                 SMALL_CIRCLE_FRONT_COLOR);
00359     graphics.put_circle((int)(((this->windowY / 3) * icosine(rotz))/0x7fff + this->windowX / 2), (int)(((this->windowY / 3) * isine(rotz))  /0x7fff + this->windowY / 2), SMALL_CIRCLE_FRONT_COLOR, 7, 1);
00360 #endif
00361 }
00362 
00363 
00364 /******************************************************************************
00365  * Public functions
00366  *****************************************************************************/
00367 GlobeDemo::GlobeDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight) 
00368     : graphics((uint16_t *)pFrameBuf, dispWidth, dispHeight) {
00369 
00370     this->windowX = dispWidth;
00371     this->windowY = dispHeight;
00372     this->pFrmBuf  = (uint16_t *)pFrameBuf;
00373     this->pFrmBuf1 = (uint16_t *)pFrameBuf;
00374     this->pFrmBuf2 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*2);
00375     this->pFrmBuf3 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*4);
00376 
00377     initialize();
00378 }
00379 
00380 void GlobeDemo::run(EaLcdBoardGPIO& lcdBoard, uint32_t loops, uint32_t delayMs) {
00381 
00382   printf("GlobeDemo, %d loops, %dms delay\n", loops, delayMs);
00383   
00384     for(int32_t n=0;n<loops;n++) {
00385     
00386         //render globe
00387         render(n);
00388     
00389         //update framebuffer
00390         lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf);
00391 
00392         wait_ms(delayMs);
00393     }
00394     free(gRVtx);
00395 }
00396