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];
120 (
char const*)glGetString(GL_EXTENSIONS),
121 "GL_EXT_texture_compression_s3tc")) {
131 "glCompressedTexImage2DARB"
133#elif defined(__APPLE__) || defined(__APPLE_CC__)
137 CFURLCreateWithFileSystemPath(
139 CFSTR(
"/System/Library/Frameworks/OpenGL.framework"),
140 kCFURLPOSIXPathStyle,
142 CFStringRef extensionName =
143 CFStringCreateWithCString(
145 "glCompressedTexImage2DARB",
146 kCFStringEncodingASCII);
147 bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);
150 CFBundleGetFunctionPointerForName
152 bundle, extensionName
154 CFRelease(bundleURL);
155 CFRelease(extensionName);
161 if(NULL == ext_addr) {
177 return has_DXT_capability;
190 std::memcpy((
void*)(&header), (
void const*)buffer,
sizeof(
DDS_header));
194 if(header.
dwMagic != ((
'D' << 0) | (
'D' << 8) | (
'S' << 16) | (
' ' << 24))) {
197 if(header.
dwSize != 124) {
202 if((header.
dwFlags & flag) != flag) {
233 GLint s3tc_format = 0;
234 GLint s3tc_format_layout = 0;
235 GLint s3tc_type = GL_UNSIGNED_BYTE;
238 s3tc_format = GL_RGB;
239 s3tc_format_layout = GL_RGB;
242 s3tc_format = GL_RGBA;
243 s3tc_format_layout = GL_RGBA;
251 dds_main_size = width * height * block_size;
275 dds_main_size = ((width + 3) >> 2) * ((height + 3) >> 2) * block_size;
277 uint32_t dds_full_size = dds_main_size;
281 for(
uint32_t i = 1; i <= mipmaps; ++i) {
282 uint32_t w = std::max<uint32_t>(width >> i, 1);
283 uint32_t h = std::max<uint32_t>(height >> i, 1);
286 dds_full_size += w * h * block_size;
289 dds_full_size += ((w + 3) / 4) * ((h + 3) / 4) * block_size;
294 if(buffer_index + dds_full_size <=
uint32_t(buffer_length)) {
297 glGenTextures(1, &texid);
299 glBindTexture(GL_TEXTURE_2D, texid);
309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
315 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
319 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
320 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
326 std::unique_ptr<uint8_t[]> dds_dest_data = std::unique_ptr<uint8_t[]>(
new uint8_t[dds_full_size]);
330 assert(dds_full_size % 4 == 0);
331 for(
uint32_t i = 0; i < dds_full_size; i += block_size) {
338 dds_dest_data[i + 0] =
static_cast<uint8_t>(r);
339 dds_dest_data[i + 1] =
static_cast<uint8_t>(g);
340 dds_dest_data[i + 2] =
static_cast<uint8_t>(b);
341 dds_dest_data[i + 3] =
static_cast<uint8_t>(a);
347 dds_dest_data.reset();
348 dds_dest_data = std::unique_ptr<uint8_t[]>(
new uint8_t[dds_full_size * 2]);
350 float mr2 = mr1 == 0 ? 0.f : 255.f / float(mr1);
352 float mg2 = mg1 == 0 ? 0.f : 255.f / float(mg1);
354 float mb2 = mb1 == 0 ? 0.f : 255.f / float(mb1);
356 float ma2 = ma1 == 0 ? 0.f : 255.f / float(ma1);
357 for(
uint32_t i = 0; i < dds_full_size; i += block_size) {
359 uint16_t
data = *(uint16_t
const*)(buffer + buffer_index + i);
364 dds_dest_data[i * 2 + 0] =
uint8_t(
float(r) * mr2);
365 dds_dest_data[i * 2 + 1] =
uint8_t(
float(g) * mg2);
366 dds_dest_data[i * 2 + 2] =
uint8_t(
float(b) * mb2);
367 dds_dest_data[i * 2 + 3] =
uint8_t(
float(a) * ma2);
373 assert(dds_full_size <= buffer_length);
374 std::memcpy(dds_dest_data.get(), buffer + buffer_index, dds_full_size);
375 for(
uint32_t i = 0; i+2 < dds_full_size; i += block_size) {
376 uint8_t temp = dds_dest_data[i];
377 dds_dest_data[i] = dds_dest_data[i + 2];
378 dds_dest_data[i + 2] = temp;
383 glTexImage2D(GL_TEXTURE_2D, 0, s3tc_format, width, height, 0, s3tc_format_layout, s3tc_type, dds_dest_data.get());
384 uint32_t buffer_offset = dds_main_size * (block_size == 2 ? 2 : 1);
404 assert(buffer_index + dds_main_size <= buffer_length);
405 if(buffer_index + dds_main_size > buffer_length)
408 glCompressedTexImage2D(GL_TEXTURE_2D, 0, s3tc_format, width, height, 0, dds_main_size, buffer + buffer_index);
409 buffer_index += dds_main_size;
433 channels = other.channels;
434 loaded = other.loaded;
435 size_x = other.size_x;
436 size_y = other.size_y;
438 texture_handle = other.texture_handle;
440 other.data =
nullptr;
443 channels = other.channels;
444 loaded = other.loaded;
445 size_x = other.size_x;
446 size_y = other.size_y;
448 texture_handle = other.texture_handle;
450 other.data =
nullptr;
456 return texture_handle;
460 auto name_length = native_name.length();
462 auto root = get_root(fs);
463 if(name_length > 4) {
464 auto dds_name = native_name;
465 if(
auto pos = dds_name.find_last_of(
'.'); pos != native_string::npos) {
466 dds_name[pos + 1] =
NATIVE(
'd');
467 dds_name[pos + 2] =
NATIVE(
'd');
468 dds_name[pos + 3] =
NATIVE(
's');
469 dds_name.resize(pos + 4);
471 auto file = open_file(root, dds_name);
479 if(asset_texture.texture_handle) {
481 asset_texture.
size_x = int32_t(w);
482 asset_texture.
size_y = int32_t(h);
483 asset_texture.
loaded =
true;
486 asset_texture.
data =
static_cast<uint8_t*
>(STBI_MALLOC(4 * w * h));
487 glGetTextureImage(asset_texture.texture_handle, 0, GL_RGBA, GL_UNSIGNED_BYTE,
static_cast<int32_t
>(4 * w * h),
490 return asset_texture.texture_handle;
495 auto file = open_file(root, native_name);
496 if(!file && name_length > 4) {
497 auto png_name = native_name;
498 if(
auto pos = png_name.find_last_of(
'.'); pos != native_string::npos) {
499 png_name[pos + 1] =
NATIVE(
'p');
500 png_name[pos + 2] =
NATIVE(
'n');
501 png_name[pos + 3] =
NATIVE(
'g');
502 png_name.resize(pos + 4);
504 file = open_file(root, png_name);
509 int32_t file_channels = 4;
511 asset_texture.
data = stbi_load_from_memory(
reinterpret_cast<uint8_t const*
>(content.data), int32_t(content.file_size),
512 &(asset_texture.
size_x), &(asset_texture.
size_y), &file_channels, 4);
515 asset_texture.
loaded =
true;
517 glGenTextures(1, &asset_texture.texture_handle);
518 if(asset_texture.texture_handle) {
519 glBindTexture(GL_TEXTURE_2D, asset_texture.texture_handle);
521 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, asset_texture.
size_x, asset_texture.
size_y);
522 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, asset_texture.
size_x, asset_texture.
size_y, GL_RGBA, GL_UNSIGNED_BYTE,
525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
526 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
527 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
530 glBindTexture(GL_TEXTURE_2D, 0);
534 STBI_FREE(asset_texture.
data);
535 asset_texture.
data =
nullptr;
538 return asset_texture.texture_handle;
540 asset_texture.
loaded =
true;
550 return NATIVE(
"_communist");
552 return NATIVE(
"_fascist");
554 return NATIVE(
"_monarchy");
556 return NATIVE(
"_republic");
559 return NATIVE(
"_theocracy");
561 return NATIVE(
"_special");
565 return NATIVE(
"_populist");
571 return NATIVE(
"_monarchy2");
573 return NATIVE(
"_monarchy3");
575 return NATIVE(
"_republic2");
577 return NATIVE(
"_republic3");
579 return NATIVE(
"_communist2");
581 return NATIVE(
"_communist3");
583 return NATIVE(
"_fascist2");
585 return NATIVE(
"_fascist3");
587 return NATIVE(
"_theocracy2");
589 return NATIVE(
"_theocracy3");
591 return NATIVE(
"_cosmetic_1");
593 return NATIVE(
"_cosmetic_2");
595 return NATIVE(
"_colonial");
597 return NATIVE(
"_nationalist");
599 return NATIVE(
"_sectarian");
601 return NATIVE(
"_socialist");
603 return NATIVE(
"_dominion");
605 return NATIVE(
"_agrarism");
607 return NATIVE(
"_national_syndicalist");
609 return NATIVE(
"_theocratic");
619 return NATIVE(
"_anarcho_liberal");
623 return NATIVE(
"_traditionalist");
625 return NATIVE(
"_ultranationalist");
633 auto masq_nat_id = state.world.nation_get_masquerade_identity(state.world.national_identity_get_nation_from_identity_holder(nat_id));
635 masq_nat_id = nat_id;
639 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) };
640 if(state.open_gl.asset_textures[
id].loaded) {
641 return state.open_gl.asset_textures[id].texture_handle;
644 file_str +=
NATIVE(
"gfx");
646 file_str +=
NATIVE(
"flags");
666 if(state.open_gl.asset_textures[
id].loaded) {
667 return state.open_gl.asset_textures[id].texture_handle;
669 auto fname = state.ui_defs.textures[id];
670 auto fname_view = state.to_string_view(fname);
682 glGenTextures(1, &texture_handle);
683 glBindTexture(GL_TEXTURE_2D, texture_handle);
686 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8,
size, 1);
688 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8,
size, 1);
690 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG8,
size, 1);
692 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8,
size, 1);
694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
695 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
696 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
697 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
699 glBindTexture(GL_TEXTURE_2D, 0);
709 glBindTexture(GL_TEXTURE_2D, texture_handle);
711 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RGB, GL_UNSIGNED_BYTE,
data);
713 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RGBA, GL_UNSIGNED_BYTE,
data);
715 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RG, GL_UNSIGNED_BYTE,
data);
717 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
size, 1, GL_RED, GL_UNSIGNED_BYTE,
data);
720 glBindTexture(GL_TEXTURE_2D, 0);
722 return texture_handle;
728 channels = other.channels;
729 texture_handle = other.texture_handle;
731 other.data =
nullptr;
737 channels = other.channels;
738 texture_handle = other.texture_handle;
740 other.data =
nullptr;
748 int32_t file_channels = 4;
751 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);
754 glGenTextures(1, &ftexid);
756 glBindTexture(GL_TEXTURE_2D, ftexid);
758 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size_x, size_y);
759 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size_x, size_y, GL_RGBA, GL_UNSIGNED_BYTE,
data);
761 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
762 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
763 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
764 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)
int query_DXT_capability(void)
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)
GLuint get_texture_handle(sys::state &state, dcon::texture_id id, bool keep_data)
void(APIENTRY * P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
native_string flag_type_to_name(sys::state &state, culture::flag_type type)
@ SOIL_CAPABILITY_PRESENT
@ SOIL_CAPABILITY_UNKNOWN
@ SOIL_FLAG_TEXTURE_REPEATS
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 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