#More accurate bounds calculations to improve shadow resolution
and a fix for the auto-build: #define enums from EXT_framebuffer_object * clip shadow bounds to frustum * add CBrush, a class representing a convex object This was SVN commit r3695.
This commit is contained in:
parent
73506eb076
commit
0d648b2df8
@ -30,16 +30,21 @@ public:
|
||||
~CFrustum ();
|
||||
|
||||
//Set the number of planes to use for
|
||||
//calculations. This is clipped to
|
||||
//calculations. This is clipped to
|
||||
//[0,MAX_NUM_FRUSTUM_PLANES]
|
||||
void SetNumPlanes (int num);
|
||||
|
||||
uint GetNumPlanes() const { return m_NumPlanes; }
|
||||
|
||||
//The following methods return true if the shape is
|
||||
//partially or completely in front of the frustum planes
|
||||
bool IsPointVisible (const CVector3D &point) const;
|
||||
bool IsSphereVisible (const CVector3D ¢er, float radius) const;
|
||||
bool IsBoxVisible (const CVector3D &position,const CBound &bounds) const;
|
||||
|
||||
CPlane& operator[](uint idx) { return m_aPlanes[idx]; }
|
||||
const CPlane& operator[](uint idx) const { return m_aPlanes[idx]; }
|
||||
|
||||
public:
|
||||
//make the planes public for ease of use
|
||||
CPlane m_aPlanes[MAX_NUM_FRUSTUM_PLANES];
|
||||
@ -47,5 +52,5 @@ public:
|
||||
private:
|
||||
int m_NumPlanes;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,61 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Enums from EXT_framebuffer_object
|
||||
#ifndef GL_FRAMEBUFFER_EXT
|
||||
#define GL_FRAMEBUFFER_EXT 0x8D40
|
||||
#define GL_RENDERBUFFER_EXT 0x8D41
|
||||
#define GL_STENCIL_INDEX1_EXT 0x8D46
|
||||
#define GL_STENCIL_INDEX4_EXT 0x8D47
|
||||
#define GL_STENCIL_INDEX8_EXT 0x8D48
|
||||
#define GL_STENCIL_INDEX16_EXT 0x8D49
|
||||
#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
|
||||
#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
|
||||
#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
|
||||
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
|
||||
#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
|
||||
#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
|
||||
#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
|
||||
#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
|
||||
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
|
||||
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
|
||||
#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
|
||||
#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
|
||||
#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
|
||||
#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
|
||||
#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
|
||||
#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
|
||||
#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
|
||||
#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
|
||||
#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
|
||||
#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
|
||||
#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
|
||||
#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
|
||||
#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
|
||||
#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
|
||||
#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
|
||||
#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
|
||||
#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
|
||||
#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
|
||||
#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
|
||||
#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
|
||||
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
|
||||
#endif
|
||||
|
||||
//
|
||||
// extensions
|
||||
//
|
||||
@ -99,7 +154,7 @@ extern int ogl_max_tex_units; // limit on GL_TEXTUREn
|
||||
|
||||
// set detect.cpp gfx_card[] and gfx_drv_ver[].
|
||||
// (called by detect.cpp get_gfx_info()).
|
||||
//
|
||||
//
|
||||
// fails if OpenGL not ready for use.
|
||||
// gfx_card and gfx_drv_ver are unchanged on failure.
|
||||
extern LibError ogl_get_gfx_info(void);
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
#include <float.h>
|
||||
#include "Bound.h"
|
||||
#include "Frustum.h"
|
||||
#include "Brush.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator+=: extend this bound to include given bound
|
||||
@ -173,6 +176,19 @@ void CBound::Transform(const CMatrix3D& m,CBound& result) const
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Intersect with the given frustum in a conservative manner
|
||||
void CBound::IntersectFrustumConservative(const CFrustum& frustum)
|
||||
{
|
||||
CBrush brush(*this);
|
||||
CBrush buf;
|
||||
|
||||
brush.Intersect(frustum, buf);
|
||||
|
||||
buf.Bounds(*this);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Render the bounding box
|
||||
void CBound::Render()
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
class CFrustum;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CBound: basic axis aligned bounding box class
|
||||
class CBound
|
||||
@ -47,6 +49,21 @@ public:
|
||||
centre=(m_Data[0]+m_Data[1])*0.5f;
|
||||
}
|
||||
|
||||
/**
|
||||
* IntersectFrustumConservative: Approximate the intersection of this bounds object
|
||||
* with the given frustum. The bounds object is overwritten with the results.
|
||||
*
|
||||
* The approximation is conservative in the sense that the result will always contain
|
||||
* the actual intersection, but it may be larger than the intersection itself.
|
||||
* The result will always be fully contained within the original bounds.
|
||||
*
|
||||
* @note While not in the spirit of this function's purpose, a no-op would be a correct
|
||||
* implementation of this function.
|
||||
*
|
||||
* @param frustum the frustum to intersect with
|
||||
*/
|
||||
void IntersectFrustumConservative(const CFrustum& frustum);
|
||||
|
||||
/**
|
||||
* Render: Render the surfaces of the bound object as polygons.
|
||||
*/
|
||||
|
324
source/maths/Brush.cpp
Normal file
324
source/maths/Brush.cpp
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : Brush.h
|
||||
* Project : Pyrogenesis
|
||||
* Description : Implementation of CBrush, a class representing a convex object
|
||||
*
|
||||
* @author Nicolai Hähnle <nicolai@wildfiregames.com>
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ogl.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "Brush.h"
|
||||
#include "Bound.h"
|
||||
#include "Frustum.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Convert the given bounds into a brush
|
||||
CBrush::CBrush(const CBound& bounds)
|
||||
{
|
||||
m_Vertices.resize(8);
|
||||
|
||||
for(uint i = 0; i < 8; ++i)
|
||||
{
|
||||
m_Vertices[i][0] = bounds[(i & 1) ? 1 : 0][0];
|
||||
m_Vertices[i][1] = bounds[(i & 2) ? 1 : 0][1];
|
||||
m_Vertices[i][2] = bounds[(i & 4) ? 1 : 0][2];
|
||||
}
|
||||
|
||||
m_Faces.resize(30);
|
||||
|
||||
m_Faces[0] = 0; m_Faces[1] = 1; m_Faces[2] = 3; m_Faces[3] = 2; m_Faces[4] = 0; // Z = min
|
||||
m_Faces[5] = 4; m_Faces[6] = 5; m_Faces[7] = 7; m_Faces[8] = 6; m_Faces[9] = 4; // Z = max
|
||||
|
||||
m_Faces[10] = 0; m_Faces[11] = 2; m_Faces[12] = 6; m_Faces[13] = 4; m_Faces[14] = 0; // X = min
|
||||
m_Faces[15] = 1; m_Faces[16] = 3; m_Faces[17] = 7; m_Faces[18] = 5; m_Faces[19] = 1; // X = max
|
||||
|
||||
m_Faces[20] = 0; m_Faces[21] = 1; m_Faces[22] = 5; m_Faces[23] = 4; m_Faces[24] = 0; // Y = min
|
||||
m_Faces[25] = 2; m_Faces[26] = 3; m_Faces[27] = 7; m_Faces[28] = 6; m_Faces[29] = 2; // Y = max
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Calculate bounds of this brush
|
||||
void CBrush::Bounds(CBound& result) const
|
||||
{
|
||||
result.SetEmpty();
|
||||
|
||||
for(uint i = 0; i < m_Vertices.size(); ++i)
|
||||
result += m_Vertices[i];
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Cut the brush according to a given plane
|
||||
struct SliceVertexInfo {
|
||||
float d; // distance
|
||||
uint res; // index in result brush (or no_vertex if cut away)
|
||||
};
|
||||
|
||||
struct NewVertexInfo {
|
||||
uint v1, v2; // adjacent vertices in original brush
|
||||
uint res; // index in result brush
|
||||
|
||||
uint neighb1, neighb2; // index into newv
|
||||
};
|
||||
|
||||
struct SliceInfo {
|
||||
std::vector<SliceVertexInfo> v;
|
||||
std::vector<NewVertexInfo> newv;
|
||||
uint thisFaceNewVertex; // index into newv
|
||||
const CBrush* original;
|
||||
CBrush* result;
|
||||
};
|
||||
|
||||
struct CBrush::Helper
|
||||
{
|
||||
static uint SliceNewVertex(SliceInfo& si, uint v1, uint v2);
|
||||
};
|
||||
|
||||
// create a new vertex between the given two vertices (index into original brush)
|
||||
// returns the index of the new vertex in the resulting brush
|
||||
uint CBrush::Helper::SliceNewVertex(SliceInfo& si, uint v1, uint v2)
|
||||
{
|
||||
uint idx;
|
||||
|
||||
for(idx = 0; idx < si.newv.size(); ++idx)
|
||||
{
|
||||
if ((si.newv[idx].v1 == v1 && si.newv[idx].v2 == v2) ||
|
||||
(si.newv[idx].v1 == v2 && si.newv[idx].v2 == v1))
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx >= si.newv.size())
|
||||
{
|
||||
NewVertexInfo nvi;
|
||||
CVector3D newpos;
|
||||
float inv = 1.0 / (si.v[v1].d - si.v[v2].d);
|
||||
|
||||
newpos = si.original->m_Vertices[v2]*(si.v[v1].d*inv) +
|
||||
si.original->m_Vertices[v1]*(-si.v[v2].d*inv);
|
||||
|
||||
nvi.v1 = v1;
|
||||
nvi.v2 = v2;
|
||||
nvi.res = si.result->m_Vertices.size();
|
||||
nvi.neighb1 = no_vertex;
|
||||
nvi.neighb2 = no_vertex;
|
||||
si.result->m_Vertices.push_back(newpos);
|
||||
si.newv.push_back(nvi);
|
||||
}
|
||||
|
||||
if (si.thisFaceNewVertex != no_vertex)
|
||||
{
|
||||
if (si.newv[si.thisFaceNewVertex].neighb1 == no_vertex)
|
||||
si.newv[si.thisFaceNewVertex].neighb1 = idx;
|
||||
else
|
||||
si.newv[si.thisFaceNewVertex].neighb2 = idx;
|
||||
|
||||
if (si.newv[idx].neighb1 == no_vertex)
|
||||
si.newv[idx].neighb1 = si.thisFaceNewVertex;
|
||||
else
|
||||
si.newv[idx].neighb2 = si.thisFaceNewVertex;
|
||||
|
||||
si.thisFaceNewVertex = no_vertex;
|
||||
}
|
||||
else
|
||||
{
|
||||
si.thisFaceNewVertex = idx;
|
||||
}
|
||||
|
||||
return si.newv[idx].res;
|
||||
}
|
||||
|
||||
void CBrush::Slice(const CPlane& plane, CBrush& result) const
|
||||
{
|
||||
debug_assert(&result != this);
|
||||
|
||||
SliceInfo si;
|
||||
|
||||
si.original = this;
|
||||
si.result = &result;
|
||||
si.thisFaceNewVertex = no_vertex;
|
||||
si.newv.reserve(m_Vertices.size() / 2);
|
||||
|
||||
result.m_Vertices.resize(0); // clear any left-overs
|
||||
result.m_Faces.resize(0);
|
||||
result.m_Vertices.reserve(m_Vertices.size() + 2);
|
||||
result.m_Faces.reserve(m_Faces.size() + 5);
|
||||
|
||||
// Classify and copy vertices
|
||||
si.v.resize(m_Vertices.size());
|
||||
|
||||
for(uint i = 0; i < m_Vertices.size(); ++i)
|
||||
{
|
||||
si.v[i].d = plane.DistanceToPlane(m_Vertices[i]);
|
||||
if (si.v[i].d >= 0.0)
|
||||
{
|
||||
si.v[i].res = result.m_Vertices.size();
|
||||
result.m_Vertices.push_back(m_Vertices[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
si.v[i].res = no_vertex;
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer faces
|
||||
uint firstInFace = no_vertex; // in original brush
|
||||
uint startInResultFaceArray = ~0;
|
||||
|
||||
for(uint i = 0; i < m_Faces.size(); ++i)
|
||||
{
|
||||
if (firstInFace == no_vertex)
|
||||
{
|
||||
debug_assert(si.thisFaceNewVertex == no_vertex);
|
||||
|
||||
firstInFace = m_Faces[i];
|
||||
startInResultFaceArray = result.m_Faces.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
uint prev = m_Faces[i-1];
|
||||
uint cur = m_Faces[i];
|
||||
|
||||
if (si.v[prev].res == no_vertex)
|
||||
{
|
||||
if (si.v[cur].res != no_vertex)
|
||||
{
|
||||
// re-entering the front side of the plane
|
||||
result.m_Faces.push_back(Helper::SliceNewVertex(si, prev, cur));
|
||||
result.m_Faces.push_back(si.v[cur].res);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (si.v[cur].res != no_vertex)
|
||||
{
|
||||
// perfectly normal edge
|
||||
result.m_Faces.push_back(si.v[cur].res);
|
||||
}
|
||||
else
|
||||
{
|
||||
// leaving the front side of the plane
|
||||
result.m_Faces.push_back(Helper::SliceNewVertex(si, prev, cur));
|
||||
}
|
||||
}
|
||||
|
||||
if (cur == firstInFace)
|
||||
{
|
||||
if (result.m_Faces.size() > startInResultFaceArray)
|
||||
result.m_Faces.push_back(result.m_Faces[startInResultFaceArray]);
|
||||
firstInFace = no_vertex; // start a new face
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert(firstInFace == no_vertex);
|
||||
|
||||
// Create the face that lies in the slicing plane
|
||||
if (si.newv.size())
|
||||
{
|
||||
uint prev = 0;
|
||||
uint idx;
|
||||
|
||||
result.m_Faces.push_back(si.newv[0].res);
|
||||
idx = si.newv[0].neighb2;
|
||||
si.newv[0].neighb2 = no_vertex;
|
||||
|
||||
while(idx != 0)
|
||||
{
|
||||
debug_assert(idx < si.newv.size());
|
||||
|
||||
if (si.newv[idx].neighb1 == prev)
|
||||
{
|
||||
si.newv[idx].neighb1 = si.newv[idx].neighb2;
|
||||
si.newv[idx].neighb2 = no_vertex;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_assert(si.newv[idx].neighb2 == prev);
|
||||
|
||||
si.newv[idx].neighb2 = no_vertex;
|
||||
}
|
||||
|
||||
result.m_Faces.push_back(si.newv[idx].res);
|
||||
|
||||
prev = idx;
|
||||
idx = si.newv[idx].neighb1;
|
||||
si.newv[prev].neighb1 = no_vertex;
|
||||
}
|
||||
|
||||
result.m_Faces.push_back(si.newv[0].res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Intersect with frustum by repeated slicing
|
||||
void CBrush::Intersect(const CFrustum& frustum, CBrush& result) const
|
||||
{
|
||||
debug_assert(&result != this);
|
||||
|
||||
if (!frustum.GetNumPlanes())
|
||||
{
|
||||
result = *this;
|
||||
return;
|
||||
}
|
||||
|
||||
CBrush buf;
|
||||
const CBrush* prev = this;
|
||||
CBrush* next;
|
||||
|
||||
if (frustum.GetNumPlanes() & 1)
|
||||
next = &result;
|
||||
else
|
||||
next = &buf;
|
||||
|
||||
for(uint i = 0; i < frustum.GetNumPlanes(); ++i)
|
||||
{
|
||||
prev->Slice(frustum[i], *next);
|
||||
prev = next;
|
||||
if (prev == &buf)
|
||||
next = &result;
|
||||
else
|
||||
next = &buf;
|
||||
}
|
||||
|
||||
debug_assert(prev == &result);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Dump the faces to OpenGL
|
||||
void CBrush::Render() const
|
||||
{
|
||||
uint firstInFace = no_vertex;
|
||||
|
||||
for(uint i = 0; i < m_Faces.size(); ++i)
|
||||
{
|
||||
if (firstInFace == no_vertex)
|
||||
{
|
||||
glBegin(GL_POLYGON);
|
||||
firstInFace = m_Faces[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
const CVector3D& vertex = m_Vertices[m_Faces[i]];
|
||||
|
||||
glVertex3fv(&vertex.X);
|
||||
|
||||
if (firstInFace == m_Faces[i])
|
||||
{
|
||||
glEnd();
|
||||
firstInFace = no_vertex;
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert(firstInFace == no_vertex);
|
||||
}
|
||||
|
87
source/maths/Brush.h
Normal file
87
source/maths/Brush.h
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : Brush.h
|
||||
* Project : Pyrogenesis
|
||||
* Description : CBrush, a class representing a convex object
|
||||
*
|
||||
* @author Nicolai Hähnle <nicolai@wildfiregames.com>
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
#ifndef maths_brush_h
|
||||
#define maths_brush_h
|
||||
|
||||
#include "Vector3D.h"
|
||||
|
||||
class CBound;
|
||||
class CFrustum;
|
||||
class CPlane;
|
||||
|
||||
|
||||
/**
|
||||
* Class CBrush: Represents a convex object, supports some CSG operations.
|
||||
*/
|
||||
class CBrush
|
||||
{
|
||||
public:
|
||||
CBrush() { }
|
||||
|
||||
/**
|
||||
* CBrush: Construct a brush from a bounds object.
|
||||
*
|
||||
* @param bounds the CBound object to construct the brush from.
|
||||
*/
|
||||
CBrush(const CBound& bounds);
|
||||
|
||||
/**
|
||||
* IsEmpty: Returns whether the brush is empty.
|
||||
*
|
||||
* @return @c true if the brush is empty, @c false otherwise
|
||||
*/
|
||||
bool IsEmpty() const { return m_Vertices.size() == 0; }
|
||||
|
||||
/**
|
||||
* Bounds: Calculate the axis-aligned bounding box for this brush.
|
||||
*
|
||||
* @param result the resulting bounding box is stored here
|
||||
*/
|
||||
void Bounds(CBound& result) const;
|
||||
|
||||
/**
|
||||
* Slice: Cut the object along the given plane, resulting in a smaller (or even empty)
|
||||
* brush representing the part of the object that lies in front of the plane.
|
||||
*
|
||||
* @param plane the slicing plane
|
||||
* @param result the resulting brush is stored here
|
||||
*/
|
||||
void Slice(const CPlane& plane, CBrush& result) const;
|
||||
|
||||
/**
|
||||
* Intersect: Intersect the brush with the given frustum.
|
||||
*
|
||||
* @param frustum the frustum to intersect with
|
||||
* @param result the resulting brush is stored here
|
||||
*/
|
||||
void Intersect(const CFrustum& frustum, CBrush& result) const;
|
||||
|
||||
/**
|
||||
* Render: Renders the brush as OpenGL polygons.
|
||||
*
|
||||
* @note the winding of the brush faces is undefined (i.e. it is undefined which
|
||||
* sides of the faces are the front faces)
|
||||
*/
|
||||
void Render() const;
|
||||
|
||||
private:
|
||||
static const uint no_vertex = ~0;
|
||||
|
||||
typedef std::vector<CVector3D> Vertices;
|
||||
typedef std::vector<uint> FaceIndices;
|
||||
|
||||
Vertices m_Vertices;
|
||||
FaceIndices m_Faces;
|
||||
|
||||
struct Helper;
|
||||
};
|
||||
|
||||
#endif // maths_brush_h
|
@ -547,13 +547,13 @@ bool CRenderer::GetOptionBool(enum Option opt) const
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SetOptionColor: set color renderer option
|
||||
void CRenderer::SetOptionColor(enum Option opt,const RGBAColor& value)
|
||||
void CRenderer::SetOptionColor(enum Option opt,const RGBAColor& UNUSED(value))
|
||||
{
|
||||
switch (opt) {
|
||||
default:
|
||||
// switch (opt) {
|
||||
// default:
|
||||
debug_warn("CRenderer::SetOptionColor: unknown option");
|
||||
break;
|
||||
}
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
void CRenderer::SetOptionFloat(enum Option opt, float val)
|
||||
@ -575,11 +575,11 @@ const RGBAColor& CRenderer::GetOptionColor(enum Option opt) const
|
||||
{
|
||||
static const RGBAColor defaultColor(1.0f,1.0f,1.0f,1.0f);
|
||||
|
||||
switch (opt) {
|
||||
default:
|
||||
// switch (opt) {
|
||||
// default:
|
||||
debug_warn("CRenderer::GetOptionColor: unknown option");
|
||||
break;
|
||||
}
|
||||
// break;
|
||||
// }
|
||||
|
||||
return defaultColor;
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ struct ShadowMapInternals
|
||||
// bounding box of shadowed objects in light space
|
||||
CBound ShadowBound;
|
||||
|
||||
// Camera transformed into light space
|
||||
CCamera LightspaceCamera;
|
||||
|
||||
// Helper functions
|
||||
void CalcShadowMatrices();
|
||||
void CreateTexture();
|
||||
@ -144,6 +147,11 @@ void ShadowMap::SetupFrame(const CCamera& camera, const CVector3D& lightdir)
|
||||
|
||||
m->LightTransform.GetInverse(m->InvLightTransform);
|
||||
m->ShadowBound.SetEmpty();
|
||||
|
||||
//
|
||||
m->LightspaceCamera = camera;
|
||||
m->LightspaceCamera.m_Orientation = m->LightTransform * camera.m_Orientation;
|
||||
m->LightspaceCamera.UpdateFrustum();
|
||||
}
|
||||
|
||||
|
||||
@ -166,6 +174,16 @@ void ShadowMapInternals::CalcShadowMatrices()
|
||||
{
|
||||
CRenderer& renderer = g_Renderer;
|
||||
|
||||
float minZ = ShadowBound[0].Z;
|
||||
|
||||
ShadowBound.IntersectFrustumConservative(LightspaceCamera.GetFrustum());
|
||||
|
||||
// minimum Z bound must not be clipped too much, because objects that lie outside
|
||||
// the shadow bounds cannot cast shadows either
|
||||
// the 2.0 is rather arbitrary: it should be big enough so that we won't accidently miss
|
||||
// a shadow generator, and small enough not to affect Z precision
|
||||
ShadowBound[0].Z = minZ - 2.0;
|
||||
|
||||
// Setup orthogonal projection (lightspace -> clip space) for shadowmap rendering
|
||||
CVector3D scale = ShadowBound[1] - ShadowBound[0];
|
||||
CVector3D shift = (ShadowBound[1] + ShadowBound[0]) * -0.5;
|
||||
|
@ -270,7 +270,7 @@ void PolygonSortModelRenderer::DestroyModelData(CModel* UNUSED(model), void* dat
|
||||
// Prepare for one rendering pass
|
||||
void PolygonSortModelRenderer::BeginPass(uint streamflags, const CMatrix3D* UNUSED(texturematrix))
|
||||
{
|
||||
debug_assert(streamflags == streamflags & (STREAM_POS|STREAM_COLOR|STREAM_UV0));
|
||||
debug_assert(streamflags == (streamflags & (STREAM_POS|STREAM_COLOR|STREAM_UV0)));
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user