texture_bu.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include "texture_bu.h"
  2. #if 0
  3. #include "core/os/os.h"
  4. #ifdef TOOLS_ENABLED
  5. #include "basisu_comp.h"
  6. #endif
  7. #include "transcoder/basisu.h"
  8. void TextureBU::_bind_methods() {
  9. ClassDB::bind_method(D_METHOD("set_bu_data", "data"), &TextureBU::set_bu_data);
  10. ClassDB::bind_method(D_METHOD("get_bu_data"), &TextureBU::get_data);
  11. ClassDB::bind_method(D_METHOD("import"), &TextureBU::import);
  12. ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "bu_data"), "set_bu_data", "get_bu_data");
  13. };
  14. int TextureBU::get_width() const {
  15. return tex_size.x;
  16. };
  17. int TextureBU::get_height() const {
  18. return tex_size.y;
  19. };
  20. RID TextureBU::get_rid() const {
  21. return texture;
  22. };
  23. bool TextureBU::has_alpha() const {
  24. return false;
  25. };
  26. void TextureBU::set_flags(uint32_t p_flags) {
  27. flags = p_flags;
  28. VisualServer::get_singleton()->texture_set_flags(texture, p_flags);
  29. };
  30. uint32_t TextureBU::get_flags() const {
  31. return flags;
  32. };
  33. void TextureBU::set_bu_data(const PoolVector<uint8_t>& p_data) {
  34. #ifdef TOOLS_ENABLED
  35. data = p_data;
  36. #endif
  37. PoolVector<uint8_t>::Read r = p_data.read();
  38. const void* ptr = r.ptr();
  39. int size = p_data.size();
  40. basist::transcoder_texture_format format;
  41. Image::Format imgfmt;
  42. if (OS::get_singleton()->has_feature("s3tc")) {
  43. format = basist::cTFBC3; // get this from renderer
  44. imgfmt = Image::FORMAT_DXT5;
  45. } else if (OS::get_singleton()->has_feature("etc2")) {
  46. format = basist::cTFETC2;
  47. imgfmt = Image::FORMAT_ETC2_RGBA8;
  48. };
  49. basist::basisu_transcoder tr(NULL);
  50. ERR_FAIL_COND(!tr.validate_header(ptr, size));
  51. basist::basisu_image_info info;
  52. tr.get_image_info(ptr, size, info, 0);
  53. tex_size = Size2(info.m_width, info.m_height);
  54. int block_size = basist::basis_get_bytes_per_block(format);
  55. PoolVector<uint8_t> gpudata;
  56. gpudata.resize(info.m_total_blocks * block_size);
  57. {
  58. PoolVector<uint8_t>::Write w = gpudata.write();
  59. uint8_t* dst = w.ptr();
  60. for (int i=0; i<gpudata.size(); i++)
  61. dst[i] = 0x00;
  62. int ofs = 0;
  63. tr.start_transcoding(ptr, size);
  64. for (int i=0; i<info.m_total_levels; i++) {
  65. basist::basisu_image_level_info level;
  66. tr.get_image_level_info(ptr, size, level, 0, i);
  67. bool ret = tr.transcode_image_level(ptr, size, 0, i, dst + ofs, level.m_total_blocks - i, format);
  68. if (!ret) {
  69. printf("failed! on level %i\n", i);
  70. break;
  71. };
  72. ofs += level.m_total_blocks * block_size;
  73. };
  74. };
  75. Ref<Image> img;
  76. img.instance();
  77. img->create(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata);
  78. VisualServer::get_singleton()->texture_allocate(texture, tex_size.x, tex_size.y, 0, img->get_format(), VS::TEXTURE_TYPE_2D, flags);
  79. VisualServer::get_singleton()->texture_set_data(texture, img);
  80. };
  81. Error TextureBU::import(const Ref<Image>& p_img) {
  82. #ifdef TOOLS_ENABLED
  83. PoolVector<uint8_t> budata;
  84. {
  85. Image::Format format = p_img->get_format();
  86. if (format != Image::FORMAT_RGB8 && format != Image::FORMAT_RGBA8) {
  87. ERR_FAIL_V(ERR_INVALID_PARAMETER);
  88. return ERR_INVALID_PARAMETER;
  89. };
  90. Ref<Image> copy = p_img->duplicate();
  91. if (format == Image::FORMAT_RGB8)
  92. copy->convert(Image::FORMAT_RGBA8);
  93. basisu::image buimg(p_img->get_width(), p_img->get_height());
  94. int size = p_img->get_width() * p_img->get_height() * 4;
  95. PoolVector<uint8_t> vec = copy->get_data();
  96. {
  97. PoolVector<uint8_t>::Read r = vec.read();
  98. memcpy(buimg.get_ptr(), r.ptr(), size);
  99. };
  100. basisu::basis_compressor_params params;
  101. params.m_max_endpoint_clusters = 512;
  102. params.m_max_selector_clusters = 512;
  103. params.m_multithreading = true;
  104. basisu::job_pool jpool(1);
  105. params.m_pJob_pool = &jpool;
  106. params.m_mip_gen = p_img->get_mipmap_count() > 0;
  107. params.m_source_images.push_back(buimg);
  108. basisu::basis_compressor c;
  109. c.init(params);
  110. int buerr = c.process();
  111. if (buerr != basisu::basis_compressor::cECSuccess) {
  112. ERR_FAIL_V(ERR_INVALID_PARAMETER);
  113. return ERR_INVALID_PARAMETER;
  114. };
  115. const basisu::uint8_vec& buvec = c.get_output_basis_file();
  116. budata.resize(buvec.size());
  117. {
  118. PoolVector<uint8_t>::Write w = budata.write();
  119. memcpy(w.ptr(), &buvec[0], budata.size());
  120. };
  121. };
  122. set_bu_data(budata);
  123. return OK;
  124. #else
  125. return ERR_UNAVAILABLE;
  126. #endif
  127. };
  128. PoolVector<uint8_t> TextureBU::get_bu_data() const {
  129. return data;
  130. };
  131. TextureBU::TextureBU() {
  132. flags = FLAGS_DEFAULT;
  133. texture = VisualServer::get_singleton()->texture_create();
  134. };
  135. TextureBU::~TextureBU() {
  136. VisualServer::get_singleton()->free(texture);
  137. };
  138. #endif