mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +02:00
Minimal frustum culling implemented
This commit is contained in:
parent
f026c5ab13
commit
3e58de9f95
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -9,8 +9,6 @@ public:
|
||||
|
||||
ViewFrustum frustum;
|
||||
|
||||
glm::mat4 view;
|
||||
|
||||
ViewCamera()
|
||||
: frustum({0.1f, 5000.f, 80.f, 1.f})
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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[])
|
||||
|
Loading…
Reference in New Issue
Block a user