fixes
This commit is contained in:
152
source/opengl/handles/shader_program_handle.cpp
Normal file
152
source/opengl/handles/shader_program_handle.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "opengl/handles/shader_program_handle.hpp"
|
||||
|
||||
#include <string_view>
|
||||
// TODO remove
|
||||
#include "opengl/error.hpp"
|
||||
#include "util/logger.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
shader_program_handle::attribute_support_type shader_program_handle::check_attribute_support(
|
||||
const std::span<const shader_program_variable> attributes
|
||||
) const {
|
||||
auto attribute_candidates = attribute_support_type{};
|
||||
|
||||
auto error = std::error_code{};
|
||||
auto check_error = [&error, ec = static_cast<GLenum>(GL_NO_ERROR)]() mutable -> std::error_code&
|
||||
{
|
||||
ec = glGetError();
|
||||
if (ec != GL_NO_ERROR) {
|
||||
error = make_error_code(ec);
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
auto curr_attribute_flag = attribute_support_type{ 1 };
|
||||
for (const auto& attribute : attributes) {
|
||||
const auto location = glGetAttribLocation(program_id, attribute.name);
|
||||
if (location == attribute.info.location)
|
||||
{
|
||||
attribute_candidates |= curr_attribute_flag;
|
||||
}
|
||||
curr_attribute_flag <<= 1;
|
||||
}
|
||||
|
||||
auto supported_attributes = attribute_support_type{};
|
||||
|
||||
GLint count;
|
||||
glGetProgramiv(program_id, GL_ACTIVE_ATTRIBUTES, &count);
|
||||
if (check_error()) ztu::logger::error("GL_err: %", error.message());
|
||||
|
||||
for (GLint i{}; i != count and attribute_candidates; ++i)
|
||||
{
|
||||
GLenum type;
|
||||
GLint size;
|
||||
GLsizei name_length;
|
||||
auto name = std::array<char, 256>{};
|
||||
glGetActiveAttrib(
|
||||
program_id, i,
|
||||
name.size(),
|
||||
&name_length,
|
||||
&size, &type,
|
||||
name.data()
|
||||
);
|
||||
if (check_error()) ztu::logger::error("GL_err: %", error.message());
|
||||
|
||||
const auto name_view = std::string_view(name.data(), name_length);
|
||||
|
||||
auto attribute_index = attribute_support_type{};
|
||||
for (auto candidates = attribute_candidates; candidates; candidates >>= 1) {
|
||||
if (candidates & 1)
|
||||
{
|
||||
const auto& attribute = attributes[attribute_index];
|
||||
if (type == attribute.info.type and name_view == attribute.name)
|
||||
{
|
||||
const auto new_uniform_flag = attribute_support_type{ 1 } << attribute_index;
|
||||
supported_attributes |= new_uniform_flag;
|
||||
attribute_candidates ^= new_uniform_flag;
|
||||
}
|
||||
}
|
||||
++attribute_index;
|
||||
}
|
||||
}
|
||||
|
||||
return supported_attributes;
|
||||
}
|
||||
|
||||
shader_program_handle::uniform_support_type shader_program_handle::check_uniform_support(
|
||||
const std::span<const shader_program_variable> uniforms
|
||||
) const {
|
||||
auto uniform_candidates = uniform_support_type{};
|
||||
|
||||
auto error = std::error_code{};
|
||||
auto check_error = [&error, ec = static_cast<GLenum>(GL_NO_ERROR)]() mutable -> std::error_code&
|
||||
{
|
||||
ec = glGetError();
|
||||
if (ec != GL_NO_ERROR) {
|
||||
error = make_error_code(ec);
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
auto curr_uniform_flag = uniform_support_type{ 1 };
|
||||
for (const auto& uniform : uniforms)
|
||||
{
|
||||
const auto location = glGetUniformLocation(program_id, uniform.name);
|
||||
|
||||
if (location == uniform.info.location)
|
||||
{
|
||||
uniform_candidates |= curr_uniform_flag;
|
||||
ztu::logger::debug("[%] '%': %.", program_id, uniform.name, location);
|
||||
}
|
||||
else
|
||||
{
|
||||
ztu::logger::debug("Expected '%' at % but was %.", uniform.name, uniform.info.location, location);
|
||||
}
|
||||
curr_uniform_flag <<= 1;
|
||||
}
|
||||
|
||||
auto supported_uniforms = uniform_support_type{};
|
||||
|
||||
GLint count;
|
||||
glGetProgramiv(program_id, GL_ACTIVE_UNIFORMS, &count);
|
||||
if (check_error()) ztu::logger::error("GL_err: %", error.message());
|
||||
|
||||
for (GLint i{}; i != count and uniform_candidates; ++i)
|
||||
{
|
||||
GLenum type;
|
||||
GLint size;
|
||||
GLsizei name_length;
|
||||
auto name = std::array<char, 256>{};
|
||||
glGetActiveUniform(
|
||||
program_id, i,
|
||||
name.size(),
|
||||
&name_length,
|
||||
&size, &type,
|
||||
name.data()
|
||||
);
|
||||
if (check_error()) ztu::logger::error("GL_err: %", error.message());
|
||||
|
||||
const auto name_view = std::string_view(name.data(), name_length);
|
||||
|
||||
auto uniform_index = uniform_support_type{};
|
||||
for (auto candidates = uniform_candidates; candidates; candidates >>= 1)
|
||||
{
|
||||
if (candidates & 1)
|
||||
{
|
||||
const auto& uniform = uniforms[uniform_index];
|
||||
if (type == uniform.info.type and name_view == uniform.name)
|
||||
{
|
||||
const auto new_uniform_flag = uniform_support_type{ 1 } << uniform_index;
|
||||
supported_uniforms |= new_uniform_flag;
|
||||
uniform_candidates ^= new_uniform_flag;
|
||||
}
|
||||
}
|
||||
++uniform_index;
|
||||
}
|
||||
}
|
||||
|
||||
return supported_uniforms;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user