main_CPU.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "stdlib.h"
  2. #include "SDL2/SDL.h"
  3. #include "math.h"
  4. #include "time.h"
  5. #include <CL/cl.h>
  6. const int WIDTH = 800;
  7. const int HEIGHT = 800;
  8. const int POLYGON_SIZE = sizeof(float) * 3 * 3;
  9. const int POLYGONS = 10;
  10. int is_intersecting(int a, int b, int c, int d, int p, int q, int r, int s) {
  11. float det, gamma, lambda;
  12. det = (c - a) * (s - q) - (r - p) * (d - b);
  13. if (det == 0) {
  14. return 1;
  15. }
  16. else {
  17. lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
  18. gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
  19. return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
  20. }
  21. }
  22. void norm(float dest[2], float a[2]){
  23. float magnitude = sqrt((pow(a[0], 2) + pow(a[1], 2)));
  24. dest[0] = a[0] / magnitude;
  25. dest[1] = a[1] / magnitude;
  26. }
  27. void sub(float dest[2], float a[2], float b[2]){
  28. dest[0] = a[0] - b[0];
  29. dest[1] = a[1] - b[1];
  30. }
  31. void add(float dest[2], float a[2], float b[2]){
  32. dest[0] = a[0] + b[0];
  33. dest[1] = a[1] + b[1];
  34. }
  35. int main(){
  36. srand(time(NULL));
  37. float polygons[POLYGONS][3][3];
  38. SDL_Init(SDL_INIT_VIDEO);
  39. SDL_Window* window = SDL_CreateWindow("Rasterizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
  40. SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
  41. SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
  42. int running = 1;
  43. Uint32 frame_buffer[WIDTH * HEIGHT];
  44. float z_buffer[WIDTH * HEIGHT];
  45. int frame = 0;
  46. Uint32 start_time, frame_time;
  47. float fps;
  48. while (running) {
  49. start_time = SDL_GetTicks();
  50. //if (frame % 1 == 0){
  51. for (int p = 0; p < POLYGONS; p++){
  52. for (int point = 0; point < 3; point++){
  53. for (int i = 0; i < 3; i++){
  54. polygons[p][point][i] = rand() % WIDTH + 1;
  55. }
  56. }
  57. }
  58. //}
  59. for (int i = 0; i < WIDTH * HEIGHT; ++i) {
  60. frame_buffer[i] = 0x22222222;
  61. }
  62. memset(&z_buffer, 0, sizeof(float) * WIDTH * HEIGHT);
  63. SDL_Event event;
  64. while (SDL_PollEvent(&event)){
  65. switch (event.type){
  66. case SDL_QUIT:
  67. running = 0;
  68. }
  69. }
  70. for (int polygon = 0; polygon < POLYGONS; polygon++){
  71. float x0 = polygons[polygon][0][0];
  72. float y0 = polygons[polygon][0][1];
  73. float z0 = polygons[polygon][0][2];
  74. float x1 = polygons[polygon][1][0];
  75. float y1 = polygons[polygon][1][1];
  76. float z1 = polygons[polygon][1][2];
  77. float x2 = polygons[polygon][2][0];
  78. float y2 = polygons[polygon][2][1];
  79. float z2 = polygons[polygon][2][2];
  80. float smallest_x = x0;
  81. float largest_x = x0;
  82. float smallest_y = y0;
  83. float largest_y = y0;
  84. for (int point = 0; point < 3; point++){
  85. float x = polygons[polygon][point][0];
  86. float y = polygons[polygon][point][1];
  87. if (x > largest_x){
  88. largest_x = x;
  89. }
  90. if (x < smallest_x){
  91. smallest_x = x;
  92. }
  93. if (y > largest_y){
  94. largest_y = y;
  95. }
  96. if (y < smallest_y){
  97. smallest_y = y;
  98. }
  99. }
  100. smallest_x = fmin(smallest_x, 0);
  101. largest_x = fmax(largest_x, WIDTH);
  102. smallest_y = fmin(smallest_y, 0);
  103. largest_y = fmax(largest_y, HEIGHT);
  104. // test every pixel in a rect around the triangle. If it's inside, color it.
  105. for (int x = (int)smallest_x; x < largest_x; x++){
  106. for (int y = (int)smallest_y; y < largest_y; y++){
  107. int intersections = 0;
  108. for (int i = 0; i < 3; i++){
  109. intersections += is_intersecting(x, y, 10000, 100000, polygons[polygon][i][0], polygons[polygon][i][1], polygons[polygon][(i + 1) % 3][0], polygons[polygon][(i + 1) % 3][1]);
  110. }
  111. if (intersections % 2 == 0){
  112. continue;
  113. }
  114. float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2);
  115. float w0 = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / denominator;
  116. float w1 = ((y2 - y0) * (x - x0) + (x0 - x2) * (y - y2)) / denominator;
  117. float w2 = 1.0 - w0 - w1;
  118. if (denominator < 0) {
  119. w0 = -w0;
  120. w1 = -w1;
  121. w2 = -w2;
  122. denominator = -denominator;
  123. }
  124. float z = w0 * z0 + w1 * z1 + w2 * z2;
  125. if (z < 0){
  126. z *= -1;
  127. }
  128. // printf("%f\n", z);
  129. if (z > z_buffer[y * WIDTH + x]){
  130. z_buffer[y * WIDTH + x] = z;
  131. }
  132. else {
  133. continue;
  134. }
  135. frame_buffer[y * WIDTH + x] = 0xFFFFFFFF / POLYGONS * (polygon + 1);
  136. }
  137. }
  138. }
  139. SDL_UpdateTexture(texture, NULL, frame_buffer, WIDTH * sizeof(Uint32));
  140. SDL_RenderClear(renderer);
  141. SDL_RenderCopy(renderer, texture, NULL, NULL);
  142. SDL_RenderPresent(renderer);
  143. frame++;
  144. frame_time = SDL_GetTicks()-start_time;
  145. fps = (frame_time > 0) ? 1000.0f / frame_time : 0.0f;
  146. printf("%f fps\n", fps);
  147. printf("%d polygons\n", POLYGONS);
  148. }
  149. SDL_DestroyTexture(texture);
  150. SDL_DestroyRenderer(renderer);
  151. SDL_DestroyWindow(window);
  152. SDL_Quit();
  153. }