Skip to content

Commit adba82e

Browse files
committed
Main: use 4D position buffer for stencil shadows
instead of splitting W into separate buffer. Works on D3D9 as well for me. Adapt support code to work with 4D positions.
1 parent 1a38f7e commit adba82e

22 files changed

+143
-295
lines changed

Components/MeshLodGenerator/include/OgreLod0Stripifier.h

-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ namespace Ogre
207207
vertexData->vertexStart = 0;
208208
vertexData->vertexCount = remapInfo.usedCount;
209209

210-
vertexData->hardwareShadowVolWBuffer = HardwareVertexBufferSharedPtr(); // TODO: check this
211210
vertexData->hwAnimationDataList.clear(); // TODO: check this
212211
vertexData->hwAnimDataItemsUsed = 0; // TODO: check this
213212
}

Media/Main/ShadowExtrudeDirLight.vert

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ uniform mat4 worldviewproj_matrix;
55
uniform vec4 light_position_object_space; // homogenous, object space
66

77
MAIN_PARAMETERS
8-
IN(vec4 uv0, TEXCOORD0)
98
IN(vec4 position, POSITION)
109
MAIN_DECLARATION
1110
{
1211
// Extrusion in object space
1312
// Vertex unmodified if w==1, extruded if w==0
1413
vec4 newpos =
15-
(uv0.xxxx * (position + light_position_object_space)) - light_position_object_space;
14+
(position.wwww * (position + light_position_object_space)) - light_position_object_space;
1615

1716
gl_Position = mul(worldviewproj_matrix, newpos);
1817
}

Media/Main/ShadowExtrudeDirLightFinite.vert

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ uniform vec4 light_position_object_space; // homogenous, object space
66
uniform float shadow_extrusion_distance; // how far to extrude
77

88
MAIN_PARAMETERS
9-
IN(vec4 uv0, TEXCOORD0)
109
IN(vec4 position, POSITION)
1110
MAIN_DECLARATION
1211
{
@@ -16,7 +15,7 @@ MAIN_DECLARATION
1615
extrusionDir = normalize(extrusionDir);
1716

1817
vec4 newpos = vec4(position.xyz +
19-
((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);
18+
((1.0 - position.w) * shadow_extrusion_distance * extrusionDir), 1.0);
2019

2120
gl_Position = mul(worldviewproj_matrix, newpos);
2221
}

Media/Main/ShadowExtrudePointLight.vert

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ uniform mat4 worldviewproj_matrix;
55
uniform vec4 light_position_object_space; // homogenous, object space
66

77
MAIN_PARAMETERS
8-
IN(vec4 uv0, TEXCOORD0)
98
IN(vec4 position, POSITION)
109
MAIN_DECLARATION
1110
{
1211
// Extrusion in object space
1312
// Vertex unmodified if w==1, extruded if w==0
1413
vec4 newpos =
15-
(uv0.xxxx * light_position_object_space) +
14+
(position.wwww * light_position_object_space) +
1615
vec4(position.xyz - light_position_object_space.xyz, 0.0);
1716

1817
gl_Position = mul(worldviewproj_matrix, newpos);

Media/Main/ShadowExtrudePointLightFinite.vert

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ uniform vec4 light_position_object_space; // homogenous, object space
66
uniform float shadow_extrusion_distance; // how far to extrude
77

88
MAIN_PARAMETERS
9-
IN(vec4 uv0, TEXCOORD0)
109
IN(vec4 position, POSITION)
1110
MAIN_DECLARATION
1211
{
@@ -16,7 +15,7 @@ MAIN_DECLARATION
1615
extrusionDir = normalize(extrusionDir);
1716

1817
vec4 newpos = vec4(position.xyz +
19-
((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);
18+
((1.0 - position.w) * shadow_extrusion_distance * extrusionDir), 1.0);
2019

2120
gl_Position = mul(worldviewproj_matrix, newpos);
2221
}

OgreMain/include/OgreEntity.h

-3
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,6 @@ namespace Ogre {
324324
Entity* mParent;
325325
/// Shared link to position buffer.
326326
HardwareVertexBufferSharedPtr mPositionBuffer;
327-
/// Shared link to w-coord buffer (optional).
328-
HardwareVertexBufferSharedPtr mWBuffer;
329327
/// Link to current vertex data used to bind (maybe changes).
330328
const VertexData* mCurrentVertexData;
331329
/// Link to SubEntity, only present if SubEntity has it's own geometry.
@@ -343,7 +341,6 @@ namespace Ogre {
343341
void _createSeparateLightCap();
344342
void getWorldTransforms(Matrix4* xform) const override;
345343
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
346-
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
347344
/// Rebind the source positions (for temp buffer users).
348345
void rebindPositionBuffer(const VertexData* vertexData, bool force);
349346
bool isVisible(void) const override;

OgreMain/include/OgreManualObject.h

-3
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,6 @@ namespace Ogre
623623
ManualObject* mParent;
624624
// Shared link to position buffer
625625
HardwareVertexBufferSharedPtr mPositionBuffer;
626-
// Shared link to w-coord buffer (optional)
627-
HardwareVertexBufferSharedPtr mWBuffer;
628626

629627
public:
630628
ManualObjectSectionShadowRenderable(ManualObject* parent,
@@ -633,7 +631,6 @@ namespace Ogre
633631
~ManualObjectSectionShadowRenderable();
634632
void getWorldTransforms(Matrix4* xform) const override;
635633
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
636-
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
637634
virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) override;
638635

639636

OgreMain/include/OgreOptimisedUtil.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,14 @@ namespace Ogre {
155155
@param faceNormals The array of Vector4 used to store triangles face normal,
156156
Must be aligned to SIMD alignment.
157157
@param numTriangles Number of triangles to calculate face normal.
158+
@param components Number of components in positions buffer. Must be 3 or 4
158159
*/
159160
virtual void calculateFaceNormals(
160161
const float *positions,
161162
const EdgeData::Triangle *triangles,
162163
Vector4 *faceNormals,
163-
size_t numTriangles) = 0;
164+
size_t numTriangles,
165+
int components = 3) = 0;
164166

165167
/** Calculate the light facing state of the triangle's face normals
166168
@remarks

OgreMain/include/OgreStaticGeometry.h

-4
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,13 @@ namespace Ogre {
292292
LODBucket* mParent;
293293
// Shared link to position buffer
294294
HardwareVertexBufferSharedPtr mPositionBuffer;
295-
// Shared link to w-coord buffer (optional)
296-
HardwareVertexBufferSharedPtr mWBuffer;
297-
298295
public:
299296
LODShadowRenderable(LODBucket* parent,
300297
HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData,
301298
bool createSeparateLightCap, bool isLightCap = false);
302299
~LODShadowRenderable();
303300
void getWorldTransforms(Matrix4* xform) const override;
304301
HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
305-
HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
306302
virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) override;
307303

308304
};

OgreMain/include/OgreVertexIndexData.h

-16
Original file line numberDiff line numberDiff line change
@@ -144,22 +144,6 @@ namespace Ogre {
144144
*/
145145
void prepareForShadowVolume(void);
146146

147-
/** Additional shadow volume vertex buffer storage.
148-
@remarks
149-
This additional buffer is only used where we have prepared this VertexData for
150-
use in shadow volume construction, and where the current render system supports
151-
vertex programs. This buffer contains the 'w' vertex position component which will
152-
be used by that program to differentiate between extruded and non-extruded vertices.
153-
This 'w' component cannot be included in the original position buffer because
154-
DirectX does not allow 4-component positions in the fixed-function pipeline, and the original
155-
position buffer must still be usable for fixed-function rendering.
156-
@par
157-
Note that we don't store any vertex declaration or vertex buffer binding here because this
158-
can be reused in the shadow algorithm.
159-
*/
160-
HardwareVertexBufferSharedPtr hardwareShadowVolWBuffer;
161-
162-
163147
/** Reorganises the data in the vertex buffers according to the
164148
new vertex declaration passed in. Note that new vertex buffers
165149
are created and written to, so if the buffers being referenced

OgreMain/src/OgreEdgeListBuilder.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,11 @@ namespace Ogre {
414414
void EdgeData::updateFaceNormals(size_t vertexSet,
415415
const HardwareVertexBufferSharedPtr& positionBuffer)
416416
{
417-
assert (positionBuffer->getVertexSize() == sizeof(float) * 3
418-
&& "Position buffer should contain only positions!");
417+
OgreAssert(positionBuffer->getVertexSize() == sizeof(float) * 4,
418+
"Position buffer should contain only positions!");
419419

420420
// Triangle face normals should be 1:1 with triangles
421-
assert(triangleFaceNormals.size() == triangles.size());
421+
OgreAssert(triangleFaceNormals.size() == triangles.size(), "size mismatch");
422422

423423
// Calculate triangles which are using this vertex set
424424
const EdgeData::EdgeGroup& eg = edgeGroups[vertexSet];
@@ -429,7 +429,8 @@ namespace Ogre {
429429
static_cast<float*>(positionsLock.pData),
430430
&triangles[eg.triStart],
431431
&triangleFaceNormals[eg.triStart],
432-
eg.triCount);
432+
eg.triCount,
433+
4);
433434
}
434435
}
435436
//---------------------------------------------------------------------

OgreMain/src/OgreEntity.cpp

+5-10
Original file line numberDiff line numberDiff line change
@@ -1987,8 +1987,10 @@ namespace Ogre {
19871987
// Lock, we'll be locking the (suppressed hardware update) shadow buffer
19881988
HardwareBufferLockGuard posLock(esrPositionBuffer, HardwareBuffer::HBL_NORMAL);
19891989
float* pSrc = static_cast<float*>(posLock.pData);
1990-
float* pDest = pSrc + (egi->vertexData->vertexCount * 3);
1991-
memcpy(pDest, pSrc, sizeof(float) * 3 * egi->vertexData->vertexCount);
1990+
float* pDest = pSrc + (egi->vertexData->vertexCount * 4);
1991+
memcpy(pDest, pSrc, sizeof(float) * 4 * egi->vertexData->vertexCount);
1992+
for (size_t i = 0; i < egi->vertexData->vertexCount; i++)
1993+
pDest[i * 4 + 3] = 0; // second part needs w=0
19921994
}
19931995
if (egi->vertexData == mMesh->sharedVertexData)
19941996
{
@@ -2121,18 +2123,11 @@ namespace Ogre {
21212123
// Create vertex data which just references position component (and 2 component)
21222124
mRenderOp.vertexData = OGRE_NEW VertexData();
21232125
// Map in position data
2124-
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION);
2126+
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT4, VES_POSITION);
21252127
mOriginalPosBufferBinding =
21262128
vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
21272129
mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(mOriginalPosBufferBinding);
21282130
mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
2129-
// Map in w-coord buffer (if present)
2130-
if(vertexData->hardwareShadowVolWBuffer)
2131-
{
2132-
mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0);
2133-
mWBuffer = vertexData->hardwareShadowVolWBuffer;
2134-
mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer);
2135-
}
21362131
// Use same vertex start as input
21372132
mRenderOp.vertexData->vertexStart = vertexData->vertexStart;
21382133

OgreMain/src/OgreHardwareBufferManager.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ namespace Ogre {
476476
if (positions && !destPositionBuffer)
477477
{
478478
destPositionBuffer = srcPositionBuffer->getManager()->allocateVertexBufferCopy(srcPositionBuffer,
479-
HardwareBufferManagerBase::BLT_AUTOMATIC_RELEASE, this);
479+
HardwareBufferManagerBase::BLT_AUTOMATIC_RELEASE, this, true); // copy contents to keep W-coord for stencil shadows
480480
}
481481
if (normals && !posNormalShareBuffer && srcNormalBuffer && !destNormalBuffer)
482482
{

OgreMain/src/OgreManualObject.cpp

+1-8
Original file line numberDiff line numberDiff line change
@@ -773,18 +773,11 @@ ManualObject::ManualObject(const String& name)
773773
// Create vertex data which just references position component (and 2 component)
774774
mRenderOp.vertexData = OGRE_NEW VertexData();
775775
// Map in position data
776-
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION);
776+
mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT4, VES_POSITION);
777777
ushort origPosBind =
778778
vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
779779
mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind);
780780
mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
781-
// Map in w-coord buffer (if present)
782-
if(vertexData->hardwareShadowVolWBuffer)
783-
{
784-
mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0);
785-
mWBuffer = vertexData->hardwareShadowVolWBuffer;
786-
mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer);
787-
}
788781
// Use same vertex start as input
789782
mRenderOp.vertexData->vertexStart = vertexData->vertexStart;
790783

OgreMain/src/OgreMesh.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -1993,10 +1993,8 @@ namespace Ogre {
19931993

19941994

19951995
// Lock destination buffers for writing
1996-
HardwareBufferLockGuard destPosLock(destPosBuf,
1997-
(destNormBuf != destPosBuf && destPosBuf->getVertexSize() == destElemPos->getSize()) ||
1998-
(destNormBuf == destPosBuf && destPosBuf->getVertexSize() == destElemPos->getSize() + destElemNorm->getSize()) ?
1999-
HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL);
1996+
// HBL_NORMAL to keep W-coord for stencil shadows
1997+
HardwareBufferLockGuard destPosLock(destPosBuf, HardwareBuffer::HBL_NORMAL);
20001998
destElemPos->baseVertexPointerToElement(destPosLock.pData, &pDestPos);
20011999
HardwareBufferLockGuard destNormLock;
20022000
if (includeNormals)

OgreMain/src/OgreOptimisedUtil.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ namespace Ogre {
202202
const float *positions,
203203
const EdgeData::Triangle *triangles,
204204
Vector4 *faceNormals,
205-
size_t numTriangles)
205+
size_t numTriangles,
206+
int components)
206207
{
207208
static ProfileItems results;
208209
static size_t index;
@@ -215,7 +216,8 @@ namespace Ogre {
215216
positions,
216217
triangles,
217218
faceNormals,
218-
numTriangles);
219+
numTriangles,
220+
components);
219221
profile.end();
220222

221223
//

OgreMain/src/OgreOptimisedUtilGeneral.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ namespace Ogre {
7575
const float *positions,
7676
const EdgeData::Triangle *triangles,
7777
Vector4 *faceNormals,
78-
size_t numTriangles);
78+
size_t numTriangles,
79+
int components);
7980

8081
/// @copydoc OptimisedUtil::calculateLightFacing
8182
virtual void calculateLightFacing(
@@ -286,20 +287,21 @@ namespace Ogre {
286287
const float *positions,
287288
const EdgeData::Triangle *triangles,
288289
Vector4 *faceNormals,
289-
size_t numTriangles)
290+
size_t numTriangles,
291+
int components)
290292
{
291293
for ( ; numTriangles; --numTriangles)
292294
{
293295
const EdgeData::Triangle& t = *triangles++;
294296
size_t offset;
295297

296-
offset = t.vertIndex[0] * 3;
298+
offset = t.vertIndex[0] * components;
297299
Vector3 v1(positions[offset+0], positions[offset+1], positions[offset+2]);
298300

299-
offset = t.vertIndex[1] * 3;
301+
offset = t.vertIndex[1] * components;
300302
Vector3 v2(positions[offset+0], positions[offset+1], positions[offset+2]);
301303

302-
offset = t.vertIndex[2] * 3;
304+
offset = t.vertIndex[2] * components;
303305
Vector3 v3(positions[offset+0], positions[offset+1], positions[offset+2]);
304306

305307
*faceNormals++ = Math::calculateFaceNormalWithoutNormalize(v1, v2, v3);
@@ -341,6 +343,7 @@ namespace Ogre {
341343
*pDestPos++ = *pSrcPos++ + extrusionDir.x;
342344
*pDestPos++ = *pSrcPos++ + extrusionDir.y;
343345
*pDestPos++ = *pSrcPos++ + extrusionDir.z;
346+
pDestPos++, pSrcPos++;
344347
}
345348
}
346349
else
@@ -360,6 +363,7 @@ namespace Ogre {
360363
*pDestPos++ = *pSrcPos++ + extrusionDir.x;
361364
*pDestPos++ = *pSrcPos++ + extrusionDir.y;
362365
*pDestPos++ = *pSrcPos++ + extrusionDir.z;
366+
pDestPos++, pSrcPos++;
363367
}
364368
}
365369
}

0 commit comments

Comments
 (0)