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(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})
|
||||
|
||||
|
@ -13,6 +13,8 @@ struct ObjMesh : public Mesh {
|
||||
Settings(float minDistanceForRender, float maxDistanceForRender) : minDistanceForRender(
|
||||
minDistanceForRender), maxDistanceForRender(maxDistanceForRender) {}
|
||||
|
||||
Settings() = default;
|
||||
|
||||
float minDistanceForRender = 0.0;
|
||||
float maxDistanceForRender = 1000.0;
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
void render(World *pWorld, Shader shader) {
|
||||
|
||||
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);
|
||||
|
||||
shader.use();
|
||||
@ -30,22 +30,24 @@ public:
|
||||
shader.setMat4("view", glm::inverse(cameraTransform->matrix));
|
||||
|
||||
std::vector<RenderObject> renderObjects;
|
||||
std::vector<RenderObject> transparentRenderObjects;
|
||||
|
||||
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();
|
||||
|
||||
// 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) {
|
||||
// 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());
|
||||
|
||||
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
|
||||
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());
|
||||
|
||||
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) {
|
||||
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) {
|
||||
shader.setMat4("model", obj.matrix);
|
||||
|
||||
// 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.render(shader);
|
||||
}
|
||||
|
||||
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 {
|
||||
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),
|
||||
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;
|
||||
unsigned int texture_id;
|
||||
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<Camera>(70.0f, 640, 480, 0.1f, 100.0f);
|
||||
player->assign<MouseLook>(0.1);
|
||||
player->get<Transform>()->translate(glm::vec3(0.0f, 1.0f, 2.0f));
|
||||
|
||||
Entity *box2 = world->create();
|
||||
box2->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))});
|
||||
box2->assign<Texture>("Resources/tex.png", Texture::Settings(true, true));
|
||||
box2->get<Transform>()->translate(glm::vec3(0.0f, 0.0f, -5.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<Texture>("Resources/Marble.jpg", Texture::Settings(true, false));
|
||||
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");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user