vbuffer.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. (*
  2. Space Impakto DS
  3. relminator
  4. Http://Rel.Phatcode.Net
  5. TVertexbuffer class
  6. *)
  7. unit VBuffer;
  8. {$mode objfpc}
  9. {$H+}
  10. interface
  11. uses
  12. ctypes, nds9, math;
  13. const
  14. PI = 3.141593;
  15. TWOPI: cfloat = PI * 2;
  16. type
  17. TVector3f32 = packed record
  18. x: cint32;
  19. y: cint32;
  20. z: cint32;
  21. end;
  22. PVector3f32 = ^TVector3f32;
  23. TRGBf32 = packed record
  24. r: cint32;
  25. g: cint32;
  26. b: cint32;
  27. end;
  28. PRGBf32 = ^TRGBf32;
  29. TTexcoordf32 = packed record
  30. u: cint32;
  31. v: cint32;
  32. end;
  33. PTexcoordf32 =^TTexcoordf32;
  34. TPolygon = packed record
  35. v1: cuint32;
  36. v2: cuint32;
  37. v3: cuint32;
  38. end;
  39. PPolygon = ^TPolygon;
  40. // vertex buffer object. LOL
  41. TVertexbuffer = class
  42. public
  43. i_max_poly: cint;
  44. i_max_vertex: cint;
  45. i_primitive_type: cint;
  46. i_texture_ID: cint;
  47. ips_vertex: array of TVector3f32;
  48. ips_texture: array of TTexcoordf32;
  49. ips_color: array of TRGBf32;
  50. ps_poly: array of TPolygon;
  51. constructor Create;
  52. destructor Destroy;
  53. procedure render(text_off_u, text_off_v: cint32; colorize: boolean);
  54. //procedure render_lines(r, g, b: cuint8);
  55. function load_texture(texture_gfx: pcuint8): cint;
  56. end;
  57. PVertexBuffer = ^TVertexBuffer;
  58. function init_grid( rings, bands: cint;
  59. width, height: cfloat;
  60. uscale, vscale: cint): PVertexBuffer;
  61. function init_super_shape(rings, bands: cint;
  62. radius: cfloat;
  63. uscale, vscale: cint;
  64. a, b, m, n1, n2, n3: cfloat): PVertexBuffer;
  65. function init_ascaris(rings, bands: cint;
  66. radius, center_offset: cfloat;
  67. uscale, vscale: cint): PVertexBuffer;
  68. implementation
  69. constructor TVertexBuffer.Create();
  70. begin
  71. SetLength(ips_vertex, 0);
  72. SetLength(ips_texture, 0);
  73. SetLength(ips_color, 0);
  74. SetLength(ps_poly, 0);
  75. i_max_poly := 0;
  76. i_primitive_type := 0;
  77. i_texture_ID := 0;
  78. end;
  79. destructor TVertexBuffer.Destroy();
  80. begin
  81. if Length(ips_vertex) > 0 then
  82. SetLength(ips_vertex, 0);
  83. if Length(ps_poly) > 0 then
  84. SetLength(ps_poly, 0);
  85. i_max_poly := 0;
  86. i_primitive_type := 0;
  87. i_texture_ID := 0;
  88. if Length(ips_texture) > 0 then
  89. SetLength(ips_texture, 0);
  90. if Length(ips_color) > 0 then
  91. SetLength(ips_color, 0);
  92. end;
  93. procedure TVertexbuffer.render(text_off_u, text_off_v: cint32; colorize: boolean);
  94. var
  95. i: integer;
  96. i1,i2,i3: integer;
  97. begin
  98. glEnable(GL_TEXTURE_2D);
  99. glBindTexture(0, i_texture_ID);
  100. if (colorize) then
  101. begin
  102. glBegin (GL_TRIANGLES);
  103. //glNormal(NORMAL_PACK(0,inttov10(-1),0));
  104. for i := 0 to i_max_poly - 1 do
  105. begin
  106. i1 := ps_poly[i].v1;
  107. i2 := ps_poly[i].v2;
  108. i3 := ps_poly[i].v3;
  109. glColor3b(ips_color[i1].r, ips_color[i1].g, ips_color[i1].b);
  110. glTexCoord2f32(ips_texture[i1].u + text_off_u, ips_texture[i1].v + text_off_v);
  111. glVertex3v16(ips_vertex[i1].x, ips_vertex[i1].y, ips_vertex[i1].z);
  112. glColor3b(ips_color[i2].r, ips_color[i2].g, ips_color[i2].b);
  113. glTexCoord2f32(ips_texture[i2].u + text_off_u, ips_texture[i2].v + text_off_v);
  114. glVertex3v16(ips_vertex[i2].x, ips_vertex[i2].y, ips_vertex[i2].z);
  115. glColor3b(ips_color[i3].r, ips_color[i3].g, ips_color[i3].b);
  116. glTexCoord2f32(ips_texture[i3].u + text_off_u, ips_texture[i3].v + text_off_v);
  117. glVertex3v16(ips_vertex[i3].x, ips_vertex[i3].y, ips_vertex[i3].z);
  118. end;
  119. glEnd();
  120. end else
  121. begin
  122. glBegin (GL_TRIANGLES);
  123. //glNormal(NORMAL_PACK(0,inttov10(-1),0));
  124. for i := 0 to i_max_poly - 1 do
  125. begin
  126. i1 := ps_poly[i].v1;
  127. i2 := ps_poly[i].v2;
  128. i3 := ps_poly[i].v3;
  129. glTexCoord2f32(ips_texture[i1].u +text_off_u,ips_texture[i1].v +text_off_v);
  130. glVertex3v16 (ips_vertex[i1].x,ips_vertex[i1].y,ips_vertex[i1].z);
  131. glTexCoord2f32 (ips_texture[i2].u + text_off_u,ips_texture[i2].v +text_off_v);
  132. glVertex3v16 (ips_vertex[i2].x,ips_vertex[i2].y,ips_vertex[i2].z);
  133. glTexCoord2f32 (ips_texture[i3].u + text_off_u,ips_texture[i3].v +text_off_v);
  134. glVertex3v16 (ips_vertex[i3].x,ips_vertex[i3].y,ips_vertex[i3].z);
  135. end;
  136. glEnd();
  137. end;
  138. end;
  139. function Tvertexbuffer.load_texture(texture_gfx: pcuint8): cint;
  140. begin
  141. if (texture_gfx^) = 0 then
  142. result := 1
  143. else
  144. begin
  145. glGenTextures(1, @i_texture_ID);
  146. glBindTexture(0, i_texture_ID);
  147. glTexImage2D( 0, 0, GL_RGB, TEXTURE_SIZE_128 , TEXTURE_SIZE_128, 0, GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T or TEXGEN_TEXCOORD, texture_gfx);
  148. result := 0;
  149. end;
  150. end;
  151. // special functions
  152. function init_grid(rings, bands: cint; width, height: cfloat; uscale, vscale: cint): PVertexBuffer;
  153. var
  154. vb: PVertexBuffer;
  155. max_point: cint;
  156. ivertex: array of TVector3f32;
  157. itexture: array of TTexcoordf32;
  158. icolor: array of TRGBf32;
  159. poly: array of TPolygon;
  160. s, u, slice, maxvert: cint;
  161. i: cint;
  162. ii, jj: integer;
  163. half_width, half_height, a1, a2: cfloat;
  164. k: cint;
  165. x, y, z: cfloat;
  166. _u, _v: cfloat;
  167. begin
  168. new(vb);
  169. vb^ := TVertexBuffer.Create();
  170. max_point := (rings) * (bands); //+1 for last band duplicate
  171. SetLength(ivertex, max_point);
  172. SetLength(itexture, max_point); //
  173. SetLength(icolor, max_point);
  174. SetLength(poly, max_point * 2); //
  175. vb^.ips_vertex := ivertex;
  176. vb^.ips_texture := itexture;
  177. vb^.ips_color := icolor;
  178. vb^.ps_poly := poly;
  179. vb^.i_max_vertex := max_point;
  180. vb^.i_max_poly := max_point * 2;
  181. vb^.i_primitive_type := GL_TRIANGLES;
  182. maxvert := max_point;
  183. i := 0;
  184. for s := 0 to rings - 1 do
  185. begin
  186. slice := s * bands;
  187. for u := 0 to bands - 1 do //duplicate texture ( not bands - 1)
  188. begin
  189. poly[i].v1 := (u + bands + 1 + (slice)) mod maxvert;
  190. poly[i].v2 := (u + bands + (slice)) mod maxvert;
  191. poly[i].v3 := (u + (slice)) mod maxvert;
  192. poly[i+1].v1 := (u + (slice)) mod maxvert;
  193. poly[i+1].v2 := (u + 1 + (slice)) mod maxvert;
  194. poly[i+1].v3 := (u + bands + 1 + (slice)) mod maxvert;
  195. inc(i, 2);
  196. end;
  197. end;
  198. half_width := width / 2;
  199. half_height := height / 2;
  200. a1 := 2 * width / rings;
  201. a2 := 2 * height / bands;
  202. k := 0;
  203. for ii := 0 to rings - 1 do
  204. begin
  205. for jj := 0 to bands - 1 do
  206. begin
  207. x := -half_width + (ii * a1);
  208. y := 0;
  209. z := -half_height + (jj * a2);;
  210. ivertex[k].x := floattov16(x);
  211. ivertex[k].y := floattov16(y);
  212. ivertex[k].z := floattov16(z);
  213. icolor[k].r := (1 - (jj * 4 div bands)) * 255;
  214. icolor[k].g := (1 - (jj * 4 div bands)) * 255;
  215. icolor[k].b := (1 - (jj * 4 div bands)) * 255;
  216. _u := (ii / rings ) * uscale;
  217. _v := (jj / bands ) * vscale;
  218. itexture[k].u := floattof32(_u);
  219. itexture[k].v := floattof32(_v);
  220. inc(k);
  221. end;
  222. end;
  223. result := vb;
  224. end;
  225. function init_super_shape (rings, bands: cint; radius: cfloat; uscale, vscale: cint;
  226. a, b, m, n1, n2, n3: cfloat): PVertexBuffer;
  227. var
  228. vb: PVertexBuffer;
  229. max_point: cint;
  230. ivertex: array of TVector3f32;
  231. itexture: array of TTexcoordf32;
  232. icolor: array of Trgbf32;
  233. poly: array of Tpolygon;
  234. s, u, slice, maxvert: cint;
  235. i: cint;
  236. phi, theta: cfloat;
  237. r1, r2, a1, a2: cfloat;
  238. Tpi_d: cfloat;
  239. Ppi_d: cfloat;
  240. k: cint;
  241. ii, jj: integer;
  242. x, y, z: cfloat;
  243. _u, _v: cint;
  244. begin
  245. new(vb);
  246. vb^ := TVertexBuffer.Create();
  247. max_point := rings * (bands + 1); //+1 for last band duplicate
  248. SetLength(ivertex, max_point);
  249. SetLength(itexture, max_point);
  250. SetLength(icolor, max_point);
  251. SetLength(poly, max_point * 2);
  252. vb^.ips_vertex := ivertex;
  253. vb^.ips_texture := itexture;
  254. vb^.ips_color := icolor;
  255. vb^.ps_poly := poly;
  256. vb^.i_max_vertex := max_point;
  257. vb^.i_max_poly := max_point * 2;
  258. vb^.i_primitive_type := GL_TRIANGLES;
  259. //lathing
  260. maxvert := max_point;
  261. i := 0;
  262. for s := 0 to rings - 1 do
  263. begin
  264. slice := s * bands;
  265. for u := 0 to bands - 1 do
  266. begin
  267. poly[i].v1:=(u+bands+1+(slice)) mod maxvert;
  268. poly[i].v2:=(u+bands+(slice)) mod maxvert;
  269. poly[i].v3:=(u+(slice)) mod maxvert;
  270. poly[i+1].v1:=(u+(slice)) mod maxvert;
  271. poly[i+1].v2:=(u+1+(slice)) mod maxvert;
  272. poly[i+1].v3:=(u+bands+1+(slice)) mod maxvert;
  273. inc(i, 2);
  274. end;
  275. end;
  276. Tpi_d := TWOPI / bands;
  277. Ppi_d := PI / rings;
  278. phi := -PI / 2;
  279. k := 0;
  280. for ii := 0 to rings - 1 do
  281. begin
  282. a1 := power(abs(cos(m * phi / 4) / a), n2);
  283. a2 := power(abs(sin(m * phi / 4) / b), n3);
  284. r2 := power(a1 + a2, -1 / n1) ;
  285. r2 := r2 * radius;
  286. phi := phi + Ppi_d;
  287. theta := -PI;
  288. for jj := 0 to bands do
  289. begin
  290. a1 := power(abs(cos(m * theta / 4) / a), n2);
  291. a2 := power(abs(sin(m * theta / 4) / b), n3);
  292. r1 := power(a1 + a2, -1 / n1) ;
  293. r1 := r1 * radius;
  294. x := r1 * cos(theta) * r2 * cos(phi);
  295. y := r1 * sin(theta) * r2 * cos(phi);
  296. z := r2 * sin(phi);
  297. theta := theta + Tpi_d;
  298. ivertex[k].x := floattov16 (x);
  299. ivertex[k].y := floattov16 (y);
  300. ivertex[k].z := floattov16 (z);
  301. icolor[k].r := (1 - (ii * 4 div rings)) * 255;
  302. icolor[k].g := (1 - (ii * 4 div rings)) * 255;
  303. icolor[k].b := (1 - (ii * 4 div rings)) * 255;
  304. _u := (ii div rings ) * uscale;
  305. _v := (jj div bands ) * vscale;
  306. itexture[k].u := floattof32(_u);
  307. itexture[k].v := floattof32(_v);
  308. inc(k);
  309. end;
  310. end;
  311. result := vb;
  312. end;
  313. // initialize out tunnel and
  314. // store float values to f32 classes
  315. function init_ascaris(rings, bands: cint; radius, center_offset: cfloat; uscale, vscale: cint): PVertexBuffer;
  316. var
  317. vb: PVertexBuffer;
  318. max_point: cint;
  319. ivertex: array of TVector3f32;
  320. itexture: array of Ttexcoordf32;
  321. icolor: array of Trgbf32;
  322. poly: array of TPolygon;
  323. s, u, slice, maxvert: cint;
  324. i: cint;
  325. ii, jj: integer;
  326. half_width, half_height, a1, a2: cfloat;
  327. k: cint;
  328. x, y, z: cfloat;
  329. _u, _v: cfloat;
  330. xc, yc, zc: cfloat;
  331. begin
  332. new(vb);
  333. vb^ := TVertexBuffer.Create();
  334. max_point := (rings) * (bands + 1); //+1 for last band duplicate
  335. setlength(ivertex, max_point);
  336. setlength(itexture, max_point);
  337. setlength(icolor, max_point);
  338. setlength(poly, max_point * 2);
  339. vb^.ips_vertex := ivertex;
  340. vb^.ips_texture := itexture;
  341. vb^.ips_color := icolor;
  342. vb^.ps_poly := poly;
  343. vb^.i_max_vertex := max_point;
  344. vb^.i_max_poly := max_point * 2;
  345. vb^.i_primitive_type := GL_TRIANGLES;
  346. //lathing
  347. maxvert := max_point;
  348. i := 0;
  349. for s := 0 to (rings - 1) do
  350. begin
  351. slice := s * bands;
  352. for u := 0 to bands do //duplicate texture ( not bands - 1)
  353. begin
  354. poly[i].v1:=(u+bands+1+(slice)) mod maxvert;
  355. poly[i].v2:=(u+bands+(slice)) mod maxvert;
  356. poly[i].v3:=(u+(slice)) mod maxvert;
  357. poly[i+1].v1:=(u+(slice)) mod maxvert;
  358. poly[i+1].v2:=(u+1+(slice)) mod maxvert;
  359. poly[i+1].v3:=(u+bands+1+(slice)) mod maxvert;
  360. inc(i, 2);
  361. end;
  362. end;
  363. k := 0;
  364. for ii := 0 to rings - 1 do
  365. begin
  366. zc := ii - (ii/20);
  367. xc := cos(TWOPI * zc / rings)* center_offset;
  368. yc := sin(TWOPI * zc / rings)* center_offset;
  369. for jj := 0 to bands do
  370. begin
  371. x := xc + cos(jj * TWOPI / bands ) * radius;
  372. y := yc + sin(jj * TWOPI / bands ) * radius;
  373. z := 0-(ii*2);
  374. ivertex[k].x := floattov16 (x);
  375. ivertex[k].y := floattov16 (y);
  376. ivertex[k].z := floattov16 (z);
  377. icolor[k].r := (1 - (ii*4 div rings)) * 255;
  378. icolor[k].g := (1 - (ii*4 div rings)) * 255;
  379. icolor[k].b := (1 - (ii*4 div rings)) * 255;
  380. _u := (ii / rings ) * uscale;
  381. _v := (jj / bands ) * vscale;
  382. itexture[k].u := floattof32(_u);
  383. itexture[k].v := floattof32(_v);
  384. inc(k);
  385. end;
  386. end;
  387. result := vb;
  388. end;
  389. end.