Improve performance by drawing into CPU framebuffer and then blitting to screen
authorNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 09:01:46 +0000 (19:01 +1000)
committerNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 09:01:46 +0000 (19:01 +1000)
render.c

index d0fec5f..83a77e5 100644 (file)
--- a/render.c
+++ b/render.c
@@ -15,7 +15,8 @@
 
 SDL_Window *window;
 SDL_Renderer *renderer;
-SDL_Surface *window_surface;
+SDL_Texture *texture;
+SDL_Surface *surface;
 
 void print_vec(const char *prefix, struct array *array, const char *suffix) {
   assert(array->n_dims == 2);
@@ -232,18 +233,24 @@ int main(void) {
     exit(EXIT_FAILURE);
   }
 
-  window_surface = SDL_GetWindowSurface(window);
-  if (window_surface == NULL) {
-    fprintf(stderr, "SDL_GetWindowSurface(): %s\n", SDL_GetError());
-    exit(EXIT_FAILURE);
-  }
-
   renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
   if (renderer == NULL) {
     fprintf(stderr, "SDL_CreateRenderer(): %s\n", SDL_GetError());
     exit(EXIT_FAILURE);
   }
 
+  texture = SDL_CreateTexture(
+    renderer,
+    SDL_PIXELFORMAT_ARGB8888,
+    SDL_TEXTUREACCESS_STREAMING,
+    WINDOW_WIDTH,
+    WINDOW_HEIGHT
+  );
+  if (texture == NULL) {
+    fprintf(stderr, "SDL_CreateTexture(): %s\n", SDL_GetError());
+    exit(EXIT_FAILURE);
+  }
+
   // device
   struct array *device_transform = array_new3_init(
     3,
@@ -489,6 +496,8 @@ int main(void) {
   }
 
   // main loop
+  struct array *frame =
+    array_new3(WINDOW_HEIGHT, WINDOW_WIDTH, sizeof(uint32_t));
   while (true) {
     SDL_Event event;
     while (SDL_PollEvent(&event))
@@ -556,6 +565,8 @@ int main(void) {
     struct array *qu = mat_unproject(q);
 
     // draw
+    array_clear0(frame);
+    //memset(array_index2(frame, 50, 50), 0xff, frame->stride[2]);
 #if 1
     {
       int I = obj->sc;
@@ -600,6 +611,7 @@ int main(void) {
           int mi = obj->sv[i].mi;
           if (mi >= 0 && mi < obj->mc) {
             struct array *map = obj->mv[mi].kv[OBJ_KD].map;
+            assert(map->dim[2] == 3);
             struct array *tc = mat_columns(model_vertices_t, 3, v);
             for (int i = 0; i < 3; ++i) {
               *(float *)array_index2(tc, 0, i) *= map->dim[1];
@@ -613,21 +625,25 @@ int main(void) {
             for (size_t k = 0; k < K; ++k) {
               float u = floorf(*(float *)array_index2(tcb, 0, k));
               float v = floorf(*(float *)array_index2(tcb, 1, k));
-              uint8_t bgra[4] = {0, 0, 0, 0xff};
-              if (v >= 0 && v < map->dim[0] && u >= 0 && u < map->dim[1])
-                array_get2(map, bgra, (size_t)v, (size_t)u);
-              SDL_SetRenderDrawColor(
-                renderer,
-                bgra[2],
-                bgra[1],
-                bgra[0],
-                bgra[3]
-              );
-              SDL_RenderDrawPoint(
-                renderer,
-                roundf(*(float *)array_index2(qcbu, 0, k)),
-                roundf(*(float *)array_index2(qcbu, 1, k))
-              );
+              float x = roundf(*(float *)array_index2(qcbu, 0, k));
+              float y = roundf(*(float *)array_index2(qcbu, 1, k));
+              if (
+                u >= 0 &&
+                u < map->dim[1] &&
+                v >= 0 &&
+                v < map->dim[0] &&
+                x >= 0 &&
+                x < WINDOW_WIDTH &&
+                y >= 0 &&
+                y < WINDOW_HEIGHT
+              ) {
+                uint8_t *m = array_index2(map, (size_t)v, (size_t)u);
+                uint8_t *f = array_index2(frame, (size_t)y, (size_t)x);
+                f[0] = m[0]; // b
+                f[1] = m[1]; // g
+                f[2] = m[2]; // r
+                f[3] = 0xff; // a
+              }
             }
             array_free(qcbu);
             array_free(qcb);
@@ -705,6 +721,8 @@ int main(void) {
     array_free(t1);
     array_free(t0);
 
+    SDL_UpdateTexture(texture, NULL, array_index0(frame), frame->stride[1]);
+    SDL_RenderCopy(renderer, texture, NULL, NULL);
     SDL_RenderPresent(renderer);
     SDL_Delay(1);
   }