lesson9.pp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. program lesson9;
  2. {$J+}
  3. {$macro on}
  4. {$mode objfpc}
  5. uses
  6. cmem, ctypes, gctypes, gccore;
  7. {$include inc/startex.tpl.inc}
  8. {$link build/startex.tpl.o}
  9. const startex = 0;
  10. const
  11. DEFAULT_FIFO_SIZE = (256 * 1024);
  12. NUM_STARS = 50;
  13. type
  14. tagtexdef = record
  15. pal_data: pointer;
  16. tex_data: pointer;
  17. sz_x: cuint32;
  18. sz_y: cuint32;
  19. fmt: cuint32;
  20. min_lod: cuint32;
  21. max_lod: cuint32;
  22. min: cuint32;
  23. mag: cuint32;
  24. wrap_s: cuint32;
  25. wrap_t: cuint32;
  26. nextdef: pointer;
  27. end;
  28. texdef = tagtexdef;
  29. ptexdef = ^texdef;
  30. TStar = record
  31. r,g,b: cuint8;
  32. dist: f32;
  33. ang: f32;
  34. end;
  35. var
  36. stars: array [0..NUM_STARS-1] of TStar;
  37. frameBuffer: array [0..1] of pcuint32 = (nil, nil);
  38. rmode: PGXRModeObj = nil;
  39. yscale: f32 = 0.0;
  40. spin: f32 = 0.0;
  41. xfbHeight, i: cuint32;
  42. fb: cuint32 = 0;
  43. first_frame: cuint32 = 1;
  44. zoom: f32 = -15.0;
  45. texture: GXTexObj;
  46. view: Mtx; // view and perspective matrices
  47. model, modelview: Mtx;
  48. perspective: Mtx44;
  49. gpfifo: pointer = nil;
  50. background: GXColor = (r:0; g:0; b:0; a:$ff;);
  51. cam: guVector = (x:0.0; y:0.0; z:0.0;);
  52. up: guVector = (x:0.0; y:1.0; z:0.0;);
  53. look: guVector = (x:0.0; y:0.0; z:-1.0;);
  54. starAxis1: guVector = (x:0; y:1; z:0;);
  55. starAxis2: guVector = (x:0; y:0; z:1;);
  56. starTPL: TPLFile;
  57. w, h: f32;
  58. mry, mrz: Mtx;
  59. begin
  60. VIDEO_Init();
  61. WPAD_Init();
  62. rmode := VIDEO_GetPreferredMode(nil);
  63. // allocate 2 framebuffers for double buffering
  64. frameBuffer[0] := SYS_AllocateFramebuffer(rmode);
  65. frameBuffer[1] := SYS_AllocateFramebuffer(rmode);
  66. // configure video
  67. VIDEO_Configure(rmode);
  68. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  69. VIDEO_Flush();
  70. VIDEO_WaitVSync();
  71. if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then VIDEO_WaitVSync();
  72. // allocate the fifo buffer
  73. gpfifo := memalign(32,DEFAULT_FIFO_SIZE);
  74. memset(gpfifo,0,DEFAULT_FIFO_SIZE);
  75. fb := fb xor 1;
  76. // init the flipper
  77. GX_Init(gpfifo,DEFAULT_FIFO_SIZE);
  78. // clears the bg to color and clears the z buffer
  79. GX_SetCopyClear(background, $00ffffff);
  80. // other gx setup
  81. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  82. yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
  83. xfbHeight := GX_SetDispCopyYScale(yscale);
  84. GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
  85. GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
  86. GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
  87. GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
  88. if rmode^.viHeight = 2 * rmode^.xfbHeight then
  89. GX_SetFieldMode(rmode^.field_rendering, GX_ENABLE)
  90. else
  91. GX_SetFieldMode(rmode^.field_rendering, GX_DISABLE);
  92. if (rmode^.aa) <> 0 then
  93. GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR)
  94. else
  95. GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
  96. GX_SetCullMode(GX_CULL_NONE);
  97. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  98. GX_SetDispCopyGamma(GX_GM_1_0);
  99. // setup the vertex attribute table
  100. // describes the data
  101. // args: vat location 0-7, type of data, data format, size, scale
  102. // so for ex. in the first call we are sending position data with
  103. // 3 values X,Y,Z of size F32. scale sets the number of fractional
  104. // bits for non float data.
  105. GX_ClearVtxDesc();
  106. GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
  107. GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
  108. GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
  109. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
  110. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
  111. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0);
  112. // set number of rasterized color channels
  113. GX_SetNumChans(1);
  114. //set number of textures to generate
  115. GX_SetNumTexGens(1);
  116. // setup texture coordinate generation
  117. // args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use
  118. GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
  119. GX_InvVtxCache();
  120. GX_InvalidateTexAll();
  121. TPL_OpenTPLFromMemory(@starTPL, @startex_tpl[0],startex_tpl_size);
  122. TPL_GetTexture(@starTPL,startex,@texture);
  123. // setup our camera at the origin
  124. // looking down the -z axis with y up
  125. guLookAt(view, @cam, @up, @look);
  126. // setup our projection matrix
  127. // this creates a perspective matrix with a view angle of 90,
  128. // and aspect ratio based on the display resolution
  129. w := rmode^.viWidth;
  130. h := rmode^.viHeight;
  131. guPerspective(perspective, 45, f32(w/h), 0.1, 300.0);
  132. GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
  133. randomize();
  134. for i:=0 to NUM_STARS - 1 do
  135. begin
  136. stars[i].ang := 0.0;
  137. stars[i].dist := f32(i)/f32(NUM_STARS);
  138. stars[i].r := random(256); // Give star[loop] A Random Red Intensity
  139. stars[i].g := random(256); // Give star[loop] A Random Green Intensity
  140. stars[i].b := random(256); // Give star[loop] A Random Blue Intensity
  141. end;
  142. while true do
  143. begin
  144. WPAD_ScanPads();
  145. if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then exit;
  146. GX_SetTevOp(GX_TEVSTAGE0,GX_MODULATE);
  147. GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
  148. GX_LoadTexObj(@texture, GX_TEXMAP0);
  149. for i:=0 to NUM_STARS - 1 do
  150. begin
  151. guMtxIdentity(model);
  152. guMtxRotAxisDeg(mry, @starAxis1, stars[i].ang);
  153. guMtxRotAxisDeg(mrz, @starAxis2, spin);
  154. guMtxConcat(mry,mrz,model);
  155. guMtxTransApply(model, model, stars[i].dist,0.0,zoom);
  156. guMtxConcat(view,model,modelview);
  157. GX_LoadPosMtxImm(modelview, GX_PNMTX0);
  158. GX_Begin(GX_QUADS, GX_VTXFMT0, 4); // Draw a quad
  159. GX_Position3f32(-1.0, -1.0, 0.0); // Top Left of the quad (top)
  160. GX_Color3u8(stars[i].r,stars[i].g,stars[i].b); // Set The Color To Green
  161. GX_TexCoord2f32(0.0,0.0);
  162. GX_Position3f32(1.0, -1.0, 0.0); // Top Right of the quad (top)
  163. GX_Color3u8(stars[i].r,stars[i].g,stars[i].b); // Set The Color To Green
  164. GX_TexCoord2f32(1.0,0.0);
  165. GX_Position3f32(1.0, 1.0, 0.0); // Bottom Right of the quad (top)
  166. GX_Color3u8(stars[i].r,stars[i].g,stars[i].b); // Set The Color To Green
  167. GX_TexCoord2f32(1.0,1.0);
  168. GX_Position3f32(-1.0, 1.0, 0.0); // Bottom Left of the quad (top)
  169. GX_Color3u8(stars[i].r,stars[i].g,stars[i].b); // Set The Color To Green
  170. GX_TexCoord2f32(0.0,1.0);
  171. GX_End(); // Done Drawing The Quad
  172. spin := spin + 0.01;
  173. stars[i].ang := stars[i].ang + f32(i)/f32(NUM_STARS);
  174. stars[i].dist := stars[i].dist - 0.01;
  175. if (stars[i].dist < 0.0) then // Is The Star In The Middle Yet
  176. begin
  177. stars[i].dist := stars[i].dist + 5.0; // Move The Star 5 Units From The Center
  178. stars[i].r := random(256); // Give It A New Red Value
  179. stars[i].g := random(256); // Give It A New Green Value
  180. stars[i].b := random(256); // Give It A New Blue Value
  181. end;
  182. end;
  183. GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
  184. GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_SET);
  185. GX_SetColorUpdate(GX_TRUE);
  186. GX_SetAlphaUpdate(GX_TRUE);
  187. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  188. GX_DrawDone();
  189. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  190. if (first_frame) <> 0 then
  191. begin
  192. first_frame := 0;
  193. VIDEO_SetBlack(FALSE);
  194. end;
  195. VIDEO_Flush();
  196. VIDEO_WaitVSync();
  197. fb := fb xor 1;
  198. end;
  199. end.