lesson1.pp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. program lesson1;
  2. {$J+}
  3. {$macro on}
  4. {$mode objfpc}
  5. uses
  6. cmem, ctypes, 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. fb: cuint32 = 0;
  17. background: GXColor = (r:0; g:0; b:0; a:$ff;);
  18. gp_fifo: pointer = nil;
  19. cam: guVector = (x:0.0; y:0.0; z:0.0;);
  20. up: guVector = (x:0.0; y:1.0; z:0.0;);
  21. look: guVector = (x:0.0; y:0.0; z:-1.0;);
  22. w,h: f32;
  23. begin
  24. VIDEO_Init();
  25. WPAD_Init();
  26. rmode := VIDEO_GetPreferredMode(nil);
  27. // allocate 2 framebuffers for double buffering
  28. frameBuffer[0] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
  29. frameBuffer[1] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
  30. VIDEO_Configure(rmode);
  31. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  32. VIDEO_SetBlack(false);
  33. VIDEO_Flush();
  34. VIDEO_WaitVSync();
  35. if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then
  36. VIDEO_WaitVSync();
  37. // setup the fifo and then init the flipper
  38. gp_fifo := memalign(32, DEFAULT_FIFO_SIZE);
  39. memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
  40. GX_Init(gp_fifo, DEFAULT_FIFO_SIZE);
  41. // clears the bg to color and clears the z buffer
  42. GX_SetCopyClear(background, $00ffffff);
  43. // other gx setup
  44. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  45. yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
  46. xfbHeight := GX_SetDispCopyYScale(yscale);
  47. GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
  48. GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
  49. GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
  50. GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
  51. if rmode^.viHeight = 2*rmode^.xfbHeight then
  52. GX_SetFieldMode(rmode^.field_rendering,GX_ENABLE)
  53. else
  54. GX_SetFieldMode(rmode^.field_rendering,GX_DISABLE);
  55. GX_SetCullMode(GX_CULL_NONE);
  56. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  57. GX_SetDispCopyGamma(GX_GM_1_0);
  58. // setup our camera at the origin
  59. // looking down the -z axis with y up
  60. guLookAt(view, @cam, @up, @look);
  61. // setup our projection matrix
  62. // this creates a perspective matrix with a view angle of 90,
  63. // and aspect ratio based on the display resolution
  64. w := rmode^.viWidth;
  65. h := rmode^.viHeight;
  66. guPerspective(perspective, 45, f32(w / h), 0.1, 300.0);
  67. GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
  68. while true do
  69. begin
  70. WPAD_ScanPads();
  71. if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then
  72. exit;
  73. // do this before drawing
  74. GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
  75. // do this stuff after drawing
  76. GX_DrawDone();
  77. fb := fb xor 1; // flip framebuffer
  78. GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
  79. GX_SetColorUpdate(GX_TRUE);
  80. GX_CopyDisp(frameBuffer[fb],GX_TRUE);
  81. VIDEO_SetNextFramebuffer(frameBuffer[fb]);
  82. VIDEO_Flush();
  83. VIDEO_WaitVSync();
  84. end;
  85. end.