lesson8.pp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. program lesson8;
  2. {$J+}
  3. {$macro on}
  4. {$mode objfpc}
  5. uses
  6. cmem, ctypes, gctypes, gccore, math;
  7. {$include inc/glass.tpl.inc}
  8. {$link build/glass.tpl.o}
  9. const glass = 0;
  10. const
  11. DEFAULT_FIFO_SIZE = (256 * 1024);
  12. type
  13. tagtexdef = record
  14. pal_data: pointer;
  15. tex_data: pointer;
  16. sz_x: cuint32;
  17. sz_y: cuint32;
  18. fmt: cuint32;
  19. min_lod: cuint32;
  20. max_lod: cuint32;
  21. min: cuint32;
  22. mag: cuint32;
  23. wrap_s: cuint32;
  24. wrap_t: cuint32;
  25. nextdef: pointer;
  26. end;
  27. texdef = tagtexdef;
  28. ptexdef = ^texdef;
  29. var
  30. litcolors: array [0..2] of GXColor = (
  31. (r:$D0; g:$D0; b:$D0; a:$FF;), // Light color 1
  32. (r:$40; g:$40; b:$40; a:$FF;), // Ambient 1
  33. (r:$80; g:$80; b:$80; a:$FF;)); // Material 1
  34. frameBuffer: array [0..1] of pcuint32 = (nil, nil);
  35. rmode: PGXRModeObj = nil;
  36. procedure setlight(view: Mtx; theta, phi: cuint32; litcol, ambcol, matcol: GXColor);
  37. var
  38. lpos: guVector;
  39. _theta, _phi: f32;
  40. lobj: GXLightObj;
  41. begin
  42. _theta := f32(theta * M_PI / 180.0);
  43. _phi := f32(phi * M_PI / 180.0);
  44. lpos.x := 1000.0 * cos(_phi) * sin(_theta);
  45. lpos.y := 1000.0 * sin(_phi);
  46. lpos.z := 1000.0 * cos(_phi) * cos(_theta);
  47. guVecMultiply(view,@lpos,@lpos);
  48. GX_InitLightPos(@lobj,lpos.x,lpos.y,lpos.z);
  49. GX_InitLightColor(@lobj,litcol);
  50. GX_LoadLightObj(@lobj,GX_LIGHT0);
  51. // set number of rasterized color channels
  52. GX_SetNumChans(1);
  53. GX_SetChanCtrl(GX_COLOR0A0,GX_ENABLE,GX_SRC_REG,GX_SRC_REG,GX_LIGHT0,GX_DF_CLAMP,GX_AF_NONE);
  54. GX_SetChanAmbColor(GX_COLOR0A0,ambcol);
  55. GX_SetChanMatColor(GX_COLOR0A0,matcol);
  56. end;
  57. var
  58. yscale: f32 = 0;
  59. zt: f32 = 0;
  60. xfbHeight: cuint32;
  61. fb: cuint32 = 0;
  62. rquad: f32 = 0.0;
  63. first_frame: cuint32 = 1;
  64. texture: GXTexObj;
  65. view, mv, mr, mvi: Mtx; // view and perspective matrices
  66. model, modelview: Mtx;
  67. perspective: Mtx44;
  68. gpfifo: pointer = nil;
  69. background: GXColor = (r:0; g:0; b:0; a:$ff;);
  70. cam: guVector = (x:0.0; y:0.0; z:0.0;);
  71. up: guVector = (x:0.0; y:1.0; z:0.0;);
  72. look: guVector = (x:0.0; y:0.0; z:-1.0;);
  73. cubeAxis: guVector = (x: 1.0; y: 1.0; z: 1.0;);
  74. glassTPL: TPLFile;
  75. w, h: f32;
  76. begin
  77. VIDEO_Init();
  78. WPAD_Init();
  79. rmode := VIDEO_GetPreferredMode(nil);
  80. // allocate 2 framebuffers for double buffering
  81. frameBuffer[0] := SYS_AllocateFramebuffer(rmode);
  82. frameBuffer[1] := SYS_AllocateFramebuffer(rmode);
  83. // configure video
  84. VIDEO_Configure(rmode);
  85. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  86. VIDEO_Flush();
  87. VIDEO_WaitVSync();
  88. if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then VIDEO_WaitVSync();
  89. // allocate the fifo buffer
  90. gpfifo := memalign(32,DEFAULT_FIFO_SIZE);
  91. memset(gpfifo,0,DEFAULT_FIFO_SIZE);
  92. fb := fb xor 1;
  93. // init the flipper
  94. GX_Init(gpfifo,DEFAULT_FIFO_SIZE);
  95. // clears the bg to color and clears the z buffer
  96. GX_SetCopyClear(background, $00ffffff);
  97. // other gx setup
  98. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  99. yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
  100. xfbHeight := GX_SetDispCopyYScale(yscale);
  101. GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
  102. GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
  103. GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
  104. GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
  105. if rmode^.viHeight = 2 * rmode^.xfbHeight then
  106. GX_SetFieldMode(rmode^.field_rendering, GX_ENABLE)
  107. else
  108. GX_SetFieldMode(rmode^.field_rendering, GX_DISABLE);
  109. if (rmode^.aa) <> 0 then
  110. GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR)
  111. else
  112. GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
  113. GX_SetCullMode(GX_CULL_NONE);
  114. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  115. GX_SetDispCopyGamma(GX_GM_1_0);
  116. // setup the vertex attribute table
  117. // describes the data
  118. // args: vat location 0-7, type of data, data format, size, scale
  119. // so for ex. in the first call we are sending position data with
  120. // 3 values X,Y,Z of size F32. scale sets the number of fractional
  121. // bits for non float data.
  122. GX_InvVtxCache();
  123. GX_ClearVtxDesc();
  124. GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
  125. GX_SetVtxDesc(GX_VA_NRM, GX_DIRECT);
  126. GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
  127. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
  128. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
  129. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
  130. // setup texture coordinate generation
  131. // args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use
  132. GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_TEX0, GX_TEXMTX0);
  133. w := rmode^.viWidth;
  134. h := rmode^.viHeight;
  135. guLightPerspective(mv,45, f32(w/h), 1.05, 1.0, 0.0, 0.0);
  136. guMtxTrans(mr, 0.0, 0.0, -1.0);
  137. guMtxConcat(mv, mr, mv);
  138. GX_LoadTexMtxImm(mv, GX_TEXMTX0, GX_MTX3x4);
  139. GX_InvalidateTexAll();
  140. TPL_OpenTPLFromMemory(@glassTPL, @glass_tpl[0], glass_tpl_size);
  141. TPL_GetTexture(@glassTPL,glass,@texture);
  142. // setup our camera at the origin
  143. // looking down the -z axis with y up
  144. guLookAt(view, @cam, @up, @look);
  145. // setup our projection matrix
  146. // this creates a perspective matrix with a view angle of 90,
  147. // and aspect ratio based on the display resolution
  148. guPerspective(perspective, 45, f32(w/h), 0.1, 300.0);
  149. GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
  150. while true do
  151. begin
  152. WPAD_ScanPads();
  153. if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then exit
  154. else
  155. if (WPAD_ButtonsHeld(0) and WPAD_BUTTON_UP) <> 0 then zt := zt - 0.25
  156. else
  157. if (WPAD_ButtonsHeld(0) and WPAD_BUTTON_DOWN) <> 0 then zt := zt + 0.25;
  158. // set number of rasterized color channels
  159. //GX_SetNumChans(1);
  160. setlight(view,8,20,litcolors[0],litcolors[1],litcolors[2]);
  161. //set number of textures to generate
  162. GX_SetNumTexGens(1);
  163. GX_SetTevOp(GX_TEVSTAGE0,GX_BLEND);
  164. GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
  165. GX_LoadTexObj(@texture, GX_TEXMAP0);
  166. guMtxIdentity(model);
  167. guMtxRotAxisDeg(model, @cubeAxis, rquad);
  168. guMtxTransApply(model, model, 0.0,0.0,zt-7.0);
  169. guMtxConcat(view,model,modelview);
  170. // load the modelview matrix into matrix memory
  171. GX_LoadPosMtxImm(modelview, GX_PNMTX0);
  172. guMtxInverse(modelview,mvi);
  173. guMtxTranspose(mvi,modelview);
  174. GX_LoadNrmMtxImm(modelview, GX_PNMTX0);
  175. GX_Begin(GX_QUADS, GX_VTXFMT0, 24); // Draw a Cube
  176. GX_Position3f32(-1.0,1.0,1.0); // Top Left of the quad (top)
  177. GX_Normal3f32(-1.0,1.0,1.0);
  178. GX_TexCoord2f32(1.0,0.0);
  179. GX_Position3f32(1.0,1.0,1.0); // Top Right of the quad (top)
  180. GX_Normal3f32(1.0,1.0,1.0); // Top Right of the quad (top)
  181. GX_TexCoord2f32(1.0,1.0);
  182. GX_Position3f32(1.0,1.0,-1.0); // Bottom Right of the quad (top)
  183. GX_Normal3f32(1.0,1.0,-1.0); // Bottom Right of the quad (top)
  184. GX_TexCoord2f32(0.0,1.0);
  185. GX_Position3f32(-1.0,1.0,-1.0); // Bottom Left of the quad (top)
  186. GX_Normal3f32(-1.0,1.0,-1.0); // Bottom Left of the quad (top)
  187. GX_TexCoord2f32(0.0,0.0);
  188. GX_Position3f32(-1.0,-1.0,1.0); // Top Left of the quad (bottom)
  189. GX_Normal3f32(-1.0,-1.0,1.0); // Top Left of the quad (bottom)
  190. GX_TexCoord2f32(1.0,0.0);
  191. GX_Position3f32(1.0,-1.0,1.0); // Top Right of the quad (bottom)
  192. GX_Normal3f32(1.0,-1.0,1.0); // Top Right of the quad (bottom)
  193. GX_TexCoord2f32(1.0,1.0);
  194. GX_Position3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (bottom)
  195. GX_Normal3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (bottom)
  196. GX_TexCoord2f32(0.0,1.0);
  197. GX_Position3f32(-1.0,-1.0,-1.0); // Bottom Left of the quad (bottom)
  198. GX_Normal3f32(-1.0,-1.0,-1.0); // Bottom Left of the quad (bottom)
  199. GX_TexCoord2f32(0.0,0.0);
  200. GX_Position3f32(-1.0,1.0,1.0); // Top Left of the quad (front)
  201. GX_Normal3f32(-1.0,1.0,1.0); // Top Left of the quad (front)
  202. GX_TexCoord2f32(1.0,0.0);
  203. GX_Position3f32(-1.0,-1.0,1.0); // Top Right of the quad (front)
  204. GX_Normal3f32(-1.0,-1.0,1.0); // Top Right of the quad (front)
  205. GX_TexCoord2f32(1.0,1.0);
  206. GX_Position3f32(1.0,-1.0,1.0); // Bottom Right of the quad (front)
  207. GX_Normal3f32(1.0,-1.0,1.0); // Bottom Right of the quad (front)
  208. GX_TexCoord2f32(0.0,1.0);
  209. GX_Position3f32(1.0,1.0,1.0); // Bottom Left of the quad (front)
  210. GX_Normal3f32(1.0,1.0,1.0); // Bottom Left of the quad (front)
  211. GX_TexCoord2f32(0.0,0.0);
  212. GX_Position3f32(-1.0,1.0,-1.0); // Top Left of the quad (back)
  213. GX_Normal3f32(-1.0,1.0,-1.0); // Top Left of the quad (back)
  214. GX_TexCoord2f32(1.0,0.0);
  215. GX_Position3f32(-1.0,-1.0,-1.0); // Top Right of the quad (back)
  216. GX_Normal3f32(-1.0,-1.0,-1.0); // Top Right of the quad (back)
  217. GX_TexCoord2f32(1.0,1.0);
  218. GX_Position3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (back)
  219. GX_Normal3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (back)
  220. GX_TexCoord2f32(0.0,1.0);
  221. GX_Position3f32(1.0,1.0,-1.0); // Bottom Left of the quad (back)
  222. GX_Normal3f32(1.0,1.0,-1.0); // Bottom Left of the quad (back)
  223. GX_TexCoord2f32(0.0,0.0);
  224. GX_Position3f32(-1.0,1.0,1.0); // Top Left of the quad (left)
  225. GX_Normal3f32(-1.0,1.0,1.0); // Top Left of the quad (left)
  226. GX_TexCoord2f32(1.0,0.0);
  227. GX_Position3f32(-1.0,1.0,-1.0); // Top Right of the quad (back)
  228. GX_Normal3f32(-1.0,1.0,-1.0); // Top Right of the quad (back)
  229. GX_TexCoord2f32(1.0,1.0);
  230. GX_Position3f32(-1.0,-1.0,-1.0); // Bottom Right of the quad (back)
  231. GX_Normal3f32(-1.0,-1.0,-1.0); // Bottom Right of the quad (back)
  232. GX_TexCoord2f32(0.0,1.0);
  233. GX_Position3f32(-1.0,-1.0,1.0); // Bottom Left of the quad (back)
  234. GX_Normal3f32(-1.0,-1.0,1.0); // Bottom Left of the quad (back)
  235. GX_TexCoord2f32(0.0,0.0);
  236. GX_Position3f32(1.0,1.0,1.0); // Top Left of the quad (right)
  237. GX_Normal3f32(1.0,1.0,1.0); // Top Left of the quad (right)
  238. GX_TexCoord2f32(1.0,0.0);
  239. GX_Position3f32(1.0,1.0,-1.0); // Top Right of the quad (right)
  240. GX_Normal3f32(1.0,1.0,-1.0); // Top Right of the quad (right)
  241. GX_TexCoord2f32(1.0,1.0);
  242. GX_Position3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (right)
  243. GX_Normal3f32(1.0,-1.0,-1.0); // Bottom Right of the quad (right)
  244. GX_TexCoord2f32(0.0,1.0);
  245. GX_Position3f32(1.0,-1.0,1.0); // Bottom Left of the quad (right)
  246. GX_Normal3f32(1.0,-1.0,1.0); // Bottom Left of the quad (right)
  247. GX_TexCoord2f32(0.0,0.0);
  248. GX_End(); // Done Drawing The Quad
  249. GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
  250. GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_SET);
  251. GX_SetColorUpdate(GX_TRUE);
  252. GX_SetAlphaUpdate(GX_TRUE);
  253. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  254. GX_DrawDone();
  255. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  256. if (first_frame) <> 0 then
  257. begin
  258. first_frame := 0;
  259. VIDEO_SetBlack(FALSE);
  260. end;
  261. VIDEO_Flush();
  262. VIDEO_WaitVSync();
  263. fb := fb xor 1;
  264. rquad := rquad - 0.15; // Decrease The Rotation Variable For The Quad ( NEW )
  265. end;
  266. end.