Advancec Frustum Culling & fixes
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "../objects/Player.h"
|
||||
#include "../assets/Assets.h"
|
||||
#include "../objects/player_control.h"
|
||||
#include "../maths/FrustumCulling.h"
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
@@ -28,6 +29,7 @@ WorldRenderer::WorldRenderer(Level* level, Assets* assets) : assets(assets), lev
|
||||
lineBatch = new LineBatch(4096);
|
||||
batch3d = new Batch3D(1024);
|
||||
renderer = new ChunksRenderer(level);
|
||||
frustumCulling = new Frustum();
|
||||
level->events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||
renderer->unload(chunk);
|
||||
});
|
||||
@@ -37,6 +39,7 @@ WorldRenderer::~WorldRenderer() {
|
||||
delete batch3d;
|
||||
delete lineBatch;
|
||||
delete renderer;
|
||||
delete frustumCulling;
|
||||
}
|
||||
|
||||
bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
||||
@@ -49,22 +52,15 @@ bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool
|
||||
|
||||
// Simple frustum culling
|
||||
if (occlusion){
|
||||
float y = camera->position.y+camera->front.y * CHUNK_H * 0.5f;
|
||||
if (y < 0.0f)
|
||||
y = 0.0f;
|
||||
if (y > CHUNK_H)
|
||||
y = CHUNK_H;
|
||||
vec3 v = vec3(chunk->x*CHUNK_W, y, chunk->z*CHUNK_D)-camera->position;
|
||||
if (v.x*v.x+v.z*v.z > (CHUNK_W*3)*(CHUNK_W*3)) {
|
||||
if (dot(camera->front, v) < 0.0f){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
glm::vec3 min = glm::vec3(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D);
|
||||
glm::vec3 max = glm::vec3(chunk->x * CHUNK_W + CHUNK_W, chunk->top, chunk->z * CHUNK_D + CHUNK_D);
|
||||
|
||||
if (!frustumCulling->IsBoxVisible(min, max)) return false;
|
||||
}
|
||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1));
|
||||
shader->uniformMatrix("u_model", model);
|
||||
mesh->draw(GL_TRIANGLES);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,10 +116,10 @@ void WorldRenderer::draw(Camera* camera, bool occlusion, float fogFactor, float
|
||||
(b->x + 0.5f - px)*(b->x + 0.5f - px) + (b->z + 0.5f - pz)*(b->z + 0.5f - pz));
|
||||
});
|
||||
|
||||
|
||||
int occludedChunks = 0;
|
||||
frustumCulling->update(camera->getProjection() * camera->getView());
|
||||
chunks->visible = 0;
|
||||
for (size_t i = 0; i < indices.size(); i++){
|
||||
occludedChunks += drawChunk(indices[i], camera, shader, occlusion);
|
||||
chunks->visible += drawChunk(indices[i], camera, shader, occlusion);
|
||||
}
|
||||
|
||||
shader->uniformMatrix("u_model", mat4(1.0f));
|
||||
@@ -146,39 +142,26 @@ void WorldRenderer::draw(Camera* camera, bool occlusion, float fogFactor, float
|
||||
}
|
||||
|
||||
if (level->player->debug) {
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||
float lenght = 40.f;
|
||||
|
||||
vec3 point = vec3(camera->position.x+camera->front.x,
|
||||
camera->position.y+camera->front.y,
|
||||
camera->position.z+camera->front.z);
|
||||
linesShader->use();
|
||||
glm::mat4 model(1.0f);
|
||||
model = glm::translate(model, glm::vec3(Window::width >> 1, -static_cast<int>(Window::height) >> 1, 0.f));
|
||||
linesShader->uniformMatrix("u_projview", glm::ortho(0.f, static_cast<float>(Window::width), -static_cast<float>(Window::height), 0.f, -lenght, lenght) * model * glm::inverse(camera->rotation));
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glLineWidth(4.0f);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x+0.1f, point.y, point.z,
|
||||
0, 0, 0, 1);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x, point.y, point.z+0.1f,
|
||||
0, 0, 0, 1);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x, point.y+0.1f, point.z,
|
||||
0, 0, 0, 1);
|
||||
lineBatch->line(0.f, 0.f, 0.f, lenght, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
lineBatch->line(0.f, 0.f, 0.f, 0.f, lenght, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||
lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, lenght, 0.f, 0.f, 0.f, 1.f);
|
||||
lineBatch->render();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glLineWidth(2.0f);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x+0.1f, point.y, point.z,
|
||||
1, 0, 0, 1);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x, point.y, point.z+0.1f,
|
||||
0, 0, 1, 1);
|
||||
lineBatch->line(point.x, point.y, point.z,
|
||||
point.x, point.y+0.1f, point.z,
|
||||
0, 1, 0, 1);
|
||||
lineBatch->line(0.f, 0.f, 0.f, lenght, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f);
|
||||
lineBatch->line(0.f, 0.f, 0.f, 0.f, lenght, 0.f, 0.f, 1.f, 0.f, 1.f);
|
||||
lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, lenght, 0.f, 0.f, 1.f, 1.f);
|
||||
lineBatch->render();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user