Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
#5338: Move View class to libs/render, to be shared across modules.
  • Loading branch information
codereader committed Sep 26, 2020
1 parent 87eab98 commit 2d13193
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 281 deletions.
220 changes: 220 additions & 0 deletions libs/render/View.h
@@ -0,0 +1,220 @@
#pragma once

#include "ivolumetest.h"

#include "math/Frustum.h"
#include "math/ViewProjection.h"
#include "math/Viewer.h"

#if defined(_DEBUG)
#define DEBUG_CULLING
#endif

#ifdef DEBUG_CULLING
#include <fmt/format.h>

#define INC_COUNTER(x) (++(const_cast<View*>(this)->x))
#else
#define INC_COUNTER(x)
#endif

namespace render
{

/// \brief View-volume culling and transformations.
class View :
public VolumeTest
{
private:
/// modelview matrix
Matrix4 _modelview;

/// projection matrix
Matrix4 _projection;

/// device-to-screen transform
Matrix4 _viewport;

Matrix4 _scissor;

/// combined modelview and projection matrix
ViewProjection _viewproj;

/// camera position in world space
Viewer _viewer;

/// view frustum in world space
Frustum _frustum;

bool _fill;

#ifdef DEBUG_CULLING
int _count_planes;
int _count_oriented_planes;
int _count_bboxs;
int _count_oriented_bboxs;
#endif

public:
View(bool fill = false) :
_modelview(Matrix4::getIdentity()),
_projection(Matrix4::getIdentity()),
_scissor(Matrix4::getIdentity()),
_fill(fill)
{}

View(const View& other) = default;

View(const VolumeTest& other) :
_modelview(other.GetModelview()),
_projection(other.GetProjection()),
_viewport(other.GetViewport()),
_scissor(Matrix4::getIdentity()),
_fill(other.fill())
{
// calculate _viewproj, _viewer and _frustum
construct();
}

void Construct(const Matrix4& projection, const Matrix4& modelview, std::size_t width, std::size_t height)
{
// modelview
_modelview = modelview;

// projection
_projection = projection;

// viewport
_viewport = Matrix4::getIdentity();
_viewport[0] = float(width / 2);
_viewport[5] = float(height / 2);
if (fabs(_projection[11]) > 0.0000001)
_viewport[10] = _projection[0] * _viewport[0];
else
_viewport[10] = 1 / _projection[10];

construct();
}

void EnableScissor(float min_x, float max_x, float min_y, float max_y)
{
_scissor = Matrix4::getIdentity();
_scissor[0] = (max_x - min_x) * 0.5f;
_scissor[5] = (max_y - min_y) * 0.5f;
_scissor[12] = (min_x + max_x) * 0.5f;
_scissor[13] = (min_y + max_y) * 0.5f;
_scissor.invertFull();

construct();
}

void DisableScissor()
{
_scissor = Matrix4::getIdentity();

construct();
}

bool TestPoint(const Vector3& point) const override
{
return _viewproj.testPoint(point);
}

bool TestLine(const Segment& segment) const override
{
return _frustum.testLine(segment);
}

bool TestPlane(const Plane3& plane) const override
{
INC_COUNTER(_count_planes);
return _viewer.testPlane(plane);
}

bool TestPlane(const Plane3& plane, const Matrix4& localToWorld) const override
{
INC_COUNTER(_count_oriented_planes);
return _viewer.testPlane(plane, localToWorld);
}

VolumeIntersectionValue TestAABB(const AABB& aabb) const override
{
INC_COUNTER(_count_bboxs);
return _frustum.testIntersection(aabb);
}

VolumeIntersectionValue TestAABB(const AABB& aabb, const Matrix4& localToWorld) const override
{
INC_COUNTER(_count_oriented_bboxs);
return _frustum.testIntersection(aabb, localToWorld);
}

const Matrix4& GetViewProjection() const override
{
return _viewproj;
}

const Matrix4& GetViewport() const override
{
return _viewport;
}

const Matrix4& GetModelview() const override
{
return _modelview;
}

const Matrix4& GetProjection() const override
{
return _projection;
}

bool fill() const override
{
return _fill;
}

const Vector3& getViewer() const
{
return _viewer.getVector3();
}

const Frustum& getFrustum() const
{
return _frustum;
}

std::string getCullStats() const
{
std::string stats;

#if defined(DEBUG_CULLING)
stats = fmt::format("planes {0:d} + {1:d} | bboxs {2:d} + {3:d}",
_count_planes, _count_oriented_planes,
_count_bboxs, _count_oriented_bboxs);
#endif

return stats;
}

void resetCullStats()
{
#if defined(DEBUG_CULLING)
_count_planes = 0;
_count_oriented_planes = 0;
_count_bboxs = 0;
_count_oriented_bboxs = 0;
#endif
}

private:
void construct()
{
_viewproj = _scissor.getMultipliedBy(_projection).getMultipliedBy(_modelview);

_frustum = Frustum::createFromViewproj(_viewproj);
_viewer = Viewer::createFromViewProjection(_viewproj);
}
};

} // namespace
1 change: 0 additions & 1 deletion radiant/Makefile.am
Expand Up @@ -56,7 +56,6 @@ darkradiant_SOURCES = main.cpp \
eventmanager/Toggle.cpp \
eventmanager/WidgetToggle.cpp \
render/OpenGLModule.cpp \
render/View.cpp \
ui/UserInterfaceModule.cpp \
ui/Documentation.cpp \
ui/entitychooser/EntityClassChooser.cpp \
Expand Down
4 changes: 2 additions & 2 deletions radiant/camera/CamWnd.cpp
Expand Up @@ -649,7 +649,7 @@ void CamWnd::Cam_Draw()

render::RenderStatistics::Instance().resetStats();

render::View::resetCullStats();
_view.resetCullStats();

glMatrixMode(GL_PROJECTION);
glLoadMatrixd(_camera.getProjection());
Expand Down Expand Up @@ -824,7 +824,7 @@ void CamWnd::Cam_Draw()

glRasterPos3f(1.0f, static_cast<float>(height) - 11.0f, 0.0f);

GlobalOpenGL().drawString(render::View::getCullStats());
GlobalOpenGL().drawString(_view.getCullStats());

drawTime();

Expand Down

0 comments on commit 2d13193

Please sign in to comment.