|
@@ -436,7 +436,7 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
// Check if ambient pass and G-buffer rendering happens at the same time
|
|
// Check if ambient pass and G-buffer rendering happens at the same time
|
|
|
- if (command.type_ == CMD_SCENEPASS && command.outputNames_.Size() > 1)
|
|
|
|
|
|
|
+ if (command.type_ == CMD_SCENEPASS && command.outputs_.Size() > 1)
|
|
|
{
|
|
{
|
|
|
if (CheckViewportWrite(command))
|
|
if (CheckViewportWrite(command))
|
|
|
deferredAmbient_ = true;
|
|
deferredAmbient_ = true;
|
|
@@ -627,7 +627,7 @@ void View::Render()
|
|
|
|
|
|
|
|
// Run framebuffer blitting if necessary
|
|
// Run framebuffer blitting if necessary
|
|
|
if (currentRenderTarget_ != renderTarget_)
|
|
if (currentRenderTarget_ != renderTarget_)
|
|
|
- BlitFramebuffer(static_cast<Texture2D*>(currentRenderTarget_->GetParentTexture()), renderTarget_, true);
|
|
|
|
|
|
|
+ BlitFramebuffer(currentRenderTarget_->GetParentTexture(), renderTarget_, true);
|
|
|
|
|
|
|
|
// "Forget" the scene, camera, octree and zone after rendering
|
|
// "Forget" the scene, camera, octree and zone after rendering
|
|
|
scene_ = 0;
|
|
scene_ = 0;
|
|
@@ -1433,7 +1433,7 @@ void View::ExecuteRenderPathCommands()
|
|
|
{
|
|
{
|
|
|
if (!currentRenderTarget_)
|
|
if (!currentRenderTarget_)
|
|
|
{
|
|
{
|
|
|
- graphics_->ResolveToTexture(viewportTextures_[0], viewRect_);
|
|
|
|
|
|
|
+ graphics_->ResolveToTexture(dynamic_cast<Texture2D*>(viewportTextures_[0]), viewRect_);
|
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
|
viewportModified = false;
|
|
viewportModified = false;
|
|
|
}
|
|
}
|
|
@@ -1441,8 +1441,8 @@ void View::ExecuteRenderPathCommands()
|
|
|
{
|
|
{
|
|
|
if (viewportWrite)
|
|
if (viewportWrite)
|
|
|
{
|
|
{
|
|
|
- BlitFramebuffer(static_cast<Texture2D*>(currentRenderTarget_->GetParentTexture()),
|
|
|
|
|
- viewportTextures_[0]->GetRenderSurface(), false);
|
|
|
|
|
|
|
+ BlitFramebuffer(currentRenderTarget_->GetParentTexture(),
|
|
|
|
|
+ GetRenderSurfaceFromTexture(viewportTextures_[0]), false);
|
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
|
viewportModified = false;
|
|
viewportModified = false;
|
|
|
}
|
|
}
|
|
@@ -1451,7 +1451,7 @@ void View::ExecuteRenderPathCommands()
|
|
|
// If the current render target is already a texture, and we are not writing to it, can read that
|
|
// If the current render target is already a texture, and we are not writing to it, can read that
|
|
|
// texture directly instead of blitting. However keep the viewport dirty flag in case a later command
|
|
// texture directly instead of blitting. However keep the viewport dirty flag in case a later command
|
|
|
// will do both read and write, and then we need to blit / resolve
|
|
// will do both read and write, and then we need to blit / resolve
|
|
|
- currentViewportTexture_ = static_cast<Texture2D*>(currentRenderTarget_->GetParentTexture());
|
|
|
|
|
|
|
+ currentViewportTexture_ = currentRenderTarget_->GetParentTexture();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1459,7 +1459,7 @@ void View::ExecuteRenderPathCommands()
|
|
|
{
|
|
{
|
|
|
// Swap the pingpong double buffer sides. Texture 0 will be read next
|
|
// Swap the pingpong double buffer sides. Texture 0 will be read next
|
|
|
viewportTextures_[1] = viewportTextures_[0];
|
|
viewportTextures_[1] = viewportTextures_[0];
|
|
|
- viewportTextures_[0] = static_cast<Texture2D*>(currentRenderTarget_->GetParentTexture());
|
|
|
|
|
|
|
+ viewportTextures_[0] = currentRenderTarget_->GetParentTexture();
|
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
currentViewportTexture_ = viewportTextures_[0];
|
|
|
viewportModified = false;
|
|
viewportModified = false;
|
|
|
}
|
|
}
|
|
@@ -1473,7 +1473,7 @@ void View::ExecuteRenderPathCommands()
|
|
|
{
|
|
{
|
|
|
if (isPingponging)
|
|
if (isPingponging)
|
|
|
{
|
|
{
|
|
|
- currentRenderTarget_ = viewportTextures_[1]->GetRenderSurface();
|
|
|
|
|
|
|
+ currentRenderTarget_ = GetRenderSurfaceFromTexture(viewportTextures_[1]);
|
|
|
// If the render path ends into a quad, it can be redirected to the final render target
|
|
// If the render path ends into a quad, it can be redirected to the final render target
|
|
|
// However, on OpenGL we can not reliably do this in case the final target is the backbuffer, and we want to
|
|
// However, on OpenGL we can not reliably do this in case the final target is the backbuffer, and we want to
|
|
|
// render depth buffer sensitive debug geometry afterward (backbuffer and textures can not share depth)
|
|
// render depth buffer sensitive debug geometry afterward (backbuffer and textures can not share depth)
|
|
@@ -1620,38 +1620,33 @@ void View::SetRenderTargets(RenderPathCommand& command)
|
|
|
bool useColorWrite = true;
|
|
bool useColorWrite = true;
|
|
|
bool useCustomDepth = false;
|
|
bool useCustomDepth = false;
|
|
|
|
|
|
|
|
- while (index < command.outputNames_.Size())
|
|
|
|
|
|
|
+ while (index < command.outputs_.Size())
|
|
|
{
|
|
{
|
|
|
- if (!command.outputNames_[index].Compare("viewport", false))
|
|
|
|
|
|
|
+ if (!command.outputs_[index].first_.Compare("viewport", false))
|
|
|
graphics_->SetRenderTarget(index, currentRenderTarget_);
|
|
graphics_->SetRenderTarget(index, currentRenderTarget_);
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- StringHash nameHash(command.outputNames_[index]);
|
|
|
|
|
- if (renderTargets_.Contains(nameHash))
|
|
|
|
|
|
|
+ Texture* texture = FindNamedTexture(command.outputs_[index].first_, true, false);
|
|
|
|
|
+
|
|
|
|
|
+ // Check for depth only rendering (by specifying a depth texture as the sole output)
|
|
|
|
|
+ if (!index && command.outputs_.Size() == 1 && texture && (texture->GetFormat() ==
|
|
|
|
|
+ Graphics::GetReadableDepthFormat() || texture->GetFormat() == Graphics::GetDepthStencilFormat()))
|
|
|
{
|
|
{
|
|
|
- Texture2D* texture = renderTargets_[nameHash];
|
|
|
|
|
- // Check for depth only rendering (by specifying a depth texture as the sole output)
|
|
|
|
|
- if (!index && command.outputNames_.Size() == 1 && texture && (texture->GetFormat() ==
|
|
|
|
|
- Graphics::GetReadableDepthFormat() || texture->GetFormat() == Graphics::GetDepthStencilFormat()))
|
|
|
|
|
|
|
+ useColorWrite = false;
|
|
|
|
|
+ useCustomDepth = true;
|
|
|
|
|
+ #if !defined(URHO3D_OPENGL) && !defined(URHO3D_D3D11)
|
|
|
|
|
+ // On D3D actual depth-only rendering is illegal, we need a color rendertarget
|
|
|
|
|
+ if (!depthOnlyDummyTexture_)
|
|
|
{
|
|
{
|
|
|
- useColorWrite = false;
|
|
|
|
|
- useCustomDepth = true;
|
|
|
|
|
- #if !defined(URHO3D_OPENGL) && !defined(URHO3D_D3D11)
|
|
|
|
|
- // On D3D9 actual depth-only rendering is illegal, we need a color rendertarget
|
|
|
|
|
- if (!depthOnlyDummyTexture_)
|
|
|
|
|
- {
|
|
|
|
|
- depthOnlyDummyTexture_ = renderer_->GetScreenBuffer(texture->GetWidth(), texture->GetHeight(),
|
|
|
|
|
- graphics_->GetDummyColorFormat(), false, false);
|
|
|
|
|
- }
|
|
|
|
|
- #endif
|
|
|
|
|
- graphics_->SetRenderTarget(0, depthOnlyDummyTexture_);
|
|
|
|
|
- graphics_->SetDepthStencil(texture);
|
|
|
|
|
|
|
+ depthOnlyDummyTexture_ = renderer_->GetScreenBuffer(texture->GetWidth(), texture->GetHeight(),
|
|
|
|
|
+ graphics_->GetDummyColorFormat(), false, false, false);
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- graphics_->SetRenderTarget(index, texture);
|
|
|
|
|
|
|
+ #endif
|
|
|
|
|
+ graphics_->SetRenderTarget(0, GetRenderSurfaceFromTexture(depthOnlyDummyTexture_));
|
|
|
|
|
+ graphics_->SetDepthStencil(GetRenderSurfaceFromTexture(texture));
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
- graphics_->SetRenderTarget(0, (RenderSurface*)0);
|
|
|
|
|
|
|
+ graphics_->SetRenderTarget(index, GetRenderSurfaceFromTexture(texture, command.outputs_[index].second_));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
++index;
|
|
++index;
|
|
@@ -1665,11 +1660,11 @@ void View::SetRenderTargets(RenderPathCommand& command)
|
|
|
|
|
|
|
|
if (command.depthStencilName_.Length())
|
|
if (command.depthStencilName_.Length())
|
|
|
{
|
|
{
|
|
|
- Texture2D* depthTexture = renderTargets_[StringHash(command.depthStencilName_)];
|
|
|
|
|
|
|
+ Texture* depthTexture = FindNamedTexture(command.depthStencilName_, true, false);
|
|
|
if (depthTexture)
|
|
if (depthTexture)
|
|
|
{
|
|
{
|
|
|
useCustomDepth = true;
|
|
useCustomDepth = true;
|
|
|
- graphics_->SetDepthStencil(depthTexture);
|
|
|
|
|
|
|
+ graphics_->SetDepthStencil(GetRenderSurfaceFromTexture(depthTexture));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1703,36 +1698,14 @@ bool View::SetTextures(RenderPathCommand& command)
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Bind a rendertarget
|
|
|
|
|
- HashMap<StringHash, Texture2D*>::ConstIterator j = renderTargets_.Find(command.textureNames_[i]);
|
|
|
|
|
- if (j != renderTargets_.End())
|
|
|
|
|
|
|
+ Texture* texture = FindNamedTexture(command.textureNames_[i], false, i == TU_VOLUMEMAP);
|
|
|
|
|
+ if (texture)
|
|
|
{
|
|
{
|
|
|
- graphics_->SetTexture(i, j->second_);
|
|
|
|
|
|
|
+ graphics_->SetTexture(i, texture);
|
|
|
// Check if the current depth stencil is being sampled
|
|
// Check if the current depth stencil is being sampled
|
|
|
- if (graphics_->GetDepthStencil() && j->second_ == graphics_->GetDepthStencil()->GetParentTexture())
|
|
|
|
|
|
|
+ if (graphics_->GetDepthStencil() && texture == graphics_->GetDepthStencil()->GetParentTexture())
|
|
|
allowDepthWrite = false;
|
|
allowDepthWrite = false;
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Bind a texture from the resource system
|
|
|
|
|
- Texture* texture;
|
|
|
|
|
-
|
|
|
|
|
- // Detect cube/3D textures by file extension: they are defined by an XML file
|
|
|
|
|
- if (GetExtension(command.textureNames_[i]) == ".xml")
|
|
|
|
|
- {
|
|
|
|
|
- // Assume 3D textures are only bound to the volume map unit, otherwise it's a cube texture
|
|
|
|
|
- #ifdef DESKTOP_GRAPHICS
|
|
|
|
|
- if (i == TU_VOLUMEMAP)
|
|
|
|
|
- texture = cache->GetResource<Texture3D>(command.textureNames_[i]);
|
|
|
|
|
- else
|
|
|
|
|
- #endif
|
|
|
|
|
- texture = cache->GetResource<TextureCube>(command.textureNames_[i]);
|
|
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- texture = cache->GetResource<Texture2D>(command.textureNames_[i]);
|
|
|
|
|
-
|
|
|
|
|
- if (texture)
|
|
|
|
|
- graphics_->SetTexture(i, texture);
|
|
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
// If requesting a texture fails, clear the texture name to prevent redundant attempts
|
|
// If requesting a texture fails, clear the texture name to prevent redundant attempts
|
|
@@ -1805,7 +1778,7 @@ void View::RenderQuad(RenderPathCommand& command)
|
|
|
|
|
|
|
|
bool View::IsNecessary(const RenderPathCommand& command)
|
|
bool View::IsNecessary(const RenderPathCommand& command)
|
|
|
{
|
|
{
|
|
|
- return command.enabled_ && command.outputNames_.Size() && (command.type_ != CMD_SCENEPASS ||
|
|
|
|
|
|
|
+ return command.enabled_ && command.outputs_.Size() && (command.type_ != CMD_SCENEPASS ||
|
|
|
!batchQueues_[command.passIndex_].IsEmpty());
|
|
!batchQueues_[command.passIndex_].IsEmpty());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1822,9 +1795,9 @@ bool View::CheckViewportRead(const RenderPathCommand& command)
|
|
|
|
|
|
|
|
bool View::CheckViewportWrite(const RenderPathCommand& command)
|
|
bool View::CheckViewportWrite(const RenderPathCommand& command)
|
|
|
{
|
|
{
|
|
|
- for (unsigned i = 0; i < command.outputNames_.Size(); ++i)
|
|
|
|
|
|
|
+ for (unsigned i = 0; i < command.outputs_.Size(); ++i)
|
|
|
{
|
|
{
|
|
|
- if (!command.outputNames_[i].Compare("viewport", false))
|
|
|
|
|
|
|
+ if (!command.outputs_[i].first_.Compare("viewport", false))
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1877,7 +1850,7 @@ void View::AllocateScreenBuffers()
|
|
|
const RenderPathCommand& command = renderPath_->commands_[i];
|
|
const RenderPathCommand& command = renderPath_->commands_[i];
|
|
|
if (!IsNecessary(command))
|
|
if (!IsNecessary(command))
|
|
|
continue;
|
|
continue;
|
|
|
- if (command.depthStencilName_.Length() && command.outputNames_.Size() && !command.outputNames_[0].Compare("viewport",
|
|
|
|
|
|
|
+ if (command.depthStencilName_.Length() && command.outputs_.Size() && !command.outputs_[0].first_.Compare("viewport",
|
|
|
false))
|
|
false))
|
|
|
{
|
|
{
|
|
|
needSubstitute = true;
|
|
needSubstitute = true;
|
|
@@ -1906,11 +1879,11 @@ void View::AllocateScreenBuffers()
|
|
|
continue;
|
|
continue;
|
|
|
if (command.depthStencilName_.Length())
|
|
if (command.depthStencilName_.Length())
|
|
|
needSubstitute = true;
|
|
needSubstitute = true;
|
|
|
- if (!needSubstitute && command.outputNames_.Size() > 1)
|
|
|
|
|
|
|
+ if (!needSubstitute && command.outputs_.Size() > 1)
|
|
|
{
|
|
{
|
|
|
- for (unsigned j = 0; j < command.outputNames_.Size(); ++j)
|
|
|
|
|
|
|
+ for (unsigned j = 0; j < command.outputs_.Size(); ++j)
|
|
|
{
|
|
{
|
|
|
- if (!command.outputNames_[j].Compare("viewport", false))
|
|
|
|
|
|
|
+ if (!command.outputs_[j].first_.Compare("viewport", false))
|
|
|
{
|
|
{
|
|
|
needSubstitute = true;
|
|
needSubstitute = true;
|
|
|
break;
|
|
break;
|
|
@@ -1982,16 +1955,16 @@ void View::AllocateScreenBuffers()
|
|
|
// Allocate screen buffers with filtering active in case the quad commands need that
|
|
// Allocate screen buffers with filtering active in case the quad commands need that
|
|
|
// Follow the sRGB mode of the destination render target
|
|
// Follow the sRGB mode of the destination render target
|
|
|
bool sRGB = renderTarget_ ? renderTarget_->GetParentTexture()->GetSRGB() : graphics_->GetSRGB();
|
|
bool sRGB = renderTarget_ ? renderTarget_->GetParentTexture()->GetSRGB() : graphics_->GetSRGB();
|
|
|
- substituteRenderTarget_ = needSubstitute ? renderer_->GetScreenBuffer(viewSize_.x_, viewSize_.y_, format, true,
|
|
|
|
|
- sRGB)->GetRenderSurface() : (RenderSurface*)0;
|
|
|
|
|
|
|
+ substituteRenderTarget_ = needSubstitute ? GetRenderSurfaceFromTexture(renderer_->GetScreenBuffer(viewSize_.x_, viewSize_.y_,
|
|
|
|
|
+ format, false, true, sRGB)) : (RenderSurface*)0;
|
|
|
for (unsigned i = 0; i < MAX_VIEWPORT_TEXTURES; ++i)
|
|
for (unsigned i = 0; i < MAX_VIEWPORT_TEXTURES; ++i)
|
|
|
{
|
|
{
|
|
|
- viewportTextures_[i] = i < numViewportTextures ? renderer_->GetScreenBuffer(viewSize_.x_, viewSize_.y_, format, true, sRGB) :
|
|
|
|
|
- (Texture2D*)0;
|
|
|
|
|
|
|
+ viewportTextures_[i] = i < numViewportTextures ? renderer_->GetScreenBuffer(viewSize_.x_, viewSize_.y_, format, false, true, sRGB) :
|
|
|
|
|
+ (Texture*)0;
|
|
|
}
|
|
}
|
|
|
// If using a substitute render target and pingponging, the substitute can act as the second viewport texture
|
|
// If using a substitute render target and pingponging, the substitute can act as the second viewport texture
|
|
|
if (numViewportTextures == 1 && substituteRenderTarget_)
|
|
if (numViewportTextures == 1 && substituteRenderTarget_)
|
|
|
- viewportTextures_[1] = static_cast<Texture2D*>(substituteRenderTarget_->GetParentTexture());
|
|
|
|
|
|
|
+ viewportTextures_[1] = substituteRenderTarget_->GetParentTexture();
|
|
|
|
|
|
|
|
// Allocate extra render targets defined by the rendering path
|
|
// Allocate extra render targets defined by the rendering path
|
|
|
for (unsigned i = 0; i < renderPath_->renderTargets_.Size(); ++i)
|
|
for (unsigned i = 0; i < renderPath_->renderTargets_.Size(); ++i)
|
|
@@ -2018,12 +1991,12 @@ void View::AllocateScreenBuffers()
|
|
|
int intHeight = (int)(height + 0.5f);
|
|
int intHeight = (int)(height + 0.5f);
|
|
|
|
|
|
|
|
// If the rendertarget is persistent, key it with a hash derived from the RT name and the view's pointer
|
|
// If the rendertarget is persistent, key it with a hash derived from the RT name and the view's pointer
|
|
|
- renderTargets_[rtInfo.name_] = renderer_->GetScreenBuffer(intWidth, intHeight, rtInfo.format_, rtInfo.filtered_,
|
|
|
|
|
|
|
+ renderTargets_[rtInfo.name_] = renderer_->GetScreenBuffer(intWidth, intHeight, rtInfo.format_, rtInfo.cubemap_, rtInfo.filtered_,
|
|
|
rtInfo.sRGB_, rtInfo.persistent_ ? StringHash(rtInfo.name_).Value() + (unsigned)(size_t)this : 0);
|
|
rtInfo.sRGB_, rtInfo.persistent_ ? StringHash(rtInfo.name_).Value() + (unsigned)(size_t)this : 0);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void View::BlitFramebuffer(Texture2D* source, RenderSurface* destination, bool depthWrite)
|
|
|
|
|
|
|
+void View::BlitFramebuffer(Texture* source, RenderSurface* destination, bool depthWrite)
|
|
|
{
|
|
{
|
|
|
if (!source)
|
|
if (!source)
|
|
|
return;
|
|
return;
|
|
@@ -2036,7 +2009,7 @@ void View::BlitFramebuffer(Texture2D* source, RenderSurface* destination, bool d
|
|
|
IntVector2 destSize = destination ? IntVector2(destination->GetWidth(), destination->GetHeight()) : IntVector2(
|
|
IntVector2 destSize = destination ? IntVector2(destination->GetWidth(), destination->GetHeight()) : IntVector2(
|
|
|
graphics_->GetWidth(), graphics_->GetHeight());
|
|
graphics_->GetWidth(), graphics_->GetHeight());
|
|
|
|
|
|
|
|
- IntRect srcRect = (source->GetRenderSurface() == renderTarget_) ? viewRect_ : IntRect(0, 0, srcSize.x_, srcSize.y_);
|
|
|
|
|
|
|
+ IntRect srcRect = (GetRenderSurfaceFromTexture(source) == renderTarget_) ? viewRect_ : IntRect(0, 0, srcSize.x_, srcSize.y_);
|
|
|
IntRect destRect = (destination == renderTarget_) ? viewRect_ : IntRect(0, 0, destSize.x_, destSize.y_);
|
|
IntRect destRect = (destination == renderTarget_) ? viewRect_ : IntRect(0, 0, destSize.x_, destSize.y_);
|
|
|
|
|
|
|
|
graphics_->SetBlendMode(BLEND_REPLACE);
|
|
graphics_->SetBlendMode(BLEND_REPLACE);
|
|
@@ -2961,4 +2934,56 @@ RenderSurface* View::GetDepthStencil(RenderSurface* renderTarget)
|
|
|
return depthStencil;
|
|
return depthStencil;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+RenderSurface* View::GetRenderSurfaceFromTexture(Texture* texture, CubeMapFace face)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!texture)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+ if (texture->GetType() == Texture2D::GetTypeStatic())
|
|
|
|
|
+ return static_cast<Texture2D*>(texture)->GetRenderSurface();
|
|
|
|
|
+ else if (texture->GetType() == TextureCube::GetTypeStatic())
|
|
|
|
|
+ return static_cast<TextureCube*>(texture)->GetRenderSurface(face);
|
|
|
|
|
+ else
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+Texture* View::FindNamedTexture(const String& name, bool isRenderTarget, bool isVolumeMap)
|
|
|
|
|
+{
|
|
|
|
|
+ // Check rendertargets first
|
|
|
|
|
+ StringHash nameHash(name);
|
|
|
|
|
+ if (renderTargets_.Contains(nameHash))
|
|
|
|
|
+ return renderTargets_[nameHash];
|
|
|
|
|
+
|
|
|
|
|
+ // Then the resource system
|
|
|
|
|
+ ResourceCache* cache = GetSubsystem<ResourceCache>();
|
|
|
|
|
+
|
|
|
|
|
+ // Check existing resources first. This does not load resources, so we can afford to guess the resource type wrong
|
|
|
|
|
+ // without having to rely on the file extension
|
|
|
|
|
+ Texture* texture = cache->GetExistingResource<Texture2D>(name);
|
|
|
|
|
+ if (!texture)
|
|
|
|
|
+ texture = cache->GetExistingResource<TextureCube>(name);
|
|
|
|
|
+ if (!texture)
|
|
|
|
|
+ texture = cache->GetExistingResource<Texture3D>(name);
|
|
|
|
|
+ if (texture)
|
|
|
|
|
+ return texture;
|
|
|
|
|
+
|
|
|
|
|
+ // If not a rendertarget (which will never be loaded from a file), finally also try to load the texture
|
|
|
|
|
+ // This will log an error if not found; the texture binding will be cleared in that case to not constantly spam the log
|
|
|
|
|
+ if (!isRenderTarget)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (GetExtension(name) == ".xml")
|
|
|
|
|
+ {
|
|
|
|
|
+ // Assume 3D textures are only bound to the volume map unit, otherwise it's a cube texture
|
|
|
|
|
+ #ifdef DESKTOP_GRAPHICS
|
|
|
|
|
+ if (isVolumeMap)
|
|
|
|
|
+ return cache->GetResource<Texture3D>(name);
|
|
|
|
|
+ else
|
|
|
|
|
+ #endif
|
|
|
|
|
+ return cache->GetResource<TextureCube>(name);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ return cache->GetResource<Texture2D>(name);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
}
|
|
}
|