gl_code.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * ETC Texture Compressor
  3. * 2013-03-20
  4. * M. Kim
  5. */
  6. #include <jni.h>
  7. #include <android/log.h>
  8. #include <GLES2/gl2.h>
  9. #include <GLES2/gl2ext.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include "rg_etc1.h"
  14. #define LOG_TAG "unity plugin"
  15. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
  16. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
  17. static void checkGlError(const char* op) {
  18. for (GLint error = glGetError(); error; error
  19. = glGetError()) {
  20. LOGI("after %s() glError (0x%x)\n", op, error);
  21. }
  22. }
  23. int g_etcInited = 0;
  24. struct compressor_t
  25. {
  26. GLuint glTex;
  27. int w;
  28. int h;
  29. int count;
  30. void** in;
  31. unsigned int* out;
  32. };
  33. extern "C" void* GenTextureCompressor(void* texPtr, int w, int h, int mipmapCount, void* mipmapData[])
  34. {
  35. if (!g_etcInited)
  36. {
  37. rg_etc1::pack_etc1_block_init();
  38. g_etcInited = 1;
  39. }
  40. compressor_t* compressor = new compressor_t;
  41. compressor->glTex = (GLuint)(size_t)(texPtr);
  42. compressor->w = w;
  43. compressor->h = h;
  44. compressor->count = mipmapCount;
  45. compressor->in = new void*[mipmapCount];
  46. for (int i = 0; i < mipmapCount; i++)
  47. compressor->in[i] = mipmapData[i];
  48. compressor->out = NULL;
  49. return compressor;
  50. }
  51. extern "C" void CompressTexture(compressor_t* compressor)
  52. {
  53. int w = compressor->w;
  54. int h = compressor->h;
  55. int memSize = 0;
  56. for (int i = 0; i < compressor->count; i++)
  57. {
  58. if (w == 0) w = 1;
  59. if (h == 0) h = 1;
  60. int dataSize = (w * h) >> 1; // bytes
  61. if (dataSize < 8)
  62. dataSize = 8;
  63. memSize += dataSize;
  64. //LOGI("%d x %d: %d", w, h, dataSize);
  65. w >>= 1;
  66. h >>= 1;
  67. }
  68. compressor->out = new unsigned int[memSize >> 2];
  69. w = compressor->w;
  70. h = compressor->h;
  71. unsigned int* compressed = compressor->out;
  72. rg_etc1::etc1_pack_params params;
  73. params.m_quality = rg_etc1::cLowQuality;
  74. params.m_dithering = false;
  75. for (int i = 0; i < compressor->count ; i++)
  76. {
  77. if (w == 0) w = 1;
  78. if (h == 0) h = 1;
  79. unsigned int* data = (unsigned int*)compressor->in[i];
  80. if (w >= 4 && h >= 4)
  81. {
  82. for (int y = 0; y < h / 4; y++)
  83. {
  84. for (int x = 0; x < w / 4; x++)
  85. {
  86. unsigned int src_blk[16];
  87. unsigned int* d = src_blk;
  88. unsigned int* s = &data[y * 4 * w + x * 4];
  89. for (int k = 0; k < 4; k++)
  90. {
  91. *d++ = *s++;
  92. *d++ = *s++;
  93. *d++ = *s++;
  94. *d++ = *s++;
  95. s += w - 4;
  96. //if (x == 0 && y == 0)
  97. // LOGI("%08x %08x %08x %08x", *(d - 3), *(d - 2), *(d - 1), *d);
  98. }
  99. rg_etc1::pack_etc1_block(compressed, src_blk, params);
  100. compressed += 2;
  101. }
  102. }
  103. //LOGI("[%d] %d x %d [%08xh]: ok", i, w, h, data);
  104. }
  105. else
  106. {
  107. //LOGI("[%d] %d x %d [%08xh]", i, w, h, data);
  108. unsigned int p[16];
  109. for (int j = 0; j < 16; j++)
  110. {
  111. p[j] = data[j % (w * h)];
  112. }
  113. rg_etc1::pack_etc1_block(compressed, p, params);
  114. compressed += 2;
  115. }
  116. w >>= 1;
  117. h >>= 1;
  118. }
  119. }
  120. extern "C" void UploadCompressedTexture(compressor_t* compressor)
  121. {
  122. glBindTexture(GL_TEXTURE_2D, compressor->glTex);
  123. checkGlError("glBindTexture");
  124. int w = compressor->w;
  125. int h = compressor->h;
  126. unsigned char* data = (unsigned char*)compressor->out;
  127. for (int i = 0; i < compressor->count; i++)
  128. {
  129. if (w == 0) w = 1;
  130. if (h == 0) h = 1;
  131. int dataSize = (w * h) >> 1; // bytes
  132. if (dataSize < 8)
  133. dataSize = 8;
  134. glCompressedTexImage2D(GL_TEXTURE_2D, i, GL_ETC1_RGB8_OES, w, h, 0, dataSize, data);
  135. checkGlError("glCompressedTexImage2D");
  136. data += dataSize;
  137. w >>= 1;
  138. h >>= 1;
  139. }
  140. delete[] compressor->out;
  141. delete[] compressor->in;
  142. delete compressor;
  143. }
  144. extern "C" void UploadCompressedTexImage2D(
  145. void* texPtr,
  146. GLuint glLevel,
  147. GLuint glInternalformat,
  148. GLuint width,
  149. GLuint height,
  150. GLuint border,
  151. GLuint imageSize,
  152. void* imgdata)
  153. {
  154. GLuint glNativeTextureID = (GLuint)(size_t)(texPtr);
  155. glBindTexture(GL_TEXTURE_2D, glNativeTextureID);
  156. checkGlError("glBindTexture");
  157. glCompressedTexImage2D(
  158. GL_TEXTURE_2D,
  159. 0,
  160. GL_ETC1_RGB8_OES,
  161. width,
  162. height,
  163. 0,
  164. imageSize,
  165. imgdata);
  166. checkGlError("glCompressedTexImage2D");
  167. LOGI(">>> [%d] <<< (%d x %d) len=%d : ok", glNativeTextureID, width, height, imageSize);
  168. }