mirror of
https://github.com/NoelFB/blah.git
synced 2024-11-29 17:08:56 +08:00
very WIP D3D11 support
This commit is contained in:
parent
52e362e1b2
commit
41ae0ac6d5
|
@ -103,6 +103,7 @@ add_library(blah
|
||||||
private/blah/third_party/stb_truetype.h
|
private/blah/third_party/stb_truetype.h
|
||||||
private/blah/internal/graphics_backend.h
|
private/blah/internal/graphics_backend.h
|
||||||
private/blah/internal/graphics_backend_gl.cpp
|
private/blah/internal/graphics_backend_gl.cpp
|
||||||
|
private/blah/internal/graphics_backend_d3d11.cpp
|
||||||
private/blah/internal/input_backend.h
|
private/blah/internal/input_backend.h
|
||||||
private/blah/internal/platform_backend.h
|
private/blah/internal/platform_backend.h
|
||||||
private/blah/internal/platform_backend_sdl2.cpp
|
private/blah/internal/platform_backend_sdl2.cpp
|
||||||
|
@ -119,16 +120,27 @@ target_include_directories(blah
|
||||||
set(SDL2_ENABLED true CACHE BOOL "Use SDL2 as the System implementation")
|
set(SDL2_ENABLED true CACHE BOOL "Use SDL2 as the System implementation")
|
||||||
set(SDL2_INCLUDE_DIRS "" CACHE FILEPATH "SDL2 Headers")
|
set(SDL2_INCLUDE_DIRS "" CACHE FILEPATH "SDL2 Headers")
|
||||||
set(SDL2_LIBRARIES "" CACHE FILEPATH "SDL2 Headers")
|
set(SDL2_LIBRARIES "" CACHE FILEPATH "SDL2 Headers")
|
||||||
set(OPENGL_ENABLED true CACHE BOOL "Include OpenGL graphics implementation")
|
set(OPENGL_ENABLED true CACHE BOOL "Use OpenGL graphics implementation")
|
||||||
|
set(D3D11_ENABLED false CACHE BOOL "Use D3D11 graphics implementation")
|
||||||
|
|
||||||
|
set(LIBS "")
|
||||||
|
|
||||||
# add OpenGL definition if we're using OpenGL
|
# add OpenGL definition if we're using OpenGL
|
||||||
if (OPENGL_ENABLED)
|
if (OPENGL_ENABLED)
|
||||||
add_compile_definitions(BLAH_USE_OPENGL)
|
add_compile_definitions(BLAH_USE_OPENGL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# add D3D11 definition if we're using OpenGL
|
||||||
|
if (D3D11_ENABLED)
|
||||||
|
add_compile_definitions(BLAH_USE_D3D11)
|
||||||
|
set(LIBS ${LIBS} d3d11.lib dxguid.lib D3Dcompiler.lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Link and create SDL2 Definition if we're using SDL2
|
# Link and create SDL2 Definition if we're using SDL2
|
||||||
if (SDL2_ENABLED)
|
if (SDL2_ENABLED)
|
||||||
add_compile_definitions(BLAH_USE_SDL2)
|
add_compile_definitions(BLAH_USE_SDL2)
|
||||||
target_include_directories(blah PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
target_include_directories(blah PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
||||||
target_link_libraries(blah PUBLIC ${SDL2_LIBRARIES})
|
set(LIBS ${LIBS} ${SDL2_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(blah PUBLIC ${LIBS})
|
1255
private/blah/internal/graphics_backend_d3d11.cpp
Normal file
1255
private/blah/internal/graphics_backend_d3d11.cpp
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -406,7 +406,7 @@ namespace Blah
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign attributes
|
// assign attributes
|
||||||
GLuint gl_mesh_assign_attributes(GLuint buffer, GLenum buffer_type, const VertexAttribute* vertex_attributes, int vertex_attribute_count, int stride, GLint divisor)
|
GLuint gl_mesh_assign_attributes(GLuint buffer, GLenum buffer_type, const VertexFormat& format, GLint divisor)
|
||||||
{
|
{
|
||||||
// bind
|
// bind
|
||||||
gl.BindBuffer(buffer_type, buffer);
|
gl.BindBuffer(buffer_type, buffer);
|
||||||
|
@ -417,49 +417,83 @@ namespace Blah
|
||||||
|
|
||||||
// enable attributes
|
// enable attributes
|
||||||
size_t ptr = 0;
|
size_t ptr = 0;
|
||||||
for (int n = 0; n < vertex_attribute_count; n++)
|
for (int n = 0; n < format.attributes.size(); n++)
|
||||||
{
|
{
|
||||||
const VertexAttribute* attrib = (vertex_attributes + n);
|
auto& attribute = format.attributes[n];
|
||||||
|
|
||||||
for (int i = 0, loc = 0; i < (int)attrib->components; i += 4, loc++)
|
|
||||||
{
|
|
||||||
int components = attrib->components - i;
|
|
||||||
if (components > 4)
|
|
||||||
components = 4;
|
|
||||||
|
|
||||||
GLenum type = GL_UNSIGNED_BYTE;
|
GLenum type = GL_UNSIGNED_BYTE;
|
||||||
size_t component_size = 0;
|
size_t component_size = 0;
|
||||||
if (attrib->type == VertexAttributeType::Byte)
|
int components = 1;
|
||||||
{
|
|
||||||
type = GL_UNSIGNED_BYTE;
|
if (attribute.type == VertexType::Float)
|
||||||
component_size = 1;
|
|
||||||
}
|
|
||||||
else if (attrib->type == VertexAttributeType::Short)
|
|
||||||
{
|
|
||||||
type = GL_SHORT;
|
|
||||||
component_size = 2;
|
|
||||||
}
|
|
||||||
else if (attrib->type == VertexAttributeType::Int)
|
|
||||||
{
|
|
||||||
type = GL_INT;
|
|
||||||
component_size = 4;
|
|
||||||
}
|
|
||||||
else if (attrib->type == VertexAttributeType::Float)
|
|
||||||
{
|
{
|
||||||
type = GL_FLOAT;
|
type = GL_FLOAT;
|
||||||
component_size = 4;
|
component_size = 4;
|
||||||
|
components = 1;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Float2)
|
||||||
|
{
|
||||||
|
type = GL_FLOAT;
|
||||||
|
component_size = 4;
|
||||||
|
components = 2;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Float3)
|
||||||
|
{
|
||||||
|
type = GL_FLOAT;
|
||||||
|
component_size = 4;
|
||||||
|
components = 3;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Float4)
|
||||||
|
{
|
||||||
|
type = GL_FLOAT;
|
||||||
|
component_size = 4;
|
||||||
|
components = 4;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Byte4)
|
||||||
|
{
|
||||||
|
type = GL_BYTE;
|
||||||
|
component_size = 1;
|
||||||
|
components = 4;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::UByte4)
|
||||||
|
{
|
||||||
|
type = GL_UNSIGNED_BYTE;
|
||||||
|
component_size = 1;
|
||||||
|
components = 4;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Short2)
|
||||||
|
{
|
||||||
|
type = GL_SHORT;
|
||||||
|
component_size = 2;
|
||||||
|
components = 2;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::UShort2)
|
||||||
|
{
|
||||||
|
type = GL_UNSIGNED_SHORT;
|
||||||
|
component_size = 2;
|
||||||
|
components = 2;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::Short4)
|
||||||
|
{
|
||||||
|
type = GL_SHORT;
|
||||||
|
component_size = 2;
|
||||||
|
components = 4;
|
||||||
|
}
|
||||||
|
else if (attribute.type == VertexType::UShort4)
|
||||||
|
{
|
||||||
|
type = GL_UNSIGNED_SHORT;
|
||||||
|
component_size = 2;
|
||||||
|
components = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t location = (uint32_t)(attrib->index + loc);
|
uint32_t location = (uint32_t)(attribute.index);
|
||||||
gl.EnableVertexAttribArray(location);
|
gl.EnableVertexAttribArray(location);
|
||||||
gl.VertexAttribPointer(location, components, type, attrib->normalized, stride, (void*)ptr);
|
gl.VertexAttribPointer(location, components, type, attribute.normalized, format.stride, (void*)ptr);
|
||||||
gl.VertexAttribDivisor(location, divisor);
|
gl.VertexAttribDivisor(location, divisor);
|
||||||
|
|
||||||
ptr += components * component_size;
|
ptr += components * component_size;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return stride;
|
return format.stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert blend op enum
|
// convert blend op enum
|
||||||
|
@ -554,12 +588,6 @@ namespace Blah
|
||||||
m_gl_format = GL_RG;
|
m_gl_format = GL_RG;
|
||||||
m_gl_type = GL_UNSIGNED_BYTE;
|
m_gl_type = GL_UNSIGNED_BYTE;
|
||||||
}
|
}
|
||||||
else if (format == TextureFormat::RGB)
|
|
||||||
{
|
|
||||||
m_gl_internal_format = GL_RGB;
|
|
||||||
m_gl_format = GL_RGB;
|
|
||||||
m_gl_type = GL_UNSIGNED_BYTE;
|
|
||||||
}
|
|
||||||
else if (format == TextureFormat::RGBA)
|
else if (format == TextureFormat::RGBA)
|
||||||
{
|
{
|
||||||
m_gl_internal_format = GL_RGBA;
|
m_gl_internal_format = GL_RGBA;
|
||||||
|
@ -779,7 +807,6 @@ namespace Blah
|
||||||
{
|
{
|
||||||
m_id = 0;
|
m_id = 0;
|
||||||
|
|
||||||
// vertex shader
|
|
||||||
if (data->vertex == nullptr)
|
if (data->vertex == nullptr)
|
||||||
{
|
{
|
||||||
Log::error("Vertex Shader is required");
|
Log::error("Vertex Shader is required");
|
||||||
|
@ -819,33 +846,32 @@ namespace Blah
|
||||||
|
|
||||||
if (log_length > 0)
|
if (log_length > 0)
|
||||||
{
|
{
|
||||||
|
gl.DeleteShader(vertex_shader);
|
||||||
gl.DeleteShader(fragment_shader);
|
gl.DeleteShader(fragment_shader);
|
||||||
Log::error(log);
|
Log::error(log);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create actual shader program
|
||||||
GLuint id = gl.CreateProgram();
|
GLuint id = gl.CreateProgram();
|
||||||
gl.AttachShader(id, vertex_shader);
|
gl.AttachShader(id, vertex_shader);
|
||||||
gl.AttachShader(id, fragment_shader);
|
gl.AttachShader(id, fragment_shader);
|
||||||
gl.LinkProgram(id);
|
gl.LinkProgram(id);
|
||||||
gl.GetProgramInfoLog(id, 1024, &log_length, log);
|
gl.GetProgramInfoLog(id, 1024, &log_length, log);
|
||||||
|
|
||||||
if (log_length > 0)
|
|
||||||
{
|
|
||||||
gl.DetachShader(id, vertex_shader);
|
gl.DetachShader(id, vertex_shader);
|
||||||
gl.DetachShader(id, fragment_shader);
|
gl.DetachShader(id, fragment_shader);
|
||||||
gl.DeleteShader(vertex_shader);
|
gl.DeleteShader(vertex_shader);
|
||||||
gl.DeleteShader(fragment_shader);
|
gl.DeleteShader(fragment_shader);
|
||||||
|
|
||||||
|
if (log_length > 0)
|
||||||
|
{
|
||||||
Log::error(log);
|
Log::error(log);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ready to go
|
|
||||||
m_id = id;
|
|
||||||
|
|
||||||
// get uniforms
|
// get uniforms
|
||||||
|
bool valid_uniforms = true;
|
||||||
{
|
{
|
||||||
const int max_name_length = 256;
|
const int max_name_length = 256;
|
||||||
|
|
||||||
|
@ -876,9 +902,19 @@ namespace Blah
|
||||||
UniformInfo uniform;
|
UniformInfo uniform;
|
||||||
uniform.name = name;
|
uniform.name = name;
|
||||||
uniform.type = UniformType::None;
|
uniform.type = UniformType::None;
|
||||||
|
uniform.buffer_index = 0;
|
||||||
uniform.array_length = size;
|
uniform.array_length = size;
|
||||||
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
||||||
|
|
||||||
|
if (type == GL_SAMPLER_2D)
|
||||||
|
{
|
||||||
|
uniform.type = UniformType::Texture;
|
||||||
|
uniform.shader = ShaderType::Fragment;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uniform.shader = (ShaderType)((int)ShaderType::Vertex | (int)ShaderType::Fragment);
|
||||||
|
|
||||||
if (type == GL_FLOAT)
|
if (type == GL_FLOAT)
|
||||||
uniform.type = UniformType::Float;
|
uniform.type = UniformType::Float;
|
||||||
else if (type == GL_FLOAT_VEC2)
|
else if (type == GL_FLOAT_VEC2)
|
||||||
|
@ -891,17 +927,23 @@ namespace Blah
|
||||||
uniform.type = UniformType::Mat3x2;
|
uniform.type = UniformType::Mat3x2;
|
||||||
else if (type == GL_FLOAT_MAT4)
|
else if (type == GL_FLOAT_MAT4)
|
||||||
uniform.type = UniformType::Mat4x4;
|
uniform.type = UniformType::Mat4x4;
|
||||||
else if (type == GL_SAMPLER_2D)
|
|
||||||
uniform.type = UniformType::Texture;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log::error("Unsupported Uniform Type. Must be either FLOAT, MAT3x2, MAT4, or SAMPLER_2D");
|
valid_uniforms = false;
|
||||||
|
Log::error("Unsupported Uniform Type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_uniforms.push_back(uniform);
|
m_uniforms.push_back(uniform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assign ID if the uniforms were valid
|
||||||
|
if (!valid_uniforms)
|
||||||
|
gl.DeleteProgram(id);
|
||||||
|
else
|
||||||
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
~OpenGL_Shader()
|
~OpenGL_Shader()
|
||||||
|
@ -943,6 +985,8 @@ namespace Blah
|
||||||
uint8_t m_instance_attribs_enabled;
|
uint8_t m_instance_attribs_enabled;
|
||||||
Vector<GLuint> m_vertex_attribs;
|
Vector<GLuint> m_vertex_attribs;
|
||||||
Vector<GLuint> m_instance_attribs;
|
Vector<GLuint> m_instance_attribs;
|
||||||
|
GLenum m_index_format;
|
||||||
|
int m_index_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -981,31 +1025,17 @@ namespace Blah
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void vertex_format_internal(const VertexAttribute* attributes, int attribute_count, int stride = -1) override
|
GLenum gl_index_format() const
|
||||||
{
|
{
|
||||||
gl.BindVertexArray(m_id);
|
return m_index_format;
|
||||||
{
|
|
||||||
if (m_vertex_buffer == 0)
|
|
||||||
gl.GenBuffers(1, &(m_vertex_buffer));
|
|
||||||
|
|
||||||
m_vertex_size = gl_mesh_assign_attributes(m_vertex_buffer, GL_ARRAY_BUFFER, attributes, attribute_count, stride, 0);
|
|
||||||
}
|
|
||||||
gl.BindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void instance_format_internal(const VertexAttribute* attributes, int attribute_count, int stride = -1) override
|
int gl_index_size() const
|
||||||
{
|
{
|
||||||
gl.BindVertexArray(m_id);
|
return m_index_size;
|
||||||
{
|
|
||||||
if (m_instance_buffer == 0)
|
|
||||||
gl.GenBuffers(1, &(m_instance_buffer));
|
|
||||||
|
|
||||||
m_instance_size = gl_mesh_assign_attributes(m_instance_buffer, GL_ARRAY_BUFFER, attributes, attribute_count, stride, 1);
|
|
||||||
}
|
|
||||||
gl.BindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void index_data(const void* indices, int64_t count) override
|
virtual void index_data(IndexFormat format, const void* indices, int64_t count) override
|
||||||
{
|
{
|
||||||
m_index_count = count;
|
m_index_count = count;
|
||||||
|
|
||||||
|
@ -1014,49 +1044,65 @@ namespace Blah
|
||||||
if (m_index_buffer == 0)
|
if (m_index_buffer == 0)
|
||||||
gl.GenBuffers(1, &(m_index_buffer));
|
gl.GenBuffers(1, &(m_index_buffer));
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case IndexFormat::UInt16:
|
||||||
|
m_index_format = GL_UNSIGNED_SHORT;
|
||||||
|
m_index_size = 2;
|
||||||
|
break;
|
||||||
|
case IndexFormat::UInt32:
|
||||||
|
m_index_format = GL_UNSIGNED_INT;
|
||||||
|
m_index_size = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
|
gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
|
||||||
gl.BufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * count, indices, GL_DYNAMIC_DRAW);
|
gl.BufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_size * count, indices, GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
gl.BindVertexArray(0);
|
gl.BindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void vertex_data(const void* vertices, int64_t count) override
|
virtual void vertex_data(const VertexFormat& format, const void* vertices, int64_t count) override
|
||||||
{
|
|
||||||
if (m_vertex_buffer == 0 || m_vertex_size <= 0)
|
|
||||||
{
|
|
||||||
Log::error("You must assign a Vertex Format before setting Vertex Data");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
m_vertex_count = count;
|
m_vertex_count = count;
|
||||||
|
|
||||||
gl.BindVertexArray(m_id);
|
gl.BindVertexArray(m_id);
|
||||||
{
|
{
|
||||||
|
// Create Buffer if it doesn't exist yet
|
||||||
|
if (m_vertex_buffer == 0)
|
||||||
|
gl.GenBuffers(1, &(m_vertex_buffer));
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Cache this
|
||||||
|
m_vertex_size = gl_mesh_assign_attributes(m_vertex_buffer, GL_ARRAY_BUFFER, format, 0);
|
||||||
|
|
||||||
|
// Upload Buffer
|
||||||
gl.BindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
|
gl.BindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
|
||||||
gl.BufferData(GL_ARRAY_BUFFER, m_vertex_size * count, vertices, GL_DYNAMIC_DRAW);
|
gl.BufferData(GL_ARRAY_BUFFER, m_vertex_size * count, vertices, GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
gl.BindVertexArray(0);
|
gl.BindVertexArray(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual void instance_data(const void* instances, int64_t count) override
|
virtual void instance_data(const VertexFormat& format, const void* instances, int64_t count) override
|
||||||
{
|
|
||||||
if (m_instance_buffer == 0 || m_instance_size <= 0)
|
|
||||||
{
|
|
||||||
Log::error("You must assign an Instance Format before setting Instance Data");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
m_instance_count = count;
|
m_instance_count = count;
|
||||||
|
|
||||||
gl.BindVertexArray(m_id);
|
gl.BindVertexArray(m_id);
|
||||||
{
|
{
|
||||||
|
// Create Buffer if it doesn't exist yet
|
||||||
|
if (m_instance_buffer == 0)
|
||||||
|
gl.GenBuffers(1, &(m_instance_buffer));
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Cache this
|
||||||
|
m_instance_size = gl_mesh_assign_attributes(m_instance_buffer, GL_ARRAY_BUFFER, format, 1);
|
||||||
|
|
||||||
|
// Upload Buffer
|
||||||
gl.BindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
|
gl.BindBuffer(GL_ARRAY_BUFFER, m_instance_buffer);
|
||||||
gl.BufferData(GL_ARRAY_BUFFER, m_instance_size * count, instances, GL_DYNAMIC_DRAW);
|
gl.BufferData(GL_ARRAY_BUFFER, m_instance_size * count, instances, GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
gl.BindVertexArray(0);
|
gl.BindVertexArray(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual int64_t index_count() const override
|
virtual int64_t index_count() const override
|
||||||
{
|
{
|
||||||
|
@ -1222,6 +1268,7 @@ namespace Blah
|
||||||
|
|
||||||
// Use the Shader
|
// Use the Shader
|
||||||
// TODO: I don't love how material values are assigned or set here
|
// TODO: I don't love how material values are assigned or set here
|
||||||
|
// TODO: this should be cached?
|
||||||
{
|
{
|
||||||
gl.UseProgram(shader->gl_id());
|
gl.UseProgram(shader->gl_id());
|
||||||
|
|
||||||
|
@ -1230,6 +1277,8 @@ namespace Blah
|
||||||
GLint texture_ids[64];
|
GLint texture_ids[64];
|
||||||
|
|
||||||
auto& uniforms = shader->uniforms();
|
auto& uniforms = shader->uniforms();
|
||||||
|
auto data = pass.material->data();
|
||||||
|
|
||||||
for (int i = 0; i < uniforms.size(); i++)
|
for (int i = 0; i < uniforms.size(); i++)
|
||||||
{
|
{
|
||||||
auto location = shader->uniform_locations[i];
|
auto location = shader->uniform_locations[i];
|
||||||
|
@ -1258,36 +1307,44 @@ namespace Blah
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
|
gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float
|
// Float
|
||||||
else if (uniform.type == UniformType::Float)
|
if (uniform.type == UniformType::Float)
|
||||||
{
|
{
|
||||||
gl.Uniform1fv(location, (GLint)uniform.array_length, (const GLfloat*)pass.material->get_value(i));
|
gl.Uniform1fv(location, (GLint)uniform.array_length, data);
|
||||||
|
data += uniform.array_length;
|
||||||
}
|
}
|
||||||
// Float2
|
// Float2
|
||||||
else if (uniform.type == UniformType::Float2)
|
else if (uniform.type == UniformType::Float2)
|
||||||
{
|
{
|
||||||
gl.Uniform2fv(location, (GLint)uniform.array_length, (const GLfloat*)pass.material->get_value(i));
|
gl.Uniform2fv(location, (GLint)uniform.array_length, data);
|
||||||
|
data += 2 * uniform.array_length;
|
||||||
}
|
}
|
||||||
// Float3
|
// Float3
|
||||||
else if (uniform.type == UniformType::Float3)
|
else if (uniform.type == UniformType::Float3)
|
||||||
{
|
{
|
||||||
gl.Uniform3fv(location, (GLint)uniform.array_length, (const GLfloat*)pass.material->get_value(i));
|
gl.Uniform3fv(location, (GLint)uniform.array_length, data);
|
||||||
|
data += 3 * uniform.array_length;
|
||||||
}
|
}
|
||||||
// Float4
|
// Float4
|
||||||
else if (uniform.type == UniformType::Float4)
|
else if (uniform.type == UniformType::Float4)
|
||||||
{
|
{
|
||||||
gl.Uniform4fv(location, (GLint)uniform.array_length, (const GLfloat*)pass.material->get_value(i));
|
gl.Uniform4fv(location, (GLint)uniform.array_length, data);
|
||||||
|
data += 4 * uniform.array_length;
|
||||||
}
|
}
|
||||||
// Matrix3x2
|
// Matrix3x2
|
||||||
else if (uniform.type == UniformType::Mat3x2)
|
else if (uniform.type == UniformType::Mat3x2)
|
||||||
{
|
{
|
||||||
gl.UniformMatrix3x2fv(location, (GLint)uniform.array_length, 0, (const GLfloat*)pass.material->get_value(i));
|
gl.UniformMatrix3x2fv(location, (GLint)uniform.array_length, 0, data);
|
||||||
|
data += 6 * uniform.array_length;
|
||||||
}
|
}
|
||||||
// Matrix4x4
|
// Matrix4x4
|
||||||
else if (uniform.type == UniformType::Mat4x4)
|
else if (uniform.type == UniformType::Mat4x4)
|
||||||
{
|
{
|
||||||
gl.UniformMatrix4fv(location, (GLint)uniform.array_length, 0, (const GLfloat*)pass.material->get_value(i));
|
gl.UniformMatrix4fv(location, (GLint)uniform.array_length, 0, data);
|
||||||
|
data += 16 * uniform.array_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1416,13 +1473,16 @@ namespace Blah
|
||||||
{
|
{
|
||||||
gl.BindVertexArray(mesh->gl_id());
|
gl.BindVertexArray(mesh->gl_id());
|
||||||
|
|
||||||
|
GLenum index_format = mesh->gl_index_format();
|
||||||
|
int index_size = mesh->gl_index_size();
|
||||||
|
|
||||||
if (pass.instance_count > 0)
|
if (pass.instance_count > 0)
|
||||||
{
|
{
|
||||||
gl.DrawElementsInstanced(
|
gl.DrawElementsInstanced(
|
||||||
GL_TRIANGLES,
|
GL_TRIANGLES,
|
||||||
(GLint)(pass.index_count),
|
(GLint)(pass.index_count),
|
||||||
GL_UNSIGNED_INT,
|
index_format,
|
||||||
(void*)(sizeof(int) * pass.index_start),
|
(void*)(index_size* pass.index_start),
|
||||||
(GLint)pass.instance_count);
|
(GLint)pass.instance_count);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1430,8 +1490,8 @@ namespace Blah
|
||||||
gl.DrawElements(
|
gl.DrawElements(
|
||||||
GL_TRIANGLES,
|
GL_TRIANGLES,
|
||||||
(GLint)(pass.index_count),
|
(GLint)(pass.index_count),
|
||||||
GL_UNSIGNED_INT,
|
index_format,
|
||||||
(void*)(sizeof(int) * pass.index_start));
|
(void*)(index_size * pass.index_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.BindVertexArray(0);
|
gl.BindVertexArray(0);
|
||||||
|
|
|
@ -113,5 +113,8 @@ namespace Blah
|
||||||
void* gl_context_create();
|
void* gl_context_create();
|
||||||
void gl_context_make_current(void* context);
|
void gl_context_make_current(void* context);
|
||||||
void gl_context_destroy(void* context);
|
void gl_context_destroy(void* context);
|
||||||
|
|
||||||
|
// D3D11 Methods
|
||||||
|
void* d3d11_get_hwnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_vulkan.h>
|
#include <SDL_vulkan.h>
|
||||||
|
#include <SDL_syswm.h>
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
// on Windows we're using the C++ <filesystem> API for now
|
// on Windows we're using the C++ <filesystem> API for now
|
||||||
|
@ -75,7 +76,7 @@ bool PlatformBackend::init(const Config* config)
|
||||||
|
|
||||||
int flags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
int flags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||||
|
|
||||||
// GL Attributes
|
// enable OpenGL
|
||||||
if (App::renderer() == Renderer::OpenGL)
|
if (App::renderer() == Renderer::OpenGL)
|
||||||
{
|
{
|
||||||
flags |= SDL_WINDOW_OPENGL;
|
flags |= SDL_WINDOW_OPENGL;
|
||||||
|
@ -93,6 +94,11 @@ bool PlatformBackend::init(const Config* config)
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||||
}
|
}
|
||||||
|
// enable DirectX
|
||||||
|
else if (App::renderer() == Renderer::D3D11)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// create the window
|
// create the window
|
||||||
window = SDL_CreateWindow(config->name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, config->width, config->height, flags);
|
window = SDL_CreateWindow(config->name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, config->width, config->height, flags);
|
||||||
|
@ -643,4 +649,12 @@ void PlatformBackend::gl_context_destroy(void* context)
|
||||||
SDL_GL_DeleteContext(context);
|
SDL_GL_DeleteContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* PlatformBackend::d3d11_get_hwnd()
|
||||||
|
{
|
||||||
|
SDL_SysWMinfo info;
|
||||||
|
SDL_VERSION(&info.version);
|
||||||
|
SDL_GetWindowWMInfo(window, &info);
|
||||||
|
return info.info.win.window;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BLAH_USE_SDL2
|
#endif // BLAH_USE_SDL2
|
||||||
|
|
|
@ -15,8 +15,10 @@ namespace Blah
|
||||||
int m_count;
|
int m_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static inline constexpr size_t MaxCapacity = Capacity;
|
||||||
|
|
||||||
StackVector();
|
StackVector();
|
||||||
|
StackVector(const std::initializer_list<T>& init);
|
||||||
StackVector(const StackVector& src);
|
StackVector(const StackVector& src);
|
||||||
StackVector(StackVector&& src) noexcept;
|
StackVector(StackVector&& src) noexcept;
|
||||||
~StackVector();
|
~StackVector();
|
||||||
|
@ -59,6 +61,14 @@ namespace Blah
|
||||||
m_count = 0;
|
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>
|
template<class T, size_t Capacity>
|
||||||
inline StackVector<T, Capacity>::StackVector(const StackVector& src)
|
inline StackVector<T, Capacity>::StackVector(const StackVector& src)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,21 +8,25 @@
|
||||||
#include <blah/app.h>
|
#include <blah/app.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// This shader needs to be graphics API agnostic
|
// This shader needs to be graphics API agnostic
|
||||||
|
|
||||||
const ShaderData data = {
|
#ifdef BLAH_USE_OPENGL
|
||||||
|
|
||||||
|
const ShaderData shader_data = {
|
||||||
// vertex shader
|
// vertex shader
|
||||||
"#version 330\n"
|
"#version 330\n"
|
||||||
"uniform mat4 u_matrix;\n"
|
"uniform mat4 u_matrix;\n"
|
||||||
"layout(location=0) in vec2 a_position;\n"
|
"layout(location=0) in vec2 a_position;\n"
|
||||||
"layout(location=1) in vec2 a_tex;\n"
|
"layout(location=1) in vec2 a_tex;\n"
|
||||||
"layout(location=2) in vec4 a_color;\n"
|
"layout(location=2) in vec4 a_color;\n"
|
||||||
"layout(location=3) in vec3 a_type;\n"
|
"layout(location=3) in vec4 a_type;\n"
|
||||||
"out vec2 v_tex;\n"
|
"out vec2 v_tex;\n"
|
||||||
"out vec4 v_col;\n"
|
"out vec4 v_col;\n"
|
||||||
"out vec3 v_type;\n"
|
"out vec4 v_type;\n"
|
||||||
"void main(void)\n"
|
"void main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = u_matrix * vec4(a_position.xy, 0, 1);\n"
|
" gl_Position = u_matrix * vec4(a_position.xy, 0, 1);\n"
|
||||||
|
@ -36,7 +40,7 @@ const ShaderData data = {
|
||||||
"uniform sampler2D u_texture;\n"
|
"uniform sampler2D u_texture;\n"
|
||||||
"in vec2 v_tex;\n"
|
"in vec2 v_tex;\n"
|
||||||
"in vec4 v_col;\n"
|
"in vec4 v_col;\n"
|
||||||
"in vec3 v_type;\n"
|
"in vec4 v_type;\n"
|
||||||
"out vec4 o_color;\n"
|
"out vec4 o_color;\n"
|
||||||
"void main(void)\n"
|
"void main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -48,13 +52,78 @@ const ShaderData data = {
|
||||||
"}"
|
"}"
|
||||||
};
|
};
|
||||||
|
|
||||||
const VertexAttribute attributes[4] = {
|
#elif BLAH_USE_D3D11
|
||||||
{ 0, VertexSemantics::Position, VertexAttributeType::Float, 2, false },
|
|
||||||
{ 1, VertexSemantics::Texcoord0, VertexAttributeType::Float, 2, false },
|
const char* d3d11_shader = ""
|
||||||
{ 2, VertexSemantics::Color0, VertexAttributeType::Byte, 4, true },
|
"cbuffer constants : register(b0)\n"
|
||||||
{ 3, VertexSemantics::Texcoord1, VertexAttributeType::Byte, 3, true },
|
"{\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
|
namespace
|
||||||
{
|
{
|
||||||
static Vec2 batch_shape_intersection(const Vec2& p0, const Vec2& p1, const Vec2& q0, const Vec2& q1)
|
static Vec2 batch_shape_intersection(const Vec2& p0, const Vec2& p1, const Vec2& q0, const Vec2& q1)
|
||||||
|
@ -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) \
|
#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; \
|
m_batch.elements += 2; \
|
||||||
int* _i = m_indices.expand(6); \
|
auto _i = m_indices.expand(6); \
|
||||||
*_i++ = (int)m_vertices.size() + 0; \
|
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||||
*_i++ = (int)m_vertices.size() + 1; \
|
*_i++ = (uint32_t)m_vertices.size() + 1; \
|
||||||
*_i++ = (int)m_vertices.size() + 2; \
|
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||||
*_i++ = (int)m_vertices.size() + 0; \
|
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||||
*_i++ = (int)m_vertices.size() + 2; \
|
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||||
*_i++ = (int)m_vertices.size() + 3; \
|
*_i++ = (uint32_t)m_vertices.size() + 3; \
|
||||||
Vertex* _v = m_vertices.expand(4); \
|
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, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, 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) \
|
#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; \
|
m_batch.elements += 1; \
|
||||||
int* _i = m_indices.expand(3); \
|
auto* _i = m_indices.expand(3); \
|
||||||
*_i++ = (int)m_vertices.size() + 0; \
|
*_i++ = (uint32_t)m_vertices.size() + 0; \
|
||||||
*_i++ = (int)m_vertices.size() + 1; \
|
*_i++ = (uint32_t)m_vertices.size() + 1; \
|
||||||
*_i++ = (int)m_vertices.size() + 2; \
|
*_i++ = (uint32_t)m_vertices.size() + 2; \
|
||||||
Vertex* _v = m_vertices.expand(3); \
|
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, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, 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()
|
Batch::Batch()
|
||||||
{
|
{
|
||||||
matrix_uniform = "u_matrix";
|
matrix_uniform = "u_matrix";
|
||||||
texture_uniform = "u_texture";
|
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,21 +359,18 @@ void Batch::render(const FrameBufferRef& target, const Mat4x4& matrix)
|
||||||
// define defaults
|
// define defaults
|
||||||
{
|
{
|
||||||
if (!m_mesh)
|
if (!m_mesh)
|
||||||
{
|
|
||||||
m_mesh = Mesh::create();
|
m_mesh = Mesh::create();
|
||||||
m_mesh->vertex_format(attributes, 4, sizeof(Vertex));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_default_shader)
|
if (!m_default_shader)
|
||||||
m_default_shader = Shader::create(&data);
|
m_default_shader = Shader::create(&shader_data);
|
||||||
|
|
||||||
if (!m_default_material)
|
if (!m_default_material)
|
||||||
m_default_material = Material::create(m_default_shader);
|
m_default_material = Material::create(m_default_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload data
|
// upload data
|
||||||
m_mesh->index_data(m_indices.data(), m_indices.size());
|
m_mesh->index_data(IndexFormat::UInt32, m_indices.data(), m_indices.size());
|
||||||
m_mesh->vertex_data(m_vertices.data(), m_vertices.size());
|
m_mesh->vertex_data(format, m_vertices.data(), m_vertices.size());
|
||||||
|
|
||||||
RenderPass pass;
|
RenderPass pass;
|
||||||
pass.target = target;
|
pass.target = target;
|
||||||
|
@ -330,7 +394,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
|
||||||
if (!pass.material)
|
if (!pass.material)
|
||||||
pass.material = m_default_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.material->set_value(matrix_uniform, &matrix.m11, 16);
|
||||||
|
|
||||||
pass.blend = b.blend;
|
pass.blend = b.blend;
|
||||||
|
|
|
@ -45,9 +45,6 @@ namespace Blah
|
||||||
// The name of the Matrix Uniform in the Shader
|
// The name of the Matrix Uniform in the Shader
|
||||||
const char* matrix_uniform;
|
const char* matrix_uniform;
|
||||||
|
|
||||||
// The name of the Texture Uniform in the Shader
|
|
||||||
const char* texture_uniform;
|
|
||||||
|
|
||||||
Batch();
|
Batch();
|
||||||
Batch(const Batch& other) = delete;
|
Batch(const Batch& other) = delete;
|
||||||
Batch& operator=(const Batch& other) = delete;
|
Batch& operator=(const Batch& other) = delete;
|
||||||
|
@ -186,6 +183,7 @@ namespace Blah
|
||||||
uint8_t mult;
|
uint8_t mult;
|
||||||
uint8_t wash;
|
uint8_t wash;
|
||||||
uint8_t fill;
|
uint8_t fill;
|
||||||
|
uint8_t pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DrawBatch
|
struct DrawBatch
|
||||||
|
@ -217,7 +215,7 @@ namespace Blah
|
||||||
uint8_t m_tex_wash;
|
uint8_t m_tex_wash;
|
||||||
DrawBatch m_batch;
|
DrawBatch m_batch;
|
||||||
Vector<Vertex> m_vertices;
|
Vector<Vertex> m_vertices;
|
||||||
Vector<int> m_indices;
|
Vector<uint32_t> m_indices;
|
||||||
Vector<Mat3x2> m_matrix_stack;
|
Vector<Mat3x2> m_matrix_stack;
|
||||||
Vector<Rect> m_scissor_stack;
|
Vector<Rect> m_scissor_stack;
|
||||||
Vector<BlendMode> m_blend_stack;
|
Vector<BlendMode> m_blend_stack;
|
||||||
|
|
|
@ -42,7 +42,6 @@ Material::Material(const ShaderRef& shader)
|
||||||
m_shader = shader;
|
m_shader = shader;
|
||||||
|
|
||||||
auto& uniforms = shader->uniforms();
|
auto& uniforms = shader->uniforms();
|
||||||
Vector<int> float_offsets;
|
|
||||||
int float_size = 0;
|
int float_size = 0;
|
||||||
|
|
||||||
for (auto& uniform : uniforms)
|
for (auto& uniform : uniforms)
|
||||||
|
@ -57,13 +56,10 @@ Material::Material(const ShaderRef& shader)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_offsets.push_back(float_size);
|
|
||||||
float_size += calc_uniform_size(uniform);
|
float_size += calc_uniform_size(uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data.expand(float_size);
|
m_data.expand(float_size);
|
||||||
for (auto& it : float_offsets)
|
|
||||||
m_floats.push_back(m_data.begin() + it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShaderRef Material::shader() const
|
const ShaderRef Material::shader() const
|
||||||
|
@ -75,8 +71,6 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
if (m_textures.size() > 0)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
|
@ -93,11 +87,34 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
|
||||||
if (offset + index >= m_textures.size())
|
if (offset + index >= m_textures.size())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index);
|
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
|
TextureRef Material::get_texture(const char* name, int index) const
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
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");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
int offset = 0;
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type == UniformType::Texture)
|
if (uniform.type == UniformType::Texture)
|
||||||
{
|
{
|
||||||
if (s == slot)
|
if (s == slot)
|
||||||
|
{
|
||||||
|
if (index > uniform.array_length)
|
||||||
|
break;
|
||||||
|
|
||||||
return m_textures[offset + index];
|
return m_textures[offset + index];
|
||||||
|
}
|
||||||
|
|
||||||
offset += uniform.array_length;
|
offset += uniform.array_length;
|
||||||
if (offset + index >= m_textures.size())
|
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");
|
BLAH_ASSERT(length >= 0, "Length must be >= 0");
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int offset = 0;
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
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;
|
length = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(m_floats[index], value, sizeof(float) * length);
|
memcpy(m_data.begin() + offset, value, sizeof(float) * length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset += calc_uniform_size(uniform);
|
||||||
index++;
|
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");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int offset = 0;
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
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)
|
if (length != nullptr)
|
||||||
*length = calc_uniform_size(uniform);
|
*length = calc_uniform_size(uniform);
|
||||||
return m_floats[index];
|
return m_data.begin() + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
offset += calc_uniform_size(uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
*length = 0;
|
*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);
|
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++;
|
const float* Material::data() const
|
||||||
}
|
{
|
||||||
|
return m_data.begin();
|
||||||
Log::warn("No Uniform [%i] exists", slot);
|
|
||||||
*length = 0;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
|
@ -31,38 +31,33 @@ namespace Blah
|
||||||
// Returns the Shader assigned to the Material.
|
// Returns the Shader assigned to the Material.
|
||||||
const ShaderRef shader() const;
|
const ShaderRef shader() const;
|
||||||
|
|
||||||
// Sets the texture. If the index is out of bounds, the Material is not valid, the Uniform
|
// Sets the texture
|
||||||
// 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 array_index = 0);
|
||||||
void set_texture(const char* name, const TextureRef& texture, int index = 0);
|
|
||||||
|
|
||||||
// Gets the texture.
|
// Sets the texture
|
||||||
// If the Uniform does not exist, or the index is out of bounds, this will return
|
void set_texture(int slot, const TextureRef& texture, int array_index = 0);
|
||||||
// an invalid Texture reference.
|
|
||||||
TextureRef get_texture(const char* name, int index = 0) const;
|
|
||||||
|
|
||||||
// Gets the texture from the given slot.
|
// Gets the texture, or an empty reference if invalid
|
||||||
// If the slot is not a Texture Uniform, or the index is out of bounds, this will return
|
TextureRef get_texture(const char* name, int array_index = 0) const;
|
||||||
// an invalid Texture reference.
|
|
||||||
TextureRef get_texture(int slot, int index = 0) const;
|
|
||||||
|
|
||||||
// Sets the value. Length is the total amount of values to set. For example, if the Uniform type
|
// Gets the texture, or an empty reference if invalid
|
||||||
// is a float2, and there are 4 elements, the maximum length should be 8.
|
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);
|
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.
|
// 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;
|
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.
|
// Returns the internal Texture buffer
|
||||||
// Length is the total amount of values. For example, if the Uniform type
|
const Vector<TextureRef>& textures() const;
|
||||||
// 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 interal float buffer of all the values
|
||||||
|
const float* data() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ShaderRef m_shader;
|
ShaderRef m_shader;
|
||||||
Vector<TextureRef> m_textures;
|
Vector<TextureRef> m_textures;
|
||||||
Vector<float*> m_floats;
|
|
||||||
Vector<float> m_data;
|
Vector<float> m_data;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -3,55 +3,38 @@
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
|
||||||
MeshRef Mesh::create()
|
MeshRef Mesh::create()
|
||||||
{
|
{
|
||||||
return GraphicsBackend::create_mesh();
|
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;
|
stride = 0;
|
||||||
|
|
||||||
for (int n = 0; n < attribute_count; n++)
|
for (auto& it : attributes)
|
||||||
{
|
{
|
||||||
const VertexAttribute* attrib = (attributes + n);
|
switch (it.type)
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vertex_format_internal(attributes, attribute_count, stride);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::instance_format(const VertexAttribute* attributes, int attribute_count, int stride)
|
|
||||||
{
|
{
|
||||||
if (stride < 0)
|
case VertexType::Float: stride += 4; break;
|
||||||
{
|
case VertexType::Float2: stride += 8; break;
|
||||||
stride = 0;
|
case VertexType::Float3: stride += 12; break;
|
||||||
|
case VertexType::Float4: stride += 16; break;
|
||||||
for (int n = 0; n < attribute_count; n++)
|
case VertexType::Byte4: stride += 4; break;
|
||||||
{
|
case VertexType::UByte4: stride += 4; break;
|
||||||
const VertexAttribute* attrib = (attributes + n);
|
case VertexType::Short2: stride += 4; break;
|
||||||
|
case VertexType::UShort2: stride += 4; break;
|
||||||
if (attrib->type == VertexAttributeType::Byte)
|
case VertexType::Short4: stride += 8; break;
|
||||||
stride += attrib->components * 1;
|
case VertexType::UShort4: stride += 8; break;
|
||||||
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
|
#pragma once
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <blah/containers/stackvector.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
enum class VertexSemantics
|
enum class VertexType
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
Position,
|
Float,
|
||||||
Normal,
|
Float2,
|
||||||
Bitangent,
|
Float3,
|
||||||
Color0,
|
Float4,
|
||||||
Color1,
|
Byte4,
|
||||||
Color2,
|
UByte4,
|
||||||
Color3,
|
Short2,
|
||||||
Indices,
|
UShort2,
|
||||||
Weight,
|
Short4,
|
||||||
Texcoord0,
|
UShort4
|
||||||
Texcoord1,
|
|
||||||
Texcoord2,
|
|
||||||
Texcoord3,
|
|
||||||
Texcoord4,
|
|
||||||
Texcoord5,
|
|
||||||
Texcoord6,
|
|
||||||
Texcoord7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class VertexAttributeType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Byte,
|
|
||||||
Short,
|
|
||||||
Int,
|
|
||||||
Float
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexAttribute
|
struct VertexAttribute
|
||||||
{
|
{
|
||||||
int index;
|
// Location / Attribute Index
|
||||||
VertexSemantics semantics;
|
int index = 0;
|
||||||
VertexAttributeType type;
|
|
||||||
int components;
|
// Vertex Type
|
||||||
bool normalized;
|
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;
|
class Mesh;
|
||||||
|
@ -66,22 +72,14 @@ namespace Blah
|
||||||
// If the Mesh creation fails, it will return an invalid Mesh.
|
// If the Mesh creation fails, it will return an invalid Mesh.
|
||||||
static MeshRef create();
|
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
|
// 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
|
// 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 VertexFormat& format, const void* vertices, int64_t count) = 0;
|
||||||
virtual void vertex_data(const void* vertices, int64_t count) = 0;
|
|
||||||
|
|
||||||
// Uploads the given instance buffer to the Mesh
|
// 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 VertexFormat& format, const void* instances, int64_t count) = 0;
|
||||||
virtual void instance_data(const void* instances, int64_t count) = 0;
|
|
||||||
|
|
||||||
// Gets the index count of the Mesh
|
// Gets the index count of the Mesh
|
||||||
virtual int64_t index_count() const = 0;
|
virtual int64_t index_count() const = 0;
|
||||||
|
@ -91,9 +89,5 @@ namespace Blah
|
||||||
|
|
||||||
// Gets the instance count of the Mesh
|
// Gets the instance count of the Mesh
|
||||||
virtual int64_t instance_count() const = 0;
|
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
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
// Supported Uniform Types
|
||||||
enum class UniformType
|
enum class UniformType
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
@ -17,17 +18,54 @@ namespace Blah
|
||||||
Texture
|
Texture
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Supported Shader Types
|
||||||
|
enum class ShaderType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Vertex = 1 << 0,
|
||||||
|
Fragment = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uniform Info, provided by the Shader
|
||||||
struct UniformInfo
|
struct UniformInfo
|
||||||
{
|
{
|
||||||
|
// Name of the Uniform
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
|
// The Value type of the Uniform
|
||||||
UniformType type;
|
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;
|
int array_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Data to be passed to the shader to construct it
|
||||||
struct ShaderData
|
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;
|
const char* vertex;
|
||||||
|
|
||||||
|
// Fragment Shader Program data
|
||||||
const char* fragment;
|
const char* fragment;
|
||||||
|
|
||||||
|
// HLSL Attributes - required for D3D11
|
||||||
|
StackVector<HLSL_Attribute, 16> hlsl_attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shader;
|
class Shader;
|
||||||
|
|
|
@ -9,6 +9,7 @@ using namespace Blah;
|
||||||
TextureRef Texture::create(const Image& image)
|
TextureRef Texture::create(const Image& image)
|
||||||
{
|
{
|
||||||
auto tex = create(image.width, image.height, TextureFormat::RGBA);
|
auto tex = create(image.width, image.height, TextureFormat::RGBA);
|
||||||
|
if (tex)
|
||||||
tex->set_data((unsigned char*)image.pixels);
|
tex->set_data((unsigned char*)image.pixels);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +17,7 @@ TextureRef Texture::create(const Image& image)
|
||||||
TextureRef Texture::create(int width, int height, unsigned char* rgba)
|
TextureRef Texture::create(int width, int height, unsigned char* rgba)
|
||||||
{
|
{
|
||||||
auto tex = create(width, height, TextureFormat::RGBA);
|
auto tex = create(width, height, TextureFormat::RGBA);
|
||||||
|
if (tex)
|
||||||
tex->set_data(rgba);
|
tex->set_data(rgba);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -35,9 +37,10 @@ TextureRef Texture::create(Stream& stream)
|
||||||
{
|
{
|
||||||
Image img = Image(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);
|
auto tex = create(img.width, img.height, TextureFormat::RGBA);
|
||||||
|
if (tex)
|
||||||
tex->set_data((unsigned char*)img.pixels);
|
tex->set_data((unsigned char*)img.pixels);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +52,10 @@ TextureRef Texture::create(const char* file)
|
||||||
{
|
{
|
||||||
Image img = Image(file);
|
Image img = Image(file);
|
||||||
|
|
||||||
if (img.pixels != nullptr)
|
if (img.pixels)
|
||||||
{
|
{
|
||||||
auto tex = create(img.width, img.height, TextureFormat::RGBA);
|
auto tex = create(img.width, img.height, TextureFormat::RGBA);
|
||||||
|
if (tex)
|
||||||
tex->set_data((unsigned char*)img.pixels);
|
tex->set_data((unsigned char*)img.pixels);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ namespace Blah
|
||||||
None,
|
None,
|
||||||
R,
|
R,
|
||||||
RG,
|
RG,
|
||||||
RGB,
|
|
||||||
RGBA,
|
RGBA,
|
||||||
DepthStencil,
|
DepthStencil,
|
||||||
Count
|
Count
|
||||||
|
|
Loading…
Reference in New Issue
Block a user