Add materials for diffuse + specular shading
This commit is contained in:
parent
30b36bd9f8
commit
d538ff64ec
@ -7,7 +7,7 @@ find_package(OpenGL REQUIRED)
|
||||
find_package(glfw3 REQUIRED)
|
||||
find_package(glm REQUIRED)
|
||||
|
||||
add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Events/MouseMoveEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h ECS/Components/ObjMesh.h Util/stb_setup.cpp ECS/Components/Texture.h ECS/Components/LODObjMesh.h ECS/Components/SineAnimation.h ECS/Systems/SineAnimationSystem.h ECS/Components/DirectionalLight.h)
|
||||
add_executable(ecsgame Util/glad.c Util/OBJ_Loader.h Rendering/Shader.cpp Rendering/Shader.h main.cpp ECS/Components/Transform.h ECS/Components/Movement.h ECS/Events/InputEvent.h ECS/Events/MouseMoveEvent.h ECS/Systems/GravitySystem.h ECS/Systems/PositionDebugSystem.h ECS/Systems/KeyboardMovementSystem.h ECS/Components/Camera.h ECS/Systems/RenderSystem.h ECS/Components/Mesh.h ECS/Systems/MouseLookSystem.h ECS/Components/MouseLook.h ECS/Components/ObjMesh.h Util/stb_setup.cpp ECS/Components/Texture.h ECS/Components/LODObjMesh.h ECS/Components/SineAnimation.h ECS/Systems/SineAnimationSystem.h ECS/Components/DirectionalLight.h Rendering/Material.h)
|
||||
|
||||
include_directories(${OPENGL_INCLUDE_DIRS})
|
||||
|
||||
|
14
ECS/Components/DirectionalLight.h
Normal file
14
ECS/Components/DirectionalLight.h
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by karl on 15.01.20.
|
||||
//
|
||||
|
||||
#ifndef ECSGAME_DIRECTIONALLIGHT_H
|
||||
#define ECSGAME_DIRECTIONALLIGHT_H
|
||||
|
||||
struct DirectionalLight {
|
||||
explicit DirectionalLight(const glm::vec3 &direction) : direction(direction) {}
|
||||
|
||||
glm::vec3 direction;
|
||||
};
|
||||
|
||||
#endif //ECSGAME_DIRECTIONALLIGHT_H
|
@ -10,11 +10,11 @@
|
||||
|
||||
struct ObjMesh : public Mesh {
|
||||
struct Settings {
|
||||
Settings(float minDistanceForRender, float maxDistanceForRender) : minDistanceForRender(
|
||||
minDistanceForRender), maxDistanceForRender(maxDistanceForRender) {}
|
||||
|
||||
Settings() = default;
|
||||
|
||||
Settings(float minDistanceForRender, float maxDistanceForRender, float diffuse, float specular)
|
||||
: minDistanceForRender(minDistanceForRender), maxDistanceForRender(maxDistanceForRender) {}
|
||||
|
||||
float minDistanceForRender = 0.0;
|
||||
float maxDistanceForRender = 1000.0;
|
||||
};
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "../Components/ObjMesh.h"
|
||||
#include "../Components/Texture.h"
|
||||
#include "../Components/LODObjMesh.h"
|
||||
#include "../Components/DirectionalLight.h"
|
||||
#include "../../Rendering/Material.h"
|
||||
|
||||
using namespace ECS;
|
||||
|
||||
@ -26,15 +28,22 @@ public:
|
||||
|
||||
shader.use();
|
||||
|
||||
// Lighting
|
||||
// TODO: Currently only the last light is used!
|
||||
pWorld->each<DirectionalLight>([&](Entity *ent, ComponentHandle<DirectionalLight> light) {
|
||||
shader.setVec3("lightDirection", light->direction);
|
||||
});
|
||||
|
||||
shader.setMat4("projection", camera->projection);
|
||||
shader.setMat4("view", glm::inverse(cameraTransform->matrix));
|
||||
shader.setVec3("cameraPosition", cameraTransform->getPosition());
|
||||
|
||||
std::vector<RenderObject> renderObjects;
|
||||
std::vector<RenderObject> transparentRenderObjects;
|
||||
|
||||
pWorld->each<Mesh, Transform>([&](Entity *ent, ComponentHandle<Mesh> mesh, ComponentHandle<Transform> transform) {
|
||||
/*pWorld->each<Mesh, Transform>([&](Entity *ent, ComponentHandle<Mesh> mesh, ComponentHandle<Transform> transform) {
|
||||
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), 0));
|
||||
});
|
||||
});*/
|
||||
|
||||
glm::vec3 cameraPos = cameraTransform->getPosition();
|
||||
|
||||
@ -55,26 +64,40 @@ public:
|
||||
float distance = glm::distance(cameraPos, transform->getPosition());
|
||||
|
||||
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
||||
// Get optional components
|
||||
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
||||
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
||||
|
||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||
|
||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||
if (texture->render_transparent) {
|
||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh.get(), distance));
|
||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh.get(), distance, material));
|
||||
} else {
|
||||
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh.get(), distance));
|
||||
renderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh.get(), distance, material));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// LODObjMesh with Texture
|
||||
pWorld->each<LODObjMesh, Transform, Texture>([&](Entity *ent, ComponentHandle<LODObjMesh> lodMesh, ComponentHandle<Transform> transform, ComponentHandle<Texture> texture) {
|
||||
pWorld->each<LODObjMesh, Transform>([&](Entity *ent, ComponentHandle<LODObjMesh> lodMesh, ComponentHandle<Transform> transform) {
|
||||
float distance = glm::distance(cameraPos, transform->getPosition());
|
||||
|
||||
for (const auto &mesh : lodMesh->meshes) {
|
||||
if (distance > mesh.minDistance && distance < mesh.maxDistance) {
|
||||
// Get optional components
|
||||
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
||||
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
||||
|
||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||
|
||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||
if (texture->render_transparent) {
|
||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh, distance));
|
||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh, distance, material));
|
||||
} else {
|
||||
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh, distance));
|
||||
renderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh, distance, material));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,11 +118,12 @@ public:
|
||||
}
|
||||
|
||||
struct RenderObject {
|
||||
RenderObject(const glm::mat4 &matrix, unsigned int textureId, const Mesh &mesh, float distance)
|
||||
RenderObject(const glm::mat4 &matrix, unsigned int textureId, const Mesh &mesh, float distance, const Material &material)
|
||||
: matrix(matrix),
|
||||
texture_id(textureId),
|
||||
mesh(mesh),
|
||||
distance(distance) {}
|
||||
distance(distance),
|
||||
material(material) {}
|
||||
|
||||
void render(Shader shader) const {
|
||||
shader.setMat4("model", matrix);
|
||||
@ -109,6 +133,9 @@ public:
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
}
|
||||
|
||||
shader.setFloat("diffuseStrength", material.diffuse);
|
||||
shader.setFloat("specularStrength", material.specular);
|
||||
|
||||
mesh.render();
|
||||
}
|
||||
|
||||
@ -116,6 +143,7 @@ public:
|
||||
unsigned int texture_id;
|
||||
Mesh mesh;
|
||||
float distance;
|
||||
Material material;
|
||||
};
|
||||
};
|
||||
|
||||
|
18
Rendering/Material.h
Normal file
18
Rendering/Material.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by karl on 15.01.20.
|
||||
//
|
||||
|
||||
#ifndef ECSGAME_MATERIAL_H
|
||||
#define ECSGAME_MATERIAL_H
|
||||
|
||||
struct Material {
|
||||
Material() = default;
|
||||
|
||||
Material(float diffuse, float specular) : diffuse(diffuse), specular(specular) {}
|
||||
|
||||
float diffuse = 0.8;
|
||||
|
||||
float specular = 0.2;
|
||||
};
|
||||
|
||||
#endif //ECSGAME_MATERIAL_H
|
@ -92,6 +92,11 @@ void Shader::setMat4(const std::string &name, glm::mat4 mat) const {
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(mat));
|
||||
}
|
||||
|
||||
|
||||
void Shader::setVec3(const std::string &name, glm::vec3 vec) const {
|
||||
glUniform3f(glGetUniformLocation(ID, name.c_str()), vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
void Shader::checkCompileErrors(unsigned int shader, const std::string &type) {
|
||||
int success;
|
||||
char infoLog[1024];
|
||||
|
@ -32,6 +32,9 @@ public:
|
||||
/// Set a uniform mat4 in the shader
|
||||
void setMat4(const std::string &name, glm::mat4 mat) const;
|
||||
|
||||
/// Set a uniform vec3 in the shader
|
||||
void setVec3(const std::string &name, glm::vec3 vec) const;
|
||||
|
||||
private:
|
||||
static void checkCompileErrors(unsigned int shader, const std::string &type);
|
||||
};
|
||||
|
@ -1,12 +1,10 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material.001
|
||||
Ns 225.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.157242 0.044599
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.0 0.0 0.0
|
||||
Ni 1.450000
|
||||
d 0.619318
|
||||
illum 9
|
||||
newmtl None
|
||||
Ns 500
|
||||
Ka 0.8 0.8 0.8
|
||||
Kd 0.8 0.8 0.8
|
||||
Ks 0.8 0.8 0.8
|
||||
d 1
|
||||
illum 2
|
||||
|
2049
Resources/Monkey.obj
2049
Resources/Monkey.obj
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3,8 +3,14 @@ out mediump vec4 FragColor;
|
||||
|
||||
in mediump vec2 TexCoord;
|
||||
in mediump vec3 Normal;
|
||||
in mediump vec3 FragPos;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform mediump vec3 lightDirection;
|
||||
uniform mediump vec3 cameraPosition;
|
||||
|
||||
uniform mediump float diffuseStrength;
|
||||
uniform mediump float specularStrength;
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -14,5 +20,23 @@ void main()
|
||||
if(texColor.a < 0.1)
|
||||
discard;
|
||||
|
||||
FragColor = texColor;
|
||||
// Lighting
|
||||
// Diffuse
|
||||
mediump float diff = max(dot(Normal, lightDirection), 0.0);
|
||||
|
||||
// Ambient
|
||||
mediump float ambient = 0.2;
|
||||
|
||||
// Specular
|
||||
mediump vec3 viewDir = normalize(cameraPosition - FragPos);
|
||||
mediump vec3 reflectDir = reflect(-lightDirection, Normal);
|
||||
|
||||
mediump float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
|
||||
|
||||
// Total
|
||||
mediump float light = min(diff * diffuseStrength + ambient + spec * specularStrength, 1.0);
|
||||
|
||||
// Assign resulting color
|
||||
mediump vec3 color = texColor.xyz * light;
|
||||
FragColor = vec4(color, texColor.a);
|
||||
}
|
@ -5,6 +5,7 @@ layout (location = 2) in vec2 UV;
|
||||
|
||||
out vec2 TexCoord;
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@ -15,4 +16,5 @@ void main()
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
TexCoord = UV;
|
||||
Normal = NORMAL;
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
}
|
18
main.cpp
18
main.cpp
@ -16,6 +16,7 @@
|
||||
#include "ECS/Components/Texture.h"
|
||||
#include "ECS/Components/SineAnimation.h"
|
||||
#include "ECS/Systems/SineAnimationSystem.h"
|
||||
#include "ECS/Components/DirectionalLight.h"
|
||||
|
||||
using namespace ECS;
|
||||
|
||||
@ -43,7 +44,7 @@ int main() {
|
||||
return -1;
|
||||
|
||||
/* Create a windowed mode window and its OpenGL context */
|
||||
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
|
||||
window = glfwCreateWindow(1280, 720, "Hello World", NULL, NULL);
|
||||
if (!window) {
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
@ -76,7 +77,7 @@ int main() {
|
||||
// world->registerSystem(new GravitySystem(-9.8f));
|
||||
// world->registerSystem(new PositionDebugOutputSystem());
|
||||
world->registerSystem(new KeyboardMovementSystem());
|
||||
world->registerSystem(new MouseLookSystem(640, 480));
|
||||
world->registerSystem(new MouseLookSystem(1280, 720));
|
||||
world->registerSystem(new SineAnimationSystem());
|
||||
|
||||
RenderSystem* renderSystem = new RenderSystem();
|
||||
@ -85,33 +86,38 @@ int main() {
|
||||
Entity *player = world->create();
|
||||
player->assign<Transform>();
|
||||
player->assign<Movement>(glm::vec3(2.f, 2.f, 2.f));
|
||||
player->assign<Camera>(70.0f, 640, 480, 0.1f, 100.0f);
|
||||
player->assign<Camera>(70.0f, 1280, 720, 0.1f, 100.0f);
|
||||
player->assign<MouseLook>(0.1);
|
||||
player->get<Transform>()->translate(glm::vec3(0.0f, 1.0f, 2.0f));
|
||||
|
||||
Entity *monkey = world->create();
|
||||
monkey->assign<Transform>();
|
||||
monkey->assign<LODObjMesh>(std::vector{ObjMesh("Resources/Monkey.obj", ObjMesh::Settings(0.0, 8.0)), ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0))});
|
||||
monkey->assign<LODObjMesh>(std::vector{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))});
|
||||
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<Material>(0.6, 0.6);
|
||||
monkey->get<Transform>()->translate(glm::vec3(0.0f, 2.0f, -6.0f));
|
||||
|
||||
Entity *wall1 = world->create();
|
||||
wall1->assign<Transform>();
|
||||
wall1->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||
wall1->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
||||
wall1->assign<Material>(0.2, 0.8);
|
||||
wall1->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -2.0f));
|
||||
|
||||
Entity *wall2 = world->create();
|
||||
wall2->assign<Transform>();
|
||||
wall2->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||
wall2->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
||||
wall2->assign<Material>(0.2, 0.8);
|
||||
wall2->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -10.0f));
|
||||
|
||||
Entity *wall3 = world->create();
|
||||
wall3->assign<Transform>();
|
||||
wall3->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||
wall3->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
||||
wall3->assign<Material>(0.2, 0.8);
|
||||
wall3->get<Transform>()->translate(glm::vec3(4.0f, 0.0f, -6.0f));
|
||||
wall3->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
||||
|
||||
@ -119,6 +125,7 @@ int main() {
|
||||
wall4->assign<Transform>();
|
||||
wall4->assign<ObjMesh>(ObjMesh("Resources/Wall.obj", ObjMesh::Settings()));
|
||||
wall4->assign<Texture>("Resources/Glass.png", Texture::Settings(true, true));
|
||||
wall4->assign<Material>(0.2, 0.8);
|
||||
wall4->get<Transform>()->translate(glm::vec3(-4.0f, 0.0f, -6.0f));
|
||||
wall4->get<Transform>()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0));
|
||||
|
||||
@ -128,6 +135,9 @@ int main() {
|
||||
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true, false));
|
||||
ground->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
Entity *sun = world->create();
|
||||
sun->assign<DirectionalLight>(glm::normalize(glm::vec3(1.0, 1.0, 1.0)));
|
||||
|
||||
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
|
||||
|
||||
double timeInLastFrame = glfwGetTime();
|
||||
|
Loading…
x
Reference in New Issue
Block a user