rasterizer

C++ software renderer

refactor: new string utils, refactor parse_obj()

Arjun Choudhary contact@arjunchoudhary.com

commit: f5532a5 parent: 62c8a78
3 files changed, 64 insertions(+), 23 deletions(-)
Msrc/globals.h+2-0
Msrc/mesh.cpp+22-23
Asrc/util_string.h+40-0
M · src/globals.h +2, -0
1@@ -1,3 +1,5 @@
2+#pragma once
3+
4 #include <stdint.h>
5 
6 typedef int8_t   i8;
M · src/mesh.cpp +22, -23
 1@@ -4,11 +4,9 @@
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5-#include <vector>
 6-
 7+#include "globals.h"
 8 #include "util_math.h"
 9-
10-using std::vector;
11+#include "util_string.h"
12 
13 Mesh parse_obj(const char *filename) {
14     Mesh mesh;
15@@ -19,34 +17,37 @@ Mesh parse_obj(const char *filename) {
16         return mesh;
17     }
18 
19-    char line[1024];
20-    while (fgets(line, sizeof(line), file)) {
21-        if (strncmp(line, "#", 2) == 0 || strncmp(line, "\n", 2) == 0) {
22+    char   line_buffer[1024];
23+    string line = {nullptr, 0};
24+
25+    while (fgets(line_buffer, sizeof(line_buffer), file)) {
26+        line = string_from_cstr(line_buffer);
27+        string_trim(&line);
28+
29+        if (line.size == 0 || line.str[0] == '#') {
30             continue;
31         }
32-        if (strncmp(line, "v ", 2) == 0) {
33+        if (strncmp(line.str, "v ", 2) == 0) {
34             vec3f v;
35-            sscanf(line, "v %f %f %f", &v.x, &v.y, &v.z);
36+            sscanf(line.str, "v %f %f %f", &v.x, &v.y, &v.z);
37             mesh.vertices.push_back(v);
38-        } else if (strncmp(line, "vt ", 3) == 0) {
39+        } else if (strncmp(line.str, "vt ", 3) == 0) {
40             vec2f vt;
41-            sscanf(line, "vt %f %f", &vt.x, &vt.y);
42+            sscanf(line.str, "vt %f %f", &vt.x, &vt.y);
43             mesh.texcoords.push_back(vt);
44-        } else if (strncmp(line, "vn ", 3) == 0) {
45+        } else if (strncmp(line.str, "vn ", 3) == 0) {
46             vec3f vn;
47-            sscanf(line, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
48+            sscanf(line.str, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
49             mesh.normals.push_back(vn);
50-        } else if (strncmp(line, "f ", 2) == 0) {
51-            char *face_token = strtok(line + 2, " \n\r");
52+        } else if (strncmp(line.str, "f ", 2) == 0) {
53+            char *face_token = strtok(line.str + 2, " \n\r");
54             while (face_token) {
55-                Face idx = {0, 0, 0};
56-                int  v = 0, vt = 0, vn = 0;
57-
58+                Face  idx = {0, 0, 0};
59+                int   v = 0, vt = 0, vn = 0;
60                 char *slash1 = strchr(face_token, '/');
61                 if (slash1) {
62-                    *slash1 = '\0';
63-                    v       = atoi(face_token);
64-
65+                    *slash1      = '\0';
66+                    v            = atoi(face_token);
67                     char *slash2 = strchr(slash1 + 1, '/');
68                     if (slash2) {
69                         *slash2 = '\0';
70@@ -58,11 +59,9 @@ Mesh parse_obj(const char *filename) {
71                 } else {
72                     v = atoi(face_token);
73                 }
74-
75                 if (v > 0) idx.vertex_idx = v - 1;
76                 if (vt > 0) idx.vertex_texture_idx = vt - 1;
77                 if (vn > 0) idx.vertex_normal_idx = vn - 1;
78-
79                 mesh.faces.push_back(idx);
80                 face_token = strtok(nullptr, " \n\r");
81             }
A · src/util_string.h +40, -0
 1@@ -0,0 +1,40 @@
 2+#pragma once
 3+
 4+#include <string.h>
 5+
 6+#include "globals.h"
 7+
 8+// No allocs, all inplace, so scoped to caller.
 9+// Don't use out of scope, unless using a custom allocator or you malloc outside
10+
11+typedef struct {
12+    char *str;
13+    u64   size;
14+} string;
15+
16+inline string string_from_cstr(char *cstr) {
17+    string s = {};
18+    if (cstr) {
19+        s.str  = cstr;
20+        s.size = (u32)strlen(cstr);
21+    }
22+    return s;
23+}
24+
25+inline void string_trim(string *s) {
26+    size_t start = 0;
27+    size_t end   = s->size;
28+    while (start < end &&
29+           (s->str[start] == ' ' || s->str[start] == '\t' ||
30+            s->str[start] == '\r' || s->str[start] == '\n')) {
31+        start++;
32+    }
33+    while (end > start &&
34+           (s->str[end - 1] == ' ' || s->str[end - 1] == '\t' ||
35+            s->str[end - 1] == '\r' || s->str[end - 1] == '\n')) {
36+        end--;
37+    }
38+    s->str += start;
39+    s->size = end - start;
40+}
41+}