Add rough texturization, driven by barycentric rather than screen coordinates
authorNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 07:25:00 +0000 (17:25 +1000)
committerNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 07:25:00 +0000 (17:25 +1000)
render.c

index 2da329f..d0fec5f 100644 (file)
--- a/render.c
+++ b/render.c
@@ -301,20 +301,19 @@ int main(void) {
 #if 1
   struct obj *obj = obj_create("Chest.obj"); //"grey_bliss_set.obj");
   struct array *model_vertices;
+  struct array *model_vertices_t;
   {
     int I = obj->vc;
     model_vertices = array_new3(4, I, sizeof(float));
+    model_vertices_t = array_new3(2, I, sizeof(float));
     for (int i = 0; i < I; ++i) {
-      float v[4] = {
-        obj->vv[i].v[0],
-        obj->vv[i].v[1],
-        obj->vv[i].v[2],
-        1.f
-      };
-      *(float *)array_index2(model_vertices, 0, i) = v[0];
-      *(float *)array_index2(model_vertices, 1, i) = v[1];
-      *(float *)array_index2(model_vertices, 2, i) = v[2];
-      *(float *)array_index2(model_vertices, 3, i) = v[3];
+      *(float *)array_index2(model_vertices, 0, i) = obj->vv[i].v[0];
+      *(float *)array_index2(model_vertices, 1, i) = obj->vv[i].v[1];
+      *(float *)array_index2(model_vertices, 2, i) = obj->vv[i].v[2];
+      *(float *)array_index2(model_vertices, 3, i) = 1.f;
+
+      *(float *)array_index2(model_vertices_t, 0, i) = obj->vv[i].t[0];
+      *(float *)array_index2(model_vertices_t, 1, i) = obj->vv[i].t[1];
     }
   }
 #else
@@ -458,6 +457,37 @@ int main(void) {
     }
   );
 
+  // helpers
+#if 0
+  struct array *to_barycentric = array_new3_init(
+    4,
+    3,
+    sizeof(float),
+    (float[4][3]){
+      {1.f, 0.f, 0.f},
+      {0.f, 1.f, 0.f},
+      {-1.f, -1.f, 1.f},
+      {0.f, 0.f, 1.f}
+    }
+  );
+#endif
+  struct array *barycentric = array_new3(
+    3,
+    101 * 102 / 2,
+    sizeof(float)
+  );
+  {
+    int k = 0;
+    for (int i = 0; i <= 100; ++i)
+      for (int j = 0; i + j <= 100; ++j) {
+        *(float *)array_index2(barycentric, 0, k) = i * .01f;
+        *(float *)array_index2(barycentric, 1, k) = j * .01f;
+        *(float *)array_index2(barycentric, 2, k) = (100 - i - j) * .01f;
+        ++k;
+      }
+    assert(k == 101 * 102 / 2);
+  }
+
   // main loop
   while (true) {
     SDL_Event event;
@@ -526,7 +556,6 @@ int main(void) {
     struct array *qu = mat_unproject(q);
 
     // draw
-    SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 0xff);
 #if 1
     {
       int I = obj->sc;
@@ -567,29 +596,71 @@ int main(void) {
           array_free(pu0);
 #endif
 
-          struct array *qug = mat_columns(qu, 3, v);
+#if 1 // roughly texturize
+          int mi = obj->sv[i].mi;
+          if (mi >= 0 && mi < obj->mc) {
+            struct array *map = obj->mv[mi].kv[OBJ_KD].map;
+            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];
+              *(float *)array_index2(tc, 1, i) *= map->dim[0];
+            }
+            struct array *tcb = mul_mat_mat(tc, barycentric);
+            struct array *qc = mat_columns(q, 3, v);
+            struct array *qcb = mul_mat_mat(qc, barycentric);
+            struct array *qcbu = mat_unproject(qcb);
+            size_t K = barycentric->dim[1];
+            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))
+              );
+            }
+            array_free(qcbu);
+            array_free(qcb);
+            array_free(qc);
+            array_free(tcb);
+            array_free(tc);
+          }
+#else // wireframe only
+          struct array *quc = mat_columns(qu, 3, v);
+          SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 0xff);
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 1, 0),
-            *(float *)array_index2(qug, 0, 1),
-            *(float *)array_index2(qug, 1, 1)
+            *(float *)array_index2(quc, 0, 0),
+            *(float *)array_index2(quc, 1, 0),
+            *(float *)array_index2(quc, 0, 1),
+            *(float *)array_index2(quc, 1, 1)
           );
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 0, 1),
-            *(float *)array_index2(qug, 1, 1),
-            *(float *)array_index2(qug, 0, 2),
-            *(float *)array_index2(qug, 1, 2)
+            *(float *)array_index2(quc, 0, 1),
+            *(float *)array_index2(quc, 1, 1),
+            *(float *)array_index2(quc, 0, 2),
+            *(float *)array_index2(quc, 1, 2)
           );
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 0, 2),
-            *(float *)array_index2(qug, 1, 2),
-            *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 1, 0)
+            *(float *)array_index2(quc, 0, 2),
+            *(float *)array_index2(quc, 1, 2),
+            *(float *)array_index2(quc, 0, 0),
+            *(float *)array_index2(quc, 1, 0)
           );
-          array_free(qug);
+          array_free(quc);
+#endif
         }
         /*int*/ J = obj->sv[i].lc;
         for (int j = 0; j < J; ++j) {
@@ -597,29 +668,31 @@ int main(void) {
             obj->sv[i].lv[j].vi[0],
             obj->sv[i].lv[j].vi[1]
           };
-          struct array *qug = mat_columns(qu, 2, v);
+          struct array *quc = mat_columns(qu, 2, v);
+          SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 0xff);
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 1, 0),
-            *(float *)array_index2(qug, 0, 1),
-            *(float *)array_index2(qug, 1, 1)
+            *(float *)array_index2(quc, 0, 0),
+            *(float *)array_index2(quc, 1, 0),
+            *(float *)array_index2(quc, 0, 1),
+            *(float *)array_index2(quc, 1, 1)
           );
-          array_free(qug);
+          array_free(quc);
         }
       }
     }
 #else
     for (int i = 0; i < 12; ++i) {
-      struct array *qug = mat_columns(qu, 2, model_lines[i]);
+      struct array *quc = mat_columns(qu, 2, model_lines[i]);
+      SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 0xff);
       SDL_RenderDrawLine(
         renderer,
-        *(float *)array_index2(qug, 0, 0),
-        *(float *)array_index2(qug, 1, 0),
-        *(float *)array_index2(qug, 0, 1),
-        *(float *)array_index2(qug, 1, 1)
+        *(float *)array_index2(quc, 0, 0),
+        *(float *)array_index2(quc, 1, 0),
+        *(float *)array_index2(quc, 0, 1),
+        *(float *)array_index2(quc, 1, 1)
       );
-      array_free(qug);
+      array_free(quc);
     }
 #endif