lesson10.pp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. (****************************************
  2. * NDS NeHe Lesson 10 *
  3. * Author: Dovoto *
  4. ****************************************)
  5. program Lesson10;
  6. {$mode objfpc}
  7. {$L build/Mud.pcx.o}
  8. {$L build/World.txt.o}
  9. uses
  10. ctypes, nds9;
  11. {$include inc/Mud.pcx.inc}
  12. {$include inc/World.txt.inc}
  13. const
  14. piover180: cfloat = 0.0174532925;
  15. var
  16. heading: cfloat = 0.0;
  17. xpos: cfloat = 0.0;
  18. zpos: cfloat = 0.0;
  19. yrot: cfloat = 0.0; // Y Rotation
  20. walkbias: cfloat = 0.0;
  21. walkbiasangle: cfloat = 0.0;
  22. lookupdown: cfloat = 0.0;
  23. texture: array [0..2] of integer; // Storage For 3 Textures (only going to use 1 on the DS for this demo)
  24. type
  25. tagVERTEX = record
  26. x, y, z: cfloat;
  27. u, v: cfloat;
  28. end;
  29. VERTEX = tagVERTEX;
  30. tagTRIANGLE = record
  31. vertex: array [0..2] of VERTEX;
  32. end;
  33. TRIANGLE = tagTRIANGLE;
  34. TTriangle = TRIANGLE;
  35. PTriangle = ^TRIANGLE;
  36. tagSECTOR = record
  37. numtriangles: integer;
  38. triangle: PTRIANGLE;
  39. end;
  40. SECTOR = tagSECTOR;
  41. var
  42. sector1: SECTOR; // Our Model Goes Here:
  43. Myfile: pchar;
  44. function DrawGLScene(): boolean;
  45. var
  46. x_m, y_m, z_m: cfloat;
  47. u_m, v_m: cfloat;
  48. xtrans, ztrans, ytrans: cfloat;
  49. sceneroty: cfloat;
  50. numtriangles: integer;
  51. loop_m: integer;
  52. begin
  53. // Reset The View
  54. xtrans := -xpos;
  55. ztrans := -zpos;
  56. ytrans := -walkbias - 0.25;
  57. sceneroty := 360.0 - yrot;
  58. glLoadIdentity();
  59. glRotatef(lookupdown,1.0,0,0);
  60. glRotatef(sceneroty,0,1.0,0);
  61. glTranslatef(xtrans, ytrans, ztrans);
  62. glBindTexture(GL_TEXTURE_2D, texture[0]);
  63. numtriangles := sector1.numtriangles;
  64. // Process Each Triangle
  65. for loop_m := 0 to numtriangles - 1 do
  66. begin
  67. glBegin(GL_TRIANGLES);
  68. glNormal3f( 0.0, 0.0, 1.0);
  69. x_m := sector1.triangle[loop_m].vertex[0].x;
  70. y_m := sector1.triangle[loop_m].vertex[0].y;
  71. z_m := sector1.triangle[loop_m].vertex[0].z;
  72. u_m := sector1.triangle[loop_m].vertex[0].u;
  73. v_m := sector1.triangle[loop_m].vertex[0].v;
  74. glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
  75. x_m := sector1.triangle[loop_m].vertex[1].x;
  76. y_m := sector1.triangle[loop_m].vertex[1].y;
  77. z_m := sector1.triangle[loop_m].vertex[1].z;
  78. u_m := sector1.triangle[loop_m].vertex[1].u;
  79. v_m := sector1.triangle[loop_m].vertex[1].v;
  80. glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
  81. x_m := sector1.triangle[loop_m].vertex[2].x;
  82. y_m := sector1.triangle[loop_m].vertex[2].y;
  83. z_m := sector1.triangle[loop_m].vertex[2].z;
  84. u_m := sector1.triangle[loop_m].vertex[2].u;
  85. v_m := sector1.triangle[loop_m].vertex[2].v;
  86. glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
  87. glEnd();
  88. end;
  89. DrawGLScene := true; // Everything Went OK
  90. end;
  91. function tsin(angle: cfloat): cfloat;
  92. var
  93. s: cint32;
  94. begin
  95. s := sinLerp(trunc((angle * DEGREES_IN_CIRCLE) / 360.0));
  96. tsin := f32tofloat(s);
  97. end;
  98. function tcos(angle: cfloat): cfloat;
  99. var
  100. c: cint32;
  101. begin
  102. c := cosLerp(trunc((angle * DEGREES_IN_CIRCLE) / 360.0));
  103. tcos := f32tofloat(c);
  104. end;
  105. procedure myGetStr(buff: pchar; size: integer);
  106. begin
  107. buff^ := Myfile^;
  108. inc(MyFile);
  109. while (buff^ <> #10) and (buff^ <> #13) do
  110. begin
  111. inc(buff);
  112. buff^ := Myfile^;
  113. inc(MyFile);
  114. end;
  115. buff[0] := #10;
  116. buff[1] := #0;
  117. end;
  118. procedure readstr(str: pchar);
  119. begin
  120. repeat
  121. myGetStr(str, 255);
  122. until ((str[0] <> '/') and (str[0] <> #10));
  123. end;
  124. procedure SetupWorld();
  125. var
  126. x, y, z: cfloat;
  127. u, v: cfloat;
  128. numtriangles: integer;
  129. oneline: array [0..254] of char;
  130. loop, vert: integer;
  131. begin
  132. readstr(oneline);
  133. sscanf(oneline, 'NUMPOLLIES %d'#10, @numtriangles);
  134. GetMem(sector1.triangle, numtriangles * sizeof(TTRIANGLE));
  135. sector1.numtriangles := numtriangles;
  136. for loop := 0 to numtriangles - 1 do
  137. begin
  138. for vert := 0 to 2 do
  139. begin
  140. readstr(oneline);
  141. sscanf(oneline, '%f %f %f %f %f', @x, @y, @z, @u, @v);
  142. sector1.triangle[loop].vertex[vert].x := x;
  143. sector1.triangle[loop].vertex[vert].y := y;
  144. sector1.triangle[loop].vertex[vert].z := z;
  145. sector1.triangle[loop].vertex[vert].u := u;
  146. sector1.triangle[loop].vertex[vert].v := v;
  147. end;
  148. end;
  149. end;
  150. // Load PCX files And Convert To Textures
  151. function LoadGLTextures(): boolean;
  152. var
  153. pcx: sImage;
  154. begin
  155. //load our texture
  156. loadPCX(pcuint8(Mud_pcx), @pcx);
  157. image8to16(@pcx);
  158. glGenTextures(1, @texture[0]);
  159. glBindTexture(0, texture[0]);
  160. glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, TEXGEN_TEXCOORD or GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T, pcx.image.data8);
  161. imageDestroy(@pcx);
  162. result := true;
  163. end;
  164. var
  165. thisXY: touchPosition;
  166. lastXY: touchPosition;
  167. dx, dy: cint16;
  168. begin
  169. MyFile := pchar(@World_txt);
  170. // Setup the Main screen for 3D
  171. videoSetMode(MODE_0_3D);
  172. vramSetBankA(VRAM_A_TEXTURE); //NEW must set up some memory for textures
  173. consoleDemoInit();
  174. // initialize the geometry engine
  175. glInit();
  176. // enable textures
  177. glEnable(GL_TEXTURE_2D);
  178. // enable antialiasing
  179. glEnable(GL_ANTIALIAS);
  180. // setup the rear plane
  181. glClearColor(0,0,0,31); // BG must be opaque for AA to work
  182. glClearPolyID(63); // BG must have a unique polygon ID for AA to work
  183. glClearDepth($7FFF);
  184. // Set our viewport to be the same size as the screen
  185. glViewport(0,0,255,191);
  186. LoadGLTextures();
  187. SetupWorld();
  188. glMatrixMode(GL_PROJECTION);
  189. glLoadIdentity();
  190. gluPerspective(70, 256.0 / 192.0, 0.1, 100);
  191. glLight(0, RGB15(31,31,31) , 0, floattov10(-1.0), 0);
  192. //need to set up some material properties since DS does not have them set by default
  193. glMaterialf(GL_AMBIENT, RGB15(16,16,16));
  194. glMaterialf(GL_DIFFUSE, RGB15(16,16,16));
  195. glMaterialf(GL_SPECULAR, BIT(15) or RGB15(8,8,8));
  196. glMaterialf(GL_EMISSION, RGB15(16,16,16));
  197. //ds uses a table for shinyness..this generates a half-ass one
  198. glMaterialShinyness();
  199. //ds specific, several attributes can be set here
  200. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_NONE or POLY_FORMAT_LIGHT0);
  201. // Set the current matrix to be the model matrix
  202. glMatrixMode(GL_MODELVIEW);
  203. while true do
  204. begin
  205. //these little button functions are pretty handy
  206. scanKeys();
  207. if (keysHeld() and KEY_A) <> 0 then lookupdown := lookupdown - 1.0;
  208. if (keysHeld() and KEY_B) <> 0 then lookupdown := lookupdown + 1.0;
  209. if (keysHeld() and KEY_LEFT) <> 0 then
  210. begin
  211. heading := heading + 1.0;
  212. yrot := heading;
  213. end;
  214. if (keysHeld() and KEY_RIGHT) <> 0 then
  215. begin
  216. heading := heading - 1.0;
  217. yrot := heading;
  218. end;
  219. if (keysHeld() and KEY_DOWN) <> 0 then
  220. begin
  221. xpos := xpos + (tsin(heading)) * 0.05;
  222. zpos := zpos + (tcos(heading)) * 0.05;
  223. if (walkbiasangle >= 359.0) then
  224. walkbiasangle := 0.0
  225. else
  226. walkbiasangle:= walkbiasangle+10;
  227. walkbias := tsin(walkbiasangle) / 20.0;
  228. end;
  229. if (keysHeld() and KEY_UP) <> 0 then
  230. begin
  231. xpos := xpos - (tsin(heading)) * 0.05;
  232. zpos := zpos - (tcos(heading)) * 0.05;
  233. if (walkbiasangle <= 1.0) then
  234. walkbiasangle := 359.0
  235. else
  236. walkbiasangle := walkbiasangle- 10;
  237. walkbias := tsin(walkbiasangle) / 20.0;
  238. end;
  239. glColor3f(1,1,1);
  240. DrawGLScene();
  241. // flush to screen
  242. glFlush(0);
  243. // wait for the screen to refresh
  244. swiWaitForVBlank();
  245. end;
  246. end.