multiple textures and normal maps

This commit is contained in:
Luca Conte 2024-06-24 15:06:02 +02:00
parent abffb2fe7c
commit 2124eb1d68
9 changed files with 81 additions and 10 deletions

View File

@ -9,6 +9,7 @@ texture ../texture/chair/chair_texture.png
model 2 model 2
file ../obj/chalkboard/Chalkboard.obj file ../obj/chalkboard/Chalkboard.obj
texture ../texture/chalkboard/Chalkboard.jpg texture ../texture/chalkboard/Chalkboard.jpg
texture2 ../texture/chalkboard/text.png
model 3 model 3
file ../obj/chalkboard/ChalkboardPoles.obj file ../obj/chalkboard/ChalkboardPoles.obj
@ -42,6 +43,11 @@ model 10
file ../obj/floor/Floor2.obj file ../obj/floor/Floor2.obj
texture ../texture/floor/Carpet.png texture ../texture/floor/Carpet.png
model 11
file ../obj/cube/cube.obj
texture ../texture/crate/texture.jpg
normal ../texture/crate/normal.jpg
# Reihe 1 # # Reihe 1 #
# Platz 1 # # Platz 1 #
@ -1677,3 +1683,10 @@ rotateY 3.14159
rotateZ 0.0 rotateZ 0.0
translate 6.0 -0.8 -6.0 translate 6.0 -0.8 -6.0
parent 0 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

View File

@ -16,6 +16,11 @@ uniform float lightBrightness[2];
uniform vec4 lightColor; uniform vec4 lightColor;
uniform sampler2D textureSampler; uniform sampler2D textureSampler;
uniform bool useSecondaryTexture;
uniform bool useNormalMap;
uniform sampler2D secondaryTexture;
uniform sampler2D normalMap; uniform sampler2D normalMap;
@ -25,13 +30,29 @@ float emissionStrength = 0.0;
void main() { void main() {
vec4 color = vec4(texture(textureSampler, textureCoordinate).rgb, 1.0); 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)); 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++) { for (int i = 0; i < lightPositions.length(); i++) {
vec3 lightDir = normalize(lightPositions[i] - fragmentPosition); vec3 lightDir = normalize(lightPositions[i] - fragmentPosition);
if (useNormalMap) {
lightDir = TBN * lightDir;
}
sumDiffusion += max(dot(norm, lightDir), 0.0) * lightBrightness[i]; sumDiffusion += max(dot(norm, lightDir), 0.0) * lightBrightness[i];

View File

@ -99,13 +99,13 @@ void handleInputs(double deltaTime) {
if (glfwGetKey(window, GLFW_KEY_J) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_J) == GLFW_PRESS) {
objectPosition.x -= deltaTime * 10; objectPosition.x -= deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_I) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_I) == GLFW_PRESS) {
objectPosition.z += deltaTime * 10; objectPosition.z += deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_K) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_K) == GLFW_PRESS) {
objectPosition.z -= deltaTime * 10; objectPosition.z -= deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
radius += deltaTime * 10; radius += deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) {
@ -154,10 +154,29 @@ void renderNode(SceneNode* node) {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, node->model->texture); glBindTexture(GL_TEXTURE_2D, node->model->texture);
// textureLocation = glGetUniformLocation(program, "normalMap"); if (node->model->secondaryTexture != -1) {
// glUniform1i(textureLocation, 4);
// glActiveTexture(GL_TEXTURE4); glUniform1i(glGetUniformLocation(program, "useSecondaryTexture"), 1);
// glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
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); draw_object(node->model->objectData);
} }

View File

@ -19,6 +19,8 @@
#define KEYWORD_DEFINE_OBJ_FILE "file" #define KEYWORD_DEFINE_OBJ_FILE "file"
#define KEYWORD_DEFINE_TEXTURE_FILE "texture" #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_USE_MODEL "use"
#define KEYWORD_DEFINE_PARENT "parent" #define KEYWORD_DEFINE_PARENT "parent"
@ -99,7 +101,7 @@ void loadTexture(char* textureFile, GLuint* texture) {
glBindTexture(GL_TEXTURE_2D, *texture); glBindTexture(GL_TEXTURE_2D, *texture);
printf("%s - %d\n", textureFile, nrChannels); 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 ----- ^^^^^^ // load texture using previously determined format ----- ^^^^^^
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
@ -196,6 +198,10 @@ SceneNode* loadSceneGraphFromFile(char* path) {
if (strcmp(keyword, KEYWORD_DEFINE_MODEL) == 0) { if (strcmp(keyword, KEYWORD_DEFINE_MODEL) == 0) {
sscanf(buf, KEYWORD_DEFINE_MODEL " %d", &currentModel); sscanf(buf, KEYWORD_DEFINE_MODEL " %d", &currentModel);
models[currentModel].objectData = NULL;
models[currentModel].texture = -1;
models[currentModel].secondaryTexture = -1;
models[currentModel].normalMap = -1;
continue; continue;
} }
if (strcmp(keyword, KEYWORD_DEFINE_OBJ_FILE) == 0) { if (strcmp(keyword, KEYWORD_DEFINE_OBJ_FILE) == 0) {
@ -208,6 +214,16 @@ SceneNode* loadSceneGraphFromFile(char* path) {
loadTexture(filepathBuffer, &models[currentModel].texture); loadTexture(filepathBuffer, &models[currentModel].texture);
continue; 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) { if (strcmp(keyword, KEYWORD_DEFINE_NODE) == 0) {

View File

@ -14,6 +14,8 @@ typedef struct SceneNode SceneNode;
typedef struct { typedef struct {
ObjectData* objectData; ObjectData* objectData;
GLuint texture; GLuint texture;
GLuint secondaryTexture;
GLuint normalMap;
} Model; } Model;
struct SceneNode { struct SceneNode {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
texture/chalkboard/text.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
texture/crate/normal.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
texture/crate/texture.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB