diff options
author | Frederico Linhares <fred@linhares.blue> | 2023-06-23 20:45:23 -0300 |
---|---|---|
committer | Frederico Linhares <fred@linhares.blue> | 2023-06-28 10:43:13 -0300 |
commit | 8cb751ff015271e1844feece5db2113eaec64af3 (patch) | |
tree | cd6c698f46408d3b19d4eaea2547efaf3c651a1a /src/vk | |
parent | 66eed8b7548c3e772d3bcb0d351608f0df81ecaf (diff) |
feat Create an interface to read binary files
* test/meshes/cube.cgmesh: Store data using Big-Endian order.
Diffstat (limited to 'src/vk')
-rw-r--r-- | src/vk/mesh.cpp | 45 | ||||
-rw-r--r-- | src/vk/qoi.cpp | 85 |
2 files changed, 31 insertions, 99 deletions
diff --git a/src/vk/mesh.cpp b/src/vk/mesh.cpp index 70b9d45..9afeac3 100644 --- a/src/vk/mesh.cpp +++ b/src/vk/mesh.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2022 Frederico de Oliveira Linhares + * Copyright 2022-2023 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,7 @@ #include "mesh.hpp" -#include <array> -#include <fstream> - +#include "../binary_reader.hpp" #include "../command.hpp" #include "../core.hpp" #include "vertex_3d.hpp" @@ -48,51 +46,26 @@ MeshBuilder::MeshBuilder(VK::Mesh *m, const char *mp): { } -uint32_t read_uint32_from_file(std::ifstream &input_file) -{ - uint32_t data{}; - input_file.read((char*)&data, sizeof(uint32_t)); - return data; -} - -glm::vec2 read_vec2_from_file(std::ifstream &input_file) -{ - glm::vec2 data{}; - input_file.read((char*)&data.x, sizeof(glm::vec2::value_type)); - input_file.read((char*)&data.y, sizeof(glm::vec2::value_type)); - return data; -} - -glm::vec3 read_vec3_from_file(std::ifstream &input_file) -{ - glm::vec3 data{}; - input_file.read((char*)&data.x, sizeof(glm::vec3::value_type)); - input_file.read((char*)&data.y, sizeof(glm::vec3::value_type)); - input_file.read((char*)&data.z, sizeof(glm::vec3::value_type)); - return data; -} - void load_mesh(void *obj) { auto self = static_cast<MeshBuilder*>(obj); - std::ifstream input_file{self->mesh_path}; - if(!input_file.is_open()) throw CommandError{"Failed to open file."}; + BinaryReader input{self->mesh_path}; self->mesh->queue_family = cg_core.vk_device_with_swapchain->get_queue_family_with_graphics(); // Load vertexes. { - auto vertex_count{read_uint32_from_file(input_file)}; + auto vertex_count{input.read_ui32()}; std::vector<VK::Vertex3D> vertexes{vertex_count}; for(auto i{0}; i < vertex_count; i++) { - vertexes[i].position = read_vec3_from_file(input_file); - vertexes[i].normal = read_vec3_from_file(input_file); - vertexes[i].texture_coord = read_vec2_from_file(input_file); + vertexes[i].position = input.read_vec3(); + vertexes[i].normal = input.read_vec3(); + vertexes[i].texture_coord = input.read_vec2(); } void *vertexes_data{vertexes.data()}; @@ -106,11 +79,11 @@ load_mesh(void *obj) // Load indexes. { - self->mesh->index_count = read_uint32_from_file(input_file); + self->mesh->index_count = input.read_ui32(); std::vector<uint32_t> indexes(self->mesh->index_count); for(auto i{0}; i < self->mesh->index_count; i++) - indexes[i] = read_uint32_from_file(input_file); + indexes[i] = input.read_ui32(); void *indexes_data{indexes.data()}; size_t indexes_size{sizeof(indexes[0]) * indexes.size()}; diff --git a/src/vk/qoi.cpp b/src/vk/qoi.cpp index 8b7ef9e..4e2b2a4 100644 --- a/src/vk/qoi.cpp +++ b/src/vk/qoi.cpp @@ -19,6 +19,8 @@ #include <array> #include <fstream> +#include "../binary_reader.hpp" + namespace { @@ -88,26 +90,6 @@ color_hash(const RGBA &colors) return colors.red*3 + colors.green*5 + colors.blue*7 + colors.alpha*11; } -void -read_chars(uint8_t *data, int &p, char *str, int size) -{ - for(int i{0}; i < size; i++) str[i] = (char)data[p++]; -} - -void -read_ui8(uint8_t *data, int &p, uint8_t &num) -{ - num = data[p++]; -} - -void -read_ui32(uint8_t *data, int &p, uint32_t &num) -{ - uint8_t b1{data[p++]}, b2{data[p++]}, b3{data[p++]}, b4{data[p++]}; - - num = b1 << 24 | b2 << 16 | b3 << 8 | b4; -} - } namespace VK::QOI @@ -116,38 +98,22 @@ namespace VK::QOI Image::Image(const char *file_path, uint8_t channels): channels{channels} { - int data_p{0}; - int data_size; - uint8_t *data; - if(this->channels != 0 && this->channels != 3 && this->channels != 4) { throw std::invalid_argument{"invalid number of channels"}; } - { // Read data from file. - std::ifstream file(file_path, std::ios::binary | std::ios::ate); - if(!file) - { - throw std::runtime_error{"failed to open QOI file"}; - } - - data_size = file.tellg(); - if(data_size < HEADER_SIZE + (int)sizeof(PADDING)) - { - throw std::runtime_error{"invalid QOI file"}; - } - - file.seekg(0); - data = new uint8_t[data_size]; - file.read((char*)data, data_size); + BinaryReader input{file_path}; + if(input.size() < HEADER_SIZE + (int)sizeof(PADDING)) + { + throw std::runtime_error{"invalid QOI file"}; } - read_chars(data, data_p, this->header.magic, 4); - read_ui32(data, data_p, this->header.width); - read_ui32(data, data_p, this->header.height); - read_ui8(data, data_p, this->header.channels); - read_ui8(data, data_p, this->header.colorspace); + input.read_chars(this->header.magic, 4); + this->header.width = input.read_ui32(); + this->header.height = input.read_ui32(); + this->header.channels = input.read_ui8(); + this->header.colorspace = input.read_ui8(); if(this->header.width == 0 || this->header.height == 0 || this->header.channels < 3 || this->header.channels > 4 || @@ -165,7 +131,7 @@ Image::Image(const char *file_path, uint8_t channels): std::array<Pixel, 64> index; Pixel pixel{}; - int chunks_len = data_size - (int)sizeof(PADDING); + int chunks_len = input.size() - (int)sizeof(PADDING); /* This algorithm is based on the original implementation that is in GitHub: @@ -181,25 +147,22 @@ Image::Image(const char *file_path, uint8_t channels): { run--; } - else if(data_p < chunks_len) + else if(input.pointer() < chunks_len) { - uint8_t output; - int b1; - read_ui8(data, data_p, output); - b1 = output; + int b1 = input.read_ui8(); if (b1 == OP_RGB) { - read_ui8(data, data_p, pixel.colors.red); - read_ui8(data, data_p, pixel.colors.green); - read_ui8(data, data_p, pixel.colors.blue); + pixel.colors.red = input.read_ui8(); + pixel.colors.green = input.read_ui8(); + pixel.colors.blue = input.read_ui8(); } else if (b1 == OP_RGBA) { - read_ui8(data, data_p, pixel.colors.red); - read_ui8(data, data_p, pixel.colors.green); - read_ui8(data, data_p, pixel.colors.blue); - read_ui8(data, data_p, pixel.colors.alpha); + pixel.colors.red = input.read_ui8(); + pixel.colors.green = input.read_ui8(); + pixel.colors.blue = input.read_ui8(); + pixel.colors.alpha = input.read_ui8(); } else if ((b1 & MASK_2_BITS) == OP_INDEX) { @@ -213,9 +176,7 @@ Image::Image(const char *file_path, uint8_t channels): } else if ((b1 & MASK_2_BITS) == OP_LUMA) { - int b2; - read_ui8(data, data_p, output); - b2 = output; + int b2 = input.read_ui8(); int vg = (b1 & 0x3f) - 32; pixel.colors.red += vg - 8 + ((b2 >> 4) & 0x0f); pixel.colors.green += vg; @@ -234,8 +195,6 @@ Image::Image(const char *file_path, uint8_t channels): this->pixels[pixel_p++] = pixel.colors.blue; if(this->channels == 4) this->pixels[pixel_p++] = pixel.colors.alpha; } - - delete[] data; } Image::~Image() |