//-----------------------------------------------------------------------------------
	PbsMaterial::PbsMaterial() : mAlbedo(1, 1, 1, 0), mF0(0.1f, 0.1f, 0.1f, 1.0f), mRoughness(0.1f), mLightRoughnessOffset(0.0f),
	/*header initial values*/	mMainUvSetIndex(0), mD1UvSetIndex(0), mD2UvSetIndex(0), _hasSamplerListChanged(false), 
								_hasSamplerChanged(false)
	{
		//Header initial values
		mMainOffset = Vector2::ZERO;
		mMainScale = Vector2::UNIT_SCALE;	
		mD1Offset = Vector2::ZERO;
		mD1Scale = Vector2::UNIT_SCALE;
		mD2Offset = Vector2::ZERO;
		mD2Scale = Vector2::UNIT_SCALE;

		_samplers[ST_ENV_MAP].init("environment", false, false, false, false, true, true, TEX_TYPE_CUBE_MAP);

		_samplers[ST_MAIN_ALBEDO].init("main_albedo", true, true, false, true);
		_samplers[ST_MAIN_NORMALR].init("main_normalr", false, true, true);
		_samplers[ST_MAIN_F0].init("main_f0", true, true);

		_samplers[ST_D1_ALBEDO].init("d1_albedo", true, true, false, true);
		_samplers[ST_D1_NORMALR].init("d1_normalr", false, true, true);
		_samplers[ST_D1_F0].init("d1_f0", true, true);

		_samplers[ST_D2_ALBEDO].init("d2_albedo", true, true, false, true);
		_samplers[ST_D2_NORMALR].init("d2_normalr", false, true, true);
		_samplers[ST_D2_F0].init("d2_f0", true, true);


		RenderSystem* rs = Root::getSingleton().getRenderSystem();

		String language = "";
		if (rs->getCapabilities()->isShaderProfileSupported("hlsl"))
		{
			language = "hlsl";
			mVertexDatablock.addProfile("vs_3_0");
			mFragmentDatablock.addProfile("ps_3_0");
		}
		else if (rs->getCapabilities()->isShaderProfileSupported("glsl"))
		{
			language = "glsl";
		}
		else 
		{
			language = "glsles";
		}

		mVertexDatablock.setLanguage(language);
		mFragmentDatablock.setLanguage(language);

		mVertexDatablock.setTemplateName("PBS");
		mFragmentDatablock.setTemplateName("PBS");

		// TODO check if the hardware supports gamma correction "Root::getSingleton().getRenderSystem()->getCapabilities()" doesen't support this check
		mCanHardwareGamma = false;
	}
    //---------------------------------------------------------------------------
		const GpuProgramManager::SyntaxCodes& GpuProgramManager::getSupportedSyntax(void) const
        {
				// Use the current render system
			  RenderSystem* rs = Root::getSingleton().getRenderSystem();

				// Get the supported syntaxed from RenderSystemCapabilities 
				return rs->getCapabilities()->getSupportedShaderProfiles();
        }
    //---------------------------------------------------------------------
    bool GpuProgramManager::canGetCompiledShaderBuffer()
    {
        // Use the current render system
        RenderSystem* rs = Root::getSingleton().getRenderSystem();

        // Check if the supported  
        return rs->getCapabilities()->hasCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER);
    }
    //---------------------------------------------------------------------------
    bool GpuProgramManager::isSyntaxSupported(const String& syntaxCode) const
    {
        // Use the current render system
        RenderSystem* rs = Root::getSingleton().getRenderSystem();

        // Get the supported syntax from RenderSystemCapabilities 
        return rs->getCapabilities()->isShaderProfileSupported(syntaxCode);
    }
	//-----------------------------------------------------------------------
	bool D3D10HLSLProgram::isSupported(void) const
	{
		// Use the current render system
		RenderSystem* rs = Root::getSingleton().getRenderSystem();

		// Get the supported syntaxed from RenderSystemCapabilities 
		return rs->getCapabilities()->isShaderProfileSupported(mTarget) && GpuProgram::isSupported();

	}
Beispiel #6
0
    //-----------------------------------------------------------------------------------
    void CompositorPass::addResourceTransition( ResourceLayoutMap::iterator currentLayout,
                                                ResourceLayout::Layout newLayout,
                                                uint32 readBarrierBits )
    {
        ResourceTransition transition;
        //transition.resource = ; TODO
        transition.oldLayout = currentLayout->second;
        transition.newLayout = newLayout;
        transition.writeBarrierBits = transitionWriteBarrierBits( transition.oldLayout );
        transition.readBarrierBits  = readBarrierBits;

        RenderSystem *renderSystem = mParentNode->getRenderSystem();
        const RenderSystemCapabilities *caps = renderSystem->getCapabilities();
        if( !caps->hasCapability( RSC_EXPLICIT_API ) )
        {
            //OpenGL. Merge the bits and use only one global barrier.
            //Keep the extra barriers uninitialized for debugging purposes,
            //but we won't be really using them.
            if( mResourceTransitions.empty() )
            {
                ResourceTransition globalBarrier;
                globalBarrier.oldLayout = ResourceLayout::Undefined;
                globalBarrier.newLayout = ResourceLayout::Undefined;
                globalBarrier.writeBarrierBits  = transition.writeBarrierBits;
                globalBarrier.readBarrierBits   = transition.readBarrierBits;
                globalBarrier.mRsData = 0;
                renderSystem->_resourceTransitionCreated( &globalBarrier );
                mResourceTransitions.push_back( globalBarrier );
            }
            else
            {
                ResourceTransition &globalBarrier = mResourceTransitions.front();

                renderSystem->_resourceTransitionDestroyed( &globalBarrier );

                globalBarrier.writeBarrierBits  |= transition.writeBarrierBits;
                globalBarrier.readBarrierBits   |= transition.readBarrierBits;

                renderSystem->_resourceTransitionCreated( &globalBarrier );
            }

            mNumValidResourceTransitions = 1;
        }
        else
        {
            //D3D12, Vulkan, Mantle. Takes advantage of per-resource barriers
            renderSystem->_resourceTransitionCreated( &transition );
            ++mNumValidResourceTransitions;
        }

        mResourceTransitions.push_back( transition );

        currentLayout->second = transition.newLayout;
    }
Beispiel #7
0
int main(int numargs, char** args)
{
    if (numargs != 1)
    {
        help();
        return -1;
    }
    
    RenderSystemCapabilities* glCaps = 0;
    RenderSystemCapabilities* d3d9Caps = 0;
    
    RenderSystemCapabilitiesSerializer serializer;
    
    // query openGL for caps if available
    Root* root = new Root("plugins.cfg");
    RenderSystem* rsGL = root->getRenderSystemByName("OpenGL Rendering Subsystem");
    if(rsGL)
    {
        setUpGLRenderSystemOptions(rsGL);
        root->setRenderSystem(rsGL);
        root->initialise(true, "OGRE rcapsdump GL Window");
        glCaps = const_cast<RenderSystemCapabilities *>(rsGL->getCapabilities());   
    }
    if(glCaps)
    {
        serializer.writeScript(glCaps, glCaps->getDeviceName(), "rcapsdump_gl.rendercaps");
    }
    
    delete root;
    
    // query D3D9 for caps if available
    root = new Root("plugins.cfg");
    RenderSystem* rsD3D9 = root->getRenderSystemByName("Direct3D9 Rendering Subsystem");
    if(rsD3D9)
    {
        setUpD3D9RenderSystemOptions(rsD3D9);
        root->setRenderSystem(rsD3D9);
        root->initialise(true, "OGRE rcapsdump D3D9 Window");
        d3d9Caps = const_cast<RenderSystemCapabilities *>(rsD3D9->getCapabilities());
    }
    if(d3d9Caps)
    {
        serializer.writeScript(d3d9Caps, d3d9Caps->getDeviceName(), "rcapsdump_d3d9.rendercaps");
    }

    delete root;
  
    return 0;

}
	//-----------------------------------------------------------------------
	size_t LightInstanceBatchHW::calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const
	{
		size_t retVal = 0;

		RenderSystem *renderSystem = Root::getSingleton().getRenderSystem();
		const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities();

		if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) )
		{
			//This value is arbitrary (theorical max is 2^30 for D3D9) but is big enough and safe
			retVal = 65535;
		}

		return retVal;
	}
    //-----------------------------------------------------------------------
    size_t InstanceBatchHW_VTF::calculateMaxNumInstances( 
                    const SubMesh *baseSubMesh, uint16 flags ) const
    {
        size_t retVal = 0;

        RenderSystem *renderSystem = Root::getSingleton().getRenderSystem();
        const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities();

        //VTF & HW Instancing must be supported
        if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) &&
            capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) )
        {
            //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one)
            const size_t numBones = std::max<size_t>( 1, baseSubMesh->blendIndexToBoneIndexMap.size() );

            const size_t maxUsableWidth = c_maxTexWidthHW - (c_maxTexWidthHW % (numBones * mRowLength));

            //See InstanceBatchHW::calculateMaxNumInstances for the 65535
            retVal = std::min<size_t>( 65535, maxUsableWidth * c_maxTexHeightHW / mRowLength / numBones );

            if( flags & IM_VTFBESTFIT )
            {
                size_t numUsedSkeletons = mInstancesPerBatch;
                if (flags & IM_VTFBONEMATRIXLOOKUP)
                    numUsedSkeletons = std::min<size_t>(getMaxLookupTableInstances(), numUsedSkeletons);
                const size_t instancesPerBatch = std::min( retVal, numUsedSkeletons );
                //Do the same as in createVertexTexture(), but changing c_maxTexWidthHW for maxUsableWidth
                const size_t numWorldMatrices = instancesPerBatch * numBones;

                size_t texWidth  = std::min<size_t>( numWorldMatrices * mRowLength, maxUsableWidth );
                size_t texHeight = numWorldMatrices * mRowLength / maxUsableWidth;

                const size_t remainder = (numWorldMatrices * mRowLength) % maxUsableWidth;

                if( remainder && texHeight > 0 )
                    retVal = static_cast<size_t>(texWidth * texHeight / (float)mRowLength / (float)(numBones));
            }
        }

        return retVal;
    }
Beispiel #10
0
    // Just override the mandatory create scene method
    void createScene(void)
    {
		RenderSystem *rs = Root::getSingleton().getRenderSystem();
		const RenderSystemCapabilities* caps = rs->getCapabilities();
        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
        {
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support vertex and fragment programs, so cannot "
                "run this demo. Sorry!", 
                "DeferredShading::createScene");
        }
		if (caps->getNumMultiRenderTargets()<2)
        {
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support at least two simultaneous render targets, so cannot "
                "run this demo. Sorry!", 
                "DeferredShading::createScene");
        }

		// Prepare athene mesh for normalmapping
        MeshPtr pAthene = MeshManager::getSingleton().load("athene.mesh", 
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        unsigned short src, dest;
        if (!pAthene->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
            pAthene->buildTangentVectors(VES_TANGENT, src, dest);
		// Prepare knot mesh for normal mapping
		pAthene = MeshManager::getSingleton().load("knot.mesh", 
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        if (!pAthene->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
            pAthene->buildTangentVectors(VES_TANGENT, src, dest);

        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.15));
        // Skybox
        mSceneMgr->setSkyBox(true, "DeferredDemo/SkyBox");

		// Create "root" node
		SceneNode* rootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		Entity* athena = mSceneMgr->createEntity("Athena", "athene.mesh");
		athena->setMaterialName("DeferredDemo/DeferredAthena");
		SceneNode *aNode = rootNode->createChildSceneNode();
		aNode->attachObject( athena );
		aNode->setPosition(-100, 40, 100);

		// Create a prefab plane
		mPlane = new MovablePlane("ReflectPlane");
		mPlane->d = 0;
		mPlane->normal = Vector3::UNIT_Y;
		MeshManager::getSingleton().createCurvedPlane("ReflectionPlane", 
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
			*mPlane,
			2000, 2000, -1000,
			20, 20, 
			true, 1, 10, 10, Vector3::UNIT_Z);
		mPlaneEnt = mSceneMgr->createEntity( "Plane", "ReflectionPlane" );
		mPlaneNode = rootNode->createChildSceneNode();
		mPlaneNode->attachObject(mPlaneEnt);
		mPlaneNode->translate(-5, -30, 0);
		//mPlaneNode->roll(Degree(5));
		mPlaneEnt->setMaterialName("DeferredDemo/Ground");

		// Create an entity from a model (will be loaded automatically)
		Entity* knotEnt = mSceneMgr->createEntity("Knot", "knot.mesh");
		knotEnt->setMaterialName("DeferredDemo/RockWall");
		knotEnt->setMeshLodBias(0.25f);

		// Create an entity from a model (will be loaded automatically)
		Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
		ogreHead->getSubEntity(0)->setMaterialName("DeferredDemo/Ogre/Eyes");// eyes
		ogreHead->getSubEntity(1)->setMaterialName("DeferredDemo/Ogre/Skin"); 
		ogreHead->getSubEntity(2)->setMaterialName("DeferredDemo/Ogre/EarRing"); // earrings
		ogreHead->getSubEntity(3)->setMaterialName("DeferredDemo/Ogre/Tusks"); // tusks
		rootNode->createChildSceneNode( "Head" )->attachObject( ogreHead );

		// Add a whole bunch of extra entities to fill the scene a bit
		Entity *cloneEnt;
		int N=4;
		for (int n = 0; n < N; ++n)
		{
			float theta = 2.0f*Math::PI*(float)n/(float)N;
			// Create a new node under the root
			SceneNode* node = mSceneMgr->createSceneNode();
			// Random translate
			Vector3 nodePos;
			nodePos.x = Math::SymmetricRandom() * 40.0 + Math::Sin(theta) * 500.0;
			nodePos.y = Math::SymmetricRandom() * 20.0 - 40.0;
			nodePos.z = Math::SymmetricRandom() * 40.0 + Math::Cos(theta) * 500.0;
			node->setPosition(nodePos);
			Quaternion orientation(Math::SymmetricRandom(),Math::SymmetricRandom(),Math::SymmetricRandom(),Math::SymmetricRandom());
			orientation.normalise();
			node->setOrientation(orientation);
			rootNode->addChild(node);
			// Clone knot
			char cloneName[12];
			sprintf(cloneName, "Knot%d", n);
			cloneEnt = knotEnt->clone(cloneName);
			// Attach to new node
			node->attachObject(cloneEnt);

		}

        mCamera->setPosition(-50, 100, 500);
        mCamera->lookAt(0,0,0);

		// show overlay
		Overlay* overlay = OverlayManager::getSingleton().getByName("Example/ShadowsOverlay");    
		overlay->show();

		mSystem = new DeferredShadingSystem(mWindow->getViewport(0), mSceneMgr, mCamera);

		// Create main, moving light
		MLight* l1 = mSystem->createMLight();//"MainLight");
        l1->setDiffuseColour(0.75f, 0.7f, 0.8f);
		l1->setSpecularColour(0.85f, 0.9f, 1.0f);
		
		SceneNode *lightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		lightNode->attachObject(l1);

		// Create a track for the light
        Animation* anim = mSceneMgr->createAnimation("LightTrack", 16);
        // Spline it for nice curves
        anim->setInterpolationMode(Animation::IM_SPLINE);
        // Create a track to animate the camera's node
        NodeAnimationTrack* track = anim->createNodeTrack(0, lightNode);
        // Setup keyframes
        TransformKeyFrame* key = track->createNodeKeyFrame(0); // A start position
        key->setTranslate(Vector3(300,300,-300));
        key = track->createNodeKeyFrame(4);//B
        key->setTranslate(Vector3(300,300,300));
        key = track->createNodeKeyFrame(8);//C
        key->setTranslate(Vector3(-300,300,300));
        key = track->createNodeKeyFrame(12);//D
        key->setTranslate(Vector3(-300,300,-300));
		key = track->createNodeKeyFrame(16);//D
        key->setTranslate(Vector3(300,300,-300));
        // Create a new animation state to track this
        SharedData::getSingleton().mAnimState = mSceneMgr->createAnimationState("LightTrack");
        SharedData::getSingleton().mAnimState->setEnabled(true);

		// Create some happy little lights
		createSampleLights();

		// safely setup application's (not postfilter!) shared data
		SharedData::getSingleton().iCamera = mCamera;
		SharedData::getSingleton().iRoot = mRoot;
		SharedData::getSingleton().iWindow = mWindow;
		SharedData::getSingleton().iActivate = true;
		SharedData::getSingleton().iGlobalActivate = true;
		SharedData::getSingleton().iSystem = mSystem;
		SharedData::getSingleton().iMainLight = l1;
	}
Beispiel #11
0
    //-----------------------------------------------------------------------------------
    void CompositorPass::_placeBarriersAndEmulateUavExecution(
                                            BoundUav boundUavs[64], ResourceAccessMap &uavsAccess,
                                            ResourceLayoutMap &resourcesLayout )
    {
        RenderSystem *renderSystem = mParentNode->getRenderSystem();
        const RenderSystemCapabilities *caps = renderSystem->getCapabilities();
        const bool explicitApi = caps->hasCapability( RSC_EXPLICIT_API );

        {
            //mResourceTransitions will be non-empty if we call _placeBarriersAndEmulateUavExecution
            //for a second time (i.e. 2nd pass to check frame-to-frame dependencies). We need
            //to tell what is shielded. On the first time, it should be empty.
            ResourceTransitionVec::const_iterator itor = mResourceTransitions.begin();
            ResourceTransitionVec::const_iterator end  = mResourceTransitions.end();

            while( itor != end )
            {
                if( itor->newLayout == ResourceLayout::Uav &&
                    itor->writeBarrierBits & WriteBarrier::Uav &&
                    itor->readBarrierBits & ReadBarrier::Uav )
                {
                    RenderTarget *renderTarget = 0;
                    resourcesLayout[renderTarget] = ResourceLayout::Uav;
                    //Set to undefined so that following passes
                    //can see it's safe / shielded by a barrier
                    uavsAccess[renderTarget] = ResourceAccess::Undefined;
                }
                ++itor;
            }
        }

        {
            //Check <anything> -> RT
            ResourceLayoutMap::iterator currentLayout = resourcesLayout.find( mTarget );
            if( (currentLayout->second != ResourceLayout::RenderTarget && explicitApi) ||
                currentLayout->second == ResourceLayout::Uav )
            {
                addResourceTransition( currentLayout,
                                       ResourceLayout::RenderTarget,
                                       ReadBarrier::RenderTarget );
            }
        }

        {
            //Check <anything> -> Texture
            CompositorTextureVec::const_iterator itDep = mTextureDependencies.begin();
            CompositorTextureVec::const_iterator enDep = mTextureDependencies.end();

            while( itDep != enDep )
            {
                TexturePtr texture = itDep->textures->front();
                RenderTarget *renderTarget = texture->getBuffer()->getRenderTarget();

                ResourceLayoutMap::iterator currentLayout = resourcesLayout.find( renderTarget );

                if( (currentLayout->second != ResourceLayout::Texture && explicitApi) ||
                     currentLayout->second == ResourceLayout::Uav )
                {
                    //TODO: Account for depth textures.
                    addResourceTransition( currentLayout,
                                           ResourceLayout::Texture,
                                           ReadBarrier::Texture );
                }

                ++itDep;
            }
        }

        //Check <anything> -> UAV; including UAV -> UAV
        //Except for RaR (Read after Read) and some WaW (Write after Write),
        //Uavs are always hazardous, an UAV->UAV 'transition' is just a memory barrier.
        CompositorPassDef::UavDependencyVec::const_iterator itor = mDefinition->mUavDependencies.begin();
        CompositorPassDef::UavDependencyVec::const_iterator end  = mDefinition->mUavDependencies.end();

        while( itor != end )
        {
            GpuResource *uavRt = boundUavs[itor->uavSlot].rttOrBuffer;

            if( !uavRt )
            {
                OGRE_EXCEPT( Exception::ERR_INVALID_STATE,
                             "No UAV is bound at slot " + StringConverter::toString( itor->uavSlot ) +
                             " but it is marked as used by node " +
                             mParentNode->getName().getFriendlyText() + "; pass #" +
                             StringConverter::toString( mParentNode->getPassNumber( this ) ),
                             "CompositorPass::emulateUavExecution" );
            }

            if( !(itor->access & boundUavs[itor->uavSlot].boundAccess) )
            {
                OGRE_EXCEPT( Exception::ERR_INVALID_STATE,
                             "Node " + mParentNode->getName().getFriendlyText() + "; pass #" +
                             StringConverter::toString( mParentNode->getPassNumber( this ) ) +
                             " marked " + ResourceAccess::toString( itor->access ) +
                             " access to UAV at slot " +
                             StringConverter::toString( itor->uavSlot ) + " but this UAV is bound for " +
                             ResourceAccess::toString( boundUavs[itor->uavSlot].boundAccess ) +
                             " access.", "CompositorPass::emulateUavExecution" );
            }

            ResourceAccessMap::iterator itResAccess = uavsAccess.find( uavRt );

            if( itResAccess == uavsAccess.end() )
            {
                //First time accessing the UAV. If we need a barrier,
                //we will see it in the second pass.
                uavsAccess[uavRt] = ResourceAccess::Undefined;
                itResAccess = uavsAccess.find( uavRt );
            }

            ResourceLayoutMap::iterator currentLayout = resourcesLayout.find( uavRt );

            if( currentLayout->second != ResourceLayout::Uav ||
                !( (itor->access == ResourceAccess::Read &&
                    itResAccess->second == ResourceAccess::Read) ||
                   (itor->access == ResourceAccess::Write &&
                    itResAccess->second == ResourceAccess::Write &&
                    itor->allowWriteAfterWrite) ||
                   itResAccess->second == ResourceAccess::Undefined ) )
            {
                //Not RaR (or not WaW when they're explicitly allowed). Insert the barrier.
                //We also may need the barrier if the resource wasn't an UAV.
                addResourceTransition( currentLayout, ResourceLayout::Uav, ReadBarrier::Uav );
            }

            itResAccess->second = itor->access;

            ++itor;
        }
    }