From c82f69094327162406056776fe04cfd20bfa289e Mon Sep 17 00:00:00 2001 From: Austin Morlan Date: Tue, 4 Sep 2018 19:50:27 -0700 Subject: [PATCH] Add OBJ file loading --- Makefile | 6 +-- include/geometry.h | 21 +++++++++++ include/loader.h | 11 ++++++ include/point.h | 24 ++++++++++++ src/engine.cpp | 13 +++++++ src/loader.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 include/geometry.h create mode 100644 include/loader.h create mode 100644 include/point.h create mode 100644 src/loader.cpp diff --git a/Makefile b/Makefile index 1df73ef..6a0199b 100644 --- a/Makefile +++ b/Makefile @@ -31,15 +31,15 @@ CC=clang++ WARNINGS_ON=-Weverything WARNINGS_OFF=-Wno-missing-braces -Wno-gnu-anonymous-struct -Wno-old-style-cast\ -Wno-zero-as-null-pointer-constant -Wno-nested-anon-types\ - -Wno-padded + -Wno-padded -Wno-exit-time-destructors -Wno-global-constructors CFLAGS=$(D) $(O) -std=c++11 $(WARNINGS_ON) $(WARNINGS_OFF) -I$(INCLUDE_DIR) LIBS=-lSDL2 -_HEADERS = engine.h platform.h util.h +_HEADERS = engine.h loader.h geometry.h platform.h point.h util.h HEADERS = $(patsubst %,$(INCLUDE_DIR)/%,$(_HEADERS)) -_OBJS = engine.o main.o platform.o +_OBJS = engine.o loader.o main.o platform.o OBJS = $(patsubst %,$(BUILD_DIR)/%,$(_OBJS)) $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS) diff --git a/include/geometry.h b/include/geometry.h new file mode 100644 index 0000000..8352526 --- /dev/null +++ b/include/geometry.h @@ -0,0 +1,21 @@ +#ifndef GEOMETRY_H + +#include "point.h" +#include + + +struct Face +{ + unsigned int vertIndex[3]; +}; + +struct Mesh +{ + std::vector verts; + std::vector faces; +}; + + +#define GEOMETRY_H +#endif + diff --git a/include/loader.h b/include/loader.h new file mode 100644 index 0000000..6e0642a --- /dev/null +++ b/include/loader.h @@ -0,0 +1,11 @@ +#ifndef LOADER_H + +#include "geometry.h" + + +int LoadMesh(char *filename, Mesh &mesh); + + +#define LOADER_H +#endif + diff --git a/include/point.h b/include/point.h new file mode 100644 index 0000000..9406bb4 --- /dev/null +++ b/include/point.h @@ -0,0 +1,24 @@ +#ifndef POINT_H + + +// STRUCTURE +struct Point +{ + inline Point(void) : x(0), y(0), z(0), w(1) {} + inline Point(float x, float y, float z) : x(x), y(y), z(z), w(1) {} + + union + { + float e[4]; + + struct + { + float x, y, z, w; + }; + }; +}; + + +#define POINT_H +#endif + diff --git a/src/engine.cpp b/src/engine.cpp index abc9ff4..4444180 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,7 +1,20 @@ #include "engine.h" +#include "loader.h" + + +// GLOBALS +static Mesh mesh; + int Engine_Init(char *filename) { + int result = LoadMesh(filename, mesh); + + if (result < 0) + { + return -1; + } + return 0; } diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100644 index 0000000..4f8197e --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,93 @@ +#include "loader.h" +#include +#include +#include + + +// STATIC PROTOTYPES +static char *GetLine(char *buffer, int maxLength, FILE *fp); + + +// PUBLIC FUNCTIONS +int LoadMesh(char *filename, Mesh &mesh) +{ + FILE *fp; + char buffer[256]; + char *token; + + char garbage[5]; + + fp = fopen(filename, "r"); + + if (fp == NULL) + { + fprintf(stderr, "Error loading file: %s\n", filename); + return -1; + } + + token = GetLine(buffer, sizeof(buffer), fp); + + while (token != NULL) + { + if (token[0] == 'v') + { + Point v; + + sscanf( + token, "%s %f %f %f", + garbage, + &v.x, + &v.y, + &v.z); + + mesh.verts.push_back(v); + } + else if (token[0] == 'f') + { + Face f; + + sscanf(token, "%s %d %d %d", + garbage, + &f.vertIndex[0], + &f.vertIndex[1], + &f.vertIndex[2]); + + // Convert to 0-indexed + f.vertIndex[0] -= 1; + f.vertIndex[1] -= 1; + f.vertIndex[2] -= 1; + + mesh.faces.push_back(f); + } + + token = GetLine(buffer, sizeof(buffer), fp); + } + + printf("OBJ: %s\n", filename); + printf("Verts: %lu\n", mesh.verts.size()); + printf("Faces: %lu\n", mesh.faces.size()); + + fclose(fp); + + return 0; +} + +static char *GetLine(char *buffer, int maxLength, FILE *fp) +{ + while(true) + { + if (!fgets(buffer, maxLength, fp)) + { + return NULL; + } + + // for (length = strlen(buffer), index = 0; isspace(buffer[index]); ++index); + + if (buffer[0] != 'v' && buffer[0] != 'f') + { + continue; + } + + return buffer; + } +}