ToonShading.pp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. program ToonShading;
  2. //NB: This would look better if the object had a bit of texturing too (eyes, nose etc)
  3. {$L build/statue.bin.o}
  4. {$mode objfpc}
  5. uses
  6. ctypes, nds9;
  7. {$include inc/statue.bin.inc}
  8. var
  9. prev_pen: array [0..1] of cint = ( $7FFFFFFF, $7FFFFFFF );
  10. procedure get_pen_delta(var dx, dy: cint);
  11. var
  12. keys: cuint32;
  13. touchXY: touchPosition;
  14. begin
  15. keys := keysHeld();
  16. if( keys and KEY_TOUCH ) <> 0 then
  17. begin
  18. touchXY := touchReadXY();
  19. if ( prev_pen[0] <> $7FFFFFFF ) then
  20. begin
  21. dx := (prev_pen[0] - touchXY.rawx);
  22. dy := (prev_pen[1] - touchXY.rawy);
  23. end;
  24. prev_pen[0] := touchXY.rawx;
  25. prev_pen[1] := touchXY.rawy;
  26. end else
  27. begin
  28. prev_pen[0] := $7FFFFFFF;
  29. prev_pen[1] := $7FFFFFFF;
  30. dx := 0;
  31. dy := 0;
  32. end;
  33. end;
  34. var
  35. rotateX: integer = 0;
  36. rotateY: integer = 0;
  37. keys: cuint32;
  38. pen_delta: array [0..1] of cint;
  39. begin
  40. //set mode 0, enable BG0 and set it to 3D
  41. videoSetMode(MODE_0_3D);
  42. // initialize gl
  43. glInit();
  44. // enable antialiasing
  45. glEnable(GL_ANTIALIAS);
  46. // setup the rear plane
  47. glClearColor(0,0,0,31); // BG must be opaque for AA to work
  48. glClearPolyID(63); // BG must have a unique polygon ID for AA to work
  49. glClearDepth($7FFF);
  50. //this should work the same as the normal gl call
  51. glViewport(0,0,255,191);
  52. //toon-table entry 0 is for completely unlit pixels, going up to entry 31 for completely lit
  53. //We block-fill it in two halves, we get cartoony 2-tone lighting
  54. glSetToonTableRange( 0, 15, RGB15(8,8,8) );
  55. glSetToonTableRange( 16, 31, RGB15(24,24,24) );
  56. //any floating point gl call is being converted to fixed prior to being implemented
  57. glMatrixMode(GL_PROJECTION);
  58. glLoadIdentity();
  59. gluPerspective(70, 256.0 / 192.0, 0.1, 40);
  60. //NB: When toon-shading, the hw ignores lights 2 and 3
  61. //Also note that the hw uses the RED component of the lit vertex to index the toon-table
  62. glLight(0, RGB15(16,16,16) , 0, floattov10(-1.0), 0);
  63. glLight(1, RGB15(16,16,16), floattov10(-1.0), 0, 0);
  64. gluLookAt( 0.0, 0.0, -3.0, //camera possition
  65. 0.0, 0.0, 0.0, //look at
  66. 0.0, 1.0, 0.0); //up
  67. while true do
  68. begin
  69. glMatrixMode(GL_MODELVIEW);
  70. glPushMatrix();
  71. glRotateXi(rotateX);
  72. glRotateYi(rotateY);
  73. glMaterialf(GL_AMBIENT, RGB15(8,8,8));
  74. glMaterialf(GL_DIFFUSE, RGB15(24,24,24));
  75. glMaterialf(GL_SPECULAR, RGB15(0,0,0));
  76. glMaterialf(GL_EMISSION, RGB15(0,0,0));
  77. glPolyFmt(POLY_ALPHA(31) or POLY_CULL_BACK or POLY_FORMAT_LIGHT0 or POLY_FORMAT_LIGHT1 or POLY_TOON_HIGHLIGHT);
  78. scanKeys();
  79. keys := keysHeld();
  80. if( keys and KEY_UP ) <> 0 then rotateX := rotateX +1;
  81. if( keys and KEY_DOWN ) <> 0 then rotateX := rotateX -1;
  82. if( keys and KEY_LEFT ) <> 0 then rotateY := rotateY +1;
  83. if( keys and KEY_RIGHT ) <> 0 then rotateY := rotateY -1;
  84. get_pen_delta( pen_delta[0], pen_delta[1] );
  85. rotateY := rotateY - pen_delta[0];
  86. rotateX := rotateY - pen_delta[1];
  87. glCallList(@statue_bin);
  88. glPopMatrix(1);
  89. glFlush(0);
  90. swiWaitForVBlank();
  91. end;
  92. end.