mirror of
https://github.com/NoelFB/blah.git
synced 2025-06-29 19:25:26 +08:00
very WIP D3D11 support
This commit is contained in:
@ -15,8 +15,10 @@ namespace Blah
|
||||
int m_count;
|
||||
|
||||
public:
|
||||
static inline constexpr size_t MaxCapacity = Capacity;
|
||||
|
||||
StackVector();
|
||||
StackVector(const std::initializer_list<T>& init);
|
||||
StackVector(const StackVector& src);
|
||||
StackVector(StackVector&& src) noexcept;
|
||||
~StackVector();
|
||||
@ -59,6 +61,14 @@ namespace Blah
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
template<class T, size_t Capacity>
|
||||
inline StackVector<T, Capacity>::StackVector(const std::initializer_list<T>& init)
|
||||
{
|
||||
m_count = 0;
|
||||
for (auto& it : init)
|
||||
push_back(it);
|
||||
}
|
||||
|
||||
template<class T, size_t Capacity>
|
||||
inline StackVector<T, Capacity>::StackVector(const StackVector& src)
|
||||
{
|
||||
|
@ -8,52 +8,121 @@
|
||||
#include <blah/app.h>
|
||||
|
||||
using namespace Blah;
|
||||
namespace
|
||||
{
|
||||
|
||||
// TODO:
|
||||
// This shader needs to be graphics API agnostic
|
||||
// TODO:
|
||||
// This shader needs to be graphics API agnostic
|
||||
|
||||
const ShaderData data = {
|
||||
// vertex shader
|
||||
"#version 330\n"
|
||||
"uniform mat4 u_matrix;\n"
|
||||
"layout(location=0) in vec2 a_position;\n"
|
||||
"layout(location=1) in vec2 a_tex;\n"
|
||||
"layout(location=2) in vec4 a_color;\n"
|
||||
"layout(location=3) in vec3 a_type;\n"
|
||||
"out vec2 v_tex;\n"
|
||||
"out vec4 v_col;\n"
|
||||
"out vec3 v_type;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = u_matrix * vec4(a_position.xy, 0, 1);\n"
|
||||
" v_tex = a_tex;\n"
|
||||
" v_col = a_color;\n"
|
||||
" v_type = a_type;\n"
|
||||
"}",
|
||||
#ifdef BLAH_USE_OPENGL
|
||||
|
||||
// fragment shader
|
||||
"#version 330\n"
|
||||
"uniform sampler2D u_texture;\n"
|
||||
"in vec2 v_tex;\n"
|
||||
"in vec4 v_col;\n"
|
||||
"in vec3 v_type;\n"
|
||||
"out vec4 o_color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" vec4 color = texture(u_texture, v_tex);\n"
|
||||
" o_color = \n"
|
||||
" v_type.x * color * v_col + \n"
|
||||
" v_type.y * color.a * v_col + \n"
|
||||
" v_type.z * v_col;\n"
|
||||
"}"
|
||||
};
|
||||
const ShaderData shader_data = {
|
||||
// vertex shader
|
||||
"#version 330\n"
|
||||
"uniform mat4 u_matrix;\n"
|
||||
"layout(location=0) in vec2 a_position;\n"
|
||||
"layout(location=1) in vec2 a_tex;\n"
|
||||
"layout(location=2) in vec4 a_color;\n"
|
||||
"layout(location=3) in vec4 a_type;\n"
|
||||
"out vec2 v_tex;\n"
|
||||
"out vec4 v_col;\n"
|
||||
"out vec4 v_type;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = u_matrix * vec4(a_position.xy, 0, 1);\n"
|
||||
" v_tex = a_tex;\n"
|
||||
" v_col = a_color;\n"
|
||||
" v_type = a_type;\n"
|
||||
"}",
|
||||
|
||||
const VertexAttribute attributes[4] = {
|
||||
{ 0, VertexSemantics::Position, VertexAttributeType::Float, 2, false },
|
||||
{ 1, VertexSemantics::Texcoord0, VertexAttributeType::Float, 2, false },
|
||||
{ 2, VertexSemantics::Color0, VertexAttributeType::Byte, 4, true },
|
||||
{ 3, VertexSemantics::Texcoord1, VertexAttributeType::Byte, 3, true },
|
||||
};
|
||||
// fragment shader
|
||||
"#version 330\n"
|
||||
"uniform sampler2D u_texture;\n"
|
||||
"in vec2 v_tex;\n"
|
||||
"in vec4 v_col;\n"
|
||||
"in vec4 v_type;\n"
|
||||
"out vec4 o_color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" vec4 color = texture(u_texture, v_tex);\n"
|
||||
" o_color = \n"
|
||||
" v_type.x * color * v_col + \n"
|
||||
" v_type.y * color.a * v_col + \n"
|
||||
" v_type.z * v_col;\n"
|
||||
"}"
|
||||
};
|
||||
|
||||
#elif BLAH_USE_D3D11
|
||||
|
||||
const char* d3d11_shader = ""
|
||||
"cbuffer constants : register(b0)\n"
|
||||
"{\n"
|
||||
" row_major float4x4 u_matrix;\n"
|
||||
"}\n"
|
||||
|
||||
"struct vs_in\n"
|
||||
"{\n"
|
||||
" float2 position : POS;\n"
|
||||
" float2 texcoord : TEX;\n"
|
||||
" float4 color : COL;\n"
|
||||
" float4 mask : MASK;\n"
|
||||
"};\n"
|
||||
|
||||
"struct vs_out\n"
|
||||
"{\n"
|
||||
" float4 position : SV_POSITION;\n"
|
||||
" float2 texcoord : TEX;\n"
|
||||
" float4 color : COL;\n"
|
||||
" float4 mask : MASK;\n"
|
||||
"};\n"
|
||||
|
||||
"Texture2D u_texture : register(t0);\n"
|
||||
"SamplerState u_sampler : register(s0);\n"
|
||||
|
||||
"vs_out vs_main(vs_in input)\n"
|
||||
"{\n"
|
||||
" vs_out output;\n"
|
||||
|
||||
" output.position = mul(float4(input.position, 0.0f, 1.0f), u_matrix);\n"
|
||||
" output.texcoord = input.texcoord;\n"
|
||||
" output.color = input.color;\n"
|
||||
" output.mask = input.mask;\n"
|
||||
|
||||
" return output;\n"
|
||||
"}\n"
|
||||
|
||||
"float4 ps_main(vs_out input) : SV_TARGET\n"
|
||||
"{\n"
|
||||
" float4 color = u_texture.Sample(u_sampler, input.texcoord);\n"
|
||||
" return\n"
|
||||
" input.mask.x * color * input.color + \n"
|
||||
" input.mask.y * color.a * input.color + \n"
|
||||
" input.mask.z * input.color;\n"
|
||||
"}\n";
|
||||
|
||||
const ShaderData shader_data = {
|
||||
d3d11_shader,
|
||||
d3d11_shader,
|
||||
{
|
||||
{ "POS", 0 },
|
||||
{ "TEX", 0 },
|
||||
{ "COL", 0 },
|
||||
{ "MASK", 0 },
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
const ShaderData shader_data;
|
||||
#endif
|
||||
|
||||
const VertexFormat format = VertexFormat(
|
||||
{
|
||||
{ 0, VertexType::Float2, false },
|
||||
{ 1, VertexType::Float2, false },
|
||||
{ 2, VertexType::UByte4, true },
|
||||
{ 3, VertexType::UByte4, true },
|
||||
});
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -84,13 +153,13 @@ namespace
|
||||
#define PUSH_QUAD(px0, py0, px1, py1, px2, py2, px3, py3, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, col0, col1, col2, col3, mult, fill, wash) \
|
||||
{ \
|
||||
m_batch.elements += 2; \
|
||||
int* _i = m_indices.expand(6); \
|
||||
*_i++ = (int)m_vertices.size() + 0; \
|
||||
*_i++ = (int)m_vertices.size() + 1; \
|
||||
*_i++ = (int)m_vertices.size() + 2; \
|
||||
*_i++ = (int)m_vertices.size() + 0; \
|
||||
*_i++ = (int)m_vertices.size() + 2; \
|
||||
*_i++ = (int)m_vertices.size() + 3; \
|
||||
auto _i = m_indices.expand(6); \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 1; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 3; \
|
||||
Vertex* _v = m_vertices.expand(4); \
|
||||
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
|
||||
@ -101,10 +170,10 @@ namespace
|
||||
#define PUSH_TRIANGLE(px0, py0, px1, py1, px2, py2, tx0, ty0, tx1, ty1, tx2, ty2, col0, col1, col2, mult, fill, wash) \
|
||||
{ \
|
||||
m_batch.elements += 1; \
|
||||
int* _i = m_indices.expand(3); \
|
||||
*_i++ = (int)m_vertices.size() + 0; \
|
||||
*_i++ = (int)m_vertices.size() + 1; \
|
||||
*_i++ = (int)m_vertices.size() + 2; \
|
||||
auto* _i = m_indices.expand(3); \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 1; \
|
||||
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||
Vertex* _v = m_vertices.expand(3); \
|
||||
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
|
||||
@ -126,8 +195,6 @@ ShaderRef Batch::m_default_shader;
|
||||
Batch::Batch()
|
||||
{
|
||||
matrix_uniform = "u_matrix";
|
||||
texture_uniform = "u_texture";
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -292,21 +359,18 @@ void Batch::render(const FrameBufferRef& target, const Mat4x4& matrix)
|
||||
// define defaults
|
||||
{
|
||||
if (!m_mesh)
|
||||
{
|
||||
m_mesh = Mesh::create();
|
||||
m_mesh->vertex_format(attributes, 4, sizeof(Vertex));
|
||||
}
|
||||
|
||||
if (!m_default_shader)
|
||||
m_default_shader = Shader::create(&data);
|
||||
m_default_shader = Shader::create(&shader_data);
|
||||
|
||||
if (!m_default_material)
|
||||
m_default_material = Material::create(m_default_shader);
|
||||
}
|
||||
|
||||
// upload data
|
||||
m_mesh->index_data(m_indices.data(), m_indices.size());
|
||||
m_mesh->vertex_data(m_vertices.data(), m_vertices.size());
|
||||
m_mesh->index_data(IndexFormat::UInt32, m_indices.data(), m_indices.size());
|
||||
m_mesh->vertex_data(format, m_vertices.data(), m_vertices.size());
|
||||
|
||||
RenderPass pass;
|
||||
pass.target = target;
|
||||
@ -330,7 +394,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
|
||||
if (!pass.material)
|
||||
pass.material = m_default_material;
|
||||
|
||||
pass.material->set_texture(texture_uniform, b.texture, 0);
|
||||
pass.material->set_texture(0, b.texture, 0);
|
||||
pass.material->set_value(matrix_uniform, &matrix.m11, 16);
|
||||
|
||||
pass.blend = b.blend;
|
||||
|
@ -45,9 +45,6 @@ namespace Blah
|
||||
// The name of the Matrix Uniform in the Shader
|
||||
const char* matrix_uniform;
|
||||
|
||||
// The name of the Texture Uniform in the Shader
|
||||
const char* texture_uniform;
|
||||
|
||||
Batch();
|
||||
Batch(const Batch& other) = delete;
|
||||
Batch& operator=(const Batch& other) = delete;
|
||||
@ -186,6 +183,7 @@ namespace Blah
|
||||
uint8_t mult;
|
||||
uint8_t wash;
|
||||
uint8_t fill;
|
||||
uint8_t pad;
|
||||
};
|
||||
|
||||
struct DrawBatch
|
||||
@ -217,7 +215,7 @@ namespace Blah
|
||||
uint8_t m_tex_wash;
|
||||
DrawBatch m_batch;
|
||||
Vector<Vertex> m_vertices;
|
||||
Vector<int> m_indices;
|
||||
Vector<uint32_t> m_indices;
|
||||
Vector<Mat3x2> m_matrix_stack;
|
||||
Vector<Rect> m_scissor_stack;
|
||||
Vector<BlendMode> m_blend_stack;
|
||||
|
@ -42,7 +42,6 @@ Material::Material(const ShaderRef& shader)
|
||||
m_shader = shader;
|
||||
|
||||
auto& uniforms = shader->uniforms();
|
||||
Vector<int> float_offsets;
|
||||
int float_size = 0;
|
||||
|
||||
for (auto& uniform : uniforms)
|
||||
@ -57,13 +56,10 @@ Material::Material(const ShaderRef& shader)
|
||||
continue;
|
||||
}
|
||||
|
||||
float_offsets.push_back(float_size);
|
||||
float_size += calc_uniform_size(uniform);
|
||||
}
|
||||
|
||||
m_data.expand(float_size);
|
||||
for (auto& it : float_offsets)
|
||||
m_floats.push_back(m_data.begin() + it);
|
||||
}
|
||||
|
||||
const ShaderRef Material::shader() const
|
||||
@ -75,29 +71,50 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
if (m_textures.size() > 0)
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
if (uniform.type != UniformType::Texture)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
{
|
||||
if (uniform.type != UniformType::Texture)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
{
|
||||
m_textures[offset + index] = texture;
|
||||
return;
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_textures.size())
|
||||
break;
|
||||
m_textures[offset + index] = texture;
|
||||
return;
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_textures.size())
|
||||
break;
|
||||
}
|
||||
|
||||
Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index);
|
||||
}
|
||||
|
||||
void Material::set_texture(int slot, const TextureRef& texture, int index)
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int s = 0;
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture)
|
||||
{
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
m_textures[offset + index] = texture;
|
||||
break;
|
||||
}
|
||||
offset += uniform.array_length;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextureRef Material::get_texture(const char* name, int index) const
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
@ -124,14 +141,19 @@ TextureRef Material::get_texture(int slot, int index) const
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int offset = 0;
|
||||
int s = 0;
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture)
|
||||
{
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
return m_textures[offset + index];
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_textures.size())
|
||||
@ -151,6 +173,7 @@ void Material::set_value(const char* name, const float* value, int64_t length)
|
||||
BLAH_ASSERT(length >= 0, "Length must be >= 0");
|
||||
|
||||
int index = 0;
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
||||
@ -165,10 +188,11 @@ void Material::set_value(const char* name, const float* value, int64_t length)
|
||||
length = max;
|
||||
}
|
||||
|
||||
memcpy(m_floats[index], value, sizeof(float) * length);
|
||||
memcpy(m_data.begin() + offset, value, sizeof(float) * length);
|
||||
return;
|
||||
}
|
||||
|
||||
offset += calc_uniform_size(uniform);
|
||||
index++;
|
||||
}
|
||||
|
||||
@ -180,6 +204,7 @@ const float* Material::get_value(const char* name, int64_t* length) const
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int index = 0;
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
||||
@ -189,10 +214,11 @@ const float* Material::get_value(const char* name, int64_t* length) const
|
||||
{
|
||||
if (length != nullptr)
|
||||
*length = calc_uniform_size(uniform);
|
||||
return m_floats[index];
|
||||
return m_data.begin() + offset;
|
||||
}
|
||||
|
||||
index++;
|
||||
offset += calc_uniform_size(uniform);
|
||||
}
|
||||
|
||||
*length = 0;
|
||||
@ -200,29 +226,12 @@ const float* Material::get_value(const char* name, int64_t* length) const
|
||||
Log::warn("No Uniform '%s' exists", name);
|
||||
}
|
||||
|
||||
const float* Material::get_value(int slot, int64_t* length) const
|
||||
const Vector<TextureRef>& Material::textures() const
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
return m_textures;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
int s = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Texture && uniform.type != UniformType::None)
|
||||
{
|
||||
if (index == slot)
|
||||
{
|
||||
if (length != nullptr)
|
||||
*length = calc_uniform_size(uniform);
|
||||
return m_floats[index];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
Log::warn("No Uniform [%i] exists", slot);
|
||||
*length = 0;
|
||||
return nullptr;
|
||||
}
|
||||
const float* Material::data() const
|
||||
{
|
||||
return m_data.begin();
|
||||
}
|
||||
|
@ -31,38 +31,33 @@ namespace Blah
|
||||
// Returns the Shader assigned to the Material.
|
||||
const ShaderRef shader() const;
|
||||
|
||||
// Sets the texture. If the index is out of bounds, the Material is not valid, the Uniform
|
||||
// is not a Texture Uniform, or the Uniform does not exist, this will do nothing.
|
||||
void set_texture(const char* name, const TextureRef& texture, int index = 0);
|
||||
// Sets the texture
|
||||
void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
|
||||
|
||||
// Gets the texture.
|
||||
// If the Uniform does not exist, or the index is out of bounds, this will return
|
||||
// an invalid Texture reference.
|
||||
TextureRef get_texture(const char* name, int index = 0) const;
|
||||
// Sets the texture
|
||||
void set_texture(int slot, const TextureRef& texture, int array_index = 0);
|
||||
|
||||
// Gets the texture from the given slot.
|
||||
// If the slot is not a Texture Uniform, or the index is out of bounds, this will return
|
||||
// an invalid Texture reference.
|
||||
TextureRef get_texture(int slot, int index = 0) const;
|
||||
// Gets the texture, or an empty reference if invalid
|
||||
TextureRef get_texture(const char* name, int array_index = 0) const;
|
||||
|
||||
// Sets the value. Length is the total amount of values to set. For example, if the Uniform type
|
||||
// is a float2, and there are 4 elements, the maximum length should be 8.
|
||||
// Gets the texture, or an empty reference if invalid
|
||||
TextureRef get_texture(int slot, int array_index = 0) const;
|
||||
|
||||
// Sets the value. `length` is the total number of floats to set
|
||||
void set_value(const char* name, const float* value, int64_t length);
|
||||
|
||||
// Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist.
|
||||
// Length is the total amount of values. For example, if the Uniform type
|
||||
// is a float2, and there are 4 elements, the length should be 8.
|
||||
const float* get_value(const char* name, int64_t* length = nullptr) const;
|
||||
|
||||
// Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist.
|
||||
// Length is the total amount of values. For example, if the Uniform type
|
||||
// is a float2, and there are 4 elements, the length should be 8.
|
||||
const float* get_value(int slot, int64_t* length = nullptr) const;
|
||||
// Returns the internal Texture buffer
|
||||
const Vector<TextureRef>& textures() const;
|
||||
|
||||
// Returns the interal float buffer of all the values
|
||||
const float* data() const;
|
||||
|
||||
private:
|
||||
ShaderRef m_shader;
|
||||
Vector<TextureRef> m_textures;
|
||||
Vector<float*> m_floats;
|
||||
Vector<float> m_data;
|
||||
};
|
||||
}
|
@ -3,55 +3,38 @@
|
||||
|
||||
using namespace Blah;
|
||||
|
||||
|
||||
MeshRef Mesh::create()
|
||||
{
|
||||
return GraphicsBackend::create_mesh();
|
||||
}
|
||||
|
||||
void Mesh::vertex_format(const VertexAttribute* attributes, int attribute_count, int stride)
|
||||
VertexFormat::VertexFormat(std::initializer_list<VertexAttribute> attributes, int stride)
|
||||
{
|
||||
if (stride < 0)
|
||||
for (auto& it : attributes)
|
||||
this->attributes.push_back(it);
|
||||
|
||||
if (stride <= 0)
|
||||
{
|
||||
stride = 0;
|
||||
|
||||
for (int n = 0; n < attribute_count; n++)
|
||||
for (auto& it : attributes)
|
||||
{
|
||||
const VertexAttribute* attrib = (attributes + n);
|
||||
|
||||
if (attrib->type == VertexAttributeType::Byte)
|
||||
stride += attrib->components * 1;
|
||||
else if (attrib->type == VertexAttributeType::Short)
|
||||
stride += attrib->components * 2;
|
||||
else if (attrib->type == VertexAttributeType::Int)
|
||||
stride += attrib->components * 4;
|
||||
else if (attrib->type == VertexAttributeType::Float)
|
||||
stride += attrib->components * 4;
|
||||
switch (it.type)
|
||||
{
|
||||
case VertexType::Float: stride += 4; break;
|
||||
case VertexType::Float2: stride += 8; break;
|
||||
case VertexType::Float3: stride += 12; break;
|
||||
case VertexType::Float4: stride += 16; break;
|
||||
case VertexType::Byte4: stride += 4; break;
|
||||
case VertexType::UByte4: stride += 4; break;
|
||||
case VertexType::Short2: stride += 4; break;
|
||||
case VertexType::UShort2: stride += 4; break;
|
||||
case VertexType::Short4: stride += 8; break;
|
||||
case VertexType::UShort4: stride += 8; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vertex_format_internal(attributes, attribute_count, stride);
|
||||
}
|
||||
|
||||
void Mesh::instance_format(const VertexAttribute* attributes, int attribute_count, int stride)
|
||||
{
|
||||
if (stride < 0)
|
||||
{
|
||||
stride = 0;
|
||||
|
||||
for (int n = 0; n < attribute_count; n++)
|
||||
{
|
||||
const VertexAttribute* attrib = (attributes + n);
|
||||
|
||||
if (attrib->type == VertexAttributeType::Byte)
|
||||
stride += attrib->components * 1;
|
||||
else if (attrib->type == VertexAttributeType::Short)
|
||||
stride += attrib->components * 2;
|
||||
else if (attrib->type == VertexAttributeType::Int)
|
||||
stride += attrib->components * 4;
|
||||
else if (attrib->type == VertexAttributeType::Float)
|
||||
stride += attrib->components * 4;
|
||||
}
|
||||
}
|
||||
|
||||
instance_format_internal(attributes, attribute_count, stride);
|
||||
}
|
||||
this->stride = stride;
|
||||
}
|
@ -1,47 +1,53 @@
|
||||
#pragma once
|
||||
#include <inttypes.h>
|
||||
#include <memory>
|
||||
#include <blah/containers/stackvector.h>
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
enum class VertexSemantics
|
||||
enum class VertexType
|
||||
{
|
||||
None,
|
||||
Position,
|
||||
Normal,
|
||||
Bitangent,
|
||||
Color0,
|
||||
Color1,
|
||||
Color2,
|
||||
Color3,
|
||||
Indices,
|
||||
Weight,
|
||||
Texcoord0,
|
||||
Texcoord1,
|
||||
Texcoord2,
|
||||
Texcoord3,
|
||||
Texcoord4,
|
||||
Texcoord5,
|
||||
Texcoord6,
|
||||
Texcoord7
|
||||
};
|
||||
|
||||
enum class VertexAttributeType
|
||||
{
|
||||
None,
|
||||
Byte,
|
||||
Short,
|
||||
Int,
|
||||
Float
|
||||
Float,
|
||||
Float2,
|
||||
Float3,
|
||||
Float4,
|
||||
Byte4,
|
||||
UByte4,
|
||||
Short2,
|
||||
UShort2,
|
||||
Short4,
|
||||
UShort4
|
||||
};
|
||||
|
||||
struct VertexAttribute
|
||||
{
|
||||
int index;
|
||||
VertexSemantics semantics;
|
||||
VertexAttributeType type;
|
||||
int components;
|
||||
bool normalized;
|
||||
// Location / Attribute Index
|
||||
int index = 0;
|
||||
|
||||
// Vertex Type
|
||||
VertexType type = VertexType::None;
|
||||
|
||||
// Whether the Vertex should be normalized (doesn't apply to Floats)
|
||||
bool normalized = false;
|
||||
};
|
||||
|
||||
struct VertexFormat
|
||||
{
|
||||
// List of Attributes
|
||||
StackVector<VertexAttribute, 16> attributes;
|
||||
|
||||
// Total size in bytes of each Vertex element
|
||||
int stride = 0;
|
||||
|
||||
VertexFormat() = default;
|
||||
VertexFormat(std::initializer_list<VertexAttribute> attributes, int stride = 0);
|
||||
};
|
||||
|
||||
enum class IndexFormat
|
||||
{
|
||||
UInt16,
|
||||
UInt32
|
||||
};
|
||||
|
||||
class Mesh;
|
||||
@ -66,22 +72,14 @@ namespace Blah
|
||||
// If the Mesh creation fails, it will return an invalid Mesh.
|
||||
static MeshRef create();
|
||||
|
||||
// Sets the Vertex Format of the Mesh
|
||||
void vertex_format(const VertexAttribute* attributes, int attribute_count, int stride = -1);
|
||||
|
||||
// Sets the Instance Format of the Mesh
|
||||
void instance_format(const VertexAttribute* attributes, int attribute_count, int stride = -1);
|
||||
|
||||
// Uploads the given index buffer to the Mesh
|
||||
virtual void index_data(const void* indices, int64_t count) = 0;
|
||||
virtual void index_data(IndexFormat format, const void* indices, int64_t count) = 0;
|
||||
|
||||
// Uploads the given vertex buffer to the Mesh
|
||||
// Note you must call vertex_format at least once before uploading vertices.
|
||||
virtual void vertex_data(const void* vertices, int64_t count) = 0;
|
||||
virtual void vertex_data(const VertexFormat& format, const void* vertices, int64_t count) = 0;
|
||||
|
||||
// Uploads the given instance buffer to the Mesh
|
||||
// Note you must call instance_format at least once before uploading instances.
|
||||
virtual void instance_data(const void* instances, int64_t count) = 0;
|
||||
virtual void instance_data(const VertexFormat& format, const void* instances, int64_t count) = 0;
|
||||
|
||||
// Gets the index count of the Mesh
|
||||
virtual int64_t index_count() const = 0;
|
||||
@ -91,9 +89,5 @@ namespace Blah
|
||||
|
||||
// Gets the instance count of the Mesh
|
||||
virtual int64_t instance_count() const = 0;
|
||||
|
||||
protected:
|
||||
virtual void vertex_format_internal(const VertexAttribute* attributes, int count, int stride) = 0;
|
||||
virtual void instance_format_internal(const VertexAttribute* attributes, int count, int stride) = 0;
|
||||
};
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
// Supported Uniform Types
|
||||
enum class UniformType
|
||||
{
|
||||
None,
|
||||
@ -17,17 +18,54 @@ namespace Blah
|
||||
Texture
|
||||
};
|
||||
|
||||
// Supported Shader Types
|
||||
enum class ShaderType
|
||||
{
|
||||
None = 0,
|
||||
Vertex = 1 << 0,
|
||||
Fragment = 1 << 1
|
||||
};
|
||||
|
||||
// Uniform Info, provided by the Shader
|
||||
struct UniformInfo
|
||||
{
|
||||
// Name of the Uniform
|
||||
String name;
|
||||
|
||||
// The Value type of the Uniform
|
||||
UniformType type;
|
||||
|
||||
// The Shader type the Uniform is a part of
|
||||
ShaderType shader;
|
||||
|
||||
// Some rendering APIs have uniform buffers. The `buffer_index`
|
||||
// specifies which buffer the uniform belongs to
|
||||
int buffer_index;
|
||||
|
||||
// Array length of the Uniform (ex. a vec2[4] would be 4)
|
||||
int array_length;
|
||||
};
|
||||
|
||||
// Data to be passed to the shader to construct it
|
||||
struct ShaderData
|
||||
{
|
||||
struct HLSL_Attribute
|
||||
{
|
||||
// Semantic Name
|
||||
const char* semantic_name = nullptr;
|
||||
|
||||
// (optional) Semantic Index
|
||||
int semantic_index = 0;
|
||||
};
|
||||
|
||||
// Vertex Shader Program data
|
||||
const char* vertex;
|
||||
|
||||
// Fragment Shader Program data
|
||||
const char* fragment;
|
||||
|
||||
// HLSL Attributes - required for D3D11
|
||||
StackVector<HLSL_Attribute, 16> hlsl_attributes;
|
||||
};
|
||||
|
||||
class Shader;
|
||||
|
@ -9,14 +9,16 @@ using namespace Blah;
|
||||
TextureRef Texture::create(const Image& image)
|
||||
{
|
||||
auto tex = create(image.width, image.height, TextureFormat::RGBA);
|
||||
tex->set_data((unsigned char*)image.pixels);
|
||||
if (tex)
|
||||
tex->set_data((unsigned char*)image.pixels);
|
||||
return tex;
|
||||
}
|
||||
|
||||
TextureRef Texture::create(int width, int height, unsigned char* rgba)
|
||||
{
|
||||
auto tex = create(width, height, TextureFormat::RGBA);
|
||||
tex->set_data(rgba);
|
||||
if (tex)
|
||||
tex->set_data(rgba);
|
||||
return tex;
|
||||
}
|
||||
|
||||
@ -35,10 +37,11 @@ TextureRef Texture::create(Stream& stream)
|
||||
{
|
||||
Image img = Image(stream);
|
||||
|
||||
if (img.pixels != nullptr && img.width > 0 && img.height > 0)
|
||||
if (img.pixels && img.width > 0 && img.height > 0)
|
||||
{
|
||||
auto tex = create(img.width, img.height, TextureFormat::RGBA);
|
||||
tex->set_data((unsigned char*)img.pixels);
|
||||
if (tex)
|
||||
tex->set_data((unsigned char*)img.pixels);
|
||||
return tex;
|
||||
}
|
||||
|
||||
@ -49,10 +52,11 @@ TextureRef Texture::create(const char* file)
|
||||
{
|
||||
Image img = Image(file);
|
||||
|
||||
if (img.pixels != nullptr)
|
||||
if (img.pixels)
|
||||
{
|
||||
auto tex = create(img.width, img.height, TextureFormat::RGBA);
|
||||
tex->set_data((unsigned char*)img.pixels);
|
||||
if (tex)
|
||||
tex->set_data((unsigned char*)img.pixels);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ namespace Blah
|
||||
None,
|
||||
R,
|
||||
RG,
|
||||
RGB,
|
||||
RGBA,
|
||||
DepthStencil,
|
||||
Count
|
||||
|
Reference in New Issue
Block a user