diff --git a/scene-graph.scg b/scene-graph.scg index 9ae36a3..1060df4 100644 --- a/scene-graph.scg +++ b/scene-graph.scg @@ -9,6 +9,7 @@ texture ../texture/chair/chair_texture.png model 2 file ../obj/chalkboard/Chalkboard.obj texture ../texture/chalkboard/Chalkboard.jpg +texture2 ../texture/chalkboard/text.png model 3 file ../obj/chalkboard/ChalkboardPoles.obj @@ -42,6 +43,11 @@ model 10 file ../obj/floor/Floor2.obj texture ../texture/floor/Carpet.png +model 11 +file ../obj/cube/cube.obj +texture ../texture/crate/texture.jpg +normal ../texture/crate/normal.jpg + # Reihe 1 # # Platz 1 # @@ -1676,4 +1682,11 @@ rotateX 0.0 rotateY 3.14159 rotateZ 0.0 translate 6.0 -0.8 -6.0 -parent 0 \ No newline at end of file +parent 0 + +# Normal Map Crate +obj 1000 +use 11 +name normalMapCrate +scale 0.5 0.5 0.5 +translate 3.0 0.0 3.0 \ No newline at end of file diff --git a/src/fragmentShader.glsl b/src/fragmentShader.glsl index 04acf12..8dae8b2 100644 --- a/src/fragmentShader.glsl +++ b/src/fragmentShader.glsl @@ -16,6 +16,11 @@ uniform float lightBrightness[2]; uniform vec4 lightColor; uniform sampler2D textureSampler; + +uniform bool useSecondaryTexture; +uniform bool useNormalMap; + +uniform sampler2D secondaryTexture; uniform sampler2D normalMap; @@ -25,13 +30,29 @@ float emissionStrength = 0.0; void main() { vec4 color = vec4(texture(textureSampler, textureCoordinate).rgb, 1.0); - vec3 norm = normalize(normal); + if (useSecondaryTexture) { + vec4 secondColor = texture(secondaryTexture, textureCoordinate).rgba; + color = vec4(color.rgb * (1 - secondColor.a) + secondColor.rgb * secondColor.a, min(color.a + secondColor.a, 1.0)); + } - vec3 lightDir = normalize(lightPosition - fragmentPosition); + vec3 norm; vec3 eyeDir = (-normalize(fragmentPosition)); + if (useNormalMap) { + norm = normalize((texture(normalMap, textureCoordinate).xyz * 2 - vec3(1,1,1))); + eyeDir = TBN * eyeDir; + } else { + norm = normalize(normal); + } + + float sumDiffusion = 0; + float sumSpecular = 0; + for (int i = 0; i < lightPositions.length(); i++) { vec3 lightDir = normalize(lightPositions[i] - fragmentPosition); + if (useNormalMap) { + lightDir = TBN * lightDir; + } sumDiffusion += max(dot(norm, lightDir), 0.0) * lightBrightness[i]; diff --git a/src/main.c b/src/main.c index 417d861..2dedaf7 100644 --- a/src/main.c +++ b/src/main.c @@ -99,13 +99,13 @@ void handleInputs(double deltaTime) { if (glfwGetKey(window, GLFW_KEY_J) == GLFW_PRESS) { objectPosition.x -= deltaTime * 10; } - if (glfwGetKey(window, GLFW_KEY_I) == GLFW_PRESS) { + if (glfwGetKey(window, GLFW_KEY_I) == GLFW_PRESS) { objectPosition.z += deltaTime * 10; } if (glfwGetKey(window, GLFW_KEY_K) == GLFW_PRESS) { objectPosition.z -= deltaTime * 10; } - if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { + if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { radius += deltaTime * 10; } if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) { @@ -154,10 +154,29 @@ void renderNode(SceneNode* node) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, node->model->texture); - // textureLocation = glGetUniformLocation(program, "normalMap"); - // glUniform1i(textureLocation, 4); - // glActiveTexture(GL_TEXTURE4); - // glBindTexture(GL_TEXTURE_2D, textures[NORMAL]); + if (node->model->secondaryTexture != -1) { + + glUniform1i(glGetUniformLocation(program, "useSecondaryTexture"), 1); + + glUniform1i(glGetUniformLocation(program, "secondaryTexture"), 1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, node->model->secondaryTexture); + + } else { + glUniform1i(glGetUniformLocation(program, "useSecondaryTexture"), 0); + } + + if (node->model->normalMap != -1) { + + glUniform1i(glGetUniformLocation(program, "useNormalMap"), 1); + + glUniform1i(glGetUniformLocation(program, "normalMap"), 2); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, node->model->normalMap); + + } else { + glUniform1i(glGetUniformLocation(program, "useNormalMap"), 0); + } draw_object(node->model->objectData); } diff --git a/src/sceneGraph.c b/src/sceneGraph.c index 9af49c8..0621e5f 100644 --- a/src/sceneGraph.c +++ b/src/sceneGraph.c @@ -19,6 +19,8 @@ #define KEYWORD_DEFINE_OBJ_FILE "file" #define KEYWORD_DEFINE_TEXTURE_FILE "texture" +#define KEYWORD_DEFINE_SECONDARY_TEXTURE_FILE "texture2" +#define KEYWORD_DEFINE_NORMAL_MAP_FILE "normal" #define KEYWORD_USE_MODEL "use" #define KEYWORD_DEFINE_PARENT "parent" @@ -99,7 +101,7 @@ void loadTexture(char* textureFile, GLuint* texture) { glBindTexture(GL_TEXTURE_2D, *texture); printf("%s - %d\n", textureFile, nrChannels); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, image); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, image); // load texture using previously determined format ----- ^^^^^^ glGenerateMipmap(GL_TEXTURE_2D); @@ -196,6 +198,10 @@ SceneNode* loadSceneGraphFromFile(char* path) { if (strcmp(keyword, KEYWORD_DEFINE_MODEL) == 0) { sscanf(buf, KEYWORD_DEFINE_MODEL " %d", ¤tModel); + models[currentModel].objectData = NULL; + models[currentModel].texture = -1; + models[currentModel].secondaryTexture = -1; + models[currentModel].normalMap = -1; continue; } if (strcmp(keyword, KEYWORD_DEFINE_OBJ_FILE) == 0) { @@ -208,6 +214,16 @@ SceneNode* loadSceneGraphFromFile(char* path) { loadTexture(filepathBuffer, &models[currentModel].texture); continue; } + if (strcmp(keyword, KEYWORD_DEFINE_SECONDARY_TEXTURE_FILE) == 0) { + sscanf(buf, KEYWORD_DEFINE_SECONDARY_TEXTURE_FILE " %s", filepathBuffer); + loadTexture(filepathBuffer, &models[currentModel].secondaryTexture); + continue; + } + if (strcmp(keyword, KEYWORD_DEFINE_NORMAL_MAP_FILE) == 0) { + sscanf(buf, KEYWORD_DEFINE_NORMAL_MAP_FILE " %s", filepathBuffer); + loadTexture(filepathBuffer, &models[currentModel].normalMap); + continue; + } if (strcmp(keyword, KEYWORD_DEFINE_NODE) == 0) { diff --git a/src/sceneGraph.h b/src/sceneGraph.h index 8042ed4..aeaca63 100644 --- a/src/sceneGraph.h +++ b/src/sceneGraph.h @@ -14,6 +14,8 @@ typedef struct SceneNode SceneNode; typedef struct { ObjectData* objectData; GLuint texture; + GLuint secondaryTexture; + GLuint normalMap; } Model; struct SceneNode { diff --git a/texture/chalkboard/Chalkboard.jpg b/texture/chalkboard/Chalkboard.jpg index 01c6f7a..258d40c 100644 Binary files a/texture/chalkboard/Chalkboard.jpg and b/texture/chalkboard/Chalkboard.jpg differ diff --git a/texture/chalkboard/text.png b/texture/chalkboard/text.png new file mode 100644 index 0000000..18677fa Binary files /dev/null and b/texture/chalkboard/text.png differ diff --git a/texture/crate/normal.jpg b/texture/crate/normal.jpg new file mode 100644 index 0000000..e9e5627 Binary files /dev/null and b/texture/crate/normal.jpg differ diff --git a/texture/crate/texture.jpg b/texture/crate/texture.jpg new file mode 100644 index 0000000..6dcbcef Binary files /dev/null and b/texture/crate/texture.jpg differ