fix: texture prasing
This commit is contained in:
		| @@ -27,21 +27,8 @@ Buffer::Buffer(const std::vector<Vertex>&   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<void*>(0)); | ||||
| 	glEnableVertexAttribArray(0); | ||||
|  | ||||
| 	// Attribute 1: color (vec3) | ||||
| 	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), | ||||
| 			      reinterpret_cast<void*>(sizeof(glm::vec3))); | ||||
| 	glEnableVertexAttribArray(1); | ||||
|  | ||||
| 	// Attribute 2: tex_coord (vec2) | ||||
| 	glVertexAttribPointer( | ||||
| 	    2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), | ||||
| 	    reinterpret_cast<void*>(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")); | ||||
|   | ||||
							
								
								
									
										99
									
								
								src/mesh.cpp
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								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<int, std::vector<Vertex>>&   out_vertices, | ||||
|     std::unordered_map<int, std::vector<uint16_t>>& out_indices) | ||||
| void process_shape_simple(const tinyobj::shape_t&   shape, | ||||
| 			  const tinyobj::attrib_t& attrib, | ||||
| 			  std::vector<Vertex>&	   out_vertices, | ||||
| 			  std::vector<uint16_t>&   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<size_t>(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<uint16_t>( | ||||
| 				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<uint16_t>(out_vertices.size() - 1)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -113,22 +118,26 @@ std::shared_ptr<Texture> load_material_texture(int	    material_id, | ||||
| 	return texture; | ||||
| } | ||||
|  | ||||
| void create_buffers_for_materials( | ||||
|     const std::unordered_map<int, std::vector<Vertex>>&	  material_vertices, | ||||
|     const std::unordered_map<int, std::vector<uint16_t>>& material_indices, | ||||
|     LoadContext& context, std::shared_ptr<Mesh>& mesh) | ||||
| // Create a single buffer for the shape with first material | ||||
| void create_buffer_simple(const tinyobj::shape_t&	shape, | ||||
| 			  const std::vector<Vertex>&	vertices, | ||||
| 			  const std::vector<uint16_t>& indices, LoadContext& context, | ||||
| 			  std::shared_ptr<Mesh>& mesh) | ||||
| { | ||||
| 	for (const auto& [material_id, vertices] : material_vertices) { | ||||
| 		const auto& indices = material_indices.at(material_id); | ||||
| 	auto buffer = std::make_shared<Buffer>(vertices, indices); | ||||
|  | ||||
| 		auto buffer  = std::make_shared<Buffer>(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> Mesh::load(const char*			filename, | ||||
| 	// Process each shape | ||||
| 	auto mesh = std::make_shared<Mesh>(); | ||||
| 	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<int, std::vector<Vertex>> material_vertices; | ||||
| 		std::unordered_map<int, std::vector<uint16_t>> material_indices; | ||||
| 		std::vector<Vertex>   vertices; | ||||
| 		std::vector<uint16_t> 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(), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user