-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathTextureLoader.cpp
More file actions
66 lines (56 loc) · 2.03 KB
/
TextureLoader.cpp
File metadata and controls
66 lines (56 loc) · 2.03 KB
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
#include "TextureLoader.hpp"
#include "RenderContext.hpp"
#include "Math.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
std::shared_ptr<Texture> loadTexture(const std::filesystem::path &p,
RenderContext &rc) {
stbi_set_flip_vertically_on_load(true);
auto f = stbi__fopen(p.string().c_str(), "rb");
assert(f);
const auto hdr = stbi_is_hdr_from_file(f);
int32_t width, height, numChannels;
auto pixels =
hdr ? (void *)stbi_loadf_from_file(f, &width, &height, &numChannels, 0)
: (void *)stbi_load_from_file(f, &width, &height, &numChannels, 0);
fclose(f);
assert(pixels);
ImageData imageData{
.dataType = static_cast<GLenum>(hdr ? GL_FLOAT : GL_UNSIGNED_BYTE),
.pixels = pixels,
};
PixelFormat pixelFormat{PixelFormat::Unknown};
switch (numChannels) {
case 1:
imageData.format = GL_RED;
pixelFormat = PixelFormat::R8_UNorm;
break;
case 3:
imageData.format = GL_RGB;
pixelFormat = hdr ? PixelFormat::RGB16F : PixelFormat::RGB8_UNorm;
break;
case 4:
imageData.format = GL_RGBA;
pixelFormat = hdr ? PixelFormat::RGBA16F : PixelFormat::RGBA8_UNorm;
break;
default:
assert(false);
}
uint32_t numMipLevels{1u};
if (isPowerOf2(width) && isPowerOf2(height))
numMipLevels = calcMipLevels(glm::max(width, height));
auto texture = rc.createTexture2D(
{static_cast<uint32_t>(width), static_cast<uint32_t>(height)}, pixelFormat,
numMipLevels);
rc.upload(texture, 0, {width, height}, imageData)
.setupSampler(texture, {
.minFilter = TexelFilter::Linear,
.mipmapMode = MipmapMode::Linear,
.magFilter = TexelFilter::Linear,
.maxAnisotropy = 16.0f,
});
stbi_image_free(pixels);
if (numMipLevels > 1) rc.generateMipmaps(texture);
return std::shared_ptr<Texture>(new Texture{std::move(texture)},
RenderContext::ResourceDeleter{rc});
}