axmol/extensions/Effekseer/EffekseerRendererCommon/EffekseerRenderer.StandardR...

958 lines
29 KiB
C++

#ifndef __EFFEKSEERRENDERER_STANDARD_RENDERER_BASE_H__
#define __EFFEKSEERRENDERER_STANDARD_RENDERER_BASE_H__
#include <Effekseer.h>
#include <algorithm>
#include <functional>
#include <vector>
#include "EffekseerRenderer.CommonUtils.h"
#include "EffekseerRenderer.Renderer.h"
#include "EffekseerRenderer.Renderer_Impl.h"
#include "EffekseerRenderer.VertexBufferBase.h"
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
namespace EffekseerRenderer
{
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
struct StandardRendererState
{
bool DepthTest;
bool DepthWrite;
bool Distortion;
float DistortionIntensity;
bool Refraction;
::Effekseer::AlphaBlendType AlphaBlend;
::Effekseer::CullingType CullingType;
RendererStateFlipbook Flipbook;
float UVDistortionIntensity;
int32_t TextureBlendType;
float BlendUVDistortionIntensity;
float EmissiveScaling;
float EdgeThreshold;
uint8_t EdgeColor[4];
float EdgeColorScaling;
bool IsAlphaCuttoffEnabled = false;
float SoftParticleDistanceFar = 0.0f;
float SoftParticleDistanceNear = 0.0f;
float SoftParticleDistanceNearOffset = 0.0f;
float Maginification = 1.0f;
float LocalTime = 0.0f;
::Effekseer::RendererMaterialType MaterialType;
int32_t MaterialUniformCount = 0;
std::array<std::array<float, 4>, 16> MaterialUniforms;
int32_t MaterialGradientCount = 0;
std::array<std::array<std::array<float, 4>, 13>, Effekseer::UserGradientSlotMax> MaterialGradients;
int32_t CustomData1Count = 0;
int32_t CustomData2Count = 0;
ShaderParameterCollector Collector{};
Effekseer::RefPtr<Effekseer::RenderingUserData> RenderingUserData{};
void* HandleUserData;
StandardRendererState()
{
DepthTest = false;
DepthWrite = false;
Distortion = false;
DistortionIntensity = 1.0f;
Refraction = false;
AlphaBlend = ::Effekseer::AlphaBlendType::Blend;
CullingType = ::Effekseer::CullingType::Front;
Flipbook = RendererStateFlipbook{};
UVDistortionIntensity = 1.0f;
TextureBlendType = 0;
BlendUVDistortionIntensity = 1.0f;
EmissiveScaling = 1.0f;
EdgeThreshold = 0.0f;
EdgeColor[0] = EdgeColor[1] = EdgeColor[2] = EdgeColor[3] = 0;
EdgeColorScaling = 1;
MaterialType = ::Effekseer::RendererMaterialType::Default;
MaterialUniformCount = 0;
MaterialGradientCount = 0;
CustomData1Count = 0;
CustomData2Count = 0;
RenderingUserData.Reset();
HandleUserData = nullptr;
}
bool operator==(const StandardRendererState& state) const
{
return !(*this != state);
}
bool operator!=(const StandardRendererState& state) const
{
if (Collector != state.Collector)
return true;
if (DepthTest != state.DepthTest)
return true;
if (DepthWrite != state.DepthWrite)
return true;
if (Distortion != state.Distortion)
return true;
if (DistortionIntensity != state.DistortionIntensity)
return true;
if (AlphaBlend != state.AlphaBlend)
return true;
if (CullingType != state.CullingType)
return true;
if (Flipbook != state.Flipbook)
return true;
if (UVDistortionIntensity != state.UVDistortionIntensity)
return true;
if (TextureBlendType != state.TextureBlendType)
return true;
if (BlendUVDistortionIntensity != state.BlendUVDistortionIntensity)
return true;
if (EmissiveScaling != state.EmissiveScaling)
return true;
if (EdgeThreshold != state.EdgeThreshold)
return true;
if (EdgeColor[0] != state.EdgeColor[0] ||
EdgeColor[1] != state.EdgeColor[1] ||
EdgeColor[2] != state.EdgeColor[2] ||
EdgeColor[3] != state.EdgeColor[3])
return true;
if (EdgeColorScaling != state.EdgeColorScaling)
return true;
if (IsAlphaCuttoffEnabled != state.IsAlphaCuttoffEnabled)
return true;
if (SoftParticleDistanceFar != state.SoftParticleDistanceFar)
return true;
if (SoftParticleDistanceNear != state.SoftParticleDistanceNear)
return true;
if (SoftParticleDistanceNearOffset != state.SoftParticleDistanceNearOffset)
return true;
if (Maginification != state.Maginification)
return true;
if (LocalTime != state.LocalTime)
return true;
if (MaterialType != state.MaterialType)
return true;
if (MaterialUniformCount != state.MaterialUniformCount)
return true;
if (Refraction != state.Refraction)
return true;
for (int32_t i = 0; i < state.MaterialUniformCount; i++)
{
if (MaterialUniforms[i] != state.MaterialUniforms[i])
return true;
}
if (MaterialGradientCount != state.MaterialGradientCount)
return true;
for (int32_t i = 0; i < state.MaterialGradientCount; i++)
{
if (MaterialGradients[i] != state.MaterialGradients[i])
return true;
}
if (CustomData1Count != state.CustomData1Count)
return true;
if (CustomData1Count != state.CustomData1Count)
return true;
if (RenderingUserData == nullptr && state.RenderingUserData != nullptr)
return true;
if (RenderingUserData != nullptr && state.RenderingUserData == nullptr)
return true;
if (RenderingUserData != nullptr && state.RenderingUserData != nullptr && !RenderingUserData->Equal(state.RenderingUserData.Get()))
return true;
if (HandleUserData != state.HandleUserData)
return true;
return false;
}
void CopyMaterialFromParameterToState(
EffekseerRenderer::Renderer* renderer,
Effekseer::Effect* effect,
Effekseer::NodeRendererBasicParameter* basicParam)
{
AlphaBlend = basicParam->AlphaBlend;
// TODO : refactor in 1.7
if (renderer->GetExternalShaderSettings() != nullptr)
{
AlphaBlend = renderer->GetExternalShaderSettings()->Blend;
}
else if (renderer->GetRenderMode() == ::Effekseer::RenderMode::Wireframe)
{
AlphaBlend = ::Effekseer::AlphaBlendType::Opacity;
}
Collector = ShaderParameterCollector();
Collector.Collect(renderer, effect, basicParam, false, renderer->GetImpl()->isSoftParticleEnabled);
SoftParticleDistanceFar = basicParam->SoftParticleDistanceFar;
SoftParticleDistanceNear = basicParam->SoftParticleDistanceNear;
SoftParticleDistanceNearOffset = basicParam->SoftParticleDistanceNearOffset;
if (Collector.MaterialRenderDataPtr != nullptr && Collector.MaterialDataPtr != nullptr)
{
CustomData1Count = Collector.MaterialDataPtr->CustomData1;
CustomData2Count = Collector.MaterialDataPtr->CustomData2;
MaterialUniformCount =
static_cast<int32_t>(Effekseer::Min(Collector.MaterialRenderDataPtr->MaterialUniforms.size(), MaterialUniforms.size()));
for (size_t i = 0; i < MaterialUniformCount; i++)
{
MaterialUniforms[i] = Collector.MaterialRenderDataPtr->MaterialUniforms[i];
}
MaterialGradientCount =
static_cast<int32_t>(Effekseer::Min(Collector.MaterialRenderDataPtr->MaterialGradients.size(), MaterialGradients.size()));
for (size_t i = 0; i < MaterialGradientCount; i++)
{
MaterialGradients[i] = ToUniform(*Collector.MaterialRenderDataPtr->MaterialGradients[i]);
}
}
else
{
Refraction = false;
CustomData1Count = 0;
CustomData2Count = 0;
}
}
};
struct StandardRendererVertexBuffer
{
Effekseer::Matrix44 constantVSBuffer[2];
float uvInversed[4];
FlipbookVertexBuffer flipbookParameter;
};
template <typename RENDERER, typename SHADER>
class StandardRenderer
{
private:
RENDERER* m_renderer;
struct RenderInfo
{
StandardRendererState state;
int offset;
int size;
int stride;
bool isLargeSize;
bool hasDistortion;
};
//! WebAssembly requires a much time to resize std::vector (in a profiler at least) so reduce to call resize
std::vector<uint8_t> vertexCaches_;
int32_t vertexCacheMaxSize_ = 0;
int32_t vertexCacheOffset_ = 0;
EffekseerRenderer::VertexBufferBase* lastVb_ = nullptr;
Effekseer::CustomAlignedVector<RenderInfo> renderInfos_;
void ColorToFloat4(::Effekseer::Color color, float fc[4])
{
fc[0] = color.R / 255.0f;
fc[1] = color.G / 255.0f;
fc[2] = color.B / 255.0f;
fc[3] = color.A / 255.0f;
}
void VectorToFloat4(const ::Effekseer::SIMD::Vec3f& v, float fc[4])
{
::Effekseer::SIMD::Float4::Store3(fc, v.s);
fc[3] = 1.0f;
}
public:
StandardRenderer(RENDERER* renderer)
{
m_renderer = renderer;
vertexCacheMaxSize_ = m_renderer->GetVertexBuffer()->GetMaxSize();
vertexCaches_.reserve(m_renderer->GetVertexBuffer()->GetMaxSize());
}
virtual ~StandardRenderer()
{
}
static int32_t CalculateCurrentStride(const StandardRendererState& state)
{
const auto renderingMode = state.Collector.ShaderType;
size_t stride = 0;
if (renderingMode == RendererShaderType::Material)
{
stride = sizeof(DynamicVertex);
stride += (state.CustomData1Count + state.CustomData2Count) * sizeof(float);
}
else if (renderingMode == RendererShaderType::Lit)
{
stride = sizeof(LightingVertex);
}
else if (renderingMode == RendererShaderType::BackDistortion)
{
stride = sizeof(LightingVertex);
}
else if (renderingMode == RendererShaderType::Unlit)
{
stride = sizeof(SimpleVertex);
}
else if (renderingMode == RendererShaderType::AdvancedLit)
{
stride = sizeof(AdvancedLightingVertex);
}
else if (renderingMode == RendererShaderType::AdvancedBackDistortion)
{
stride = sizeof(AdvancedLightingVertex);
}
else if (renderingMode == RendererShaderType::AdvancedUnlit)
{
stride = sizeof(AdvancedSimpleVertex);
}
return static_cast<int32_t>(stride);
}
void BeginRenderingAndRenderingIfRequired(const StandardRendererState& state, int32_t count, int& stride, void*& data)
{
if (renderInfos_.size() > 0 && (renderInfos_[renderInfos_.size() - 1].isLargeSize || renderInfos_[renderInfos_.size() - 1].hasDistortion))
{
Rendering();
}
stride = CalculateCurrentStride(state);
const int32_t requiredSize = count * stride;
const auto spriteStride = stride * 4;
const auto maxVertexCount = m_renderer->GetSquareMaxCount() * 4;
if (requiredSize > vertexCacheMaxSize_ || requiredSize == 0)
{
data = nullptr;
return;
}
if (requiredSize + EffekseerRenderer::VertexBufferBase::GetNextAliginedVertexRingOffset(vertexCacheOffset_, spriteStride) > vertexCacheMaxSize_ || count > maxVertexCount)
{
Rendering();
}
if (renderInfos_.size() == 0)
{
EffekseerRenderer::VertexBufferBase* vb = m_renderer->GetVertexBuffer();
vertexCacheOffset_ = vb->GetVertexRingOffset();
lastVb_ = vb;
// reset
if (!vb->GetIsRingEnabled())
{
vertexCacheOffset_ = 0;
}
if (requiredSize + EffekseerRenderer::VertexBufferBase::GetNextAliginedVertexRingOffset(vertexCacheOffset_, spriteStride) > vertexCacheMaxSize_)
{
vertexCacheOffset_ = 0;
}
}
vertexCacheOffset_ = EffekseerRenderer::VertexBufferBase::GetNextAliginedVertexRingOffset(vertexCacheOffset_, spriteStride);
const auto oldOffset = vertexCacheOffset_;
vertexCacheOffset_ += requiredSize;
if (vertexCaches_.size() < vertexCacheOffset_)
{
vertexCaches_.resize(vertexCacheOffset_);
}
data = (vertexCaches_.data() + oldOffset);
if (renderInfos_.size() > 0 && renderInfos_.back().state == state && (renderInfos_.back().size + requiredSize) / spriteStride <= m_renderer->GetSquareMaxCount())
{
RenderInfo& renderInfo = renderInfos_.back();
renderInfo.size += requiredSize;
}
else
{
RenderInfo renderInfo;
renderInfo.state = state;
renderInfo.size = requiredSize;
renderInfo.offset = oldOffset;
renderInfo.stride = stride;
renderInfo.isLargeSize = requiredSize > vertexCacheMaxSize_;
renderInfo.hasDistortion = state.Collector.IsBackgroundRequiredOnFirstPass && m_renderer->GetDistortingCallback() != nullptr;
renderInfos_.emplace_back(renderInfo);
}
}
void ResetAndRenderingIfRequired()
{
Rendering();
}
StandardRendererState& GetState()
{
assert(renderInfos_.size() > 0);
return renderInfos_.back().state;
}
void Rendering()
{
if (renderInfos_.size() == 0)
{
return;
}
int cpuBufStart = INT_MAX;
int cpuBufEnd = 0;
for (auto& info : renderInfos_)
{
cpuBufStart = Effekseer::Min(cpuBufStart, info.offset);
cpuBufEnd = Effekseer::Max(cpuBufEnd, info.offset + info.size);
}
const int cpuBufSize = cpuBufEnd - cpuBufStart;
{
VertexBufferBase* vb = m_renderer->GetVertexBuffer();
assert(vb == lastVb_);
void* vbData = nullptr;
int32_t vbOffset = 0;
if (vb->RingBufferLock(cpuBufSize, vbOffset, vbData, renderInfos_.begin()->stride * 4))
{
assert(vbData != nullptr);
assert(vbOffset == cpuBufStart);
const auto dst = (reinterpret_cast<uint8_t*>(vbData));
memcpy(dst, vertexCaches_.data() + cpuBufStart, cpuBufSize);
vb->Unlock();
}
else
{
m_renderer->GetImpl()->CurrentRingBufferIndex++;
m_renderer->GetImpl()->CurrentRingBufferIndex %= m_renderer->GetImpl()->RingBufferCount;
return;
}
}
for (auto& info : renderInfos_)
{
const auto& state = info.state;
const auto& mProj = m_renderer->GetProjectionMatrix();
int32_t stride = CalculateCurrentStride(state);
int32_t passNum = 1;
if (state.Collector.ShaderType == RendererShaderType::Material)
{
if (state.Collector.MaterialDataPtr->RefractionUserPtr != nullptr)
{
// refraction and standard
passNum = 2;
}
}
for (int32_t passInd = 0; passInd < passNum; passInd++)
{
int32_t offset = 0;
// only sprite
int32_t renderBufferSize = info.size;
if (renderBufferSize > vertexCacheMaxSize_)
{
assert(renderInfos_.size() == 1 && renderInfos_[0].offset == 0);
renderBufferSize = (vertexCacheMaxSize_ / (stride * 4)) * (stride * 4);
}
const auto maxVertexCount = m_renderer->GetSquareMaxCount() * 4;
const auto currentVertexCount = renderBufferSize / stride;
if (currentVertexCount > maxVertexCount)
{
renderBufferSize = m_renderer->GetSquareMaxCount() * (stride * 4);
}
Rendering_(m_renderer->GetCameraMatrix(), mProj, info.offset, renderBufferSize, info.stride, passInd, state);
}
}
renderInfos_.clear();
m_renderer->GetImpl()->CurrentRingBufferIndex++;
m_renderer->GetImpl()->CurrentRingBufferIndex %= m_renderer->GetImpl()->RingBufferCount;
}
void Rendering_(const Effekseer::SIMD::Mat44f& mCamera,
const Effekseer::SIMD::Mat44f& mProj,
int32_t vbOffset,
int32_t bufferSize,
int32_t stride,
int32_t renderPass,
const StandardRendererState& renderState)
{
bool isBackgroundRequired = renderState.Collector.IsBackgroundRequiredOnFirstPass && renderPass == 0;
if (isBackgroundRequired)
{
auto callback = m_renderer->GetDistortingCallback();
if (callback != nullptr)
{
if (!callback->OnDistorting(m_renderer))
{
return;
}
}
}
if (isBackgroundRequired && m_renderer->GetBackground() == 0)
{
return;
}
auto textures = renderState.Collector.Textures;
if (isBackgroundRequired)
{
textures[renderState.Collector.BackgroundIndex] = m_renderer->GetBackground();
}
::Effekseer::Backend::TextureRef depthTexture = nullptr;
::EffekseerRenderer::DepthReconstructionParameter reconstructionParam;
m_renderer->GetImpl()->GetDepth(depthTexture, reconstructionParam);
if (renderState.Collector.IsDepthRequired)
{
if (depthTexture == nullptr || (renderState.SoftParticleDistanceFar == 0.0f &&
renderState.SoftParticleDistanceNear == 0.0f &&
renderState.SoftParticleDistanceNearOffset == 0.0f &&
renderState.Collector.ShaderType != RendererShaderType::Material))
{
depthTexture = m_renderer->GetImpl()->GetProxyTexture(EffekseerRenderer::ProxyTextureType::White);
}
textures[renderState.Collector.DepthIndex] = depthTexture;
}
SHADER* shader_ = nullptr;
bool distortion = renderState.Distortion;
bool renderDistortedBackground = false;
if (renderState.Collector.ShaderType == RendererShaderType::Material)
{
if (renderState.Collector.MaterialDataPtr->IsRefractionRequired)
{
if (renderPass == 0)
{
if (m_renderer->GetBackground() == 0)
{
return;
}
shader_ = (SHADER*)renderState.Collector.MaterialDataPtr->RefractionUserPtr;
renderDistortedBackground = true;
}
else
{
shader_ = (SHADER*)renderState.Collector.MaterialDataPtr->UserPtr;
}
}
else
{
shader_ = (SHADER*)renderState.Collector.MaterialDataPtr->UserPtr;
}
}
else
{
shader_ = m_renderer->GetShader(renderState.Collector.ShaderType);
}
// validate
if (shader_ == nullptr)
return;
RenderStateBase::State& state = m_renderer->GetRenderState()->Push();
state.DepthTest = renderState.DepthTest;
state.DepthWrite = renderState.DepthWrite;
state.CullingType = renderState.CullingType;
state.AlphaBlend = renderState.AlphaBlend;
if (renderDistortedBackground)
{
state.AlphaBlend = ::Effekseer::AlphaBlendType::Blend;
}
m_renderer->BeginShader(shader_);
for (int32_t i = 0; i < renderState.Collector.TextureCount; i++)
{
state.TextureFilterTypes[i] = renderState.Collector.TextureFilterTypes[i];
state.TextureWrapTypes[i] = renderState.Collector.TextureWrapTypes[i];
}
m_renderer->SetTextures(shader_, textures.data(), renderState.Collector.TextureCount);
std::array<float, 4> uvInversed;
std::array<float, 4> uvInversedBack;
std::array<float, 4> uvInversedMaterial;
if (m_renderer->GetTextureUVStyle() == UVStyle::VerticalFlipped)
{
uvInversed[0] = 1.0f;
uvInversed[1] = -1.0f;
}
else
{
uvInversed[0] = 0.0f;
uvInversed[1] = 1.0f;
}
if (m_renderer->GetBackgroundTextureUVStyle() == UVStyle::VerticalFlipped)
{
uvInversedBack[0] = 1.0f;
uvInversedBack[1] = -1.0f;
}
else
{
uvInversedBack[0] = 0.0f;
uvInversedBack[1] = 1.0f;
}
uvInversedMaterial[0] = uvInversed[0];
uvInversedMaterial[1] = uvInversed[1];
uvInversedMaterial[2] = uvInversedBack[0];
uvInversedMaterial[3] = uvInversedBack[1];
if (renderState.Collector.ShaderType == RendererShaderType::Material)
{
Effekseer::Matrix44 mstCamera = ToStruct(mCamera);
Effekseer::Matrix44 mstProj = ToStruct(mProj);
// camera
float cameraPosition[4];
::Effekseer::SIMD::Vec3f cameraPosition3 = m_renderer->GetCameraPosition();
VectorToFloat4(cameraPosition3, cameraPosition);
// time
std::array<float, 4> predefined_uniforms;
predefined_uniforms.fill(0.5f);
predefined_uniforms[0] = m_renderer->GetTime();
predefined_uniforms[1] = renderState.Maginification;
predefined_uniforms[2] = m_renderer->GetImpl()->MaintainGammaColorInLinearColorSpace ? 1.0f : 0.0f;
predefined_uniforms[3] = renderState.LocalTime;
// vs
int32_t vsOffset = 0;
m_renderer->SetVertexBufferToShader(&mstCamera, sizeof(Effekseer::Matrix44), vsOffset);
vsOffset += sizeof(Effekseer::Matrix44);
m_renderer->SetVertexBufferToShader(&mstProj, sizeof(Effekseer::Matrix44), vsOffset);
vsOffset += sizeof(Effekseer::Matrix44);
m_renderer->SetVertexBufferToShader(uvInversedMaterial.data(), sizeof(float) * 4, vsOffset);
vsOffset += (sizeof(float) * 4);
m_renderer->SetVertexBufferToShader(predefined_uniforms.data(), sizeof(float) * 4, vsOffset);
vsOffset += (sizeof(float) * 4);
m_renderer->SetVertexBufferToShader(cameraPosition, sizeof(float) * 4, vsOffset);
vsOffset += (sizeof(float) * 4);
for (size_t i = 0; i < renderState.MaterialUniformCount; i++)
{
m_renderer->SetVertexBufferToShader(renderState.MaterialUniforms[i].data(), sizeof(float) * 4, vsOffset);
vsOffset += (sizeof(float) * 4);
}
for (size_t i = 0; i < renderState.MaterialGradientCount; i++)
{
m_renderer->SetVertexBufferToShader(renderState.MaterialGradients[i].data(), sizeof(float) * 4 * 13, vsOffset);
vsOffset += (sizeof(float) * 4) * 13;
}
// ps
int32_t psOffset = 0;
m_renderer->SetPixelBufferToShader(uvInversedMaterial.data(), sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
m_renderer->SetPixelBufferToShader(predefined_uniforms.data(), sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
m_renderer->SetPixelBufferToShader(cameraPosition, sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
SoftParticleParameter softParticleParam;
softParticleParam.SetParam(
0.0f,
0.0f,
0.0f,
0.0f,
reconstructionParam.DepthBufferScale,
reconstructionParam.DepthBufferOffset,
reconstructionParam.ProjectionMatrix33,
reconstructionParam.ProjectionMatrix34,
reconstructionParam.ProjectionMatrix43,
reconstructionParam.ProjectionMatrix44);
m_renderer->SetPixelBufferToShader(softParticleParam.reconstructionParam1.data(), sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
m_renderer->SetPixelBufferToShader(softParticleParam.reconstructionParam2.data(), sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
// shader model
float lightDirection[4];
float lightColor[4];
float lightAmbientColor[4];
::Effekseer::SIMD::Vec3f lightDirection3 = m_renderer->GetLightDirection();
lightDirection3 = lightDirection3.Normalize();
VectorToFloat4(lightDirection3, lightDirection);
ColorToFloat4(m_renderer->GetLightColor(), lightColor);
ColorToFloat4(m_renderer->GetLightAmbientColor(), lightAmbientColor);
m_renderer->SetPixelBufferToShader(lightDirection, sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
m_renderer->SetPixelBufferToShader(lightColor, sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
m_renderer->SetPixelBufferToShader(lightAmbientColor, sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
// refraction
if (renderState.Collector.MaterialDataPtr->RefractionUserPtr != nullptr && renderPass == 0)
{
auto mat = m_renderer->GetCameraMatrix();
m_renderer->SetPixelBufferToShader(&mat, sizeof(float) * 16, psOffset);
psOffset += (sizeof(float) * 16);
}
for (size_t i = 0; i < renderState.MaterialUniformCount; i++)
{
m_renderer->SetPixelBufferToShader(renderState.MaterialUniforms[i].data(), sizeof(float) * 4, psOffset);
psOffset += (sizeof(float) * 4);
}
for (size_t i = 0; i < renderState.MaterialGradientCount; i++)
{
m_renderer->SetPixelBufferToShader(renderState.MaterialGradients[i].data(), sizeof(float) * 4 * 13, psOffset);
psOffset += (sizeof(float) * 4) * 13;
}
}
else if (renderState.MaterialType == ::Effekseer::RendererMaterialType::Lighting)
{
StandardRendererVertexBuffer vcb;
vcb.constantVSBuffer[0] = ToStruct(mCamera);
vcb.constantVSBuffer[1] = ToStruct(mCamera * mProj);
vcb.uvInversed[0] = uvInversed[0];
vcb.uvInversed[1] = uvInversed[1];
vcb.flipbookParameter = ToVertexBuffer(renderState.Flipbook);
m_renderer->SetVertexBufferToShader(&vcb, sizeof(StandardRendererVertexBuffer), 0);
// ps
PixelConstantBuffer pcb{};
pcb.MiscFlags.fill(0.0f);
pcb.MiscFlags[0] = m_renderer->GetImpl()->MaintainGammaColorInLinearColorSpace ? 1.0f : 0.0f;
pcb.FalloffParam.Enable = 0;
auto lightDirection3 = m_renderer->GetLightDirection();
Effekseer::Vector3D::Normal(lightDirection3, lightDirection3);
pcb.LightDirection = lightDirection3.ToFloat4();
pcb.LightColor = m_renderer->GetLightColor().ToFloat4();
pcb.LightAmbientColor = m_renderer->GetLightAmbientColor().ToFloat4();
pcb.FlipbookParam.EnableInterpolation = static_cast<float>(renderState.Flipbook.EnableInterpolation);
pcb.FlipbookParam.InterpolationType = static_cast<float>(renderState.Flipbook.InterpolationType);
pcb.UVDistortionParam.Intensity = renderState.UVDistortionIntensity;
pcb.UVDistortionParam.BlendIntensity = renderState.BlendUVDistortionIntensity;
pcb.UVDistortionParam.UVInversed[0] = uvInversed[0];
pcb.UVDistortionParam.UVInversed[1] = uvInversed[1];
pcb.BlendTextureParam.BlendType = static_cast<float>(renderState.TextureBlendType);
pcb.EmmisiveParam.EmissiveScaling = renderState.EmissiveScaling;
pcb.EdgeParam.EdgeColor = Effekseer::Color(renderState.EdgeColor[0], renderState.EdgeColor[1], renderState.EdgeColor[2], renderState.EdgeColor[3]).ToFloat4();
pcb.EdgeParam.Threshold = renderState.EdgeThreshold;
pcb.EdgeParam.ColorScaling = static_cast<float>(renderState.EdgeColorScaling);
pcb.SoftParticleParam.SetParam(
renderState.SoftParticleDistanceFar,
renderState.SoftParticleDistanceNear,
renderState.SoftParticleDistanceNearOffset,
renderState.Maginification,
reconstructionParam.DepthBufferScale,
reconstructionParam.DepthBufferOffset,
reconstructionParam.ProjectionMatrix33,
reconstructionParam.ProjectionMatrix34,
reconstructionParam.ProjectionMatrix43,
reconstructionParam.ProjectionMatrix44);
pcb.UVInversedBack[0] = uvInversedBack[0];
pcb.UVInversedBack[1] = uvInversedBack[1];
m_renderer->SetPixelBufferToShader(&pcb, sizeof(PixelConstantBuffer), 0);
}
else
{
StandardRendererVertexBuffer vcb;
vcb.constantVSBuffer[0] = ToStruct(mCamera);
vcb.constantVSBuffer[1] = ToStruct(mCamera * mProj);
vcb.uvInversed[0] = uvInversed[0];
vcb.uvInversed[1] = uvInversed[1];
vcb.uvInversed[2] = 0.0f;
vcb.uvInversed[3] = 0.0f;
vcb.flipbookParameter = ToVertexBuffer(renderState.Flipbook);
m_renderer->SetVertexBufferToShader(&vcb, sizeof(StandardRendererVertexBuffer), 0);
if (distortion)
{
PixelConstantBufferDistortion pcb;
pcb.DistortionIntencity[0] = renderState.DistortionIntensity;
pcb.UVInversedBack[0] = uvInversedBack[0];
pcb.UVInversedBack[1] = uvInversedBack[1];
pcb.FlipbookParam.EnableInterpolation = static_cast<float>(renderState.Flipbook.EnableInterpolation);
pcb.FlipbookParam.InterpolationType = static_cast<float>(renderState.Flipbook.InterpolationType);
pcb.UVDistortionParam.Intensity = renderState.UVDistortionIntensity;
pcb.UVDistortionParam.BlendIntensity = renderState.BlendUVDistortionIntensity;
pcb.UVDistortionParam.UVInversed[0] = uvInversed[0];
pcb.UVDistortionParam.UVInversed[1] = uvInversed[1];
pcb.BlendTextureParam.BlendType = static_cast<float>(renderState.TextureBlendType);
pcb.SoftParticleParam.SetParam(
renderState.SoftParticleDistanceFar,
renderState.SoftParticleDistanceNear,
renderState.SoftParticleDistanceNearOffset,
renderState.Maginification,
reconstructionParam.DepthBufferScale,
reconstructionParam.DepthBufferOffset,
reconstructionParam.ProjectionMatrix33,
reconstructionParam.ProjectionMatrix34,
reconstructionParam.ProjectionMatrix43,
reconstructionParam.ProjectionMatrix44);
m_renderer->SetPixelBufferToShader(&pcb, sizeof(PixelConstantBufferDistortion), 0);
}
else
{
PixelConstantBuffer pcb;
pcb.MiscFlags.fill(0.0f);
pcb.MiscFlags[0] = m_renderer->GetImpl()->MaintainGammaColorInLinearColorSpace ? 1.0f : 0.0f;
pcb.FalloffParam.Enable = 0;
pcb.FlipbookParam.EnableInterpolation = static_cast<float>(renderState.Flipbook.EnableInterpolation);
pcb.FlipbookParam.InterpolationType = static_cast<float>(renderState.Flipbook.InterpolationType);
pcb.UVDistortionParam.Intensity = renderState.UVDistortionIntensity;
pcb.UVDistortionParam.BlendIntensity = renderState.BlendUVDistortionIntensity;
pcb.UVDistortionParam.UVInversed[0] = uvInversed[0];
pcb.UVDistortionParam.UVInversed[1] = uvInversed[1];
pcb.BlendTextureParam.BlendType = static_cast<float>(renderState.TextureBlendType);
pcb.EmmisiveParam.EmissiveScaling = renderState.EmissiveScaling;
pcb.EdgeParam.EdgeColor = Effekseer::Color(renderState.EdgeColor[0], renderState.EdgeColor[1], renderState.EdgeColor[2], renderState.EdgeColor[3]).ToFloat4();
pcb.EdgeParam.Threshold = renderState.EdgeThreshold;
pcb.EdgeParam.ColorScaling = static_cast<float>(renderState.EdgeColorScaling);
pcb.SoftParticleParam.SetParam(
renderState.SoftParticleDistanceFar,
renderState.SoftParticleDistanceNear,
renderState.SoftParticleDistanceNearOffset,
renderState.Maginification,
reconstructionParam.DepthBufferScale,
reconstructionParam.DepthBufferOffset,
reconstructionParam.ProjectionMatrix33,
reconstructionParam.ProjectionMatrix34,
reconstructionParam.ProjectionMatrix43,
reconstructionParam.ProjectionMatrix44);
pcb.UVInversedBack[0] = uvInversedBack[0];
pcb.UVInversedBack[1] = uvInversedBack[1];
m_renderer->SetPixelBufferToShader(&pcb, sizeof(PixelConstantBuffer), 0);
}
}
shader_->SetConstantBuffer();
m_renderer->GetRenderState()->Update(distortion);
assert(vbOffset % stride == 0);
m_renderer->SetVertexBuffer(m_renderer->GetVertexBuffer(), stride);
m_renderer->SetIndexBuffer(m_renderer->GetIndexBuffer());
m_renderer->SetLayout(shader_);
m_renderer->GetImpl()->CurrentRenderingUserData = renderState.RenderingUserData;
m_renderer->GetImpl()->CurrentHandleUserData = renderState.HandleUserData;
m_renderer->DrawSprites(bufferSize / stride / 4, vbOffset / stride);
m_renderer->EndShader(shader_);
m_renderer->GetRenderState()->Pop();
}
};
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
} // namespace EffekseerRenderer
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
#endif // __EFFEKSEERRENDERER_STANDARD_RENDERER_H__