scene graph logic
This commit is contained in:
parent
2632068106
commit
14626a5bd5
|
@ -4,7 +4,7 @@ OTHER_LIBS = -lm
|
||||||
|
|
||||||
ALL_LIBS = $(GLEW_LIBS) $(GLFW_LIBS) $(OTHER_LIBS)
|
ALL_LIBS = $(GLEW_LIBS) $(GLFW_LIBS) $(OTHER_LIBS)
|
||||||
|
|
||||||
OBJ = matrixMath.o transformation.o wavefrontobj.o
|
OBJ = matrixMath.o transformation.o wavefrontobj.o sceneGraph.o objectHandler.o
|
||||||
SHADERS = fragmentShader.c vertexShader.c
|
SHADERS = fragmentShader.c vertexShader.c
|
||||||
|
|
||||||
cg1.out: test.out main.o $(OBJ) $(SHADERS)
|
cg1.out: test.out main.o $(OBJ) $(SHADERS)
|
||||||
|
@ -17,7 +17,7 @@ test.out: test.o $(OBJ)
|
||||||
%Shader.c: %Shader.glsl
|
%Shader.c: %Shader.glsl
|
||||||
xxd -i $? > $@
|
xxd -i $? > $@
|
||||||
|
|
||||||
main.o: $(SHADERS) matrixMath.h transformation.h wavefrontobj.h
|
main.o: $(SHADERS) matrixMath.h transformation.h wavefrontobj.h sceneGraph.h objectHandler.h
|
||||||
|
|
||||||
test.o: matrixMath.h transformation.h wavefrontobj.h
|
test.o: matrixMath.h transformation.h wavefrontobj.h
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,7 @@ uniform vec4 ambientLight;
|
||||||
uniform vec3 lightPosition;
|
uniform vec3 lightPosition;
|
||||||
uniform vec4 lightColor;
|
uniform vec4 lightColor;
|
||||||
|
|
||||||
uniform sampler2D day;
|
uniform sampler2D textureSampler;
|
||||||
uniform sampler2D night;
|
|
||||||
uniform sampler2D clouds;
|
|
||||||
uniform sampler2D ocean;
|
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,13 +21,7 @@ float emissionStrength = 0.0;
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = vec4(texture(day, textureCoordinate).rgb, 1.0);
|
vec4 color = vec4(texture(textureSampler, textureCoordinate).rgb, 1.0);
|
||||||
|
|
||||||
float nightBrightness = texture(night, textureCoordinate).r;
|
|
||||||
vec4 nightColor = vec4(nightBrightness, nightBrightness * 0.7, nightBrightness * 0.5, 1.0);
|
|
||||||
float shininessMultiplier = texture(ocean, textureCoordinate).r;
|
|
||||||
|
|
||||||
vec4 cloudColor = texture(clouds, textureCoordinate).rgba;
|
|
||||||
|
|
||||||
vec3 norm = normalize(normal);
|
vec3 norm = normalize(normal);
|
||||||
|
|
||||||
|
@ -40,7 +31,7 @@ void main() {
|
||||||
float diff = max(dot(norm, lightDir), 0.0);
|
float diff = max(dot(norm, lightDir), 0.0);
|
||||||
|
|
||||||
vec3 halfway = (lightDir + eyeDir) / length(lightDir + eyeDir);
|
vec3 halfway = (lightDir + eyeDir) / length(lightDir + eyeDir);
|
||||||
float specular = pow(max(dot(halfway, norm), 0.0), shininess) * shininessMultiplier;
|
float specular = pow(max(dot(halfway, norm), 0.0), shininess);
|
||||||
|
|
||||||
|
|
||||||
gl_FragColor =
|
gl_FragColor =
|
||||||
|
@ -51,7 +42,7 @@ void main() {
|
||||||
ambientLight * color +
|
ambientLight * color +
|
||||||
|
|
||||||
// DIFFUSION
|
// DIFFUSION
|
||||||
mix(nightColor * (vec4(1,1,1,1) - cloudColor) + (cloudColor * ambientLight), color + cloudColor, diff) +
|
color * diff +
|
||||||
|
|
||||||
// SPECULAR
|
// SPECULAR
|
||||||
specular * lightColor * color;
|
specular * lightColor * color;
|
||||||
|
|
166
src/main.c
166
src/main.c
|
@ -5,10 +5,12 @@
|
||||||
|
|
||||||
#include "vertexShader.c"
|
#include "vertexShader.c"
|
||||||
#include "fragmentShader.c"
|
#include "fragmentShader.c"
|
||||||
#include "objectHandler.c"
|
|
||||||
|
#include "objectHandler.h"
|
||||||
#include "matrixMath.h"
|
#include "matrixMath.h"
|
||||||
#include "transformation.h"
|
#include "transformation.h"
|
||||||
#include "wavefrontobj.h"
|
#include "wavefrontobj.h"
|
||||||
|
#include "sceneGraph.h"
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "../lib/stb_image.h"
|
#include "../lib/stb_image.h"
|
||||||
|
@ -58,6 +60,11 @@ const GLfloat pi = 3.14159f;
|
||||||
vec3 cameraPosition = {0.0f, 3.0f, 5.5f};
|
vec3 cameraPosition = {0.0f, 3.0f, 5.5f};
|
||||||
vec3 objectPosition = {0.0f, 0.0f, 0.0f};
|
vec3 objectPosition = {0.0f, 0.0f, 0.0f};
|
||||||
GLfloat radius = 1.0f;
|
GLfloat radius = 1.0f;
|
||||||
|
mat4 viewingTransformation;
|
||||||
|
|
||||||
|
// Define a global scene graph root node
|
||||||
|
SceneNode* rootNode;
|
||||||
|
|
||||||
|
|
||||||
int numModels = 0;
|
int numModels = 0;
|
||||||
char* models[] = {
|
char* models[] = {
|
||||||
|
@ -150,9 +157,39 @@ void loadTexture(char* textureFile, GLuint* texture) {
|
||||||
stbi_image_free(image);
|
stbi_image_free(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
void renderNode(SceneNode* node) {
|
||||||
void drawObject() {
|
mat4 modelView;
|
||||||
|
identity(&modelView);
|
||||||
|
multiply(&modelView, &node->worldTransformation, &modelView);
|
||||||
|
multiply(&modelView, &viewingTransformation, &modelView);
|
||||||
|
|
||||||
|
// calculate matrix for normals
|
||||||
|
mat3 normalModelView;
|
||||||
|
mat3From4(&normalModelView, &modelView);
|
||||||
|
mat3Inverse(&normalModelView, &normalModelView);
|
||||||
|
mat3Transpose(&normalModelView, &normalModelView);
|
||||||
|
|
||||||
|
// send transformation matrix to shader
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program, "modelView"), 1, GL_FALSE, (GLfloat*)&modelView);
|
||||||
|
glUniformMatrix3fv(glGetUniformLocation(program, "normalModelView"), 1, GL_FALSE, (GLfloat*)&normalModelView);
|
||||||
|
|
||||||
|
// SET MATERIAL DATA
|
||||||
|
glUniform1f(glGetUniformLocation(program, "shininess"), 60.0f * 4.0f);
|
||||||
|
|
||||||
|
|
||||||
|
// BIND TEXTURES
|
||||||
|
GLuint textureLocation;
|
||||||
|
textureLocation = glGetUniformLocation(program, "textureSampler");
|
||||||
|
glUniform1i(textureLocation, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[DAY]);
|
||||||
|
|
||||||
|
textureLocation = glGetUniformLocation(program, "normalMap");
|
||||||
|
glUniform1i(textureLocation, 4);
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
|
||||||
|
|
||||||
|
draw_object(node->objectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(void) {
|
void init(void) {
|
||||||
|
@ -227,32 +264,7 @@ void init(void) {
|
||||||
|
|
||||||
//objectData = readObjFiles(&models, numModels);
|
//objectData = readObjFiles(&models, numModels);
|
||||||
char* c = "../obj/new/Window.obj";
|
char* c = "../obj/new/Window.obj";
|
||||||
objectData = readSingleObjFile(&c, 10, &numModels);
|
objectData = readSingleObjFile(&c);
|
||||||
printf("\nAmount %d\n", numModels);
|
|
||||||
fflush(stdout);
|
|
||||||
/*
|
|
||||||
objectData = malloc(numModels * sizeof(ObjectData));
|
|
||||||
for (int i = 0; i < numModels; i++) {
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &objData->vao);
|
|
||||||
glGenBuffers(1, &objData->vbo);
|
|
||||||
|
|
||||||
glBindVertexArray(objData->vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, objData->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, objData->object.numFaces * 3 * sizeof(Vertex), objData->object.vertices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(3 * sizeof(GLfloat)));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(6 * sizeof(GLfloat)));
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
objectData[i] = objData;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
stbi_set_flip_vertically_on_load(flipFlag);
|
stbi_set_flip_vertically_on_load(flipFlag);
|
||||||
// -------------- READ TEXTURE FILES
|
// -------------- READ TEXTURE FILES
|
||||||
|
@ -260,6 +272,19 @@ void init(void) {
|
||||||
loadTexture(textureFiles[i], &textures[i]);
|
loadTexture(textureFiles[i], &textures[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setNodeRenderFunction(&renderNode);
|
||||||
|
|
||||||
|
// Create the root scene node
|
||||||
|
rootNode = createSceneNode();
|
||||||
|
|
||||||
|
// Create a child node (e.g., for the model)
|
||||||
|
SceneNode* modelNode = createSceneNode();
|
||||||
|
modelNode->objectData = objectData;
|
||||||
|
addChild(rootNode, modelNode);
|
||||||
|
|
||||||
|
// Set transformations for the modelNode (example)
|
||||||
|
rotateY(&modelNode->transformation, &modelNode->transformation, pi / 4);
|
||||||
|
|
||||||
// ENABLE BACKFACE CULLING
|
// ENABLE BACKFACE CULLING
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
@ -312,7 +337,6 @@ void draw(void) {
|
||||||
vec3 origin = {0.0f, 0.0f, 0.0f};
|
vec3 origin = {0.0f, 0.0f, 0.0f};
|
||||||
vec3 up = {0.0f, 1.0f, 0.0f};
|
vec3 up = {0.0f, 1.0f, 0.0f};
|
||||||
|
|
||||||
mat4 viewingTransformation;
|
|
||||||
lookAt(&viewingTransformation, &cameraPosition, &origin, &up);
|
lookAt(&viewingTransformation, &cameraPosition, &origin, &up);
|
||||||
|
|
||||||
// -------------- PROJECTION TRANSFORMATION ----------------
|
// -------------- PROJECTION TRANSFORMATION ----------------
|
||||||
|
@ -331,75 +355,27 @@ void draw(void) {
|
||||||
multiply(&projection, &projectionTransformation, &projection);
|
multiply(&projection, &projectionTransformation, &projection);
|
||||||
multiply(&projection, &normalisationTransformation, &projection);
|
multiply(&projection, &normalisationTransformation, &projection);
|
||||||
|
|
||||||
// ------------- DRAW EACH OBJECT SEPARATELY ----------------
|
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, (GLfloat*)&projection);
|
||||||
for (int i = 0; i < numModels; i++) {
|
|
||||||
// Reset model transformation for each object
|
|
||||||
mat4 modelTransformation;
|
|
||||||
identity(&modelTransformation);
|
|
||||||
|
|
||||||
// Apply object-specific transformations
|
// SET LIGHT DATA
|
||||||
vec3 v = {
|
glUniform4f(glGetUniformLocation(program, "lightColor"), 1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
(GLfloat)i*2+objectPosition.x,
|
glUniform4f(glGetUniformLocation(program, "ambientLight"), 0.05f, 0.05f, 0.05f, 1.0f);
|
||||||
0.0f+objectPosition.y,
|
|
||||||
0.0f+objectPosition.z
|
// BIND TEXTURES
|
||||||
};
|
GLuint textureLocation;
|
||||||
translate(&modelTransformation, &modelTransformation, &v);
|
textureLocation = glGetUniformLocation(program, "textureSampler");
|
||||||
|
glUniform1i(textureLocation, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[DAY]);
|
||||||
|
|
||||||
|
textureLocation = glGetUniformLocation(program, "normalMap");
|
||||||
|
glUniform1i(textureLocation, 4);
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
|
||||||
|
|
||||||
|
|
||||||
mat4 modelView;
|
renderSceneNode(rootNode);
|
||||||
identity(&modelView);
|
|
||||||
multiply(&modelView, &modelTransformation, &modelView);
|
|
||||||
multiply(&modelView, &viewingTransformation, &modelView);
|
|
||||||
|
|
||||||
// calculate matrix for normals
|
|
||||||
mat3 normalModelView;
|
|
||||||
mat3From4(&normalModelView, &modelView);
|
|
||||||
mat3Inverse(&normalModelView, &normalModelView);
|
|
||||||
mat3Transpose(&normalModelView, &normalModelView);
|
|
||||||
|
|
||||||
// send transformation matrix to shader
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "modelView"), 1, GL_FALSE, (GLfloat*)&modelView);
|
|
||||||
glUniformMatrix3fv(glGetUniformLocation(program, "normalModelView"), 1, GL_FALSE, (GLfloat*)&normalModelView);
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, (GLfloat*)&projection);
|
|
||||||
|
|
||||||
// SET MATERIAL DATA
|
|
||||||
glUniform1f(glGetUniformLocation(program, "shininess"), 60.0f * 4.0f);
|
|
||||||
|
|
||||||
// SET LIGHT DATA
|
|
||||||
glUniform4f(glGetUniformLocation(program, "lightColor"), 1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
glUniform4f(glGetUniformLocation(program, "ambientLight"), 0.05f, 0.05f, 0.05f, 1.0f);
|
|
||||||
|
|
||||||
// BIND TEXTURES
|
|
||||||
GLuint textureLocation;
|
|
||||||
textureLocation = glGetUniformLocation(program, "day");
|
|
||||||
glUniform1i(textureLocation, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[DAY]);
|
|
||||||
|
|
||||||
textureLocation = glGetUniformLocation(program, "night");
|
|
||||||
glUniform1i(textureLocation, 1);
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[NIGHT]);
|
|
||||||
|
|
||||||
textureLocation = glGetUniformLocation(program, "clouds");
|
|
||||||
glUniform1i(textureLocation, 2);
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[CLOUDS]);
|
|
||||||
|
|
||||||
textureLocation = glGetUniformLocation(program, "ocean");
|
|
||||||
glUniform1i(textureLocation, 3);
|
|
||||||
glActiveTexture(GL_TEXTURE3);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[OCEAN]);
|
|
||||||
|
|
||||||
textureLocation = glGetUniformLocation(program, "normalMap");
|
|
||||||
glUniform1i(textureLocation, 4);
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
|
|
||||||
|
|
||||||
// draw each object separately
|
|
||||||
glBindVertexArray(objectData[i].vao);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, objectData[i].object.length * 3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
|
#include "objectHandler.h"
|
||||||
#include "wavefrontobj.h"
|
#include "wavefrontobj.h"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
typedef struct {
|
|
||||||
GLuint vao;
|
|
||||||
GLuint vbo;
|
|
||||||
ParsedObjFile object;
|
|
||||||
} ObjectData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an object.
|
* Loads an object.
|
||||||
|
@ -17,7 +13,7 @@ void load_object(ObjectData* objectData) {
|
||||||
//GLuint triangleVertexBufferObject;
|
//GLuint triangleVertexBufferObject;
|
||||||
glGenBuffers(1, &objectData->vbo);
|
glGenBuffers(1, &objectData->vbo);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, objectData->vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, objectData->vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, objectData->object.length * sizeof(face), objectData->object.faces, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, objectData->object->length * sizeof(face), objectData->object->faces, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,23 +94,19 @@ ObjectData* readObjFiles(char** path, int numModels, int* count) {
|
||||||
* Takes a single object and reads it a certain number of times.
|
* Takes a single object and reads it a certain number of times.
|
||||||
* Returns an array of objects.
|
* Returns an array of objects.
|
||||||
*/
|
*/
|
||||||
ObjectData* readSingleObjFile(char** path, int numModels, int* count) {
|
ObjectData* readSingleObjFile(char** path) {
|
||||||
ObjectData* objects = (ObjectData*) malloc(sizeof(ObjectData) * numModels);
|
ObjectData* objectData = (ObjectData*) malloc(sizeof(ObjectData));
|
||||||
*count += numModels;
|
|
||||||
|
|
||||||
if (!objects) {
|
if (!objectData) {
|
||||||
printf("ERROR in objectHandler: Failed to allocate memory for objects\n");
|
printf("ERROR in objectHandler: Failed to allocate memory for objects\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < numModels; ++i) {
|
objectData->object = readObjFile(*path);
|
||||||
objects[i].object = readObjFile(*path);
|
load_object(objectData);
|
||||||
load_object(&objects[i]);
|
|
||||||
*count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return objects;
|
return objectData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,6 +115,6 @@ ObjectData* readSingleObjFile(char** path, int numModels, int* count) {
|
||||||
*/
|
*/
|
||||||
void draw_object(ObjectData* objectData) {
|
void draw_object(ObjectData* objectData) {
|
||||||
glBindVertexArray(objectData->vao);
|
glBindVertexArray(objectData->vao);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, objectData->object.length * 3); // Annahme: Jedes face hat 3 vertices
|
glDrawArrays(GL_TRIANGLES, 0, objectData->object->length * 3); // Annahme: Jedes face hat 3 vertices
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef OBJECTHANDLER_H
|
||||||
|
#define OBJECTHANDLER_H
|
||||||
|
|
||||||
|
#include "wavefrontobj.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GLuint vao;
|
||||||
|
GLuint vbo;
|
||||||
|
ParsedObjFile* object;
|
||||||
|
} ObjectData;
|
||||||
|
|
||||||
|
extern void load_object(ObjectData* objectData);
|
||||||
|
extern ObjectData* readObjFiles(char** path, int numModels, int* count);
|
||||||
|
extern ObjectData* readSingleObjFile(char** path);
|
||||||
|
extern void draw_object(ObjectData* objectData);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,51 @@
|
||||||
|
// sceneGraph.c
|
||||||
|
|
||||||
|
#include "sceneGraph.h"
|
||||||
|
#include "objectHandler.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void (*renderFunction)(SceneNode*);
|
||||||
|
|
||||||
|
void setNodeRenderFunction(void (*newRenderFunction)(SceneNode*)) {
|
||||||
|
renderFunction = newRenderFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneNode* createSceneNode() {
|
||||||
|
SceneNode* node = (SceneNode*)malloc(sizeof(SceneNode));
|
||||||
|
identity(&node->transformation);
|
||||||
|
identity(&node->worldTransformation);
|
||||||
|
node->children = NULL;
|
||||||
|
node->numChildren = 0;
|
||||||
|
node->objectData = NULL;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addChild(SceneNode* parent, SceneNode* child) {
|
||||||
|
parent->children = (SceneNode**)realloc(parent->children, sizeof(SceneNode*) * (parent->numChildren + 1));
|
||||||
|
parent->children[parent->numChildren] = child;
|
||||||
|
parent->numChildren++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSceneNode(SceneNode* node, mat4* parentTransformation) {
|
||||||
|
multiply(&node->worldTransformation, parentTransformation, &node->transformation);
|
||||||
|
for (int i = 0; i < node->numChildren; i++) {
|
||||||
|
updateSceneNode(node->children[i], &node->worldTransformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderSceneNode(SceneNode* node) {
|
||||||
|
if (node->objectData) {
|
||||||
|
renderFunction(node);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < node->numChildren; i++) {
|
||||||
|
renderSceneNode(node->children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeSceneNode(SceneNode* node) {
|
||||||
|
for (int i = 0; i < node->numChildren; i++) {
|
||||||
|
freeSceneNode(node->children[i]);
|
||||||
|
}
|
||||||
|
free(node->children);
|
||||||
|
free(node);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// sceneGraph.h
|
||||||
|
|
||||||
|
#ifndef SCENE_GRAPH_H
|
||||||
|
#define SCENE_GRAPH_H
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "matrixMath.h"
|
||||||
|
#include "wavefrontobj.h"
|
||||||
|
#include "objectHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SceneNode SceneNode;
|
||||||
|
|
||||||
|
struct SceneNode {
|
||||||
|
mat4 transformation; // Local transformation matrix
|
||||||
|
mat4 worldTransformation; // World transformation matrix
|
||||||
|
SceneNode** children; // Array of pointers to child nodes
|
||||||
|
int numChildren; // Number of child nodes
|
||||||
|
ObjectData* objectData;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void setNodeRenderFunction(void (*newRenderFunction)(SceneNode*));
|
||||||
|
extern SceneNode* createSceneNode();
|
||||||
|
extern void addChild(SceneNode* parent, SceneNode* child);
|
||||||
|
extern void updateSceneNode(SceneNode* node, mat4* parentTransformation);
|
||||||
|
extern void renderSceneNode(SceneNode* node);
|
||||||
|
extern void freeSceneNode(SceneNode* node);
|
||||||
|
|
||||||
|
#endif
|
|
@ -71,7 +71,7 @@ void storeTB(face* f,
|
||||||
memcpy(&f->v3.tangent, &tangent, sizeof(vec3));
|
memcpy(&f->v3.tangent, &tangent, sizeof(vec3));
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedObjFile readObjFile(char* path) {
|
ParsedObjFile* readObjFile(char* path) {
|
||||||
ParsedObjFile parsedFile;
|
ParsedObjFile parsedFile;
|
||||||
|
|
||||||
FILE* fp = fopen(path, "r");
|
FILE* fp = fopen(path, "r");
|
||||||
|
@ -235,9 +235,14 @@ ParsedObjFile readObjFile(char* path) {
|
||||||
free(normals);
|
free(normals);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return parsedFile;
|
// copy parsed file into allocated memory and return pointer to it
|
||||||
|
ParsedObjFile* ptr = (ParsedObjFile*) malloc(sizeof(ParsedObjFile));
|
||||||
|
memcpy(ptr, &parsedFile, sizeof(ParsedObjFile));
|
||||||
|
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearParsedFile(ParsedObjFile file) {
|
void clearParsedFile(ParsedObjFile* file) {
|
||||||
free(file.faces);
|
free(file->faces);
|
||||||
|
free(file);
|
||||||
}
|
}
|
|
@ -23,8 +23,8 @@ typedef struct {
|
||||||
} ParsedObjFile;
|
} ParsedObjFile;
|
||||||
|
|
||||||
|
|
||||||
extern ParsedObjFile readObjFile(char* path);
|
extern ParsedObjFile* readObjFile(char* path);
|
||||||
extern void clearParsedFile(ParsedObjFile file);
|
extern void clearParsedFile(ParsedObjFile* file);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue