lesson2.pp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. program lesson2;
  2. {$J+}
  3. {$macro on}
  4. {$mode objfpc}
  5. uses
  6. cmem, ctypes, gctypes, gccore;
  7. const
  8. DEFAULT_FIFO_SIZE = (256*1024);
  9. var
  10. frameBuffer: array [0..1] of pcuint32 = (nil, nil);
  11. rmode: PGXRModeObj = nil;
  12. yscale: f32;
  13. xfbHeight: cuint32;
  14. view: Mtx;
  15. perspective: Mtx44;
  16. model, modelview: Mtx;
  17. fb: cuint32 = 0;
  18. background: GXColor = (r:0; g:0; b:0; a:$ff;);
  19. gp_fifo: pointer = nil;
  20. cam: guVector = (x:0.0; y:0.0; z:0.0;);
  21. up: guVector = (x:0.0; y:1.0; z:0.0;);
  22. look: guVector = (x:0.0; y:0.0; z:-1.0;);
  23. w,h: f32;
  24. begin
  25. // init the vi.
  26. VIDEO_Init();
  27. WPAD_Init();
  28. rmode := VIDEO_GetPreferredMode(nil);
  29. // allocate 2 framebuffers for double buffering
  30. frameBuffer[0] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
  31. frameBuffer[1] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
  32. VIDEO_Configure(rmode);
  33. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  34. VIDEO_SetBlack(FALSE);
  35. VIDEO_Flush();
  36. VIDEO_WaitVSync();
  37. if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then
  38. VIDEO_WaitVSync();
  39. // setup the fifo and then init the flipper
  40. gp_fifo := memalign(32, DEFAULT_FIFO_SIZE);
  41. memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
  42. GX_Init(gp_fifo, DEFAULT_FIFO_SIZE);
  43. // clears the bg to color and clears the z buffer
  44. GX_SetCopyClear(background, $00ffffff);
  45. // other gx setup
  46. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  47. yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
  48. xfbHeight := GX_SetDispCopyYScale(yscale);
  49. GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
  50. GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
  51. GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
  52. GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
  53. if rmode^.viHeight = 2*rmode^.xfbHeight then
  54. GX_SetFieldMode(rmode^.field_rendering,GX_ENABLE)
  55. else
  56. GX_SetFieldMode(rmode^.field_rendering,GX_DISABLE);
  57. GX_SetCullMode(GX_CULL_NONE);
  58. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  59. GX_SetDispCopyGamma(GX_GM_1_0);
  60. // setup the vertex descriptor
  61. // tells the flipper to expect direct data
  62. GX_ClearVtxDesc();
  63. GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
  64. // setup the vertex attribute table
  65. // describes the data
  66. // args: vat location 0-7, type of data, data format, size, scale
  67. // so for ex. in the first call we are sending position data with
  68. // 3 values X,Y,Z of size F32. scale sets the number of fractional
  69. // bits for non float data.
  70. GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
  71. GX_SetNumChans(1);
  72. GX_SetNumTexGens(0);
  73. GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
  74. GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
  75. guLookAt(view, @cam, @up, @look);
  76. // setup our projection matrix
  77. // this creates a perspective matrix with a view angle of 90,
  78. // and aspect ratio based on the display resolution
  79. w := rmode^.viWidth;
  80. h := rmode^.viHeight;
  81. guPerspective(perspective, 45, f32(w / h), 0.1, 300.0);
  82. GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
  83. while true do
  84. begin
  85. WPAD_ScanPads();
  86. if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then
  87. exit;
  88. // do this before drawing
  89. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  90. guMtxIdentity(model);
  91. guMtxTransApply(model, model, -1.5,0.0,-6.0);
  92. guMtxConcat(view,model,modelview);
  93. // load the modelview matrix into matrix memory
  94. GX_LoadPosMtxImm(modelview, GX_PNMTX0);
  95. GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 3);
  96. GX_Position3f32( 0.0, 1.0, 0.0); // Top
  97. GX_Position3f32(-1.0,-1.0, 0.0); // Bottom Left
  98. GX_Position3f32( 1.0,-1.0, 0.0); // Bottom Right
  99. GX_End();
  100. guMtxTransApply(model, model, 3.0,0.0,0.0);
  101. guMtxConcat(view,model,modelview);
  102. // load the modelview matrix into matrix memory
  103. GX_LoadPosMtxImm(modelview, GX_PNMTX0);
  104. GX_Begin(GX_QUADS, GX_VTXFMT0, 4); // Draw A Quad
  105. GX_Position3f32(-1.0, 1.0, 0.0); // Top Left
  106. GX_Position3f32( 1.0, 1.0, 0.0); // Top Right
  107. GX_Position3f32( 1.0,-1.0, 0.0); // Bottom Right
  108. GX_Position3f32(-1.0,-1.0, 0.0); // Bottom Left
  109. GX_End(); // Done Drawing The Quad
  110. // do this stuff after drawing
  111. GX_DrawDone();
  112. fb := fb xor 1; // flip framebuffer
  113. GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
  114. GX_SetColorUpdate(GX_TRUE);
  115. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  116. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  117. VIDEO_Flush();
  118. VIDEO_WaitVSync();
  119. end;
  120. end.