Proper transparency via sorting + new test level
This commit is contained in:
parent
be9f178780
commit
59e3132d6e
@ -7,7 +7,7 @@ find_package(OpenGL REQUIRED)
|
|||||||
find_package(glfw3 REQUIRED)
|
find_package(glfw3 REQUIRED)
|
||||||
find_package(glm 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)
|
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)
|
||||||
|
|
||||||
include_directories(${OPENGL_INCLUDE_DIRS})
|
include_directories(${OPENGL_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ struct ObjMesh : public Mesh {
|
|||||||
Settings(float minDistanceForRender, float maxDistanceForRender) : minDistanceForRender(
|
Settings(float minDistanceForRender, float maxDistanceForRender) : minDistanceForRender(
|
||||||
minDistanceForRender), maxDistanceForRender(maxDistanceForRender) {}
|
minDistanceForRender), maxDistanceForRender(maxDistanceForRender) {}
|
||||||
|
|
||||||
|
Settings() = default;
|
||||||
|
|
||||||
float minDistanceForRender = 0.0;
|
float minDistanceForRender = 0.0;
|
||||||
float maxDistanceForRender = 1000.0;
|
float maxDistanceForRender = 1000.0;
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
void render(World *pWorld, Shader shader) {
|
void render(World *pWorld, Shader shader) {
|
||||||
|
|
||||||
pWorld->each<Camera, Transform>([&](Entity *ent, ComponentHandle<Camera> camera, ComponentHandle<Transform> cameraTransform) {
|
pWorld->each<Camera, Transform>([&](Entity *ent, ComponentHandle<Camera> camera, ComponentHandle<Transform> cameraTransform) {
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.6f, 0.9f, 0.9f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
shader.use();
|
shader.use();
|
||||||
@ -30,22 +30,24 @@ public:
|
|||||||
shader.setMat4("view", glm::inverse(cameraTransform->matrix));
|
shader.setMat4("view", glm::inverse(cameraTransform->matrix));
|
||||||
|
|
||||||
std::vector<RenderObject> renderObjects;
|
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()));
|
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
glm::vec3 cameraPos = cameraTransform->getPosition();
|
glm::vec3 cameraPos = cameraTransform->getPosition();
|
||||||
|
|
||||||
// TODO: Is it possible to do get ObjMeshes in the Mesh loop above implicitly via polymorphism?
|
/*// TODO: Is it possible to do get ObjMeshes in the Mesh loop above implicitly via polymorphism?
|
||||||
|
* // TODO: Commented out because of double rendering - we only want to get objects that explicitly DON'T have a texture here!
|
||||||
pWorld->each<ObjMesh, Transform>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
pWorld->each<ObjMesh, Transform>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
||||||
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
||||||
float distance = glm::distance(cameraPos, transform->getPosition());
|
float distance = glm::distance(cameraPos, transform->getPosition());
|
||||||
|
|
||||||
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get()));
|
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), distance));
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
// ObjMesh with textures
|
// ObjMesh with textures
|
||||||
pWorld->each<ObjMesh, Transform, Texture>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform, ComponentHandle<Texture> texture) {
|
pWorld->each<ObjMesh, Transform, Texture>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform, ComponentHandle<Texture> texture) {
|
||||||
@ -53,7 +55,12 @@ public:
|
|||||||
float distance = glm::distance(cameraPos, transform->getPosition());
|
float distance = glm::distance(cameraPos, transform->getPosition());
|
||||||
|
|
||||||
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh.get()));
|
// 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));
|
||||||
|
} else {
|
||||||
|
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh.get(), distance));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -63,35 +70,52 @@ public:
|
|||||||
|
|
||||||
for (const auto &mesh : lodMesh->meshes) {
|
for (const auto &mesh : lodMesh->meshes) {
|
||||||
if (distance > mesh.minDistance && distance < mesh.maxDistance) {
|
if (distance > mesh.minDistance && distance < mesh.maxDistance) {
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh));
|
// 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));
|
||||||
|
} else {
|
||||||
|
renderObjects.emplace_back(RenderObject(transform->matrix, texture->id, mesh, distance));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Separate lists for transparent and non-transparent RenderObjects. The non-transparent list is
|
|
||||||
// rendered first, then the transparent list is sorted and rendered.
|
|
||||||
|
|
||||||
for (const RenderObject &obj : renderObjects) {
|
for (const RenderObject &obj : renderObjects) {
|
||||||
shader.setMat4("model", obj.matrix);
|
obj.render(shader);
|
||||||
|
|
||||||
// 0 can't be a valid texture name, so we use it for meshes without textures here
|
|
||||||
if (obj.texture_id != 0) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, obj.texture_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.mesh.render();
|
// Sort transparent objects and render them
|
||||||
|
std::sort(transparentRenderObjects.begin(), transparentRenderObjects.end(), [](const RenderObject &first, const RenderObject &second) -> bool {
|
||||||
|
return first.distance > second.distance;
|
||||||
|
});
|
||||||
|
for (const RenderObject &obj : transparentRenderObjects) {
|
||||||
|
obj.render(shader);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderObject {
|
struct RenderObject {
|
||||||
RenderObject(const glm::mat4 &matrix, unsigned int textureId, const Mesh &mesh) : matrix(matrix),
|
RenderObject(const glm::mat4 &matrix, unsigned int textureId, const Mesh &mesh, float distance)
|
||||||
|
: matrix(matrix),
|
||||||
texture_id(textureId),
|
texture_id(textureId),
|
||||||
mesh(mesh) {}
|
mesh(mesh),
|
||||||
|
distance(distance) {}
|
||||||
|
|
||||||
|
void render(Shader shader) const {
|
||||||
|
shader.setMat4("model", matrix);
|
||||||
|
|
||||||
|
// 0 can't be a valid texture name, so we use it for meshes without textures here
|
||||||
|
if (texture_id != 0) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.render();
|
||||||
|
}
|
||||||
|
|
||||||
glm::mat4 matrix;
|
glm::mat4 matrix;
|
||||||
unsigned int texture_id;
|
unsigned int texture_id;
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
|
float distance;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BIN
Resources/Facade01_col.jpg
Normal file
BIN
Resources/Facade01_col.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
BIN
Resources/Glass.png
Normal file
BIN
Resources/Glass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
BIN
Resources/Grass.jpg
Normal file
BIN
Resources/Grass.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 MiB |
10
Resources/Ground.mtl
Normal file
10
Resources/Ground.mtl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
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
|
16
Resources/Ground.obj
Normal file
16
Resources/Ground.obj
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Blender v2.80 (sub 75) OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib Ground.mtl
|
||||||
|
o Plane_Plane.001
|
||||||
|
v -100.000000 0.000000 100.000000
|
||||||
|
v 100.000000 0.000000 100.000000
|
||||||
|
v -100.000000 0.000000 -100.000000
|
||||||
|
v 100.000000 0.000000 -100.000000
|
||||||
|
vt -49.500000 -49.500000
|
||||||
|
vt 50.500000 -49.500000
|
||||||
|
vt 50.500000 50.500000
|
||||||
|
vt -49.500000 50.500000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
usemtl None
|
||||||
|
s off
|
||||||
|
f 1/1/1 2/2/1 4/3/1 3/4/1
|
BIN
Resources/Marble.jpg
Normal file
BIN
Resources/Marble.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 MiB |
10
Resources/Wall.mtl
Normal file
10
Resources/Wall.mtl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
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
|
16
Resources/Wall.obj
Normal file
16
Resources/Wall.obj
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Blender v2.80 (sub 75) OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib Wall.mtl
|
||||||
|
o Plane
|
||||||
|
v -4.000000 0.000000 -0.000000
|
||||||
|
v 4.000000 0.000000 -0.000000
|
||||||
|
v -4.000000 8.000000 0.000000
|
||||||
|
v 4.000000 8.000000 0.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vn 0.0000 -0.0000 1.0000
|
||||||
|
usemtl None
|
||||||
|
s off
|
||||||
|
f 1/1/1 2/2/1 4/3/1 3/4/1
|
29
main.cpp
29
main.cpp
@ -84,12 +84,31 @@ int main() {
|
|||||||
player->assign<Movement>(glm::vec3(2.f, 2.f, 2.f));
|
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, 640, 480, 0.1f, 100.0f);
|
||||||
player->assign<MouseLook>(0.1);
|
player->assign<MouseLook>(0.1);
|
||||||
|
player->get<Transform>()->translate(glm::vec3(0.0f, 1.0f, 2.0f));
|
||||||
|
|
||||||
Entity *box2 = world->create();
|
Entity *monkey = world->create();
|
||||||
box2->assign<Transform>();
|
monkey->assign<Transform>();
|
||||||
box2->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)), ObjMesh("Resources/MonkeySimple.obj", ObjMesh::Settings(8.0, 100.0))});
|
||||||
box2->assign<Texture>("Resources/tex.png", Texture::Settings(true, true));
|
monkey->assign<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
|
||||||
box2->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -5.0f));
|
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->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->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -10.0f));
|
||||||
|
|
||||||
|
Entity *ground = world->create();
|
||||||
|
ground->assign<Transform>();
|
||||||
|
ground->assign<ObjMesh>(ObjMesh("Resources/Ground.obj", ObjMesh::Settings()));
|
||||||
|
ground->assign<Texture>("Resources/Grass.jpg", Texture::Settings(true, false));
|
||||||
|
ground->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
|
Shader defaultShader("Shaders/default-vertex.vs", "Shaders/default-fragment.fs");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user