std::string
LoadObj(
  std::vector<shape_t>& shapes,
  std::vector<material_t>& materials,   // [output]
  const char* filename,
  const char* mtl_basepath)
{

  shapes.clear();

  std::stringstream err;

  std::ifstream ifs(filename);
  if (!ifs) {
    err << "Cannot open file [" << filename << "]" << std::endl;
    return err.str();
  }

  std::string basePath;
  if (mtl_basepath) {
    basePath = mtl_basepath;
  }
  MaterialFileReader matFileReader( basePath );

  return LoadObj(shapes, materials, ifs, matFileReader);
}
Example #2
0
    void prepareVertices()
    {
        // Load mesh from compressed asset
        AAsset* asset = AAssetManager_open(app->activity->assetManager, "models/vulkanlogo.obj", AASSET_MODE_STREAMING);
        assert(asset);
        size_t size = AAsset_getLength(asset);
        assert(size > 0);

        char *assetData = new char[size];
        AAsset_read(asset, assetData, size);
        AAsset_close(asset);

        std::stringstream assetStream(assetData);

        std::vector<tinyobj::shape_t> shapes;
        std::vector<tinyobj::material_t> materials;
        std::string objerr;
        tinyobj::MaterialFileReader matFileReader("");
        bool ret = tinyobj::LoadObj(shapes, materials, objerr, assetStream, matFileReader, true);

        LOGW("shapes %d", shapes.size());

        // Setup vertices
        float scale = 0.025f;
        std::vector<Vertex> vertexBuffer;
        std::vector<uint32_t> indexBuffer;
        for (auto& shape : shapes)
        {
            // Vertices
            for (size_t i = 0; i < shape.mesh.positions.size() / 3; i++)
            {
                Vertex v;
                v.pos[0] = shape.mesh.positions[3 * i + 0] * scale;
                v.pos[1] = -shape.mesh.positions[3 * i + 1] * scale;
                v.pos[2] = shape.mesh.positions[3 * i + 2] * scale;
                v.normal[0] = shape.mesh.normals[3 * i + 0];
                v.normal[1] = shape.mesh.normals[3 * i + 1];
                v.normal[2] = shape.mesh.normals[3 * i + 2];
                v.color = glm::vec3(1.0f, 0.0f, 0.0f);
                vertexBuffer.push_back(v);
            }
            // Indices
            for (size_t i = 0; i < shape.mesh.indices.size() / 3; i++)
            {
                indexBuffer.push_back(shape.mesh.indices[3 * i + 0]);
                indexBuffer.push_back(shape.mesh.indices[3 * i + 1]);
                indexBuffer.push_back(shape.mesh.indices[3 * i + 2]);
            }

        }

        uint32_t vertexBufferSize = vertexBuffer.size() * sizeof(Vertex);
        uint32_t indexBufferSize = indexBuffer.size() * sizeof(uint32_t);

        VkMemoryAllocateInfo memAlloc = {};
        memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
        memAlloc.pNext = NULL;
        memAlloc.allocationSize = 0;
        memAlloc.memoryTypeIndex = 0;
        VkMemoryRequirements memReqs;

        VkResult err;
        void *data;

        // Generate vertex buffer
        //	Setup
        VkBufferCreateInfo bufInfo = {};
        bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
        bufInfo.pNext = NULL;
        bufInfo.size = vertexBufferSize;
        bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
        bufInfo.flags = 0;
        //	Copy vertex data to VRAM
        memset(&vertices, 0, sizeof(vertices));
        err = vkCreateBuffer(device, &bufInfo, nullptr, &vertices.buf);
        assert(!err);
        vkGetBufferMemoryRequirements(device, vertices.buf, &memReqs);
        memAlloc.allocationSize = memReqs.size;
        getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAlloc.memoryTypeIndex);
        vkAllocateMemory(device, &memAlloc, nullptr, &vertices.mem);
        assert(!err);
        err = vkMapMemory(device, vertices.mem, 0, memAlloc.allocationSize, 0, &data);
        assert(!err);
        memcpy(data, vertexBuffer.data(), vertexBufferSize);
        vkUnmapMemory(device, vertices.mem);
        assert(!err);
        err = vkBindBufferMemory(device, vertices.buf, vertices.mem, 0);
        assert(!err);

        // Generate index buffer
        //	Setup
        VkBufferCreateInfo indexbufferInfo = {};
        indexbufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
        indexbufferInfo.pNext = NULL;
        indexbufferInfo.size = indexBufferSize;
        indexbufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
        indexbufferInfo.flags = 0;
        // Copy index data to VRAM
        memset(&indices, 0, sizeof(indices));
        err = vkCreateBuffer(device, &bufInfo, nullptr, &indices.buf);
        assert(!err);
        vkGetBufferMemoryRequirements(device, indices.buf, &memReqs);
        memAlloc.allocationSize = memReqs.size;
        getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAlloc.memoryTypeIndex);
        err = vkAllocateMemory(device, &memAlloc, nullptr, &indices.mem);
        assert(!err);
        err = vkMapMemory(device, indices.mem, 0, indexBufferSize, 0, &data);
        assert(!err);
        memcpy(data, indexBuffer.data(), indexBufferSize);
        vkUnmapMemory(device, indices.mem);
        err = vkBindBufferMemory(device, indices.buf, indices.mem, 0);
        assert(!err);
        indices.count = indexBuffer.size();

        // Binding description
        vertices.bindingDescriptions.resize(1);
        vertices.bindingDescriptions[0] =
            vkTools::initializers::vertexInputBindingDescription(
                VERTEX_BUFFER_BIND_ID,
                sizeof(Vertex),
                VK_VERTEX_INPUT_RATE_VERTEX);

        // Attribute descriptions
        // Describes memory layout and shader positions
        vertices.attributeDescriptions.resize(3);
        // Location 0 : Position
        vertices.attributeDescriptions[0] =
            vkTools::initializers::vertexInputAttributeDescription(
                VERTEX_BUFFER_BIND_ID,
                0,
                VK_FORMAT_R32G32B32_SFLOAT,
                0);
        // Location 1 : Normal
        vertices.attributeDescriptions[1] =
            vkTools::initializers::vertexInputAttributeDescription(
                VERTEX_BUFFER_BIND_ID,
                1,
                VK_FORMAT_R32G32B32_SFLOAT,
                sizeof(float) * 3);
        // Location 2 : Color
        vertices.attributeDescriptions[2] =
            vkTools::initializers::vertexInputAttributeDescription(
                VERTEX_BUFFER_BIND_ID,
                2,
                VK_FORMAT_R32G32B32_SFLOAT,
                sizeof(float) * 6);

        // Assign to vertex buffer
        vertices.inputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
        vertices.inputState.pNext = NULL;
        vertices.inputState.vertexBindingDescriptionCount = vertices.bindingDescriptions.size();
        vertices.inputState.pVertexBindingDescriptions = vertices.bindingDescriptions.data();
        vertices.inputState.vertexAttributeDescriptionCount = vertices.attributeDescriptions.size();
        vertices.inputState.pVertexAttributeDescriptions = vertices.attributeDescriptions.data();
    }