Пример #1
0
	//[-------------------------------------------------------]
	//[ Private virtual RendererRuntime::IMaterialBlueprintResourceListener methods ]
	//[-------------------------------------------------------]
	void MaterialBlueprintResourceListener::beginFillPass(IRendererRuntime& rendererRuntime, const Renderer::IRenderTarget& renderTarget, const Transform& worldSpaceToViewSpaceTransform, PassBufferManager::PassData& passData)
	{
		// Remember the pass data memory address of the current scope
		mPassData = &passData;

		// Get the render target with and height
		renderTarget.getWidthAndHeight(mRenderTargetWidth, mRenderTargetHeight);
		assert(0 != mRenderTargetWidth);
		assert(0 != mRenderTargetHeight);

		// Get the aspect ratio
		const float aspectRatio = static_cast<float>(mRenderTargetWidth) / mRenderTargetHeight;

		// TODO(co) Use dynamic values
		float fovY = 45.0f;
		float nearZ = 0.1f;
		float farZ = 100.0f;

		// Calculate required matrices basing whether or not the VR-manager is currently running
		glm::mat4 viewSpaceToClipSpaceMatrix;
		glm::mat4 viewTranslateMatrix;
		{
			const IVrManager& vrManager = rendererRuntime.getVrManager();
			if (vrManager.isRunning() && VrEye::UNKNOWN != getCurrentRenderedVrEye())
			{
				const IVrManager::VrEye vrEye = static_cast<IVrManager::VrEye>(getCurrentRenderedVrEye());
				viewSpaceToClipSpaceMatrix = vrManager.getHmdViewSpaceToClipSpaceMatrix(vrEye, nearZ, farZ);
				viewTranslateMatrix = vrManager.getHmdEyeSpaceToHeadSpaceMatrix(vrEye) * vrManager.getHmdPoseMatrix();
			}
			else
			{
				viewSpaceToClipSpaceMatrix = glm::perspective(fovY, aspectRatio, nearZ, farZ);
			}
		}

		// Calculate the final matrices
		mPassData->worldSpaceToViewSpaceMatrix = glm::translate(glm::mat4(1.0f), worldSpaceToViewSpaceTransform.position) * glm::toMat4(worldSpaceToViewSpaceTransform.rotation);
		mPassData->worldSpaceToClipSpaceMatrix = viewSpaceToClipSpaceMatrix * viewTranslateMatrix * mPassData->worldSpaceToViewSpaceMatrix;
	}
Пример #2
0
void FirstMesh::onDraw()
{
    RendererRuntime::IRendererRuntime* rendererRuntime = getRendererRuntime();
    if (nullptr == rendererRuntime)
    {
        return;
    }

    // Due to background texture loading, some textures might not be ready, yet
    // TODO(co) Add dummy textures so rendering also works when textures are not ready, yet
    const RendererRuntime::TextureResources& textureResources = rendererRuntime->getTextureResourceManager().getTextureResources();
    const RendererRuntime::TextureResource* diffuseTextureResource  = textureResources.tryGetElementById(mDiffuseTextureResourceId);
    const RendererRuntime::TextureResource* normalTextureResource   = textureResources.tryGetElementById(mNormalTextureResourceId);
    const RendererRuntime::TextureResource* specularTextureResource = textureResources.tryGetElementById(mSpecularTextureResourceId);
    const RendererRuntime::TextureResource* emissiveTextureResource = textureResources.tryGetElementById(mEmissiveTextureResourceId);
    if (nullptr == diffuseTextureResource || nullptr == diffuseTextureResource->getTexture() ||
            nullptr == normalTextureResource || nullptr == normalTextureResource->getTexture() ||
            nullptr == specularTextureResource || nullptr == specularTextureResource->getTexture() ||
            nullptr == emissiveTextureResource || nullptr == emissiveTextureResource->getTexture())
    {
        return;
    }

    // Get and check the renderer instance
    Renderer::IRendererPtr renderer(getRenderer());
    if (nullptr != renderer && nullptr != mPipelineState)
    {
        // Begin debug event
        COMMAND_BEGIN_DEBUG_EVENT_FUNCTION(mCommandBuffer)

        // Set the viewport and get the aspect ratio
        float aspectRatio = 4.0f / 3.0f;
        {
            // Get the render target with and height
            uint32_t width  = 1;
            uint32_t height = 1;
            Renderer::IRenderTarget *renderTarget = renderer->getMainSwapChain();
            if (nullptr != renderTarget)
            {
                renderTarget->getWidthAndHeight(width, height);

                // Get the aspect ratio
                aspectRatio = static_cast<float>(width) / height;
            }
        }

        // Clear the color buffer of the current render target with gray, do also clear the depth buffer
        Renderer::Command::Clear::create(mCommandBuffer, Renderer::ClearFlag::COLOR_DEPTH, Color4::GRAY, 1.0f, 0);

        // Set the used graphics root signature
        Renderer::Command::SetGraphicsRootSignature::create(mCommandBuffer, mRootSignature);

        // Set sampler and textures
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 0, mUniformBuffer);
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 1, mSamplerState);
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 2, diffuseTextureResource->getTexture());
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 3, normalTextureResource->getTexture());
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 4, specularTextureResource->getTexture());
        Renderer::Command::SetGraphicsRootDescriptorTable::create(mCommandBuffer, 5, emissiveTextureResource->getTexture());

        // Set the used pipeline state object (PSO)
        Renderer::Command::SetPipelineState::create(mCommandBuffer, mPipelineState);

        {   // Set uniform
            // Calculate the object space to clip space matrix
            const glm::mat4 viewSpaceToClipSpace	= glm::perspective(45.0f, aspectRatio, 0.1f, 100.f);
            const glm::mat4 viewTranslate			= glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -7.0f, -25.0f));
            const glm::mat4 worldSpaceToViewSpace	= glm::rotate(viewTranslate, mGlobalTimer, glm::vec3(0.0f, 1.0f, 0.0f));
            const glm::mat4 objectSpaceToWorldSpace	= glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
            glm::mat4 objectSpaceToViewSpace	= worldSpaceToViewSpace * objectSpaceToWorldSpace;
            const glm::mat4 objectSpaceToClipSpace	= viewSpaceToClipSpace * objectSpaceToViewSpace;

            // Upload the uniform data
            // -> Two versions: One using an uniform buffer and one setting an individual uniform
            if (nullptr != mUniformBuffer)
            {
                struct UniformBlockDynamicVs
                {
                    float objectSpaceToClipSpaceMatrix[4 * 4];	// Object space to clip space matrix
                    float objectSpaceToViewSpaceMatrix[4 * 4];	// Object space to view space matrix
                };
                UniformBlockDynamicVs uniformBlockDynamicVS;
                memcpy(uniformBlockDynamicVS.objectSpaceToClipSpaceMatrix, glm::value_ptr(objectSpaceToClipSpace), sizeof(float) * 4 * 4);

                // TODO(co) float3x3 (currently there are alignment issues when using Direct3D, have a look into possible solutions)
                glm::mat3 objectSpaceToViewSpace3x3 = glm::mat3(objectSpaceToViewSpace);
                objectSpaceToViewSpace = glm::mat4(objectSpaceToViewSpace3x3);
                memcpy(uniformBlockDynamicVS.objectSpaceToViewSpaceMatrix, glm::value_ptr(objectSpaceToViewSpace), sizeof(float) * 4 * 4);

                // Copy data
                Renderer::Command::CopyUniformBufferData::create(mCommandBuffer, mUniformBuffer, sizeof(UniformBlockDynamicVs), &uniformBlockDynamicVS);
            }
            else
            {
                // TODO(co) Not compatible with command buffer: This certainly is going to be removed, we need to implement internal uniform buffer emulation
                // Set uniforms
                mProgram->setUniformMatrix4fv(mObjectSpaceToClipSpaceMatrixUniformHandle, glm::value_ptr(objectSpaceToClipSpace));
                mProgram->setUniformMatrix3fv(mObjectSpaceToViewSpaceMatrixUniformHandle, glm::value_ptr(glm::mat3(objectSpaceToViewSpace)));
            }
        }

        {   // Draw mesh instance
            const RendererRuntime::MeshResource* meshResource = rendererRuntime->getMeshResourceManager().getMeshResources().tryGetElementById(mMeshResourceId);
            if (nullptr != meshResource)
            {
                {   // Setup input assembly (IA)
                    // Set the used vertex array
                    Renderer::Command::SetVertexArray::create(mCommandBuffer, meshResource->getVertexArrayPtr());

                    // Set the primitive topology used for draw calls
                    Renderer::Command::SetPrimitiveTopology::create(mCommandBuffer, Renderer::PrimitiveTopology::TRIANGLE_LIST);
                }

                // Render the specified geometric primitive, based on indexing into an array of vertices
                Renderer::Command::DrawIndexed::create(mCommandBuffer, meshResource->getNumberOfIndices());
            }
        }

        // End debug event
        COMMAND_END_DEBUG_EVENT(mCommandBuffer)

        // Submit command buffer to the renderer backend
        mCommandBuffer.submitAndClear(*renderer);
    }