mirror of https://github.com/axmolengine/axmol.git
1299 lines
41 KiB
C
1299 lines
41 KiB
C
|
|
|||
|
#ifndef __EFFEKSEERRENDERER_MODEL_RENDERER_BASE_H__
|
|||
|
#define __EFFEKSEERRENDERER_MODEL_RENDERER_BASE_H__
|
|||
|
|
|||
|
#include <Effekseer.h>
|
|||
|
#include <algorithm>
|
|||
|
#include <assert.h>
|
|||
|
#include <string.h>
|
|||
|
#include <vector>
|
|||
|
|
|||
|
#include "EffekseerRenderer.CommonUtils.h"
|
|||
|
#include "EffekseerRenderer.IndexBufferBase.h"
|
|||
|
#include "EffekseerRenderer.RenderStateBase.h"
|
|||
|
#include "EffekseerRenderer.Renderer.h"
|
|||
|
#include "EffekseerRenderer.VertexBufferBase.h"
|
|||
|
|
|||
|
namespace EffekseerRenderer
|
|||
|
{
|
|||
|
|
|||
|
typedef ::Effekseer::ModelRenderer::NodeParameter efkModelNodeParam;
|
|||
|
typedef ::Effekseer::ModelRenderer::InstanceParameter efkModelInstanceParam;
|
|||
|
typedef ::Effekseer::SIMD::Vec3f efkVector3D;
|
|||
|
|
|||
|
template <int MODEL_COUNT>
|
|||
|
struct ModelRendererVertexConstantBuffer
|
|||
|
{
|
|||
|
Effekseer::Matrix44 CameraMatrix;
|
|||
|
Effekseer::Matrix44 ModelMatrix[MODEL_COUNT];
|
|||
|
float ModelUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
void SetModelFlipbookParameter(const Effekseer::NodeRendererFlipbookParameter& param)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelUVDistortionUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendAlphaUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUVDistortionUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelFlipbookIndexAndNextRate(int32_t index, float value)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaThreshold(int32_t index, float value)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
float ModelColor[MODEL_COUNT][4];
|
|||
|
|
|||
|
float LightDirection[4];
|
|||
|
float LightColor[4];
|
|||
|
float LightAmbientColor[4];
|
|||
|
float UVInversed[4];
|
|||
|
};
|
|||
|
|
|||
|
template <int MODEL_COUNT>
|
|||
|
struct ModelRendererAdvancedVertexConstantBuffer
|
|||
|
{
|
|||
|
Effekseer::Matrix44 CameraMatrix;
|
|||
|
Effekseer::Matrix44 ModelMatrix[MODEL_COUNT];
|
|||
|
float ModelUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelAlphaUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelUVDistortionUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelBlendUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelBlendAlphaUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelBlendUVDistortionUV[MODEL_COUNT][4];
|
|||
|
|
|||
|
FlipbookVertexBuffer ModelFlipbookParameter;
|
|||
|
|
|||
|
float ModelFlipbookIndexAndNextRate[MODEL_COUNT][4];
|
|||
|
|
|||
|
float ModelAlphaThreshold[MODEL_COUNT][4];
|
|||
|
|
|||
|
void SetModelFlipbookParameter(const Effekseer::NodeRendererFlipbookParameter& param)
|
|||
|
{
|
|||
|
const auto state = ToState(param);
|
|||
|
ModelFlipbookParameter = ToVertexBuffer(state);
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
ModelAlphaUV[index][0] = x;
|
|||
|
ModelAlphaUV[index][1] = y;
|
|||
|
ModelAlphaUV[index][2] = w;
|
|||
|
ModelAlphaUV[index][3] = h;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelUVDistortionUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
ModelUVDistortionUV[index][0] = x;
|
|||
|
ModelUVDistortionUV[index][1] = y;
|
|||
|
ModelUVDistortionUV[index][2] = w;
|
|||
|
ModelUVDistortionUV[index][3] = h;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
ModelBlendUV[index][0] = x;
|
|||
|
ModelBlendUV[index][1] = y;
|
|||
|
ModelBlendUV[index][2] = w;
|
|||
|
ModelBlendUV[index][3] = h;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendAlphaUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
ModelBlendAlphaUV[index][0] = x;
|
|||
|
ModelBlendAlphaUV[index][1] = y;
|
|||
|
ModelBlendAlphaUV[index][2] = w;
|
|||
|
ModelBlendAlphaUV[index][3] = h;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUVDistortionUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
ModelBlendUVDistortionUV[index][0] = x;
|
|||
|
ModelBlendUVDistortionUV[index][1] = y;
|
|||
|
ModelBlendUVDistortionUV[index][2] = w;
|
|||
|
ModelBlendUVDistortionUV[index][3] = h;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelFlipbookIndexAndNextRate(int32_t index, float value)
|
|||
|
{
|
|||
|
ModelFlipbookIndexAndNextRate[index][0] = value;
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaThreshold(int32_t index, float value)
|
|||
|
{
|
|||
|
ModelAlphaThreshold[index][0] = value;
|
|||
|
}
|
|||
|
|
|||
|
float ModelColor[MODEL_COUNT][4];
|
|||
|
|
|||
|
float LightDirection[4];
|
|||
|
float LightColor[4];
|
|||
|
float LightAmbientColor[4];
|
|||
|
float UVInversed[4];
|
|||
|
};
|
|||
|
|
|||
|
template <int MODEL_COUNT>
|
|||
|
struct ModelRendererMaterialVertexConstantBuffer
|
|||
|
{
|
|||
|
Effekseer::Matrix44 CameraMatrix;
|
|||
|
Effekseer::Matrix44 ModelMatrix[MODEL_COUNT];
|
|||
|
float ModelUV[MODEL_COUNT][4];
|
|||
|
float ModelColor[MODEL_COUNT][4];
|
|||
|
|
|||
|
float LightDirection[4];
|
|||
|
float LightColor[4];
|
|||
|
float LightAmbientColor[4];
|
|||
|
float UVInversed[4];
|
|||
|
|
|||
|
void SetModelFlipbookParameter(const Effekseer::NodeRendererFlipbookParameter& param)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelUVDistortionUV(int32_t index, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUV(int32_t iondex, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendAlphaUV(int32_t iondex, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelBlendUVDistortionUV(int32_t iondex, float x, float y, float w, float h)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelFlipbookIndexAndNextRate(int32_t index, float value)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void SetModelAlphaThreshold(int32_t index, float value)
|
|||
|
{
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
enum class ModelRendererVertexType
|
|||
|
{
|
|||
|
Instancing,
|
|||
|
Single,
|
|||
|
};
|
|||
|
|
|||
|
class ModelRendererBase : public ::Effekseer::ModelRenderer, public ::Effekseer::SIMD::AlignedAllocationPolicy<16>
|
|||
|
{
|
|||
|
protected:
|
|||
|
struct KeyValue
|
|||
|
{
|
|||
|
float Key;
|
|||
|
int Value;
|
|||
|
};
|
|||
|
|
|||
|
std::vector<KeyValue> keyValues_;
|
|||
|
|
|||
|
std::vector<Effekseer::Matrix44> matrixesSorted_;
|
|||
|
std::vector<Effekseer::RectF> uvSorted_;
|
|||
|
std::vector<Effekseer::RectF> alphaUVSorted_;
|
|||
|
std::vector<Effekseer::RectF> uvDistortionUVSorted_;
|
|||
|
std::vector<Effekseer::RectF> blendUVSorted_;
|
|||
|
std::vector<Effekseer::RectF> blendAlphaUVSorted_;
|
|||
|
std::vector<Effekseer::RectF> blendUVDistortionUVSorted_;
|
|||
|
std::vector<float> flipbookIndexAndNextRateSorted_;
|
|||
|
std::vector<float> alphaThresholdSorted_;
|
|||
|
std::vector<float> viewOffsetDistanceSorted_;
|
|||
|
|
|||
|
std::vector<Effekseer::Color> colorsSorted_;
|
|||
|
std::vector<int32_t> timesSorted_;
|
|||
|
std::vector<std::array<float, 4>> customData1Sorted_;
|
|||
|
std::vector<std::array<float, 4>> customData2Sorted_;
|
|||
|
|
|||
|
std::vector<Effekseer::Matrix44> m_matrixes;
|
|||
|
std::vector<Effekseer::RectF> m_uv;
|
|||
|
|
|||
|
std::vector<Effekseer::RectF> m_alphaUV;
|
|||
|
std::vector<Effekseer::RectF> m_uvDistortionUV;
|
|||
|
std::vector<Effekseer::RectF> m_blendUV;
|
|||
|
std::vector<Effekseer::RectF> m_blendAlphaUV;
|
|||
|
std::vector<Effekseer::RectF> m_blendUVDistortionUV;
|
|||
|
std::vector<float> m_flipbookIndexAndNextRate;
|
|||
|
std::vector<float> m_alphaThreshold;
|
|||
|
std::vector<float> m_viewOffsetDistance;
|
|||
|
|
|||
|
std::vector<Effekseer::Color> m_colors;
|
|||
|
std::vector<int32_t> m_times;
|
|||
|
std::vector<std::array<float, 4>> customData1_;
|
|||
|
std::vector<std::array<float, 4>> customData2_;
|
|||
|
|
|||
|
int32_t customData1Count_ = 0;
|
|||
|
int32_t customData2Count_ = 0;
|
|||
|
|
|||
|
ShaderParameterCollector collector_;
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
std::array<float, 4> ColorToFloat4(::Effekseer::Color color)
|
|||
|
{
|
|||
|
std::array<float, 4> fc;
|
|||
|
fc[0] = color.R / 255.0f;
|
|||
|
fc[1] = color.G / 255.0f;
|
|||
|
fc[2] = color.B / 255.0f;
|
|||
|
fc[3] = color.A / 255.0f;
|
|||
|
return fc;
|
|||
|
}
|
|||
|
|
|||
|
void VectorToFloat4(const ::Effekseer::SIMD::Vec3f& v, float fc[4])
|
|||
|
{
|
|||
|
::Effekseer::SIMD::Float4::Store3(fc, v.s);
|
|||
|
fc[3] = 1.0f;
|
|||
|
}
|
|||
|
|
|||
|
void VectorToFloat4(const ::Effekseer::SIMD::Vec3f& v, std::array<float, 4>& fc)
|
|||
|
{
|
|||
|
::Effekseer::SIMD::Float4::Store3(fc.data(), v.s);
|
|||
|
fc[3] = 1.0f;
|
|||
|
}
|
|||
|
|
|||
|
ModelRendererBase()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER>
|
|||
|
void GetInversedFlags(RENDERER* renderer, std::array<float, 4>& uvInversed, std::array<float, 4>& uvInversedBack)
|
|||
|
{
|
|||
|
if (renderer->GetTextureUVStyle() == UVStyle::VerticalFlipped)
|
|||
|
{
|
|||
|
uvInversed[0] = 1.0f;
|
|||
|
uvInversed[1] = -1.0f;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
uvInversed[0] = 0.0f;
|
|||
|
uvInversed[1] = 1.0f;
|
|||
|
}
|
|||
|
|
|||
|
if (renderer->GetBackgroundTextureUVStyle() == UVStyle::VerticalFlipped)
|
|||
|
{
|
|||
|
uvInversedBack[0] = 1.0f;
|
|||
|
uvInversedBack[1] = -1.0f;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
uvInversedBack[0] = 0.0f;
|
|||
|
uvInversedBack[1] = 1.0f;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER>
|
|||
|
void SortTemporaryValues(RENDERER* renderer, const efkModelNodeParam& param)
|
|||
|
{
|
|||
|
if (param.DepthParameterPtr->ZSort != Effekseer::ZSortType::None)
|
|||
|
{
|
|||
|
keyValues_.resize(m_matrixes.size());
|
|||
|
for (size_t i = 0; i < keyValues_.size(); i++)
|
|||
|
{
|
|||
|
efkVector3D t(m_matrixes[i].Values[3][0], m_matrixes[i].Values[3][1], m_matrixes[i].Values[3][2]);
|
|||
|
|
|||
|
auto frontDirection = renderer->GetCameraFrontDirection();
|
|||
|
if (!param.IsRightHand)
|
|||
|
{
|
|||
|
frontDirection = -frontDirection;
|
|||
|
}
|
|||
|
|
|||
|
keyValues_[i].Key = Effekseer::SIMD::Vec3f::Dot(t, frontDirection);
|
|||
|
keyValues_[i].Value = static_cast<int32_t>(i);
|
|||
|
}
|
|||
|
|
|||
|
if (param.DepthParameterPtr->ZSort == Effekseer::ZSortType::NormalOrder)
|
|||
|
{
|
|||
|
std::sort(keyValues_.begin(), keyValues_.end(), [](const KeyValue& a, const KeyValue& b) -> bool { return a.Key < b.Key; });
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
std::sort(keyValues_.begin(), keyValues_.end(), [](const KeyValue& a, const KeyValue& b) -> bool { return a.Key > b.Key; });
|
|||
|
}
|
|||
|
|
|||
|
matrixesSorted_.resize(m_matrixes.size());
|
|||
|
uvSorted_.resize(m_matrixes.size());
|
|||
|
alphaUVSorted_.resize(m_matrixes.size());
|
|||
|
uvDistortionUVSorted_.resize(m_matrixes.size());
|
|||
|
blendUVSorted_.resize(m_matrixes.size());
|
|||
|
blendAlphaUVSorted_.resize(m_matrixes.size());
|
|||
|
blendUVDistortionUVSorted_.resize(m_matrixes.size());
|
|||
|
flipbookIndexAndNextRateSorted_.resize(m_matrixes.size());
|
|||
|
alphaThresholdSorted_.resize(m_matrixes.size());
|
|||
|
viewOffsetDistanceSorted_.resize(m_matrixes.size());
|
|||
|
colorsSorted_.resize(m_matrixes.size());
|
|||
|
timesSorted_.resize(m_matrixes.size());
|
|||
|
|
|||
|
if (customData1Count_ > 0)
|
|||
|
{
|
|||
|
customData1Sorted_.resize(m_matrixes.size());
|
|||
|
}
|
|||
|
|
|||
|
if (customData2Count_ > 0)
|
|||
|
{
|
|||
|
customData2Sorted_.resize(m_matrixes.size());
|
|||
|
}
|
|||
|
|
|||
|
for (size_t i = 0; i < keyValues_.size(); i++)
|
|||
|
{
|
|||
|
matrixesSorted_[keyValues_[i].Value] = m_matrixes[i];
|
|||
|
uvSorted_[keyValues_[i].Value] = m_uv[i];
|
|||
|
alphaUVSorted_[keyValues_[i].Value] = m_alphaUV[i];
|
|||
|
uvDistortionUVSorted_[keyValues_[i].Value] = m_uvDistortionUV[i];
|
|||
|
blendUVSorted_[keyValues_[i].Value] = m_blendUV[i];
|
|||
|
blendAlphaUVSorted_[keyValues_[i].Value] = m_blendAlphaUV[i];
|
|||
|
blendUVDistortionUVSorted_[keyValues_[i].Value] = m_blendUVDistortionUV[i];
|
|||
|
flipbookIndexAndNextRateSorted_[keyValues_[i].Value] = m_flipbookIndexAndNextRate[i];
|
|||
|
alphaThresholdSorted_[keyValues_[i].Value] = m_alphaThreshold[i];
|
|||
|
viewOffsetDistanceSorted_[keyValues_[i].Value] = m_viewOffsetDistance[i];
|
|||
|
colorsSorted_[keyValues_[i].Value] = m_colors[i];
|
|||
|
timesSorted_[keyValues_[i].Value] = m_times[i];
|
|||
|
}
|
|||
|
|
|||
|
if (customData1Count_ > 0)
|
|||
|
{
|
|||
|
for (size_t i = 0; i < keyValues_.size(); i++)
|
|||
|
{
|
|||
|
customData1Sorted_[keyValues_[i].Value] = customData1_[i];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (customData2Count_ > 0)
|
|||
|
{
|
|||
|
for (size_t i = 0; i < keyValues_.size(); i++)
|
|||
|
{
|
|||
|
customData2Sorted_[keyValues_[i].Value] = customData2_[i];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_matrixes = matrixesSorted_;
|
|||
|
m_uv = uvSorted_;
|
|||
|
m_alphaUV = alphaUVSorted_;
|
|||
|
m_uvDistortionUV = uvDistortionUVSorted_;
|
|||
|
m_blendUV = blendUVSorted_;
|
|||
|
m_blendAlphaUV = blendAlphaUVSorted_;
|
|||
|
m_blendUVDistortionUV = blendUVDistortionUVSorted_;
|
|||
|
m_flipbookIndexAndNextRate = flipbookIndexAndNextRateSorted_;
|
|||
|
m_alphaThreshold = alphaThresholdSorted_;
|
|||
|
m_viewOffsetDistance = viewOffsetDistanceSorted_;
|
|||
|
m_colors = colorsSorted_;
|
|||
|
m_times = timesSorted_;
|
|||
|
customData1_ = customData1Sorted_;
|
|||
|
customData2_ = customData2Sorted_;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER, typename SHADER, int InstanceCount>
|
|||
|
void StoreFileUniform(RENDERER* renderer,
|
|||
|
SHADER* shader_,
|
|||
|
Effekseer::MaterialRef material,
|
|||
|
Effekseer::MaterialRenderData* materialRenderData,
|
|||
|
const efkModelNodeParam& param,
|
|||
|
int32_t renderPassInd,
|
|||
|
float*& cutomData1Ptr,
|
|||
|
float*& cutomData2Ptr)
|
|||
|
{
|
|||
|
std::array<float, 4> uvInversed;
|
|||
|
std::array<float, 4> uvInversedBack;
|
|||
|
cutomData1Ptr = nullptr;
|
|||
|
cutomData2Ptr = nullptr;
|
|||
|
|
|||
|
const auto materialGradientCount = static_cast<int32_t>(Effekseer::Min(materialRenderData->MaterialGradients.size(), Effekseer::UserGradientSlotMax));
|
|||
|
|
|||
|
GetInversedFlags(renderer, uvInversed, uvInversedBack);
|
|||
|
|
|||
|
std::array<float, 4> uvInversedMaterial;
|
|||
|
uvInversedMaterial[0] = uvInversed[0];
|
|||
|
uvInversedMaterial[1] = uvInversed[1];
|
|||
|
uvInversedMaterial[2] = uvInversedBack[0];
|
|||
|
uvInversedMaterial[3] = uvInversedBack[1];
|
|||
|
|
|||
|
// camera
|
|||
|
float cameraPosition[4];
|
|||
|
::Effekseer::SIMD::Vec3f cameraPosition3 = renderer->GetCameraPosition();
|
|||
|
VectorToFloat4(cameraPosition3, cameraPosition);
|
|||
|
|
|||
|
// time
|
|||
|
std::array<float, 4> predefined_uniforms;
|
|||
|
predefined_uniforms.fill(0.5f);
|
|||
|
predefined_uniforms[0] = renderer->GetTime();
|
|||
|
predefined_uniforms[1] = param.Magnification;
|
|||
|
predefined_uniforms[2] = renderer->GetImpl()->MaintainGammaColorInLinearColorSpace ? 1.0f : 0.0f;
|
|||
|
predefined_uniforms[3] = param.LocalTime;
|
|||
|
|
|||
|
// vs
|
|||
|
int32_t vsOffset = sizeof(Effekseer::Matrix44) + (sizeof(Effekseer::Matrix44) + sizeof(float) * 4 * 2) * InstanceCount;
|
|||
|
|
|||
|
renderer->SetVertexBufferToShader(uvInversedMaterial.data(), sizeof(float) * 4, vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetVertexBufferToShader(predefined_uniforms.data(), sizeof(float) * 4, vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetVertexBufferToShader(cameraPosition, sizeof(float) * 4, vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
// vs - custom data
|
|||
|
if (customData1Count_ > 0)
|
|||
|
{
|
|||
|
cutomData1Ptr = (float*)((uint8_t*)shader_->GetVertexConstantBuffer() + vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4) * InstanceCount;
|
|||
|
}
|
|||
|
|
|||
|
if (customData2Count_ > 0)
|
|||
|
{
|
|||
|
cutomData2Ptr = (float*)((uint8_t*)shader_->GetVertexConstantBuffer() + vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4) * InstanceCount;
|
|||
|
}
|
|||
|
|
|||
|
for (size_t i = 0; i < materialRenderData->MaterialUniforms.size(); i++)
|
|||
|
{
|
|||
|
renderer->SetVertexBufferToShader(materialRenderData->MaterialUniforms[i].data(), sizeof(float) * 4, vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4);
|
|||
|
}
|
|||
|
|
|||
|
for (size_t i = 0; i < materialGradientCount; i++)
|
|||
|
{
|
|||
|
auto data = ToUniform(*materialRenderData->MaterialGradients[i]);
|
|||
|
renderer->SetVertexBufferToShader(data.data(), sizeof(float) * 4 * 13, vsOffset);
|
|||
|
vsOffset += (sizeof(float) * 4) * 13;
|
|||
|
}
|
|||
|
|
|||
|
// ps
|
|||
|
int32_t psOffset = 0;
|
|||
|
renderer->SetPixelBufferToShader(uvInversedMaterial.data(), sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(predefined_uniforms.data(), sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(cameraPosition, sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
::Effekseer::Backend::TextureRef depthTexture = nullptr;
|
|||
|
::EffekseerRenderer::DepthReconstructionParameter reconstructionParam;
|
|||
|
renderer->GetImpl()->GetDepth(depthTexture, reconstructionParam);
|
|||
|
|
|||
|
SoftParticleParameter softParticleParam;
|
|||
|
|
|||
|
softParticleParam.SetParam(
|
|||
|
0.0f,
|
|||
|
0.0f,
|
|||
|
0.0f,
|
|||
|
param.Maginification,
|
|||
|
reconstructionParam.DepthBufferScale,
|
|||
|
reconstructionParam.DepthBufferOffset,
|
|||
|
reconstructionParam.ProjectionMatrix33,
|
|||
|
reconstructionParam.ProjectionMatrix34,
|
|||
|
reconstructionParam.ProjectionMatrix43,
|
|||
|
reconstructionParam.ProjectionMatrix44);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(softParticleParam.reconstructionParam1.data(), sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(softParticleParam.reconstructionParam2.data(), sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
// shader model
|
|||
|
material = param.EffectPointer->GetMaterial(materialRenderData->MaterialIndex);
|
|||
|
|
|||
|
float lightDirection[4];
|
|||
|
float lightColor[4];
|
|||
|
float lightAmbientColor[4];
|
|||
|
|
|||
|
::Effekseer::SIMD::Vec3f lightDirection3 = renderer->GetLightDirection();
|
|||
|
lightDirection3 = lightDirection3.Normalize();
|
|||
|
|
|||
|
VectorToFloat4(lightDirection3, lightDirection);
|
|||
|
ColorToFloat4(renderer->GetLightColor(), lightColor);
|
|||
|
ColorToFloat4(renderer->GetLightAmbientColor(), lightAmbientColor);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(lightDirection, sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(lightColor, sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
renderer->SetPixelBufferToShader(lightAmbientColor, sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
|
|||
|
// refraction
|
|||
|
if (material->RefractionModelUserPtr != nullptr && renderPassInd == 0)
|
|||
|
{
|
|||
|
auto mat = renderer->GetCameraMatrix();
|
|||
|
renderer->SetPixelBufferToShader(&mat, sizeof(float) * 16, psOffset);
|
|||
|
psOffset += (sizeof(float) * 16);
|
|||
|
}
|
|||
|
|
|||
|
for (size_t i = 0; i < materialRenderData->MaterialUniforms.size(); i++)
|
|||
|
{
|
|||
|
renderer->SetPixelBufferToShader(materialRenderData->MaterialUniforms[i].data(), sizeof(float) * 4, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4);
|
|||
|
}
|
|||
|
|
|||
|
for (int32_t i = 0; i < materialGradientCount; i++)
|
|||
|
{
|
|||
|
auto data = ToUniform(*materialRenderData->MaterialGradients[i]);
|
|||
|
renderer->SetPixelBufferToShader(data.data(), sizeof(float) * 4 * 13, psOffset);
|
|||
|
psOffset += (sizeof(float) * 4) * 13;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER, typename SHADER, int InstanceCount, typename VertexConstantBufferType, bool REQUIRE_ADVANCED_DATA, bool DISTORTION>
|
|||
|
void StoreFixedUniforms(RENDERER* renderer,
|
|||
|
SHADER* shader_,
|
|||
|
const efkModelNodeParam& param)
|
|||
|
{
|
|||
|
VertexConstantBufferType* vcb = (VertexConstantBufferType*)shader_->GetVertexConstantBuffer();
|
|||
|
std::array<float, 4> uvInversed;
|
|||
|
std::array<float, 4> uvInversedBack;
|
|||
|
|
|||
|
GetInversedFlags(renderer, uvInversed, uvInversedBack);
|
|||
|
|
|||
|
vcb->UVInversed[0] = uvInversed[0];
|
|||
|
vcb->UVInversed[1] = uvInversed[1];
|
|||
|
|
|||
|
::Effekseer::Backend::TextureRef depthTexture = nullptr;
|
|||
|
::EffekseerRenderer::DepthReconstructionParameter reconstructionParam;
|
|||
|
renderer->GetImpl()->GetDepth(depthTexture, reconstructionParam);
|
|||
|
|
|||
|
if (DISTORTION)
|
|||
|
{
|
|||
|
auto pcb = (PixelConstantBufferDistortion*)shader_->GetPixelConstantBuffer();
|
|||
|
pcb->DistortionIntencity[0] = param.BasicParameterPtr->DistortionIntensity;
|
|||
|
|
|||
|
pcb->UVInversedBack[0] = uvInversedBack[0];
|
|||
|
pcb->UVInversedBack[1] = uvInversedBack[1];
|
|||
|
|
|||
|
pcb->FlipbookParam.EnableInterpolation = static_cast<float>(param.BasicParameterPtr->Flipbook.EnableInterpolation);
|
|||
|
pcb->FlipbookParam.InterpolationType = static_cast<float>(param.BasicParameterPtr->Flipbook.InterpolationType);
|
|||
|
|
|||
|
pcb->UVDistortionParam.Intensity = param.BasicParameterPtr->UVDistortionIntensity;
|
|||
|
pcb->UVDistortionParam.BlendIntensity = param.BasicParameterPtr->BlendUVDistortionIntensity;
|
|||
|
pcb->UVDistortionParam.UVInversed[0] = uvInversed[0];
|
|||
|
pcb->UVDistortionParam.UVInversed[1] = uvInversed[1];
|
|||
|
|
|||
|
pcb->BlendTextureParam.BlendType = static_cast<float>(param.BasicParameterPtr->TextureBlendType);
|
|||
|
|
|||
|
pcb->SoftParticleParam.SetParam(
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceFar,
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNear,
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNearOffset,
|
|||
|
param.Maginification,
|
|||
|
reconstructionParam.DepthBufferScale,
|
|||
|
reconstructionParam.DepthBufferOffset,
|
|||
|
reconstructionParam.ProjectionMatrix33,
|
|||
|
reconstructionParam.ProjectionMatrix34,
|
|||
|
reconstructionParam.ProjectionMatrix43,
|
|||
|
reconstructionParam.ProjectionMatrix44);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
auto pcb = (PixelConstantBuffer*)shader_->GetPixelConstantBuffer();
|
|||
|
pcb->MiscFlags.fill(0.0f);
|
|||
|
pcb->MiscFlags[0] = renderer->GetImpl()->MaintainGammaColorInLinearColorSpace ? 1.0f : 0.0f;
|
|||
|
|
|||
|
// specify predefined parameters
|
|||
|
if (param.BasicParameterPtr->MaterialType == Effekseer::RendererMaterialType::Lighting)
|
|||
|
{
|
|||
|
::Effekseer::SIMD::Vec3f lightDirection = renderer->GetLightDirection();
|
|||
|
lightDirection = lightDirection.Normalize();
|
|||
|
VectorToFloat4(lightDirection, vcb->LightDirection);
|
|||
|
VectorToFloat4(lightDirection, pcb->LightDirection);
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
ColorToFloat4(renderer->GetLightColor(), vcb->LightColor);
|
|||
|
pcb->LightColor = ColorToFloat4(renderer->GetLightColor());
|
|||
|
}
|
|||
|
|
|||
|
{
|
|||
|
ColorToFloat4(renderer->GetLightAmbientColor(), vcb->LightAmbientColor);
|
|||
|
pcb->LightAmbientColor = ColorToFloat4(renderer->GetLightAmbientColor());
|
|||
|
}
|
|||
|
|
|||
|
pcb->SetEmissiveScaling(static_cast<float>(param.BasicParameterPtr->EmissiveScaling));
|
|||
|
|
|||
|
if (REQUIRE_ADVANCED_DATA)
|
|||
|
{
|
|||
|
pcb->SetModelFlipbookParameter(param.BasicParameterPtr->Flipbook.EnableInterpolation, static_cast<float>(param.BasicParameterPtr->Flipbook.InterpolationType));
|
|||
|
pcb->SetModelUVDistortionParameter(param.BasicParameterPtr->UVDistortionIntensity, param.BasicParameterPtr->BlendUVDistortionIntensity, {uvInversed[0], uvInversed[1]});
|
|||
|
pcb->SetModelBlendTextureParameter(static_cast<float>(param.BasicParameterPtr->TextureBlendType));
|
|||
|
|
|||
|
::Effekseer::Vector3D CameraFront = renderer->GetCameraFrontDirection();
|
|||
|
|
|||
|
if (!param.IsRightHand)
|
|||
|
{
|
|||
|
CameraFront = -CameraFront;
|
|||
|
}
|
|||
|
|
|||
|
pcb->SetCameraFrontDirection(-CameraFront.X, -CameraFront.Y, -CameraFront.Z);
|
|||
|
pcb->SetFalloffParameter(
|
|||
|
static_cast<float>(param.EnableFalloff),
|
|||
|
static_cast<float>(param.FalloffParam.ColorBlendType),
|
|||
|
static_cast<float>(param.FalloffParam.Pow),
|
|||
|
ColorToFloat4(param.FalloffParam.BeginColor),
|
|||
|
ColorToFloat4(param.FalloffParam.EndColor));
|
|||
|
|
|||
|
pcb->SetEdgeParameter(ColorToFloat4(Effekseer::Color(
|
|||
|
param.BasicParameterPtr->EdgeColor[0],
|
|||
|
param.BasicParameterPtr->EdgeColor[1],
|
|||
|
param.BasicParameterPtr->EdgeColor[2],
|
|||
|
param.BasicParameterPtr->EdgeColor[3])),
|
|||
|
param.BasicParameterPtr->EdgeThreshold,
|
|||
|
static_cast<float>(param.BasicParameterPtr->EdgeColorScaling));
|
|||
|
}
|
|||
|
|
|||
|
pcb->SoftParticleParam.SetParam(
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceFar,
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNear,
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNearOffset,
|
|||
|
param.Maginification,
|
|||
|
reconstructionParam.DepthBufferScale,
|
|||
|
reconstructionParam.DepthBufferOffset,
|
|||
|
reconstructionParam.ProjectionMatrix33,
|
|||
|
reconstructionParam.ProjectionMatrix34,
|
|||
|
reconstructionParam.ProjectionMatrix43,
|
|||
|
reconstructionParam.ProjectionMatrix44);
|
|||
|
|
|||
|
pcb->UVInversedBack[0] = uvInversedBack[0];
|
|||
|
pcb->UVInversedBack[1] = uvInversedBack[1];
|
|||
|
}
|
|||
|
|
|||
|
vcb->CameraMatrix = renderer->GetCameraProjectionMatrix();
|
|||
|
|
|||
|
vcb->SetModelFlipbookParameter(param.BasicParameterPtr->Flipbook);
|
|||
|
}
|
|||
|
|
|||
|
public:
|
|||
|
ModelRendererVertexType VertexType = ModelRendererVertexType::Single;
|
|||
|
|
|||
|
virtual ~ModelRendererBase()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER>
|
|||
|
void BeginRendering_(RENDERER* renderer, const efkModelNodeParam& parameter, int32_t count, void* userData)
|
|||
|
{
|
|||
|
keyValues_.clear();
|
|||
|
|
|||
|
m_matrixes.clear();
|
|||
|
m_uv.clear();
|
|||
|
m_alphaUV.clear();
|
|||
|
m_uvDistortionUV.clear();
|
|||
|
m_blendUV.clear();
|
|||
|
m_blendAlphaUV.clear();
|
|||
|
m_blendUVDistortionUV.clear();
|
|||
|
m_flipbookIndexAndNextRate.clear();
|
|||
|
m_alphaThreshold.clear();
|
|||
|
m_viewOffsetDistance.clear();
|
|||
|
m_colors.clear();
|
|||
|
m_times.clear();
|
|||
|
customData1_.clear();
|
|||
|
customData2_.clear();
|
|||
|
|
|||
|
matrixesSorted_.clear();
|
|||
|
uvSorted_.clear();
|
|||
|
alphaUVSorted_.clear();
|
|||
|
uvDistortionUVSorted_.clear();
|
|||
|
blendUVSorted_.clear();
|
|||
|
blendAlphaUVSorted_.clear();
|
|||
|
blendUVDistortionUVSorted_.clear();
|
|||
|
flipbookIndexAndNextRateSorted_.clear();
|
|||
|
alphaThresholdSorted_.clear();
|
|||
|
viewOffsetDistanceSorted_.clear();
|
|||
|
colorsSorted_.clear();
|
|||
|
timesSorted_.clear();
|
|||
|
customData1Sorted_.clear();
|
|||
|
customData2Sorted_.clear();
|
|||
|
|
|||
|
if (parameter.BasicParameterPtr->MaterialType == ::Effekseer::RendererMaterialType::File &&
|
|||
|
parameter.BasicParameterPtr->MaterialRenderDataPtr != nullptr &&
|
|||
|
parameter.BasicParameterPtr->MaterialRenderDataPtr->MaterialIndex >= 0 &&
|
|||
|
parameter.EffectPointer->GetMaterial(parameter.BasicParameterPtr->MaterialRenderDataPtr->MaterialIndex) != nullptr)
|
|||
|
{
|
|||
|
auto material = parameter.EffectPointer->GetMaterial(parameter.BasicParameterPtr->MaterialRenderDataPtr->MaterialIndex);
|
|||
|
customData1Count_ = material->CustomData1;
|
|||
|
customData2Count_ = material->CustomData2;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
customData1Count_ = 0;
|
|||
|
customData2Count_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
renderer->GetStandardRenderer()->ResetAndRenderingIfRequired();
|
|||
|
|
|||
|
collector_ = ShaderParameterCollector();
|
|||
|
collector_.Collect(renderer, parameter.EffectPointer, parameter.BasicParameterPtr, parameter.EnableFalloff, renderer->GetImpl()->isSoftParticleEnabled);
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER>
|
|||
|
void Rendering_(RENDERER* renderer, const efkModelNodeParam& parameter, const efkModelInstanceParam& instanceParameter, void* userData)
|
|||
|
{
|
|||
|
::Effekseer::BillboardType btype = parameter.Billboard;
|
|||
|
Effekseer::SIMD::Mat44f mat44;
|
|||
|
|
|||
|
if (btype == ::Effekseer::BillboardType::Fixed)
|
|||
|
{
|
|||
|
mat44 = instanceParameter.SRTMatrix43;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Effekseer::SIMD::Mat43f mat43;
|
|||
|
Effekseer::SIMD::Vec3f s;
|
|||
|
Effekseer::SIMD::Vec3f R;
|
|||
|
Effekseer::SIMD::Vec3f F;
|
|||
|
|
|||
|
CalcBillboard(btype, mat43, s, R, F, instanceParameter.SRTMatrix43, renderer->GetCameraFrontDirection());
|
|||
|
|
|||
|
mat44 = ::Effekseer::SIMD::Mat43f::Scaling(s) * mat43;
|
|||
|
}
|
|||
|
|
|||
|
if (parameter.Magnification != 1.0f)
|
|||
|
{
|
|||
|
mat44 = Effekseer::SIMD::Mat44f::Scaling(::Effekseer::SIMD::Vec3f(parameter.Magnification)) * mat44;
|
|||
|
}
|
|||
|
|
|||
|
if (!parameter.IsRightHand)
|
|||
|
{
|
|||
|
mat44 = Effekseer::SIMD::Mat44f::Scaling(1.0f, 1.0f, -1.0f) * mat44;
|
|||
|
}
|
|||
|
|
|||
|
m_matrixes.push_back(ToStruct(mat44));
|
|||
|
m_uv.push_back(instanceParameter.UV);
|
|||
|
m_alphaUV.push_back(instanceParameter.AlphaUV);
|
|||
|
m_uvDistortionUV.push_back(instanceParameter.UVDistortionUV);
|
|||
|
m_blendUV.push_back(instanceParameter.BlendUV);
|
|||
|
m_blendAlphaUV.push_back(instanceParameter.BlendAlphaUV);
|
|||
|
m_blendUVDistortionUV.push_back(instanceParameter.BlendUVDistortionUV);
|
|||
|
m_flipbookIndexAndNextRate.push_back(instanceParameter.FlipbookIndexAndNextRate);
|
|||
|
m_alphaThreshold.push_back(instanceParameter.AlphaThreshold);
|
|||
|
m_viewOffsetDistance.push_back(instanceParameter.ViewOffsetDistance);
|
|||
|
m_colors.push_back(instanceParameter.AllColor);
|
|||
|
m_times.push_back(instanceParameter.Time);
|
|||
|
|
|||
|
if (customData1Count_ > 0)
|
|||
|
{
|
|||
|
customData1_.push_back(instanceParameter.CustomData1);
|
|||
|
}
|
|||
|
|
|||
|
if (customData2Count_ > 0)
|
|||
|
{
|
|||
|
customData2_.push_back(instanceParameter.CustomData2);
|
|||
|
}
|
|||
|
|
|||
|
//parameter.BasicParameterPtr
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER, typename SHADER, typename MODEL, bool Instancing, int InstanceCount>
|
|||
|
void EndRendering_(RENDERER* renderer,
|
|||
|
SHADER* advanced_shader_lit,
|
|||
|
SHADER* advanced_shader_unlit,
|
|||
|
SHADER* advanced_shader_distortion,
|
|||
|
SHADER* shader_lit,
|
|||
|
SHADER* shader_unlit,
|
|||
|
SHADER* shader_distortion,
|
|||
|
const efkModelNodeParam& param,
|
|||
|
void* userData)
|
|||
|
{
|
|||
|
if (m_matrixes.size() == 0)
|
|||
|
return;
|
|||
|
if (param.ModelIndex < 0)
|
|||
|
return;
|
|||
|
|
|||
|
if (renderer->GetExternalShaderSettings() == nullptr)
|
|||
|
{
|
|||
|
shader_unlit->OverrideShader(nullptr);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
shader_unlit->OverrideShader(renderer->GetExternalShaderSettings()->ModelShader);
|
|||
|
}
|
|||
|
|
|||
|
int32_t renderPassCount = 1;
|
|||
|
|
|||
|
if (param.BasicParameterPtr->MaterialRenderDataPtr != nullptr && param.BasicParameterPtr->MaterialRenderDataPtr->MaterialIndex >= 0)
|
|||
|
{
|
|||
|
auto material = param.EffectPointer->GetMaterial(param.BasicParameterPtr->MaterialRenderDataPtr->MaterialIndex);
|
|||
|
if (material != nullptr && material->IsRefractionRequired)
|
|||
|
{
|
|||
|
// refraction, standard
|
|||
|
renderPassCount = 2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// sort
|
|||
|
SortTemporaryValues(renderer, param);
|
|||
|
|
|||
|
for (int32_t renderPassInd = 0; renderPassInd < renderPassCount; renderPassInd++)
|
|||
|
{
|
|||
|
Effekseer::MaterialRenderData* materialRenderData = param.BasicParameterPtr->MaterialRenderDataPtr;
|
|||
|
|
|||
|
if (materialRenderData != nullptr && materialRenderData->MaterialIndex >= 0 &&
|
|||
|
param.EffectPointer->GetMaterial(materialRenderData->MaterialIndex) != nullptr)
|
|||
|
{
|
|||
|
RenderPass<RENDERER, SHADER, MODEL, Instancing, InstanceCount, ModelRendererMaterialVertexConstantBuffer<InstanceCount>, false>(
|
|||
|
renderer, advanced_shader_lit, advanced_shader_unlit, advanced_shader_distortion, shader_lit, shader_unlit, shader_distortion, param, renderPassInd, userData);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (collector_.DoRequireAdvancedRenderer())
|
|||
|
{
|
|||
|
RenderPass<RENDERER, SHADER, MODEL, Instancing, InstanceCount, ModelRendererAdvancedVertexConstantBuffer<InstanceCount>, true>(
|
|||
|
renderer, advanced_shader_lit, advanced_shader_unlit, advanced_shader_distortion, shader_lit, shader_unlit, shader_distortion, param, renderPassInd, userData);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RenderPass<RENDERER, SHADER, MODEL, Instancing, InstanceCount, ModelRendererVertexConstantBuffer<InstanceCount>, false>(
|
|||
|
renderer, advanced_shader_lit, advanced_shader_unlit, advanced_shader_distortion, shader_lit, shader_unlit, shader_distortion, param, renderPassInd, userData);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename RENDERER, typename SHADER, typename MODEL, bool Instancing, int InstanceCount, typename VertexConstantBufferType, bool REQUIRE_ADVANCED_DATA>
|
|||
|
void RenderPass(RENDERER* renderer,
|
|||
|
SHADER* advanced_shader_lit,
|
|||
|
SHADER* advanced_shader_unlit,
|
|||
|
SHADER* advanced_shader_distortion,
|
|||
|
SHADER* shader_lit,
|
|||
|
SHADER* shader_unlit,
|
|||
|
SHADER* shader_distortion,
|
|||
|
const efkModelNodeParam& param,
|
|||
|
int32_t renderPassInd,
|
|||
|
void* userData)
|
|||
|
{
|
|||
|
if (m_matrixes.size() == 0)
|
|||
|
return;
|
|||
|
if (param.ModelIndex < 0)
|
|||
|
return;
|
|||
|
|
|||
|
::Effekseer::RefPtr<MODEL> model;
|
|||
|
|
|||
|
if (param.IsProceduralMode)
|
|||
|
{
|
|||
|
model = param.EffectPointer->GetProceduralModel(param.ModelIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
model = param.EffectPointer->GetModel(param.ModelIndex);
|
|||
|
}
|
|||
|
|
|||
|
if (model == nullptr)
|
|||
|
return;
|
|||
|
|
|||
|
auto isBackgroundRequired = collector_.IsBackgroundRequiredOnFirstPass && renderPassInd == 0;
|
|||
|
|
|||
|
if (isBackgroundRequired)
|
|||
|
{
|
|||
|
auto callback = renderer->GetDistortingCallback();
|
|||
|
if (callback != nullptr)
|
|||
|
{
|
|||
|
if (!callback->OnDistorting(renderer))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
auto distortion = collector_.ShaderType == EffekseerRenderer::RendererShaderType::BackDistortion ||
|
|||
|
collector_.ShaderType == EffekseerRenderer::RendererShaderType::AdvancedBackDistortion;
|
|||
|
|
|||
|
if (isBackgroundRequired && renderer->GetBackground() == 0)
|
|||
|
return;
|
|||
|
|
|||
|
if (isBackgroundRequired)
|
|||
|
{
|
|||
|
collector_.Textures[collector_.BackgroundIndex] = renderer->GetBackground();
|
|||
|
}
|
|||
|
|
|||
|
::Effekseer::Backend::TextureRef depthTexture = nullptr;
|
|||
|
::EffekseerRenderer::DepthReconstructionParameter reconstructionParam;
|
|||
|
renderer->GetImpl()->GetDepth(depthTexture, reconstructionParam);
|
|||
|
|
|||
|
if (collector_.IsDepthRequired)
|
|||
|
{
|
|||
|
if (depthTexture == nullptr || (param.BasicParameterPtr->SoftParticleDistanceFar == 0.0f &&
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNear == 0.0f &&
|
|||
|
param.BasicParameterPtr->SoftParticleDistanceNearOffset == 0.0f &&
|
|||
|
collector_.ShaderType != RendererShaderType::Material))
|
|||
|
{
|
|||
|
depthTexture = renderer->GetImpl()->GetProxyTexture(EffekseerRenderer::ProxyTextureType::White);
|
|||
|
}
|
|||
|
|
|||
|
collector_.Textures[collector_.DepthIndex] = depthTexture;
|
|||
|
}
|
|||
|
|
|||
|
// select shader
|
|||
|
Effekseer::MaterialRenderData* materialRenderData = param.BasicParameterPtr->MaterialRenderDataPtr;
|
|||
|
// materialRenderData = nullptr;
|
|||
|
Effekseer::MaterialRef material = nullptr;
|
|||
|
SHADER* shader_ = nullptr;
|
|||
|
bool renderDistortedBackground = false;
|
|||
|
|
|||
|
if (collector_.ShaderType == EffekseerRenderer::RendererShaderType::Material &&
|
|||
|
materialRenderData != nullptr && materialRenderData->MaterialIndex >= 0 &&
|
|||
|
param.EffectPointer->GetMaterial(materialRenderData->MaterialIndex) != nullptr)
|
|||
|
{
|
|||
|
material = param.EffectPointer->GetMaterial(materialRenderData->MaterialIndex);
|
|||
|
|
|||
|
if (material != nullptr && material->IsRefractionRequired)
|
|||
|
{
|
|||
|
if (renderPassInd == 0)
|
|||
|
{
|
|||
|
shader_ = (SHADER*)material->RefractionModelUserPtr;
|
|||
|
renderDistortedBackground = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
shader_ = (SHADER*)material->ModelUserPtr;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
shader_ = (SHADER*)material->ModelUserPtr;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (collector_.DoRequireAdvancedRenderer())
|
|||
|
{
|
|||
|
if (distortion)
|
|||
|
{
|
|||
|
shader_ = advanced_shader_distortion;
|
|||
|
}
|
|||
|
else if (collector_.ShaderType == EffekseerRenderer::RendererShaderType::AdvancedLit)
|
|||
|
{
|
|||
|
shader_ = advanced_shader_lit;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
shader_ = advanced_shader_unlit;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (distortion)
|
|||
|
{
|
|||
|
shader_ = shader_distortion;
|
|||
|
}
|
|||
|
else if (collector_.ShaderType == EffekseerRenderer::RendererShaderType::Lit)
|
|||
|
{
|
|||
|
shader_ = shader_lit;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
shader_ = shader_unlit;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// validate
|
|||
|
if (shader_ == nullptr)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
RenderStateBase::State& state = renderer->GetRenderState()->Push();
|
|||
|
state.DepthTest = param.ZTest;
|
|||
|
state.DepthWrite = param.ZWrite;
|
|||
|
state.AlphaBlend = param.BasicParameterPtr->AlphaBlend;
|
|||
|
state.CullingType = param.Culling;
|
|||
|
|
|||
|
// TODO : refactor in 1.7
|
|||
|
if (renderer->GetExternalShaderSettings() != nullptr)
|
|||
|
{
|
|||
|
state.AlphaBlend = renderer->GetExternalShaderSettings()->Blend;
|
|||
|
}
|
|||
|
else if (renderer->GetRenderMode() == Effekseer::RenderMode::Wireframe)
|
|||
|
{
|
|||
|
state.AlphaBlend = ::Effekseer::AlphaBlendType::Opacity;
|
|||
|
}
|
|||
|
|
|||
|
if (renderDistortedBackground)
|
|||
|
{
|
|||
|
state.AlphaBlend = ::Effekseer::AlphaBlendType::Blend;
|
|||
|
}
|
|||
|
|
|||
|
renderer->BeginShader(shader_);
|
|||
|
|
|||
|
for (int32_t i = 0; i < collector_.TextureCount; i++)
|
|||
|
{
|
|||
|
state.TextureFilterTypes[i] = collector_.TextureFilterTypes[i];
|
|||
|
state.TextureWrapTypes[i] = collector_.TextureWrapTypes[i];
|
|||
|
}
|
|||
|
|
|||
|
renderer->SetTextures(shader_, collector_.Textures.data(), collector_.TextureCount);
|
|||
|
|
|||
|
renderer->GetRenderState()->Update(distortion);
|
|||
|
|
|||
|
VertexConstantBufferType* vcb = (VertexConstantBufferType*)shader_->GetVertexConstantBuffer();
|
|||
|
|
|||
|
float* cutomData1Ptr = nullptr;
|
|||
|
float* cutomData2Ptr = nullptr;
|
|||
|
|
|||
|
if (materialRenderData != nullptr && material != nullptr)
|
|||
|
{
|
|||
|
StoreFileUniform<RENDERER, SHADER, InstanceCount>(
|
|||
|
renderer, shader_, material, materialRenderData, param, renderPassInd, cutomData1Ptr, cutomData2Ptr);
|
|||
|
|
|||
|
vcb->CameraMatrix = renderer->GetCameraProjectionMatrix();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (distortion)
|
|||
|
{
|
|||
|
StoreFixedUniforms<RENDERER, SHADER, InstanceCount, VertexConstantBufferType, REQUIRE_ADVANCED_DATA, true>(renderer, shader_, param);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
StoreFixedUniforms<RENDERER, SHADER, InstanceCount, VertexConstantBufferType, REQUIRE_ADVANCED_DATA, false>(renderer, shader_, param);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
renderer->GetImpl()->CurrentRenderingUserData = param.UserData;
|
|||
|
renderer->GetImpl()->CurrentHandleUserData = userData;
|
|||
|
|
|||
|
// Check time
|
|||
|
auto stTime0 = m_times[0] % model->GetFrameCount();
|
|||
|
auto isTimeSame = true;
|
|||
|
|
|||
|
for (auto t : m_times)
|
|||
|
{
|
|||
|
t = t % model->GetFrameCount();
|
|||
|
if (t != stTime0)
|
|||
|
{
|
|||
|
isTimeSame = false;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (Instancing && isTimeSame)
|
|||
|
{
|
|||
|
//auto& imodel = model->InternalModels[stTime0];
|
|||
|
|
|||
|
// Invalid unless layout is set after buffer
|
|||
|
renderer->SetVertexBuffer(model->GetVertexBuffer(stTime0), sizeof(Effekseer::Model::Vertex));
|
|||
|
|
|||
|
int32_t indexPerFace = 3;
|
|||
|
if (renderer->GetRenderMode() == Effekseer::RenderMode::Wireframe)
|
|||
|
{
|
|||
|
renderer->SetIndexBuffer(model->GetWireIndexBuffer(stTime0));
|
|||
|
indexPerFace = 6;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
renderer->SetIndexBuffer(model->GetIndexBuffer(stTime0));
|
|||
|
}
|
|||
|
|
|||
|
renderer->SetLayout(shader_);
|
|||
|
|
|||
|
for (size_t loop = 0; loop < m_matrixes.size();)
|
|||
|
{
|
|||
|
int32_t modelCount = Effekseer::Min(static_cast<int32_t>(m_matrixes.size()) - (int32_t)loop, InstanceCount);
|
|||
|
|
|||
|
for (int32_t num = 0; num < modelCount; num++)
|
|||
|
{
|
|||
|
vcb->ModelMatrix[num] = m_matrixes[loop + num];
|
|||
|
|
|||
|
// DepthParameter
|
|||
|
::Effekseer::SIMD::Mat44f modelMatrix = vcb->ModelMatrix[num];
|
|||
|
|
|||
|
if (param.EnableViewOffset)
|
|||
|
{
|
|||
|
ApplyViewOffset(modelMatrix, renderer->GetCameraMatrix(), m_viewOffsetDistance[loop + num]);
|
|||
|
}
|
|||
|
|
|||
|
ApplyDepthParameters(modelMatrix,
|
|||
|
renderer->GetCameraFrontDirection(),
|
|||
|
renderer->GetCameraPosition(),
|
|||
|
param.DepthParameterPtr,
|
|||
|
param.IsRightHand);
|
|||
|
vcb->ModelMatrix[num] = ToStruct(modelMatrix);
|
|||
|
|
|||
|
vcb->ModelUV[num][0] = m_uv[loop + num].X;
|
|||
|
vcb->ModelUV[num][1] = m_uv[loop + num].Y;
|
|||
|
vcb->ModelUV[num][2] = m_uv[loop + num].Width;
|
|||
|
vcb->ModelUV[num][3] = m_uv[loop + num].Height;
|
|||
|
|
|||
|
vcb->SetModelAlphaUV(
|
|||
|
num, m_alphaUV[loop + num].X, m_alphaUV[loop + num].Y, m_alphaUV[loop + num].Width, m_alphaUV[loop + num].Height);
|
|||
|
vcb->SetModelUVDistortionUV(num,
|
|||
|
m_uvDistortionUV[loop + num].X,
|
|||
|
m_uvDistortionUV[loop + num].Y,
|
|||
|
m_uvDistortionUV[loop + num].Width,
|
|||
|
m_uvDistortionUV[loop + num].Height);
|
|||
|
vcb->SetModelBlendUV(
|
|||
|
num, m_blendUV[loop + num].X, m_blendUV[loop + num].Y, m_blendUV[loop + num].Width, m_blendUV[loop + num].Height);
|
|||
|
vcb->SetModelBlendAlphaUV(num,
|
|||
|
m_blendAlphaUV[loop + num].X,
|
|||
|
m_blendAlphaUV[loop + num].Y,
|
|||
|
m_blendAlphaUV[loop + num].Width,
|
|||
|
m_blendAlphaUV[loop + num].Height);
|
|||
|
vcb->SetModelBlendUVDistortionUV(num,
|
|||
|
m_blendUVDistortionUV[loop + num].X,
|
|||
|
m_blendUVDistortionUV[loop + num].Y,
|
|||
|
m_blendUVDistortionUV[loop + num].Width,
|
|||
|
m_blendUVDistortionUV[loop + num].Height);
|
|||
|
vcb->SetModelFlipbookIndexAndNextRate(num, m_flipbookIndexAndNextRate[loop + num]);
|
|||
|
vcb->SetModelAlphaThreshold(num, m_alphaThreshold[loop + num]);
|
|||
|
|
|||
|
ColorToFloat4(m_colors[loop + num], vcb->ModelColor[num]);
|
|||
|
|
|||
|
if (cutomData1Ptr != nullptr)
|
|||
|
{
|
|||
|
cutomData1Ptr[num * 4 + 0] = customData1_[loop + num][0];
|
|||
|
cutomData1Ptr[num * 4 + 1] = customData1_[loop + num][1];
|
|||
|
cutomData1Ptr[num * 4 + 2] = customData1_[loop + num][2];
|
|||
|
cutomData1Ptr[num * 4 + 3] = customData1_[loop + num][3];
|
|||
|
}
|
|||
|
|
|||
|
if (cutomData2Ptr != nullptr)
|
|||
|
{
|
|||
|
cutomData2Ptr[num * 4 + 0] = customData2_[loop + num][0];
|
|||
|
cutomData2Ptr[num * 4 + 1] = customData2_[loop + num][1];
|
|||
|
cutomData2Ptr[num * 4 + 2] = customData2_[loop + num][2];
|
|||
|
cutomData2Ptr[num * 4 + 3] = customData2_[loop + num][3];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
shader_->SetConstantBuffer();
|
|||
|
|
|||
|
if (VertexType == ModelRendererVertexType::Instancing)
|
|||
|
{
|
|||
|
renderer->DrawPolygonInstanced(model->GetVertexCount(stTime0), model->GetFaceCount(stTime0) * indexPerFace, modelCount);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
assert(0);
|
|||
|
}
|
|||
|
|
|||
|
loop += modelCount;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for (size_t loop = 0; loop < m_matrixes.size();)
|
|||
|
{
|
|||
|
auto stTime = m_times[loop] % model->GetFrameCount();
|
|||
|
// auto& imodel = model->InternalModels[stTime];
|
|||
|
|
|||
|
// Invalid unless layout is set after buffer
|
|||
|
renderer->SetVertexBuffer(model->GetVertexBuffer(stTime), sizeof(Effekseer::Model::Vertex));
|
|||
|
|
|||
|
int32_t indexPerFace = 3;
|
|||
|
if (renderer->GetRenderMode() == Effekseer::RenderMode::Wireframe)
|
|||
|
{
|
|||
|
renderer->SetIndexBuffer(model->GetWireIndexBuffer(stTime));
|
|||
|
indexPerFace = 6;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
renderer->SetIndexBuffer(model->GetIndexBuffer(stTime));
|
|||
|
}
|
|||
|
|
|||
|
renderer->SetLayout(shader_);
|
|||
|
|
|||
|
vcb->ModelMatrix[0] = m_matrixes[loop];
|
|||
|
vcb->ModelUV[0][0] = m_uv[loop].X;
|
|||
|
vcb->ModelUV[0][1] = m_uv[loop].Y;
|
|||
|
vcb->ModelUV[0][2] = m_uv[loop].Width;
|
|||
|
vcb->ModelUV[0][3] = m_uv[loop].Height;
|
|||
|
|
|||
|
vcb->SetModelAlphaUV(0, m_alphaUV[loop].X, m_alphaUV[loop].Y, m_alphaUV[loop].Width, m_alphaUV[loop].Height);
|
|||
|
vcb->SetModelUVDistortionUV(
|
|||
|
0, m_uvDistortionUV[loop].X, m_uvDistortionUV[loop].Y, m_uvDistortionUV[loop].Width, m_uvDistortionUV[loop].Height);
|
|||
|
vcb->SetModelBlendUV(0, m_blendUV[loop].X, m_blendUV[loop].Y, m_blendUV[loop].Width, m_blendUV[loop].Height);
|
|||
|
vcb->SetModelBlendAlphaUV(
|
|||
|
0, m_blendAlphaUV[loop].X, m_blendAlphaUV[loop].Y, m_blendAlphaUV[loop].Width, m_blendAlphaUV[loop].Height);
|
|||
|
vcb->SetModelBlendUVDistortionUV(
|
|||
|
0, m_blendUVDistortionUV[loop].X, m_blendUVDistortionUV[loop].Y, m_blendUVDistortionUV[loop].Width, m_blendUVDistortionUV[loop].Height);
|
|||
|
vcb->SetModelFlipbookIndexAndNextRate(0, m_flipbookIndexAndNextRate[loop]);
|
|||
|
vcb->SetModelAlphaThreshold(0, m_alphaThreshold[loop]);
|
|||
|
|
|||
|
// DepthParameters
|
|||
|
::Effekseer::SIMD::Mat44f modelMatrix = vcb->ModelMatrix[0];
|
|||
|
if (param.EnableViewOffset == true)
|
|||
|
{
|
|||
|
ApplyViewOffset(modelMatrix, renderer->GetCameraMatrix(), m_viewOffsetDistance[0]);
|
|||
|
}
|
|||
|
|
|||
|
ApplyDepthParameters(modelMatrix,
|
|||
|
renderer->GetCameraFrontDirection(),
|
|||
|
renderer->GetCameraPosition(),
|
|||
|
param.DepthParameterPtr,
|
|||
|
param.IsRightHand);
|
|||
|
vcb->ModelMatrix[0] = ToStruct(modelMatrix);
|
|||
|
ColorToFloat4(m_colors[loop], vcb->ModelColor[0]);
|
|||
|
|
|||
|
if (cutomData1Ptr != nullptr)
|
|||
|
{
|
|||
|
cutomData1Ptr[0] = customData1_[loop][0];
|
|||
|
cutomData1Ptr[1] = customData1_[loop][1];
|
|||
|
cutomData1Ptr[2] = customData1_[loop][2];
|
|||
|
cutomData1Ptr[3] = customData1_[loop][3];
|
|||
|
}
|
|||
|
|
|||
|
if (cutomData2Ptr != nullptr)
|
|||
|
{
|
|||
|
cutomData2Ptr[0] = customData2_[loop][0];
|
|||
|
cutomData2Ptr[1] = customData2_[loop][1];
|
|||
|
cutomData2Ptr[2] = customData2_[loop][2];
|
|||
|
cutomData2Ptr[3] = customData2_[loop][3];
|
|||
|
}
|
|||
|
|
|||
|
shader_->SetConstantBuffer();
|
|||
|
renderer->DrawPolygon(model->GetVertexCount(stTime), model->GetFaceCount(stTime) * indexPerFace);
|
|||
|
|
|||
|
loop += 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
renderer->EndShader(shader_);
|
|||
|
|
|||
|
renderer->GetRenderState()->Pop();
|
|||
|
}
|
|||
|
};
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
} // namespace EffekseerRenderer
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------------------
|
|||
|
#endif // __EFFEKSEERRENDERER_MODEL_RENDERER_H__
|