level.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. Example program for small3dlib, showing a Quake-like level.
  3. author: Miloslav Ciz
  4. license: CC0 1.0
  5. */
  6. #define TEXTURES 1 // whether to use textures for the level
  7. #define FOG 1
  8. #include <stdio.h>
  9. #include <time.h>
  10. #define S3L_RESOLUTION_X 640
  11. #define S3L_RESOLUTION_Y 480
  12. #define S3L_NEAR_CROSS_STRATEGY 3
  13. #if TEXTURES
  14. #define S3L_PERSPECTIVE_CORRECTION 2
  15. #else
  16. #define S3L_PERSPECTIVE_CORRECTION 0
  17. #endif
  18. #define S3L_NEAR (S3L_F / 5)
  19. #define S3L_USE_WIDER_TYPES 0
  20. #define S3L_FLAT 0
  21. #define S3L_SORT 0
  22. #define S3L_Z_BUFFER 1
  23. #define S3L_MAX_TRIANGES_DRAWN 512
  24. #define S3L_PIXEL_FUNCTION drawPixel
  25. #include "../small3dlib.h"
  26. #define TEXTURE_W 64
  27. #define TEXTURE_H 64
  28. #include "sdl_helper.h"
  29. #include "levelModel.h"
  30. #include "levelTextures.h"
  31. S3L_Scene scene;
  32. S3L_Vec4 teleportPoint;
  33. uint32_t frame = 0;
  34. const uint8_t *texture = 0;
  35. uint32_t previousTriangle = 1000;
  36. S3L_Vec4 uv0, uv1, uv2;
  37. void drawTeleport(int16_t x, int16_t y, S3L_ScreenCoord size)
  38. {
  39. int16_t halfSize = size / 2;
  40. S3L_ScreenCoord x0 = S3L_max(0,x - halfSize);
  41. S3L_ScreenCoord x1 = S3L_min(S3L_RESOLUTION_X,x + halfSize);
  42. S3L_ScreenCoord y0 = S3L_max(0,y - halfSize);
  43. S3L_ScreenCoord y1 = S3L_min(S3L_RESOLUTION_Y,y + halfSize);
  44. S3L_ScreenCoord row = y0 - (y - halfSize);
  45. for (S3L_ScreenCoord j = y0; j < y1; ++j)
  46. {
  47. S3L_ScreenCoord i0, i1;
  48. if (row <= halfSize)
  49. {
  50. i0 = S3L_max(x0,x - row);
  51. i1 = S3L_min(x1,x + row);
  52. }
  53. else
  54. {
  55. i0 = S3L_max(x0,x - size + row);
  56. i1 = S3L_min(x1,x + size - row);
  57. }
  58. for (S3L_ScreenCoord i = i0; i < i1; ++i)
  59. if (rand() % 8 == 0)
  60. setPixel(i,j,255,0,0);
  61. row++;
  62. }
  63. }
  64. void drawPixel(S3L_PixelInfo *p)
  65. {
  66. uint8_t r, g, b;
  67. #if TEXTURES
  68. if (p->triangleID != previousTriangle)
  69. {
  70. uint8_t material = levelMaterials[p->triangleIndex];
  71. switch (material)
  72. {
  73. case 0:
  74. texture = level1Texture;
  75. break;
  76. case 1:
  77. texture = level2Texture;
  78. break;
  79. case 2:
  80. default:
  81. texture = level3Texture;
  82. break;
  83. }
  84. S3L_getIndexedTriangleValues(p->triangleIndex,levelUVIndices,levelUVs,2,&uv0,&uv1,&uv2);
  85. previousTriangle = p->triangleID;
  86. }
  87. S3L_Unit uv[2];
  88. uv[0] = S3L_interpolateBarycentric(uv0.x,uv1.x,uv2.x,p->barycentric) / 16;
  89. uv[1] = S3L_interpolateBarycentric(uv0.y,uv1.y,uv2.y,p->barycentric) / 16;
  90. sampleTexture(texture,uv[0],uv[1],&r,&g,&b);
  91. #else
  92. switch (p->modelIndex)
  93. {
  94. case 0: r = 255; g = 0; b = 0; break;
  95. case 1: r = 0; g = 255; b = 0; break;
  96. case 2:
  97. default: r = 0; g = 0; b = 255; break;
  98. }
  99. #endif
  100. #if FOG
  101. S3L_Unit fog = (p->depth *
  102. #if TEXTURES
  103. 8
  104. #else
  105. 16
  106. #endif
  107. ) / S3L_F;
  108. r = S3L_clamp(((S3L_Unit) r) - fog,0,255);
  109. g = S3L_clamp(((S3L_Unit) g) - fog,0,255);
  110. b = S3L_clamp(((S3L_Unit) b) - fog,0,255);
  111. #endif
  112. setPixel(p->x,p->y,r,g,b);
  113. }
  114. S3L_Transform3D modelTransform;
  115. S3L_DrawConfig conf;
  116. clock_t nextT;
  117. int fps = 0;
  118. void draw(void)
  119. {
  120. S3L_newFrame();
  121. clearScreen();
  122. S3L_drawScene(scene);
  123. S3L_Vec4 screenPoint;
  124. S3L_project3DPointToScreen(teleportPoint,scene.camera,&screenPoint);
  125. if (screenPoint.w > 0 &&
  126. screenPoint.x >= 0 && screenPoint.x < S3L_RESOLUTION_X &&
  127. screenPoint.y >= 0 && screenPoint.y < S3L_RESOLUTION_Y &&
  128. screenPoint.z < S3L_zBufferRead(screenPoint.x,screenPoint.y))
  129. drawTeleport(screenPoint.x,screenPoint.y,screenPoint.w);
  130. clock_t nowT = clock();
  131. double timeDiff = ((double) (nowT - nextT)) / CLOCKS_PER_SEC;
  132. fps++;
  133. if (timeDiff >= 1.0)
  134. {
  135. nextT = nowT;
  136. printf("FPS: %d\n",fps);
  137. printf("camera: ");
  138. S3L_logTransform3D(scene.camera.transform);
  139. fps = 0;
  140. }
  141. }
  142. int main(void)
  143. {
  144. sdlInit();
  145. teleportPoint.x = 6 * S3L_F;
  146. teleportPoint.y = -3 * S3L_F;
  147. teleportPoint.z = 3 * S3L_F / 2;
  148. teleportPoint.w = S3L_F;
  149. nextT = clock();
  150. levelModelInit();
  151. S3L_sceneInit(&levelModel,1,&scene);
  152. int running = 1;
  153. while (running) // main loop
  154. {
  155. draw();
  156. while (SDL_PollEvent(&event))
  157. if (event.type == SDL_QUIT)
  158. running = 0;
  159. S3L_Vec4 camF, camR;
  160. S3L_rotationToDirections(scene.camera.transform.rotation,20,&camF,&camR,0);
  161. const uint8_t *state = SDL_GetKeyboardState(NULL);
  162. if (state[SDL_SCANCODE_ESCAPE])
  163. running = 0;
  164. if (state[SDL_SCANCODE_A])
  165. scene.camera.transform.rotation.y += 1;
  166. else if (state[SDL_SCANCODE_D])
  167. scene.camera.transform.rotation.y -= 1;
  168. else if (state[SDL_SCANCODE_W])
  169. scene.camera.transform.rotation.x += 1;
  170. else if (state[SDL_SCANCODE_S])
  171. scene.camera.transform.rotation.x -= 1;
  172. if (state[SDL_SCANCODE_UP])
  173. S3L_vec3Add(&scene.camera.transform.translation,camF);
  174. else if (state[SDL_SCANCODE_DOWN])
  175. S3L_vec3Sub(&scene.camera.transform.translation,camF);
  176. else if (state[SDL_SCANCODE_LEFT])
  177. S3L_vec3Sub(&scene.camera.transform.translation,camR);
  178. else if (state[SDL_SCANCODE_RIGHT])
  179. S3L_vec3Add(&scene.camera.transform.translation,camR);
  180. sdlUpdate();
  181. frame++;
  182. }
  183. sdlEnd();
  184. return 0;
  185. }