Hello! I need to make a dynamic displace map in just a specific object, but maintaining all the pbs features, so... since there's is no way to add a custom texture to the vertex shader to a specific datablock I just did this:
dark_sylinc wrote: Wed Jan 27, 2016 10:22 pm
.......
The best method I see is deriving from both HlmsPbs and HlmsPbsDatablock:
.......
this is my code:
yHlmsPbsExtended.cpp:
Code: Select all
#include "yHlmsPbsExtended.h"
#include "yHlmsPbsDatablockExtended.h"
#include "OgreRoot.h"
#include "OgreHlmsManager.h"
#include "CommandBuffer/OgreCommandBuffer.h"
#include "CommandBuffer/OgreCbTexture.h"
#include "CommandBuffer/OgreCbShaderBuffer.h"
#include "OgreTextureManager.h"
#include <iostream>
yHlmsPbsExtended::yHlmsPbsExtended( Ogre::Archive *dataFolder, Ogre::ArchiveVec *libraryFolders ) :
HlmsPbs( dataFolder, libraryFolders )
{
Ogre::HlmsSamplerblock samplerblock;
samplerblock.mU = Ogre::TextureAddressingMode::TAM_CLAMP;
samplerblock.mV = Ogre::TextureAddressingMode::TAM_CLAMP;
samplerblock.mW = Ogre::TextureAddressingMode::TAM_CLAMP;
samplerblock.mMaxAnisotropy = 8;
samplerblock.mMagFilter = Ogre::FO_ANISOTROPIC;
mSamplerblockWrap = Ogre::Root::getSingleton().getHlmsManager()->getSamplerblock(samplerblock);
}
const Ogre::HlmsCache* yHlmsPbsExtended::createShaderCacheEntry( Ogre::uint32 renderableHash,
const Ogre::HlmsCache &passCache,
Ogre::uint32 finalHash,
const Ogre::QueuedRenderable &queuedRenderable )
{
const Ogre::HlmsCache* retVal = HlmsPbs::createShaderCacheEntry( renderableHash, passCache, finalHash, queuedRenderable );
const bool useDisplaceTexture = getProperty( "displace_map" ) != 0;
Ogre::GpuProgramParametersSharedPtr vsParams = retVal->pso.vertexShader->getDefaultParameters();
if( useDisplaceTexture ){
vsParams->setNamedConstant( "displaceMap", 13 );
}
mRenderSystem->bindGpuProgramParameters( Ogre::GPT_VERTEX_PROGRAM, vsParams, Ogre::GPV_ALL );
return retVal;
}
void yHlmsPbsExtended::calculateHashForPreCreate( Ogre::Renderable *renderable, Ogre::PiecesMap *inOutPieces ){
HlmsPbs::calculateHashForPreCreate( renderable, inOutPieces );
assert( dynamic_cast<yHlmsPbsDatablockExtended*>( renderable->getDatablock() ) );
yHlmsPbsDatablockExtended *datablock = static_cast<yHlmsPbsDatablockExtended*>(
renderable->getDatablock() );
if( !datablock->getDisplaceTexture().isNull() ){
setProperty( "displace_map", 1 );
}
}
Ogre::uint32 yHlmsPbsExtended::fillBuffersForV2( const Ogre::HlmsCache *cache,
const Ogre::QueuedRenderable &queuedRenderable,
bool casterPass, Ogre::uint32 lastCacheHash,
Ogre::CommandBuffer *commandBuffer )
{
Ogre::uint32 retVal = HlmsPbs::fillBuffersForV2( cache, queuedRenderable, casterPass, lastCacheHash, commandBuffer );
assert( dynamic_cast<const yHlmsPbsDatablockExtended*>( queuedRenderable.renderable->getDatablock() ) );
const yHlmsPbsDatablockExtended *datablock = static_cast<const yHlmsPbsDatablockExtended*>(
queuedRenderable.renderable->getDatablock() );
if( OGRE_EXTRACT_HLMS_TYPE_FROM_CACHE_HASH( lastCacheHash ) != mType )
{
if( !datablock->getDisplaceTexture().isNull() ){
const Ogre::TexturePtr &displaceTex = datablock->getDisplaceTexture();
*commandBuffer->addCommand<Ogre::CbTexture>() = Ogre::CbTexture( 13, true, displaceTex.get(), mSamplerblockWrap );
}
}
return retVal;
}
Ogre::HlmsDatablock* yHlmsPbsExtended::createDatablockImpl( Ogre::IdString datablockName,
const Ogre::HlmsMacroblock *macroblock,
const Ogre::HlmsBlendblock *blendblock,
const Ogre::HlmsParamVec ¶mVec )
{
return OGRE_NEW yHlmsPbsDatablockExtended( datablockName, this, macroblock, blendblock, paramVec );
}
.h:
Code: Select all
#ifndef YHLMSPBSEXTENDED_H
#define YHLMSPBSEXTENDED_H
#include "OgreHlmsPbs.h"
class yHlmsPbsDatablockExtended;
class yHlmsPbsExtended : public Ogre::HlmsPbs
{
public:
yHlmsPbsExtended( Ogre::Archive *dataFolder, Ogre::ArchiveVec *libraryFolders );
const Ogre::HlmsCache* createShaderCacheEntry( Ogre::uint32 renderableHash,
const Ogre::HlmsCache &passCache,
Ogre::uint32 finalHash,
const Ogre::QueuedRenderable &queuedRenderable ) override;
void calculateHashForPreCreate( Ogre::Renderable *renderable, Ogre::PiecesMap *inOutPieces ) override;
Ogre::uint32 fillBuffersForV2( const Ogre::HlmsCache *cache,
const Ogre::QueuedRenderable &queuedRenderable,
bool casterPass, Ogre::uint32 lastCacheHash,
Ogre::CommandBuffer *commandBuffer ) override;
Ogre::HlmsDatablock* createDatablockImpl( Ogre::IdString datablockName,
const Ogre::HlmsMacroblock *macroblock,
const Ogre::HlmsBlendblock *blendblock,
const Ogre::HlmsParamVec ¶mVec ) override;
const Ogre::HlmsSamplerblock* mSamplerblockWrap;
};
#endif // YHLMSPBSEXTENDED_H
and yHlmsPbsDatablockExtended.cpp:
Code: Select all
#include "yHlmsPbsDatablockExtended.h"
#include <iostream>
yHlmsPbsDatablockExtended::yHlmsPbsDatablockExtended( Ogre::IdString name, Ogre::HlmsPbs *creator,
const Ogre::HlmsMacroblock *macroblock,
const Ogre::HlmsBlendblock *blendblock,
const Ogre::HlmsParamVec ¶ms ) :
Ogre::HlmsPbsDatablock( name, creator, macroblock, blendblock, params )
{
mDisplaceTexture.setNull();
}
void yHlmsPbsDatablockExtended::setDisplaceTexture( Ogre::TexturePtr texture ){
mDisplaceTexture = texture;
}
const Ogre::TexturePtr &yHlmsPbsDatablockExtended::getDisplaceTexture() const{
return mDisplaceTexture;
}
.h:
Code: Select all
#ifndef YHLMSPBSDATABLOCKEXTENDED_H
#define YHLMSPBSDATABLOCKEXTENDED_H
#include "OgreHlmsPbsDatablock.h"
class yHlmsPbsDatablockExtended : public Ogre::HlmsPbsDatablock
{
friend class yHlmsPbsExtended;
public:
yHlmsPbsDatablockExtended( Ogre::IdString name, Ogre::HlmsPbs *creator,
const Ogre::HlmsMacroblock *macroblock,
const Ogre::HlmsBlendblock *blendblock,
const Ogre::HlmsParamVec ¶ms );
void setDisplaceTexture( Ogre::TexturePtr texture );
const Ogre::TexturePtr &getDisplaceTexture() const;
private:
Ogre::TexturePtr mDisplaceTexture;
};
#endif // YHLMSPBSDATABLOCKEXTENDED_H
and the corresponding @property( "displace_map" ) in the vertex shader:
Code: Select all
@property( displace_map )
uniform sampler2DArray displaceMap[1]; //yes! the texture is TEX_TYPE_2D_ARRAY for no real reason
@end
.....
@property( displace_map )
worldPos.xyz += ( vec4( @insertpiece(local_normal) * texture( displaceMap[0], vec3( uv0, 0 ) ).x*0.1, 0 ) * worldMat ).xyz ;
@end
and it was working!!! until yesterday that I updated Ogre to the current version, (I was using a version from many months ago)
I think that I am doing something wrong and it was working just by luck before... or there is something broken in the current version?
the @property is working, it is entering the right parts of the Hlms code, but in the vertex shader I don't get the texture, there might be a binding problem