示例#1
0
void IApplicationRendererRuntime::onUpdate()
{
	RendererRuntime::IRendererRuntime* rendererRuntime = getRendererRuntime();
	if (nullptr != rendererRuntime)
	{
		rendererRuntime->update();
	}
}
示例#2
0
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void IApplicationRendererRuntime::onInitialization()
{
	// Call the base implementation
	IApplicationRenderer::onInitialization();

	// Is there a valid renderer instance?
	Renderer::IRenderer *renderer = getRenderer();
	if (nullptr != renderer)
	{
		// Create the renderer runtime instance
		mRendererRuntimeInstance = new RendererRuntime::RendererRuntimeInstance(*renderer);

		{
			RendererRuntime::IRendererRuntime* rendererRuntime = getRendererRuntime();
			if (nullptr != rendererRuntime)
			{
				// TODO(co) Under construction: Will probably become "mount asset package"
				// Add used asset package
			//	rendererRuntime->getAssetManager().addAssetPackageByFilename("../DataMobile/Content/AssetPackage.assets");
				rendererRuntime->getAssetManager().addAssetPackageByFilename("../DataPc/Content/AssetPackage.assets");

				#ifdef SHARED_LIBRARIES
				{
					// TODO(co) First asset hot-reloading test
					RendererToolkit::IRendererToolkit* rendererToolkit = getRendererToolkit();
					if (nullptr != rendererToolkit)
					{
						mProject = rendererToolkit->createProject();
						if (nullptr != mProject)
						{
							try
							{
								mProject->loadByFilename("../DataSource/Example.project");
								// TODO(co) Renderer check
							//	mProject->startupAssetMonitor(*rendererRuntime, "OpenGLES2_100");
								mProject->startupAssetMonitor(*rendererRuntime, "Direct3D11_50");
							}
							catch (const std::exception& e)
							{
								const char* text = e.what();
								text = text;
							}
						}
					}
				}
				#endif
			}
		}
	}
}
示例#3
0
//[-------------------------------------------------------]
//[ Public virtual IApplication methods                   ]
//[-------------------------------------------------------]
void FirstMesh::onInitialization()
{
    // Call the base implementation
    IApplicationRendererRuntime::onInitialization();

    // Get and check the renderer runtime instance
    RendererRuntime::IRendererRuntime* rendererRuntime = getRendererRuntime();
    if (nullptr != rendererRuntime)
    {
        Renderer::IRendererPtr renderer(getRenderer());

        // Create uniform buffers
        // -> Direct3D 9 and OpenGL ES 2 do not support uniform buffers
        // -> Direct3D 10, 11 and 12 do not support individual uniforms
        // -> The renderer is just a light weight abstraction layer, so we need to handle the differences
        if ((0 == strcmp(renderer->getName(), "Direct3D10") || 0 == strcmp(renderer->getName(), "Direct3D11") || 0 == strcmp(renderer->getName(), "Direct3D12")))
        {
            // Allocate enough memory for two 4x4 floating point matrices
            mUniformBuffer = rendererRuntime->getBufferManager().createUniformBuffer(2 * 4 * 4 * sizeof(float), nullptr, Renderer::BufferUsage::DYNAMIC_DRAW);
        }

        // Decide which shader language should be used (for example "GLSL" or "HLSL")
        Renderer::IShaderLanguagePtr shaderLanguage(renderer->getShaderLanguage());
        if (nullptr != shaderLanguage)
        {
            // Vertex input layout
            const Renderer::VertexAttribute vertexAttributesLayout[] =
            {
                {   // Attribute 0
                    // Data destination
                    Renderer::VertexAttributeFormat::FLOAT_3,	// vertexAttributeFormat (Renderer::VertexAttributeFormat)
                    "Position",									// name[32] (char)
                    "POSITION",									// semanticName[32] (char)
                    0,											// semanticIndex (uint32_t)
                    // Data source
                    0,											// inputSlot (uint32_t)
                    0,											// alignedByteOffset (uint32_t)
                    // Data source, instancing part
                    0											// instancesPerElement (uint32_t)
                },
                {   // Attribute 1
                    // Data destination
                    Renderer::VertexAttributeFormat::SHORT_2,	// vertexAttributeFormat (Renderer::VertexAttributeFormat)
                    "TexCoord",									// name[32] (char)
                    "TEXCOORD",									// semanticName[32] (char)
                    0,											// semanticIndex (uint32_t)
                    // Data source
                    0,											// inputSlot (uint32_t)
                    sizeof(float) * 3,							// alignedByteOffset (uint32_t)
                    // Data source, instancing part
                    0											// instancesPerElement (uint32_t)
                },
                {   // Attribute 2
                    // Data destination
                    Renderer::VertexAttributeFormat::SHORT_4,	// vertexAttributeFormat (Renderer::VertexAttributeFormat)
                    "QTangent",									// name[32] (char)
                    "TEXCOORD",									// semanticName[32] (char)
                    1,											// semanticIndex (uint32_t)
                    // Data source
                    0,											// inputSlot (uint32_t)
                    sizeof(float) * 3 + sizeof(short) * 2,		// alignedByteOffset (uint32_t)
                    // Data source, instancing part
                    0											// instancesPerElement (uint32_t)
                }
            };
            const Renderer::VertexAttributes vertexAttributes(glm::countof(vertexAttributesLayout), vertexAttributesLayout);

            {   // Create the root signature
                Renderer::DescriptorRangeBuilder ranges[6];
                ranges[0].initialize(Renderer::DescriptorRangeType::UBV, 1, 0, "UniformBlockDynamicVs", 0);
                ranges[1].initializeSampler(1, 0);
                ranges[2].initialize(Renderer::DescriptorRangeType::SRV, 1, 0, "DiffuseMap", 1);
                ranges[3].initialize(Renderer::DescriptorRangeType::SRV, 1, 1, "EmissiveMap", 1);
                ranges[4].initialize(Renderer::DescriptorRangeType::SRV, 1, 2, "NormalMap", 1);
                ranges[5].initialize(Renderer::DescriptorRangeType::SRV, 1, 3, "SpecularMap", 1);

                Renderer::RootParameterBuilder rootParameters[6];
                rootParameters[0].initializeAsDescriptorTable(1, &ranges[0], Renderer::ShaderVisibility::VERTEX);
                rootParameters[1].initializeAsDescriptorTable(1, &ranges[1], Renderer::ShaderVisibility::FRAGMENT);
                rootParameters[2].initializeAsDescriptorTable(1, &ranges[2], Renderer::ShaderVisibility::FRAGMENT);
                rootParameters[3].initializeAsDescriptorTable(1, &ranges[3], Renderer::ShaderVisibility::FRAGMENT);
                rootParameters[4].initializeAsDescriptorTable(1, &ranges[4], Renderer::ShaderVisibility::FRAGMENT);
                rootParameters[5].initializeAsDescriptorTable(1, &ranges[5], Renderer::ShaderVisibility::FRAGMENT);

                // Setup
                Renderer::RootSignatureBuilder rootSignature;
                rootSignature.initialize(glm::countof(rootParameters), rootParameters, 0, nullptr, Renderer::RootSignatureFlags::ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

                // Create the instance
                mRootSignature = renderer->createRootSignature(rootSignature);
            }

            // Create the program
            Renderer::IProgramPtr program;
            {
                // Get the shader source code (outsourced to keep an overview)
                const char *vertexShaderProfile = nullptr;
                const char *vertexShaderSourceCode = nullptr;
                const char *fragmentShaderProfile = nullptr;
                const char *fragmentShaderSourceCode = nullptr;
#include "FirstMesh_GLSL_410.h"
#include "FirstMesh_GLSL_ES2.h"
#include "FirstMesh_HLSL_D3D9.h"
#include "FirstMesh_HLSL_D3D10_D3D11_D3D12.h"
#include "FirstMesh_Null.h"

                // Create the program
                mProgram = program = shaderLanguage->createProgram(
                                         *mRootSignature,
                                         vertexAttributes,
                                         shaderLanguage->createVertexShaderFromSourceCode(vertexAttributes, vertexShaderSourceCode, vertexShaderProfile),
                                         shaderLanguage->createFragmentShaderFromSourceCode(fragmentShaderSourceCode, fragmentShaderProfile));
            }

            // Is there a valid program?
            if (nullptr != program)
            {
                // Create the pipeline state object (PSO)
                mPipelineState = renderer->createPipelineState(Renderer::PipelineStateBuilder(mRootSignature, program, vertexAttributes));

                // Optimization: Cached data to not bother the renderer API too much
                if (nullptr == mUniformBuffer)
                {
                    mObjectSpaceToClipSpaceMatrixUniformHandle = program->getUniformHandle("ObjectSpaceToClipSpaceMatrix");
                    mObjectSpaceToViewSpaceMatrixUniformHandle = program->getUniformHandle("ObjectSpaceToViewSpaceMatrix");
                }
            }

            // Create mesh instance
            mMeshResourceId = rendererRuntime->getMeshResourceManager().loadMeshResourceByAssetId("Example/Mesh/Character/Imrod");

            {   // Load in the diffuse, emissive, normal and specular texture
                // -> The tangent space normal map is stored with three components, two would be enough to recalculate the third component within the fragment shader
                // -> The specular map could be put into the alpha channel of the diffuse map instead of storing it as an individual texture
                RendererRuntime::TextureResourceManager& textureResourceManager = rendererRuntime->getTextureResourceManager();
                mDiffuseTextureResourceId  = textureResourceManager.loadTextureResourceByAssetId("Example/Texture/Character/ImrodDiffuseMap");
                mNormalTextureResourceId   = textureResourceManager.loadTextureResourceByAssetId("Example/Texture/Character/ImrodEmissiveMap");
                mSpecularTextureResourceId = textureResourceManager.loadTextureResourceByAssetId("Example/Texture/Character/ImrodNormalMap");
                mEmissiveTextureResourceId = textureResourceManager.loadTextureResourceByAssetId("Example/Texture/Character/ImrodSpecularMap");
            }

            {   // Create sampler state
                Renderer::SamplerState samplerStateSettings = Renderer::ISamplerState::getDefaultSamplerState();
                samplerStateSettings.addressU = Renderer::TextureAddressMode::WRAP;
                samplerStateSettings.addressV = Renderer::TextureAddressMode::WRAP;
                mSamplerState = renderer->createSamplerState(samplerStateSettings);
            }
        }
    }
}
示例#4
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);
    }