mirror of
https://github.com/NoelFB/blah.git
synced 2025-06-30 19:35:25 +08:00
separated Textures from Samplers, to accommodate HLSL etc
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
#include <blah/graphics/material.h>
|
||||
#include <blah/graphics/mesh.h>
|
||||
#include <blah/graphics/renderpass.h>
|
||||
#include <blah/graphics/sampler.h>
|
||||
#include <blah/graphics/shader.h>
|
||||
#include <blah/graphics/texture.h>
|
||||
|
||||
|
@ -339,6 +339,18 @@ void Batch::set_texture(const TextureRef& texture)
|
||||
}
|
||||
}
|
||||
|
||||
void Batch::set_sampler(const TextureSampler& sampler)
|
||||
{
|
||||
if (m_batch.elements > 0 && sampler != m_batch.sampler)
|
||||
{
|
||||
m_batches.push_back(m_batch);
|
||||
m_batch.offset += m_batch.elements;
|
||||
m_batch.elements = 0;
|
||||
}
|
||||
|
||||
m_batch.sampler = sampler;
|
||||
}
|
||||
|
||||
void Batch::render(const FrameBufferRef& target)
|
||||
{
|
||||
Point size;
|
||||
@ -394,7 +406,8 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
|
||||
if (!pass.material)
|
||||
pass.material = m_default_material;
|
||||
|
||||
pass.material->set_texture(0, b.texture, 0);
|
||||
pass.material->set_texture(0, b.texture);
|
||||
pass.material->set_sampler(0, b.sampler);
|
||||
pass.material->set_value(matrix_uniform, &matrix.m11, 16);
|
||||
|
||||
pass.blend = b.blend;
|
||||
@ -422,6 +435,7 @@ void Batch::clear()
|
||||
m_batch.blend = BlendMode::Normal;
|
||||
m_batch.material.reset();
|
||||
m_batch.texture.reset();
|
||||
m_batch.sampler = default_sampler;
|
||||
m_batch.scissor.w = m_batch.scissor.h = -1;
|
||||
m_batch.flip_vertically = false;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <blah/drawing/spritefont.h>
|
||||
#include <blah/containers/vector.h>
|
||||
#include <blah/graphics/blend.h>
|
||||
#include <blah/graphics/sampler.h>
|
||||
#include <blah/graphics/renderpass.h>
|
||||
#include <blah/app.h>
|
||||
|
||||
@ -45,6 +46,9 @@ namespace Blah
|
||||
// The name of the Matrix Uniform in the Shader
|
||||
const char* matrix_uniform;
|
||||
|
||||
// Default Sampler, set on clear
|
||||
TextureSampler default_sampler;
|
||||
|
||||
Batch();
|
||||
Batch(const Batch& other) = delete;
|
||||
Batch& operator=(const Batch& other) = delete;
|
||||
@ -112,6 +116,9 @@ namespace Blah
|
||||
// this (ex the `str` and `tex` methods)
|
||||
void set_texture(const TextureRef& texture);
|
||||
|
||||
// Sets the current texture sampler for drawing.
|
||||
void set_sampler(const TextureSampler& sampler);
|
||||
|
||||
// Draws the batch to the given target
|
||||
void render(const FrameBufferRef& target = App::backbuffer);
|
||||
|
||||
@ -194,6 +201,7 @@ namespace Blah
|
||||
MaterialRef material;
|
||||
BlendMode blend;
|
||||
TextureRef texture;
|
||||
TextureSampler sampler;
|
||||
bool flip_vertically;
|
||||
Rect scissor;
|
||||
|
||||
|
@ -89,7 +89,7 @@ namespace Blah
|
||||
rgba = blendColor;
|
||||
}
|
||||
|
||||
inline bool operator==(const BlendMode& rhs) const
|
||||
bool operator==(const BlendMode& rhs) const
|
||||
{
|
||||
return
|
||||
color_op == rhs.color_op && color_src == rhs.color_src && color_dst == rhs.color_dst &&
|
||||
@ -97,7 +97,7 @@ namespace Blah
|
||||
mask == rhs.mask && rgba == rhs.rgba;
|
||||
}
|
||||
|
||||
inline bool operator!=(const BlendMode& rhs) const
|
||||
bool operator!=(const BlendMode& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
@ -49,13 +49,20 @@ Material::Material(const ShaderRef& shader)
|
||||
if (uniform.type == UniformType::None)
|
||||
continue;
|
||||
|
||||
if (uniform.type == UniformType::Texture)
|
||||
if (uniform.type == UniformType::Texture2D)
|
||||
{
|
||||
for (int i = 0; i < uniform.array_length; i ++)
|
||||
m_textures.push_back(TextureRef());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uniform.type == UniformType::Sampler2D)
|
||||
{
|
||||
for (int i = 0; i < uniform.array_length; i++)
|
||||
m_samplers.push_back(TextureSampler());
|
||||
continue;
|
||||
}
|
||||
|
||||
float_size += calc_uniform_size(uniform);
|
||||
}
|
||||
|
||||
@ -74,7 +81,7 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Texture)
|
||||
if (uniform.type != UniformType::Texture2D)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
@ -99,19 +106,20 @@ void Material::set_texture(int slot, const TextureRef& texture, int index)
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture)
|
||||
{
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
if (uniform.type != UniformType::Texture2D)
|
||||
continue;
|
||||
|
||||
m_textures[offset + index] = texture;
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
}
|
||||
offset += uniform.array_length;
|
||||
s++;
|
||||
|
||||
m_textures[offset + index] = texture;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +130,7 @@ TextureRef Material::get_texture(const char* name, int index) const
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Texture)
|
||||
if (uniform.type != UniformType::Texture2D)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
@ -145,21 +153,21 @@ TextureRef Material::get_texture(int slot, int index) const
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture)
|
||||
if (uniform.type != UniformType::Texture2D)
|
||||
continue;
|
||||
|
||||
if (s == slot)
|
||||
{
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
return m_textures[offset + index];
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_textures.size())
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
return m_textures[offset + index];
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_textures.size())
|
||||
break;
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
@ -167,6 +175,107 @@ TextureRef Material::get_texture(int slot, int index) const
|
||||
return TextureRef();
|
||||
}
|
||||
|
||||
void Material::set_sampler(const char* name, const TextureSampler& sampler, int index)
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Sampler2D)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
{
|
||||
m_samplers[offset + index] = sampler;
|
||||
return;
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_samplers.size())
|
||||
break;
|
||||
}
|
||||
|
||||
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
|
||||
}
|
||||
|
||||
void Material::set_sampler(int slot, const TextureSampler& sampler, 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::Sampler2D)
|
||||
continue;
|
||||
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
m_samplers[offset + index] = sampler;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
TextureSampler Material::get_sampler(const char* name, int index) const
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Sampler2D)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
return m_samplers[offset + index];
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_samplers.size())
|
||||
break;
|
||||
}
|
||||
|
||||
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
|
||||
return TextureSampler();
|
||||
}
|
||||
|
||||
TextureSampler Material::get_sampler(int slot, int index) const
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
|
||||
int s = 0;
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type != UniformType::Sampler2D)
|
||||
continue;
|
||||
|
||||
if (s == slot)
|
||||
{
|
||||
if (index > uniform.array_length)
|
||||
break;
|
||||
|
||||
return m_samplers[offset + index];
|
||||
}
|
||||
|
||||
offset += uniform.array_length;
|
||||
if (offset + index >= m_samplers.size())
|
||||
break;
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
Log::warn("No Sampler Uniform ['%i'] at index [%i] exists", slot, index);
|
||||
return TextureSampler();
|
||||
}
|
||||
|
||||
void Material::set_value(const char* name, const float* value, int64_t length)
|
||||
{
|
||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||
@ -176,7 +285,9 @@ void Material::set_value(const char* name, const float* value, int64_t length)
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
||||
if (uniform.type == UniformType::Texture2D ||
|
||||
uniform.type == UniformType::Sampler2D ||
|
||||
uniform.type == UniformType::None)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
@ -207,7 +318,9 @@ const float* Material::get_value(const char* name, int64_t* length) const
|
||||
int offset = 0;
|
||||
for (auto& uniform : m_shader->uniforms())
|
||||
{
|
||||
if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
|
||||
if (uniform.type == UniformType::Texture2D ||
|
||||
uniform.type == UniformType::Sampler2D ||
|
||||
uniform.type == UniformType::None)
|
||||
continue;
|
||||
|
||||
if (strcmp(uniform.name, name) == 0)
|
||||
@ -231,6 +344,11 @@ const Vector<TextureRef>& Material::textures() const
|
||||
return m_textures;
|
||||
}
|
||||
|
||||
const Vector<TextureSampler>& Material::samplers() const
|
||||
{
|
||||
return m_samplers;
|
||||
}
|
||||
|
||||
const float* Material::data() const
|
||||
{
|
||||
return m_data.begin();
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <blah/graphics/texture.h>
|
||||
#include <blah/graphics/shader.h>
|
||||
#include <blah/graphics/sampler.h>
|
||||
#include <blah/containers/vector.h>
|
||||
#include <memory>
|
||||
|
||||
@ -43,6 +44,18 @@ namespace Blah
|
||||
// Gets the texture, or an empty reference if invalid
|
||||
TextureRef get_texture(int slot, int array_index = 0) const;
|
||||
|
||||
// Sets the sampler
|
||||
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
|
||||
|
||||
// Sets the sampler
|
||||
void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0);
|
||||
|
||||
// Gets the sampler
|
||||
TextureSampler get_sampler(const char* name, int array_index = 0) const;
|
||||
|
||||
// Gets the sampler
|
||||
TextureSampler get_sampler(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);
|
||||
|
||||
@ -52,12 +65,16 @@ namespace Blah
|
||||
// Returns the internal Texture buffer
|
||||
const Vector<TextureRef>& textures() const;
|
||||
|
||||
// Returns the internal Sampler buffer
|
||||
const Vector<TextureSampler>& samplers() const;
|
||||
|
||||
// Returns the interal float buffer of all the values
|
||||
const float* data() const;
|
||||
|
||||
private:
|
||||
ShaderRef m_shader;
|
||||
Vector<TextureRef> m_textures;
|
||||
Vector<TextureSampler> m_samplers;
|
||||
Vector<float> m_data;
|
||||
};
|
||||
}
|
53
public/blah/graphics/sampler.h
Normal file
53
public/blah/graphics/sampler.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
enum class TextureFilter
|
||||
{
|
||||
None,
|
||||
Linear,
|
||||
Nearest
|
||||
};
|
||||
|
||||
enum class TextureWrap
|
||||
{
|
||||
None,
|
||||
Clamp,
|
||||
Repeat
|
||||
};
|
||||
|
||||
struct TextureSampler
|
||||
{
|
||||
TextureFilter filter;
|
||||
TextureWrap wrap_x;
|
||||
TextureWrap wrap_y;
|
||||
|
||||
TextureSampler() :
|
||||
filter(TextureFilter::Linear),
|
||||
wrap_x(TextureWrap::Repeat),
|
||||
wrap_y(TextureWrap::Repeat) {}
|
||||
|
||||
TextureSampler(TextureFilter filter) :
|
||||
filter(filter),
|
||||
wrap_x(TextureWrap::Repeat),
|
||||
wrap_y(TextureWrap::Repeat) {}
|
||||
|
||||
TextureSampler(TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y) :
|
||||
filter(filter),
|
||||
wrap_x(wrap_x),
|
||||
wrap_y(wrap_y) {}
|
||||
|
||||
bool operator==(const TextureSampler& rhs) const
|
||||
{
|
||||
return
|
||||
filter == rhs.filter &&
|
||||
wrap_x == rhs.wrap_x &&
|
||||
wrap_y == rhs.wrap_y;
|
||||
}
|
||||
|
||||
bool operator!=(const TextureSampler& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
}
|
@ -15,7 +15,8 @@ namespace Blah
|
||||
Float4,
|
||||
Mat3x2,
|
||||
Mat4x4,
|
||||
Texture
|
||||
Texture2D,
|
||||
Sampler2D
|
||||
};
|
||||
|
||||
// Supported Shader Types
|
||||
|
@ -28,7 +28,7 @@ TextureRef Texture::create(int width, int height, TextureFormat format)
|
||||
BLAH_ASSERT((int)format > (int)TextureFormat::None && (int)format < (int)TextureFormat::Count, "Invalid texture format");
|
||||
|
||||
if (width > 0 && height > 0)
|
||||
return GraphicsBackend::create_texture(width, height, TextureFilter::Linear, TextureWrap::Repeat, TextureWrap::Repeat, format);
|
||||
return GraphicsBackend::create_texture(width, height, format);
|
||||
|
||||
return TextureRef();
|
||||
}
|
||||
|
@ -3,19 +3,6 @@
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
enum class TextureFilter
|
||||
{
|
||||
None,
|
||||
Linear,
|
||||
Nearest
|
||||
};
|
||||
|
||||
enum class TextureWrap
|
||||
{
|
||||
None,
|
||||
Clamp,
|
||||
Repeat
|
||||
};
|
||||
|
||||
enum class TextureFormat
|
||||
{
|
||||
@ -76,21 +63,6 @@ namespace Blah
|
||||
// Gets the format of the Texture
|
||||
virtual TextureFormat format() const = 0;
|
||||
|
||||
// Sets the filter of the Texture
|
||||
virtual void set_filter(TextureFilter filter) = 0;
|
||||
|
||||
// Gets the filter of the Texture
|
||||
virtual TextureFilter get_filter() const = 0;
|
||||
|
||||
// Sets the wrap of the Texture
|
||||
virtual void set_wrap(TextureWrap x, TextureWrap y) = 0;
|
||||
|
||||
// Gets the wrap of the Texture
|
||||
virtual TextureWrap get_wrap_x() const = 0;
|
||||
|
||||
// Gets the wrap of the Texture
|
||||
virtual TextureWrap get_wrap_y() const = 0;
|
||||
|
||||
// Sets the data of the Texture.
|
||||
// Note that the pixel buffer should be in the same format as the Texture. There is no row padding.
|
||||
// If the pixel buffer isn't the same size as the texture, it will set the minimum available amount of data.
|
||||
|
Reference in New Issue
Block a user