OgreGenUtilites.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include "OgreGenUtilites.h"
  16. #include "Logger.h"
  17. void CreateTextureFromVram(
  18. const Ogre::PixelBox& pixel_box, Vram* vram,
  19. const int start_x, const int start_y, const int clut_x, const int clut_y,
  20. const int texture_x, const int texture_y, const BPP bpp,
  21. const bool transparency
  22. ){
  23. for (u32 y = 0; y < 256; ++ y){
  24. // IVV type cast
  25. u32* data = static_cast<u32*>(
  26. (unsigned int *) (
  27. (pixel_box.data) + (y + start_y) * pixel_box.rowPitch
  28. )
  29. );
  30. for (u32 x = 0; x < 256; ++ x){
  31. if (bpp == BPP_4){
  32. u8 pixel = vram->GetU8(texture_x * 2 + x / 2, texture_y + y);
  33. u16 clut1 = vram->GetU16(
  34. clut_x * 2 + (pixel & 0xf) * 2, clut_y
  35. );
  36. u16 clut2 = vram->GetU16(clut_x * 2 + (pixel >> 4) * 2, clut_y);
  37. u32 ogre_pixel1
  38. = (((clut1 & 0x1f) * 255 / 31) << 0x18)
  39. | ((((clut1 >> 5) & 0x1f) * 255 / 31) << 0x10)
  40. | ((((clut1 >> 10) & 0x1f) * 255 / 31) << 0x8)
  41. | 0;
  42. u8 stp = (clut1 & 0x8000) >> 15;
  43. AddTransparency(ogre_pixel1, transparency, stp > 0);
  44. u32 ogre_pixel2
  45. = (((clut2 & 0x1f) * 255 / 31) << 0x18)
  46. | ((((clut2 >> 5) & 0x1f) * 255 / 31) << 0x10)
  47. | ((((clut2 >> 10) & 0x1f) * 255 / 31) << 0x8)
  48. | 0;
  49. stp = (clut2 & 0x8000) >> 15;
  50. AddTransparency(ogre_pixel2, transparency, stp > 0);
  51. data[start_x + x] = ogre_pixel1;
  52. ++ x;
  53. data[start_x + x] = ogre_pixel2;
  54. }
  55. else if (bpp == BPP_8){
  56. u8 pixel = vram->GetU8(texture_x * 2 + x, texture_y + y);
  57. u16 clut = vram->GetU16(clut_x * 2 + pixel * 2, clut_y);
  58. u32 ogre_pixel
  59. = (((clut & 0x1f) * 255 / 31) << 0x18)
  60. | ((((clut >> 5) & 0x1f) * 255 / 31) << 0x10)
  61. | ((((clut >> 10) & 0x1f) * 255 / 31) << 0x8)
  62. | 0;
  63. u8 stp = (clut & 0x8000) >> 15;
  64. AddTransparency(ogre_pixel, transparency, stp > 0);
  65. data[start_x + x ] = ogre_pixel;
  66. }
  67. else if (bpp == BPP_BLACK) data[ start_x + x ] = 0xffffffff;
  68. }
  69. }
  70. }
  71. void CreateTexture(
  72. Vram* vram, const MeshData& mesh_data, const Ogre::String& texture_file_name,
  73. const VectorTexForGen& textures
  74. ){
  75. Ogre::TexturePtr ptex;
  76. Ogre::HardwarePixelBufferSharedPtr buffer;
  77. ptex = Ogre::TextureManager::getSingleton().createManual(
  78. "DynaTex", "General", Ogre::TEX_TYPE_2D,
  79. mesh_data.tex_width, mesh_data.tex_height,
  80. 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC
  81. );
  82. buffer = ptex->getBuffer(0, 0);
  83. buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
  84. const Ogre::PixelBox& pixel_box = buffer->getCurrentLock();
  85. for (unsigned int i = 0; i < textures.size(); ++ i){
  86. LOGGER->Log(
  87. "CreateTexture palette_x=\""
  88. + Ogre::StringConverter::toString(textures[i].palette_x)
  89. + "\" palette_y=\""
  90. + Ogre::StringConverter::toString(textures[i].palette_y) + "\" bpp=\""
  91. + Ogre::StringConverter::toString(textures[i].bpp) + "\"."
  92. );
  93. CreateTextureFromVram(
  94. pixel_box, vram, textures[i].start_x, textures[i].start_y,
  95. textures[i].palette_x, textures[i].palette_y,
  96. textures[i].texture_x, textures[i].texture_y, textures[i].bpp, true
  97. );
  98. }
  99. Ogre::Image image;
  100. image.loadDynamicImage(
  101. (Ogre::uchar*) pixel_box.data, mesh_data.tex_width, mesh_data.tex_height,
  102. Ogre::PF_R8G8B8A8
  103. );
  104. image.save(texture_file_name);
  105. buffer->unlock();
  106. return;
  107. }
  108. void
  109. CreateMaterial(
  110. const Ogre::String& material_name, const Ogre::String& material_file_name,
  111. const Ogre::String& texture_name, const Ogre::String& vertex_program,
  112. const Ogre::String& fragment_program
  113. ){
  114. Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(
  115. material_name, "General"
  116. );
  117. Ogre::Technique* tech = material->getTechnique(0);
  118. Ogre::Pass* pass1 = tech->getPass(0);
  119. pass1->setVertexColourTracking(Ogre::TVC_AMBIENT);
  120. //pass1->setCullingMode(Ogre::CULL_NONE);
  121. if (texture_name != ""){
  122. pass1->setAlphaRejectFunction(Ogre::CMPF_GREATER);
  123. pass1->setAlphaRejectValue(0);
  124. Ogre::TextureUnitState* tex = pass1->createTextureUnitState();
  125. tex->setTextureName(texture_name);
  126. tex->setNumMipmaps(-1);
  127. tex->setTextureFiltering(Ogre::TFO_NONE);
  128. }
  129. if (vertex_program != "") pass1->setVertexProgram(vertex_program, true);
  130. if (fragment_program != "")
  131. pass1->setFragmentProgram(fragment_program, true);
  132. Ogre::MaterialSerializer mat;
  133. mat.exportMaterial(material, material_file_name);
  134. }
  135. void AddTexture(
  136. TexForGen& texture, const MeshData& data, VectorTexForGen& textures,
  137. Logger* logger
  138. ){
  139. for (unsigned int i = 0; i < textures.size(); ++ i){
  140. if (texture == textures[ i ]){
  141. texture.start_x = textures[ i ].start_x;
  142. texture.start_y = textures[ i ].start_y;
  143. return;
  144. }
  145. }
  146. /*
  147. if (logger != NULL){
  148. logger->Log(
  149. "New Texture: X:" + ToHexString(texture.texture_x, 4, '0')
  150. + ", Y:" + ToHexString(texture.texture_y, 4, '0') + ", CLUTX:"
  151. + ToHexString(texture.palette_x, 4, '0') + ", CLUTY:"
  152. + ToHexString(texture.palette_y, 4, '0') + ", bpp:"
  153. + ToHexString(texture.bpp, 4, '0') + "\n"
  154. );
  155. }
  156. */
  157. float start_x = 0;
  158. float start_y = 0;
  159. if (textures.size() > 0){
  160. start_x = float(textures[ textures.size() - 1 ].start_x);
  161. start_y = float(textures[ textures.size() - 1 ].start_y);
  162. if (start_x + 256 >= data.tex_width){
  163. if (start_y + 256 >= data.tex_height){
  164. if (logger != NULL){
  165. logger->Log(
  166. "[ERROR] Can't add anymore textures. Increase tex size.\n"
  167. );
  168. }
  169. return;
  170. }
  171. start_x = 0;
  172. start_y += 256;
  173. }
  174. else start_x += 256;
  175. }
  176. texture.start_x = static_cast<int>(start_x);
  177. texture.start_y = static_cast<int>(start_y);
  178. textures.push_back(texture);
  179. /*
  180. if (logger != NULL){
  181. logger->Log(
  182. "Startx:" + ToHexString(texture.start_x, 4, '0')
  183. + ", Starty:" + ToHexString(texture.start_y, 4, '0') + "\n"
  184. );
  185. }
  186. */
  187. }
  188. void AddTransparency(u32& colour, const bool transparency, const bool stp){
  189. if (transparency == false){
  190. if (stp == false && (colour & 0xffffff00) == 0) colour |= 0;
  191. else colour |= 255;
  192. }
  193. else{
  194. if (stp == false && (colour & 0xffffff00) == 0) colour |= 0;
  195. else if (stp == false && (colour & 0xffffff00) != 0) colour |= 255;
  196. else if (stp == true && (colour & 0xffffff00) == 0) colour |= 255;
  197. else if (stp == true && (colour & 0xffffff00) != 0) colour |= 255 / 4;
  198. }
  199. }