-
Notifications
You must be signed in to change notification settings - Fork 1
/
textures.cpp
130 lines (122 loc) · 5.14 KB
/
textures.cpp
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "gpu.h"
#include "sys.h"
#include "misc.h"
#include "materials.h"
#include <vector>
#include <utility>
#include <stb_image.h>
#include <iostream>
#include <assert.h>
#include <glm/vec2.hpp>
#include <fmt/format.h>
namespace cw::textures {
GLuint x256_array = 0;
GLuint x512_array = 0;
GLuint x1024_array = 0;
std::map<std::string, int> x256_indices;
std::map<std::string, int> x512_indices;
std::map<std::string, int> x1024_indices;
void load_all();
void load_general();
void print_debug_info();
}
void cw::textures::load_all() {
load_general();
print_debug_info();
}
void cw::textures::load_general() {
auto items = misc::map_file_names_and_extensions(sys::bin_path().string() + "texture\\object");
if (!items) return;
std::map<std::string, std::pair<std::vector<char>, glm::ivec2>> textures_256, textures_512, textures_1024;
for (auto &item : *items) {
auto texture_path = fmt::format("{}texture\\object\\{}.png", sys::bin_path().string(), item.first);
auto texture_file_contents = misc::read_file(texture_path);
if (!texture_file_contents) continue;
int w, h, channels;
unsigned char *image = stbi_load_from_memory(
reinterpret_cast<unsigned char *>(texture_file_contents->data()),
texture_file_contents->size(),
&w, &h, &channels, STBI_rgb
);
if (!image) {
std::cout << "Unable to recognize file \"" << texture_path << "\" as an image." << std::endl;
continue;
}
if (w == 256 && h == 256) {
textures_256[item.first].first.resize(w * h * 3);
textures_256[item.first].second = { w, h };
memcpy(textures_256[item.first].first.data(), image, w * h * 3);
} else if (w == 512 && h == 512) {
textures_512[item.first].first.resize(w * h * 3);
textures_512[item.first].second = { w, h };
memcpy(textures_512[item.first].first.data(), image, w * h * 3);
} else if (w == 1024 && h == 1024) {
textures_1024[item.first].first.resize(w * h * 3);
textures_1024[item.first].second = { w, h };
memcpy(textures_1024[item.first].first.data(), image, w * h * 3);
} else {
std::cout << "Texture within \"" << texture_path << "\" is an unsupported size. (" << w << " by " << h << ")" << std::endl;
}
stbi_image_free(image);
}
if (x256_array) glDeleteTextures(1, &x256_array);
if (x512_array) glDeleteTextures(1, &x512_array);
if (x1024_array) glDeleteTextures(1, &x1024_array);
glGenTextures(1, &x256_array);
assert(x256_array);
glGenTextures(1, &x512_array);
assert(x512_array);
glGenTextures(1, &x1024_array);
assert(x1024_array);
glBindTexture(GL_TEXTURE_2D_ARRAY, x256_array);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB8, 256, 256, textures_256.size(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLint z_offset = 0;
for (auto &image : textures_256) {
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY, 0, 0, 0,
z_offset, image.second.second.x, image.second.second.y, 1,
GL_RGB, GL_UNSIGNED_BYTE, image.second.first.data());
x256_indices[image.first] = z_offset;
z_offset++;
}
glBindTexture(GL_TEXTURE_2D_ARRAY, x512_array);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB8, 512, 512, textures_512.size(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
z_offset = 0;
for (auto &image : textures_512) {
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY, 0, 0, 0,
z_offset, image.second.second.x, image.second.second.y, 1,
GL_RGB, GL_UNSIGNED_BYTE, image.second.first.data());
x512_indices[image.first] = z_offset;
z_offset++;
}
glBindTexture(GL_TEXTURE_2D_ARRAY, x1024_array);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB8, 1024, 1024, textures_1024.size(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
z_offset = 0;
for (auto &image : textures_1024) {
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY, 0, 0, 0,
z_offset, image.second.second.x, image.second.second.y, 1,
GL_RGB, GL_UNSIGNED_BYTE, image.second.first.data());
x512_indices[image.first] = z_offset;
z_offset++;
}
}
void cw::textures::print_debug_info() {
std::cout << "Loaded " << x256_indices.size() << " x256, " << x512_indices.size() << " x512, " << x1024_indices.size() << " x1024 textures." << std::endl;
for (auto &e : x256_indices) std::cout << " x256[" << e.second << "] <- " << e.first << std::endl;
for (auto &e : x512_indices) std::cout << " x512[" << e.second << "] <- " << e.first << std::endl;
for (auto &e : x1024_indices) std::cout << " x1024[" << e.second << "] <- " << e.first << std::endl;
}