5#define STB_IMAGE_IMPLEMENTATION 1
7#define STBI_NO_LINEAR 1
17#define STBI_NO_THREAD_LOCALS 1
25#define ALICE_DDSD_CAPS 0x00000001
26#define ALICE_DDSD_HEIGHT 0x00000002
27#define ALICE_DDSD_WIDTH 0x00000004
28#define ALICE_DDSD_PITCH 0x00000008
29#define ALICE_DDSD_PIXELFORMAT 0x00001000
30#define ALICE_DDSD_MIPMAPCOUNT 0x00020000
31#define ALICE_DDSD_LINEARSIZE 0x00080000
32#define ALICE_DDSD_DEPTH 0x00800000
35#define ALICE_DDPF_ALPHAPIXELS 0x00000001
36#define ALICE_DDPF_FOURCC 0x00000004
37#define ALICE_DDPF_RGB 0x00000040
41#define ALICE_DDSCAPS_COMPLEX 0x00000008
42#define ALICE_DDSCAPS_TEXTURE 0x00001000
43#define ALICE_DDSCAPS_MIPMAP 0x00400000
47#define ALICE_DDSCAPS2_CUBEMAP 0x00000200
48#define ALICE_DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
49#define ALICE_DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
50#define ALICE_DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
51#define ALICE_DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
52#define ALICE_DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
53#define ALICE_DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
54#define ALICE_DDSCAPS2_VOLUME 0x00200000
56#define SOIL_GL_SRGB 0x8C40
57#define SOIL_GL_SRGB_ALPHA 0x8C42
58#define SOIL_RGB_S3TC_DXT1 0x83F0
59#define SOIL_RGBA_S3TC_DXT1 0x83F1
60#define SOIL_RGBA_S3TC_DXT3 0x83F2
61#define SOIL_RGBA_S3TC_DXT5 0x83F3
63#define SOIL_TEXTURE_WRAP_R 0x8072
64#define SOIL_CLAMP_TO_EDGE 0x812F
65#define SOIL_REFLECTION_MAP 0x8512
76 unsigned int dwReserved1[11];
110 std::memcpy((
void*)(&header), (
void const*)buffer,
sizeof(
DDS_header));
114 if(header.
dwMagic != ((
'D' << 0) | (
'D' << 8) | (
'S' << 16) | (
' ' << 24))) {
117 if(header.
dwSize != 124) {
122 if((header.
dwFlags & flag) != flag) {
153 GLint s3tc_format = 0;
154 GLint s3tc_format_layout = 0;
155 GLint s3tc_type = GL_UNSIGNED_BYTE;
158 s3tc_format = GL_RGB;
159 s3tc_format_layout = GL_RGB;
162 s3tc_format = GL_RGBA;
163 s3tc_format_layout = GL_RGBA;
171 dds_main_size = width * height * block_size;
198 dds_main_size = ((width + 3) >> 2) * ((height + 3) >> 2) * block_size;
200 uint32_t dds_full_size = dds_main_size;
204 for(
uint32_t i = 1; i <= mipmaps; ++i) {
205 uint32_t w = std::max<uint32_t>(width >> i, 1);
206 uint32_t h = std::max<uint32_t>(height >> i, 1);
209 dds_full_size += w * h * block_size;
212 dds_full_size += ((w + 3) / 4) * ((h + 3) / 4) * block_size;
217 if(buffer_index + dds_full_size <=
uint32_t(buffer_length)) {
220 glGenTextures(1, &texid);
222 glBindTexture(GL_TEXTURE_2D, texid);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
248 std::unique_ptr<uint8_t[]> dds_dest_data = std::unique_ptr<uint8_t[]>(
new uint8_t[dds_full_size]);
252 for(
uint32_t i = 0; i < dds_full_size; i += block_size) {
258 dds_dest_data[i + 0] =
static_cast<uint8_t>(r);
259 dds_dest_data[i + 1] =
static_cast<uint8_t>(g);
260 dds_dest_data[i + 2] =
static_cast<uint8_t>(b);
261 dds_dest_data[i + 3] =
static_cast<uint8_t>(a);
267 dds_dest_data.reset();
268 dds_dest_data = std::unique_ptr<uint8_t[]>(
new uint8_t[dds_full_size * 2]);
270 float mr2 = mr1 == 0 ? 0.f : 255.f / float(mr1);
272 float mg2 = mg1 == 0 ? 0.f : 255.f / float(mg1);
274 float mb2 = mb1 == 0 ? 0.f : 255.f / float(mb1);
276 float ma2 = ma1 == 0 ? 0.f : 255.f / float(ma1);
277 for(
uint32_t i = 0; i < dds_full_size; i += block_size) {
278 uint16_t
data = *(uint16_t
const*)(buffer + buffer_index + i);
283 dds_dest_data[i * 2 + 0] =
uint8_t(
float(r) * mr2);
284 dds_dest_data[i * 2 + 1] =
uint8_t(
float(g) * mg2);
285 dds_dest_data[i * 2 + 2] =
uint8_t(
float(b) * mb2);
286 dds_dest_data[i * 2 + 3] =
uint8_t(
float(a) * ma2);
292 std::memcpy(dds_dest_data.get(), buffer + buffer_index, dds_full_size);
293 for(
uint32_t i = 0; i < dds_full_size; i += block_size) {
294 uint8_t temp = dds_dest_data[i];
295 dds_dest_data[i] = dds_dest_data[i + 2];
296 dds_dest_data[i + 2] = temp;
301 glTexImage2D(GL_TEXTURE_2D, 0, s3tc_format, width, height, 0, s3tc_format_layout, s3tc_type, dds_dest_data.get());
302 uint32_t buffer_offset = dds_main_size * (block_size == 2 ? 2 : 1);
304 for(
uint32_t i = 1; i <= mipmaps; ++i) {
305 uint32_t w = std::max<uint32_t>(width >> i, 1);
306 uint32_t h = std::max<uint32_t>(height >> i, 1);
308 uint32_t mip_size = w * h * block_size;
311 mip_size = w * h * 4;
316 glTexImage2D(GL_TEXTURE_2D, i, s3tc_format, w, h, 0, s3tc_format_layout, s3tc_type, dds_dest_data.get() + buffer_offset);
318 buffer_offset += mip_size;
321 glCompressedTexImage2D(GL_TEXTURE_2D, 0, s3tc_format, width, height, 0, dds_main_size, buffer + buffer_index);
322 buffer_index += dds_main_size;
324 for(
uint32_t i = 1; i <= mipmaps; ++i) {
325 uint32_t w = std::max<uint32_t>(width >> i, 1);
326 uint32_t h = std::max<uint32_t>(height >> i, 1);
328 uint32_t mip_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size;
329 glCompressedTexImage2D(GL_TEXTURE_2D, i, s3tc_format, w, h, 0, mip_size, buffer + buffer_index);
331 buffer_index += mip_size;
345 channels = other.channels;
346 loaded = other.loaded;
347 size_x = other.size_x;
348 size_y = other.size_y;
350 texture_handle = other.texture_handle;
352 other.data =
nullptr;
355 channels = other.channels;
356 loaded = other.loaded;
357 size_x = other.size_x;
358 size_y = other.size_y;
360 texture_handle = other.texture_handle;
362 other.data =
nullptr;
368 return texture_handle;
372 auto name_length = native_name.length();
374 auto root = get_root(fs);
375 if(name_length > 4) {
376 auto dds_name = native_name;
377 if(
auto pos = dds_name.find_last_of(
'.'); pos != native_string::npos) {
378 dds_name[pos + 1] =
NATIVE(
'd');
379 dds_name[pos + 2] =
NATIVE(
'd');
380 dds_name[pos + 3] =
NATIVE(
's');
381 dds_name.resize(pos + 4);
383 auto file = open_file(root, dds_name);
391 if(asset_texture.texture_handle) {
393 asset_texture.
size_x = int32_t(w);
394 asset_texture.
size_y = int32_t(h);
395 asset_texture.
loaded =
true;
398 asset_texture.
data =
static_cast<uint8_t*
>(STBI_MALLOC(4 * w * h));
399 glGetTextureImage(asset_texture.texture_handle, 0, GL_RGBA, GL_UNSIGNED_BYTE,
static_cast<int32_t
>(4 * w * h),
402 return asset_texture.texture_handle;
407 auto file = open_file(root, native_name);
408 if(!file && name_length > 4) {
409 auto png_name = native_name;
410 if(
auto pos = png_name.find_last_of(
'.'); pos != native_string::npos) {
411 png_name[pos + 1] =
NATIVE(
'p');
412 png_name[pos + 2] =
NATIVE(
'n');
413 png_name[pos + 3] =
NATIVE(
'g');
414 png_name.resize(pos + 4);
416 file = open_file(root, png_name);
421 int32_t file_channels = 4;
423 asset_texture.
data = stbi_load_from_memory(
reinterpret_cast<uint8_t const*
>(content.data), int32_t(content.file_size),
424 &(asset_texture.
size_x), &(asset_texture.
size_y), &file_channels, 4);
427 asset_texture.
loaded =
true;
429 glGenTextures(1, &asset_texture.texture_handle);
430 if(asset_texture.texture_handle) {
431 glBindTexture(GL_TEXTURE_2D, asset_texture.texture_handle);
433 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, asset_texture.
size_x, asset_texture.
size_y);
434 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, asset_texture.
size_x, asset_texture.
size_y, GL_RGBA, GL_UNSIGNED_BYTE,
437 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
439 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
440 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
442 glBindTexture(GL_TEXTURE_2D, 0);
446 STBI_FREE(asset_texture.
data);
447 asset_texture.
data =
nullptr;
450 return asset_texture.texture_handle;
452 asset_texture.
loaded =
true;
462 return NATIVE(
"_communist");
464 return NATIVE(
"_fascist");
466 return NATIVE(
"_monarchy");
468 return NATIVE(
"_republic");
471 return NATIVE(
"_theocracy");
473 return NATIVE(
"_special");
477 return NATIVE(
"_populist");
483 return NATIVE(
"_monarchy2");
485 return NATIVE(
"_monarchy3");
487 return NATIVE(
"_republic2");
489 return NATIVE(
"_republic3");
491 return NATIVE(
"_communist2");
493 return NATIVE(
"_communist3");
495 return NATIVE(
"_fascist2");
497 return NATIVE(
"_fascist3");
499 return NATIVE(
"_theocracy2");
501 return NATIVE(
"_theocracy3");
503 return NATIVE(
"_cosmetic_1");
505 return NATIVE(
"_cosmetic_2");
507 return NATIVE(
"_colonial");
509 return NATIVE(
"_nationalist");
511 return NATIVE(
"_sectarian");
513 return NATIVE(
"_socialist");
515 return NATIVE(
"_dominion");
517 return NATIVE(
"_agrarism");
519 return NATIVE(
"_national_syndicalist");
521 return NATIVE(
"_theocratic");
531 return NATIVE(
"_anarcho_liberal");
535 return NATIVE(
"_traditionalist");
537 return NATIVE(
"_ultranationalist");
545 auto masq_nat_id = state.world.nation_get_masquerade_identity(state.world.national_identity_get_nation_from_identity_holder(nat_id));
547 masq_nat_id = nat_id;
551 dcon::texture_id
id = dcon::texture_id{ dcon::texture_id::value_base_t(state.ui_defs.textures.size() + (1 + masq_nat_id.id.index()) * state.flag_types.size() + offset) };
552 if(state.open_gl.asset_textures[
id].loaded) {
553 return state.open_gl.asset_textures[id].texture_handle;
556 file_str +=
NATIVE(
"gfx");
558 file_str +=
NATIVE(
"flags");
578 if(state.open_gl.asset_textures[
id].loaded) {
579 return state.open_gl.asset_textures[id].texture_handle;
581 auto fname = state.ui_defs.textures[id];
582 auto fname_view = state.to_string_view(fname);
594 glGenTextures(1, &texture_handle);
595 glBindTexture(GL_TEXTURE_2D, texture_handle);
598 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8,
size, 1);
600 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8,
size, 1);
602 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8,
size, 1);
604 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8,
size, 1);
606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
611 glBindTexture(GL_TEXTURE_2D, 0);
621 glBindTexture(GL_TEXTURE_2D, texture_handle);
623 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RGB, GL_UNSIGNED_BYTE,
data);
625 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RGBA, GL_UNSIGNED_BYTE,
data);
627 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RG, GL_UNSIGNED_BYTE,
data);
629 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RED, GL_UNSIGNED_BYTE,
data);
632 glBindTexture(GL_TEXTURE_2D, 0);
634 return texture_handle;
640 channels = other.channels;
641 texture_handle = other.texture_handle;
643 other.data =
nullptr;
649 channels = other.channels;
650 texture_handle = other.texture_handle;
652 other.data =
nullptr;
660 int32_t file_channels = 4;
663 uint8_t*
data = stbi_load_from_memory(
reinterpret_cast<uint8_t const*
>(content.data), int32_t(content.file_size), &(size_x), &(size_y), &file_channels, 4);
666 glGenTextures(1, &ftexid);
668 glBindTexture(GL_TEXTURE_2D, ftexid);
670 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size_x, size_y);
671 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size_x, size_y, GL_RGBA, GL_UNSIGNED_BYTE,
data);
673 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
674 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
data_texture & operator=(data_texture const &)=delete
data_texture(int32_t sz, int32_t ch)
texture & operator=(texture const &)=delete
GLuint get_texture_handle() const
#define assert(condition)
uint32_t get_remapped_flag_type(sys::state const &state, flag_type type)
std::string int_to_tag(uint32_t v)
GLuint load_file_and_return_handle(native_string const &native_name, simple_fs::file_system const &fs, texture &asset_texture, bool keep_data)
GLuint SOIL_direct_load_DDS_from_memory(unsigned char const *const buffer, uint32_t buffer_length, uint32_t &width, uint32_t &height, int soil_flags)
@ SOIL_FLAG_TEXTURE_REPEATS
GLuint get_texture_handle(sys::state &state, dcon::texture_id id, bool keep_data)
native_string flag_type_to_name(sys::state &state, culture::flag_type type)
font_texture_result make_font_texture(simple_fs::file &f)
GLuint get_flag_handle(sys::state &state, dcon::national_identity_id nat_id, culture::flag_type type)
native_string win1250_to_native(std::string_view data_in)
file_contents view_contents(file const &f)
std::string native_string
#define NATIVE_DIR_SEPARATOR
#define SOIL_TEXTURE_WRAP_R
#define ALICE_DDSCAPS_TEXTURE
#define ALICE_DDPF_ALPHAPIXELS
#define ALICE_DDPF_FOURCC
#define SOIL_RGBA_S3TC_DXT3
#define SOIL_RGBA_S3TC_DXT1
#define ALICE_DDSD_PIXELFORMAT
#define ALICE_DDSCAPS2_CUBEMAP
#define ALICE_DDSCAPS_MIPMAP
#define SOIL_RGBA_S3TC_DXT5
#define ALICE_DDSD_HEIGHT