rasterizer

C++ software renderer

refactor: new string utils, refactor parse_obj()

Arjun Choudhary contact@arjunchoudhary.com

commit: c3fac5b parent: 8348e78

3 files changed, 64 insertions(+), 23 deletions(-)
MODsrc/globals.h+2-0
MODsrc/mesh.cpp+22-23
ADDsrc/util_string.h+40-0
MOD · src/globals.h +2 -0
--- a/src/globals.h
+++ b/src/globals.h
@@ -1,3 +1,5 @@
+#pragma once
+
 #include <stdint.h>
 
 typedef int8_t   i8;
MOD · src/mesh.cpp +22 -23
--- a/src/mesh.cpp
+++ b/src/mesh.cpp
@@ -4,11 +4,9 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <vector>
-
+#include "globals.h"
 #include "util_math.h"
-
-using std::vector;
+#include "util_string.h"
 
 Mesh parse_obj(const char *filename) {
     Mesh mesh;
@@ -19,34 +17,37 @@ Mesh parse_obj(const char *filename) {
         return mesh;
     }
 
-    char line[1024];
-    while (fgets(line, sizeof(line), file)) {
-        if (strncmp(line, "#", 2) == 0 || strncmp(line, "\n", 2) == 0) {
+    char   line_buffer[1024];
+    string line = {nullptr, 0};
+
+    while (fgets(line_buffer, sizeof(line_buffer), file)) {
+        line = string_from_cstr(line_buffer);
+        string_trim(&line);
+
+        if (line.size == 0 || line.str[0] == '#') {
             continue;
         }
-        if (strncmp(line, "v ", 2) == 0) {
+        if (strncmp(line.str, "v ", 2) == 0) {
             vec3f v;
-            sscanf(line, "v %f %f %f", &v.x, &v.y, &v.z);
+            sscanf(line.str, "v %f %f %f", &v.x, &v.y, &v.z);
             mesh.vertices.push_back(v);
-        } else if (strncmp(line, "vt ", 3) == 0) {
+        } else if (strncmp(line.str, "vt ", 3) == 0) {
             vec2f vt;
-            sscanf(line, "vt %f %f", &vt.x, &vt.y);
+            sscanf(line.str, "vt %f %f", &vt.x, &vt.y);
             mesh.texcoords.push_back(vt);
-        } else if (strncmp(line, "vn ", 3) == 0) {
+        } else if (strncmp(line.str, "vn ", 3) == 0) {
             vec3f vn;
-            sscanf(line, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
+            sscanf(line.str, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
             mesh.normals.push_back(vn);
-        } else if (strncmp(line, "f ", 2) == 0) {
-            char *face_token = strtok(line + 2, " \n\r");
+        } else if (strncmp(line.str, "f ", 2) == 0) {
+            char *face_token = strtok(line.str + 2, " \n\r");
             while (face_token) {
-                Face idx = {0, 0, 0};
-                int  v = 0, vt = 0, vn = 0;
-
+                Face  idx = {0, 0, 0};
+                int   v = 0, vt = 0, vn = 0;
                 char *slash1 = strchr(face_token, '/');
                 if (slash1) {
-                    *slash1 = '\0';
-                    v       = atoi(face_token);
-
+                    *slash1      = '\0';
+                    v            = atoi(face_token);
                     char *slash2 = strchr(slash1 + 1, '/');
                     if (slash2) {
                         *slash2 = '\0';
@@ -58,11 +59,9 @@ Mesh parse_obj(const char *filename) {
                 } else {
                     v = atoi(face_token);
                 }
-
                 if (v > 0) idx.vertex_idx = v - 1;
                 if (vt > 0) idx.vertex_texture_idx = vt - 1;
                 if (vn > 0) idx.vertex_normal_idx = vn - 1;
-
                 mesh.faces.push_back(idx);
                 face_token = strtok(nullptr, " \n\r");
             }
ADD · src/util_string.h +40 -0
--- a/src/util_string.h
+++ b/src/util_string.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <string.h>
+
+#include "globals.h"
+
+// No allocs, all inplace, so scoped to caller.
+// Don't use out of scope, unless using a custom allocator or you malloc outside
+
+typedef struct {
+    char *str;
+    u64   size;
+} string;
+
+inline string string_from_cstr(char *cstr) {
+    string s = {};
+    if (cstr) {
+        s.str  = cstr;
+        s.size = (u32)strlen(cstr);
+    }
+    return s;
+}
+
+inline void string_trim(string *s) {
+    size_t start = 0;
+    size_t end   = s->size;
+    while (start < end &&
+           (s->str[start] == ' ' || s->str[start] == '\t' ||
+            s->str[start] == '\r' || s->str[start] == '\n')) {
+        start++;
+    }
+    while (end > start &&
+           (s->str[end - 1] == ' ' || s->str[end - 1] == '\t' ||
+            s->str[end - 1] == '\r' || s->str[end - 1] == '\n')) {
+        end--;
+    }
+    s->str += start;
+    s->size = end - start;
+}
+}