瀏覽代碼

Make olive.c act like a header by default

Unless OLIVEC_IMPLEMENTATION is defined. Basically make actually an
stb-style library.
rexim 3 年之前
父節點
當前提交
d09b2f17ea
共有 5 個文件被更改,包括 44 次插入25 次删除
  1. 4 2
      README.md
  2. 4 3
      examples/gallery.c
  3. 2 1
      examples/triangle.c
  4. 28 14
      olive.c
  5. 6 5
      test.c

+ 4 - 2
README.md

@@ -26,6 +26,7 @@ $ ./build.sh
 
 ```c
 // flag_jp.c
+#define OLIVEC_IMPLEMENTATION
 #include "olive.c"
 
 #define STB_IMAGE_WRITE_IMPLEMENTATION
@@ -38,9 +39,10 @@ uint32_t pixels[WIDTH*HEIGHT];
 
 int main(void)
 {
+    Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
     // Taken from https://upload.wikimedia.org/wikipedia/en/9/9e/Flag_of_Japan.svg
-    olivec_fill(pixels, WIDTH, HEIGHT, 0xFFFFFFFF);
-    olivec_circle(pixels, WIDTH, HEIGHT, WIDTH/2, HEIGHT/2, 180, 0xFF2D00BC);
+    olivec_fill(oc, 0xFFFFFFFF);
+    olivec_circle(oc, WIDTH/2, HEIGHT/2, 180, 0xFF2D00BC);
 
     const char *file_path = "flag_jp.png";
     if (!stbi_write_png(file_path, WIDTH, HEIGHT, 4, pixels, sizeof(uint32_t)*WIDTH)) {

+ 4 - 3
examples/gallery.c

@@ -8,6 +8,7 @@
 #define STB_IMAGE_WRITE_IMPLEMENTATION
 #include "./stb_image_write.h"
 
+#define OLIVEC_IMPLEMENTATION
 #include "olive.c"
 
 #define WIDTH 800
@@ -27,7 +28,7 @@ static uint32_t pixels[WIDTH*HEIGHT];
 
 bool checker_example(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
 
     olivec_fill(oc, BACKGROUND_COLOR);
 
@@ -57,7 +58,7 @@ float lerpf(float a, float b, float t)
 
 bool circle_example(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
     olivec_fill(oc, BACKGROUND_COLOR);
 
     for (int y = 0; y < ROWS; ++y) {
@@ -87,7 +88,7 @@ bool circle_example(void)
 
 bool lines_example(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
 
     olivec_fill(oc, BACKGROUND_COLOR);
     olivec_line(oc, 0, 0, WIDTH, HEIGHT, FOREGROUND_COLOR);

+ 2 - 1
examples/triangle.c

@@ -1,6 +1,7 @@
 // This example renders a rotating triangle.
 // This idea is that you can take this code and compile it to different platforms with different rendering machanisms:
 // native with SDL, WebAssembly with HTML5 canvas, etc.
+#define OLIVEC_IMPLEMENTATION
 #include "olive.c"
 
 #define WIDTH 800
@@ -35,7 +36,7 @@ static inline void rotate_point(float *x, float *y)
 
 uint32_t *render(float dt)
 {
-    Olivec_Canvas oc = olivec_make_canvas(pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(pixels, WIDTH, HEIGHT);
 
     olivec_fill(oc, BACKGROUND_COLOR);
 

+ 28 - 14
olive.c

@@ -23,16 +23,15 @@ typedef struct {
 #define OLIVEC_CANVAS_NULL ((Olivec_Canvas) {0})
 #define OLIVEC_PIXEL(oc, x, y) (oc).pixels[(y)*(oc).stride + (x)]
 
-OLIVECDEF Olivec_Canvas olivec_make_canvas(uint32_t *pixels, size_t width, size_t height)
-{
-    Olivec_Canvas oc = {
-        .pixels = pixels,
-        .width  = width,
-        .height = height,
-        .stride = width,
-    };
-    return oc;
-}
+OLIVECDEF Olivec_Canvas olivec_canvas(uint32_t *pixels, size_t width, size_t height);
+OLIVECDEF Olivec_Canvas olivec_subcanvas(Olivec_Canvas oc, int x, int y, int w, int h);
+OLIVECDEF void olivec_blend_color(uint32_t *c1, uint32_t c2);
+OLIVECDEF void olivec_fill(Olivec_Canvas oc, uint32_t color);
+OLIVECDEF void olivec_rect(Olivec_Canvas oc, int x, int y, int w, int h, uint32_t color);
+OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t color);
+// TODO: lines with different thicness
+OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color);
+OLIVECDEF void olivec_triangle(Olivec_Canvas oc, int x1, int y1, int x2, int y2, int x3, int y3, uint32_t color);
 
 // The point of this function is to produce two ranges x1..x2 and y1..y2 that are guaranteed to be safe to iterate over the canvas of size pixels_width by pixels_height without any boundary checks.
 //
@@ -45,6 +44,23 @@ OLIVECDEF Olivec_Canvas olivec_make_canvas(uint32_t *pixels, size_t width, size_
 // } else {
 //     // Rectangle is invisible cause it's completely out-of-bounds
 // }
+OLIVECDEF bool olivec_normalize_rect(int x, int y, int w, int h, size_t pixels_width, size_t pixels_height, int *x1, int *x2, int *y1, int *y2);
+
+#endif // OLIVE_C_
+
+#ifdef OLIVEC_IMPLEMENTATION
+
+OLIVECDEF Olivec_Canvas olivec_canvas(uint32_t *pixels, size_t width, size_t height)
+{
+    Olivec_Canvas oc = {
+        .pixels = pixels,
+        .width  = width,
+        .height = height,
+        .stride = width,
+    };
+    return oc;
+}
+
 OLIVECDEF bool olivec_normalize_rect(int x, int y, int w, int h,
                                      size_t pixels_width, size_t pixels_height,
                                      int *x1, int *x2, int *y1, int *y2)
@@ -83,7 +99,6 @@ OLIVECDEF Olivec_Canvas olivec_subcanvas(Olivec_Canvas oc, int x, int y, int w,
     return oc;
 }
 
-
 OLIVECDEF void olivec_blend_color(uint32_t *c1, uint32_t c2)
 {
     uint32_t r1 = ((*c1)>>(0*8))&0xFF;
@@ -140,7 +155,6 @@ OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t c
     }
 }
 
-// TODO: lines with different thicness
 OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color)
 {
     // TODO: fix the olivec_draw_line stairs
@@ -232,11 +246,11 @@ OLIVECDEF void olivec_triangle(Olivec_Canvas oc, int x1, int y1, int x2, int y2,
     }
 }
 
+#endif // OLIVEC_IMPLEMENTATION
+
 // TODO: supersampling
 // TODO: 3D triangles
 // TODO: Benchmarking
 // TODO: SIMD implementations
 // TODO: olivec_ring
 // TODO: olivec_ellipse
-
-#endif // OLIVE_C_

+ 6 - 5
test.c

@@ -10,6 +10,7 @@
 #define STB_IMAGE_IMPLEMENTATION
 #include "./stb_image.h"
 
+#define OLIVEC_IMPLEMENTATION
 #include "olive.c"
 
 #define return_defer(value) do { result = (value); goto defer; } while (0)
@@ -160,7 +161,7 @@ typedef struct {
 
 void test_fill_rect(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(actual_pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(actual_pixels, WIDTH, HEIGHT);
     olivec_fill(oc, BACKGROUND_COLOR);
     olivec_rect(oc, WIDTH/2 - WIDTH/8, HEIGHT/2 - HEIGHT/8, WIDTH/4, HEIGHT/4, RED_COLOR);
     olivec_rect(oc, WIDTH - 1, HEIGHT - 1, -WIDTH/2, -HEIGHT/2, GREEN_COLOR);
@@ -169,7 +170,7 @@ void test_fill_rect(void)
 
 void test_fill_circle(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(actual_pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(actual_pixels, WIDTH, HEIGHT);
     olivec_fill(oc, BACKGROUND_COLOR);
     olivec_circle(oc, 0, 0, WIDTH/2, RED_COLOR);
     olivec_circle(oc, WIDTH/2, HEIGHT/2, WIDTH/4, BLUE_COLOR);
@@ -178,7 +179,7 @@ void test_fill_circle(void)
 
 void test_draw_line(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(actual_pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(actual_pixels, WIDTH, HEIGHT);
     olivec_fill(oc, BACKGROUND_COLOR);
     olivec_line(oc, 0, 0, WIDTH, HEIGHT, RED_COLOR);
     olivec_line(oc, WIDTH, 0, 0, HEIGHT, BLUE_COLOR);
@@ -187,7 +188,7 @@ void test_draw_line(void)
 
 void test_fill_triangle(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(actual_pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(actual_pixels, WIDTH, HEIGHT);
 
     olivec_fill(oc, BACKGROUND_COLOR);
 
@@ -215,7 +216,7 @@ void test_fill_triangle(void)
 
 void test_alpha_blending(void)
 {
-    Olivec_Canvas oc = olivec_make_canvas(actual_pixels, WIDTH, HEIGHT);
+    Olivec_Canvas oc = olivec_canvas(actual_pixels, WIDTH, HEIGHT);
     olivec_fill(oc, BACKGROUND_COLOR);
     olivec_rect(oc, 0, 0, WIDTH*3/4, HEIGHT*3/4, RED_COLOR);
     olivec_rect(oc, WIDTH-1, HEIGHT-1, -WIDTH*3/4, -HEIGHT*3/4, 0x5520AA20);