3d.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // This example renders a rotating triangle.
  2. // This idea is that you can take this code and compile it to different platforms with different rendering machanisms:
  3. // native with SDL, WebAssembly with HTML5 canvas, etc.
  4. #define OLIVEC_IMPLEMENTATION
  5. #include "olive.c"
  6. float sqrtf(float x);
  7. float atan2f(float y, float x);
  8. float sinf(float x);
  9. float cosf(float x);
  10. #define PI 3.14159265359
  11. // #define FACTOR 100
  12. // #define WIDTH (16*FACTOR)
  13. // #define HEIGHT (9*FACTOR)
  14. #define WIDTH 800
  15. #define HEIGHT 600
  16. #define BACKGROUND_COLOR 0xFF181818
  17. #define GRID_COUNT 10
  18. #define GRID_PAD 0.5/GRID_COUNT
  19. #define GRID_SIZE ((GRID_COUNT - 1)*GRID_PAD)
  20. #define CIRCLE_RADIUS 5
  21. #define Z_START 0.25
  22. #define ABOBA_PADDING 50
  23. uint32_t circle_colors[] = {
  24. 0xFF2020FF,
  25. 0xFF20FF20,
  26. 0xFFFF2020,
  27. 0xFF20FFFF,
  28. 0xFFFF20FF,
  29. 0xFFFFFF20,
  30. };
  31. #define circle_colors_count (sizeof(circle_colors)/sizeof(circle_colors[0]))
  32. static uint32_t pixels[WIDTH*HEIGHT];
  33. static float angle = 0;
  34. uint32_t *render(float dt)
  35. {
  36. angle += 0.25*PI*dt;
  37. Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
  38. olivec_fill(oc, BACKGROUND_COLOR);
  39. for (int ix = 0; ix < GRID_COUNT; ++ix) {
  40. for (int iy = 0; iy < GRID_COUNT; ++iy) {
  41. for (int iz = 0; iz < GRID_COUNT; ++iz) {
  42. float x = ix*GRID_PAD - GRID_SIZE/2;
  43. float y = iy*GRID_PAD - GRID_SIZE/2;
  44. float z = Z_START + iz*GRID_PAD;
  45. float cx = 0.0;
  46. float cz = Z_START + GRID_SIZE/2;
  47. float dx = x - cx;
  48. float dz = z - cz;
  49. float a = atan2f(dz, dx);
  50. float m = sqrtf(dx*dx + dz*dz);
  51. dx = cosf(a + angle)*m;
  52. dz = sinf(a + angle)*m;
  53. x = dx + cx;
  54. z = dz + cz;
  55. x /= z;
  56. y /= z;
  57. uint32_t r = ix*255/GRID_COUNT;
  58. uint32_t g = iy*255/GRID_COUNT;
  59. uint32_t b = iz*255/GRID_COUNT;
  60. uint32_t color = 0xFF000000 | (r<<(0*8)) | (g<<(1*8)) | (b<<(2*8));
  61. olivec_circle(oc, (x + 1)/2*WIDTH, (y + 1)/2*HEIGHT, CIRCLE_RADIUS, color);
  62. }
  63. }
  64. }
  65. size_t size = 8;
  66. olivec_text(oc, "aboba", ABOBA_PADDING, HEIGHT - ABOBA_PADDING - default_font.height*size, default_font, size, 0xFFFFFFFF);
  67. return pixels;
  68. }
  69. #ifdef SDL_PLATFORM
  70. #include <stdio.h>
  71. #include <SDL2/SDL.h>
  72. #define return_defer(value) do { result = (value); goto defer; } while (0)
  73. int main(void)
  74. {
  75. int result = 0;
  76. SDL_Window *window = NULL;
  77. SDL_Renderer *renderer = NULL;
  78. SDL_Texture *texture = NULL;
  79. {
  80. if (SDL_Init(SDL_INIT_VIDEO) < 0) return_defer(1);
  81. window = SDL_CreateWindow("Olivec", 0, 0, WIDTH, HEIGHT, 0);
  82. if (window == NULL) return_defer(1);
  83. renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
  84. if (renderer == NULL) return_defer(1);
  85. texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT);
  86. if (texture == NULL) return_defer(1);
  87. Uint32 prev = SDL_GetTicks();
  88. for (;;) {
  89. // Compute Delta Time
  90. Uint32 curr = SDL_GetTicks();
  91. float dt = (curr - prev)/1000.f;
  92. prev = curr;
  93. // Flush the events
  94. SDL_Event event;
  95. while (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) return_defer(0);
  96. // Render the texture
  97. SDL_Rect window_rect = {0, 0, WIDTH, HEIGHT};
  98. uint32_t *pixels_src = render(dt);
  99. void *pixels_dst;
  100. int pitch;
  101. if (SDL_LockTexture(texture, &window_rect, &pixels_dst, &pitch) < 0) return_defer(1);
  102. for (size_t y = 0; y < HEIGHT; ++y) {
  103. memcpy(pixels_dst + y*pitch, pixels_src + y*WIDTH, WIDTH*sizeof(uint32_t));
  104. }
  105. SDL_UnlockTexture(texture);
  106. // Display the texture
  107. if (SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0) < 0) return_defer(1);
  108. if (SDL_RenderClear(renderer) < 0) return_defer(1);
  109. if (SDL_RenderCopy(renderer, texture, &window_rect, &window_rect) < 0) return_defer(1);
  110. SDL_RenderPresent(renderer);
  111. }
  112. }
  113. defer:
  114. switch (result) {
  115. case 0:
  116. printf("OK\n");
  117. break;
  118. default:
  119. fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
  120. }
  121. if (texture) SDL_DestroyTexture(texture);
  122. if (renderer) SDL_DestroyRenderer(renderer);
  123. if (window) SDL_DestroyWindow(window);
  124. SDL_Quit();
  125. return result;
  126. }
  127. #endif // SDL_PLATFORM