182 lines
6.0 KiB
C++
182 lines
6.0 KiB
C++
#include "device/dvc_buffer_accessor.h"
|
|
#include "math/dvc_vector2.h"
|
|
#include "math/dvc_vector3.h"
|
|
#include "math/dvc_matrix4.h"
|
|
#include "pipe/dvc_render_pipe.h"
|
|
#include "device/dvc_uniform_buffer.h"
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
StandardVertexShader<WithNormal, WithUV>::StandardVertexShader()
|
|
{
|
|
m_outputVertexDesc.addElement("v_position", davinci::VET_POSITION, davinci::CT_Float32, davinci::DT_Vec3);
|
|
|
|
if constexpr(WithNormal)
|
|
m_outputVertexDesc.addElement("v_normal", davinci::VET_NORMAL, davinci::CT_Float32, davinci::DT_Vec3);
|
|
|
|
if constexpr(WithUV)
|
|
m_outputVertexDesc.addElement("v_uv", davinci::VET_TEXCOORD_0, davinci::CT_Float32, davinci::DT_Vec2);
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
StandardVertexShader<WithNormal, WithUV>::~StandardVertexShader()
|
|
{
|
|
|
|
}
|
|
|
|
template<std::size_t N>
|
|
struct CompileTimeString {
|
|
std::array<char, N> data{};
|
|
std::size_t size = 0;
|
|
|
|
constexpr void append(const char* str, std::size_t len) {
|
|
for (std::size_t i = 0; i < len; ++i) {
|
|
data[size++] = str[i];
|
|
}
|
|
}
|
|
|
|
constexpr void append(const char* str) {
|
|
while (*str) {
|
|
data[size++] = *str++;
|
|
}
|
|
}
|
|
|
|
constexpr const char* c_str() const { return data.data(); }
|
|
constexpr std::string_view view() const { return {data.data(), size}; }
|
|
};
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
constexpr auto buildNameString()
|
|
{
|
|
constexpr const char* prefix = "standard";
|
|
constexpr const char* normalString = WithNormal ? "+normal" : "-normal";
|
|
constexpr const char* uvString = WithUV ? "+uv" : "-uv";
|
|
|
|
constexpr std::size_t total_len = std::char_traits<char>::length(prefix)
|
|
+ std::char_traits<char>::length(normalString)
|
|
+ std::char_traits<char>::length(uvString);
|
|
|
|
CompileTimeString<total_len> result;
|
|
result.append(prefix);
|
|
result.append(normalString);
|
|
result.append(uvString);
|
|
result.append(""); // null terminator
|
|
return result;
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
const char* StandardVertexShader<WithNormal, WithUV>::getName(void) const
|
|
{
|
|
static constexpr auto strName = buildNameString<WithNormal, WithUV>();
|
|
const char* p = strName.c_str();
|
|
return p;
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
const davinci::VertexDesc& StandardVertexShader<WithNormal, WithUV>::getOutputVertexDesc() const
|
|
{
|
|
return m_outputVertexDesc;
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
size_t StandardVertexShader<WithNormal, WithUV>::getOutputVertexByteSize(void) const
|
|
{
|
|
return m_outputVertexDesc.vertexByteSize();
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
void StandardVertexShader<WithNormal, WithUV>::prepare(const davinci::RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc)
|
|
{
|
|
m_pipe = pipe;
|
|
|
|
std::get<iPOSITION()>(m_inputAccessors) = setInputAttributeFunc(davinci::VET_POSITION);
|
|
|
|
if constexpr(WithNormal)
|
|
std::get<iNORMAL()>(m_inputAccessors) = setInputAttributeFunc(davinci::VET_NORMAL);
|
|
|
|
if constexpr(WithUV)
|
|
std::get<iUV()>(m_inputAccessors) = setInputAttributeFunc(davinci::VET_TEXCOORD_0);
|
|
|
|
}
|
|
/*
|
|
template<bool WithNormal, bool WithUV>
|
|
davinci::DeviceBufferAccessorConstPtr& StandardVertexShader<WithNormal, WithUV>::getPositionAccessor()
|
|
{
|
|
return std::get<0>(m_inputAccessors);
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
davinci::DeviceBufferAccessorConstPtr& StandardVertexShader<WithNormal, WithUV>::getNormalAccessor()
|
|
{
|
|
if constexpr(WithNormal)
|
|
return std::get<1>(m_inputAccessors);
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
template<bool WithNormal, bool WithUV>
|
|
davinci::DeviceBufferAccessorConstPtr& StandardVertexShader<WithNormal, WithUV>::getUVAccessor()
|
|
{
|
|
if constexpr(WithUV)
|
|
return std::get<WithNormal+1>(m_inputAccessors);
|
|
else
|
|
return nullptr;
|
|
}
|
|
*/
|
|
template<bool WithNormal, bool WithUV>
|
|
void StandardVertexShader<WithNormal, WithUV>::process(size_t index, void* outputVertex, davinci::fVector3& vertexWorldPos)
|
|
{
|
|
static const float DEFAULT_POSITION[] = {0.f, 0.f, 0.f};
|
|
static const float32_t DEFAULT_NORMAL[] = { 0.f, 0.f, 0.f };
|
|
static const float32_t DEFAULT_TEXCOORD0[] = { 0.f, 0.f};
|
|
|
|
const davinci::UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
|
|
|
|
davinci::DeviceBufferAccessorConstPtr inputPosition = std::get<0>(m_inputAccessors);
|
|
|
|
davinci::DeviceBufferAccessorConstPtr inputNormal = nullptr;
|
|
if constexpr(WithNormal)
|
|
inputNormal = std::get<iNORMAL()>(m_inputAccessors);
|
|
|
|
davinci::DeviceBufferAccessorConstPtr inputUV = nullptr;
|
|
if constexpr(WithUV)
|
|
inputUV = std::get<iUV()>(m_inputAccessors);
|
|
|
|
davinci::fVector3 a_position(inputPosition ? (const float32_t*)(inputPosition->getElement(index)) : DEFAULT_POSITION);
|
|
davinci::fVector3 a_normal(inputNormal ? (const float32_t*)(inputNormal->getElement(index)) : DEFAULT_NORMAL);
|
|
davinci::fVector2 a_uv(inputUV ? (const float32_t*)(inputUV->getElement(index)) : DEFAULT_TEXCOORD0);
|
|
|
|
davinci::fMatrix4 mat_world = davinci::fMatrix4::IDENTITY;
|
|
if (davinci::fMatrix4* p_mat_world = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform")))
|
|
{
|
|
mat_world = *p_mat_world;
|
|
}
|
|
|
|
davinci::fMatrix4 mat_camera_view_proj = davinci::fMatrix4::IDENTITY;
|
|
if (davinci::fMatrix4* p_mat_camera_view_proj = (davinci::fMatrix4*)(uniformBuffer.getAttribute("camera:view_proj_mat")))
|
|
{
|
|
mat_camera_view_proj = *p_mat_camera_view_proj;
|
|
}
|
|
|
|
vertexWorldPos = mat_world * a_position;
|
|
davinci::fVector3 v_position = mat_camera_view_proj * vertexWorldPos;
|
|
|
|
int32_t outputOffset=0;
|
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(outputOffset++)->offset, &v_position, sizeof(davinci::fVector3));
|
|
|
|
if constexpr(WithNormal)
|
|
{
|
|
davinci::fMatrix4 matNormal = davinci::fMatrix4::IDENTITY;
|
|
if (davinci::fMatrix4* p_mat_normal = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform_inverse_trans")))
|
|
{
|
|
matNormal = *p_mat_normal;
|
|
}
|
|
davinci::fVector3 v_normal = (matNormal * davinci::fVector4(a_normal, 0)).xyz().normalise();
|
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(outputOffset++)->offset, &v_normal, sizeof(davinci::fVector3));
|
|
}
|
|
|
|
if constexpr(WithUV)
|
|
{
|
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElement(outputOffset++)->offset, &a_uv, sizeof(float32_t) * 2);
|
|
}
|
|
}
|