Add normalmap support
Tangents are not yet used, so the normals are currently only correct for the ground.
This commit is contained in:
parent
4073897f74
commit
4951ad3b04
@ -8,16 +8,22 @@
|
|||||||
#include "../../Util/stb_image.h"
|
#include "../../Util/stb_image.h"
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
|
uint id;
|
||||||
|
uint normal_id;
|
||||||
|
bool render_transparent = false;
|
||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
Settings(bool mipmaps, bool transparent) : mipmaps(mipmaps), transparent(transparent) {}
|
Settings(bool mipmaps) : mipmaps(mipmaps) {}
|
||||||
|
|
||||||
bool mipmaps = true;
|
bool mipmaps = true;
|
||||||
bool transparent = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Texture(const std::string& path, Settings settings) {
|
// Bind a texture from the given path and return its ID
|
||||||
glGenTextures(1, &id);
|
uint loadTexture(const std::string& path, Settings settings) {
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
uint gl_id;
|
||||||
|
|
||||||
|
glGenTextures(1, &gl_id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gl_id);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
@ -50,11 +56,17 @@ struct Texture {
|
|||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
render_transparent = settings.transparent;
|
return gl_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int id;
|
explicit Texture(const std::string& path, Settings settings, bool transparent) : id(loadTexture(path, settings)), render_transparent(transparent) {}
|
||||||
bool render_transparent = false;
|
|
||||||
|
void addNormalmap(const std::string& path, Settings settings) {
|
||||||
|
normal_id = loadTexture(path, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //ECSGAME_TEXTURE_H
|
#endif //ECSGAME_TEXTURE_H
|
||||||
|
@ -51,10 +51,11 @@ void renderQuad()
|
|||||||
class RenderSystem : public EntitySystem {
|
class RenderSystem : public EntitySystem {
|
||||||
public:
|
public:
|
||||||
struct RenderObject {
|
struct RenderObject {
|
||||||
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, const Mesh &mesh, float distance, const Material &material)
|
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, unsigned int normalId, const Mesh &mesh, float distance, const Material &material)
|
||||||
: matrix(matrix),
|
: matrix(matrix),
|
||||||
origin(origin),
|
origin(origin),
|
||||||
texture_id(textureId),
|
texture_id(textureId),
|
||||||
|
normal_id(normalId),
|
||||||
mesh(mesh),
|
mesh(mesh),
|
||||||
distance(distance),
|
distance(distance),
|
||||||
material(material) {}
|
material(material) {}
|
||||||
@ -69,6 +70,10 @@ public:
|
|||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
}
|
}
|
||||||
|
if (normal_id != 0) {
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, normal_id);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Not always required (not when rendering shadows) - make functions separate?
|
// TODO: Not always required (not when rendering shadows) - make functions separate?
|
||||||
shader.setFloat("diffuseStrength", material.diffuse);
|
shader.setFloat("diffuseStrength", material.diffuse);
|
||||||
@ -80,6 +85,7 @@ public:
|
|||||||
glm::mat4 matrix;
|
glm::mat4 matrix;
|
||||||
glm::vec3 origin;
|
glm::vec3 origin;
|
||||||
unsigned int texture_id;
|
unsigned int texture_id;
|
||||||
|
unsigned int normal_id;
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
float distance;
|
float distance;
|
||||||
Material material;
|
Material material;
|
||||||
@ -116,12 +122,13 @@ public:
|
|||||||
|
|
||||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||||
|
unsigned int normalID = textureComponent.isValid() ? textureComponent->normal_id : 0;
|
||||||
|
|
||||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||||
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh.get(), distance, material));
|
||||||
} else {
|
} else {
|
||||||
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh.get(), distance, material));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -138,12 +145,13 @@ public:
|
|||||||
|
|
||||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||||
|
unsigned int normalID = textureComponent.isValid() ? textureComponent->normal_id : 0;
|
||||||
|
|
||||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||||
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh, distance, material));
|
||||||
} else {
|
} else {
|
||||||
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, normalID, mesh, distance, material));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 31 MiB |
BIN
Resources/Grass_Normal.jpg
Normal file
BIN
Resources/Grass_Normal.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 MiB |
@ -8,6 +8,7 @@ in mediump vec4 FragPosLightSpace;
|
|||||||
|
|
||||||
layout(binding=0) uniform sampler2D shadowMap;
|
layout(binding=0) uniform sampler2D shadowMap;
|
||||||
layout(binding=1) uniform sampler2D tex;
|
layout(binding=1) uniform sampler2D tex;
|
||||||
|
layout(binding=2) uniform sampler2D normalmap;
|
||||||
|
|
||||||
uniform mediump vec3 lightDirection;
|
uniform mediump vec3 lightDirection;
|
||||||
uniform mediump vec3 cameraPosition;
|
uniform mediump vec3 cameraPosition;
|
||||||
@ -43,20 +44,25 @@ void main()
|
|||||||
{
|
{
|
||||||
mediump vec4 texColor = texture(tex, TexCoord);
|
mediump vec4 texColor = texture(tex, TexCoord);
|
||||||
|
|
||||||
|
// Get normal from normal map in the range [-1,1]
|
||||||
|
mediump vec3 map_normal = normalize(texture(normalmap, TexCoord).rgb * 2.0 - 1.0);
|
||||||
|
|
||||||
|
mediump vec3 final_normal = map_normal;
|
||||||
|
|
||||||
// Alpha Scissors
|
// Alpha Scissors
|
||||||
if(texColor.a < 0.1)
|
if(texColor.a < 0.1)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
// Lighting
|
// Lighting
|
||||||
// Diffuse
|
// Diffuse
|
||||||
mediump float diff = max(dot(Normal, lightDirection), 0.0);
|
mediump float diff = max(dot(final_normal, lightDirection), 0.0);
|
||||||
|
|
||||||
// Ambient
|
// Ambient
|
||||||
mediump float ambient = 0.2;
|
mediump float ambient = 0.2;
|
||||||
|
|
||||||
// Specular
|
// Specular
|
||||||
mediump vec3 viewDir = normalize(cameraPosition - FragPos);
|
mediump vec3 viewDir = normalize(cameraPosition - FragPos);
|
||||||
mediump vec3 reflectDir = reflect(-lightDirection, Normal);
|
mediump vec3 reflectDir = reflect(-lightDirection, final_normal);
|
||||||
|
|
||||||
mediump float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
|
mediump float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
|
||||||
|
|
||||||
|
19
main.cpp
19
main.cpp
@ -118,7 +118,7 @@ int main() {
|
|||||||
monkey->assign<Transform>();
|
monkey->assign<Transform>();
|
||||||
monkey->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
|
monkey->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
|
||||||
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
|
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
|
||||||
monkey->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
|
monkey->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true), false);
|
||||||
monkey->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
|
monkey->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
|
||||||
monkey->assign<Material>(0.6, 0.6);
|
monkey->assign<Material>(0.6, 0.6);
|
||||||
monkey->get<Transform>()->set_origin(glm::vec3(0.0f, 2.0f, -6.0f));
|
monkey->get<Transform>()->set_origin(glm::vec3(0.0f, 2.0f, -6.0f));
|
||||||
@ -127,7 +127,7 @@ int main() {
|
|||||||
monkey2->assign<Transform>();
|
monkey2->assign<Transform>();
|
||||||
monkey2->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
|
monkey2->assign<LODObjMesh>(std::vector<ObjMesh>{ObjMesh("Resources/Monkey.obj",ObjMesh::Settings(0.0, 8.0, 0.4, 0.6)),
|
||||||
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
|
ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0, 0.4, 0.6))});
|
||||||
monkey2->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
|
monkey2->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true), false);
|
||||||
monkey2->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
|
monkey2->assign<SineAnimation>(glm::vec3(0.0, 0.3, 0.0), 0.5);
|
||||||
monkey2->assign<Material>(0.6, 0.6);
|
monkey2->assign<Material>(0.6, 0.6);
|
||||||
monkey2->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, -20.0f));
|
monkey2->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, -20.0f));
|
||||||
@ -135,21 +135,21 @@ int main() {
|
|||||||
Entity *wall1 = world->create();
|
Entity *wall1 = world->create();
|
||||||
wall1->assign<Transform>();
|
wall1->assign<Transform>();
|
||||||
wall1->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
wall1->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||||
wall1->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
wall1->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
|
||||||
wall1->assign<Material>(0.2, 0.8);
|
wall1->assign<Material>(0.2, 0.8);
|
||||||
wall1->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -2.0f));
|
wall1->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -2.0f));
|
||||||
|
|
||||||
Entity *wall2 = world->create();
|
Entity *wall2 = world->create();
|
||||||
wall2->assign<Transform>();
|
wall2->assign<Transform>();
|
||||||
wall2->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
wall2->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||||
wall2->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
wall2->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
|
||||||
wall2->assign<Material>(0.2, 0.8);
|
wall2->assign<Material>(0.2, 0.8);
|
||||||
wall2->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -10.0f));
|
wall2->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, -10.0f));
|
||||||
|
|
||||||
Entity *wall3 = world->create();
|
Entity *wall3 = world->create();
|
||||||
wall3->assign<Transform>();
|
wall3->assign<Transform>();
|
||||||
wall3->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
wall3->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||||
wall3->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
wall3->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
|
||||||
wall3->assign<Material>(0.2, 0.8);
|
wall3->assign<Material>(0.2, 0.8);
|
||||||
wall3->get<Transform>()->set_origin(glm::vec3(4.0f, 0.0f, -6.0f));
|
wall3->get<Transform>()->set_origin(glm::vec3(4.0f, 0.0f, -6.0f));
|
||||||
wall3->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
wall3->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
||||||
@ -157,7 +157,7 @@ int main() {
|
|||||||
Entity *wall4 = world->create();
|
Entity *wall4 = world->create();
|
||||||
wall4->assign<Transform>();
|
wall4->assign<Transform>();
|
||||||
wall4->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
wall4->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||||
wall4->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
wall4->assign<Texture>("Resources/Glass.png", Texture::Settings(true), true);
|
||||||
wall4->assign<Material>(0.2, 0.8);
|
wall4->assign<Material>(0.2, 0.8);
|
||||||
wall4->get<Transform>()->set_origin(glm::vec3(-4.0f, 0.0f, -6.0f));
|
wall4->get<Transform>()->set_origin(glm::vec3(-4.0f, 0.0f, -6.0f));
|
||||||
wall4->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
wall4->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
||||||
@ -165,14 +165,15 @@ int main() {
|
|||||||
Entity *ground = world->create();
|
Entity *ground = world->create();
|
||||||
ground->assign<Transform>();
|
ground->assign<Transform>();
|
||||||
ground->assign<ObjMesh>(ObjMesh("Resources/Ground.obj", ObjMesh::Settings()));
|
ground->assign<ObjMesh>(ObjMesh("Resources/Ground.obj", ObjMesh::Settings()));
|
||||||
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true, false));
|
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true), false);
|
||||||
|
ground->get<Texture>()->addNormalmap("Resources/Grass_Normal.jpg", Texture::Settings(true));
|
||||||
ground->assign<Material>(1.0, 0.0);
|
ground->assign<Material>(1.0, 0.0);
|
||||||
ground->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, 0.0f));
|
ground->get<Transform>()->set_origin(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
Entity *bench = world->create();
|
Entity *bench = world->create();
|
||||||
bench->assign<Transform>();
|
bench->assign<Transform>();
|
||||||
bench->assign<ObjMesh>(ObjMesh("Resources/bench.obj", ObjMesh::Settings()));
|
bench->assign<ObjMesh>(ObjMesh("Resources/bench.obj", ObjMesh::Settings()));
|
||||||
bench->assign<Texture>("Resources/Wood.jpg", Texture::Settings(true, false));
|
bench->assign<Texture>("Resources/Wood.jpg", Texture::Settings(true), false);
|
||||||
bench->assign<Material>(0.8, 0.2);
|
bench->assign<Material>(0.8, 0.2);
|
||||||
bench->get<Transform>()->set_origin(glm::vec3(8.0f, 0.0f, 0.0f));
|
bench->get<Transform>()->set_origin(glm::vec3(8.0f, 0.0f, 0.0f));
|
||||||
bench->get<Transform>()->rotate(-90.0, glm::vec3(0.0, 1.0, 0.0));
|
bench->get<Transform>()->rotate(-90.0, glm::vec3(0.0, 1.0, 0.0));
|
||||||
@ -180,7 +181,7 @@ int main() {
|
|||||||
Entity *ring = world->create();
|
Entity *ring = world->create();
|
||||||
ring->assign<Transform>();
|
ring->assign<Transform>();
|
||||||
ring->assign<ObjMesh>(ObjMesh("Resources/ring.obj", ObjMesh::Settings()));
|
ring->assign<ObjMesh>(ObjMesh("Resources/ring.obj", ObjMesh::Settings()));
|
||||||
ring->assign<Texture>("Resources/Gold.jpg", Texture::Settings(true, false));
|
ring->assign<Texture>("Resources/Gold.jpg", Texture::Settings(true), false);
|
||||||
ring->assign<Material>(0.1, 0.9);
|
ring->assign<Material>(0.1, 0.9);
|
||||||
ring->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, 0.0f));
|
ring->get<Transform>()->set_origin(glm::vec3(-5.0f, 2.0f, 0.0f));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user