tornavis/source/blender/draw/intern/attribute_convert.hh

147 lines
5.0 KiB
C++

/* SPDX-FileCopyrightText: 2005 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#include "BLI_color.hh"
#include "BLI_generic_span.hh"
#include "BLI_math_quaternion_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_string_ref.hh"
#include "DNA_customdata_types.h" /* #eCustomDataType. */
#include "GPU_vertex_format.h"
struct GPUVertBuf;
/**
* Component length of 3 is used for scalars because implicit conversion is done by OpenGL from a
* scalar `s` will produce `vec4(s, 0, 0, 1)`. However, following the Blender convention, it should
* be `vec4(s, s, s, 1)`.
*/
constexpr int COMPONENT_LEN_SCALAR = 3;
namespace blender::draw {
/**
* Utility to convert from the type used in the attributes to the types for GPU vertex buffers.
*/
template<typename T> struct AttributeConverter {
using VBOType = void;
};
template<> struct AttributeConverter<bool> {
using VBOType = VecBase<int, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
static VBOType convert(const bool &value)
{
return VBOType(value);
}
};
template<> struct AttributeConverter<int8_t> {
using VBOType = VecBase<int, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
static VBOType convert(const int8_t &value)
{
return VecBase<int, COMPONENT_LEN_SCALAR>(value);
}
};
template<> struct AttributeConverter<int> {
using VBOType = VecBase<int, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
static VBOType convert(const int &value)
{
return int3(value);
}
};
template<> struct AttributeConverter<int2> {
using VBOType = int2;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32;
static constexpr int gpu_component_len = 2;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT;
static VBOType convert(const int2 &value)
{
return int2(value.x, value.y);
}
};
template<> struct AttributeConverter<float> {
using VBOType = VecBase<float, COMPONENT_LEN_SCALAR>;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float &value)
{
return VBOType(value);
}
};
template<> struct AttributeConverter<float2> {
using VBOType = float2;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 2;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float2 &value)
{
return value;
}
};
template<> struct AttributeConverter<float3> {
using VBOType = float3;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 3;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const float3 &value)
{
return value;
}
};
template<> struct AttributeConverter<ColorGeometry4b> {
/* 16 bits are required to store the color in linear space without precision loss. */
using VBOType = ushort4;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_U16;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
static VBOType convert(const ColorGeometry4b &value)
{
return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]),
ushort(value.a * 257)};
}
};
template<> struct AttributeConverter<ColorGeometry4f> {
using VBOType = ColorGeometry4f;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const ColorGeometry4f &value)
{
return value;
}
};
template<> struct AttributeConverter<math::Quaternion> {
using VBOType = float4;
static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32;
static constexpr int gpu_component_len = 4;
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT;
static VBOType convert(const math::Quaternion &value)
{
return float4(value.w, value.x, value.y, value.z);
}
};
GPUVertFormat init_format_for_attribute(eCustomDataType data_type, StringRefNull vbo_name);
void vertbuf_data_extract_direct(GSpan attribute, GPUVertBuf &vbo);
} // namespace blender::draw