ddutil.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #include "std.h"
  2. #include "ddutil.h"
  3. #include "asmcoder.h"
  4. #include "gxcanvas.h"
  5. #include "gxruntime.h"
  6. extern gxRuntime *gx_runtime;
  7. #include "..\..\freeimage241\source\freeimage.h"
  8. static AsmCoder asm_coder;
  9. static void calcShifts( unsigned mask,unsigned char *shr,unsigned char *shl ){
  10. if( mask ){
  11. for( *shl=0;!(mask&1);++*shl,mask>>=1 ){}
  12. for( *shr=8;mask&1;--*shr,mask>>=1 ){}
  13. }else *shr=*shl=0;
  14. }
  15. PixelFormat::~PixelFormat(){
  16. if( plot_code ){
  17. VirtualFree( plot_code,0,MEM_RELEASE );
  18. }
  19. }
  20. void PixelFormat::setFormat( const DDPIXELFORMAT &pf ){
  21. if( plot_code ){
  22. VirtualFree( plot_code,0,MEM_RELEASE );
  23. }
  24. if( !(pf.dwFlags & DDPF_RGB) ){
  25. memset( this,0,sizeof(*this) );
  26. return;
  27. }
  28. plot_code=(char*)VirtualAlloc( 0,128,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE );
  29. point_code=plot_code+64;
  30. depth=pf.dwRGBBitCount;
  31. amask=pf.dwRGBAlphaBitMask;
  32. rmask=pf.dwRBitMask;
  33. gmask=pf.dwGBitMask;
  34. bmask=pf.dwBBitMask;
  35. pitch=depth/8;argbfill=0;
  36. if( !amask ) argbfill|=0xff000000;
  37. if( !rmask ) argbfill|=0x00ff0000;
  38. if( !gmask ) argbfill|=0x0000ff00;
  39. if( !bmask ) argbfill|=0x000000ff;
  40. calcShifts( amask,&ashr,&ashl );ashr+=24;
  41. calcShifts( rmask,&rshr,&rshl );rshr+=16;
  42. calcShifts( gmask,&gshr,&gshl );gshr+=8;
  43. calcShifts( bmask,&bshr,&bshl );
  44. plot=(Plot)(void*)plot_code;
  45. point=(Point)(void*)point_code;
  46. asm_coder.CodePlot( plot_code,depth,amask,rmask,gmask,bmask );
  47. asm_coder.CodePoint( point_code,depth,amask,rmask,gmask,bmask );
  48. }
  49. static void adjustTexSize( int *width,int *height,IDirect3DDevice7 *dir3dDev ){
  50. D3DDEVICEDESC7 ddDesc={0};
  51. if( dir3dDev->GetCaps( &ddDesc )<0 ){
  52. *width=*height=256;
  53. return;
  54. }
  55. int w=*width,h=*height,min,max;
  56. //make power of 2
  57. //Try *always* making POW2 size to fix GF6800 non-pow2 tex issue
  58. // if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 ){
  59. for( w=1;w<*width;w<<=1 ){}
  60. for( h=1;h<*height;h<<=1 ){}
  61. // }
  62. //make square
  63. if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ){
  64. if( w>h ) h=w;
  65. else w=h;
  66. }
  67. //check aspect ratio
  68. if( max=ddDesc.dwMaxTextureAspectRatio ){
  69. int asp=w>h ? w/h : h/w;
  70. if( asp>max ){
  71. if( w>h ) h=w/max;
  72. else w=h/max;
  73. }
  74. }
  75. //clamp size
  76. if( (min=ddDesc.dwMinTextureWidth) && w<min ) w=min;
  77. if( (min=ddDesc.dwMinTextureHeight) && h<min ) h=min;
  78. if( (max=ddDesc.dwMaxTextureWidth) && w>max ) w=max;
  79. if( (max=ddDesc.dwMaxTextureHeight) && h>max ) h=max;
  80. *width=w;*height=h;
  81. }
  82. static ddSurf *createSurface( int width,int height,int pitch,void *bits,IDirectDraw7 *dirDraw ){
  83. DDSURFACEDESC2 desc={sizeof(desc)};
  84. desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_LPSURFACE|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_CAPS;
  85. desc.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
  86. desc.dwWidth=width;desc.dwHeight=height;
  87. desc.lPitch=pitch;desc.lpSurface=bits;
  88. desc.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
  89. desc.ddpfPixelFormat.dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS;
  90. desc.ddpfPixelFormat.dwRGBBitCount=32;
  91. desc.ddpfPixelFormat.dwRBitMask=0xff0000;
  92. desc.ddpfPixelFormat.dwGBitMask=0x00ff00;
  93. desc.ddpfPixelFormat.dwBBitMask=0x0000ff;
  94. desc.ddpfPixelFormat.dwRGBAlphaBitMask=0xff000000;
  95. ddSurf *surf;
  96. if( dirDraw->CreateSurface( &desc,&surf,0 )>=0 ) return surf;
  97. return 0;
  98. }
  99. static void buildMask( ddSurf *surf ){
  100. DDSURFACEDESC2 desc={sizeof(desc)};
  101. surf->Lock( 0,&desc,DDLOCK_WAIT,0 );
  102. unsigned char *surf_p=(unsigned char*)desc.lpSurface;
  103. PixelFormat fmt( desc.ddpfPixelFormat );
  104. for( int y=0;y<desc.dwHeight;++y ){
  105. unsigned char *p=surf_p;
  106. for( int x=0;x<desc.dwWidth;++x ){
  107. unsigned argb=fmt.getPixel( p );
  108. unsigned rgb=argb&0xffffff;
  109. unsigned a=rgb ? 0xff000000 : 0;
  110. fmt.setPixel( p,a|rgb );
  111. p+=fmt.getPitch();
  112. }
  113. surf_p+=desc.lPitch;
  114. }
  115. surf->Unlock( 0 );
  116. }
  117. static void buildAlpha( ddSurf *surf,bool whiten ){
  118. DDSURFACEDESC2 desc={sizeof(desc)};
  119. surf->Lock( 0,&desc,DDLOCK_WAIT,0 );
  120. unsigned char *surf_p=(unsigned char*)desc.lpSurface;
  121. PixelFormat fmt( desc.ddpfPixelFormat );
  122. for( int y=0;y<desc.dwHeight;++y ){
  123. unsigned char *p=surf_p;
  124. for( int x=0;x<desc.dwWidth;++x ){
  125. unsigned argb=fmt.getPixel( p );
  126. unsigned alpha=(((argb>>16)&0xff)+((argb>>8)&0xff)+(argb&0xff))/3;
  127. argb=(alpha<<24) | (argb & 0xffffff);
  128. if( whiten ) argb|=0xffffff;
  129. fmt.setPixel( p,argb );
  130. p+=fmt.getPitch();
  131. }
  132. surf_p+=desc.lPitch;
  133. }
  134. surf->Unlock( 0 );
  135. }
  136. void ddUtil::buildMipMaps( ddSurf *surf ){
  137. DDSURFACEDESC2 desc={sizeof(desc)};
  138. surf->GetSurfaceDesc( &desc );
  139. if( !(desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) ) return;
  140. if( !(desc.ddpfPixelFormat.dwFlags & DDPF_RGB) ) return;
  141. DDSCAPS2 caps={0};
  142. caps.dwCaps=DDSCAPS_TEXTURE;
  143. caps.dwCaps2=DDSCAPS2_MIPMAPSUBLEVEL;
  144. IDirectDrawSurface7 *src=surf,*dest;
  145. while( src->GetAttachedSurface( &caps,&dest )>=0 ){
  146. DDSURFACEDESC2 src_desc={sizeof(src_desc)};
  147. if( src->Lock( 0,&src_desc,DDLOCK_WAIT,0 )<0 ) abort();
  148. unsigned char *src_p=(unsigned char*)src_desc.lpSurface;
  149. PixelFormat src_fmt( src_desc.ddpfPixelFormat );
  150. DDSURFACEDESC2 dest_desc={sizeof(dest_desc)};
  151. if( dest->Lock( 0,&dest_desc,DDLOCK_WAIT,0 )<0 ) abort();
  152. unsigned char *dest_p=(unsigned char *)dest_desc.lpSurface;
  153. PixelFormat dest_fmt( dest_desc.ddpfPixelFormat );
  154. if( src_desc.dwWidth==1 ){
  155. for( int y=0;y<dest_desc.dwHeight;++y ){
  156. unsigned p1=src_fmt.getPixel( src_p );
  157. unsigned p2=src_fmt.getPixel( src_p+src_desc.lPitch );
  158. unsigned argb=
  159. ((p1&0xfefefefe)>>1)+((p2&0xfefefefe)>>1);
  160. argb+=( (
  161. (p1&0x01010101)+(p2&0x01010101) )>>1 ) & 0x01010101;
  162. dest_fmt.setPixel( dest_p,argb );
  163. src_p+=src_desc.lPitch*2;
  164. dest_p+=dest_desc.lPitch;
  165. }
  166. }else if( src_desc.dwHeight==1 ){
  167. for( int x=0;x<dest_desc.dwWidth;++x ){
  168. unsigned p1=src_fmt.getPixel( src_p );
  169. unsigned p2=src_fmt.getPixel( src_p+src_fmt.getPitch() );
  170. unsigned argb=
  171. ((p1&0xfefefefe)>>1)+((p2&0xfefefefe)>>1);
  172. argb+=( (
  173. (p1&0x01010101)+(p2&0x01010101) )>>1 ) & 0x01010101;
  174. dest_fmt.setPixel( dest_p,argb );
  175. src_p+=src_fmt.getPitch()*2;
  176. dest_p+=dest_fmt.getPitch();
  177. }
  178. }else{
  179. for( int y=0;y<dest_desc.dwHeight;++y ){
  180. unsigned char *src_t=src_p;
  181. unsigned char *dest_t=dest_p;
  182. for( int x=0;x<dest_desc.dwWidth;++x ){
  183. unsigned p1=src_fmt.getPixel( src_t );
  184. unsigned p2=src_fmt.getPixel( src_t+src_fmt.getPitch() );
  185. unsigned p3=src_fmt.getPixel( src_t+src_desc.lPitch+src_fmt.getPitch() );
  186. unsigned p4=src_fmt.getPixel( src_t+src_desc.lPitch );
  187. unsigned argb=
  188. ((p1&0xfcfcfcfc)>>2)+((p2&0xfcfcfcfc)>>2)+
  189. ((p3&0xfcfcfcfc)>>2)+((p4&0xfcfcfcfc)>>2);
  190. argb+=( (
  191. (p1&0x03030303)+(p2&0x03030303)+
  192. (p3&0x03030303)+(p4&0x03030303) )>>2 ) & 0x03030303;
  193. dest_fmt.setPixel( dest_t,argb );
  194. src_t+=src_fmt.getPitch()*2;
  195. dest_t+=dest_fmt.getPitch();
  196. }
  197. src_p+=src_desc.lPitch*2;
  198. dest_p+=dest_desc.lPitch;
  199. }
  200. }
  201. src->Unlock( 0 );
  202. dest->Unlock( 0 );
  203. dest->Release();
  204. src=dest;
  205. }
  206. }
  207. void ddUtil::copy( ddSurf *dest,int dx,int dy,int dw,int dh,ddSurf *src,int sx,int sy,int sw,int sh ){
  208. DDSURFACEDESC2 src_desc={sizeof(src_desc)};
  209. src->Lock( 0,&src_desc,DDLOCK_WAIT,0 );
  210. PixelFormat src_fmt( src_desc.ddpfPixelFormat );
  211. unsigned char *src_p=(unsigned char*)src_desc.lpSurface;
  212. src_p+=src_desc.lPitch*sy+src_fmt.getPitch()*sx;
  213. DDSURFACEDESC2 dest_desc={sizeof(dest_desc)};
  214. dest->Lock( 0,&dest_desc,DDLOCK_WAIT,0 );
  215. PixelFormat dest_fmt( dest_desc.ddpfPixelFormat );
  216. unsigned char *dest_p=(unsigned char *)dest_desc.lpSurface;
  217. dest_p+=dest_desc.lPitch*dy+dest_fmt.getPitch()*dx;
  218. for( int y=0;y<dh;++y ){
  219. unsigned char *dest=dest_p;
  220. unsigned char *src=src_p+src_desc.lPitch*(y*sh/dh);
  221. for( int x=0;x<dw;++x ){
  222. dest_fmt.setPixel( dest,src_fmt.getPixel( src+src_fmt.getPitch()*(x*sw/dw) ) );
  223. dest+=dest_fmt.getPitch();
  224. }
  225. dest_p+=dest_desc.lPitch;
  226. }
  227. src->Unlock( 0 );
  228. dest->Unlock( 0 );
  229. }
  230. ddSurf *ddUtil::createSurface( int w,int h,int flags,gxGraphics *gfx ){
  231. DDSURFACEDESC2 desc={sizeof(desc)};
  232. desc.dwFlags=DDSD_CAPS;
  233. int hi=flags & gxCanvas::CANVAS_TEX_HICOLOR?1:0;
  234. if( w ){ desc.dwWidth=w;desc.dwFlags|=DDSD_WIDTH; }
  235. if( h ){ desc.dwHeight=h;desc.dwFlags|=DDSD_HEIGHT; }
  236. if( flags & gxCanvas::CANVAS_TEX_MASK ){
  237. desc.dwFlags|=DDSD_PIXELFORMAT;
  238. desc.ddpfPixelFormat=gfx->texRGBMaskFmt[hi];
  239. }else if( flags & gxCanvas::CANVAS_TEX_RGB ){
  240. desc.dwFlags|=DDSD_PIXELFORMAT;
  241. desc.ddpfPixelFormat=(flags&gxCanvas::CANVAS_TEX_ALPHA)?gfx->texRGBAlphaFmt[hi]:gfx->texRGBFmt[hi];
  242. }else if( flags & gxCanvas::CANVAS_TEX_ALPHA ){
  243. desc.dwFlags|=DDSD_PIXELFORMAT;
  244. desc.ddpfPixelFormat=gfx->texAlphaFmt[hi];
  245. }else if( flags & gxCanvas::CANVAS_TEXTURE ){
  246. desc.dwFlags|=DDSD_PIXELFORMAT;
  247. desc.ddpfPixelFormat=gfx->primFmt;
  248. }
  249. if( flags & gxCanvas::CANVAS_TEXTURE ){
  250. desc.ddsCaps.dwCaps|=DDSCAPS_TEXTURE;
  251. if( !(flags & gxCanvas::CANVAS_TEX_VIDMEM) ){
  252. desc.ddsCaps.dwCaps2|=DDSCAPS2_TEXTUREMANAGE;
  253. if( flags & gxCanvas::CANVAS_TEX_MIPMAP ){
  254. desc.ddsCaps.dwCaps|=DDSCAPS_MIPMAP|DDSCAPS_COMPLEX;
  255. }
  256. }
  257. if( flags & (gxCanvas::CANVAS_TEX_CUBE) ){
  258. desc.ddsCaps.dwCaps|=DDSCAPS_COMPLEX;
  259. desc.ddsCaps.dwCaps2|=DDSCAPS2_CUBEMAP|DDSCAPS2_CUBEMAP_ALLFACES;
  260. }
  261. adjustTexSize( (int*)&desc.dwWidth,(int*)&desc.dwHeight,gfx->dir3dDev );
  262. }else{
  263. desc.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
  264. if( flags & gxCanvas::CANVAS_HIGHCOLOR ){
  265. desc.dwFlags|=DDSD_PIXELFORMAT;
  266. desc.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY;
  267. desc.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
  268. desc.ddpfPixelFormat.dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS;
  269. desc.ddpfPixelFormat.dwRGBBitCount=32;
  270. desc.ddpfPixelFormat.dwRBitMask=0xff0000;
  271. desc.ddpfPixelFormat.dwGBitMask=0x00ff00;
  272. desc.ddpfPixelFormat.dwBBitMask=0x0000ff;
  273. desc.ddpfPixelFormat.dwRGBAlphaBitMask=0xff000000;
  274. }else if( flags & gxCanvas::CANVAS_NONDISPLAY ){
  275. desc.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY;
  276. }
  277. }
  278. ddSurf *surf;
  279. if( gfx->dirDraw->CreateSurface( &desc,&surf,0 )>=0 ) return surf;
  280. if( desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN ){
  281. if( !(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) ){
  282. //try again in system memory!
  283. desc.ddsCaps.dwCaps|=DDSCAPS_SYSTEMMEMORY;
  284. if( gfx->dirDraw->CreateSurface( &desc,&surf,0 )>=0 ) return surf;
  285. }
  286. }
  287. return 0;
  288. }
  289. //Tom Speed's DXTC loader
  290. //
  291. IDirectDrawSurface7 *loadDXTC(const char* filename,gxGraphics *gfx)
  292. {
  293. HRESULT hr;
  294. DDSURFACEDESC2 ddsd;
  295. DDSURFACEDESC2 fileddsd;
  296. char magicID[4];
  297. FILE *fp;
  298. /* try to open the file */
  299. fp = fopen(filename, "rb");
  300. if(!fp) return NULL;
  301. /* valid DDS? */
  302. fread(magicID, 1, 4, fp);
  303. if (strncmp(magicID, "DDS ", 4) != 0)
  304. {
  305. fclose(fp);
  306. return NULL;
  307. }
  308. /* get the DXTC file surface description */
  309. fread(&fileddsd, sizeof(DDSURFACEDESC2), 1, fp);
  310. if (fileddsd.dwSize != sizeof(DDSURFACEDESC2))
  311. {
  312. fclose(fp);
  313. return NULL;
  314. }
  315. /* copy the fileddsd before we manipulate it so you
  316. can get neccessary info you want about it later */
  317. memcpy(&ddsd, &fileddsd,sizeof(DDSURFACEDESC2));
  318. /* remove unwanted flags if they exist */
  319. //not sure if this is needed, works without it though
  320. //ddsd.dwFlags &= ~DDSD_LINEARSIZE;
  321. int blockSize = 0;
  322. int chunkSize = 0;
  323. if(ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1)
  324. blockSize = 8; // DXT1
  325. if(ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT3)
  326. blockSize = 16; // DXT3
  327. if(ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT5)
  328. blockSize = 16; // DXT5
  329. /* if it isn't a format we support, exit */
  330. if (blockSize == 0)
  331. {
  332. fclose(fp);
  333. return NULL;
  334. }
  335. /* add texture manage flag */
  336. ddsd.ddsCaps.dwCaps2|=DDSCAPS2_TEXTUREMANAGE;
  337. /* Create the new DXTC surface using the DDSURFACEDESC2
  338. we read in from the file */
  339. IDirectDrawSurface7 * newSurf = NULL;
  340. hr = gfx->dirDraw->CreateSurface(&ddsd, &newSurf, NULL);
  341. if(FAILED(hr))
  342. {
  343. fclose(fp);
  344. return NULL;
  345. }
  346. /* Define what type of child surfaces we may wish
  347. to access, in this case MipMaps */
  348. DDSCAPS2 mipmapddsd;
  349. ZeroMemory(&mipmapddsd,sizeof(DDSCAPS2));
  350. mipmapddsd.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_MIPMAP|DDSCAPS_COMPLEX;
  351. /* pointers used when iterating through mipmaps */
  352. IDirectDrawSurface7 *topDDS = NULL;
  353. IDirectDrawSurface7 *nextDDS = NULL;
  354. topDDS = newSurf;
  355. topDDS->AddRef();
  356. while(TRUE)
  357. {
  358. /* get a description of this surface */
  359. hr = topDDS->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);
  360. if(FAILED(hr))
  361. {
  362. fclose(fp);
  363. topDDS->Release();
  364. newSurf->Release();
  365. nextDDS->Release();
  366. return NULL;
  367. }
  368. /* how big the raw data is for this surface */
  369. chunkSize = ((ddsd.dwWidth+3)/4) * ((ddsd.dwHeight+3)/4) * blockSize;
  370. /* read in the raw DXTC surface data */
  371. if(!fread(ddsd.lpSurface, chunkSize, 1, fp))
  372. {
  373. fclose(fp);
  374. topDDS->Release();
  375. newSurf->Release();
  376. nextDDS->Release();
  377. return NULL;
  378. }
  379. topDDS->Unlock(NULL);
  380. /* Get next mipmap in chain, or exit the loop if there's no more */
  381. hr = topDDS->GetAttachedSurface(&mipmapddsd,&nextDDS);
  382. if(FAILED(hr))
  383. {
  384. fclose(fp);
  385. topDDS->Release();
  386. break;
  387. }
  388. topDDS->Release();
  389. topDDS = nextDDS;
  390. nextDDS->Release();
  391. }
  392. return newSurf;
  393. }
  394. ddSurf *ddUtil::loadSurface( const std::string &f,int flags,gxGraphics *gfx ){
  395. int i=f.find( ".dds" );
  396. if( i!=string::npos && i+4==f.size() ){
  397. //dds file!
  398. ddSurf *surf=loadDXTC( f.c_str(),gfx );
  399. return surf;
  400. }
  401. FreeImage_Initialise();
  402. FREE_IMAGE_FORMAT fmt=FreeImage_GetFileType( f.c_str(),f.size() );
  403. if( fmt==FIF_UNKNOWN ){
  404. int n=f.find( "." );if( n==string::npos ) return 0;
  405. fmt=FreeImage_GetFileTypeFromExt( f.substr(n+1).c_str() );
  406. if( fmt==FIF_UNKNOWN ) return 0;
  407. }
  408. FIBITMAP *t_dib=FreeImage_Load( fmt,f.c_str(),0 );
  409. if( !t_dib ) return 0;
  410. bool trans=FreeImage_GetBPP( t_dib )==32 || FreeImage_IsTransparent( t_dib );
  411. FIBITMAP *dib=FreeImage_ConvertTo32Bits( t_dib );
  412. if( dib ) FreeImage_Unload( t_dib );
  413. else dib=t_dib;
  414. int width=FreeImage_GetWidth(dib);
  415. int height=FreeImage_GetHeight(dib);
  416. int pitch=FreeImage_GetPitch(dib);
  417. void *bits=FreeImage_GetBits(dib);
  418. ddSurf *src=::createSurface( width,height,pitch,bits,gfx->dirDraw );
  419. if( !src ){
  420. FreeImage_Unload( dib );
  421. return 0;
  422. }
  423. if( flags & gxCanvas::CANVAS_TEX_ALPHA ){
  424. if( flags & gxCanvas::CANVAS_TEX_MASK ){
  425. buildMask( src );
  426. }else if( !trans ){
  427. buildAlpha( src,(flags & gxCanvas::CANVAS_TEX_RGB)?false:true );
  428. }
  429. }else{
  430. unsigned char *p=(unsigned char *)bits;
  431. for( int k=0;k<height;++k ){
  432. unsigned char *t=p+3;
  433. for( int j=0;j<width;++j ){
  434. *t=0xff;t+=4;
  435. }
  436. p+=pitch;
  437. }
  438. }
  439. ddSurf *dest=createSurface( width,height,flags,gfx );
  440. if( !dest ){
  441. src->Release();
  442. FreeImage_Unload( dib );
  443. return 0;
  444. }
  445. int t_w=width,t_h=height;
  446. if( flags & gxCanvas::CANVAS_TEXTURE ) adjustTexSize( &t_w,&t_h,gfx->dir3dDev );
  447. copy( dest,0,0,t_w,t_h,src,0,height-1,width,-height );
  448. src->Release();
  449. FreeImage_Unload( dib );
  450. return dest;
  451. }