1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "Texture.hpp"
#include "PodVector.hpp"
#include <stb_image.h>
#include <stb_rect_pack.h>
#include <cstdint>
#include <cstring>
#include <deque>
#include <filesystem>
#include <fstream>
#include <stdexcept>
#include <utility>
Texture::~Texture() {
glDeleteTextures(1, &mHandle);
}
static GLenum MapTextureFilteringToGL(Texture::Filtering option) {
switch (option) {
case Texture::LinearFilter: return GL_LINEAR;
case Texture::NearestFilter: return GL_NEAREST;
}
return 0;
}
bool Texture::InitFromFile(const char* filePath, const TextureProperties& props, bool flipVertically) {
int width, height;
int channels;
stbi_set_flip_vertically_on_load(flipVertically);
auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, 4);
if (!result) {
return false;
}
glDeleteTextures(1, &mHandle); // In case the caller gave us
glGenTextures(1, &mHandle);
glBindTexture(GL_TEXTURE_2D, mHandle);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result);
mInfo.size = { width, height };
mInfo.isAtlas = false;
return true;
}
// bool Texture::InitFromImage(const Image& image, const TextureProperties& props, bool flipVertically) {
// GLenum sourceFormat;
// switch (image.GetChannels()) {
// case 1: sourceFormat = GL_RED; break;
// case 2: sourceFormat = GL_RG; break;
// case 3: sourceFormat = GL_RGB; break;
// case 4: sourceFormat = GL_RGBA; break;
// default: return false;
// }
// auto size = image.GetSize();
// std::unique_ptr<uint8_t[]> dataStorage;
// uint8_t* dataPtr;
// if (flipVertically) {
// dataStorage = std::make_unique<uint8_t[]>(image.GetDataLength());
// dataPtr = dataStorage.get();
// size_t rowStride = size.width * image.GetChannels() * sizeof(uint8_t);
// for (size_t y = 0; y < size.height; ++y) {
// size_t invY = (size.height - 1) - y;
// std::memcpy(dataPtr + invY * rowStride, image.GetDataPtr() + y * rowStride, rowStride);
// }
// } else {
// // dataStorage is unused, we read pixels directly from `image`
// dataPtr = image.GetDataPtr();
// }
// glDeleteTextures(1, &mHandle);
// glGenTextures(1, &mHandle);
// glBindTexture(GL_TEXTURE_2D, mHandle);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter));
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter));
// glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, size.width, size.height, 0, sourceFormat, GL_UNSIGNED_BYTE, dataPtr);
// mInfo.size = size;
// mInfo.isAtlas = false;
// return true;
// }
const TextureInfo& Texture::GetInfo() const {
return mInfo;
}
GLuint Texture::GetHandle() const {
return mHandle;
}
bool Texture::IsValid() const {
return mHandle != 0;
}
|