-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add regression test to check having many materials still works
- Loading branch information
1 parent
30b58c9
commit cea72df
Showing
5 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#------------------------------------------------------------------- | ||
# This file is part of the CMake build system for OGRE | ||
# (Object-oriented Graphics Rendering Engine) | ||
# For the latest info, see http://www.ogre3d.org/ | ||
# | ||
# The contents of this file are placed in the public domain. Feel | ||
# free to make use of it in any way you like. | ||
#------------------------------------------------------------------- | ||
|
||
macro( add_recursive dir retVal ) | ||
file( GLOB_RECURSE ${retVal} ${dir}/*.h ${dir}/*.cpp ${dir}/*.c ) | ||
endmacro() | ||
|
||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) | ||
|
||
include_directories(${CMAKE_SOURCE_DIR}/Components/Hlms/Common/include) | ||
ogre_add_component_include_dir(Hlms/Unlit) | ||
|
||
add_recursive( ./ SOURCE_FILES ) | ||
|
||
ogre_add_executable(Test_ManyMaterials WIN32 MACOSX_BUNDLE ${SOURCE_FILES} ${SAMPLE_COMMON_RESOURCES}) | ||
|
||
target_link_libraries(Test_ManyMaterials ${OGRE_LIBRARIES} ${OGRE_SAMPLES_LIBRARIES}) | ||
ogre_config_sample_lib(Test_ManyMaterials) | ||
ogre_config_sample_pkg(Test_ManyMaterials) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
|
||
#include "GraphicsSystem.h" | ||
#include "ManyMaterialsGameState.h" | ||
|
||
// Declares WinMain / main | ||
#include "MainEntryPointHelper.h" | ||
#include "System/MainEntryPoints.h" | ||
|
||
#if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID | ||
# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 | ||
INT WINAPI WinMainApp( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow ) | ||
# else | ||
int mainApp( int argc, const char *argv[] ) | ||
# endif | ||
{ | ||
return Demo::MainEntryPoints::mainAppSingleThreaded( DEMO_MAIN_ENTRY_PARAMS ); | ||
} | ||
#endif | ||
|
||
namespace Demo | ||
{ | ||
void MainEntryPoints::createSystems( GameState **outGraphicsGameState, | ||
GraphicsSystem **outGraphicsSystem, | ||
GameState **outLogicGameState, LogicSystem **outLogicSystem ) | ||
{ | ||
ManyMaterialsGameState *gfxGameState = new ManyMaterialsGameState( | ||
"Creates lots of materials and ensures the right ones are still assigned to objects." ); | ||
|
||
GraphicsSystem *graphicsSystem = new GraphicsSystem( gfxGameState ); | ||
|
||
gfxGameState->_notifyGraphicsSystem( graphicsSystem ); | ||
|
||
*outGraphicsGameState = gfxGameState; | ||
*outGraphicsSystem = graphicsSystem; | ||
} | ||
|
||
void MainEntryPoints::destroySystems( GameState *graphicsGameState, GraphicsSystem *graphicsSystem, | ||
GameState *logicGameState, LogicSystem *logicSystem ) | ||
{ | ||
delete graphicsSystem; | ||
delete graphicsGameState; | ||
} | ||
|
||
const char *MainEntryPoints::getWindowTitle( void ) { return "Test many materials"; } | ||
} // namespace Demo |
269 changes: 269 additions & 0 deletions
269
Samples/2.0/Tests/ManyMaterials/ManyMaterialsGameState.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
|
||
#include "ManyMaterialsGameState.h" | ||
|
||
#include "GraphicsSystem.h" | ||
|
||
#include "OgreHlmsUnlitDatablock.h" | ||
|
||
#include "Compositor/OgreCompositorManager2.h" | ||
#include "Compositor/OgreCompositorNodeDef.h" | ||
#include "Compositor/OgreCompositorWorkspace.h" | ||
#include "Compositor/OgreCompositorWorkspaceDef.h" | ||
#include "Compositor/Pass/PassScene/OgreCompositorPassSceneDef.h" | ||
#include "OgreCamera.h" | ||
#include "OgreHlms.h" | ||
#include "OgreItem.h" | ||
#include "OgreLogManager.h" | ||
#include "OgreLwString.h" | ||
#include "OgreMesh.h" | ||
#include "OgreMesh2.h" | ||
#include "OgreMeshManager.h" | ||
#include "OgreMeshManager2.h" | ||
#include "OgreRoot.h" | ||
#include "OgreSceneManager.h" | ||
#include "OgreTextureBox.h" | ||
#include "OgreTextureGpu.h" | ||
#include "OgreTextureGpuManager.h" | ||
|
||
using namespace Demo; | ||
|
||
ManyMaterialsGameState::ManyMaterialsGameState( const Ogre::String &helpDescription ) : | ||
TutorialGameState( helpDescription ), | ||
mCurrentMaterialId( 0u ), | ||
mPlaneItem( 0 ), | ||
mRgbaReference( 0 ), | ||
mTextureBox( 0 ), | ||
mErrorDetected( false ) | ||
{ | ||
} | ||
//----------------------------------------------------------------------------------- | ||
Ogre::HlmsUnlitDatablock *ManyMaterialsGameState::createUnlitDatablock( const Ogre::ColourValue &colour ) | ||
{ | ||
Ogre::HlmsManager *hlmsManager = mGraphicsSystem->getRoot()->getHlmsManager(); | ||
Ogre::Hlms *hlmsUnlit = hlmsManager->getHlms( Ogre::HLMS_UNLIT ); | ||
|
||
const std::string datablockId = "Test/" + Ogre::StringConverter::toString( mCurrentMaterialId++ ); | ||
|
||
Ogre::HlmsUnlitDatablock *newDatablock = (Ogre::HlmsUnlitDatablock *)hlmsUnlit->createDatablock( | ||
datablockId, datablockId, Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec(), | ||
true ); | ||
|
||
newDatablock->setUseColour( true ); | ||
newDatablock->setColour( colour ); | ||
|
||
return newDatablock; | ||
} | ||
//----------------------------------------------------------------------------------- | ||
Ogre::HlmsUnlitDatablock *ManyMaterialsGameState::generateMaterial( size_t newDummyMaterials, | ||
const Ogre::ColourValue &colour ) | ||
{ | ||
for( size_t i = 0u; i < newDummyMaterials; ++i ) | ||
createUnlitDatablock( Ogre::ColourValue::White ); | ||
return createUnlitDatablock( colour ); | ||
} | ||
//----------------------------------------------------------------------------------- | ||
void ManyMaterialsGameState::createScene01() | ||
{ | ||
Ogre::SceneManager *sceneManager = mGraphicsSystem->getSceneManager(); | ||
|
||
Ogre::v1::MeshPtr planeMeshV1 = Ogre::v1::MeshManager::getSingleton().createPlane( | ||
"Plane v1", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, | ||
Ogre::Plane( Ogre::Vector3::UNIT_Z, 0.0f ), 50.0f, 50.0f, 1, 1, true, 1, 4.0f, 4.0f, | ||
Ogre::Vector3::UNIT_Y, Ogre::v1::HardwareBuffer::HBU_STATIC, | ||
Ogre::v1::HardwareBuffer::HBU_STATIC ); | ||
|
||
Ogre::MeshPtr planeMesh = Ogre::MeshManager::getSingleton().createByImportingV1( | ||
"Plane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, planeMeshV1.get(), true, true, | ||
true ); | ||
|
||
{ | ||
// We must alter the AABB because we want to always pass frustum culling | ||
// Otherwise frustum culling may hide bugs in the projection matrix math | ||
planeMesh->load(); | ||
Ogre::Aabb aabb = planeMesh->getAabb(); | ||
aabb.mHalfSize.z = aabb.mHalfSize.x; | ||
planeMesh->_setBounds( aabb ); | ||
} | ||
|
||
Ogre::Item *item = sceneManager->createItem( planeMesh, Ogre::SCENE_DYNAMIC ); | ||
Ogre::SceneNode *sceneNode = sceneManager->getRootSceneNode( Ogre::SCENE_DYNAMIC ) | ||
->createChildSceneNode( Ogre::SCENE_DYNAMIC ); | ||
sceneNode->setScale( Ogre::Vector3( 1000.0f ) ); | ||
sceneNode->attachObject( item ); | ||
mPlaneItem = item; | ||
|
||
Ogre::Light *light = sceneManager->createLight(); | ||
Ogre::SceneNode *lightNode = sceneManager->getRootSceneNode()->createChildSceneNode(); | ||
lightNode->attachObject( light ); | ||
light->setPowerScale( Ogre::Math::PI ); // Since we don't do HDR, counter the PBS' division by | ||
// PI | ||
light->setType( Ogre::Light::LT_DIRECTIONAL ); | ||
light->setDirection( Ogre::Vector3( -1, -1, -1 ).normalisedCopy() ); | ||
|
||
Ogre::Camera *camera = mGraphicsSystem->getCamera(); | ||
camera->setPosition( 0, 0, 0 ); | ||
camera->setOrientation( Ogre::Quaternion::IDENTITY ); | ||
|
||
camera->setNearClipDistance( 0.5f ); | ||
sceneNode->setPosition( 0, 0, -camera->getNearClipDistance() - 50.0f ); | ||
|
||
{ | ||
using namespace Ogre; | ||
CompositorManager2 *compositorManager = mGraphicsSystem->getRoot()->getCompositorManager2(); | ||
CompositorNodeDef *nodeDef = compositorManager->addNodeDefinition( "ManyMaterials Node" ); | ||
|
||
// Input texture | ||
nodeDef->addTextureSourceName( "WindowRT", 0, TextureDefinitionBase::TEXTURE_INPUT ); | ||
|
||
nodeDef->setNumTargetPass( 1 ); | ||
{ | ||
CompositorTargetDef *targetDef = nodeDef->addTargetPass( "WindowRT" ); | ||
targetDef->setNumPasses( 1 ); | ||
{ | ||
{ | ||
CompositorPassSceneDef *passScene = | ||
static_cast<CompositorPassSceneDef *>( targetDef->addPass( PASS_SCENE ) ); | ||
passScene->setAllClearColours( Ogre::ColourValue( 1.0f, 0.5f, 0.0f, 1.0f ) ); | ||
passScene->setAllLoadActions( LoadAction::Clear ); | ||
passScene->mIncludeOverlays = false; | ||
} | ||
} | ||
} | ||
|
||
CompositorWorkspaceDef *workDef = | ||
compositorManager->addWorkspaceDefinition( "ManyMaterials Workspace" ); | ||
workDef->connectExternal( 0, nodeDef->getName(), 0 ); | ||
} | ||
|
||
TutorialGameState::createScene01(); | ||
} | ||
//----------------------------------------------------------------------------------- | ||
void ManyMaterialsGameState::update( float timeSinceLast ) | ||
{ | ||
Ogre::TextureGpuManager *textureManager = | ||
mGraphicsSystem->getRoot()->getRenderSystem()->getTextureGpuManager(); | ||
|
||
Ogre::TextureGpu *manyMaterialsTex = | ||
textureManager->createTexture( "ManyMaterials Tex", Ogre::GpuPageOutStrategy::Discard, | ||
Ogre::TextureFlags::RenderToTexture, Ogre::TextureTypes::Type2D ); | ||
const Ogre::uint32 resolution = 96u; | ||
manyMaterialsTex->setResolution( resolution, resolution ); | ||
manyMaterialsTex->setPixelFormat( Ogre::PFG_RGBA8_UNORM ); | ||
manyMaterialsTex->scheduleTransitionTo( Ogre::GpuResidency::Resident ); | ||
|
||
// const Ogre::PixelFormatGpu pixelFormat = manyMaterialsTex->getPixelFormat(); | ||
|
||
mGraphicsSystem->getSceneManager()->updateSceneGraph(); | ||
|
||
Ogre::CompositorManager2 *compositorManager = mGraphicsSystem->getRoot()->getCompositorManager2(); | ||
Ogre::CompositorWorkspace *workspace = compositorManager->addWorkspace( | ||
mGraphicsSystem->getSceneManager(), manyMaterialsTex, mGraphicsSystem->getCamera(), | ||
"ManyMaterials Workspace", false ); | ||
|
||
const size_t iterations = 200u; | ||
|
||
for( size_t i = 0u; i < iterations; ++i ) | ||
{ | ||
// Choose random colour | ||
Ogre::ColourValue randColour( | ||
Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ), | ||
Ogre::Math::RangeRandom( 0.0f, 1.0f ), Ogre::Math::RangeRandom( 0.0f, 1.0f ) ); | ||
|
||
// Quantize | ||
const Ogre::RGBA asRgba = randColour.getAsRGBA(); | ||
randColour.setAsRGBA( asRgba ); | ||
mRgbaReference = asRgba; | ||
|
||
// Use a prime number as extra materials. | ||
Ogre::HlmsUnlitDatablock *newMaterial = generateMaterial( 67u, randColour ); | ||
|
||
mPlaneItem->setDatablock( newMaterial ); | ||
|
||
uint32_t rgba = randColour.getAsABGR(); | ||
const uint8_t *rgba8 = reinterpret_cast<const uint8_t *>( &rgba ); | ||
|
||
Ogre::LogManager::getSingleton().logMessage( | ||
"Testing colour: " + std::to_string( rgba8[0] ) + " " + std::to_string( rgba8[1] ) + " " + | ||
std::to_string( rgba8[2] ) + " " + std::to_string( rgba8[3] ), | ||
Ogre::LML_CRITICAL ); | ||
|
||
workspace->_validateFinalTarget(); | ||
workspace->_beginUpdate( false ); | ||
workspace->_update(); | ||
workspace->_endUpdate( false ); | ||
|
||
Ogre::Image2 image; | ||
image.convertFromTexture( manyMaterialsTex, 0u, 0u ); | ||
// image.save( "/home/matias/tttt.png",0,1 ); | ||
|
||
Ogre::TextureBox box = image.getData( 0u ); | ||
mTextureBox = &box; | ||
|
||
mGraphicsSystem->getSceneManager()->executeUserScalableTask( this, true ); | ||
// execute(0u,1u); | ||
|
||
if( mErrorDetected ) | ||
{ | ||
Ogre::LogManager::getSingleton().logMessage( | ||
"Mismatch detected!. Expected value: " + std::to_string( rgba8[0] ) + " " + | ||
std::to_string( rgba8[1] ) + " " + std::to_string( rgba8[2] ) + " " + | ||
std::to_string( rgba8[3] ) + " Got instead: " + std::to_string( mRgbaResult[0] ) + | ||
" " + std::to_string( mRgbaResult[1] ) + " " + std::to_string( mRgbaResult[2] ) + | ||
" " + std::to_string( mRgbaResult[3] ), | ||
Ogre::LML_CRITICAL ); | ||
|
||
mErrorDetected = false; | ||
|
||
OGRE_EXCEPT( Ogre::Exception::ERR_RT_ASSERTION_FAILED, "Mismatch detected!", | ||
"Test failed!" ); | ||
} | ||
} | ||
|
||
compositorManager->removeWorkspace( workspace ); | ||
textureManager->destroyTexture( manyMaterialsTex ); | ||
|
||
mGraphicsSystem->setQuit(); | ||
|
||
TutorialGameState::update( timeSinceLast ); | ||
} | ||
//----------------------------------------------------------------------------------- | ||
void ManyMaterialsGameState::execute( size_t threadId, size_t numThreads ) | ||
{ | ||
const Ogre::uint32 rgbaRef = mRgbaReference; | ||
const Ogre::TextureBox box = *mTextureBox; | ||
|
||
const uint8_t *refValue = reinterpret_cast<const Ogre::uint8 *>( &rgbaRef ); | ||
|
||
const size_t heightToProcess = std::max<size_t>( 1u, box.height / numThreads ); | ||
const size_t heightStart = heightToProcess * threadId; | ||
|
||
// Clamp heightEnd (in case there's more threads than rows) | ||
// Ceil heightEnd for the last thread (when box.height / numThreads is not perfectly divisible) | ||
size_t heightEnd = heightToProcess * ( threadId + 1u ); | ||
if( ( threadId + 2u ) * heightToProcess > box.height ) | ||
heightEnd = box.height; | ||
|
||
for( size_t y = heightStart; y < heightEnd; ++y ) | ||
{ | ||
for( size_t x = 0u; x < box.width; ++x ) | ||
{ | ||
const Ogre::uint8 *dataPtr = reinterpret_cast<const Ogre::uint8 *>( box.data ) + | ||
y * box.bytesPerRow + x * box.bytesPerPixel; | ||
|
||
// const Ogre::ColourValue readValue = box.getColourAt( x, y, 0u, pixelFormat ); | ||
// if( readValue != randColour ) | ||
if( dataPtr[0] != refValue[3] || dataPtr[1] != refValue[2] || dataPtr[2] != refValue[1] || | ||
dataPtr[3] != refValue[0] ) | ||
{ | ||
if( !mErrorDetected ) | ||
{ | ||
mRgbaResult[0] = dataPtr[0]; | ||
mRgbaResult[1] = dataPtr[1]; | ||
mRgbaResult[2] = dataPtr[2]; | ||
mRgbaResult[3] = dataPtr[3]; | ||
} | ||
mErrorDetected = true; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
|
||
#ifndef _Demo_ManyMaterialsGameState_H_ | ||
#define _Demo_ManyMaterialsGameState_H_ | ||
|
||
#include "OgrePrerequisites.h" | ||
#include "TutorialGameState.h" | ||
|
||
#include "Threading/OgreUniformScalableTask.h" | ||
|
||
namespace Ogre | ||
{ | ||
class HlmsUnlitDatablock; | ||
} | ||
|
||
namespace Demo | ||
{ | ||
class ManyMaterialsGameState final : public TutorialGameState, public Ogre::UniformScalableTask | ||
{ | ||
size_t mCurrentMaterialId; | ||
|
||
Ogre::Item *mPlaneItem; | ||
|
||
Ogre::uint32 mRgbaReference; | ||
Ogre::uint8 mRgbaResult[4]; | ||
Ogre::TextureBox const *mTextureBox; | ||
bool mErrorDetected; | ||
|
||
Ogre::HlmsUnlitDatablock *createUnlitDatablock( const Ogre::ColourValue &colour ); | ||
|
||
Ogre::HlmsUnlitDatablock *generateMaterial( size_t numDummyMaterials, | ||
const Ogre::ColourValue &colour ); | ||
|
||
public: | ||
ManyMaterialsGameState( const Ogre::String &helpDescription ); | ||
|
||
void createScene01() override; | ||
void update( float timeSinceLast ) override; | ||
|
||
void execute( size_t threadId, size_t numThreads ) override; | ||
}; | ||
} // namespace Demo | ||
|
||
#endif |