Engine²
Open-source game engine written in C++.
Loading...
Searching...
No Matches
Image.hpp
Go to the documentation of this file.
1#pragma once
2
6#include "lodepng.h"
7#include "stb_image.h"
8#include <filesystem>
9#include <functional>
10#include <glm/vec2.hpp>
11#include <glm/vec4.hpp>
12#include <string>
13#include <string_view>
14#include <vector>
15
16namespace Graphic::Resource {
17
18struct Image {
19 uint32_t width = 0;
20 uint32_t height = 0;
21 int channels = 0;
22 std::vector<glm::u8vec4> pixels;
23
24 Image() = default;
25
26 template <typename Callback>
27 explicit Image(const glm::uvec2 &size, Callback callback) : width(size.x), height(size.y), channels(4)
28 {
29 this->pixels.resize(size.x * size.y);
30 for (uint32_t y = 0; y < size.y; ++y)
31 {
32 for (uint32_t x = 0; x < size.x; ++x)
33 {
34 glm::uvec2 pos{x, y};
35 this->pixels[y * size.x + x] = callback(pos);
36 }
37 }
38 }
39
40 explicit Image(const std::filesystem::path &filepath)
41 {
42 // Should we assume the file exists before calling this function?
43 if (std::filesystem::exists(filepath) == false)
44 throw Exception::UnknownFileError("File not found at: " + filepath.string());
45
46 int width_ = -1;
47 int height_ = -1;
48 int channels_ = -1;
49 unsigned char *data = stbi_load(filepath.string().c_str(), &width_, &height_, &channels_, 4);
50
51 if (!data || width_ <= 0 || height_ <= 0 || channels_ <= 0)
52 throw Exception::FileReadingError("Failed to load image data from file: " + filepath.string());
53
54 this->width = static_cast<uint32_t>(width_);
55 this->height = static_cast<uint32_t>(height_);
56 this->channels = 4;
57
58 this->pixels.resize(width_ * height_);
59 for (uint32_t y = 0; y < this->height; ++y)
60 {
61 for (uint32_t x = 0; x < this->width; ++x)
62 {
63 size_t index = y * this->width + x;
64 this->pixels[index] =
65 glm::u8vec4(data[index * 4 + 0], data[index * 4 + 1], data[index * 4 + 2], data[index * 4 + 3]);
66 }
67 }
68
69 stbi_image_free(data);
70 }
71
72 void ToPng(std::string_view filename)
73 {
74 unsigned int error =
75 lodepng::encode(filename.data(), reinterpret_cast<const unsigned char *>(pixels.data()), width, height);
76
77 if (error != 0)
79 fmt::format("Failed to write PNG file '{}': {}", filename, lodepng_error_text(error)));
80 }
81};
82}; // namespace Graphic::Resource
Definition FileReadingError.hpp:7
Definition FileWritingError.hpp:7
Definition UnknownFileError.hpp:7
Definition AGPUBuffer.hpp:6
uint32_t height
Definition Image.hpp:20
void ToPng(std::string_view filename)
Definition Image.hpp:72
uint32_t width
Definition Image.hpp:19
Image(const glm::uvec2 &size, Callback callback)
Definition Image.hpp:27
Image(const std::filesystem::path &filepath)
Definition Image.hpp:40
int channels
Definition Image.hpp:21
std::vector< glm::u8vec4 > pixels
Definition Image.hpp:22