main.pp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. (*---------------------------------------------------------------------------------
  2. $id $
  3. Box test to demonstrate 3D bounding box es. also shows the effect of culling and
  4. clipping on vertex usage
  5. $log $
  6. *--------------------------------------------------------------------------------*)
  7. program main;
  8. {$apptype arm9}
  9. {$define ARM9}
  10. {$mode objfpc}
  11. uses
  12. ctypes, nds9;
  13. var
  14. rotX: cfloat = 0;
  15. rotY: cfloat = 0;
  16. translate: cfloat = -5.0;
  17. //some profiling code
  18. time: cuint16;
  19. //keep track of vertex ram usage
  20. polygon_count, vertex_count: integer;
  21. //object
  22. rx: integer = 50;
  23. ry: integer = 15;
  24. oldx: integer = 0;
  25. oldy: integer = 0;
  26. hit: integer;
  27. //some code for profiling
  28. function startTimer(timer: cint): cuint16;
  29. begin
  30. TIMER_CR(timer)^ := (0);
  31. TIMER_DATA(0)^ := (0);
  32. TIMER_CR(timer)^ := (TIMER_DIV_1);
  33. startTimer := TIMER_DATA(0)^;
  34. end;
  35. function getTimer(timer: integer): cuint32;
  36. begin
  37. getTimer := TIMER_DATA(timer)^;
  38. end;
  39. { $define getTimer(timer) := (TIMER_DATA(timer))^}
  40. //draws a box...same signature as boxTest
  41. procedure DrawBox(x, y, z, height, width, depth: cfloat);
  42. begin
  43. glBegin(GL_QUADS);
  44. //z face
  45. glColor3f(1,0,0);
  46. glVertex3f(x , y , z );
  47. glVertex3f(x + width, y , z );
  48. glVertex3f(x + width, y + height, z );
  49. glVertex3f(x , y + height, z );
  50. //z + depth face
  51. glColor3f(1,0,1);
  52. glVertex3f(x , y , z + depth);
  53. glVertex3f(x , y + height, z + depth);
  54. glVertex3f(x + width, y + height, z + depth);
  55. glVertex3f(x + width, y , z + depth);
  56. //x face
  57. glColor3f(1,1,0);
  58. glVertex3f(x , y , z );
  59. glVertex3f(x , y + height, z );
  60. glVertex3f(x , y + height, z + depth);
  61. glVertex3f(x , y , z + depth);
  62. //x + width face
  63. glColor3f(1,1,1);
  64. glVertex3f(x + width, y , z );
  65. glVertex3f(x + width, y , z + depth);
  66. glVertex3f(x + width, y + height, z + depth);
  67. glVertex3f(x + width, y + height, z );
  68. //y face
  69. glColor3f(0,1,0);
  70. glVertex3f(x , y , z );
  71. glVertex3f(x , y , z + depth);
  72. glVertex3f(x + width, y , z + depth);
  73. glVertex3f(x + width, y , z );
  74. //y + height face
  75. glColor3f(0,1,1);
  76. glVertex3f(x , y + height, z );
  77. glVertex3f(x + width, y + height, z );
  78. glVertex3f(x + width, y + height, z + depth);
  79. glVertex3f(x , y + height, z + depth);
  80. glEnd();
  81. end;
  82. var
  83. i: integer;
  84. //draw the clock
  85. begin
  86. // Turn on everything
  87. powerON(POWER_ALL);
  88. //put 3D on top
  89. lcdMainOnTop();
  90. //setup the sub screen for basic printing
  91. consoleDemoInit();
  92. // Setup the Main screen for 3D
  93. videoSetMode(MODE_0_3D);
  94. // IRQ basic setup
  95. irqInit();
  96. irqSet(IRQ_VBLANK, nil);
  97. // initialize gl
  98. glInit();
  99. // enable antialiasing
  100. glEnable(GL_ANTIALIAS);
  101. // setup the rear plane
  102. glClearColor(0,0,0,31); // BG must be opaque for AA to work
  103. glClearPolyID(63); // BG must have a unique polygon ID for AA to work
  104. glClearDepth($7FFF);
  105. // Set our view port to be the same size as the screen
  106. glViewPort(0,0,255,191);
  107. //main loop
  108. while true do
  109. begin
  110. scanKeys();
  111. //process input
  112. if (keysHeld() and KEY_LEFT) <> 0 then rotY := rotY + 1;
  113. if (keysHeld() and KEY_RIGHT) <> 0 then rotY := rotY - 1;
  114. if (keysHeld() and KEY_UP) <> 0 then rotX := rotX + 1;
  115. if (keysHeld() and KEY_DOWN) <> 0 then rotX := rotX - 1;
  116. if (keysHeld() and KEY_L) <> 0 then translate := translate + 0.1;
  117. if (keysHeld() and KEY_R) <> 0 then translate := translate - 0.1;
  118. //reset x and y when user touches screen
  119. if (keysDown() and KEY_TOUCH) <> 0 then
  120. begin
  121. oldx := touchReadXY().px;
  122. oldy := touchReadXY().py;
  123. end;
  124. //if user drags then grab the delta
  125. if (keysHeld() and KEY_TOUCH) <> 0 then
  126. begin
  127. rx := rx + touchReadXY().px - oldx;
  128. ry := ry + touchReadXY().py - oldy;
  129. oldx := touchReadXY().px;
  130. oldy := touchReadXY().py;
  131. end;
  132. //change ortho vs perspective
  133. glMatrixMode(GL_PROJECTION);
  134. glLoadIdentity();
  135. if (keysHeld() and KEY_B) <> 0 then
  136. glOrtho(-4,4,-3,3,0.1,10)
  137. else
  138. gluPerspective(35, 256.0 / 192.0, 0.1, 10);
  139. //change cull mode
  140. if (keysHeld() and KEY_A) <> 0 then
  141. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE )
  142. else
  143. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_FRONT );
  144. // Set the current matrix to be the model matrix
  145. glMatrixMode(GL_MODELVIEW);
  146. glLoadIdentity();
  147. //handle camera
  148. glRotateY(rotY);
  149. glRotateX(rotX);
  150. glTranslatef(0,0,translate);
  151. //move the cube
  152. glRotateX(ry);
  153. glRotateY(rx);
  154. DrawBox(-1,-1,-1,2,2,2);
  155. printf(#27 + '[2J' + 'Box test cycle count');
  156. time := startTimer(0);
  157. hit := BoxTestf(-1,-1,-1,2,2,2);
  158. printf(#10 + 'Single test (float): %i', [2*(getTimer(0) - time)]);
  159. time := startTimer(0);
  160. BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
  161. printf(#10 + 'Single test (fixed): %i', [2*(getTimer(0) - time)]);
  162. time := startTimer(0);
  163. for i := 0 to 63 do
  164. BoxTest(inttov16(-1),inttov16(-1),inttov16(-1),inttov16(2),inttov16(2),inttov16(2));
  165. printf(#10 + '64 tests avg. (fixed): %i', [(getTimer(0) - time) / 32]);
  166. if hit > 0 then
  167. printf(#10 + 'Box Test result: hit')
  168. else
  169. printf(#10 + 'Box Test result: miss');
  170. while (GFX_STATUS^ and (1 shl 27)) <> 0 do; // wait until the geometry engine is not busy
  171. glGetInt(GL_GET_VERTEX_RAM_COUNT, vertex_count);
  172. glGetInt(GL_GET_POLYGON_RAM_COUNT, polygon_count);
  173. if (keysHeld() and KEY_A) <> 0 then
  174. printf(#10#10 + 'Ram usage: Culling none')
  175. else
  176. printf(#10#10 + 'Ram usage: Culling back faces');
  177. printf(#10 + 'Vertex ram: %i', vertex_count);
  178. printf(#10 + 'Polygon ram: %i', polygon_count);
  179. printf(#10#10 + 'Press A to change culling');
  180. printf(#10#10 + 'Press B to change Ortho vs Persp');
  181. printf(#10 + 'Press Left and Right Up and Down to rotate');
  182. printf(#10 + 'Press L and R to zoom');
  183. printf(#10 + 'Touch screen to rotate cube');
  184. //a handy little built in function to wait for a screen refresh
  185. swiWaitForVBlank();
  186. // flush to screen
  187. glFlush(0);
  188. end;
  189. end.