modelViewer.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. Pokitto example demo for small3dlib -- model viewer.
  3. author: Miloslav Ciz
  4. license: CC0 1.0
  5. */
  6. #include "Pokitto.h"
  7. /* Before including small3dli, we need to define some values for it, such as
  8. the resolution, the name of the pixel drawing function etc.: */
  9. #define S3L_PIXEL_FUNCTION pixelFunc
  10. #define S3L_RESOLUTION_X 110
  11. #define S3L_RESOLUTION_Y 88
  12. #define S3L_Z_BUFFER 2 // this sets up a reduced precision z-buffer
  13. #define S3L_SORT 0 // no sorting of triangles
  14. #define S3L_STENCIL_BUFFER 0 // no stencil buffer
  15. #define S3L_PERSPECTIVE_CORRECTION 0 /* perspective correction expensive and
  16. dosn't improve quality significantly
  17. with far away models, so turn it off,
  18. but you can try setting it it 2
  19. (approximation) */
  20. #include "small3dlib.h" // now we can include the library
  21. // include the resources (converted using provided Python scripts):
  22. #include "palette.h"
  23. #include "houseModel.h"
  24. #include "houseTexture.h"
  25. #include "chestModel.h"
  26. #include "chestTexture.h"
  27. #include "earthModel.h"
  28. #include "earthTexture.h"
  29. #include "pokittoModel.h"
  30. #include "pokittoTexture.h"
  31. Pokitto::Core pokitto;
  32. #define MIN_ZOOM (-6 * S3L_FRACTIONS_PER_UNIT)
  33. #define MAX_ZOOM (-16 * S3L_FRACTIONS_PER_UNIT)
  34. #define TEXTURE_W 64
  35. #define TEXTURE_H 64
  36. // helper global variabls and pointers:
  37. int16_t previousTriangle = -1;
  38. S3L_Vec4 uv0, uv1, uv2;
  39. const uint8_t *texture = houseTexture;
  40. const S3L_Index *uvIndices = houseUVIndices;
  41. const S3L_Unit *uvs = houseUVs;
  42. static inline unsigned short sampleTexure(int32_t u, int32_t v)
  43. {
  44. int index = v * TEXTURE_W + u;
  45. return texture[index];
  46. }
  47. /* This function will be called by the library to render individual pixels --
  48. remember, this is the bottleneck, it should be as fast as possible! */
  49. void pixelFunc(S3L_PixelInfo *p)
  50. {
  51. S3L_Unit u, v; // texturing coordinates
  52. if (p->triangleIndex != previousTriangle)
  53. {
  54. /* This is a per-triangle cache, it prevents computing per-triangle values
  55. for each pixel. We only recompute these when the triangleID changes. */
  56. S3L_getIndexedTriangleValues(p->triangleIndex,uvIndices,uvs,2,&uv0,&uv1,&uv2);
  57. /* ^ This is a helper funtion that retrieves the 3 UV coordinates of the
  58. triangle (one for each triangle vertex). */
  59. previousTriangle = p->triangleIndex;
  60. }
  61. u = S3L_interpolateBarycentric(uv0.x,uv1.x,uv2.x,p->barycentric);
  62. v = S3L_interpolateBarycentric(uv0.y,uv1.y,uv2.y,p->barycentric);
  63. uint8_t c = sampleTexure(u >> 3,v >> 3);
  64. /* ^ Shifting by 3 gets the value from 0 to 512
  65. (S3L_FRACTIONS_PER_UNIT) to 0 to 32 (texture resoltion). */
  66. // now write the pixel:
  67. uint8_t *buf = pokitto.display.screenbuffer;
  68. buf += p->y * S3L_RESOLUTION_X;
  69. buf += p->x;
  70. *buf = c;
  71. }
  72. S3L_Scene scene; // our 3D scene, it will only hold one model at a time
  73. void draw()
  74. {
  75. S3L_newFrame(); // needs to be done before rendering a new frame
  76. S3L_drawScene(scene); // renders the 3D scene
  77. }
  78. void setModel(uint8_t index)
  79. {
  80. #define modelCase(n)\
  81. scene.models = &(n##Model);\
  82. texture = n##Texture;\
  83. uvIndices = n##UVIndices;\
  84. uvs = n##UVs;
  85. switch (index)
  86. {
  87. case 1:
  88. modelCase(chest)
  89. break;
  90. case 2:
  91. modelCase(earth)
  92. break;
  93. case 3:
  94. modelCase(pokitto)
  95. break;
  96. default:
  97. modelCase(house)
  98. break;
  99. }
  100. #undef modelCase
  101. }
  102. uint8_t modelIndex = 0;
  103. int main()
  104. {
  105. pokitto.begin();
  106. pokitto.setFrameRate(60);
  107. pokitto.display.load565Palette(palette);
  108. houseModelInit();
  109. chestModelInit();
  110. earthModelInit();
  111. pokittoModelInit();
  112. S3L_initScene(&houseModel,1,&scene);
  113. setModel(0);
  114. scene.camera.transform.translation.z = -8 * S3L_FRACTIONS_PER_UNIT;
  115. // ^ place the camera a little bit to the front so that the model is seen
  116. while (pokitto.isRunning())
  117. {
  118. if (pokitto.update())
  119. {
  120. S3L_Unit rotationStep = 8;
  121. S3L_Unit zoomStep = 128;
  122. if (pokitto.aBtn())
  123. {
  124. if (pokitto.downBtn())
  125. scene.camera.transform.translation.z =
  126. S3L_max(MAX_ZOOM,scene.camera.transform.translation.z - zoomStep);
  127. else if (pokitto.upBtn())
  128. scene.camera.transform.translation.z =
  129. S3L_min(MIN_ZOOM,scene.camera.transform.translation.z + zoomStep);
  130. }
  131. else
  132. {
  133. if (pokitto.upBtn())
  134. scene.models[0].transform.rotation.x += rotationStep;
  135. else if (pokitto.downBtn())
  136. scene.models[0].transform.rotation.x -= rotationStep;
  137. if (pokitto.rightBtn())
  138. scene.models[0].transform.rotation.y += rotationStep;
  139. else if (pokitto.leftBtn())
  140. scene.models[0].transform.rotation.y -= rotationStep;
  141. }
  142. if (pokitto.buttons.timeHeld(BTN_B) == 1)
  143. {
  144. modelIndex = (modelIndex + 1) % 4;
  145. setModel(modelIndex);
  146. }
  147. draw();
  148. }
  149. }
  150. }