Working prototype for entt based rendering
This commit is contained in:
@@ -69,6 +69,7 @@ void main()
|
||||
fragmentColor += pointLightContribution(u_pointLight[i], normal, v_fragmentPosition, viewDir);
|
||||
}
|
||||
|
||||
fragmentColor = vec3(1.,1.,1.);
|
||||
f_color = vec4(fragmentColor, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,123 +31,124 @@ Controller::Controller()
|
||||
m_gameWindow->dimensions().second,
|
||||
postProcessingProgram)
|
||||
{
|
||||
fx::gltf::ReadQuotas read_quotas{.MaxFileSize = 512 * 1024 * 1024,
|
||||
.MaxBufferByteLength = 512 * 1024 * 1024};
|
||||
// fx::gltf::ReadQuotas read_quotas{.MaxFileSize = 512 * 1024 * 1024,
|
||||
// .MaxBufferByteLength = 512 * 1024 * 1024};
|
||||
|
||||
// auto gltf_path = std::filesystem::path("Lantern/glTF/Lantern.gltf");
|
||||
// auto gltf_path = std::filesystem::path("WaterBottle/glTF/WaterBottle.gltf");
|
||||
auto gltf_path = std::filesystem::path("ABeautifulGame.glb");
|
||||
auto gltf = [&]() {
|
||||
if (gltf_path.extension() == ".gltf") {
|
||||
return fx::gltf::LoadFromText(gltf_path, read_quotas);
|
||||
}
|
||||
// // auto gltf_path = std::filesystem::path("Lantern/glTF/Lantern.gltf");
|
||||
// // auto gltf_path = std::filesystem::path("WaterBottle/glTF/WaterBottle.gltf");
|
||||
// auto gltf_path = std::filesystem::path("ABeautifulGame.glb");
|
||||
// auto gltf = [&]() {
|
||||
// if (gltf_path.extension() == ".gltf") {
|
||||
// return fx::gltf::LoadFromText(gltf_path, read_quotas);
|
||||
// }
|
||||
|
||||
return fx::gltf::LoadFromBinary(gltf_path, read_quotas);
|
||||
}();
|
||||
// return fx::gltf::LoadFromBinary(gltf_path, read_quotas);
|
||||
// }();
|
||||
|
||||
defaultProgram.bind();
|
||||
AttributeLocations locations{};
|
||||
// defaultProgram.bind();
|
||||
// AttributeLocations locations{};
|
||||
|
||||
locations.position = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_position");
|
||||
locations.normal = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_normal");
|
||||
locations.uv = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_texCoord");
|
||||
locations.tangent = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_tangent");
|
||||
// locations.position = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_position");
|
||||
// locations.normal = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_normal");
|
||||
// locations.uv = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_texCoord");
|
||||
// locations.tangent = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_tangent");
|
||||
|
||||
ShaderProgram::unbind();
|
||||
// ShaderProgram::unbind();
|
||||
|
||||
if (!gltf.cameras.empty()) {
|
||||
auto const &gltf_camera = gltf.cameras.at(0);
|
||||
// if (!gltf.cameras.empty()) {
|
||||
// auto const &gltf_camera = gltf.cameras.at(0);
|
||||
|
||||
assert(gltf_camera.type == fx::gltf::Camera::Type::Perspective);
|
||||
auto const &perspective = gltf_camera.perspective;
|
||||
// assert(gltf_camera.type == fx::gltf::Camera::Type::Perspective);
|
||||
// auto const &perspective = gltf_camera.perspective;
|
||||
|
||||
m_camera = std::make_shared<Camera>(perspective.yfov, perspective.aspectRatio);
|
||||
} else {
|
||||
m_camera = std::make_shared<Camera>(90., m_gameWindow->aspectRatio());
|
||||
}
|
||||
// m_camera = std::make_shared<Camera>(perspective.yfov, perspective.aspectRatio);
|
||||
// } else {
|
||||
m_camera = std::make_shared<Camera>(90., m_gameWindow->aspectRatio());
|
||||
// }
|
||||
|
||||
std::vector<Model> models;
|
||||
for (auto const &mesh : gltf.meshes) {
|
||||
std::vector<Mesh_> meshes;
|
||||
for (auto const &primitive : mesh.primitives) {
|
||||
auto const &material = gltf.materials.at(primitive.material);
|
||||
auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture.index;
|
||||
auto normalTexture = material.normalTexture.index;
|
||||
// std::vector<Model> models;
|
||||
// for (auto const &mesh : gltf.meshes) {
|
||||
// std::vector<Mesh_> meshes;
|
||||
// for (auto const &primitive : mesh.primitives) {
|
||||
// auto const &material = gltf.materials.at(primitive.material);
|
||||
// auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture.index;
|
||||
// auto normalTexture = material.normalTexture.index;
|
||||
|
||||
std::vector<std::reference_wrapper<const Texture>> primitive_textures;
|
||||
// std::vector<std::reference_wrapper<const Texture>> primitive_textures;
|
||||
|
||||
// Check if texture already exists, if not load it.
|
||||
if (baseColorTexture != -1 && !m_textures.contains(baseColorTexture)) {
|
||||
auto const &gltf_texture = gltf.textures.at(baseColorTexture);
|
||||
m_textures.emplace(baseColorTexture,
|
||||
Texture(gltf_texture,
|
||||
gltf_path.parent_path(),
|
||||
gltf.images,
|
||||
gltf.bufferViews,
|
||||
gltf.buffers,
|
||||
gltf.samplers,
|
||||
TextureType::Diffuse));
|
||||
// // Check if texture already exists, if not load it.
|
||||
// if (baseColorTexture != -1 && !m_textures.contains(baseColorTexture)) {
|
||||
// auto const &gltf_texture = gltf.textures.at(baseColorTexture);
|
||||
// m_textures.emplace(baseColorTexture,
|
||||
// Texture(gltf_texture,
|
||||
// gltf_path.parent_path(),
|
||||
// gltf.images,
|
||||
// gltf.bufferViews,
|
||||
// gltf.buffers,
|
||||
// gltf.samplers,
|
||||
// TextureType::Diffuse));
|
||||
|
||||
primitive_textures.emplace_back(m_textures.at(baseColorTexture));
|
||||
}
|
||||
// primitive_textures.emplace_back(m_textures.at(baseColorTexture));
|
||||
// }
|
||||
|
||||
if (normalTexture != -1 && !m_textures.contains(normalTexture)) {
|
||||
auto const &gltf_texture = gltf.textures.at(normalTexture);
|
||||
m_textures.emplace(normalTexture,
|
||||
Texture(gltf_texture,
|
||||
gltf_path.parent_path(),
|
||||
gltf.images,
|
||||
gltf.bufferViews,
|
||||
gltf.buffers,
|
||||
gltf.samplers,
|
||||
TextureType::Normal));
|
||||
// if (normalTexture != -1 && !m_textures.contains(normalTexture)) {
|
||||
// auto const &gltf_texture = gltf.textures.at(normalTexture);
|
||||
// m_textures.emplace(normalTexture,
|
||||
// Texture(gltf_texture,
|
||||
// gltf_path.parent_path(),
|
||||
// gltf.images,
|
||||
// gltf.bufferViews,
|
||||
// gltf.buffers,
|
||||
// gltf.samplers,
|
||||
// TextureType::Normal));
|
||||
|
||||
primitive_textures.emplace_back(m_textures.at(normalTexture));
|
||||
}
|
||||
// primitive_textures.emplace_back(m_textures.at(normalTexture));
|
||||
// }
|
||||
|
||||
meshes.emplace_back(Mesh_({primitive, gltf, locations}, primitive_textures));
|
||||
}
|
||||
models.emplace_back(Model(mesh.name, std::move(meshes)));
|
||||
}
|
||||
m_models = std::move(models);
|
||||
// meshes.emplace_back(Mesh_({primitive, gltf, locations}, primitive_textures));
|
||||
// }
|
||||
// models.emplace_back(Model(mesh.name, std::move(meshes)));
|
||||
// }
|
||||
// m_models = std::move(models);
|
||||
|
||||
std::vector<ModelEntity> entities;
|
||||
for (auto const &node : gltf.nodes) {
|
||||
if (node.mesh == -1) {
|
||||
continue;
|
||||
}
|
||||
// std::vector<ModelEntity> entities;
|
||||
// for (auto const &node : gltf.nodes) {
|
||||
// if (node.mesh == -1) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F),
|
||||
m_models[static_cast<unsigned>(node.mesh)],
|
||||
defaultProgram);
|
||||
// ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F),
|
||||
// m_models[static_cast<unsigned>(node.mesh)],
|
||||
// defaultProgram);
|
||||
|
||||
if (!node.translation.empty()) {
|
||||
entity.setPosition(
|
||||
glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
}
|
||||
// if (!node.translation.empty()) {
|
||||
// entity.setPosition(
|
||||
// glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
// }
|
||||
|
||||
if (!node.rotation.empty()) {
|
||||
entity.setRotation(glm::eulerAngles(
|
||||
glm::quat(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2])));
|
||||
}
|
||||
// if (!node.rotation.empty()) {
|
||||
// entity.setRotation(glm::eulerAngles(
|
||||
// glm::quat(node.rotation[3], node.rotation[0], node.rotation[1],
|
||||
// node.rotation[2])));
|
||||
// }
|
||||
|
||||
if (!node.scale.empty()) {
|
||||
entity.setScale(node.scale[0]);
|
||||
}
|
||||
// if (!node.scale.empty()) {
|
||||
// entity.setScale(node.scale[0]);
|
||||
// }
|
||||
|
||||
entities.push_back(std::move(entity));
|
||||
}
|
||||
// entities.push_back(std::move(entity));
|
||||
// }
|
||||
|
||||
for (auto const &node : gltf.nodes) {
|
||||
for (auto const &child : node.children) {
|
||||
if (!node.translation.empty()) {
|
||||
entities[child].translate(
|
||||
glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (auto const &node : gltf.nodes) {
|
||||
// for (auto const &child : node.children) {
|
||||
// if (!node.translation.empty()) {
|
||||
// entities[child].translate(
|
||||
// glm::vec3(node.translation[0], node.translation[1], node.translation[2]));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
m_entities = std::move(entities);
|
||||
// m_entities = std::move(entities);
|
||||
}
|
||||
|
||||
void Controller::run()
|
||||
@@ -183,12 +184,19 @@ void Controller::run()
|
||||
m_camera->lookForward();
|
||||
m_camera->updateVPM();
|
||||
|
||||
static constexpr auto MICROSECONDS_PER_SECOND = 1'000'000;
|
||||
m_scene.update(
|
||||
std::chrono::microseconds(static_cast<unsigned>(m_deltaTime * MICROSECONDS_PER_SECOND)),
|
||||
&defaultProgram,
|
||||
m_camera->getViewProj(),
|
||||
m_camera->getPosition());
|
||||
|
||||
// Draw scene
|
||||
defaultProgram.bind();
|
||||
for (auto const &entity : m_entities) {
|
||||
entity.draw(m_camera->getViewProj(), m_camera->getPosition());
|
||||
}
|
||||
ShaderProgram::unbind();
|
||||
// defaultProgram.bind();
|
||||
// for (auto const &entity : m_entities) {
|
||||
// entity.draw(m_camera->getViewProj(), m_camera->getPosition());
|
||||
// }
|
||||
// ShaderProgram::unbind();
|
||||
|
||||
m_postProcessFrameBuffer.unbind();
|
||||
m_postProcessFrameBuffer.drawOnEntireScreen();
|
||||
|
||||
@@ -109,7 +109,7 @@ void Helper::gl_debug_callback(GLenum source,
|
||||
}
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM)
|
||||
Log::logger().debug("\n[OpenGL Debug Message]\n"
|
||||
Log::logger().debug("[OpenGL Debug Message]\n"
|
||||
"Message: {}\n"
|
||||
"Source: {}\n"
|
||||
"Type: {}\n"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "Scene.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include "mesh.h"
|
||||
#include "name.h"
|
||||
#include "transform.h"
|
||||
#include "util/Log.h"
|
||||
@@ -48,13 +50,50 @@ Scene::Scene()
|
||||
Log::logger().info("Hello entity {}!", name);
|
||||
}
|
||||
|
||||
auto mesh_view = m_registry.view<Mesh>();
|
||||
for (auto [entity, mesh] : mesh_view.each()) {
|
||||
Log::logger().info("Convert mesh {}!");
|
||||
|
||||
auto mesh_view = m_registry.view<entt::resource<Mesh>>();
|
||||
for (auto [entity, mesh] : mesh_view.each()) {
|
||||
m_registry.emplace<GpuMesh>(entity, GpuMesh{mesh});
|
||||
|
||||
// Remove Mesh resource as it is no longer needed.
|
||||
m_registry.erase<entt::resource<Mesh>>(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::update(std::chrono::duration<float> delta)
|
||||
void Scene::update(std::chrono::duration<float> delta,
|
||||
ShaderProgram *shaderprogram,
|
||||
glm::mat4 viewProjMatrix,
|
||||
glm::vec3 viewPosition)
|
||||
{
|
||||
auto mesh_view = m_registry.view<GpuMesh, Transform>();
|
||||
for (auto [entity, mesh, transform] : mesh_view.each()) {
|
||||
shaderprogram->bind();
|
||||
|
||||
// Bind modelview matrix uniform
|
||||
{
|
||||
// Translate * Rotate * Scale * vertex_vec;
|
||||
// First scaling, then rotation, then translation
|
||||
|
||||
// Translate
|
||||
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), transform.translation);
|
||||
|
||||
// Rotate
|
||||
glm::mat4 rotationMatrix = glm::toMat4(transform.rotation);
|
||||
|
||||
// Scale
|
||||
glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), transform.scale);
|
||||
|
||||
glm::mat4 modelMatrix = translationMatrix * rotationMatrix * scaleMatrix;
|
||||
|
||||
glm::mat4 modelViewProj = viewProjMatrix * modelMatrix;
|
||||
shaderprogram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
// shaderprogram->setUniform("u_modelMatrix", modelMatrix);
|
||||
// shaderprogram->setUniform("u_viewPosition", viewPosition);
|
||||
}
|
||||
|
||||
glBindVertexArray(mesh.vao);
|
||||
glDrawElements(GL_TRIANGLES, mesh.indices_count, mesh.indices_type, nullptr);
|
||||
glBindVertexArray(0);
|
||||
|
||||
ShaderProgram::unbind();
|
||||
}
|
||||
}
|
||||
|
||||
13
src/Scene.h
13
src/Scene.h
@@ -1,18 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "mesh.h"
|
||||
#include "material.h"
|
||||
#include "gltf_loader.h"
|
||||
#include "material.h"
|
||||
#include "mesh.h"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <chrono>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
class ShaderProgram;
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene();
|
||||
|
||||
void update(std::chrono::duration<float> delta);
|
||||
void update(std::chrono::duration<float> delta,
|
||||
ShaderProgram *shaderprogram,
|
||||
glm::mat4 viewProjMatrix,
|
||||
glm::vec3 viewPosition);
|
||||
|
||||
private:
|
||||
entt::registry m_registry;
|
||||
|
||||
@@ -8,7 +8,7 @@ static auto create_vertex_attribute_data(std::span<uint8_t const> vertex_attribu
|
||||
-> VertexAttributeData
|
||||
{
|
||||
T attribute_data;
|
||||
attribute_data.reserve(vertex_attribute_data.size_bytes());
|
||||
attribute_data.resize(vertex_attribute_data.size_bytes());
|
||||
|
||||
std::memcpy(
|
||||
attribute_data.data(), vertex_attribute_data.data(), vertex_attribute_data.size_bytes());
|
||||
@@ -20,7 +20,7 @@ template <typename T>
|
||||
static auto create_indices(std::span<uint8_t const> gltf_index_data) -> Indices
|
||||
{
|
||||
T index_data;
|
||||
index_data.reserve(gltf_index_data.size_bytes());
|
||||
index_data.resize(gltf_index_data.size_bytes());
|
||||
|
||||
std::memcpy(index_data.data(), gltf_index_data.data(), gltf_index_data.size_bytes());
|
||||
|
||||
@@ -105,7 +105,7 @@ static auto load_material(fx::gltf::Material const &material,
|
||||
|
||||
static auto load_attribute(std::string_view attribute_name,
|
||||
uint32_t attribute_id,
|
||||
fx::gltf::Document const &gltf) -> std::optional<VertexAttributeData>
|
||||
fx::gltf::Document const &gltf) -> std::optional<std::pair<std::size_t,VertexAttributeData>>
|
||||
{
|
||||
auto const &attribute_accessor = gltf.accessors.at(attribute_id);
|
||||
|
||||
@@ -165,13 +165,12 @@ static auto load_attribute(std::string_view attribute_name,
|
||||
std::terminate();
|
||||
}();
|
||||
|
||||
return std::move(vertex_attribute_data);
|
||||
return std::make_pair(vertex_attribute_id.value(), std::move(vertex_attribute_data));
|
||||
}
|
||||
|
||||
auto load_gltf_primitive(fx::gltf::Primitive const &gltf_primitive,
|
||||
fx::gltf::Document const &gltf,
|
||||
std::filesystem::path const &document_path,
|
||||
unsigned primitive_id,
|
||||
std::string_view primitive_identifier,
|
||||
entt::resource_cache<Material> &material_cache,
|
||||
entt::resource_cache<Mesh> &mesh_cache) -> GltfPrimitive
|
||||
{
|
||||
@@ -188,13 +187,13 @@ auto load_gltf_primitive(fx::gltf::Primitive const &gltf_primitive,
|
||||
|
||||
std::map<Mesh::VertexAttributeId, VertexAttributeData> attributes;
|
||||
for (auto const &attribute : gltf_primitive.attributes) {
|
||||
auto vertex_attribute_data = load_attribute(attribute.first, attribute.second, gltf);
|
||||
auto vertex_attribute = load_attribute(attribute.first, attribute.second, gltf);
|
||||
|
||||
if (!vertex_attribute_data.has_value()) {
|
||||
if (!vertex_attribute.has_value()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
attributes.emplace(attribute.second, std::move(vertex_attribute_data.value()));
|
||||
attributes.emplace(vertex_attribute.value().first, std::move(vertex_attribute.value().second));
|
||||
}
|
||||
|
||||
// Load indices
|
||||
@@ -206,11 +205,10 @@ auto load_gltf_primitive(fx::gltf::Primitive const &gltf_primitive,
|
||||
std::span<uint8_t const> indices_data_span =
|
||||
indices_buffer_span.subspan(indices_buffer_view.byteOffset, indices_buffer_view.byteLength);
|
||||
|
||||
auto indices = [indices_data_span, &indices_accessor]() {
|
||||
Indices indices = [indices_data_span, &indices_accessor]() {
|
||||
if (indices_accessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedByte) {
|
||||
return create_indices<Indices::UnsignedByte>(indices_data_span);
|
||||
}
|
||||
|
||||
if (indices_accessor.componentType == fx::gltf::Accessor::ComponentType::UnsignedShort) {
|
||||
return create_indices<Indices::UnsignedShort>(indices_data_span);
|
||||
}
|
||||
@@ -222,12 +220,10 @@ auto load_gltf_primitive(fx::gltf::Primitive const &gltf_primitive,
|
||||
std::terminate();
|
||||
}();
|
||||
|
||||
std::string const mesh_name =
|
||||
document_path.string() + ".primitive." + std::to_string(primitive_id);
|
||||
entt::hashed_string const mesh_hash(mesh_name.c_str());
|
||||
entt::hashed_string const mesh_hash(primitive_identifier.data());
|
||||
|
||||
entt::resource<Mesh> mesh =
|
||||
mesh_cache.load(mesh_hash, Mesh{.attributes = attributes, .indices = indices})
|
||||
mesh_cache.load(mesh_hash, Mesh{.attributes = attributes, .indices = std::move(indices)})
|
||||
.first->second;
|
||||
|
||||
// Get material by hash
|
||||
@@ -274,8 +270,13 @@ auto GltfLoader::operator()(std::filesystem::path const &document_path) -> resul
|
||||
primitives.reserve(gltf_mesh.primitives.size());
|
||||
|
||||
for (auto const &gltf_primitive : gltf_mesh.primitives) {
|
||||
std::string const primitive_identifier = document_path.string() + "." + gltf_mesh.name +
|
||||
"." + ".primitive." +
|
||||
std::to_string(primitive_count);
|
||||
|
||||
primitives.push_back(load_gltf_primitive(
|
||||
gltf_primitive, gltf, document_path, primitive_count, material_cache, mesh_cache));
|
||||
gltf_primitive, gltf, primitive_identifier, material_cache, mesh_cache));
|
||||
++primitive_count;
|
||||
}
|
||||
|
||||
if (gltf_mesh.name.empty()) {
|
||||
@@ -296,13 +297,10 @@ auto GltfLoader::operator()(std::filesystem::path const &document_path) -> resul
|
||||
for (std::size_t i = 0; i < gltf.nodes.size(); ++i) {
|
||||
auto const &node = gltf.nodes.at(i);
|
||||
|
||||
auto mesh = [this, &node, &gltf]() -> std::optional<entt::resource<GltfMesh>> {
|
||||
auto mesh = [this, &node, &gltf_meshes]() -> std::optional<entt::resource<GltfMesh>> {
|
||||
if (node.mesh != -1) {
|
||||
// Get mesh by hash
|
||||
auto const &gltf_mesh = gltf.meshes.at(node.mesh);
|
||||
entt::hashed_string mesh_hash(gltf_mesh.name.c_str());
|
||||
entt::resource<GltfMesh> mesh = gltf_mesh_cache[mesh_hash];
|
||||
return {mesh};
|
||||
auto const &gltf_mesh = gltf_meshes.at(node.mesh);
|
||||
return {gltf_mesh};
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
85
src/mesh.cpp
85
src/mesh.cpp
@@ -1,30 +1,81 @@
|
||||
#include "mesh.h"
|
||||
#include "util/Log.h"
|
||||
|
||||
#include <exception>
|
||||
|
||||
GpuMesh::GpuMesh(Mesh const &mesh)
|
||||
{
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
// Vertex attributes
|
||||
for (auto const &[attribute_id, attribute_data] : mesh.attributes) {
|
||||
// BUG: https://github.com/llvm/llvm-project/issues/48582
|
||||
auto attr_id = attribute_id;
|
||||
|
||||
std::visit([=](auto&& arg) {
|
||||
GLuint vbo{};
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, arg.size(), arg.data(), GL_STATIC_DRAW);
|
||||
GLuint vbo{};
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
||||
glEnableVertexAttribArray(attr_id);
|
||||
glVertexAttribPointer(
|
||||
attr_id,
|
||||
accessor_byte_size(position_accessor.type),
|
||||
static_cast<GLenum>(position_accessor.componentType),
|
||||
position_accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||
position_buffer_view.byteStride,
|
||||
reinterpret_cast<void *>(
|
||||
position_accessor
|
||||
.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
// performance-no-int-to-ptr)
|
||||
}
|
||||
std::visit(
|
||||
[attr_id](auto &&arg) {
|
||||
glBufferData(GL_ARRAY_BUFFER, arg.size(), arg.data(), GL_STATIC_DRAW);
|
||||
|
||||
int const components = [arg]() -> int {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, VertexAttributeData::Scalar>) {
|
||||
return 1;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, VertexAttributeData::Vec2>) {
|
||||
return 2;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, VertexAttributeData::Vec3>) {
|
||||
return 3;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, VertexAttributeData::Vec4>) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::terminate();
|
||||
}();
|
||||
|
||||
glEnableVertexAttribArray(attr_id);
|
||||
glVertexAttribPointer(
|
||||
attr_id,
|
||||
components,
|
||||
GL_FLOAT, // static_cast<GLenum>(position_accessor.componentType),
|
||||
false, // position_accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||
0,
|
||||
nullptr);
|
||||
},
|
||||
attribute_data.values);
|
||||
}
|
||||
|
||||
// Indices
|
||||
GLuint ebo{};
|
||||
glGenBuffers(1, &ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
std::visit(
|
||||
[this](auto &&arg) {
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, arg.size(), arg.data(), GL_STATIC_DRAW);
|
||||
|
||||
indices_count = arg.size();
|
||||
indices_type = [arg]() -> GLenum {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, Indices::UnsignedByte>) {
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, Indices::UnsignedShort>) {
|
||||
return GL_UNSIGNED_SHORT;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, Indices::UnsignedInt>) {
|
||||
return GL_UNSIGNED_INT;
|
||||
}
|
||||
|
||||
std::terminate();
|
||||
}();
|
||||
},
|
||||
mesh.indices.values);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
16
src/mesh.h
16
src/mesh.h
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <glad/gl.h>
|
||||
#include <map>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
struct VertexAttributeData
|
||||
{
|
||||
@@ -45,11 +45,20 @@ struct GpuMesh
|
||||
GpuMesh(GpuMesh const &) = delete;
|
||||
auto operator=(GpuMesh const &) -> GpuMesh & = delete;
|
||||
|
||||
GpuMesh(GpuMesh &&other) noexcept : vao(other.vao) { other.vao = 0; }
|
||||
GpuMesh(GpuMesh &&other) noexcept
|
||||
: vao(other.vao), indices_count(other.indices_count), indices_type(other.indices_type)
|
||||
{
|
||||
other.vao = 0;
|
||||
}
|
||||
auto operator=(GpuMesh &&other) noexcept -> GpuMesh &
|
||||
{
|
||||
vao = other.vao;
|
||||
indices_count = other.indices_count;
|
||||
indices_type = other.indices_type;
|
||||
|
||||
// Deinitialize other
|
||||
other.vao = 0;
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -57,4 +66,7 @@ struct GpuMesh
|
||||
|
||||
// TODO: also store vertex buffers.
|
||||
GLuint vao{};
|
||||
|
||||
GLsizei indices_count{};
|
||||
GLenum indices_type{};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user