axmol/extensions/Effekseer/EffekseerRendererLLGI/EffekseerRendererLLGI.Rende...

920 lines
30 KiB
C++

#include "EffekseerRendererLLGI.Renderer.h"
#include "EffekseerRendererLLGI.RenderState.h"
#include "EffekseerRendererLLGI.RendererImplemented.h"
#include "EffekseerRendererLLGI.DeviceObject.h"
#include "EffekseerRendererLLGI.IndexBuffer.h"
#include "EffekseerRendererLLGI.MaterialLoader.h"
#include "EffekseerRendererLLGI.ModelRenderer.h"
#include "EffekseerRendererLLGI.Shader.h"
#include "EffekseerRendererLLGI.VertexBuffer.h"
#include "../EffekseerRendererCommon/EffekseerRenderer.RibbonRendererBase.h"
#include "../EffekseerRendererCommon/EffekseerRenderer.RingRendererBase.h"
#include "../EffekseerRendererCommon/EffekseerRenderer.SpriteRendererBase.h"
#include "../EffekseerRendererCommon/EffekseerRenderer.TrackRendererBase.h"
#include "../EffekseerRendererCommon/ModelLoader.h"
#include "../EffekseerRendererCommon/TextureLoader.h"
#include <iostream>
namespace EffekseerRendererLLGI
{
bool PiplineStateKey::operator<(const PiplineStateKey& v) const
{
if (shader != v.shader)
return shader < v.shader;
if (state.AlphaBlend != v.state.AlphaBlend)
return state.AlphaBlend < v.state.AlphaBlend;
if (state.CullingType != v.state.CullingType)
return state.CullingType < v.state.CullingType;
if (state.DepthTest != v.state.DepthTest)
return v.state.DepthTest;
if (state.DepthWrite != v.state.DepthWrite)
return v.state.DepthWrite;
for (int i = 0; i < 4; i++)
{
if (state.TextureFilterTypes[i] != v.state.TextureFilterTypes[i])
return state.TextureFilterTypes[i] < v.state.TextureFilterTypes[i];
if (state.TextureWrapTypes[i] != v.state.TextureWrapTypes[i])
return state.TextureWrapTypes[i] < v.state.TextureWrapTypes[i];
}
if (topologyType != v.topologyType)
return topologyType < v.topologyType;
if (renderPassPipelineState != v.renderPassPipelineState)
return renderPassPipelineState < v.renderPassPipelineState;
return false;
}
LLGI::TextureFormatType ConvertTextureFormat(Effekseer::Backend::TextureFormatType format)
{
switch (format)
{
case Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM:
return LLGI::TextureFormatType::R8G8B8A8_UNORM;
break;
case Effekseer::Backend::TextureFormatType::B8G8R8A8_UNORM:
return LLGI::TextureFormatType::B8G8R8A8_UNORM;
break;
case Effekseer::Backend::TextureFormatType::R8_UNORM:
return LLGI::TextureFormatType::R8_UNORM;
break;
case Effekseer::Backend::TextureFormatType::R16G16_FLOAT:
return LLGI::TextureFormatType::R16G16_FLOAT;
break;
case Effekseer::Backend::TextureFormatType::R16G16B16A16_FLOAT:
return LLGI::TextureFormatType::R16G16B16A16_FLOAT;
break;
case Effekseer::Backend::TextureFormatType::R32G32B32A32_FLOAT:
return LLGI::TextureFormatType::R32G32B32A32_FLOAT;
break;
case Effekseer::Backend::TextureFormatType::BC1:
return LLGI::TextureFormatType::BC1;
break;
case Effekseer::Backend::TextureFormatType::BC2:
return LLGI::TextureFormatType::BC2;
break;
case Effekseer::Backend::TextureFormatType::BC3:
return LLGI::TextureFormatType::BC3;
break;
case Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM_SRGB:
return LLGI::TextureFormatType::R8G8B8A8_UNORM_SRGB;
break;
case Effekseer::Backend::TextureFormatType::B8G8R8A8_UNORM_SRGB:
return LLGI::TextureFormatType::B8G8R8A8_UNORM_SRGB;
break;
case Effekseer::Backend::TextureFormatType::BC1_SRGB:
return LLGI::TextureFormatType::BC1_SRGB;
break;
case Effekseer::Backend::TextureFormatType::BC2_SRGB:
return LLGI::TextureFormatType::BC2_SRGB;
break;
case Effekseer::Backend::TextureFormatType::BC3_SRGB:
return LLGI::TextureFormatType::BC3_SRGB;
break;
case Effekseer::Backend::TextureFormatType::D32:
return LLGI::TextureFormatType::D32;
break;
case Effekseer::Backend::TextureFormatType::D24S8:
return LLGI::TextureFormatType::D24S8;
break;
case Effekseer::Backend::TextureFormatType::D32S8:
return LLGI::TextureFormatType::D32S8;
break;
case Effekseer::Backend::TextureFormatType::Unknown:
break;
default:
break;
}
return LLGI::TextureFormatType::Unknown;
}
LLGI::CommandList* RendererImplemented::GetCurrentCommandList()
{
if (commandList_ != nullptr)
{
auto cl = commandList_.DownCast<CommandList>();
return cl->GetInternal();
}
assert(0);
return nullptr;
}
LLGI::PipelineState* RendererImplemented::GetOrCreatePiplineState()
{
PiplineStateKey key;
key.state = m_renderState->GetActiveState();
key.shader = currentShader;
key.topologyType = currentTopologyType_;
key.renderPassPipelineState = currentRenderPassPipelineState_.get();
auto it = piplineStates_.find(key);
if (it != piplineStates_.end())
{
return it->second;
}
auto piplineState = GetGraphics()->CreatePiplineState();
if (isReversedDepth_)
{
piplineState->DepthFunc = LLGI::DepthFuncType::GreaterEqual;
}
else
{
piplineState->DepthFunc = LLGI::DepthFuncType::LessEqual;
}
piplineState->SetShader(LLGI::ShaderStageType::Vertex, currentShader->GetVertexShader());
piplineState->SetShader(LLGI::ShaderStageType::Pixel, currentShader->GetPixelShader());
for (auto i = 0; i < currentShader->GetVertexLayouts().size(); i++)
{
piplineState->VertexLayouts[i] = currentShader->GetVertexLayouts()[i].Format;
piplineState->VertexLayoutNames[i] = currentShader->GetVertexLayouts()[i].Name;
piplineState->VertexLayoutSemantics[i] = currentShader->GetVertexLayouts()[i].Semantic;
}
piplineState->VertexLayoutCount = (int32_t)currentShader->GetVertexLayouts().size();
piplineState->Topology = currentTopologyType_;
piplineState->IsDepthTestEnabled = key.state.DepthTest;
piplineState->IsDepthWriteEnabled = key.state.DepthWrite;
if (isReversedDepth_)
{
if (key.state.CullingType == ::Effekseer::CullingType::Back)
{
piplineState->Culling = LLGI::CullingMode::Clockwise;
}
else if (key.state.CullingType == ::Effekseer::CullingType::Front)
{
piplineState->Culling = LLGI::CullingMode::CounterClockwise;
}
else if (key.state.CullingType == ::Effekseer::CullingType::Double)
{
piplineState->Culling = LLGI::CullingMode::DoubleSide;
}
}
else
{
piplineState->Culling = (LLGI::CullingMode)key.state.CullingType;
}
piplineState->IsBlendEnabled = true;
piplineState->BlendSrcFuncAlpha = LLGI::BlendFuncType::One;
piplineState->BlendDstFuncAlpha = LLGI::BlendFuncType::One;
piplineState->BlendEquationAlpha = LLGI::BlendEquationType::Max;
if (key.state.AlphaBlend == Effekseer::AlphaBlendType::Opacity)
{
piplineState->IsBlendEnabled = false;
piplineState->IsBlendEnabled = true;
piplineState->BlendDstFunc = LLGI::BlendFuncType::Zero;
piplineState->BlendSrcFunc = LLGI::BlendFuncType::One;
piplineState->BlendEquationRGB = LLGI::BlendEquationType::Add;
}
if (key.state.AlphaBlend == Effekseer::AlphaBlendType::Blend)
{
piplineState->BlendDstFunc = LLGI::BlendFuncType::OneMinusSrcAlpha;
piplineState->BlendSrcFunc = LLGI::BlendFuncType::SrcAlpha;
piplineState->BlendEquationRGB = LLGI::BlendEquationType::Add;
}
if (key.state.AlphaBlend == Effekseer::AlphaBlendType::Add)
{
piplineState->BlendDstFunc = LLGI::BlendFuncType::One;
piplineState->BlendSrcFunc = LLGI::BlendFuncType::SrcAlpha;
piplineState->BlendEquationRGB = LLGI::BlendEquationType::Add;
}
if (key.state.AlphaBlend == Effekseer::AlphaBlendType::Sub)
{
piplineState->BlendDstFunc = LLGI::BlendFuncType::One;
piplineState->BlendSrcFunc = LLGI::BlendFuncType::SrcAlpha;
piplineState->BlendEquationRGB = LLGI::BlendEquationType::ReverseSub;
piplineState->BlendSrcFuncAlpha = LLGI::BlendFuncType::Zero;
piplineState->BlendDstFuncAlpha = LLGI::BlendFuncType::One;
piplineState->BlendEquationAlpha = LLGI::BlendEquationType::Add;
}
if (key.state.AlphaBlend == Effekseer::AlphaBlendType::Mul)
{
piplineState->BlendDstFunc = LLGI::BlendFuncType::SrcColor;
piplineState->BlendSrcFunc = LLGI::BlendFuncType::Zero;
piplineState->BlendEquationRGB = LLGI::BlendEquationType::Add;
piplineState->BlendSrcFuncAlpha = LLGI::BlendFuncType::Zero;
piplineState->BlendDstFuncAlpha = LLGI::BlendFuncType::One;
piplineState->BlendEquationAlpha = LLGI::BlendEquationType::Add;
}
piplineState->SetRenderPassPipelineState(currentRenderPassPipelineState_.get());
if (!piplineState->Compile())
{
assert(0);
}
piplineStates_[key] = piplineState;
return piplineState;
}
void RendererImplemented::GenerateVertexBuffer()
{
m_vertexBuffer =
VertexBuffer::Create(graphicsDevice_.Get(), EffekseerRenderer::GetMaximumVertexSizeInAllTypes() * m_squareMaxCount * 4, true, false);
}
void RendererImplemented::GenerateIndexBuffer()
{
m_indexBuffer = IndexBuffer::Create(graphicsDevice_.Get(), m_squareMaxCount * 6, false, false);
if (m_indexBuffer == nullptr)
return;
m_indexBuffer->Lock();
for (int i = 0; i < m_squareMaxCount; i++)
{
uint16_t* buf = (uint16_t*)m_indexBuffer->GetBufferDirect(6);
buf[0] = 3 + 4 * i;
buf[1] = 1 + 4 * i;
buf[2] = 0 + 4 * i;
buf[3] = 3 + 4 * i;
buf[4] = 0 + 4 * i;
buf[5] = 2 + 4 * i;
}
m_indexBuffer->Unlock();
}
RendererImplemented::RendererImplemented(int32_t squareMaxCount)
: graphicsDevice_(nullptr)
, m_vertexBuffer(nullptr)
, m_indexBuffer(nullptr)
, m_squareMaxCount(squareMaxCount)
, m_coordinateSystem(::Effekseer::CoordinateSystem::RH)
, m_renderState(nullptr)
, shader_unlit_(nullptr)
, shader_distortion_(nullptr)
, m_standardRenderer(nullptr)
, m_distortingCallback(nullptr)
{
}
RendererImplemented::~RendererImplemented()
{
// to prevent objects to be disposed before finish renderings.
GetGraphics()->WaitFinish();
for (auto p : piplineStates_)
{
p.second->Release();
}
piplineStates_.clear();
commandList_.Reset();
GetImpl()->DeleteProxyTextures(this);
ES_SAFE_DELETE(m_distortingCallback);
ES_SAFE_DELETE(m_standardRenderer);
ES_SAFE_DELETE(shader_unlit_);
ES_SAFE_DELETE(shader_lit_);
ES_SAFE_DELETE(shader_distortion_);
ES_SAFE_DELETE(shader_ad_unlit_);
ES_SAFE_DELETE(shader_ad_lit_);
ES_SAFE_DELETE(shader_ad_distortion_);
ES_SAFE_DELETE(m_renderState);
ES_SAFE_DELETE(m_vertexBuffer);
ES_SAFE_DELETE(m_indexBuffer);
ES_SAFE_DELETE(m_indexBufferForWireframe);
if (materialCompiler_ != nullptr)
{
materialCompiler_->Release();
materialCompiler_ = nullptr;
}
}
void RendererImplemented::OnLostDevice()
{
}
void RendererImplemented::OnResetDevice()
{
}
bool RendererImplemented::Initialize(LLGI::Graphics* graphics, LLGI::RenderPassPipelineStateKey key, bool isReversedDepth)
{
auto gd = Effekseer::MakeRefPtr<Backend::GraphicsDevice>(graphics);
auto ret = Initialize(gd, key, isReversedDepth);
return ret;
}
bool RendererImplemented::Initialize(Backend::GraphicsDeviceRef graphicsDevice,
LLGI::RenderPassPipelineStateKey key,
bool isReversedDepth)
{
graphicsDevice_ = graphicsDevice;
ChangeRenderPassPipelineState(key);
isReversedDepth_ = isReversedDepth;
LLGI::SetLogger([](LLGI::LogType type, const std::string& message) { std::cout << message << std::endl; });
// Generate vertex buffer
{
GenerateVertexBuffer();
if (m_vertexBuffer == nullptr)
return false;
}
// Generate index buffer
{
GenerateIndexBuffer();
if (m_indexBuffer == nullptr)
return false;
}
// Generate index buffer for rendering wireframes
{
m_indexBufferForWireframe = IndexBuffer::Create(graphicsDevice_.Get(), m_squareMaxCount * 8, false, false);
if (m_indexBufferForWireframe == nullptr)
return false;
m_indexBufferForWireframe->Lock();
for (int i = 0; i < m_squareMaxCount; i++)
{
uint16_t* buf = (uint16_t*)m_indexBufferForWireframe->GetBufferDirect(8);
buf[0] = 0 + 4 * i;
buf[1] = 1 + 4 * i;
buf[2] = 2 + 4 * i;
buf[3] = 3 + 4 * i;
buf[4] = 0 + 4 * i;
buf[5] = 2 + 4 * i;
buf[6] = 1 + 4 * i;
buf[7] = 3 + 4 * i;
}
m_indexBufferForWireframe->Unlock();
}
m_renderState = new RenderState(this);
// shader
// pos(3) color(1) uv(2)
std::vector<VertexLayout> layouts;
layouts.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32_FLOAT, "TEXCOORD", 0});
layouts.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 1});
layouts.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 2});
std::vector<VertexLayout> layouts_ad;
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32_FLOAT, "TEXCOORD", 0});
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 1});
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 2});
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32A32_FLOAT, "TEXCOORD", 3}); // AlphaTextureUV + UVDistortionTextureUV
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 4}); // BlendUV
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32A32_FLOAT, "TEXCOORD", 5}); // BlendAlphaUV + BlendUVDistortionUV
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32_FLOAT, "TEXCOORD", 6}); // FlipbookIndexAndNextRate
layouts_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32_FLOAT, "TEXCOORD", 7}); // AlphaThreshold
std::vector<VertexLayout> layouts_normal;
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32_FLOAT, "TEXCOORD", 0});
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 1});
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 2});
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 3});
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 4});
layouts_normal.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 5});
std::vector<VertexLayout> layouts_normal_ad;
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32_FLOAT, "TEXCOORD", 0});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 1});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 2});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R8G8B8A8_UNORM, "TEXCOORD", 3});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 4});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 5});
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32A32_FLOAT, "TEXCOORD", 6}); // AlphaTextureUV + UVDistortionTextureUV
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32_FLOAT, "TEXCOORD", 7}); // BlendUV
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32G32B32A32_FLOAT, "TEXCOORD", 8}); // BlendAlphaUV + BlendUVDistortionUV
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32_FLOAT, "TEXCOORD", 9}); // FlipbookIndexAndNextRate
layouts_normal_ad.push_back(VertexLayout{LLGI::VertexLayoutFormat::R32_FLOAT, "TEXCOORD", 10}); // AlphaThreshold
shader_unlit_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.SpriteUnlit_VS.data(),
(int32_t)fixedShader_.SpriteUnlit_VS.size(),
fixedShader_.ModelUnlit_PS.data(),
(int32_t)fixedShader_.ModelUnlit_PS.size(),
"StandardRenderer",
layouts,
false);
if (shader_unlit_ == nullptr)
return false;
shader_distortion_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.SpriteDistortion_VS.data(),
(int32_t)fixedShader_.SpriteDistortion_VS.size(),
fixedShader_.ModelDistortion_PS.data(),
(int32_t)fixedShader_.ModelDistortion_PS.size(),
"StandardRenderer Distortion",
layouts_normal,
false);
if (shader_distortion_ == nullptr)
return false;
shader_ad_unlit_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.AdvancedSpriteUnlit_VS.data(),
(int32_t)fixedShader_.AdvancedSpriteUnlit_VS.size(),
fixedShader_.AdvancedModelUnlit_PS.data(),
(int32_t)fixedShader_.AdvancedModelUnlit_PS.size(),
"StandardRenderer",
layouts_ad,
false);
if (shader_ad_unlit_ == nullptr)
return false;
shader_ad_distortion_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.AdvancedSpriteDistortion_VS.data(),
(int32_t)fixedShader_.AdvancedSpriteDistortion_VS.size(),
fixedShader_.AdvancedModelDistortion_PS.data(),
(int32_t)fixedShader_.AdvancedModelDistortion_PS.size(),
"StandardRenderer Distortion",
layouts_normal_ad,
false);
if (shader_ad_distortion_ == nullptr)
return false;
shader_lit_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.SpriteLit_VS.data(),
(int32_t)fixedShader_.SpriteLit_VS.size(),
fixedShader_.ModelLit_PS.data(),
(int32_t)fixedShader_.ModelLit_PS.size(),
"StandardRenderer Lighting",
layouts_normal,
false);
shader_ad_lit_ = Shader::Create(graphicsDevice_.Get(),
fixedShader_.AdvancedSpriteLit_VS.data(),
(int32_t)fixedShader_.AdvancedSpriteLit_VS.size(),
fixedShader_.AdvancedModelLit_PS.data(),
(int32_t)fixedShader_.AdvancedModelLit_PS.size(),
"StandardRenderer Lighting",
layouts_normal_ad,
false);
shader_unlit_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_unlit_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBuffer));
shader_distortion_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_distortion_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBufferDistortion));
shader_ad_unlit_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_ad_unlit_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBuffer));
shader_ad_distortion_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_ad_distortion_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBufferDistortion));
shader_lit_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_lit_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBuffer));
shader_ad_lit_->SetVertexConstantBufferSize(sizeof(EffekseerRenderer::StandardRendererVertexBuffer));
shader_ad_lit_->SetPixelConstantBufferSize(sizeof(EffekseerRenderer::PixelConstantBuffer));
m_standardRenderer = new EffekseerRenderer::StandardRenderer<RendererImplemented, Shader>(this);
GetImpl()->CreateProxyTextures(this);
GetImpl()->isSoftParticleEnabled = true;
GetImpl()->isDepthReversed = isReversedDepth;
return true;
}
void RendererImplemented::SetRestorationOfStatesFlag(bool flag)
{
}
void RendererImplemented::ChangeRenderPassPipelineState(LLGI::RenderPassPipelineStateKey key)
{
auto it = renderpassPipelineStates_.find(key);
if (it != renderpassPipelineStates_.end())
{
currentRenderPassPipelineState_ = it->second;
}
else
{
auto gd = graphicsDevice_.DownCast<EffekseerRendererLLGI::Backend::GraphicsDevice>();
auto pipelineState = LLGI::CreateSharedPtr(gd->GetGraphics()->CreateRenderPassPipelineState(key));
if (pipelineState != nullptr)
{
renderpassPipelineStates_[key] = pipelineState;
}
currentRenderPassPipelineState_ = pipelineState;
}
}
bool RendererImplemented::BeginRendering()
{
assert(graphicsDevice_ != nullptr);
if (commandList_ == nullptr)
{
return false;
}
impl->CalculateCameraProjectionMatrix();
// initialize states
m_renderState->GetActiveState().Reset();
m_renderState->Update(true);
// reset renderer
m_standardRenderer->ResetAndRenderingIfRequired();
return true;
}
bool RendererImplemented::EndRendering()
{
assert(graphicsDevice_ != nullptr);
if (commandList_ == nullptr)
{
return false;
}
// reset renderer
m_standardRenderer->ResetAndRenderingIfRequired();
return true;
}
void RendererImplemented::SetCommandList(Effekseer::RefPtr<EffekseerRenderer::CommandList> commandList)
{
commandList_ = commandList;
}
VertexBuffer* RendererImplemented::GetVertexBuffer()
{
return m_vertexBuffer;
}
IndexBuffer* RendererImplemented::GetIndexBuffer()
{
if (m_renderMode == ::Effekseer::RenderMode::Wireframe)
{
return m_indexBufferForWireframe;
}
else
{
return m_indexBuffer;
}
}
int32_t RendererImplemented::GetSquareMaxCount() const
{
return m_squareMaxCount;
}
::EffekseerRenderer::RenderStateBase* RendererImplemented::GetRenderState()
{
return m_renderState;
}
::Effekseer::SpriteRendererRef RendererImplemented::CreateSpriteRenderer()
{
return ::Effekseer::SpriteRendererRef(new ::EffekseerRenderer::SpriteRendererBase<RendererImplemented, false>(this));
}
::Effekseer::RibbonRendererRef RendererImplemented::CreateRibbonRenderer()
{
return ::Effekseer::RibbonRendererRef(new ::EffekseerRenderer::RibbonRendererBase<RendererImplemented, false>(this));
}
::Effekseer::RingRendererRef RendererImplemented::CreateRingRenderer()
{
return ::Effekseer::RingRendererRef(new ::EffekseerRenderer::RingRendererBase<RendererImplemented, false>(this));
}
::Effekseer::ModelRendererRef RendererImplemented::CreateModelRenderer()
{
return ModelRenderer::Create(this, &fixedShader_);
}
::Effekseer::TrackRendererRef RendererImplemented::CreateTrackRenderer()
{
return ::Effekseer::TrackRendererRef(new ::EffekseerRenderer::TrackRendererBase<RendererImplemented, false>(this));
}
::Effekseer::TextureLoaderRef RendererImplemented::CreateTextureLoader(::Effekseer::FileInterfaceRef fileInterface)
{
return ::EffekseerRenderer::CreateTextureLoader(graphicsDevice_, fileInterface, ::Effekseer::ColorSpaceType::Gamma);
}
::Effekseer::ModelLoaderRef RendererImplemented::CreateModelLoader(::Effekseer::FileInterfaceRef fileInterface)
{
return ::Effekseer::MakeRefPtr<EffekseerRenderer::ModelLoader>(graphicsDevice_, fileInterface);
}
::Effekseer::MaterialLoaderRef RendererImplemented::CreateMaterialLoader(::Effekseer::FileInterfaceRef fileInterface)
{
return ::Effekseer::MakeRefPtr<MaterialLoader>(graphicsDevice_.Get(), fileInterface, platformType_, materialCompiler_);
}
void RendererImplemented::SetBackgroundInternal(LLGI::Texture* background)
{
if (m_backgroundLLGI == nullptr)
{
m_backgroundLLGI = graphicsDevice_->CreateTexture(background);
}
else
{
auto texture = static_cast<Backend::Texture*>(m_backgroundLLGI.Get());
texture->Init(background);
}
EffekseerRenderer::Renderer::SetBackground((background) ? m_backgroundLLGI : nullptr);
}
EffekseerRenderer::DistortingCallback* RendererImplemented::GetDistortingCallback()
{
return m_distortingCallback;
}
void RendererImplemented::SetDistortingCallback(EffekseerRenderer::DistortingCallback* callback)
{
ES_SAFE_DELETE(m_distortingCallback);
m_distortingCallback = callback;
}
void RendererImplemented::SetVertexBuffer(LLGI::Buffer* vertexBuffer, int32_t stride)
{
currentVertexBuffer_ = vertexBuffer;
currentVertexBufferStride_ = stride;
}
void RendererImplemented::SetVertexBuffer(VertexBuffer* vertexBuffer, int32_t stride)
{
currentVertexBuffer_ = vertexBuffer->GetVertexBuffer();
currentVertexBufferStride_ = stride;
}
void RendererImplemented::SetIndexBuffer(IndexBuffer* indexBuffer)
{
GetCurrentCommandList()->SetIndexBuffer(indexBuffer->GetIndexBuffer(), 2);
}
void RendererImplemented::SetIndexBuffer(LLGI::Buffer* indexBuffer)
{
GetCurrentCommandList()->SetIndexBuffer(indexBuffer, 4);
}
void RendererImplemented::SetVertexBuffer(const Effekseer::Backend::VertexBufferRef& vertexBuffer, int32_t stride)
{
auto vb = static_cast<Backend::VertexBuffer*>(vertexBuffer.Get());
SetVertexBuffer(vb->GetBuffer(), stride);
}
void RendererImplemented::SetIndexBuffer(const Effekseer::Backend::IndexBufferRef& indexBuffer)
{
auto ib = static_cast<Backend::IndexBuffer*>(indexBuffer.Get());
SetIndexBuffer(ib->GetBuffer());
}
void RendererImplemented::SetLayout(Shader* shader)
{
if (m_renderMode == Effekseer::RenderMode::Normal)
{
currentTopologyType_ = LLGI::TopologyType::Triangle;
}
else
{
currentTopologyType_ = LLGI::TopologyType::Line;
}
}
void RendererImplemented::DrawSprites(int32_t spriteCount, int32_t vertexOffset)
{
// constant buffer
LLGI::Buffer* constantBufferVS = nullptr;
LLGI::Buffer* constantBufferPS = nullptr;
auto cl = commandList_.DownCast<CommandList>();
if (currentShader->GetVertexConstantBufferSize() > 0)
{
constantBufferVS = cl->GetMemoryPool()->CreateConstantBuffer(currentShader->GetVertexConstantBufferSize());
assert(constantBufferVS != nullptr);
memcpy(constantBufferVS->Lock(), currentShader->GetVertexConstantBuffer(), currentShader->GetVertexConstantBufferSize());
constantBufferVS->Unlock();
GetCurrentCommandList()->SetConstantBuffer(constantBufferVS, LLGI::ShaderStageType::Vertex);
}
if (currentShader->GetPixelConstantBufferSize() > 0)
{
constantBufferPS = cl->GetMemoryPool()->CreateConstantBuffer(currentShader->GetPixelConstantBufferSize());
assert(constantBufferPS != nullptr);
memcpy(constantBufferPS->Lock(), currentShader->GetPixelConstantBuffer(), currentShader->GetPixelConstantBufferSize());
constantBufferPS->Unlock();
GetCurrentCommandList()->SetConstantBuffer(constantBufferPS, LLGI::ShaderStageType::Pixel);
}
auto piplineState = GetOrCreatePiplineState();
GetCurrentCommandList()->SetPipelineState(piplineState);
impl->drawcallCount++;
impl->drawvertexCount += spriteCount * 4;
if (m_renderMode == Effekseer::RenderMode::Normal)
{
GetCurrentCommandList()->SetVertexBuffer(
currentVertexBuffer_, currentVertexBufferStride_, vertexOffset * currentVertexBufferStride_);
GetCurrentCommandList()->Draw(spriteCount * 2);
}
else
{
GetCurrentCommandList()->SetVertexBuffer(
currentVertexBuffer_, currentVertexBufferStride_, vertexOffset * currentVertexBufferStride_);
GetCurrentCommandList()->Draw(spriteCount * 4);
}
LLGI::SafeRelease(constantBufferVS);
LLGI::SafeRelease(constantBufferPS);
}
void RendererImplemented::DrawPolygon(int32_t vertexCount, int32_t indexCount)
{
DrawPolygonInstanced(vertexCount, indexCount, 1);
}
void RendererImplemented::DrawPolygonInstanced(int32_t vertexCount, int32_t indexCount, int32_t instanceCount)
{
// constant buffer
LLGI::Buffer* constantBufferVS = nullptr;
LLGI::Buffer* constantBufferPS = nullptr;
auto cl = commandList_.DownCast<CommandList>();
if (currentShader->GetVertexConstantBufferSize() > 0)
{
constantBufferVS = cl->GetMemoryPool()->CreateConstantBuffer(currentShader->GetVertexConstantBufferSize());
assert(constantBufferVS != nullptr);
memcpy(constantBufferVS->Lock(), currentShader->GetVertexConstantBuffer(), currentShader->GetVertexConstantBufferSize());
constantBufferVS->Unlock();
GetCurrentCommandList()->SetConstantBuffer(constantBufferVS, LLGI::ShaderStageType::Vertex);
}
if (currentShader->GetPixelConstantBufferSize() > 0)
{
constantBufferPS = cl->GetMemoryPool()->CreateConstantBuffer(currentShader->GetPixelConstantBufferSize());
assert(constantBufferPS != nullptr);
memcpy(constantBufferPS->Lock(), currentShader->GetPixelConstantBuffer(), currentShader->GetPixelConstantBufferSize());
constantBufferPS->Unlock();
GetCurrentCommandList()->SetConstantBuffer(constantBufferPS, LLGI::ShaderStageType::Pixel);
}
auto piplineState = GetOrCreatePiplineState();
GetCurrentCommandList()->SetPipelineState(piplineState);
impl->drawcallCount++;
impl->drawvertexCount += vertexCount * instanceCount;
GetCurrentCommandList()->SetVertexBuffer(currentVertexBuffer_, currentVertexBufferStride_, 0);
GetCurrentCommandList()->Draw(indexCount / 3, instanceCount);
LLGI::SafeRelease(constantBufferVS);
LLGI::SafeRelease(constantBufferPS);
}
Shader* RendererImplemented::GetShader(::EffekseerRenderer::RendererShaderType type) const
{
if (type == ::EffekseerRenderer::RendererShaderType::AdvancedBackDistortion)
{
return shader_ad_distortion_;
}
else if (type == ::EffekseerRenderer::RendererShaderType::AdvancedLit)
{
return shader_ad_lit_;
}
else if (type == ::EffekseerRenderer::RendererShaderType::AdvancedUnlit)
{
return shader_ad_unlit_;
}
else if (type == ::EffekseerRenderer::RendererShaderType::BackDistortion)
{
return shader_distortion_;
}
else if (type == ::EffekseerRenderer::RendererShaderType::Lit)
{
return shader_lit_;
}
else if (type == ::EffekseerRenderer::RendererShaderType::Unlit)
{
return shader_unlit_;
}
return nullptr;
}
void RendererImplemented::BeginShader(Shader* shader)
{
currentShader = shader;
}
void RendererImplemented::EndShader(Shader* shader)
{
currentShader = nullptr;
}
void RendererImplemented::SetVertexBufferToShader(const void* data, int32_t size, int32_t dstOffset)
{
assert(currentShader != nullptr);
auto p = static_cast<uint8_t*>(currentShader->GetVertexConstantBuffer()) + dstOffset;
memcpy(p, data, size);
}
void RendererImplemented::SetPixelBufferToShader(const void* data, int32_t size, int32_t dstOffset)
{
assert(currentShader != nullptr);
auto p = static_cast<uint8_t*>(currentShader->GetPixelConstantBuffer()) + dstOffset;
memcpy(p, data, size);
}
void RendererImplemented::SetTextures(Shader* shader, Effekseer::Backend::TextureRef* textures, int32_t count)
{
auto state = GetRenderState()->GetActiveState();
LLGI::TextureWrapMode ws[2];
ws[(int)Effekseer::TextureWrapType::Clamp] = LLGI::TextureWrapMode::Clamp;
ws[(int)Effekseer::TextureWrapType::Repeat] = LLGI::TextureWrapMode::Repeat;
LLGI::TextureMinMagFilter fs[2];
fs[(int)Effekseer::TextureFilterType::Linear] = LLGI::TextureMinMagFilter::Linear;
fs[(int)Effekseer::TextureFilterType::Nearest] = LLGI::TextureMinMagFilter::Nearest;
for (int32_t i = 0; i < count; i++)
{
if (textures[i] == nullptr)
{
GetCurrentCommandList()->SetTexture(
nullptr, ws[(int)state.TextureWrapTypes[i]], fs[(int)state.TextureFilterTypes[i]], i, LLGI::ShaderStageType::Vertex);
GetCurrentCommandList()->SetTexture(
nullptr, ws[(int)state.TextureWrapTypes[i]], fs[(int)state.TextureFilterTypes[i]], i, LLGI::ShaderStageType::Pixel);
}
else
{
auto texture = static_cast<Backend::Texture*>(textures[i].Get());
auto t = texture->GetTexture().get();
GetCurrentCommandList()->SetTexture(
t, ws[(int)state.TextureWrapTypes[i]], fs[(int)state.TextureFilterTypes[i]], i, LLGI::ShaderStageType::Vertex);
GetCurrentCommandList()->SetTexture(
t, ws[(int)state.TextureWrapTypes[i]], fs[(int)state.TextureFilterTypes[i]], i, LLGI::ShaderStageType::Pixel);
}
}
}
void RendererImplemented::ResetRenderState()
{
m_renderState->GetActiveState().Reset();
m_renderState->Update(true);
}
} // namespace EffekseerRendererLLGI