lesson10b.pp 6.8 KB

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