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.
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
Generated on Tue Jul 12 2022 20:36:12 by 1.7.2