Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Components/Hlms/Pbs/src/OgreHlmsPbs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3128,6 +3128,8 @@ namespace Ogre

if( OGRE_EXTRACT_HLMS_TYPE_FROM_CACHE_HASH( lastCacheHash ) != mType )
{
if( mCurrentPassBuffer == 0 )

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated.

return 0;
// layout(binding = 0) uniform PassBuffer {} pass
ConstBufferPacked *passBuffer = mPassBuffers[mCurrentPassBuffer - 1];
*commandBuffer->addCommand<CbShaderBuffer>() = CbShaderBuffer(
Expand Down
14 changes: 13 additions & 1 deletion Components/MeshLodGenerator/include/OgreLodConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,27 @@ namespace Ogre

struct _OgreLodExport LodConfig
{
v1::MeshPtr mesh; ///< The mesh which we want to reduce.
v1::MeshPtr mesh; ///< The v1 mesh which we want to reduce. Null if meshV2 is set.
MeshPtr meshV2; ///< The v2 mesh which we want to reduce. Null if mesh is set.
LodStrategy *strategy; ///< Lod strategy to use.

typedef vector<LodLevel>::type LodLevelList;
LodLevelList levels; ///< Info about Lod levels

LodConfig( v1::MeshPtr &_mesh, LodStrategy *_strategy = DistanceLodStrategy::getSingletonPtr() );
/** Constructs a config for generating LOD levels directly against a v2 mesh,
without going through a v1 mesh at any point.
@remarks
Exactly one of mesh / meshV2 must be set; MeshLodGenerator selects the v1 or
v2 code path (LodInputProviderMesh/LodOutputProviderMesh vs.
LodInputProviderMeshV2/LodOutputProviderMeshV2) based on which one is non-null.
*/
LodConfig( MeshPtr &_meshV2, LodStrategy *_strategy = DistanceLodStrategy::getSingletonPtr() );
LodConfig();

/// True if this config targets a v2 mesh (meshV2 is set) rather than a v1 one.
bool isV2() const { return meshV2 != 0; }

// Helper functions:
void createManualLodLevel( Ogre::Real distance, const String &manualMeshName );
void createGeneratedLodLevel(
Expand Down
52 changes: 50 additions & 2 deletions Components/MeshLodGenerator/include/OgreLodInputProvider.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
* -----------------------------------------------------------------------------
* This source file is part of OGRE-Next
Expand Down Expand Up @@ -50,7 +49,56 @@ namespace Ogre
bool isDuplicateTriangle( LodData::Triangle *triangle, LodData::Triangle *triangle2 );
LodData::Triangle *isDuplicateTriangle( LodData *data, LodData::Triangle *triangle );
static size_t getTriangleCount( OperationType renderOp, size_t indexCount );

/// Typedef shared by every concrete provider: maps a raw vertex-buffer index
/// (as found in the source index buffer) to the deduplicated LodData::VertexI
/// produced while reading vertex data. See LodInputProviderMesh::addVertexData /
/// LodInputProviderMeshV2::addVertexData for how this gets populated.
typedef vector<LodData::VertexI>::type VertexLookupList;

/** Builds a LodData::Triangle from three raw vertex-buffer indices (translated
through 'lookup') and registers it with 'data', for both v1 and v2 source
meshes alike -- once vertex/index data has been read into CPU-side arrays,
triangle construction itself does not depend on the source mesh format.
@remarks
Moved here (promoted from LodInputProviderMesh, which used to be the only
concrete provider) so LodInputProviderMeshV2 does not need to duplicate it.
Templated on IndexType since callers read raw indices as either
'unsigned short' or 'unsigned int' depending on the source index buffer's
element size.
*/
template <typename IndexType>
void addTriangle( LodData *data, IndexType i0, IndexType i1, IndexType i2,
VertexLookupList &lookup, unsigned submeshID )
{
LodData::Triangle tri;
tri.vertexID[0] = static_cast<unsigned int>( i0 );
tri.vertexID[1] = static_cast<unsigned int>( i1 );
tri.vertexID[2] = static_cast<unsigned int>( i2 );
tri.vertexi[0] = lookup[i0];
tri.vertexi[1] = lookup[i1];
tri.vertexi[2] = lookup[i2];
// No setter exists for this -- it's a plain public field. isRemoved()/
// setRemoved() use the all-bits-set sentinel value on this same field, so
// assigning a real submeshID here is also what marks the triangle as
// "not removed" (see LodData::Triangle::isRemoved()).
tri.submeshIDOrRemovedTag = submeshID;

if( tri.isMalformed() )
{
// Degenerate after vertex dedup (e.g. two raw indices that pointed at
// distinct, but identically-positioned, vertices). Exclude it from
// collapse calculations the same way isDuplicateTriangle() does.
data->mIndexBufferInfoList[submeshID].indexCount -= 3;
return;
}

tri.computeNormal( data->mVertexList );

data->mTriangleList.push_back( tri );
addTriangleToEdges( data, &data->mTriangleList.back() );
}
};

} // namespace Ogre
#endif
#endif
74 changes: 74 additions & 0 deletions Components/MeshLodGenerator/include/OgreLodInputProviderMeshV2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* -----------------------------------------------------------------------------
* This source file is part of OGRE-Next
* (Object-oriented Graphics Rendering Engine)
* For the latest info, see http://www.ogre3d.org/
*
* Copyright (c) 2000-2014 Torus Knot Software Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* -----------------------------------------------------------------------------
*/

#ifndef _LodInputProviderMeshV2_H__
#define _LodInputProviderMeshV2_H__

#include "OgreLodPrerequisites.h"

#include "OgreLodInputProvider.h"
#include "OgreSharedPtr.h"

namespace Ogre
{
/** Reads geometry directly from a v2 Mesh's SubMesh VAOs (no v1 mesh involved at
any point) and populates a LodData for MeshLodGenerator to collapse.
@remarks
Unlike LodInputProviderMesh, there is no shared-vertex-data concept to handle:
v2 Mesh has no Mesh-level shared vertex buffer, only per-SubMesh VAOs. This
removes the mSharedVertexLookup / useSharedVertexLookup branching entirely.
@par
Reads vertex/index data via VertexArrayObject::readRequests() +
mapAsyncTickets() + unmapAsyncTickets() (the same pattern SubMesh::
_dearrangeEfficient() already uses elsewhere in this codebase), which works
synchronously regardless of whether the buffers are shadow-copied, so there
is no special buffer-policy requirement on the source mesh.
*/
class _OgreLodExport LodInputProviderMeshV2 : public LodInputProvider
{
public:
LodInputProviderMeshV2( MeshPtr mesh );

void initData( LodData *data ) override;

protected:
MeshPtr mMesh;

/// Reused across submeshes; cleared at the start of each addVertexData() call.
/// One entry per vertex in the submesh's LOD-0 vertex buffer, mapping its
/// position in that buffer to the deduplicated LodData::VertexI.
VertexLookupList mVertexLookup;

void tuneContainerSize( LodData *data );
void initialize( LodData *data );
void addVertexData( LodData *data, SubMesh *subMesh, unsigned submeshID );
void addIndexData( LodData *data, SubMesh *subMesh, unsigned submeshID );
};

} // namespace Ogre
#endif
79 changes: 79 additions & 0 deletions Components/MeshLodGenerator/include/OgreLodOutputProviderMeshV2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* -----------------------------------------------------------------------------
* This source file is part of OGRE-Next
* (Object-oriented Graphics Rendering Engine)
* For the latest info, see http://www.ogre3d.org/
*
* Copyright (c) 2000-2014 Torus Knot Software Ltd
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* -----------------------------------------------------------------------------
*/

#ifndef _LodOutputProviderMeshV2_H__
#define _LodOutputProviderMeshV2_H__

#include "OgreLodPrerequisites.h"

#include "OgreLodOutputProvider.h"
#include "OgreSharedPtr.h"

namespace Ogre
{
/** Writes generated LOD levels directly onto a v2 Mesh's SubMesh::mVao arrays.
@remarks
Unlike LodOutputProviderMesh (which builds a v1::SubMesh::LODFaceList), this
appends a brand new VertexArrayObject per LOD level directly onto
SubMesh::mVao[VpNormal] (and [VpShadow], see bakeLodLevel()), reusing the
existing LOD-0 vertex buffers untouched -- LOD generation only ever changes
the index buffer, never vertex data, matching the pattern already proven in
SubMesh::importBuffersFromV1()'s own v1-LOD-import loop.
@par
Populating Mesh::_setLodValues() is intentionally NOT done here: just like
v1's LodOutputProviderMesh leaves _configureMeshLodUsage() as a separate step
MeshLodGenerator calls itself (it already has LodConfig in scope, this
provider doesn't need to carry a copy of it), the v2 path has a parallel
MeshLodGenerator::_configureMeshLodUsageV2() called the same way, after
output->finalize().
@par
Manual (mesh-swap) LOD levels are intentionally not supported here; see
bakeManualLodLevel().
*/
class _OgreLodExport LodOutputProviderMeshV2 : public LodOutputProvider
{
public:
LodOutputProviderMeshV2( MeshPtr mesh ) : mMesh( mesh ) {}

void prepare( LodData *data ) override;
void finalize( LodData *data ) override {}
void bakeManualLodLevel( LodData *data, String &manualMeshName, int lodIndex ) override;
void bakeLodLevel( LodData *data, int lodIndex ) override;

protected:
MeshPtr mMesh;

/// Builds a new IndexBufferPacked from data's current triangle list for one
/// submesh, exactly mirroring LodOutputProviderMesh::bakeLodLevel's v1 index
/// construction (same "dummy triangle if empty" handling), but returning a
/// v2 IndexBufferPacked instead of writing into a v1::IndexData.
IndexBufferPacked *buildIndexBufferForSubmesh( LodData *data, unsigned submeshID );
};

} // namespace Ogre
#endif
22 changes: 19 additions & 3 deletions Components/MeshLodGenerator/include/OgreMeshLodGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,28 @@ namespace Ogre
*/
void getAutoconfig( v1::MeshPtr &inMesh, LodConfig &outLodConfig );

/**
* @brief Fills Lod Config with a config, which works on any v2 mesh.
*
* Identical heuristic to the v1 overload above; sets outLodConfig.meshV2
* instead of outLodConfig.mesh, which is what _resolveComponents() uses to
* select the v2 input/output providers.
*
* @param inMesh Optimize for this mesh.
* @param outLodConfig Lod configuration storing the output.
*/
void getAutoconfig( MeshPtr &inMesh, LodConfig &outLodConfig );

static void _configureMeshLodUsage( const LodConfig &lodConfig );
/// v2 equivalent of _configureMeshLodUsage(): populates Mesh::_setLodValues()
/// instead of v1::Mesh's MeshLodUsage list. Called from _process() instead of
/// _configureMeshLodUsage() whenever lodConfig.isV2() is true.
static void _configureMeshLodUsageV2( const LodConfig &lodConfig );
void _resolveComponents( LodConfig &lodConfig, LodCollapseCostPtr &cost, LodDataPtr &data,
LodInputProviderPtr &input, LodOutputProviderPtr &output,
LodCollapserPtr &collapser );
void _process( LodConfig &lodConfig, LodCollapseCost *cost, LodData *data,
LodInputProvider *input, LodOutputProvider *output, LodCollapser *collapser );
void _process( LodConfig &lodConfig, LodCollapseCost *cost, LodData *data,
LodInputProvider *input, LodOutputProvider *output, LodCollapser *collapser );

/// If you only use manual Lod levels, then you don't need to build LodData mesh representation.
/// This function will generate manual Lod levels without overhead, but every Lod level needs to
Expand All @@ -105,4 +121,4 @@ namespace Ogre
};

} // namespace Ogre
#endif
#endif
7 changes: 7 additions & 0 deletions Components/MeshLodGenerator/src/OgreLodConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ namespace Ogre
{
}

LodConfig::LodConfig( MeshPtr &_meshV2,
LodStrategy *_strategy /*= DistanceLodStrategy::getSingletonPtr()*/ ) :
meshV2( _meshV2 ),
strategy( _strategy )
{
}

LodConfig::LodConfig() {}

void LodConfig::createManualLodLevel( Ogre::Real distance, const String &manualMeshName )
Expand Down
Loading
Loading