diff --git a/src/buffer.cpp b/src/buffer.cpp index 3bdede9..92b3006 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -27,21 +27,8 @@ Buffer::Buffer(const std::vector& vertices, glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW); - // Attribute 0: position (vec3) - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(0)); - glEnableVertexAttribArray(0); - - // Attribute 1: color (vec3) - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(sizeof(glm::vec3))); - glEnableVertexAttribArray(1); - - // Attribute 2: tex_coord (vec2) - glVertexAttribPointer( - 2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), - reinterpret_cast(sizeof(glm::vec3) * 2)); - glEnableVertexAttribArray(2); + // Note: Vertex attributes are set up by Shader::setup_attribs() during rendering + // This allows the shader to dynamically query and set the correct attribute locations Logger::info(sstr("Buffer created with ", vertices.size(), " vertices and ", indices.size(), " indices")); diff --git a/src/mesh.cpp b/src/mesh.cpp index 0ef345d..869f38b 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -30,46 +30,51 @@ Vertex create_vertex(const tinyobj::attrib_t& attrib, Vertex vertex; // Position - vertex.position.x = attrib.vertices[3 * idx.vertex_index + 0]; - vertex.position.y = attrib.vertices[3 * idx.vertex_index + 1]; - vertex.position.z = attrib.vertices[3 * idx.vertex_index + 2]; + if (idx.vertex_index >= 0) { + vertex.position.x = attrib.vertices[3 * idx.vertex_index + 0]; + vertex.position.y = attrib.vertices[3 * idx.vertex_index + 1]; + vertex.position.z = attrib.vertices[3 * idx.vertex_index + 2]; + } // Color (default to white) vertex.color = glm::vec3(1.0f, 1.0f, 1.0f); - // Texture coordinates + // Texture coordinates (default to 0,0) + vertex.tex_coord = glm::vec2(0.0f, 0.0f); if (idx.texcoord_index >= 0) { vertex.tex_coord.x = attrib.texcoords[2 * idx.texcoord_index + 0]; - vertex.tex_coord.y = 1.0f - - attrib.texcoords[2 * idx.texcoord_index + 1]; // Flip Y + vertex.tex_coord.y = + attrib.texcoords[2 * idx.texcoord_index + 1]; // No Y-flip } return vertex; } -void group_vertices_by_material( - const tinyobj::shape_t& shape, const tinyobj::attrib_t& attrib, - std::unordered_map>& out_vertices, - std::unordered_map>& out_indices) +void process_shape_simple(const tinyobj::shape_t& shape, + const tinyobj::attrib_t& attrib, + std::vector& out_vertices, + std::vector& out_indices) { - size_t index_offset = 0; - for (size_t f = 0; f < shape.mesh.num_face_vertices.size(); ++f) { - int fv = shape.mesh.num_face_vertices[f]; - int material_id = shape.mesh.material_ids[f]; + // Process all indices directly - one vertex per index + for (size_t i = 0; i < shape.mesh.indices.size(); ++i) { + const tinyobj::index_t& idx = shape.mesh.indices[i]; + Vertex vertex = create_vertex(attrib, idx); - for (size_t v = 0; v < static_cast(fv); ++v) { - const tinyobj::index_t& idx = - shape.mesh.indices[index_offset + v]; - - Vertex vertex = create_vertex(attrib, idx); - out_vertices[material_id].push_back(vertex); - out_indices[material_id].push_back( - static_cast( - out_vertices[material_id].size() - 1)); + // Debug: Print first 3 vertices + if (i < 3) { + Logger::info(sstr(" Vertex ", i, ": pos(", + vertex.position.x, ",", + vertex.position.y, ",", + vertex.position.z, ") tex(", + vertex.tex_coord.x, ",", + vertex.tex_coord.y, ") texidx=", + idx.texcoord_index)); } - index_offset += fv; + out_vertices.push_back(vertex); + out_indices.push_back( + static_cast(out_vertices.size() - 1)); } } @@ -113,22 +118,26 @@ std::shared_ptr load_material_texture(int material_id, return texture; } -void create_buffers_for_materials( - const std::unordered_map>& material_vertices, - const std::unordered_map>& material_indices, - LoadContext& context, std::shared_ptr& mesh) +// Create a single buffer for the shape with first material +void create_buffer_simple(const tinyobj::shape_t& shape, + const std::vector& vertices, + const std::vector& indices, LoadContext& context, + std::shared_ptr& mesh) { - for (const auto& [material_id, vertices] : material_vertices) { - const auto& indices = material_indices.at(material_id); + auto buffer = std::make_shared(vertices, indices); - auto buffer = std::make_shared(vertices, indices); - auto texture = load_material_texture(material_id, context); - auto material_shader = - context.shader ? context.shader : state::default_shader; - - Material mat(texture, material_shader); - mesh->add_buffer(buffer, mat); + // Use first material ID from the shape + int material_id = -1; + if (!shape.mesh.material_ids.empty() && shape.mesh.material_ids[0] >= 0) { + material_id = shape.mesh.material_ids[0]; } + + auto texture = load_material_texture(material_id, context); + auto material_shader = + context.shader ? context.shader : state::default_shader; + + Material mat(texture, material_shader); + mesh->add_buffer(buffer, mat); } } // namespace @@ -174,15 +183,17 @@ std::shared_ptr Mesh::load(const char* filename, // Process each shape auto mesh = std::make_shared(); for (const auto& shape : shapes) { - Logger::info(sstr("Processing shape: ", shape.name)); + Logger::info(sstr("Processing shape: ", shape.name, " with ", + shape.mesh.indices.size(), " indices")); - std::unordered_map> material_vertices; - std::unordered_map> material_indices; + std::vector vertices; + std::vector indices; - group_vertices_by_material(shape, attrib, material_vertices, - material_indices); - create_buffers_for_materials(material_vertices, - material_indices, context, mesh); + process_shape_simple(shape, attrib, vertices, indices); + create_buffer_simple(shape, vertices, indices, context, mesh); + + Logger::info(sstr("Created buffer with ", vertices.size(), + " vertices")); } Logger::info(sstr("Mesh loaded successfully with ", mesh->num_buffers(),