mirror of
https://github.com/NoelFB/blah.git
synced 2025-04-11 01:26:05 +08:00
fixed Textures/Samplers potentially using incorrect registers
This commit is contained in:
parent
0628e0dce5
commit
410adbfe12
@ -257,12 +257,15 @@ namespace Blah
|
|||||||
// The Shader type the Uniform is a part of
|
// The Shader type the Uniform is a part of
|
||||||
ShaderType shader;
|
ShaderType shader;
|
||||||
|
|
||||||
|
// Texture / Sampler register index, which shaders can manually assign
|
||||||
|
int register_index = 0;
|
||||||
|
|
||||||
// Some rendering APIs have uniform buffers. The `buffer_index`
|
// Some rendering APIs have uniform buffers. The `buffer_index`
|
||||||
// specifies which buffer the uniform belongs to
|
// specifies which buffer the uniform belongs to
|
||||||
int buffer_index;
|
int buffer_index = 0;
|
||||||
|
|
||||||
// Array length of the Uniform (ex. a vec2[4] would be 4)
|
// Array length of the Uniform (ex. a vec2[4] would be 4)
|
||||||
int array_length;
|
int array_length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Supported Vertex value types
|
// Supported Vertex value types
|
||||||
@ -550,25 +553,25 @@ namespace Blah
|
|||||||
void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
|
void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
|
||||||
|
|
||||||
// Sets the texture
|
// Sets the texture
|
||||||
void set_texture(int slot, const TextureRef& texture, int array_index = 0);
|
void set_texture(int register_index, const TextureRef& texture);
|
||||||
|
|
||||||
// Gets the texture, or an empty reference if invalid
|
// Gets the texture, or an empty reference if invalid
|
||||||
TextureRef get_texture(const char* name, int array_index = 0) const;
|
TextureRef get_texture(const char* name, int array_index = 0) const;
|
||||||
|
|
||||||
// Gets the texture, or an empty reference if invalid
|
// Gets the texture, or an empty reference if invalid
|
||||||
TextureRef get_texture(int slot, int array_index = 0) const;
|
TextureRef get_texture(int register_index) const;
|
||||||
|
|
||||||
// Sets the sampler
|
// Sets the sampler
|
||||||
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
|
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
|
||||||
|
|
||||||
// Sets the sampler
|
// Sets the sampler
|
||||||
void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0);
|
void set_sampler(int register_index, const TextureSampler& sampler);
|
||||||
|
|
||||||
// Gets the sampler
|
// Gets the sampler
|
||||||
TextureSampler get_sampler(const char* name, int array_index = 0) const;
|
TextureSampler get_sampler(const char* name, int array_index = 0) const;
|
||||||
|
|
||||||
// Gets the sampler
|
// Gets the sampler
|
||||||
TextureSampler get_sampler(int slot, int array_index = 0) const;
|
TextureSampler get_sampler(int register_index) const;
|
||||||
|
|
||||||
// Sets the value. `length` is the total number of floats to set
|
// Sets the value. `length` is the total number of floats to set
|
||||||
// For example if the uniform is a float2[4], a total of 8 float values
|
// For example if the uniform is a float2[4], a total of 8 float values
|
||||||
|
158
src/graphics.cpp
158
src/graphics.cpp
@ -256,15 +256,15 @@ Material::Material(const ShaderRef& shader)
|
|||||||
|
|
||||||
if (uniform.type == UniformType::Texture2D)
|
if (uniform.type == UniformType::Texture2D)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < uniform.array_length; i++)
|
if (m_textures.size() < uniform.register_index + uniform.array_length)
|
||||||
m_textures.push_back(TextureRef());
|
m_textures.resize(uniform.register_index + uniform.array_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uniform.type == UniformType::Sampler2D)
|
if (uniform.type == UniformType::Sampler2D)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < uniform.array_length; i++)
|
if (m_samplers.size() < uniform.register_index + uniform.array_length)
|
||||||
m_samplers.push_back(TextureSampler());
|
m_samplers.resize(uniform.register_index + uniform.array_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +302,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");
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Texture2D)
|
if (uniform.type != UniformType::Texture2D)
|
||||||
@ -310,92 +309,60 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
|
|||||||
|
|
||||||
if (strcmp(uniform.name, name) == 0)
|
if (strcmp(uniform.name, name) == 0)
|
||||||
{
|
{
|
||||||
m_textures[offset + index] = texture;
|
if (uniform.register_index + index < m_textures.size())
|
||||||
return;
|
{
|
||||||
}
|
m_textures[uniform.register_index + index] = texture;
|
||||||
|
return;
|
||||||
offset += uniform.array_length;
|
}
|
||||||
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)
|
void Material::set_texture(int register_index, const TextureRef& texture)
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int s = 0;
|
if (register_index >= m_textures.size())
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Texture2D)
|
Log::warn("Texture Register index [%i] is out of bounds", register_index);
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
if (s == slot)
|
|
||||||
{
|
|
||||||
if (index > uniform.array_length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_textures[offset + index] = texture;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += uniform.array_length;
|
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_textures[register_index] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Texture2D)
|
if (uniform.type != UniformType::Texture2D)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp(uniform.name, name) == 0)
|
if (strcmp(uniform.name, name) == 0)
|
||||||
return m_textures[offset + index];
|
{
|
||||||
|
if (uniform.register_index + index < m_textures.size())
|
||||||
offset += uniform.array_length;
|
return m_textures[uniform.register_index + index];
|
||||||
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);
|
||||||
return TextureRef();
|
return TextureRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureRef Material::get_texture(int slot, int index) const
|
TextureRef Material::get_texture(int register_index) const
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int s = 0;
|
if (register_index < m_textures.size())
|
||||||
int offset = 0;
|
return m_textures[register_index];
|
||||||
for (auto& uniform : m_shader->uniforms())
|
|
||||||
{
|
|
||||||
if (uniform.type != UniformType::Texture2D)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (s == slot)
|
Log::warn("No Texture Uniform at register index [%i]", register_index);
|
||||||
{
|
|
||||||
if (index > uniform.array_length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
return m_textures[offset + index];
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += uniform.array_length;
|
|
||||||
if (offset + index >= m_textures.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log::warn("No Texture Uniform ['%i'] at index [%i] exists", slot, index);
|
|
||||||
return TextureRef();
|
return TextureRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +370,6 @@ void Material::set_sampler(const char* name, const TextureSampler& sampler, int
|
|||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Sampler2D)
|
if (uniform.type != UniformType::Sampler2D)
|
||||||
@ -411,92 +377,60 @@ void Material::set_sampler(const char* name, const TextureSampler& sampler, int
|
|||||||
|
|
||||||
if (strcmp(uniform.name, name) == 0)
|
if (strcmp(uniform.name, name) == 0)
|
||||||
{
|
{
|
||||||
m_samplers[offset + index] = sampler;
|
if (uniform.register_index + index < m_samplers.size())
|
||||||
return;
|
{
|
||||||
}
|
m_samplers[uniform.register_index + index] = sampler;
|
||||||
|
return;
|
||||||
offset += uniform.array_length;
|
}
|
||||||
if (offset + index >= m_samplers.size())
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
|
Log::warn("No Texture Sampler Uniform '%s' at index [%i] exists", name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::set_sampler(int slot, const TextureSampler& sampler, int index)
|
void Material::set_sampler(int register_index, const TextureSampler& sampler)
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int s = 0;
|
if (register_index >= m_samplers.size())
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Sampler2D)
|
Log::warn("Texture Sampler Register index [%i] is out of bounds", register_index);
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
if (s == slot)
|
|
||||||
{
|
|
||||||
if (index > uniform.array_length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
m_samplers[offset + index] = sampler;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += uniform.array_length;
|
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_samplers[register_index] = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureSampler Material::get_sampler(const char* name, int index) const
|
TextureSampler Material::get_sampler(const char* name, int index) const
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (auto& uniform : m_shader->uniforms())
|
for (auto& uniform : m_shader->uniforms())
|
||||||
{
|
{
|
||||||
if (uniform.type != UniformType::Sampler2D)
|
if (uniform.type != UniformType::Sampler2D)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp(uniform.name, name) == 0)
|
if (strcmp(uniform.name, name) == 0)
|
||||||
return m_samplers[offset + index];
|
{
|
||||||
|
if (uniform.register_index + index < m_samplers.size())
|
||||||
offset += uniform.array_length;
|
return m_samplers[uniform.register_index + index];
|
||||||
if (offset + index >= m_samplers.size())
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
|
Log::warn("No Texture Sampler Uniform '%s' at index [%i] exists", name, index);
|
||||||
return TextureSampler();
|
return TextureSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureSampler Material::get_sampler(int slot, int index) const
|
TextureSampler Material::get_sampler(int register_index) const
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
BLAH_ASSERT(m_shader, "Material Shader is invalid");
|
||||||
|
|
||||||
int s = 0;
|
if (register_index < m_samplers.size())
|
||||||
int offset = 0;
|
return m_samplers[register_index];
|
||||||
for (auto& uniform : m_shader->uniforms())
|
|
||||||
{
|
|
||||||
if (uniform.type != UniformType::Sampler2D)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (s == slot)
|
Log::warn("No Texture Sampler Uniform at register index [%i]", register_index);
|
||||||
{
|
|
||||||
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();
|
return TextureSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,6 +1204,7 @@ namespace Blah
|
|||||||
auto uniform = append_uniforms_to.expand();
|
auto uniform = append_uniforms_to.expand();
|
||||||
uniform->name = desc.Name;
|
uniform->name = desc.Name;
|
||||||
uniform->shader = shader_type;
|
uniform->shader = shader_type;
|
||||||
|
uniform->register_index = desc.BindPoint;
|
||||||
uniform->buffer_index = 0;
|
uniform->buffer_index = 0;
|
||||||
uniform->array_length = max(1, desc.BindCount);
|
uniform->array_length = max(1, desc.BindCount);
|
||||||
uniform->type = UniformType::Texture2D;
|
uniform->type = UniformType::Texture2D;
|
||||||
@ -1213,6 +1214,7 @@ namespace Blah
|
|||||||
auto uniform = append_uniforms_to.expand();
|
auto uniform = append_uniforms_to.expand();
|
||||||
uniform->name = desc.Name;
|
uniform->name = desc.Name;
|
||||||
uniform->shader = shader_type;
|
uniform->shader = shader_type;
|
||||||
|
uniform->register_index = desc.BindPoint;
|
||||||
uniform->buffer_index = 0;
|
uniform->buffer_index = 0;
|
||||||
uniform->array_length = max(1, desc.BindCount);
|
uniform->array_length = max(1, desc.BindCount);
|
||||||
uniform->type = UniformType::Sampler2D;
|
uniform->type = UniformType::Sampler2D;
|
||||||
@ -1254,6 +1256,7 @@ namespace Blah
|
|||||||
auto uniform = append_uniforms_to.expand();
|
auto uniform = append_uniforms_to.expand();
|
||||||
uniform->name = var_desc.Name;
|
uniform->name = var_desc.Name;
|
||||||
uniform->shader = shader_type;
|
uniform->shader = shader_type;
|
||||||
|
uniform->register_index = 0;
|
||||||
uniform->buffer_index = i;
|
uniform->buffer_index = i;
|
||||||
uniform->array_length = max(1, type_desc.Elements);
|
uniform->array_length = max(1, type_desc.Elements);
|
||||||
uniform->type = UniformType::None;
|
uniform->type = UniformType::None;
|
||||||
|
@ -894,6 +894,7 @@ namespace Blah
|
|||||||
const int max_name_length = 256;
|
const int max_name_length = 256;
|
||||||
|
|
||||||
GLint active_uniforms = 0;
|
GLint active_uniforms = 0;
|
||||||
|
GLint sampler_uniforms = 0;
|
||||||
renderer->gl.GetProgramiv(id, GL_ACTIVE_UNIFORMS, &active_uniforms);
|
renderer->gl.GetProgramiv(id, GL_ACTIVE_UNIFORMS, &active_uniforms);
|
||||||
|
|
||||||
for (int i = 0; i < active_uniforms; i++)
|
for (int i = 0; i < active_uniforms; i++)
|
||||||
@ -921,6 +922,7 @@ namespace Blah
|
|||||||
{
|
{
|
||||||
UniformInfo tex_uniform;
|
UniformInfo tex_uniform;
|
||||||
tex_uniform.name = name;
|
tex_uniform.name = name;
|
||||||
|
tex_uniform.register_index = sampler_uniforms;
|
||||||
tex_uniform.buffer_index = 0;
|
tex_uniform.buffer_index = 0;
|
||||||
tex_uniform.array_length = size;
|
tex_uniform.array_length = size;
|
||||||
tex_uniform.type = UniformType::Texture2D;
|
tex_uniform.type = UniformType::Texture2D;
|
||||||
@ -930,18 +932,22 @@ namespace Blah
|
|||||||
|
|
||||||
UniformInfo sampler_uniform;
|
UniformInfo sampler_uniform;
|
||||||
sampler_uniform.name = String(name).append("_sampler");
|
sampler_uniform.name = String(name).append("_sampler");
|
||||||
|
sampler_uniform.register_index = sampler_uniforms;
|
||||||
sampler_uniform.buffer_index = 0;
|
sampler_uniform.buffer_index = 0;
|
||||||
sampler_uniform.array_length = size;
|
sampler_uniform.array_length = size;
|
||||||
sampler_uniform.type = UniformType::Sampler2D;
|
sampler_uniform.type = UniformType::Sampler2D;
|
||||||
sampler_uniform.shader = ShaderType::Fragment;
|
sampler_uniform.shader = ShaderType::Fragment;
|
||||||
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
|
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
|
||||||
m_uniforms.push_back(sampler_uniform);
|
m_uniforms.push_back(sampler_uniform);
|
||||||
|
|
||||||
|
sampler_uniforms += size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UniformInfo uniform;
|
UniformInfo uniform;
|
||||||
uniform.name = name;
|
uniform.name = name;
|
||||||
uniform.type = UniformType::None;
|
uniform.type = UniformType::None;
|
||||||
|
uniform.register_index = 0;
|
||||||
uniform.buffer_index = 0;
|
uniform.buffer_index = 0;
|
||||||
uniform.array_length = size;
|
uniform.array_length = size;
|
||||||
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
|
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
|
||||||
@ -1297,7 +1303,6 @@ namespace Blah
|
|||||||
renderer->gl.UseProgram(shader->gl_id());
|
renderer->gl.UseProgram(shader->gl_id());
|
||||||
|
|
||||||
int texture_slot = 0;
|
int texture_slot = 0;
|
||||||
int gl_texture_slot = 0;
|
|
||||||
GLint texture_ids[64];
|
GLint texture_ids[64];
|
||||||
auto& uniforms = shader->uniforms();
|
auto& uniforms = shader->uniforms();
|
||||||
auto data = pass.material->data();
|
auto data = pass.material->data();
|
||||||
@ -1316,10 +1321,10 @@ namespace Blah
|
|||||||
{
|
{
|
||||||
for (int n = 0; n < uniform.array_length; n++)
|
for (int n = 0; n < uniform.array_length; n++)
|
||||||
{
|
{
|
||||||
auto tex = pass.material->get_texture(texture_slot, n);
|
auto tex = pass.material->get_texture(texture_slot);
|
||||||
auto sampler = pass.material->get_sampler(texture_slot, n);
|
auto sampler = pass.material->get_sampler(texture_slot);
|
||||||
|
|
||||||
renderer->gl.ActiveTexture(GL_TEXTURE0 + gl_texture_slot);
|
renderer->gl.ActiveTexture(GL_TEXTURE0 + texture_slot);
|
||||||
|
|
||||||
if (!tex)
|
if (!tex)
|
||||||
{
|
{
|
||||||
@ -1332,12 +1337,11 @@ namespace Blah
|
|||||||
renderer->gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id());
|
renderer->gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_ids[n] = gl_texture_slot;
|
texture_ids[n] = texture_slot;
|
||||||
gl_texture_slot++;
|
texture_slot++;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
|
renderer->gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
|
||||||
texture_slot++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user