main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * 3D Engine
  3. * main.c:
  4. * Based on pikuma.com 3D software renderer in C
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 01/03/2021.
  8. */
  9. #include <stdio.h>
  10. #include <stdint.h>
  11. #include <stdbool.h>
  12. #include <SDL.h>
  13. #include <log.h>
  14. #include <display.h>
  15. #include <vector.h>
  16. bool isRunning = true;
  17. int previousFrameTime = 0;
  18. #define N_POINTS (9*9*9)
  19. vec3_t cubePoints[N_POINTS];
  20. vec2_t projectedPoints[N_POINTS];
  21. vec3_t cameraPosition =
  22. {
  23. .x = 0,
  24. .y = 0,
  25. .z = -5,
  26. };
  27. vec3_t cubeRotation =
  28. {
  29. .x = 0,
  30. .y = 0,
  31. .z = 0,
  32. };
  33. double fovFactor = 820 ;
  34. void setup()
  35. {
  36. frameBuffer = (uint32_t *)calloc(windowWidth * windowHeight, sizeof(uint32_t));
  37. if (!frameBuffer)
  38. {
  39. log(TLOG_PANIC, NULL, "Memory allocation error.");
  40. goto exit;
  41. }
  42. frameBufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, windowWidth,
  43. windowHeight);
  44. if (frameBufferTexture == NULL)
  45. {
  46. log(TLOG_PANIC, NULL, "SDL Texture creation error: %s", SDL_GetError());
  47. goto exit;
  48. }
  49. int pointCount = 0;
  50. for(double x = -1; x <= 1 ; x += 0.25)
  51. {
  52. for(double y = -1; y <= 1 ; y += 0.25)
  53. {
  54. for(double z = -1; z <= 1 ; z += 0.25)
  55. {
  56. vec3_t new_point = { x, y, z };
  57. cubePoints[pointCount++] = new_point;
  58. }
  59. }
  60. }
  61. exit:
  62. return;
  63. }
  64. void processInput()
  65. {
  66. SDL_Event event;
  67. SDL_PollEvent(&event);
  68. switch (event.type)
  69. {
  70. case SDL_QUIT:isRunning = false;
  71. break;
  72. case SDL_KEYDOWN:
  73. if (event.key.keysym.sym == SDLK_ESCAPE)
  74. {
  75. isRunning = false;
  76. }
  77. break;
  78. default:
  79. break;
  80. }
  81. }
  82. vec2_t orthographicPointProjection(vec3_t point)
  83. {
  84. vec2_t ret;
  85. ret.x = point.x * fovFactor + (windowWidth / 2.);
  86. ret.y = point.y * fovFactor + (windowHeight / 2.);
  87. return ret;
  88. }
  89. vec2_t perspectivePointProjection(vec3_t point)
  90. {
  91. vec2_t ret;
  92. ret.x = (point.x/point.z) * (fovFactor/2.) + (windowWidth / 2.);
  93. ret.y = (point.y/point.z) * (fovFactor/2.) + (windowHeight / 2.);
  94. return ret;
  95. }
  96. void update()
  97. {
  98. int i;
  99. while(!SDL_TICKS_PASSED(SDL_GetTicks(), previousFrameTime + FRAME_TARGET_TIME));
  100. previousFrameTime = SDL_GetTicks();
  101. cubeRotation.x += 0.01;
  102. cubeRotation.y += 0.01;
  103. cubeRotation.z += 0.01;
  104. for(i = 0; i < N_POINTS; i++)
  105. {
  106. vec3_t point = cubePoints[i];
  107. point = vec3RotateX(point, cubeRotation.x);
  108. point = vec3RotateY(point, cubeRotation.y);
  109. point = vec3RotateZ(point, cubeRotation.z);
  110. point.z -= cameraPosition.z;
  111. projectedPoints[i] = perspectivePointProjection(point);
  112. }
  113. }
  114. void render()
  115. {
  116. int i;
  117. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
  118. SDL_RenderClear(renderer);
  119. for(i = 0; i < N_POINTS; i++)
  120. {
  121. vec2_t projPoint = projectedPoints[i];
  122. drawRectangle(projPoint.x, projPoint.y, 4, 4, 0xFFFFFF00);
  123. }
  124. renderFrameBuffer();
  125. clearFrameBuffer(0xFF000000);
  126. SDL_RenderPresent(renderer);
  127. }
  128. int main(int argc, char *argv[])
  129. {
  130. int param_i;
  131. bool fullScreen = false;
  132. MAX_DEBUG_LEVEL = TLOG_DEBUG;
  133. log(TLOG_ALWAYS, NULL, "Booting 3D Engine (version %s)!", VERSION);
  134. for (param_i = 1 ; (param_i < argc) && (argv[param_i][0] == '-') ; param_i++)
  135. {
  136. switch (argv[param_i][1])
  137. {
  138. default: exit(-1); /* Option not recognized */
  139. case 'f': fullScreen = true; break;
  140. case 'w': windowWidth = atoi(argv[++param_i]);
  141. case 'h': windowHeight = atoi(argv[++param_i]); break;
  142. #ifdef DYNA_LOG_LEVEL
  143. case 'l': MAX_DEBUG_LEVEL = atoi(argv[++param_i]); break;
  144. #endif
  145. case '-': goto no_more_params; /* Could use break, but this is more clear */
  146. }
  147. }
  148. no_more_params:
  149. isRunning = initialiseWindow(fullScreen);
  150. setup();
  151. while (isRunning)
  152. {
  153. processInput();
  154. update();
  155. render();
  156. }
  157. destroy_window();
  158. return 0;
  159. }