1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 06:52:34 +02:00

Minimal frustum culling implemented

This commit is contained in:
Daniel Evans 2013-07-02 09:58:01 +01:00
parent f026c5ab13
commit 3e58de9f95
6 changed files with 43 additions and 20 deletions

View File

@ -1,6 +1,7 @@
#ifndef _RWBINARYSTREAM_H_
#define _RWBINARYSTREAM_H_
#include "gtfwpre.h"
#include <glm/glm.hpp>
#include <cstddef>
#include <cassert>
@ -41,10 +42,7 @@ namespace RW
/**
* Vector data
*/
struct BSTVector3
{
float x, y, z;
};
typedef glm::vec3 BSTVector3;
/**
* Rotation Matrix

View File

@ -75,34 +75,47 @@ GTARenderer::GTARenderer()
void GTARenderer::renderWorld(GTAEngine* engine)
{
glm::mat4 proj = camera.frustum.projection();
glm::mat4 view = camera.view;
glm::mat4 view = camera.frustum.view;
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
camera.frustum.update();
camera.frustum.update(camera.frustum.projection() * view);
rendered = culled = 0;
auto& textureLoader = engine->gameData.textureLoader;
for (size_t i = 0; i < engine->instances.size(); ++i) {
auto &obj = engine->instances[i];
LoaderIPLInstance &obj = engine->instances[i];
std::string modelname = obj.model;
if (modelname.substr(0, 3) == "LOD")
continue;
auto &model = engine->gameData.models[modelname];
// std::cout << "Rendering " << modelname << std::endl;
std::unique_ptr<Model> &model = engine->gameData.models[modelname];
glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ);
glm::vec3 pos(obj.posX, obj.posY, obj.posZ);
glm::vec3 scale(obj.scaleX, obj.scaleY, obj.scaleZ);
if(!model)
{
std::cout << "model " << modelname << " not there (" << engine->gameData.models.size() << " models loaded)" << std::endl;
}
for (size_t g = 0; g < model->geometries.size(); g++) {
for (size_t g = 0; g < model->geometries.size(); g++)
{
RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds;
if(! camera.frustum.intersects(bounds.center + pos, bounds.radius)) {
culled++;
continue;
}
else {
rendered++;
}
// This is a hack I have no idea why negating the quaternion fixes the issue but it does.
glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ);
glm::mat4 matrixModel;
matrixModel = glm::translate(matrixModel, glm::vec3(obj.posX, obj.posY, obj.posZ));
matrixModel = glm::scale(matrixModel, glm::vec3(obj.scaleX, obj.scaleY, obj.scaleZ));
matrixModel = glm::translate(matrixModel, pos);
matrixModel = glm::scale(matrixModel, scale);
matrixModel = matrixModel * glm::mat4_cast(rot);
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(matrixModel));

View File

@ -11,6 +11,10 @@ public:
ViewCamera camera;
/// The numer of things rendered by the last renderWorld
size_t rendered;
size_t culled;
void renderWorld(GTAEngine* engine);
};

View File

@ -9,8 +9,6 @@ public:
ViewFrustum frustum;
glm::mat4 view;
ViewCamera()
: frustum({0.1f, 5000.f, 80.f, 1.f})
{

View File

@ -19,6 +19,8 @@ public:
float fov;
float aspectRatio;
glm::mat4 view;
ViewPlane planes[6];
ViewFrustum(float near, float far, float fov, float aspect)
@ -32,9 +34,8 @@ public:
return glm::perspective(fov, aspectRatio, near, far);
}
void update()
void update(const glm::mat4& proj)
{
auto proj = projection();
for(size_t i = 0; i < 6; ++i)
{
float sign = (i%2==0) ? 1.f : -1.f;
@ -56,7 +57,7 @@ public:
for(size_t i = 0; i < 6; ++i)
{
d = glm::dot(planes[i].normal, center) + planes[i].distance;
if( -d < radius ) return false;
if( d < -radius ) return false;
}
return true;
}

View File

@ -106,7 +106,7 @@ void update()
view = glm::translate(view, -plyPos);
gta->renderer.camera.view = view;
gta->renderer.camera.frustum.view = view;
i++;
}
@ -117,8 +117,17 @@ void render()
// Update aspect ratio..
gta->renderer.camera.frustum.aspectRatio = window.getSize().x / (float) window.getSize().y;
glEnable(GL_CULL_FACE);
gta->renderer.renderWorld(gta);
static size_t fc = 0;
if(fc++ == 60)
{
std::cout << "Rendered: " << gta->renderer.rendered << " / Culled: " << gta->renderer.culled << std::endl;
fc = 0;
}
}
int main(int argc, char *argv[])