mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-21 21:35:38 +00:00
Cull geometry based on the culling distances in the nodes. Should give some sort of speedup on lower end pcs where the CPU is predominantly the bottle neck.
This commit is contained in:
parent
f31f06b42e
commit
c2b1db11f8
|
@ -473,8 +473,8 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
|||
GLfloat texWidth = (GLfloat) (32<<((P->header[3]>>3)&7));
|
||||
GLfloat texHeight = (GLfloat) (32<<((P->header[3]>>0)&7));
|
||||
TexSheet *texSheet = fmtToTexSheet[texFormat]; // get X, Y offset of texture sheet within texture map
|
||||
GLfloat texBaseX = texSheet->xOffset + GetTextureBaseX(P);
|
||||
GLfloat texBaseY = texSheet->yOffset + GetTextureBaseY(P);
|
||||
GLfloat texBaseX = (GLfloat)(texSheet->xOffset + GetTextureBaseX(P));
|
||||
GLfloat texBaseY = (GLfloat)(texSheet->yOffset + GetTextureBaseY(P));
|
||||
|
||||
/*
|
||||
* Lighting and Color Modulation:
|
||||
|
|
|
@ -4,9 +4,10 @@ namespace New3D {
|
|||
|
||||
NodeAttributes::NodeAttributes()
|
||||
{
|
||||
currentTexOffsetX = 0;
|
||||
currentTexOffsetY = 0;
|
||||
currentPage = 0;
|
||||
currentTexOffsetX = 0;
|
||||
currentTexOffsetY = 0;
|
||||
currentPage = 0;
|
||||
currentClipStatus = Clip::INTERCEPT;
|
||||
}
|
||||
|
||||
bool NodeAttributes::Push()
|
||||
|
@ -20,9 +21,10 @@ bool NodeAttributes::Push()
|
|||
return false;
|
||||
}
|
||||
|
||||
na.page = currentPage;
|
||||
na.texOffsetX = currentTexOffsetX;
|
||||
na.texOffsetY = currentTexOffsetY;
|
||||
na.page = currentPage;
|
||||
na.texOffsetX = currentTexOffsetX;
|
||||
na.texOffsetY = currentTexOffsetY;
|
||||
na.clip = currentClipStatus;
|
||||
|
||||
m_vecAttribs.push_back(na);
|
||||
|
||||
|
@ -37,9 +39,10 @@ bool NodeAttributes::Pop()
|
|||
|
||||
auto last = &m_vecAttribs.back();
|
||||
|
||||
currentPage = last->page;
|
||||
currentTexOffsetX = last->texOffsetX;
|
||||
currentTexOffsetY = last->texOffsetY;
|
||||
currentPage = last->page;
|
||||
currentTexOffsetX = last->texOffsetX;
|
||||
currentTexOffsetY = last->texOffsetY;
|
||||
currentClipStatus = last->clip;
|
||||
|
||||
m_vecAttribs.pop_back();
|
||||
|
||||
|
@ -53,9 +56,11 @@ bool NodeAttributes::StackLimit()
|
|||
|
||||
void NodeAttributes::Reset()
|
||||
{
|
||||
currentPage = 0;
|
||||
currentTexOffsetX = 0;
|
||||
currentTexOffsetY = 0;
|
||||
currentPage = 0;
|
||||
currentTexOffsetX = 0;
|
||||
currentTexOffsetY = 0;
|
||||
currentClipStatus = Clip::INTERCEPT;
|
||||
|
||||
m_vecAttribs.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ struct Viewport
|
|||
int priority;
|
||||
};
|
||||
|
||||
enum class Clip { INSIDE, OUTSIDE, INTERCEPT };
|
||||
|
||||
class NodeAttributes
|
||||
{
|
||||
public:
|
||||
|
@ -114,6 +116,7 @@ public:
|
|||
int currentTexOffsetX;
|
||||
int currentTexOffsetY;
|
||||
int currentPage;
|
||||
Clip currentClipStatus;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -122,6 +125,7 @@ private:
|
|||
int texOffsetX;
|
||||
int texOffsetY;
|
||||
int page;
|
||||
Clip clip;
|
||||
};
|
||||
std::vector<NodeAttribs> m_vecAttribs;
|
||||
};
|
||||
|
|
|
@ -342,6 +342,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
UINT32 matrixOffset, child1Ptr, sibling2Ptr;
|
||||
float x, y, z;
|
||||
int tx, ty;
|
||||
BBox bbox;
|
||||
|
||||
if (m_nodeAttribs.StackLimit()) {
|
||||
return;
|
||||
|
@ -358,8 +359,6 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
sibling2Ptr = node[0x08 - m_offset] & 0x1FFFFFF; // mask colour table bits
|
||||
matrixOffset = node[0x03 - m_offset] & 0xFFF;
|
||||
|
||||
float test = ToFloat(Convert16BitProFloat(node[9 - m_offset] >> 16));
|
||||
|
||||
if ((node[0x00] & 0x07) != 0x06) { // colour table seems to indicate no siblings
|
||||
if (!(sibling2Ptr & 0x1000000) && sibling2Ptr) {
|
||||
DescendCullingNode(sibling2Ptr); // no need to mask bit, would already be zero
|
||||
|
@ -400,24 +399,38 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
|||
// multiply matrix, if specified
|
||||
else if (matrixOffset) {
|
||||
MultMatrix(matrixOffset,m_modelMat);
|
||||
}
|
||||
}
|
||||
|
||||
// Descend down first link
|
||||
if ((node[0x00] & 0x08)) // 4-element LOD table
|
||||
{
|
||||
lodTable = TranslateCullingAddress(child1Ptr);
|
||||
if (m_nodeAttribs.currentClipStatus != Clip::INSIDE) {
|
||||
|
||||
if (NULL != lodTable) {
|
||||
if ((node[0x03 - m_offset] & 0x20000000)) {
|
||||
DescendCullingNode(lodTable[0] & 0xFFFFFF);
|
||||
}
|
||||
else {
|
||||
DrawModel(lodTable[0] & 0xFFFFFF); //TODO
|
||||
float distance = ToFloat(Convert16BitProFloat(node[9 - m_offset] & 0xFFFF));
|
||||
|
||||
CalcBox(distance, bbox);
|
||||
TransformBox(m_modelMat, bbox);
|
||||
|
||||
m_nodeAttribs.currentClipStatus = ClipBox(bbox, m_planes);
|
||||
}
|
||||
|
||||
if (m_nodeAttribs.currentClipStatus != Clip::OUTSIDE) {
|
||||
|
||||
// Descend down first link
|
||||
if ((node[0x00] & 0x08)) // 4-element LOD table
|
||||
{
|
||||
lodTable = TranslateCullingAddress(child1Ptr);
|
||||
|
||||
if (NULL != lodTable) {
|
||||
if ((node[0x03 - m_offset] & 0x20000000)) {
|
||||
DescendCullingNode(lodTable[0] & 0xFFFFFF);
|
||||
}
|
||||
else {
|
||||
DrawModel(lodTable[0] & 0xFFFFFF); //TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
DescendNodePtr(child1Ptr);
|
||||
else {
|
||||
DescendNodePtr(child1Ptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_modelMat.PopMatrix();
|
||||
|
@ -671,6 +684,9 @@ void CNew3D::RenderViewport(UINT32 addr)
|
|||
vp->projectionMatrix.Frustum(l, r, b, t, near, far);
|
||||
}
|
||||
|
||||
// calculate frustum planes
|
||||
CalcFrustumPlanes(m_planes, vp->projectionMatrix);
|
||||
|
||||
// Lighting (note that sun vector points toward sun -- away from vertex)
|
||||
vp->lightingParams[0] = *(float *)&vpnode[0x05]; // sun X
|
||||
vp->lightingParams[1] = *(float *)&vpnode[0x06]; // sun Y
|
||||
|
@ -1209,5 +1225,165 @@ float CNew3D::ToFloat(UINT32 a1)
|
|||
return *(float*)(&a1);
|
||||
}
|
||||
|
||||
void CNew3D::CalcFrustumPlanes(Plane p[6], const float* matrix)
|
||||
{
|
||||
// Left Plane
|
||||
p[0].a = matrix[3] + matrix[0];
|
||||
p[0].b = matrix[7] + matrix[4];
|
||||
p[0].c = matrix[11] + matrix[8];
|
||||
p[0].d = matrix[15] + matrix[12];
|
||||
p[0].Normalise();
|
||||
|
||||
// Right Plane
|
||||
p[1].a = matrix[3] - matrix[0];
|
||||
p[1].b = matrix[7] - matrix[4];
|
||||
p[1].c = matrix[11] - matrix[8];
|
||||
p[1].d = matrix[15] - matrix[12];
|
||||
p[1].Normalise();
|
||||
|
||||
// Bottom Plane
|
||||
p[2].a = matrix[3] + matrix[1];
|
||||
p[2].b = matrix[7] + matrix[5];
|
||||
p[2].c = matrix[11] + matrix[9];
|
||||
p[2].d = matrix[15] + matrix[13];
|
||||
p[2].Normalise();
|
||||
|
||||
// Top Plane
|
||||
p[3].a = matrix[3] - matrix[1];
|
||||
p[3].b = matrix[7] - matrix[5];
|
||||
p[3].c = matrix[11] - matrix[9];
|
||||
p[3].d = matrix[15] - matrix[13];
|
||||
p[3].Normalise();
|
||||
|
||||
// Near Plane
|
||||
p[4].a = matrix[3] + matrix[2];
|
||||
p[4].b = matrix[7] + matrix[6];
|
||||
p[4].c = matrix[11] + matrix[10];
|
||||
p[4].d = matrix[15] + matrix[14];
|
||||
p[4].Normalise();
|
||||
|
||||
// Far Plane
|
||||
p[5].a = matrix[3] - matrix[2];
|
||||
p[5].b = matrix[7] - matrix[6];
|
||||
p[5].c = matrix[11] - matrix[10];
|
||||
p[5].d = matrix[15] - matrix[14];
|
||||
p[5].Normalise();
|
||||
}
|
||||
|
||||
void CNew3D::CalcBox(float distance, BBox& box)
|
||||
{
|
||||
//bottom left front
|
||||
box.points[0][0] = -distance;
|
||||
box.points[0][1] = -distance;
|
||||
box.points[0][2] = distance;
|
||||
box.points[0][3] = 1;
|
||||
|
||||
//bottom left back
|
||||
box.points[1][0] = -distance;
|
||||
box.points[1][1] = -distance;
|
||||
box.points[1][2] = -distance;
|
||||
box.points[1][3] = 1;
|
||||
|
||||
//bottom right back
|
||||
box.points[2][0] = distance;
|
||||
box.points[2][1] = -distance;
|
||||
box.points[2][2] = -distance;
|
||||
box.points[2][3] = 1;
|
||||
|
||||
//bottom right front
|
||||
box.points[3][0] = distance;
|
||||
box.points[3][1] = -distance;
|
||||
box.points[3][2] = distance;
|
||||
box.points[3][3] = 1;
|
||||
|
||||
//top left front
|
||||
box.points[4][0] = -distance;
|
||||
box.points[4][1] = distance;
|
||||
box.points[4][2] = distance;
|
||||
box.points[4][3] = 1;
|
||||
|
||||
//top left back
|
||||
box.points[5][0] = -distance;
|
||||
box.points[5][1] = distance;
|
||||
box.points[5][2] = -distance;
|
||||
box.points[5][3] = 1;
|
||||
|
||||
//top right back
|
||||
box.points[6][0] = distance;
|
||||
box.points[6][1] = distance;
|
||||
box.points[6][2] = -distance;
|
||||
box.points[6][3] = 1;
|
||||
|
||||
//top right front
|
||||
box.points[7][0] = distance;
|
||||
box.points[7][1] = distance;
|
||||
box.points[7][2] = distance;
|
||||
box.points[7][3] = 1;
|
||||
}
|
||||
|
||||
void CNew3D::MultVec(const float matrix[16], const float in[4], float out[4])
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
out[i] =
|
||||
in[0] * matrix[0 * 4 + i] +
|
||||
in[1] * matrix[1 * 4 + i] +
|
||||
in[2] * matrix[2 * 4 + i] +
|
||||
in[3] * matrix[3 * 4 + i];
|
||||
}
|
||||
}
|
||||
|
||||
void CNew3D::TransformBox(const float *m, BBox& box)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
float v[4];
|
||||
MultVec(m, box.points[i], v);
|
||||
box.points[i][0] = v[0];
|
||||
box.points[i][1] = v[1];
|
||||
box.points[i][2] = v[2];
|
||||
}
|
||||
}
|
||||
|
||||
Clip CNew3D::ClipBox(BBox& box, Plane planes[6])
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
|
||||
int temp = 0;
|
||||
|
||||
for (int j = 0; j < 6; j++) {
|
||||
if (planes[j].DistanceToPoint(box.points[i]) >= 0) {
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp == 6) count++; // point is inside all 6 frustum planes
|
||||
}
|
||||
|
||||
if (count == 8) return Clip::INSIDE;
|
||||
if (count > 0) return Clip::INTERCEPT;
|
||||
|
||||
//if we got here all points are outside of the view frustum
|
||||
//check for all points being side same of any plane, means box outside of view
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
|
||||
int temp = 0;
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (planes[i].DistanceToPoint(box.points[j]) >= 0) {
|
||||
float distance = planes[i].DistanceToPoint(box.points[j]);
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp == 0) return Clip::OUTSIDE;
|
||||
}
|
||||
|
||||
//if we got here, box is traversing view frustum
|
||||
|
||||
return Clip::INTERCEPT;
|
||||
}
|
||||
|
||||
} // New3D
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "R3DShader.h"
|
||||
#include "VBO.h"
|
||||
#include "R3DData.h"
|
||||
#include "Plane.h"
|
||||
#include "Vec.h"
|
||||
|
||||
namespace New3D {
|
||||
|
||||
|
@ -218,6 +220,19 @@ private:
|
|||
|
||||
VBO m_vbo; // large VBO to hold our poly data, start of VBO is ROM data, ram polys follow
|
||||
R3DShader m_r3dShader;
|
||||
|
||||
Plane m_planes[6];
|
||||
|
||||
struct BBox
|
||||
{
|
||||
V4::Vec4 points[8];
|
||||
};
|
||||
|
||||
void CalcFrustumPlanes (Plane p[6], const float* matrix);
|
||||
void CalcBox (float distance, BBox& box);
|
||||
void TransformBox (const float *m, BBox& box);
|
||||
void MultVec (const float matrix[16], const float in[4], float out[4]);
|
||||
Clip ClipBox (BBox& box, Plane planes[6]);
|
||||
};
|
||||
|
||||
} // New3D
|
||||
|
|
23
Src/Graphics/New3D/Plane.h
Normal file
23
Src/Graphics/New3D/Plane.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef _PLANE_H_
|
||||
#define _PLANE_H_
|
||||
|
||||
#include <cmath>
|
||||
|
||||
struct Plane
|
||||
{
|
||||
float a, b, c, d;
|
||||
|
||||
void Normalise() {
|
||||
float temp = std::sqrt((a * a) + (b * b) + (c * c));
|
||||
a /= temp;
|
||||
b /= temp;
|
||||
c /= temp;
|
||||
d /= temp;
|
||||
}
|
||||
|
||||
float DistanceToPoint(const float v[3]) {
|
||||
return a*v[0] + b*v[1] + c*v[2] + d;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -32,6 +32,11 @@ namespace V3
|
|||
bool cmp (const Vec3 a, const Vec3 b);
|
||||
void clamp (Vec3 a, float _min, float _max);
|
||||
}
|
||||
|
||||
namespace V4
|
||||
{
|
||||
typedef float Vec4[4];
|
||||
}
|
||||
} // New3D
|
||||
|
||||
#endif
|
|
@ -535,6 +535,7 @@ xcopy /D /Y "$(ProjectDir)\SDL\$(Platform)\$(Configuration)\SDL.dll" "$(TargetDi
|
|||
<ClInclude Include="..\Src\Graphics\New3D\Mat4.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\Model.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\New3D.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\Plane.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\PolyHeader.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\R3DData.h" />
|
||||
<ClInclude Include="..\Src\Graphics\New3D\R3DShader.h" />
|
||||
|
|
|
@ -784,6 +784,9 @@
|
|||
<ClInclude Include="..\Src\Util\BMPFile.h">
|
||||
<Filter>Header Files\Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Src\Graphics\New3D\Plane.h">
|
||||
<Filter>Source Files\Graphics\New</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\Src\Debugger\ReadMe.txt">
|
||||
|
|
Loading…
Reference in a new issue