optimized_texture.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:5k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "optimized_texture.h"
  2. COptimizedTexture::COptimizedTexture()
  3. {
  4. tex = 0;
  5. tex_data = 0;
  6. maxw = 1024;
  7. maxh = 1024;
  8. texw = 0;
  9. texh = 0;
  10. pitch = 0;
  11. }
  12. void COptimizedTexture::Reset()
  13. {
  14. obj_list.clear();
  15. placer.Init();
  16. texw = 0;
  17. texh = 0;
  18. pitch = 0;
  19. if(tex_data)
  20. {
  21. hge->Texture_Unlock(tex);
  22. tex_data = 0;
  23. }
  24. if(tex)
  25. {
  26. hge->Texture_Free(tex);
  27. tex = 0;
  28. }
  29. }
  30. bool COptimizedTexture::PlaceObject(CGfxObject *obj)
  31. {
  32. // find & reserve a place for the object
  33. CRectPlacement::TRect r(0, 0, obj->GetWidth(), obj->GetHeight());
  34. if(placer.AddAtEmptySpotAutoGrow(&r, maxw, maxh))
  35. {
  36. obj->Place(r.x, r.y);
  37. obj_list.push_back(obj);
  38. return true;
  39. }
  40. return false;
  41. }
  42. void COptimizedTexture::AddNoTextureObject(CGfxObject *obj)
  43. {
  44. obj->Place(0,0);
  45. obj_list.push_back(obj);
  46. }
  47. bool COptimizedTexture::Create()
  48. {
  49. // create texture
  50. texw = placer.GetW();
  51. texh = placer.GetH();
  52. tex = hge->Texture_Create(texw, texh);
  53. if(!tex)
  54. {
  55. SysLog("Can't create target texture.n");
  56. return false;
  57. }
  58. // get hardware width
  59. pitch = hge->Texture_GetWidth(tex, false);
  60. // lock texture
  61. tex_data = (CColor *)hge->Texture_Lock(tex);
  62. if(!tex_data)
  63. {
  64. SysLog("Can't lock target texture.n");
  65. return false;
  66. }
  67. // clear texture
  68. memset(tex_data, 0, sizeof(CColor) * pitch * hge->Texture_GetHeight(tex, false));
  69. return true;
  70. }
  71. bool COptimizedTexture::CopyData()
  72. {
  73. GfxObjIterator it;
  74. CGfxObject *obj;
  75. int i;
  76. int src_x, src_y;
  77. int tgt_x, tgt_y;
  78. HTEXTURE source_tex;
  79. CColor *source_data;
  80. int source_pitch;
  81. for(it = obj_list.begin(); it != obj_list.end(); it++)
  82. {
  83. obj = *it;
  84. source_tex = obj->GetTexture();
  85. source_pitch = hge->Texture_GetWidth(source_tex, false);
  86. source_data = (CColor *)hge->Texture_Lock(source_tex, true);
  87. if(!source_data)
  88. {
  89. SysLog("Can't lock source texture for "%s"n", obj->GetName());
  90. return false;
  91. }
  92. obj->GetSourcePos(&src_x, &src_y);
  93. obj->GetTargetPos(&tgt_x, &tgt_y);
  94. for(i = 0; i < obj->GetHeight(); i++)
  95. {
  96. memcpy(&tex_data[tgt_y * pitch + tgt_x],
  97.    &source_data[src_y * source_pitch + src_x],
  98.    sizeof(CColor) * int(obj->GetWidth()));
  99. src_y++;
  100. tgt_y++;
  101. }
  102. hge->Texture_Unlock(source_tex);
  103. }
  104. return true;
  105. }
  106. bool COptimizedTexture::OptimizeAlpha()
  107. {
  108. CColor *buf;
  109. int i,j,k,l;
  110. int r,g,b;
  111. int count;
  112. if(!tex_data || !pitch)
  113. {
  114. SysLog("No texture generated to optimize alpha.n");
  115. return false;
  116. }
  117. buf = tex_data;
  118. for(i=0; i<texh; i++)
  119. for(j=0; j<texw; j++)
  120. if(!buf[i*pitch+j].a)
  121. {
  122. count = 0;
  123. r=g=b = 0;
  124. for(k=-1; k<=1; k++)
  125. for(l=-1; l<=1; l++)
  126. if(i+k >= 0 && i+k < texh &&
  127.    j+l >= 0 && j+l < texw &&
  128.    buf[(i+k)*pitch + (j+l)].a)
  129. {
  130. r += buf[(i+k)*pitch + (j+l)].r;
  131. g += buf[(i+k)*pitch + (j+l)].g;
  132. b += buf[(i+k)*pitch + (j+l)].b;
  133. count++;
  134. }
  135. if(count)
  136. {
  137. buf[i*pitch+j].r = unsigned char(r / count);
  138. buf[i*pitch+j].g = unsigned char(g / count);
  139. buf[i*pitch+j].b = unsigned char(b / count);
  140. }
  141. }
  142. return true;
  143. }
  144. bool COptimizedTexture::Save(char *filename)
  145. {
  146. FILE *fp;
  147. if(!tex_data || !pitch)
  148. {
  149. SysLog("No texture generated to save: %sn", filename);
  150. return false;
  151. }
  152. fp=fopen(filename,"wb");
  153. if(!fp)
  154. {
  155. SysLog("Can't create texture file: %sn", filename);
  156. return false;
  157. }
  158. if(!Write32BitPNGWithPitch(fp, tex_data, true, texw, texh, pitch))
  159. {
  160. fclose(fp);
  161. SysLog("Error writing data: %sn", filename);
  162. return false;
  163. }
  164. fclose(fp);
  165. return true;
  166. }
  167. bool COptimizedTexture::SaveDescriptions(char *resfile, char *texfile, char *texname)
  168. {
  169. GfxObjIterator it;
  170. FILE *fp;
  171. // check for data to be available
  172. if(!GetNumPlaced())
  173. {
  174. SysLog("No descriptions to save: %sn", resfile);
  175. return false;
  176. }
  177. // create resource file
  178. fp=fopen(resfile,"w");
  179. if(!fp)
  180. {
  181. SysLog("Can't create description file: %sn", resfile);
  182. return false;
  183. }
  184. // save texture description
  185. if(texfile && texname)
  186. {
  187. fprintf(fp, "Texture %sn", texname);
  188. fprintf(fp, "{n");
  189. fprintf(fp, " filename = "%s"n", texfile);
  190. fprintf(fp, " resgroup = %dn", (*obj_list.begin())->GetResGroup());
  191. fprintf(fp, "}nn");
  192. }
  193. // save object descriptions
  194. for(it = obj_list.begin(); it != obj_list.end(); it++)
  195. {
  196. if(!(*it)->SaveDescription(fp, texname))
  197. {
  198. fclose(fp);
  199. SysLog("Error writing description: %sn", (*it)->GetName());
  200. return false;
  201. }
  202. fprintf(fp,"n");
  203. }
  204. fclose(fp);
  205. return true;
  206. }