| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #include "vk_mesh.h"
- #include <tiny_obj_loader.h>
- #include <iostream>
- using namespace Coral3D;
- VertexInputDescription Vertex::get_vert_desc()
- {
- VertexInputDescription desc;
- // We only have one vertex buffer binding, with a per-vertex rate
- VkVertexInputBindingDescription mainBinding{};
- mainBinding.binding = 0;
- mainBinding.stride = sizeof(Vertex);
- mainBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
- desc.bindings.emplace_back(mainBinding);
- // Position will be stored at Location 0
- VkVertexInputAttributeDescription positionAttribute{};
- positionAttribute.binding = 0;
- positionAttribute.location = 0;
- positionAttribute.format = VK_FORMAT_R32G32B32_SFLOAT;
- positionAttribute.offset = offsetof(Vertex, position);
- // Normal will be stored at Location 1
- VkVertexInputAttributeDescription normalAttribute{};
- normalAttribute.binding = 0;
- normalAttribute.location = 1;
- normalAttribute.format = VK_FORMAT_R32G32B32_SFLOAT;
- normalAttribute.offset = offsetof(Vertex, normal);
- // Color will be stored at Location 2
- VkVertexInputAttributeDescription colorAttribute{};
- colorAttribute.binding = 0;
- colorAttribute.location = 2;
- colorAttribute.format = VK_FORMAT_R32G32B32_SFLOAT;
- colorAttribute.offset = offsetof(Vertex, color);
- // UV will be stored at Location 3
- VkVertexInputAttributeDescription uvAttribute{};
- uvAttribute.binding = 0;
- uvAttribute.location = 3;
- uvAttribute.format = VK_FORMAT_R32G32_SFLOAT;
- uvAttribute.offset = offsetof(Vertex, uv);
- desc.attributes.emplace_back(positionAttribute);
- desc.attributes.emplace_back(normalAttribute);
- desc.attributes.emplace_back(colorAttribute);
- desc.attributes.emplace_back(uvAttribute);
- return desc;
- }
- bool Mesh::load_from_obj(const char* filename)
- {
- // attrib will contain the vertex arrays of the file
- tinyobj::attrib_t attrib;
- // shapes contains the info for each separate object in the file
- std::vector<tinyobj::shape_t> shapes;
- // materials contains the information about the material of each shape, not yet used.
- std::vector<tinyobj::material_t> materials;
- // error and warning output from the load function
- std::string warn;
- std::string err;
- // load the OBJ file
- tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename);
- //make sure to output the warnings to the console, in case there are issues with the file
- if (!warn.empty())
- {
- std::cout << "WARNING! Mesh::load_from_obj() >> " << warn << std::endl;
- }
- //if we have any error, print it to the console, and break the mesh loading.
- //This happens if the file can't be found or is malformed
- if (!err.empty())
- {
- std::cerr << err << std::endl;
- return false;
- }
- // Loop over shapes
- for (size_t s = 0; s < shapes.size(); s++)
- {
- // Loop over faces(polygon)
- size_t index_offset = 0;
- for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++)
- {
- //hardcode loading to triangles
- int fv = 3;
- // Loop over vertices in the face.
- for (size_t v = 0; v < fv; v++)
- {
- // access to vertex
- tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
- //vertex position
- tinyobj::real_t vx = attrib.vertices[3 * idx.vertex_index + 0];
- tinyobj::real_t vy = attrib.vertices[3 * idx.vertex_index + 1];
- tinyobj::real_t vz = attrib.vertices[3 * idx.vertex_index + 2];
- //vertex normal
- tinyobj::real_t nx = attrib.normals[3 * idx.normal_index + 0];
- tinyobj::real_t ny = attrib.normals[3 * idx.normal_index + 1];
- tinyobj::real_t nz = attrib.normals[3 * idx.normal_index + 2];
- //copy it into our vertex
- Vertex new_vert;
- new_vert.position.x = vx;
- new_vert.position.y = vy;
- new_vert.position.z = vz;
- new_vert.normal.x = nx;
- new_vert.normal.y = ny;
- new_vert.normal.z = nz;
- //we are setting the vertex color as the vertex normal. This is just for display purposes
- new_vert.color = new_vert.normal;
- tinyobj::real_t ux{attrib.texcoords[2 * idx.texcoord_index + 0]};
- tinyobj::real_t uy{attrib.texcoords[2 * idx.texcoord_index + 1]};
- new_vert.uv = { ux, 1 - uy };
- vertices.push_back(new_vert);
- }
- index_offset += fv;
- }
- }
- return true;
- }
|