aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--README.md14
-rw-r--r--shaders/dummy.fsh12
-rw-r--r--shaders/dummy.vsh2
-rw-r--r--src/main.c40
-rw-r--r--src/obj.c176
-rw-r--r--src/obj.h17
8 files changed, 222 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
index 53be119..42ef77d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
objs/
+docs/
mverse
tags
models
diff --git a/Makefile b/Makefile
index 3895e4d..26317a4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
CC := cc
-CFLAGS := -Wall -pedantic -pedantic-errors -std=c11
+CFLAGS := -Wall -pedantic -pedantic-errors -std=c99
DLIBS := -lm $(shell pkg-config --libs glfw3 opengl glew)
INCLUDE := $(addprefix -I,./include)
OBJDIR = objs
diff --git a/README.md b/README.md
index 786ee34..183a62e 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,17 @@
The goal of this project is learning Opengl through a project, which consists in
making a convincing world with mountains and lands, this will take a while 🥲.
+
+# Installation
+
+```shell
+$ cd mverse
+$ make
+```
+
+# Usage
+
+```
+$ ./mverse <FILE>
+```
+
diff --git a/shaders/dummy.fsh b/shaders/dummy.fsh
index 7d94f22..472bb26 100644
--- a/shaders/dummy.fsh
+++ b/shaders/dummy.fsh
@@ -1,7 +1,17 @@
#version 330 core
+
+struct Material {
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+ int illum;
+ float Ns;
+};
+
+uniform Material mtl;
out vec4 FragColor;
void main()
{
- FragColor = vec4(0.0f);
+ FragColor = vec4(mtl.diffuse, 1.0);
}
diff --git a/shaders/dummy.vsh b/shaders/dummy.vsh
index ab57a50..bd540ab 100644
--- a/shaders/dummy.vsh
+++ b/shaders/dummy.vsh
@@ -14,7 +14,7 @@ out vec2 TexCoords;
void main()
{
gl_Position = proj * view * model * vec4(aPos, 1.0f);
- //FragPos = vec3(model * vec4(aPos, 1.0));
+ FragPos = vec3(model * vec4(aPos, 1.0));
//Normal = vec3(rotNormals * vec4(aNormal, 1.0));
//TexCoords = aTexCoords;
}
diff --git a/src/main.c b/src/main.c
index 93275f4..8111496 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,6 +30,8 @@ static Mat4 processCameraInput(GLFWwindow *window, struct Camera *cameraObj, flo
static unsigned int loadTexture(char const *path);
static void meshSetUp(Mesh *mesh);
static void meshDraw(unsigned int shader, Mesh mesh);
+static void objSetUp(Obj obj);
+static void objDraw(unsigned int shader, Obj obj);
static float cameraSpeed = 2.0;
@@ -214,17 +216,38 @@ meshDraw(unsigned int shader, Mesh mesh)
glBindVertexArray(0);
}
+void
+objSetUp(Obj obj)
+{
+ int i;
+ for (i = 0; i < obj.size; i++)
+ meshSetUp(obj.mesh + i);
+}
+
+void
+objDraw(unsigned int shader, Obj obj)
+{
+ int i;
+ for (i = 0; i < obj.size; i++) {
+ shaderSetfv(shader, "mtl.ambient", obj.mesh[i].material.ka, glUniform3fv);
+ shaderSetfv(shader, "mtl.diffuse", obj.mesh[i].material.kd, glUniform3fv);
+ shaderSetfv(shader, "mtl.specular", obj.mesh[i].material.ks, glUniform3fv);
+ meshDraw(shader, obj.mesh[i]);
+ }
+}
+
+
int main(int argc, char *argv[])
{
- Mesh *mesh;
+ Obj obj;
GLFWwindow *window;
const char *glfwErrno;
- if (argc == 2) mesh = objCreateMesh(argv[1]);
- else if (argc == 1) mesh = objCreateMesh("-");
+ if (argc == 2) obj = objCreate(argv[1]);
+ else if (argc == 1) obj = objCreate("-");
else return 1;
- if (mesh == NULL) {
+ if (obj.mesh == NULL) {
glfwTerminate();
userError("objCreateMesh Error", "NULL mesh returned");
}
@@ -254,7 +277,7 @@ int main(int argc, char *argv[])
unsigned int shader = shaderCreateProgram("shaders/dummy.vsh", "shaders/dummy.fsh");
- meshSetUp(mesh);
+ objSetUp(obj);
struct Camera mainCamera;
mainCamera.position = linearVec3(0.0, 0.0, 10.0);
@@ -270,7 +293,7 @@ int main(int argc, char *argv[])
glEnable(GL_DEPTH_TEST);
while (!glfwWindowShouldClose(window)) {
processInput(window);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwGetWindowSize(window, &width, &height);
@@ -292,15 +315,12 @@ int main(int argc, char *argv[])
shaderSetMatrixfv(shader, "view", view.matrix[0], glUniformMatrix4fv);
shaderSetMatrixfv(shader, "rotNormals", R.matrix[0], glUniformMatrix4fv);
- meshDraw(shader, mesh[0]);
+ objDraw(shader, obj);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
- free(mesh->vertices);
- free(mesh->indices);
- free(mesh);
return 0;
}
diff --git a/src/obj.c b/src/obj.c
index a457fba..272dc30 100644
--- a/src/obj.c
+++ b/src/obj.c
@@ -5,14 +5,6 @@
#include "obj.h"
-enum ObjVertexType {
- OBJ_V,
- OBJ_VN,
- OBJ_VT,
- OBJ_F,
- OBJ_OTHER
-};
-
struct Setv3 {
float data[3];
};
@@ -27,9 +19,13 @@ struct Seti {
static void readV3(char *line, struct Setv3 **v, int vIndex);
static void readV2(char *line, struct Setv2 **vn, int vtIndex);
-static void readF(char *line, Mesh *mesh, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *vn);
+static void readF(char *line, Mesh *mesh, int meshIndex, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *vn);
+
+static Material * readMtl(char *line, const char *path, int *size);
+static unsigned int useMtl(char *line, Material *mtl, unsigned int size);
+
+/* -------------------------------------------------------------------------- */
-// ----------------------------------------------------------------------------
struct Seti * readIndices(char *line, int *nIndices);
static int readIndex(char *line, struct Seti *f);
static Vertex createVertex(struct Seti f, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *vn);
@@ -38,10 +34,18 @@ static void vertexAdd(Mesh *mesh, Vertex vertex);
static int vertexGetIndex(Vertex *vertices, Vertex vertex, int nVertices);
static void indexAdd(Mesh *mesh, int index);
-Mesh *
-objCreateMesh(const char *filename)
+/* -------------------------------------------------------------------------- */
+static void getDir(char *filepath);
+static void appendMtl(char *line, Material **mtl, int index);
+static void readColor(char *line, float *k);
+
+
+Obj
+objCreate(const char *filename)
{
+ Obj o;
Mesh *mesh;
+ Material *mtl;
char lineBuffer[OBJ_LINE_MAX_SIZE];
FILE *fi;
@@ -57,30 +61,48 @@ objCreateMesh(const char *filename)
if (fi == NULL || mesh == NULL) {
fprintf(stderr, "objCreateMesh() Error: %s\n", strerror(errno));
fclose(fi);
- return NULL;
+ exit(1);
}
v = (struct Setv3 *)calloc(1, vSize * sizeof(struct Setv3));
vt = (struct Setv2 *)calloc(1, vtSize * sizeof(struct Setv2));
vn = (struct Setv3 *)calloc(1, vnSize * sizeof(struct Setv3));
- /*
- if (vSize == 0) {
- fprintf(stderr, "objCreateMesh() Error: v components not found\n");
- exit(1);
- } else if (v == NULL) {
+ if (v == NULL) {
fprintf(stderr, "objCreateMesh() Error: %s\n", strerror(errno));
exit(1);
}
- */
+ int n;
+ char key[500];
int vIndex, vtIndex, vnIndex;
- vIndex = vtIndex = vnIndex = 0;
+ int mtlSize, mtlIndex, meshIndex;
+ vIndex = vtIndex = vnIndex = meshIndex = 0;
+
while (fgets(lineBuffer, OBJ_LINE_MAX_SIZE, fi)) {
- if (!strncmp("f", lineBuffer, 1)) readF (lineBuffer + 1, mesh, v, vt, vn);
- else if (!strncmp("vt", lineBuffer, 2)) readV2(lineBuffer + 2, &vt, vtIndex++);
- else if (!strncmp("vn", lineBuffer, 2)) readV3(lineBuffer + 2, &vn, vnIndex++);
- else if (!strncmp("v", lineBuffer, 1)) readV3(lineBuffer + 1, &v, vIndex++);
+
+ sscanf(lineBuffer, "%s%n", key, &n);
+
+ if (!strcmp("f" , key)) readF (lineBuffer + n, mesh, meshIndex, v, vt, vn);
+ else if (!strcmp("vt", key)) readV2(lineBuffer + n, &vt, vtIndex++);
+ else if (!strcmp("vn", key)) readV3(lineBuffer + n, &vn, vnIndex++);
+ else if (!strcmp("v" , key)) readV3(lineBuffer + n, &v, vIndex++);
+
+ else if (!strcmp("mtllib", key)) mtl = readMtl(lineBuffer + n, filename, &mtlSize);
+ else if (!strcmp("usemtl", key)) {
+ mtlIndex = useMtl (lineBuffer + n, mtl, mtlSize);
+ mesh = (Mesh *)realloc(mesh, (++meshIndex + 1) * sizeof(Mesh));
+ memset(mesh + meshIndex, 0, sizeof(Mesh));
+ mesh[meshIndex].material = mtl[mtlIndex];
+ mesh[meshIndex].indexSize = 0;
+ }
+ }
+
+ o.mesh = mesh;
+ o.size = meshIndex + 1;
+ for (int i = 1; i < o.size; i++) {
+ o.mesh[i].vertices = o.mesh[0].vertices;
+ o.mesh[i].vertexSize = o.mesh[0].vertexSize;
}
free(v);
@@ -88,11 +110,11 @@ objCreateMesh(const char *filename)
free(vn);
fclose(fi);
- return mesh;
+ return o;
}
void
-readF(char *line, Mesh *mesh, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *vn)
+readF(char *line, Mesh *mesh, int meshIndex, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *vn)
{
Vertex vertexBuffer;
struct Seti *f;
@@ -104,7 +126,7 @@ readF(char *line, Mesh *mesh, struct Setv3 *v, struct Setv2 *vt, struct Setv3 *v
if (!vertexInVertices(vertexBuffer, mesh->vertices, mesh->vertexSize))
vertexAdd(mesh, vertexBuffer);
vi = vertexGetIndex(mesh->vertices, vertexBuffer, mesh->vertexSize);
- indexAdd(mesh, vi);
+ indexAdd(mesh + meshIndex, vi);
}
free(f);
}
@@ -305,3 +327,103 @@ indexAdd(Mesh *mesh, int index)
mesh->indices = iv;
mesh->indexSize++;
}
+
+Material *
+readMtl(char *line, const char *objFile, int *size)
+{
+ Material *out;
+ char buffer[OBJ_LINE_MAX_SIZE], mtlFilename[OBJ_LINE_MAX_SIZE], key[500];
+ char path[512], fileName[512];
+ FILE *fin;
+ int i, n;
+
+ strncpy(path, objFile, 512);
+ getDir(path);
+ sscanf(line, " ./%s", fileName);
+ sprintf(mtlFilename, "%s/%s", path, fileName);
+
+ fin = fopen(mtlFilename, "r");
+ i = 0;
+ while(fgets(buffer, OBJ_LINE_MAX_SIZE, fin)) {
+ sscanf(buffer, "%s%n", key, &n);
+ if (!strcmp(key, "newmtl")) appendMtl(buffer + n, &out, i++);
+ if (i > 0) {
+ if (!strcmp(key, "Ka")) readColor(buffer + n, out[i - 1].ka);
+ else if (!strcmp(key, "Kd")) readColor(buffer + n, out[i - 1].kd);
+ else if (!strcmp(key, "Ks")) readColor(buffer + n, out[i - 1].ks);
+ else if (!strcmp(key, "illum")) sscanf(buffer + n, "%u", &out[i - 1].illum);
+ else if (!strcmp(key, "Ns")) sscanf(buffer + n, "%f", &out[i - 1].ns);
+ }
+ }
+
+ if (size) *size = i;
+ fclose(fin);
+ return out;
+}
+
+void
+appendMtl(char *line, Material **mtl, int index)
+{
+ char name[OBJ_LINE_MAX_SIZE];
+
+ if (index == 0)
+ *mtl = (Material *)calloc(1, sizeof(Material));
+ else
+ *mtl = (Material *)realloc(*mtl, (index + 1) * sizeof(Material));
+
+ sscanf(line, "%s", name);
+ strncpy((*mtl + index)->name, name, OBJ_LINE_MAX_SIZE);
+
+ if (mtl == NULL) {
+ fprintf(stderr, "appendMtl() Error: %s\n", strerror(errno));
+ exit(1);
+ }
+}
+
+void
+readColor(char *line, float *k)
+{
+ int ret;
+ ret = sscanf(line, "%f %f %f", k, k + 1, k + 2);
+ switch (ret) {
+ case 1:
+ k[1] = k[2] = k[0];
+ break;
+ case 3:
+ break;
+ default:
+ fprintf(stderr, "readColor() Error: line '%s' invalid format", line - 2);
+ exit(1);
+ break;
+ }
+}
+
+unsigned int
+useMtl(char *line, Material *mtl, unsigned int size)
+{
+ int i;
+ char name[OBJ_LINE_MAX_SIZE];
+ for (i = 0; i < size; i++) {
+ sscanf(line, "%s", name);
+ if (!strcmp(name, mtl[i].name))
+ return i;
+ }
+ return 0;
+}
+
+void
+getDir(char *filepath)
+{
+ int i;
+ for (i = strlen(filepath) - 1; i >= 0; i--) {
+ switch (filepath[i]) {
+ case '/':
+ case '\\':
+ filepath[i] = '\0';
+ return;
+ default:
+ break;
+ }
+ }
+ strcpy(filepath, ".");
+}
diff --git a/src/obj.h b/src/obj.h
index 864910f..19a156e 100644
--- a/src/obj.h
+++ b/src/obj.h
@@ -2,6 +2,7 @@
#define __OBJ__
#define OBJ_LINE_MAX_SIZE 1024
+#define OBJ_MAX_NAME 512
typedef struct {
float position[3];
@@ -15,12 +16,24 @@ typedef struct {
} Texture;
typedef struct {
+ char name[OBJ_LINE_MAX_SIZE];
+ float ka[3], kd[3], ks[3];
+ unsigned int illum;
+ float ns;
+} Material;
+
+typedef struct {
Vertex *vertices;
- Texture *textures;
+ Material material;
unsigned int *indices;
unsigned int indexSize, vertexSize;
unsigned int VAO, EBO, VBO;
} Mesh;
-Mesh * objCreateMesh(const char *filename);
+typedef struct {
+ Mesh *mesh;
+ unsigned int size;
+} Obj;
+
+Obj objCreate(const char *filename);
# endif
Feel free to download, copy and edit any repo