frameBuffer->AttachDepthStencilTexture(texture, mipmapLevel);
}
+void RenderManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel)
+{
+ frameBuffer->SetMultiSamplingLevel(multiSamplingLevel);
+}
+
void RenderManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
{
mImpl->vertexBufferContainer.PushBack(vertexBuffer.Release());
// Clean collected dirty/damaged rects on exit if 3d layer or 3d node or other conditions.
DamagedRectsCleaner damagedRectCleaner(damagedRects, surfaceRect);
+ bool cleanDamagedRect = false;
// Mark previous dirty rects in the sorted array. The array is already sorted by node and renderer, frame number.
// so you don't need to sort: std::stable_sort(itemsDirtyRects.begin(), itemsDirtyRects.end());
if(instruction.mFrameBuffer)
{
- return; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
+ cleanDamagedRect = true;
+ continue; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
}
const Camera* camera = instruction.GetCamera();
- if(camera->mType == Camera::DEFAULT_TYPE && camera->mTargetPosition == Camera::DEFAULT_TARGET_POSITION)
+ if(camera && camera->mType == Camera::DEFAULT_TYPE && camera->mTargetPosition == Camera::DEFAULT_TARGET_POSITION)
{
- const Node* node = instruction.GetCamera()->GetNode();
- if(node)
+ Vector3 position;
+ Vector3 scale;
+ Quaternion orientation;
+ camera->GetWorldMatrix(mImpl->renderBufferIndex).GetTransformComponents(position, orientation, scale);
+
+ Vector3 orientationAxis;
+ Radian orientationAngle;
+ orientation.ToAxisAngle(orientationAxis, orientationAngle);
+
+ if(position.x > Math::MACHINE_EPSILON_10000 ||
+ position.y > Math::MACHINE_EPSILON_10000 ||
+ orientationAxis != Vector3(0.0f, 1.0f, 0.0f) ||
+ orientationAngle != ANGLE_180 ||
+ scale != Vector3(1.0f, 1.0f, 1.0f))
{
- Vector3 position;
- Vector3 scale;
- Quaternion orientation;
- node->GetWorldMatrix(mImpl->renderBufferIndex).GetTransformComponents(position, orientation, scale);
-
- Vector3 orientationAxis;
- Radian orientationAngle;
- orientation.ToAxisAngle(orientationAxis, orientationAngle);
-
- if(position.x > Math::MACHINE_EPSILON_10000 ||
- position.y > Math::MACHINE_EPSILON_10000 ||
- orientationAxis != Vector3(0.0f, 1.0f, 0.0f) ||
- orientationAngle != ANGLE_180 ||
- scale != Vector3(1.0f, 1.0f, 1.0f))
- {
- return;
- }
+ cleanDamagedRect = true;
+ continue;
}
}
else
{
- return;
+ cleanDamagedRect = true;
+ continue;
}
Rect<int32_t> viewportRect;
viewportRect.Set(instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height);
if(viewportRect.IsEmpty() || !viewportRect.IsValid())
{
- return; // just skip funny use cases for now, empty viewport means it is set somewhere else
+ cleanDamagedRect = true;
+ continue; // just skip funny use cases for now, empty viewport means it is set somewhere else
}
}
else
for(uint32_t listIndex = 0u; listIndex < listCount; ++listIndex)
{
RenderItem& item = renderList->GetItem(listIndex);
- // If the item does 3D transformation, do early exit and clean the damaged rect array
+ // If the item does 3D transformation, make full update
if(item.mUpdateArea == Vector4::ZERO)
{
- return;
+ cleanDamagedRect = true;
+
+ // Save the full rect in the damaged list. We need it when this item is removed
+ DirtyRect dirtyRect(item.mNode, item.mRenderer, surfaceRect);
+ auto dirtyRectPos = std::lower_bound(itemsDirtyRects.begin(), itemsDirtyRects.end(), dirtyRect);
+ if(dirtyRectPos != itemsDirtyRects.end() && dirtyRectPos->node == item.mNode && dirtyRectPos->renderer == item.mRenderer)
+ {
+ // Replace the rect
+ dirtyRectPos->visited = true;
+ dirtyRectPos->rect = dirtyRect.rect;
+ }
+ else
+ {
+ // Else, just insert the new dirtyrect in the correct position
+ itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
+ }
+ continue;
}
Rect<int> rect;
// If the item refers to updated node or renderer.
if(item.mIsUpdated ||
(item.mNode &&
- (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated(mImpl->renderBufferIndex, item.mNode)))))
+ (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated(mImpl->renderBufferIndex)))))
{
item.mIsUpdated = false;
- rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(item.mUpdateArea.x, item.mUpdateArea.y, 0.0f), Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f), viewportRect.width, viewportRect.height);
+ Vector4 updateArea = item.mRenderer ? item.mRenderer->GetVisualTransformedUpdateArea(mImpl->renderBufferIndex, item.mUpdateArea) : item.mUpdateArea;
+
+ rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(updateArea.x, updateArea.y, 0.0f), Vector3(updateArea.z, updateArea.w, 0.0f), viewportRect.width, viewportRect.height);
if(rect.IsValid() && rect.Intersect(viewportRect) && !rect.IsEmpty())
{
const int left = rect.x;
{
dirtyRectPos->visited = true;
}
+ else
+ {
+ // The item is not in the list for some reason. Add it!
+ dirtyRect.rect = surfaceRect;
+ itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
+ cleanDamagedRect = true; // And make full update at this frame
+ }
}
}
}
}
itemsDirtyRects.resize(j - itemsDirtyRects.begin());
- damagedRectCleaner.SetCleanOnReturn(false);
- // Reset updated flag from the root
- Layer* root = sceneObject->GetRoot();
- if(root)
+ if(!cleanDamagedRect)
{
- root->SetUpdatedTree(false);
+ damagedRectCleaner.SetCleanOnReturn(false);
}
}
Rect<int32_t> viewportRect;
- int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation();
+ int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation() + sceneObject->GetScreenOrientation();
+ if(surfaceOrientation >= 360)
+ {
+ surfaceOrientation -= 360;
+ }
// @todo Should these be part of scene?
Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable;
// Scissor's value should be set based on the default system coordinates.
// When the surface is rotated, the input values already were set with the rotated angle.
// So, re-calculation is needed.
- scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, viewportRect);
+ scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, surfaceRect);
// Begin render pass
mainCommandBuffer->BeginRenderPass(
mImpl->boundTextures,
viewportRect,
clippingRect,
- surfaceOrientation);
+ surfaceOrientation,
+ Uint16Pair(surfaceRect.width, surfaceRect.height));
Graphics::SyncObject* syncObject{nullptr};
// If the render instruction has an associated render tracker (owned separately)
{
if(!mImpl->commandBufferSubmitted)
{
- // Rendering is skipped but there may be pending commands
- // Submit command buffers
- mImpl->renderAlgorithms.SubmitCommandBuffer();
+ // Rendering is skipped but there may be pending tasks. Flush them.
+ Graphics::SubmitInfo submitInfo;
+ submitInfo.cmdBuffer.clear(); // Only flush
+ submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
+ mImpl->graphicsController.SubmitCommandBuffers(submitInfo);
+
mImpl->commandBufferSubmitted = true;
}
iter->OnRenderFinished();
}
+ // Notify RenderTexture that rendering has finished
+ for(auto&& iter : mImpl->textureContainer)
+ {
+ iter->OnRenderFinished();
+ }
+
mImpl->UpdateTrackers();
uint32_t count = 0u;