rasterizer
C++ software rendererrefactor: new string utils, refactor parse_obj()
| 3 files changed, 64 insertions(+), 23 deletions(-) | |||
|---|---|---|---|
| MOD | src/globals.h | +2 | -0 |
| MOD | src/mesh.cpp | +22 | -23 |
| ADD | src/util_string.h | +40 | -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;
+}
+}