mirror of
https://github.com/NoelFB/blah.git
synced 2025-06-29 19:25:26 +08:00
separated Textures from Samplers, to accommodate HLSL etc
This commit is contained in:
@ -43,11 +43,11 @@ namespace Blah
|
||||
|
||||
// Creates a new Texture.
|
||||
// if the Texture is invalid, this should return an empty reference.
|
||||
TextureRef create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format);
|
||||
TextureRef create_texture(int width, int height, TextureFormat format);
|
||||
|
||||
// Creates a new FrameBuffer.
|
||||
// if the FrameBuffer is invalid, this should return an empty reference.
|
||||
FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount);
|
||||
FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count);
|
||||
|
||||
// Creates a new Shader.
|
||||
// if the Shader is invalid, this should return an empty reference.
|
||||
|
@ -58,9 +58,7 @@ namespace Blah
|
||||
|
||||
struct StoredSampler
|
||||
{
|
||||
TextureFilter filter;
|
||||
TextureWrap wrap_x;
|
||||
TextureWrap wrap_y;
|
||||
TextureSampler sampler;
|
||||
ID3D11SamplerState* state;
|
||||
};
|
||||
|
||||
@ -79,7 +77,7 @@ namespace Blah
|
||||
ID3D11InputLayout* get_layout(D3D11_Shader* shader, const VertexFormat& format);
|
||||
ID3D11BlendState* get_blend(const BlendMode& blend);
|
||||
ID3D11RasterizerState* get_rasterizer(const RenderPass& pass);
|
||||
ID3D11SamplerState* get_sampler(const TextureRef& texture);
|
||||
ID3D11SamplerState* get_sampler(const TextureSampler& sampler);
|
||||
ID3D11DepthStencilState* get_depthstencil(const RenderPass& pass);
|
||||
};
|
||||
|
||||
@ -140,15 +138,23 @@ namespace Blah
|
||||
D3D11_SHADER_INPUT_BIND_DESC desc;
|
||||
reflector->GetResourceBindingDesc(i, &desc);
|
||||
|
||||
if (desc.Type == D3D_SIT_TEXTURE &&
|
||||
desc.Dimension == D3D_SRV_DIMENSION_TEXTURE2D)
|
||||
if (desc.Type == D3D_SIT_TEXTURE && desc.Dimension == D3D_SRV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
auto uniform = append_to.expand();
|
||||
uniform->name = desc.Name;
|
||||
uniform->shader = shader_type;
|
||||
uniform->buffer_index = 0;
|
||||
uniform->array_length = max(1, desc.BindCount);
|
||||
uniform->type = UniformType::Texture;
|
||||
uniform->type = UniformType::Texture2D;
|
||||
}
|
||||
else if (desc.Type == D3D_SIT_SAMPLER)
|
||||
{
|
||||
auto uniform = append_to.expand();
|
||||
uniform->name = desc.Name;
|
||||
uniform->shader = shader_type;
|
||||
uniform->buffer_index = 0;
|
||||
uniform->array_length = max(1, desc.BindCount);
|
||||
uniform->type = UniformType::Sampler2D;
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,10 +230,7 @@ namespace Blah
|
||||
private:
|
||||
int m_width;
|
||||
int m_height;
|
||||
TextureFilter m_filter;
|
||||
TextureFormat m_format;
|
||||
TextureWrap m_wrap_x;
|
||||
TextureWrap m_wrap_y;
|
||||
bool m_is_framebuffer;
|
||||
int m_size;
|
||||
|
||||
@ -235,14 +238,11 @@ namespace Blah
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
ID3D11ShaderResourceView* view = nullptr;
|
||||
|
||||
D3D11_Texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format, bool is_framebuffer)
|
||||
D3D11_Texture(int width, int height, TextureFormat format, bool is_framebuffer)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_filter = filter;
|
||||
m_format = format;
|
||||
m_wrap_x = wrap_x;
|
||||
m_wrap_y = wrap_y;
|
||||
m_is_framebuffer = is_framebuffer;
|
||||
m_size = 0;
|
||||
|
||||
@ -320,32 +320,6 @@ namespace Blah
|
||||
return m_format;
|
||||
}
|
||||
|
||||
virtual void set_filter(TextureFilter filter) override
|
||||
{
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
virtual TextureFilter get_filter() const override
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
virtual void set_wrap(TextureWrap x, TextureWrap y) override
|
||||
{
|
||||
m_wrap_x = x;
|
||||
m_wrap_y = y;
|
||||
}
|
||||
|
||||
virtual TextureWrap get_wrap_x() const override
|
||||
{
|
||||
return m_wrap_x;
|
||||
}
|
||||
|
||||
virtual TextureWrap get_wrap_y() const override
|
||||
{
|
||||
return m_wrap_y;
|
||||
}
|
||||
|
||||
virtual void set_data(unsigned char* data) override
|
||||
{
|
||||
D3D11_BOX box;
|
||||
@ -386,17 +360,12 @@ namespace Blah
|
||||
StackVector<ID3D11RenderTargetView*, Attachments::MaxCapacity - 1> color_views;
|
||||
ID3D11DepthStencilView* depth_view = nullptr;
|
||||
|
||||
D3D11_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
||||
D3D11_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
|
||||
{
|
||||
for (int i = 0; i < attachmentCount; i++)
|
||||
for (int i = 0; i < attachment_count; i++)
|
||||
{
|
||||
auto tex = new D3D11_Texture(
|
||||
width, height,
|
||||
TextureFilter::Linear,
|
||||
TextureWrap::Repeat,
|
||||
TextureWrap::Repeat,
|
||||
attachments[i],
|
||||
true);
|
||||
auto tex = new D3D11_Texture(width, height, attachments[i], true);
|
||||
|
||||
m_attachments.push_back(TextureRef(tex));
|
||||
|
||||
if (attachments[i] == TextureFormat::DepthStencil)
|
||||
@ -891,9 +860,9 @@ namespace Blah
|
||||
state.swap_chain->Present(1, 0);
|
||||
}
|
||||
|
||||
TextureRef GraphicsBackend::create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
|
||||
TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format)
|
||||
{
|
||||
auto result = new D3D11_Texture(width, height, filter, wrap_x, wrap_y, format, false);
|
||||
auto result = new D3D11_Texture(width, height, format, false);
|
||||
if (result->texture)
|
||||
return TextureRef(result);
|
||||
|
||||
@ -901,9 +870,9 @@ namespace Blah
|
||||
return TextureRef();
|
||||
}
|
||||
|
||||
FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
||||
FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
|
||||
{
|
||||
return FrameBufferRef(new D3D11_FrameBuffer(width, height, attachments, attachmentCount));
|
||||
return FrameBufferRef(new D3D11_FrameBuffer(width, height, attachments, attachment_count));
|
||||
}
|
||||
|
||||
ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
|
||||
@ -936,7 +905,9 @@ namespace Blah
|
||||
const float* data = material->data();
|
||||
for (auto& it : shader->uniforms())
|
||||
{
|
||||
if (it.type == UniformType::Texture)
|
||||
if (it.type == UniformType::None ||
|
||||
it.type == UniformType::Texture2D ||
|
||||
it.type == UniformType::Sampler2D)
|
||||
continue;
|
||||
|
||||
int size = 0;
|
||||
@ -1071,7 +1042,7 @@ namespace Blah
|
||||
ctx->PSSetShader(shader->fragment, nullptr, 0);
|
||||
ctx->PSSetConstantBuffers(0, shader->fcb.size(), shader->fcb.begin());
|
||||
|
||||
// Fragment Shader Textures & Samplers
|
||||
// Fragment Shader Textures
|
||||
auto& textures = pass.material->textures();
|
||||
for (int i = 0; i < textures.size(); i++)
|
||||
{
|
||||
@ -1080,23 +1051,17 @@ namespace Blah
|
||||
// Assign the Texture
|
||||
auto view = ((D3D11_Texture*)textures[i].get())->view;
|
||||
ctx->PSSetShaderResources(i, 1, &view);
|
||||
|
||||
// Assign the Sampler
|
||||
|
||||
// TODO:
|
||||
// This is incorrect! Textures and Samplers are separate in HLSL.
|
||||
// For now, assuming there's 1 Sampler Per Texture, and we set it to
|
||||
// the properties of the texture at the same index.
|
||||
|
||||
// I think most modern APIs separate these, where as OpenGL makes
|
||||
// them the same (afaik). Either we need to separate these in our
|
||||
// API, or find some work around here.
|
||||
|
||||
auto sampler = state.get_sampler(textures[i]);
|
||||
if (sampler)
|
||||
ctx->PSSetSamplers(i, 1, &sampler);
|
||||
}
|
||||
}
|
||||
|
||||
// Fragment Shader Samplers
|
||||
auto& samplers = pass.material->samplers();
|
||||
for (int i = 0; i < samplers.size(); i++)
|
||||
{
|
||||
auto sampler = state.get_sampler(samplers[i]);
|
||||
if (sampler)
|
||||
ctx->PSSetSamplers(i, 1, &sampler);
|
||||
}
|
||||
}
|
||||
|
||||
// RS
|
||||
@ -1294,14 +1259,10 @@ namespace Blah
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ID3D11SamplerState* D3D11::get_sampler(const TextureRef& texture)
|
||||
ID3D11SamplerState* D3D11::get_sampler(const TextureSampler& sampler)
|
||||
{
|
||||
auto filter = texture->get_filter();
|
||||
auto wrap_x = texture->get_wrap_x();
|
||||
auto wrap_y = texture->get_wrap_y();
|
||||
|
||||
for (auto& it : sampler_cache)
|
||||
if (it.filter == filter && it.wrap_x == wrap_x && it.wrap_y == wrap_y)
|
||||
if (it.sampler == sampler)
|
||||
return it.state;
|
||||
|
||||
D3D11_SAMPLER_DESC desc = {};
|
||||
@ -1311,19 +1272,19 @@ namespace Blah
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
|
||||
switch (filter)
|
||||
switch (sampler.filter)
|
||||
{
|
||||
case TextureFilter::Nearest: desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; break;
|
||||
case TextureFilter::Linear: desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; break;
|
||||
}
|
||||
|
||||
switch (wrap_x)
|
||||
switch (sampler.wrap_x)
|
||||
{
|
||||
case TextureWrap::Clamp: desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; break;
|
||||
case TextureWrap::Repeat: desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; break;
|
||||
}
|
||||
|
||||
switch (wrap_y)
|
||||
switch (sampler.wrap_y)
|
||||
{
|
||||
case TextureWrap::Clamp: desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; break;
|
||||
case TextureWrap::Repeat: desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; break;
|
||||
@ -1335,9 +1296,7 @@ namespace Blah
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto entry = sampler_cache.expand();
|
||||
entry->filter = filter;
|
||||
entry->wrap_x = wrap_x;
|
||||
entry->wrap_y = wrap_y;
|
||||
entry->sampler = sampler;
|
||||
entry->state = result;
|
||||
return result;
|
||||
}
|
||||
|
@ -545,9 +545,7 @@ namespace Blah
|
||||
GLuint m_id;
|
||||
int m_width;
|
||||
int m_height;
|
||||
TextureWrap m_wrap_x;
|
||||
TextureWrap m_wrap_y;
|
||||
TextureFilter m_filter;
|
||||
TextureSampler m_sampler;
|
||||
TextureFormat m_format;
|
||||
GLenum m_gl_internal_format;
|
||||
GLenum m_gl_format;
|
||||
@ -556,14 +554,12 @@ namespace Blah
|
||||
public:
|
||||
bool framebuffer_parent;
|
||||
|
||||
OpenGL_Texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
|
||||
OpenGL_Texture(int width, int height, TextureFormat format)
|
||||
{
|
||||
m_id = 0;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_wrap_x = wrap_x;
|
||||
m_wrap_y = wrap_y;
|
||||
m_filter = filter;
|
||||
m_sampler = TextureSampler(TextureFilter::None, TextureWrap::None, TextureWrap::None);
|
||||
m_format = format;
|
||||
framebuffer_parent = false;
|
||||
m_gl_internal_format = GL_RED;
|
||||
@ -609,12 +605,7 @@ namespace Blah
|
||||
gl.GenTextures(1, &m_id);
|
||||
gl.ActiveTexture(GL_TEXTURE0);
|
||||
gl.BindTexture(GL_TEXTURE_2D, m_id);
|
||||
|
||||
gl.TexImage2D(GL_TEXTURE_2D, 0, m_gl_internal_format, width, height, 0, m_gl_format, m_gl_type, nullptr);
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (m_filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (m_filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (m_wrap_x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (m_wrap_y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
}
|
||||
|
||||
~OpenGL_Texture()
|
||||
@ -643,38 +634,18 @@ namespace Blah
|
||||
return m_format;
|
||||
}
|
||||
|
||||
virtual void set_filter(TextureFilter filter) override
|
||||
void update_sampler(const TextureSampler& sampler)
|
||||
{
|
||||
m_filter = filter;
|
||||
if (m_sampler != sampler)
|
||||
{
|
||||
m_sampler = sampler;
|
||||
|
||||
gl.BindTexture(GL_TEXTURE_2D, m_id);
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
}
|
||||
|
||||
virtual TextureFilter get_filter() const override
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
virtual void set_wrap(TextureWrap x, TextureWrap y) override
|
||||
{
|
||||
m_wrap_x = x;
|
||||
m_wrap_y = y;
|
||||
|
||||
gl.BindTexture(GL_TEXTURE_2D, m_id);
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
}
|
||||
|
||||
virtual TextureWrap get_wrap_x() const override
|
||||
{
|
||||
return m_wrap_x;
|
||||
}
|
||||
|
||||
virtual TextureWrap get_wrap_y() const override
|
||||
{
|
||||
return m_wrap_y;
|
||||
gl.BindTexture(GL_TEXTURE_2D, m_id);
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (m_sampler.filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (m_sampler.filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (m_sampler.wrap_x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (m_sampler.wrap_y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_data(unsigned char* data) override
|
||||
@ -899,20 +870,34 @@ namespace Blah
|
||||
}
|
||||
}
|
||||
|
||||
UniformInfo uniform;
|
||||
uniform.name = name;
|
||||
uniform.type = UniformType::None;
|
||||
uniform.buffer_index = 0;
|
||||
uniform.array_length = size;
|
||||
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
||||
|
||||
if (type == GL_SAMPLER_2D)
|
||||
{
|
||||
uniform.type = UniformType::Texture;
|
||||
uniform.shader = ShaderType::Fragment;
|
||||
UniformInfo tex_uniform;
|
||||
tex_uniform.name = name;
|
||||
tex_uniform.buffer_index = 0;
|
||||
tex_uniform.array_length = size;
|
||||
tex_uniform.type = UniformType::Texture2D;
|
||||
tex_uniform.shader = ShaderType::Fragment;
|
||||
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
||||
m_uniforms.push_back(tex_uniform);
|
||||
|
||||
UniformInfo sampler_uniform;
|
||||
sampler_uniform.name = String(name).append("_sampler");
|
||||
sampler_uniform.buffer_index = 0;
|
||||
sampler_uniform.array_length = size;
|
||||
sampler_uniform.type = UniformType::Sampler2D;
|
||||
sampler_uniform.shader = ShaderType::Fragment;
|
||||
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
||||
m_uniforms.push_back(sampler_uniform);
|
||||
}
|
||||
else
|
||||
{
|
||||
UniformInfo uniform;
|
||||
uniform.name = name;
|
||||
uniform.type = UniformType::None;
|
||||
uniform.buffer_index = 0;
|
||||
uniform.array_length = size;
|
||||
uniform_locations.push_back(gl.GetUniformLocation(id, name));
|
||||
uniform.shader = (ShaderType)((int)ShaderType::Vertex | (int)ShaderType::Fragment);
|
||||
|
||||
if (type == GL_FLOAT)
|
||||
@ -933,9 +918,10 @@ namespace Blah
|
||||
Log::error("Unsupported Uniform Type");
|
||||
break;
|
||||
}
|
||||
|
||||
m_uniforms.push_back(uniform);
|
||||
}
|
||||
|
||||
m_uniforms.push_back(uniform);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1192,9 +1178,9 @@ namespace Blah
|
||||
void GraphicsBackend::before_render() {}
|
||||
void GraphicsBackend::after_render() {}
|
||||
|
||||
TextureRef GraphicsBackend::create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
|
||||
TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format)
|
||||
{
|
||||
auto resource = new OpenGL_Texture(width, height, filter, wrap_x, wrap_y, format);
|
||||
auto resource = new OpenGL_Texture(width, height, format);
|
||||
|
||||
if (resource->gl_id() <= 0)
|
||||
{
|
||||
@ -1272,10 +1258,9 @@ namespace Blah
|
||||
{
|
||||
gl.UseProgram(shader->gl_id());
|
||||
|
||||
// upload uniform values
|
||||
int texture_slot = 0;
|
||||
int gl_texture_slot = 0;
|
||||
GLint texture_ids[64];
|
||||
|
||||
auto& uniforms = shader->uniforms();
|
||||
auto data = pass.material->data();
|
||||
|
||||
@ -1284,14 +1269,19 @@ namespace Blah
|
||||
auto location = shader->uniform_locations[i];
|
||||
auto& uniform = uniforms[i];
|
||||
|
||||
// Sampler 2D
|
||||
if (uniform.type == UniformType::Texture)
|
||||
// Sampler 2D's are assigned by updating texture values
|
||||
if (uniform.type == UniformType::Sampler2D)
|
||||
continue;
|
||||
|
||||
// Texture2D
|
||||
if (uniform.type == UniformType::Texture2D)
|
||||
{
|
||||
for (int n = 0; n < uniform.array_length; n++)
|
||||
{
|
||||
auto tex = pass.material->get_texture(i, n);
|
||||
auto tex = pass.material->get_texture(texture_slot, n);
|
||||
auto sampler = pass.material->get_sampler(texture_slot, n);
|
||||
|
||||
gl.ActiveTexture(GL_TEXTURE0 + texture_slot);
|
||||
gl.ActiveTexture(GL_TEXTURE0 + gl_texture_slot);
|
||||
|
||||
if (!tex)
|
||||
{
|
||||
@ -1299,14 +1289,17 @@ namespace Blah
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.BindTexture(GL_TEXTURE_2D, ((OpenGL_Texture*)tex.get())->gl_id());
|
||||
auto gl_tex = ((OpenGL_Texture*)tex.get());
|
||||
gl_tex->update_sampler(sampler);
|
||||
gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id());
|
||||
}
|
||||
|
||||
texture_ids[n] = texture_slot;
|
||||
texture_slot++;
|
||||
texture_ids[n] = gl_texture_slot;
|
||||
gl_texture_slot++;
|
||||
}
|
||||
|
||||
gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
|
||||
texture_slot++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user