//[-------------------------------------------------------] //[ 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; }
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); }