00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <assert.h>
00020 #include <time.h>
00021 #include "dxTextureContext7.h"
00022 #include "config_dxgsg7.h"
00023 #include "dxGraphicsStateGuardian7.h"
00024 #include "pnmImage.h"
00025
00026 static const DWORD g_LowByteMask = 0x000000FF;
00027
00028
00029
00030 #define PANDA_BGRA_ORDER
00031
00032 #ifdef PANDA_BGRA_ORDER
00033
00034
00035 #define GET_RED_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD >> 16) & g_LowByteMask))
00036 #define GET_BLUE_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD) & g_LowByteMask))
00037 #else
00038
00039 #define GET_RED_BYTE(PIXEL_DWORD) ((BYTE)(PIXEL_DWORD & g_LowByteMask))
00040 #define GET_BLUE_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD >> 16) & g_LowByteMask))
00041 #endif
00042
00043 #define GET_GREEN_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD >> 8) & g_LowByteMask))
00044 #define GET_ALPHA_BYTE(PIXEL_DWORD) ((BYTE)(((DWORD)PIXEL_DWORD) >> 24)) // unsigned >> shifts in 0's, so dont need to mask off upper bits
00045
00046 typedef enum {
00047 None,Conv32to32,Conv32to32_NoAlpha,Conv32to24,Conv32to16_X555,
00048 Conv32to16_1555,Conv32to16_0565,Conv32to16_4444,Conv24to32,Conv24to24,
00049 Conv24to16_X555,Conv24to16_0565,ConvLum16to16_1555,ConvLum16to16_4444,
00050 ConvLum16to32,ConvLum16to16,ConvLum8to8,ConvLum8to24,ConvLum8to32,ConvLum8to16_X555,ConvLum8to16_0565,
00051 ConvAlpha8to16_4444,ConvAlpha8to32,ConvAlpha8to8
00052 } ConversionType;
00053
00054 #ifndef NDEBUG
00055 char *ConvNameStrs[] = {"None","Conv32to32","Conv32to32_NoAlpha","Conv32to24","Conv32to16_X555",
00056 "Conv32to16_1555","Conv32to16_0565","Conv32to16_4444","Conv24to32","Conv24to24",
00057 "Conv24to16_X555","Conv24to16_0565","ConvLum16to16_1555","ConvLum16to16_4444",
00058 "ConvLum16to32","ConvLum16to16","ConvLum8to8","ConvLum8to24","ConvLum8to32",
00059 "ConvLum8to16_X555","ConvLum8to16_0565","ConvAlpha8to16_4444","ConvAlpha8to32","ConvAlpha8to8"
00060 };
00061 #endif
00062
00063 char *PandaFilterNameStrs[] = {"FT_nearest","FT_linear","FT_nearest_mipmap_nearest","FT_linear_mipmap_nearest",
00064 "FT_nearest_mipmap_linear", "FT_linear_mipmap_linear"
00065 };
00066
00067 TypeHandle DXTextureContext7::_type_handle;
00068
00069 #define SWAPDWORDS(X,Y) { DWORD temp=X; X=Y; Y=temp; }
00070
00071 #ifdef _DEBUG
00072 static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) {
00073 static int iddpfnum=0;
00074 ostream *dbgout = &dxgsg7_cat.debug();
00075
00076 *dbgout << "DDPF[" << iddpfnum << "]: RGBBitCount:" << pddpf->dwRGBBitCount
00077 << " Flags:" << (void *)pddpf->dwFlags ;
00078
00079 if(pddpf->dwFlags & DDPF_RGB) {
00080 *dbgout << " RGBmask:" << (void *) (pddpf->dwRBitMask | pddpf->dwGBitMask | pddpf->dwBBitMask);
00081 *dbgout << " Rmask:" << (void *) (pddpf->dwRBitMask);
00082 }
00083
00084 if(pddpf->dwFlags & DDPF_ALPHAPIXELS) {
00085 *dbgout << " Amask:" << (void *) pddpf->dwRGBAlphaBitMask;
00086 }
00087
00088 if(pddpf->dwFlags & DDPF_LUMINANCE) {
00089 *dbgout << " Lummask:" << (void *) pddpf->dwLuminanceBitMask;
00090 }
00091
00092 *dbgout << endl;
00093
00094 iddpfnum++;
00095 }
00096
00097 void PrintLastError(char *msgbuf) {
00098 DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
00099
00100 if(msgbuf==NULL) {
00101 LPVOID lpMsgBuf;
00102 dwFlags|=FORMAT_MESSAGE_ALLOCATE_BUFFER;
00103 FormatMessage( dwFlags,
00104 NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00105 (LPTSTR) &lpMsgBuf,0,NULL );
00106 MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
00107 LocalFree(lpMsgBuf);
00108 } else {
00109 FormatMessage( dwFlags,
00110 NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00111 (LPTSTR) msgbuf,500,NULL );
00112 }
00113 }
00114
00115 #endif
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 unsigned int DXTextureContext7::
00160 get_bits_per_pixel(PixelBuffer::Format format, int *alphbits) {
00161 *alphbits = 0;
00162 switch(format) {
00163 case PixelBuffer::F_alpha:
00164 *alphbits = 8;
00165 return 8;
00166 case PixelBuffer::F_color_index:
00167 case PixelBuffer::F_red:
00168 case PixelBuffer::F_green:
00169 case PixelBuffer::F_blue:
00170 case PixelBuffer::F_rgb332:
00171 case PixelBuffer::F_luminance_alphamask:
00172 *alphbits = 1;
00173 return 16;
00174 case PixelBuffer::F_luminance_alpha:
00175 *alphbits = 8;
00176 return 16;
00177 case PixelBuffer::F_luminance:
00178 return 8;
00179 case PixelBuffer::F_rgba4:
00180 *alphbits = 4;
00181 return 16;
00182 case PixelBuffer::F_rgba5:
00183 *alphbits = 1;
00184 return 16;
00185 case PixelBuffer::F_depth_component:
00186 case PixelBuffer::F_rgb5:
00187 return 16;
00188 case PixelBuffer::F_rgb8:
00189 case PixelBuffer::F_rgb:
00190 return 24;
00191 case PixelBuffer::F_rgba8:
00192 case PixelBuffer::F_rgba:
00193 *alphbits = 8;
00194 return 32;
00195 case PixelBuffer::F_rgbm:
00196 *alphbits = 1;
00197 return 32;
00198 case PixelBuffer::F_rgb12:
00199 return 36;
00200 case PixelBuffer::F_rgba12:
00201 *alphbits = 12;
00202 return 48;
00203 }
00204 return 8;
00205 }
00206
00207 HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWSURFACE7 pDDSurf) {
00208 HRESULT hr;
00209 DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
00210
00211 if(IsBadWritePtr(pDDSurf,sizeof(DWORD))) {
00212 dxgsg7_cat.error() << "ConvertPixBuftoDDSurf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n";
00213 exit(1);
00214 }
00215
00216 if(FAILED( hr = pDDSurf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) {
00217 dxgsg7_cat.error() << "CreateTexture failed: _surface->Lock() failed on texture! hr = " << ConvD3DErrorToString(hr) << "\n";
00218 return hr;
00219 }
00220
00221
00222
00223 DWORD lPitch = ddsd.lPitch;
00224 BYTE* pDDSurfBytes = (BYTE*)ddsd.lpSurface;
00225 DWORD dwOrigWidth=ddsd.dwWidth,dwOrigHeight=ddsd.dwHeight;
00226
00227 switch(ConvNeeded) {
00228 case Conv32to32:
00229 case Conv32to32_NoAlpha: {
00230
00231 #ifdef PANDA_BGRA_ORDER
00232 if(ConvNeeded==Conv32to32) {
00233 memcpy(pDDSurfBytes,(BYTE*) pbuf,dwOrigWidth*dwOrigHeight*sizeof(DWORD));
00234 } else {
00235 DWORD *pSrcWord = (DWORD *) pbuf;
00236 DWORD *pDstWord;
00237
00238
00239 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00240 pDstWord = (DWORD*)pDDSurfBytes;
00241 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00242 *pDstWord = *pSrcWord | 0xFF000000;
00243 }
00244 }
00245 }
00246 #else
00247 DWORD *pDstWord,*pSrcWord = (DWORD *) pbuf;
00248 DWORD dwAlphaMaskOn = (ConvNeeded==Conv32to32_NoAlpha) ? 0xFF000000 : 0x0;
00249
00250 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00251 pDstWord = (DWORD*)pDDSurfBytes;
00252 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00253 DWORD dwPixel = *pSrcWord;
00254
00255
00256
00257
00258 BYTE r,b;
00259
00260 b = GET_BLUE_BYTE(dwPixel);
00261 r = GET_RED_BYTE(dwPixel);
00262 *pDstWord = ((dwPixel & 0xff00ff00) | (r<<16) | b) | dwAlphaMaskOn;
00263 }
00264 }
00265 #endif
00266 break;
00267 }
00268
00269 case Conv32to16_1555:
00270 case Conv32to16_X555: {
00271 DWORD *pSrcWord = (DWORD *) pbuf;
00272 WORD *pDstWord;
00273
00274 unsigned short dwAlphaMaskOn = (ConvNeeded==Conv32to16_X555) ? 0x8000 : 0x0;
00275
00276 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00);
00277
00278 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00279 pDstWord = (WORD*)pDDSurfBytes;
00280
00281 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00282 BYTE r,g,b;
00283 DWORD dwPixel = *pSrcWord;
00284 unsigned short abit;
00285
00286
00287
00288
00289 abit = ((dwPixel>>16) & 0x00008000) | dwAlphaMaskOn;
00290 g = GET_GREEN_BYTE(dwPixel) >> 3;
00291 b = GET_BLUE_BYTE(dwPixel) >> 3;
00292 r = GET_RED_BYTE(dwPixel) >> 3;
00293
00294
00295
00296 *pDstWord = (abit | (r << 10)| (g << 5) | b);
00297 }
00298 }
00299 break;
00300 }
00301
00302 case Conv32to16_0565: {
00303 DWORD *pSrcWord = (DWORD *) pbuf;
00304 WORD *pDstWord;
00305
00306 assert(ddsd.ddpfPixelFormat.dwRBitMask==0xF800);
00307
00308
00309 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00310 pDstWord = (WORD*)pDDSurfBytes;
00311
00312 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00313 BYTE r,g,b;
00314 DWORD dwPixel = *pSrcWord;
00315
00316 g = GET_GREEN_BYTE(dwPixel) >> 2;
00317 b = GET_BLUE_BYTE(dwPixel) >> 3;
00318 r = GET_RED_BYTE(dwPixel) >> 3;
00319 *pDstWord = ((r << 11)| (g << 5) | b);
00320 }
00321 }
00322 break;
00323 }
00324
00325 case Conv32to16_4444: {
00326 DWORD *pSrcWord = (DWORD *) pbuf;
00327 WORD *pDstWord;
00328
00329 assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0xf000);
00330 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0f00);
00331
00332 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00333 pDstWord = (WORD*)pDDSurfBytes;
00334
00335 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00336 BYTE r,g,b,a;
00337 DWORD dwPixel = *pSrcWord;
00338
00339 a = GET_ALPHA_BYTE(dwPixel) >> 4;
00340 g = GET_GREEN_BYTE(dwPixel) >> 4;
00341 b = GET_BLUE_BYTE(dwPixel) >> 4;
00342 r = GET_RED_BYTE(dwPixel) >> 4;
00343
00344 *pDstWord = (a << 12) | (r << 8)| (g << 4) | b;
00345 }
00346 }
00347 break;
00348 }
00349
00350 case Conv32to24: {
00351
00352 DWORD *pSrcWord = (DWORD *) pbuf;
00353 BYTE *pDstWord;
00354
00355 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00356 pDstWord = (BYTE*)pDDSurfBytes;
00357
00358 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord+=3) {
00359 BYTE r,g,b;
00360 DWORD dwPixel = *pSrcWord;
00361
00362 r = GET_RED_BYTE(dwPixel);
00363 g = GET_GREEN_BYTE(dwPixel);
00364 b = GET_BLUE_BYTE(dwPixel);
00365
00366 *pDstWord = r;
00367 *(pDstWord+1) = g;
00368 *(pDstWord+2) = b;
00369 }
00370 }
00371 break;
00372 }
00373
00374
00375 case Conv24to24: {
00376 #ifdef PANDA_BGRA_ORDER
00377 memcpy(pDDSurfBytes,(BYTE*)pbuf,dwOrigHeight*dwOrigWidth*3);
00378 #else
00379 BYTE *pSrcWord = (BYTE *) pbuf;
00380 BYTE *pDstWord;
00381
00382 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00383 pDstWord = (BYTE*)pDDSurfBytes;
00384
00385 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord+=3) {
00386 BYTE r,g,b;
00387
00388 b = *pSrcWord;
00389 g = *(pSrcWord+1);
00390 r = *(pSrcWord+2);
00391
00392 *pDstWord = r;
00393 *(pDstWord+1) = g;
00394 *(pDstWord+2) = b;
00395 }
00396 }
00397 #endif
00398 break;
00399 }
00400
00401 case Conv24to16_X555: {
00402 BYTE *pSrcWord = (BYTE *) pbuf;
00403 WORD *pDstWord;
00404
00405 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00);
00406
00407
00408 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00409 pDstWord = (WORD*)pDDSurfBytes;
00410
00411 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
00412 BYTE r,g,b;
00413
00414 #ifdef PANDA_BGRA_ORDER
00415 b = *pSrcWord >> 3;
00416 r = *(pSrcWord+2) >> 3;
00417 #else
00418 r = *pSrcWord >> 3;
00419 b = *(pSrcWord+2) >> 3;
00420 #endif
00421 g = *(pSrcWord+1) >> 3;
00422
00423 *pDstWord = 0x8000 | (r << 10)| (g << 5) | b;
00424 }
00425 }
00426 break;
00427 }
00428
00429 case Conv24to16_0565: {
00430 BYTE *pSrcWord = (BYTE *) pbuf;
00431 WORD *pDstWord;
00432
00433 assert(ddsd.ddpfPixelFormat.dwRBitMask==0xF800);
00434
00435 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00436 pDstWord = (WORD*)pDDSurfBytes;
00437
00438 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
00439 BYTE r,g,b;
00440
00441 #ifdef PANDA_BGRA_ORDER
00442 b = *pSrcWord >> 3;
00443 g = *(pSrcWord+1) >> 2;
00444 r = *(pSrcWord+2) >> 3;
00445 #else
00446 r = *pSrcWord >> 3;
00447 g = *(pSrcWord+1) >> 2;
00448 b = *(pSrcWord+2) >> 3;
00449 #endif
00450
00451 *pDstWord = (r << 11)| (g << 5) | b;
00452 }
00453 }
00454 break;
00455 }
00456
00457 case Conv24to32: {
00458 BYTE *pSrcWord = (BYTE *) pbuf;
00459 DWORD *pDstWord;
00460
00461 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00462 pDstWord = (DWORD *)pDDSurfBytes;
00463
00464 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
00465 BYTE r,g,b;
00466
00467
00468
00469 #ifdef PANDA_BGRA_ORDER
00470 b = *pSrcWord;
00471 r = *(pSrcWord+2);
00472 #else
00473 r = *pSrcWord;
00474 b = *(pSrcWord+2);
00475 #endif
00476 g = *(pSrcWord+1);
00477
00478 *pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
00479 }
00480 }
00481 break;
00482 }
00483
00484 case ConvLum16to32: {
00485 WORD *pSrcWord = (WORD *) pbuf;
00486 DWORD *pDstWord;
00487
00488 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00489 pDstWord = (DWORD *)pDDSurfBytes;
00490
00491 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00492
00493
00494 DWORD dwPixel=*pSrcWord;
00495 BYTE lum,a;
00496
00497 a = dwPixel >> 8;
00498 lum = dwPixel & 0xFF;
00499 *pDstWord = (a<<24) | lum | (lum << 8) | (lum << 16);
00500 }
00501 }
00502 break;
00503 }
00504
00505 case ConvLum16to16_4444: {
00506 WORD *pSrcWord = (WORD *) pbuf;
00507 WORD *pDstWord;
00508
00509 assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0xf000);
00510
00511 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00512 pDstWord = (WORD*)pDDSurfBytes;
00513
00514 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00515 DWORD dwPixel=*pSrcWord;
00516 BYTE lum,a;
00517 dwPixel = *pSrcWord;
00518
00519 a = (BYTE)(dwPixel>>8) >> 4;
00520 lum = (BYTE)(dwPixel & 0x000000ff) >> 4;
00521
00522 *pDstWord = (a << 12) | lum | (lum << 4)| (lum << 8);
00523 }
00524 }
00525 break;
00526 }
00527
00528 case ConvLum16to16_1555: {
00529 WORD *pSrcWord = (WORD *) pbuf;
00530 WORD *pDstWord;
00531
00532 assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0x8000);
00533
00534 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00535 pDstWord = (WORD*)pDDSurfBytes;
00536
00537 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00538 WORD dwPixel=*pSrcWord;
00539 BYTE lum;
00540
00541 lum = (BYTE)(dwPixel & 0x00FF) >> 3;
00542
00543 *pDstWord = (dwPixel & 0x8000) | lum | (lum << 5) | (lum << 10);
00544 }
00545 }
00546 break;
00547 }
00548
00549 case ConvLum16to16: {
00550
00551 CopyMemory(pDDSurfBytes,pbuf,dwOrigWidth*dwOrigHeight*2);
00552 break;
00553 }
00554
00555 case ConvLum8to16_0565:
00556 case ConvLum8to16_X555: {
00557 BYTE *pSrcWord = (BYTE *) pbuf;
00558 WORD *pDstWord;
00559 DWORD FarShift,OrVal,MiddleRoundShift;
00560
00561 if(ConvNeeded==ConvLum8to16_X555) {
00562 FarShift=10; OrVal=0x8000;
00563 MiddleRoundShift = 3;
00564 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00);
00565 } else {
00566 FarShift=11; OrVal=0x0;
00567 MiddleRoundShift = 2;
00568 assert(ddsd.ddpfPixelFormat.dwRBitMask==0xF800);
00569 }
00570
00571 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
00572 pDstWord = (WORD*)pDDSurfBytes;
00573
00574 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00575 DWORD dwPixel=*pSrcWord,GrnVal;
00576 BYTE r;
00577
00578 r = (BYTE) dwPixel >> 3;
00579 GrnVal = (BYTE) dwPixel >> MiddleRoundShift;
00580
00581
00582
00583 *pDstWord = ((r << FarShift)| (GrnVal << 5) | r) | OrVal;
00584 }
00585 }
00586 break;
00587 }
00588
00589 case ConvLum8to8: {
00590 CopyMemory(pDDSurfBytes,pbuf,dwOrigWidth*dwOrigHeight);
00591 break;
00592 }
00593
00594 case ConvLum8to32: {
00595
00596
00597 BYTE *pSrcWord = (BYTE *) pbuf;
00598 DWORD *pDstWord;
00599
00600 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00601 pDstWord = (DWORD *)pDDSurfBytes;
00602
00603 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00604 DWORD dwPixel=*pSrcWord;
00605
00606 *pDstWord = 0xFF000000 | dwPixel | (dwPixel << 8) | (dwPixel<<16);
00607 }
00608 }
00609 break;
00610 }
00611
00612 case ConvLum8to24: {
00613
00614 BYTE *pSrcWord = (BYTE *) pbuf;
00615 BYTE *pDstWord;
00616
00617 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00618 pDstWord = (BYTE *)pDDSurfBytes;
00619
00620 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00621 DWORD dwPixel=*pSrcWord;
00622
00623 *pDstWord++ = dwPixel;
00624 *pDstWord++ = dwPixel;
00625 *pDstWord = dwPixel;
00626 }
00627 }
00628 break;
00629 }
00630
00631 case ConvAlpha8to32: {
00632
00633 BYTE *pSrcWord = (BYTE *) pbuf;
00634 DWORD *pDstWord;
00635
00636 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00637 pDstWord = (DWORD *)pDDSurfBytes;
00638
00639 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00640
00641 *pDstWord = (*pSrcWord << 24) | 0x00FFFFFF;
00642 }
00643 }
00644 break;
00645 }
00646
00647 case ConvAlpha8to16_4444: {
00648 BYTE *pSrcWord = (BYTE *) pbuf;
00649 WORD *pDstWord;
00650
00651 assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0xf000);
00652
00653 for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
00654 pDstWord = (WORD*)pDDSurfBytes;
00655
00656 for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
00657 WORD a = (BYTE)(*pSrcWord>>4);
00658 *pDstWord = (a << 12) | 0x0FFF;
00659 }
00660 }
00661 break;
00662 }
00663
00664 default:
00665 dxgsg7_cat.error() << "CreateTexture failed! unhandled texture conversion type: "<< ConvNeeded <<" \n";
00666 pDDSurf->Unlock(NULL);
00667 return E_INVALIDARG;
00668 }
00669
00670 pDDSurf->Unlock(NULL);
00671
00672 return S_OK;
00673 }
00674
00675 HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) {
00676
00677 HRESULT hr;
00678 DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
00679
00680 DWORD dwNumComponents=pixbuf->get_num_components();
00681
00682 assert(pixbuf->get_component_width()==sizeof(BYTE));
00683 assert(pixbuf->get_image_type()==PixelBuffer::T_unsigned_byte);
00684 assert((dwNumComponents==3) || (dwNumComponents==4));
00685
00686 BYTE *pbuf=pixbuf->_image.p();
00687
00688 if(IsBadWritePtr(pDDSurf,sizeof(DWORD))) {
00689 dxgsg7_cat.error() << "ConvertDDSurftoPixBuf failed: bad pDDSurf ptr value (" << ((void*)pDDSurf) << ")\n";
00690 exit(1);
00691 }
00692
00693 if(FAILED( hr = pDDSurf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) {
00694 dxgsg7_cat.error() << "ConvertDDSurftoPixBuf Lock() failed! hr = " << ConvD3DErrorToString(hr) << "\n";
00695 return hr;
00696 }
00697
00698 DWORD dwXWindowOffset=0,dwYWindowOffset=0;
00699 DWORD dwCopyWidth=ddsd.dwWidth,dwCopyHeight=ddsd.dwHeight;
00700
00701
00702
00703 LPDIRECTDRAWCLIPPER pDDClipper;
00704 hr = pDDSurf->GetClipper(&pDDClipper);
00705
00706 #ifdef _DEBUG
00707 if(FAILED(hr) && !((hr == DDERR_NOCLIPPERATTACHED) && dx_full_screen)) {
00708 dxgsg7_cat.error() << "ConvertDDSurftoPixBuf GetClipper failed! hr = " << ConvD3DErrorToString(hr) << "\n";
00709 return hr;
00710 }
00711 #endif
00712
00713 if(hr==S_OK) {
00714 HWND hWin;
00715
00716 if(FAILED(hr = pDDClipper->GetHWnd(&hWin))) {
00717 dxgsg7_cat.error() << "ConvertDDSurftoPixBuf GetHwnd failed! hr = " << ConvD3DErrorToString(hr) << "\n";
00718 return hr;
00719 }
00720
00721 RECT view_rect;
00722 GetClientRect( hWin, &view_rect );
00723 ClientToScreen( hWin, (POINT*)&view_rect.left );
00724 ClientToScreen( hWin, (POINT*)&view_rect.right );
00725
00726 dwXWindowOffset=view_rect.left;
00727 dwYWindowOffset=view_rect.top;
00728 dwCopyWidth=view_rect.right-view_rect.left;
00729 dwCopyHeight=view_rect.bottom-view_rect.top;
00730
00731 pDDClipper->Release();
00732 }
00733
00734
00735
00736
00737 if(!((dwCopyWidth==pixbuf->get_xsize()) && (dwCopyHeight<=(DWORD)pixbuf->get_ysize()))) {
00738 pDDSurf->Unlock(NULL);
00739 assert(0);
00740 dxgsg7_cat.error() << "ConvertDDSurftoPixBuf, PixBuf incorrect size to hold display surface!\n";
00741 return E_FAIL;
00742 }
00743
00744
00745 assert((ddsd.ddpfPixelFormat.dwRGBBitCount==32)||(ddsd.ddpfPixelFormat.dwRGBBitCount==16)||(ddsd.ddpfPixelFormat.dwRGBBitCount==24));
00746
00747
00748
00749 DWORD lPitch = ddsd.lPitch;
00750 BYTE* pDDSurfBytes = (BYTE*)ddsd.lpSurface;
00751
00752
00753
00754 if(dxgsg7_cat.is_debug())
00755 dxgsg7_cat.debug() << "ConvertDDSurftoPixBuf converting " << ddsd.ddpfPixelFormat.dwRGBBitCount << "bpp DDSurf to "
00756 << dwNumComponents << "-channel panda PixelBuffer\n";
00757
00758
00759 if(dwNumComponents==4) {
00760 DWORD *pDstWord = (DWORD *) pbuf;
00761 switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
00762
00763 case 32: {
00764 DWORD *pSrcWord;
00765 #ifdef PANDA_BGRA_ORDER
00766 BYTE *pDstLine = (BYTE*)pDstWord;
00767 #endif
00768
00769 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00770 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00771 pSrcWord = ((DWORD*)pDDSurfBytes)+dwXWindowOffset;
00772 #ifdef PANDA_BGRA_ORDER
00773 memcpy(pDstLine,pSrcWord,ddsd.lPitch);
00774 pDstLine+=ddsd.lPitch;
00775 #else
00776 for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
00777 DWORD dwPixel = *pSrcWord;
00778 BYTE r,b;
00779
00780
00781 r= (BYTE) ((dwPixel >> 16) & g_LowByteMask);
00782 b = (BYTE) (dwPixel & g_LowByteMask);
00783
00784
00785 *pDstWord = (dwPixel & 0xFF00FF00) | (b<<16) | r;
00786 }
00787 #endif
00788 }
00789 break;
00790 }
00791
00792 case 24: {
00793 BYTE *pSrcByte;
00794
00795 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00796 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00797 pSrcByte = pDDSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
00798 for(DWORD x=0; x<dwCopyWidth; x++,pDstWord++) {
00799 DWORD r,g,b;
00800
00801 b = *pSrcByte++;
00802 g = *pSrcByte++;
00803 r = *pSrcByte++;
00804
00805 #ifdef PANDA_BGRA_ORDER
00806 *pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
00807 #else
00808 *pDstWord = 0xFF000000 | (b << 16) | (g << 8) | r;
00809 #endif
00810 }
00811 }
00812 break;
00813 }
00814
00815 case 16: {
00816 assert((ddsd.ddpfPixelFormat.dwRBitMask==0xF800) ||
00817 (ddsd.ddpfPixelFormat.dwRBitMask==0x0F00) ||
00818 (ddsd.ddpfPixelFormat.dwRBitMask==0x7C00));
00819
00820 WORD *pSrcWord;
00821
00822 BYTE redshift,greenshift,blueshift;
00823 DWORD redmask,greenmask,bluemask;
00824
00825 if(ddsd.ddpfPixelFormat.dwRBitMask==0xF800) {
00826 redshift=(11-3);
00827 redmask=0xF800;
00828 greenmask=0x07E0;
00829 greenshift=(5-2);
00830 bluemask=0x001F;
00831 blueshift=3;
00832 } else if(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00) {
00833 redmask=0x7C00;
00834 redshift=(10-3);
00835 greenmask=0x03E0;
00836 greenshift=(5-3);
00837 bluemask=0x001F;
00838 blueshift=3;
00839 } else {
00840 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00);
00841 redmask=0x0F00;
00842 redshift=4;
00843 greenmask=0x00F0;
00844 greenshift=0;
00845 bluemask=0x000F;
00846 blueshift=4;
00847 }
00848
00849 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00850 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00851 pSrcWord = ((WORD*)pDDSurfBytes)+dwXWindowOffset;
00852 for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
00853 WORD dwPixel = *pSrcWord;
00854 BYTE r,g,b;
00855
00856 b = (dwPixel & bluemask) << blueshift;
00857 g = (dwPixel & greenmask) >> greenshift;
00858 r = (dwPixel & redmask) >> redshift;
00859
00860 #ifdef PANDA_BGRA_ORDER
00861 *pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
00862 #else
00863 *pDstWord = 0xFF000000 | (b << 16) | (g << 8) | r;
00864 #endif
00865 }
00866 }
00867 }
00868 break;
00869 }
00870 } else {
00871 BYTE *pDstByte = (BYTE *) pbuf;
00872 switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
00873
00874 case 32: {
00875 DWORD *pSrcWord;
00876
00877 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00878 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00879 pSrcWord = ((DWORD*)pDDSurfBytes)+dwXWindowOffset;
00880
00881 for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
00882 BYTE r,g,b;
00883 DWORD dwPixel = *pSrcWord;
00884
00885 r = (BYTE)((dwPixel>>16) & g_LowByteMask);
00886 g = (BYTE)((dwPixel>> 8) & g_LowByteMask);
00887 b = (BYTE)((dwPixel ) & g_LowByteMask);
00888
00889 #ifdef PANDA_BGRA_ORDER
00890 *pDstByte++ = b;
00891 *pDstByte++ = g;
00892 *pDstByte++ = r;
00893 #else
00894 *pDstByte++ = r;
00895 *pDstByte++ = g;
00896 *pDstByte++ = b;
00897 #endif
00898 }
00899 }
00900 break;
00901 }
00902
00903 case 24: {
00904 BYTE *pSrcByte;
00905
00906 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00907 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00908 pSrcByte = pDDSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
00909 #ifdef PANDA_BGRA_ORDER
00910 memcpy(pDstByte,pSrcByte,ddsd.lPitch);
00911 pDstByte+=ddsd.lPitch;
00912 #else
00913 for(DWORD x=0; x<dwCopyWidth; x++) {
00914 BYTE r,g,b;
00915
00916
00917
00918
00919 b = *pSrcByte++;
00920 g = *pSrcByte++;
00921 r = *pSrcByte++;
00922
00923 *pDstByte++ = r;
00924 *pDstByte++ = g;
00925 *pDstByte++ = b;
00926 }
00927 #endif
00928 }
00929 break;
00930 }
00931
00932 case 16: {
00933
00934 assert((ddsd.ddpfPixelFormat.dwRBitMask==0xF800) ||
00935 (ddsd.ddpfPixelFormat.dwRBitMask==0x0F00) ||
00936 (ddsd.ddpfPixelFormat.dwRBitMask==0x7C00));
00937
00938 WORD *pSrcWord;
00939
00940 BYTE redshift,greenshift,blueshift;
00941 DWORD redmask,greenmask,bluemask;
00942
00943 if(ddsd.ddpfPixelFormat.dwRBitMask==0xF800) {
00944 redshift=(11-3);
00945 redmask=0xF800;
00946 greenmask=0x07E0;
00947 greenshift=(5-2);
00948 bluemask=0x001F;
00949 blueshift=3;
00950 } else if(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00) {
00951 redmask=0x7C00;
00952 redshift=(10-3);
00953 greenmask=0x03E0;
00954 greenshift=(5-3);
00955 bluemask=0x001F;
00956 blueshift=3;
00957 } else {
00958 assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00);
00959 redmask=0x0F00;
00960 redshift=4;
00961 greenmask=0x00F0;
00962 greenshift=0;
00963 bluemask=0x000F;
00964 blueshift=4;
00965 }
00966
00967 pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
00968 for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
00969 pSrcWord = ((WORD*)pDDSurfBytes)+dwXWindowOffset;
00970 for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
00971 WORD dwPixel = *pSrcWord;
00972 BYTE r,g,b;
00973
00974 b = (dwPixel & bluemask) << blueshift;
00975 g = (dwPixel & greenmask) >> greenshift;
00976 r = (dwPixel & redmask) >> redshift;
00977
00978 #ifdef PANDA_BGRA_ORDER
00979 *pDstByte++ = b;
00980 *pDstByte++ = g;
00981 *pDstByte++ = r;
00982 #else
00983 *pDstByte++ = r;
00984 *pDstByte++ = g;
00985 *pDstByte++ = b;
00986 #endif
00987 }
00988 }
00989 }
00990 break;
00991 }
00992 }
00993
00994
00995 pDDSurf->Unlock(NULL);
00996
00997 return S_OK;
00998 }
00999
01000
01001
01002
01003
01004
01005
01006 LPDIRECTDRAWSURFACE7 DXTextureContext7::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice,
01007 #ifdef USE_TEXFMTVEC
01008 DDPixelFormatVec &TexFmts,LPD3DDEVICEDESC7 pD3DDevDesc)
01009 #else
01010 int cNumTexPixFmts, DDPIXELFORMAT *pTexFmts,LPD3DDEVICEDESC7 pD3DDevDesc)
01011 #endif
01012 {
01013 HRESULT hr;
01014 int i,cNumAlphaBits;
01015 DDPIXELFORMAT *pDesiredPixFmt;
01016 LPDIRECTDRAWSURFACE7 pddsRender;
01017 LPDIRECTDRAW7 pDD = NULL;
01018 ConversionType ConvNeeded;
01019
01020 assert(_texture!=NULL);
01021
01022 PixelBuffer *pbuf = _texture->_pbuffer;
01023
01024 #ifdef USE_TEXFMTVEC
01025 int cNumTexPixFmts=TexturePixelFormats.size();
01026 #endif
01027 DDPIXELFORMAT *pTexPixFmts = new DDPIXELFORMAT[cNumTexPixFmts];
01028
01029
01030
01031
01032
01033 #ifdef USE_TEXFMTVEC
01034 memcpy(pTexPixFmts,&TexturePixelFormats[0],cNumTexPixFmts*sizeof(DDPIXELFORMAT));
01035 #else
01036 memcpy(pTexPixFmts,pTexFmts,cNumTexPixFmts*sizeof(DDPIXELFORMAT));
01037 #endif
01038
01039
01040 DWORD bpp = get_bits_per_pixel(pbuf->get_format(), &cNumAlphaBits);
01041 PixelBuffer::Type pixbuf_type = pbuf->get_image_type();
01042 DWORD cNumColorChannels = pbuf->get_num_components();
01043
01044 assert(pbuf->get_component_width()==sizeof(BYTE));
01045 assert(pixbuf_type==PixelBuffer::T_unsigned_byte);
01046
01047 if((pixbuf_type != PixelBuffer::T_unsigned_byte) || (pbuf->get_component_width()!=1)) {
01048 dxgsg7_cat.error() << "CreateTexture failed, havent handled non 8-bit channel pixelbuffer types yet! \n";
01049 return NULL;
01050 }
01051
01052 DWORD dwOrigWidth = (DWORD)pbuf->get_xsize();
01053 DWORD dwOrigHeight = (DWORD)pbuf->get_ysize();
01054
01055
01056
01057
01058 assert((pD3DDevDesc->dwMaxTextureWidth>0) && (pD3DDevDesc->dwMaxTextureHeight>0));
01059
01060
01061
01062 DDSURFACEDESC2 ddsd;
01063 ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
01064 ddsd.dwSize = sizeof(DDSURFACEDESC2);
01065 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH
01066 | DDSD_PIXELFORMAT ;
01067
01068 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
01069
01070
01071
01072 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
01073
01074 if((pbuf->get_format() == PixelBuffer::F_luminance_alpha)||
01075 (pbuf->get_format() == PixelBuffer::F_luminance_alphamask) ||
01076 (pbuf->get_format() == PixelBuffer::F_luminance)) {
01077 ddsd.ddpfPixelFormat.dwFlags = DDPF_LUMINANCE;
01078 }
01079
01080 ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
01081
01082 if(cNumAlphaBits) {
01083 if(bpp == 8 && cNumAlphaBits == 8) {
01084 ddsd.dwFlags |= DDPF_ALPHA;
01085 ddsd.dwAlphaBitDepth = 8;
01086 ddsd.ddpfPixelFormat.dwAlphaBitDepth = 8;
01087 ddsd.ddpfPixelFormat.dwFlags = DDPF_ALPHA;
01088 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff;
01089 } else {
01090 ddsd.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
01091 if(cNumAlphaBits == 8)
01092 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
01093 else if(cNumAlphaBits == 4)
01094 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xf000;
01095 }
01096 }
01097
01098 ddsd.dwWidth = dwOrigWidth;
01099 ddsd.dwHeight = dwOrigHeight;
01100
01101 if(!ISPOW2(ddsd.dwWidth) || !ISPOW2(ddsd.dwHeight)) {
01102 dxgsg7_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "!!!!! \n";
01103 #ifdef _DEBUG
01104 exit(1);
01105 #else
01106 goto error_exit;
01107 #endif
01108 }
01109
01110 bool bShrinkOriginal;
01111 bShrinkOriginal=false;
01112
01113 if((dwOrigWidth>pD3DDevDesc->dwMaxTextureWidth)||(dwOrigHeight>pD3DDevDesc->dwMaxTextureHeight)) {
01114 #ifdef _DEBUG
01115 dxgsg7_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << pD3DDevDesc->dwMaxTextureWidth << "," << pD3DDevDesc->dwMaxTextureHeight << ") !!\n"
01116 << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," <<dwOrigHeight << ") => ("<< pD3DDevDesc->dwMaxTextureWidth << "," << pD3DDevDesc->dwMaxTextureHeight << ") !\n";
01117 #endif
01118
01119 if(dwOrigWidth>pD3DDevDesc->dwMaxTextureWidth)
01120 ddsd.dwWidth=pD3DDevDesc->dwMaxTextureWidth;
01121 if(dwOrigHeight>pD3DDevDesc->dwMaxTextureHeight)
01122 ddsd.dwHeight=pD3DDevDesc->dwMaxTextureHeight;
01123 bShrinkOriginal=true;
01124 }
01125
01126
01127 if((ddsd.dwWidth != ddsd.dwHeight) && (pD3DDevDesc->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )) {
01128
01129
01130 int i,width_exp,height_exp;
01131 for(i=ddsd.dwWidth,width_exp=0;i>1;width_exp++,i>>=1);
01132 for(i=ddsd.dwHeight,height_exp=0;i>1;height_exp++,i>>=1);
01133 ddsd.dwHeight = ddsd.dwWidth = 1<<((width_exp+height_exp)>>1);
01134 bShrinkOriginal=true;
01135
01136 #ifdef _DEBUG
01137 dxgsg7_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," <<dwOrigHeight << ") => ("<< ddsd.dwWidth<<"," << ddsd.dwHeight << ") to meet HW square texture reqmt\n";
01138 #endif
01139 }
01140
01141 if(bShrinkOriginal) {
01142
01143 PNMImage pnmi_src;
01144 PNMImage *pnmi = new PNMImage(ddsd.dwWidth, ddsd.dwHeight, cNumColorChannels);
01145 pbuf->store(pnmi_src);
01146 pnmi->quick_filter_from(pnmi_src,0,0);
01147
01148 pbuf->load(*pnmi);
01149
01150 dwOrigWidth = (DWORD)pbuf->get_xsize();
01151 dwOrigHeight = (DWORD)pbuf->get_ysize();
01152 delete pnmi;
01153 }
01154
01155 #if 0
01156
01157
01158 { static BOOL bPrinted=FALSE;
01159 if(!bPrinted) {
01160 dxgsg7_cat.debug() << "Gfx card supported TexFmts:\n";
01161 for(i=0;i<cNumTexPixFmts;i++) {
01162 DebugPrintPixFmt(&pTexPixFmts[i]);
01163 }
01164 bPrinted=TRUE;
01165 }
01166 }
01167 #endif
01168
01169
01170 pDesiredPixFmt = &ddsd.ddpfPixelFormat;
01171
01172 LPDDPIXELFORMAT pCurPixFmt;
01173 char *szErrorMsg;
01174
01175 szErrorMsg = "CreateTexture failed: couldn't find compatible Tex DDPIXELFORMAT!\n";
01176
01177 if(dxgsg7_cat.is_spam())
01178 dxgsg7_cat.spam() << "CreateTexture handling bitdepth: " << bpp << " alphabits: " << cNumAlphaBits << "\n";
01179
01180
01181 for(i=0,pCurPixFmt=pTexPixFmts;i<cNumTexPixFmts;i++,pCurPixFmt++) {
01182 if(( pCurPixFmt->dwFlags & (DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) ) ||
01183 ( pCurPixFmt->dwFourCC != 0 ) ||
01184 ((cNumAlphaBits==0) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS))) {
01185
01186
01187
01188
01189
01190
01191
01192
01193 pCurPixFmt->dwRGBBitCount+=1;
01194 }
01195 }
01196
01197
01198
01199 switch(bpp) {
01200
01201 case 32:
01202
01203 #ifdef _DEBUG
01204 if(!dx_force_16bpptextures)
01205 #endif
01206 for(i=0,pCurPixFmt=pTexPixFmts;i<cNumTexPixFmts;i++,pCurPixFmt++) {
01207 if((pCurPixFmt->dwRGBBitCount==32) &&
01208 (((pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)!=0)==(cNumAlphaBits!=0))) {
01209
01210 assert(pCurPixFmt->dwRGBAlphaBitMask==0xFF000000);
01211 ConvNeeded=((cNumColorChannels==3) ? Conv24to32 : Conv32to32);
01212 goto found_matching_format;
01213 break;
01214 }
01215 }
01216
01217 if(cNumAlphaBits>0) {
01218
01219
01220
01221
01222
01223
01224 ConversionType ConvTo1=Conv32to16_4444,ConvTo2=Conv32to16_1555;
01225 DWORD dwAlphaMask1=0xF000,dwAlphaMask2=0x8000;
01226
01227
01228
01229 #ifndef FORCE_16bpp_1555
01230 if(cNumAlphaBits==1)
01231 #endif
01232 {
01233 ConvTo1=Conv32to16_1555;
01234 dwAlphaMask1=0x8000;
01235 }
01236
01237 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01238 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)
01239 && (pCurPixFmt->dwRGBAlphaBitMask==dwAlphaMask1)) {
01240 ConvNeeded=ConvTo1;
01241 goto found_matching_format;
01242 }
01243 }
01244
01245 #ifdef FORCE_16bpp_1555
01246 break;
01247 #endif
01248
01249 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01250 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)
01251 && (pCurPixFmt->dwRGBAlphaBitMask==dwAlphaMask2)) {
01252 ConvNeeded=ConvTo2;
01253 goto found_matching_format;
01254 }
01255 }
01256
01257
01258
01259 szErrorMsg = "CreateTexture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!\n";
01260 }
01261
01262 break;
01263
01264 case 24:
01265
01266 assert(cNumAlphaBits==0);
01267
01268 if(!dx_force_16bpptextures)
01269 for(i=0,pCurPixFmt=pTexPixFmts;i<cNumTexPixFmts;i++,pCurPixFmt++) {
01270 if((pCurPixFmt->dwFlags & DDPF_RGB)&&(pCurPixFmt->dwRGBBitCount==24)) {
01271 ConvNeeded=((cNumColorChannels==3) ? Conv24to24 : Conv32to24);
01272 goto found_matching_format;
01273 }
01274 }
01275
01276 if(!dx_force_16bpptextures) {
01277
01278
01279
01280 for(i=0,pCurPixFmt=pTexPixFmts;i<cNumTexPixFmts;i++,pCurPixFmt++) {
01281 if((pCurPixFmt->dwRGBBitCount==32) && (pCurPixFmt->dwFlags & DDPF_RGB)
01282 && ((pCurPixFmt->dwRBitMask|pCurPixFmt->dwGBitMask|pCurPixFmt->dwBBitMask)==0xFFFFFF)
01283 ) {
01284
01285 ConvNeeded=((cNumColorChannels==3) ? Conv24to32 : Conv32to32_NoAlpha);
01286 goto found_matching_format;
01287 }
01288 }
01289 }
01290
01291
01292 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01293
01294 if((pCurPixFmt->dwFlags & DDPF_RGB) && (pCurPixFmt->dwRGBBitCount==16)
01295 && !(pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)) {
01296
01297 if(pCurPixFmt->dwGBitMask==0x7E0) {
01298
01299 ConvNeeded=((cNumColorChannels==3) ? Conv24to16_0565 : Conv32to16_0565);
01300 } else {
01301 assert((pCurPixFmt->dwRBitMask|pCurPixFmt->dwGBitMask|pCurPixFmt->dwBBitMask)==0x7FFF);
01302 ConvNeeded=((cNumColorChannels==3) ? Conv24to16_X555 : Conv32to16_X555);
01303 }
01304 goto found_matching_format;
01305 }
01306 }
01307
01308
01309 break;
01310
01311 case 16:
01312
01313 if(ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) {
01314
01315 if(!dx_force_16bpptextures) {
01316 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01317 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS) &&
01318 (pCurPixFmt->dwFlags & DDPF_LUMINANCE)) {
01319 ConvNeeded=ConvLum16to16;
01320 goto found_matching_format;
01321 }
01322 }
01323
01324
01325 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01326 if((pCurPixFmt->dwRGBBitCount==32) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS) &&
01327 (pCurPixFmt->dwFlags & DDPF_RGB)) {
01328 ConvNeeded=ConvLum16to32;
01329 goto found_matching_format;
01330 }
01331 }
01332 }
01333
01334
01335 ConversionType ConvTo1=ConvLum16to16_4444,ConvTo2=ConvLum16to16_1555;
01336 DWORD dwAlphaMask1=0xF000,dwAlphaMask2=0x8000;
01337
01338
01339
01340 #ifndef FORCE_16bpp_1555
01341 if(cNumAlphaBits==1)
01342 #endif
01343 {
01344 ConvTo1=ConvLum16to16_1555;
01345 dwAlphaMask1=0x8000;
01346 }
01347
01348 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01349 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)
01350 && (pCurPixFmt->dwRGBAlphaBitMask==dwAlphaMask1)) {
01351 ConvNeeded=ConvTo1;
01352 goto found_matching_format;
01353 }
01354 }
01355
01356 #ifdef FORCE_16bpp_1555
01357 break;
01358 #endif
01359
01360 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01361 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)
01362 && (pCurPixFmt->dwRGBAlphaBitMask==dwAlphaMask2)) {
01363 ConvNeeded=ConvTo2;
01364 goto found_matching_format;
01365 }
01366 }
01367
01368 } else
01369
01370
01371
01372
01373 for(i=0,pCurPixFmt=pTexPixFmts;i<cNumTexPixFmts;i++,pCurPixFmt++) {
01374
01375 if((pCurPixFmt->dwRGBBitCount==16)&&(pCurPixFmt->dwFlags & DDPF_RGB)) {
01376 switch(cNumAlphaBits) {
01377 case 0:
01378 if(!(pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)) {
01379
01380 if(pCurPixFmt->dwGBitMask==0x7E0) {
01381
01382 ConvNeeded=((cNumColorChannels==3) ? Conv24to16_0565 : Conv32to16_0565);
01383 } else {
01384 assert((pCurPixFmt->dwRBitMask|pCurPixFmt->dwGBitMask|pCurPixFmt->dwBBitMask)==0x7FFF);
01385 ConvNeeded=((cNumColorChannels==3) ? Conv24to16_X555 : Conv32to16_X555);
01386 }
01387 goto found_matching_format;
01388 }
01389 break;
01390 case 1:
01391 if((pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)&&
01392 (pCurPixFmt->dwRGBAlphaBitMask==0x8000)) {
01393 ConvNeeded=Conv32to16_1555;
01394 goto found_matching_format;
01395 }
01396 break;
01397 case 4:
01398 if((pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)&&
01399 (pCurPixFmt->dwRGBAlphaBitMask==0xF000)) {
01400 ConvNeeded=Conv32to16_4444;
01401 goto found_matching_format;
01402 }
01403 break;
01404 }
01405 }
01406 }
01407
01408 break;
01409
01410 case 8:
01411 if(ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) {
01412
01413
01414 assert(cNumAlphaBits==0);
01415 if(!dx_force_16bpptextures)
01416 {
01417 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01418 if((pCurPixFmt->dwRGBBitCount==8) && (pCurPixFmt->dwFlags & DDPF_LUMINANCE) &&
01419 (pCurPixFmt->dwLuminanceBitMask==0xFF)) {
01420 ConvNeeded=ConvLum8to8;
01421 goto found_matching_format;
01422 }
01423 }
01424
01425
01426 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01427 if((pCurPixFmt->dwRGBBitCount==24) && (pCurPixFmt->dwFlags & DDPF_RGB)) {
01428 ConvNeeded=ConvLum8to24;
01429 goto found_matching_format;
01430 }
01431 }
01432
01433
01434 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01435 if((pCurPixFmt->dwRGBBitCount==32) && (pCurPixFmt->dwFlags & DDPF_RGB)) {
01436 ConvNeeded=ConvLum8to32;
01437 goto found_matching_format;
01438 }
01439 }
01440 }
01441
01442
01443 DWORD dwMasks[2] = {0xF800, 0x7C00};
01444 ConversionType ConvType[2] = {ConvLum8to16_0565,ConvLum8to16_X555};
01445
01446 for(DWORD modenum=0;modenum<2;modenum++)
01447 for(i=0,pCurPixFmt=&pTexPixFmts[0];i<cNumTexPixFmts;i++,pCurPixFmt++) {
01448 if((pCurPixFmt->dwRGBBitCount==16) && (pCurPixFmt->dwFlags & DDPF_RGB)
01449 && (!(pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS))
01450 && (pCurPixFmt->dwRBitMask==dwMasks[modenum])) {
01451 ConvNeeded=ConvType[modenum];
01452 goto found_matching_format;
01453 }
01454 }
01455 } else if(ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHA) {
01456
01457
01458
01459
01460 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01461 if((pCurPixFmt->dwRGBBitCount==32) && (pCurPixFmt->dwFlags & DDPF_RGB) &&
01462 (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)) {
01463 ConvNeeded=ConvAlpha8to32;
01464 goto found_matching_format;
01465 }
01466 }
01467
01468 for(i=0,pCurPixFmt=&pTexPixFmts[cNumTexPixFmts-1];i<cNumTexPixFmts;i++,pCurPixFmt--) {
01469 if((pCurPixFmt->dwRGBBitCount==16)
01470 && (pCurPixFmt->dwFlags & DDPF_RGB)
01471 && (pCurPixFmt->dwFlags & DDPF_ALPHAPIXELS)
01472 && (pCurPixFmt->dwRGBAlphaBitMask==0xF000)) {
01473 ConvNeeded=ConvAlpha8to16_4444;
01474 goto found_matching_format;
01475 }
01476 }
01477 }
01478 break;
01479
01480 default:
01481 szErrorMsg = "CreateTexture failed: unhandled pixel bitdepth in DX loader";
01482 }
01483
01484
01485
01486 dxgsg7_cat.error() << szErrorMsg << "; requested tex bitdepth: " << bpp << "\n";
01487 goto error_exit;
01488
01489
01490
01491 found_matching_format:
01492
01493 ddsd.ddpfPixelFormat = *pCurPixFmt;
01494
01495
01496
01497
01498
01499 pd3dDevice->GetRenderTarget( &pddsRender );
01500 pddsRender->GetDDInterface( (VOID**)&pDD );
01501 pddsRender->Release();
01502
01503 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
01504
01505 if(pD3DDevDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) {
01506 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE
01507 | DDSCAPS2_HINTSTATIC;
01508 } else {
01509 ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
01510 }
01511
01512
01513
01514
01515 Texture::FilterType ft;
01516
01517 ft =_tex->get_magfilter();
01518 if((ft!=Texture::FT_linear) && ft!=Texture::FT_nearest) {
01519 if(ft==Texture::FT_nearest_mipmap_nearest)
01520 ft=Texture::FT_nearest;
01521 else ft=Texture::FT_linear;
01522 }
01523
01524 if((ft==Texture::FT_linear) && !(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR))
01525 ft=Texture::FT_nearest;
01526 _tex->set_magfilter(ft);
01527
01528
01529 ft =_tex->get_minfilter();
01530 _bHasMipMaps=FALSE;
01531
01532 if(!dx_ignore_mipmaps) {
01533 switch(ft) {
01534 case Texture::FT_nearest_mipmap_nearest:
01535 case Texture::FT_linear_mipmap_nearest:
01536 case Texture::FT_nearest_mipmap_linear:
01537 case Texture::FT_linear_mipmap_linear:
01538 _bHasMipMaps=TRUE;
01539 }
01540
01541 if(dx_mipmap_everything) {
01542 _bHasMipMaps=TRUE;
01543 if(ft != Texture::FT_linear_mipmap_linear) {
01544 dxgsg7_cat.spam() << "Forcing mipmap filtering on DX texture [" << _tex->get_name() << "]\n";
01545 }
01546 ft = Texture::FT_linear_mipmap_linear;
01547 _tex->set_minfilter(ft);
01548 }
01549 } else if((ft==Texture::FT_nearest_mipmap_nearest) ||
01550 (ft==Texture::FT_nearest_mipmap_linear)) {
01551 ft=Texture::FT_nearest;
01552 } else if((ft==Texture::FT_linear_mipmap_nearest) ||
01553 (ft==Texture::FT_linear_mipmap_linear)) {
01554 ft=Texture::FT_linear;
01555 }
01556
01557 assert((pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_NEAREST)!=0);
01558
01559 switch(ft) {
01560 case Texture::FT_nearest_mipmap_linear:
01561 if(!(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPNEAREST))
01562 ft=Texture::FT_nearest_mipmap_nearest;
01563 break;
01564 case Texture::FT_linear_mipmap_nearest:
01565 if(!(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPLINEAR))
01566 ft=Texture::FT_nearest_mipmap_nearest;
01567 break;
01568 case Texture::FT_linear_mipmap_linear:
01569 if(!(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR)) {
01570 if(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPLINEAR)
01571 ft=Texture::FT_linear_mipmap_nearest;
01572 else ft=Texture::FT_nearest_mipmap_nearest;
01573 }
01574 break;
01575 case Texture::FT_linear:
01576 if(!(pD3DDevDesc->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR))
01577 ft=Texture::FT_nearest;
01578 break;
01579 }
01580
01581 _tex->set_minfilter(ft);
01582
01583 uint aniso_degree;
01584
01585 aniso_degree=1;
01586 if(pD3DDevDesc->dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
01587 aniso_degree=_tex->get_anisotropic_degree();
01588 if((aniso_degree>pD3DDevDesc->dwMaxAnisotropy)
01589 #ifdef _DEBUG
01590 || dx_force_anisotropic_filtering
01591 #endif
01592 )
01593 aniso_degree=pD3DDevDesc->dwMaxAnisotropy;
01594 }
01595 _tex->set_anisotropic_degree(aniso_degree);
01596 #ifdef _DEBUG
01597 dxgsg7_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl;
01598 #endif
01599
01600 if(_bHasMipMaps) {
01601
01602
01603 ddsd.ddsCaps.dwCaps |= (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX);
01604 dxgsg7_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl;
01605 }
01606
01607 if(pD3DDevDesc->dwDevCaps & D3DDEVCAPS_SEPARATETEXTUREMEMORIES) {
01608
01609
01610 ddsd.dwTextureStage=0;
01611 ddsd.dwFlags |= DDSD_TEXTURESTAGE;
01612 }
01613
01614 PRINTVIDMEM(pDD,&ddsd.ddsCaps,"texture surf (includes AGP mem)");
01615
01616
01617 if(FAILED( hr = pDD->CreateSurface( &ddsd, &_surface, NULL ) )) {
01618 dxgsg7_cat.error() << "CreateTexture failed: pDD->CreateSurface() failed! hr = " << ConvD3DErrorToString(hr) << "\n";
01619 goto error_exit;
01620 }
01621
01622
01623 #ifdef _DEBUG
01624 dxgsg7_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converted " << ConvNameStrs[ConvNeeded] << " \n";
01625 #endif
01626
01627 _PixBufConversionType=ConvNeeded;
01628
01629 hr = FillDDSurfTexturePixels();
01630 if(FAILED(hr)) {
01631 goto error_exit;
01632 }
01633
01634
01635 pDD->Release();
01636
01637 delete [] pTexPixFmts;
01638
01639
01640 return _surface;
01641
01642 error_exit:
01643
01644 if(pDD!=NULL)
01645 pDD->Release();
01646 if(_surface!=NULL) {
01647 _surface->Release();
01648 _surface = NULL;
01649 }
01650
01651 delete [] pTexPixFmts;
01652 return NULL;
01653 }
01654
01655 HRESULT DXTextureContext7::
01656 FillDDSurfTexturePixels(void) {
01657
01658 PixelBuffer *pbuf = _texture->get_ram_image();
01659 if (pbuf == (PixelBuffer *)NULL) {
01660 dxgsg7_cat.fatal() << "CreateTexture: get_ram_image() failed\n";
01661
01662 return E_FAIL;
01663 }
01664
01665 HRESULT hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pbuf->_image.p(),_surface);
01666 if(FAILED(hr)) {
01667 return hr;
01668 }
01669
01670 DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
01671
01672 _surface->GetSurfaceDesc(&ddsd);
01673
01674 if(_bHasMipMaps) {
01675 DWORD i,oldcurxsize,oldcurysize,curxsize,curysize,cMipMapCount=ddsd.dwMipMapCount;
01676 assert(ddsd.dwMipMapCount<20);
01677
01678 DWORD cNumColorChannels = pbuf->get_num_components();
01679
01680 curxsize=ddsd.dwWidth; curysize=ddsd.dwHeight;
01681
01682 assert(pbuf->get_image_type()==PixelBuffer::T_unsigned_byte);
01683
01684
01685 BYTE *pMipMapPixBufSpace = new BYTE[((curxsize*curysize*cNumColorChannels)/2)+1024];
01686
01687 LPDIRECTDRAWSURFACE7 pCurDDSurf=_surface;
01688 pCurDDSurf->AddRef();
01689
01690 BYTE *pDstWord = pMipMapPixBufSpace;
01691 BYTE *pLastMipLevelStart = (BYTE *) pbuf->_image.p();
01692
01693
01694 for(i=1;i<ddsd.dwMipMapCount;i++) {
01695 oldcurxsize=curxsize; oldcurysize=curysize;
01696 curysize = max(curysize>>1,1);
01697 curxsize = max(curxsize>>1,1);
01698
01699 assert(!((oldcurxsize==1)&&(oldcurysize==1)));
01700
01701 BYTE *pSrcWord;
01702 BYTE *pSrcLineStart=pLastMipLevelStart;
01703
01704
01705 while(((DWORD)pDstWord) & 0x11)
01706 pDstWord++;
01707
01708 pLastMipLevelStart = pDstWord;
01709
01710 DWORD x,y,cPixelSize=cNumColorChannels;
01711 DWORD src_row_bytelength=oldcurxsize*cPixelSize;
01712 DWORD two_src_row_bytelength=2*src_row_bytelength;
01713
01714 #define GENMIPMAP_DO_INTEGER_DIV // should be a little faster, but no rounding up
01715 #ifdef GENMIPMAP_DO_INTEGER_DIV
01716 DWORD DivShift=2;
01717 if((oldcurxsize==1)||(oldcurysize==1))
01718 DivShift = 1;
01719 #else
01720 float numpixels_per_filter=4.0f;
01721 if((oldcurxsize==1)||(oldcurysize==1))
01722 numpixels_per_filter=2.0f;
01723 #endif
01724
01725 DWORD x_srcptr_inc = ((oldcurxsize==1)? cPixelSize: (2*cPixelSize));
01726
01727
01728 for(y=0; y<curysize; y++,pSrcLineStart+=two_src_row_bytelength) {
01729 pSrcWord=pSrcLineStart;
01730 for(x=0; x<curxsize; x++,pSrcWord+=x_srcptr_inc,pDstWord+=cPixelSize) {
01731
01732
01733
01734 for(DWORD c=0;c<cPixelSize;c++) {
01735 DWORD colr;
01736 colr = *(pSrcWord+c);
01737 if(oldcurxsize>1)
01738 colr += *(pSrcWord+cPixelSize+c);
01739 if(oldcurysize>1) {
01740 colr += *(pSrcWord+src_row_bytelength+c);
01741 if(oldcurxsize>1)
01742 colr += *(pSrcWord+src_row_bytelength+cPixelSize+c);
01743 }
01744 #ifdef GENMIPMAP_DO_INTEGER_DIV
01745 colr >>= DivShift;
01746 #else
01747 colr = (DWORD) ((((float)colr)/numpixels_per_filter)+0.5f);
01748 #endif
01749
01750 *(pDstWord+c)=(BYTE)colr;
01751 }
01752 }
01753 }
01754
01755
01756
01757 DDSCAPS2 ddsCaps;
01758 LPDIRECTDRAWSURFACE7 pMipLevel_DDSurf;
01759 ZeroMemory(&ddsCaps,sizeof(DDSCAPS2));
01760 ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
01761 ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
01762
01763 hr = pCurDDSurf->GetAttachedSurface(&ddsCaps, &pMipLevel_DDSurf);
01764 if(FAILED(hr)) {
01765 dxgsg7_cat.error() << "CreateTexture failed creating mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n";
01766 delete [] pMipMapPixBufSpace;
01767 pCurDDSurf->Release();
01768 return hr;
01769 }
01770
01771 hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pLastMipLevelStart,pMipLevel_DDSurf);
01772 if(FAILED(hr)) {
01773 delete [] pMipMapPixBufSpace;
01774 pCurDDSurf->Release();
01775 return hr;
01776 }
01777
01778 pCurDDSurf->Release();
01779 pCurDDSurf=pMipLevel_DDSurf;
01780 }
01781
01782
01783
01784
01785
01786 delete [] pMipMapPixBufSpace;
01787 pCurDDSurf->Release();
01788
01789 #ifdef _DEBUG
01790 if(dx_debug_view_mipmaps) {
01791 #if 0
01792 if(!(ddcaps.dwCaps & DDCAPS_BLTSTRETCH)) {
01793 dxgsg7_cat.error() << "CreateTexture failed debug-viewing mipmaps, BLT stretching not supported! ( we need to do SW stretch) \n";
01794 return hr;
01795 }
01796 #endif
01797
01798
01799 HDC hTexDC;
01800 LPDIRECTDRAWSURFACE7 pTextureCurrent,pTexturePrev = _surface;
01801 int cury,curx;
01802 HDC hScreenDC;
01803 RECT scrnrect;
01804 hScreenDC=GetDC(NULL);
01805
01806 scrnrect.left=scrnrect.top=0;
01807 scrnrect.bottom=GetDeviceCaps(hScreenDC,VERTRES);
01808 scrnrect.right=GetDeviceCaps(hScreenDC,HORZRES);
01809 char msg[500];
01810
01811 pTexturePrev->AddRef();
01812
01813 for(i = 0,curx=scrnrect.left,cury=scrnrect.top; i < ddsd.dwMipMapCount; i++) {
01814
01815 DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_cur);
01816 pTexturePrev->GetSurfaceDesc(&ddsd_cur);
01817
01818 hr = pTexturePrev->GetDC(&hTexDC);
01819 if(FAILED(hr)) {
01820 dxgsg7_cat.error() << "GetDC failed hr = " << ConvD3DErrorToString(hr) << "\n";
01821 break;
01822 }
01823
01824 BOOL res;
01825
01826
01827
01828 #if 0
01829 if(cNumAlphaBits>0) {
01830 BLENDFUNCTION bf;
01831 bf.BlendOp = AC_SRC_OVER; bf.BlendFlags=0;
01832 bf.SourceConstantAlpha=255; bf.AlphaFormat=AC_SRC_ALPHA;
01833 res = AlphaBlend(hScreenDC,curx,cury,ddsd_cur.dwWidth,ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,bf);
01834 if(!res) {
01835 PrintLastError(msg);
01836 dxgsg7_cat.error() << "AlphaBlend BLT failed: "<<msg<<"\n";
01837 }
01838
01839 } else
01840 #endif
01841 {
01842 res = StretchBlt(hScreenDC,curx,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-((int)ddsd_cur.dwHeight), hTexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY);
01843 if(!res) {
01844 PrintLastError(msg);
01845 dxgsg7_cat.error() << "StretchBLT failed: "<<msg<<"\n";
01846
01847 }
01848 }
01849
01850 sprintf(msg,"%d",i);
01851 TextOut(hScreenDC,curx+(ddsd_cur.dwWidth)/2,5+cury+ddsd_cur.dwHeight,msg,strlen(msg));
01852
01853 curx+=max(20,ddsd_cur.dwWidth+10);
01854
01855 if(curx>scrnrect.right) {
01856 curx=0; cury+=(scrnrect.bottom-scrnrect.top)/2;
01857 }
01858
01859 hr = pTexturePrev->ReleaseDC(hTexDC);
01860
01861 if(FAILED(hr)) {
01862 dxgsg7_cat.error() << "tex ReleaseDC failed for mip "<<i<<" hr = " << ConvD3DErrorToString(hr) << "\n";
01863 break;
01864 }
01865
01866 if(i==ddsd.dwMipMapCount-1) {
01867 pTexturePrev->Release();
01868 continue;
01869 }
01870
01871 DDSCAPS2 ddsCaps;
01872 ZeroMemory(&ddsCaps,sizeof(DDSCAPS2));
01873 ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
01874 ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
01875 hr = pTexturePrev->GetAttachedSurface(&ddsCaps, &pTextureCurrent);
01876 if(FAILED(hr)) {
01877 dxgsg7_cat.error() << " failed displaying mipmaps: GetAttachedSurf hr = " << ConvD3DErrorToString(hr) << "\n";
01878 }
01879
01880 pTexturePrev->Release();
01881 pTexturePrev = pTextureCurrent;
01882 }
01883
01884 ReleaseDC(0,hScreenDC);
01885
01886 HANDLE hArr[1];
01887 MSG winmsg;
01888 hArr[0]=GetStdHandle(STD_INPUT_HANDLE);
01889 GetMessage(&winmsg,NULL,0,0);
01890
01891 int val=MsgWaitForMultipleObjects(1,hArr,TRUE,INFINITE,QS_KEY);
01892 if(val==-1) {
01893 PrintLastError(msg);
01894 dxgsg7_cat.error() << " MsgWaitForMultipleObjects returns " << val << " " <<msg << endl;
01895 } else {
01896 dxgsg7_cat.error() << " MsgWaitForMultipleObjects returns " << val << endl;
01897 }
01898 }
01899 #endif
01900 }
01901 return S_OK;
01902 }
01903
01904
01905
01906
01907
01908
01909
01910 void DXTextureContext7::
01911 DeleteTexture( ) {
01912 if(dxgsg7_cat.is_spam()) {
01913 dxgsg7_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n";
01914 }
01915
01916 ULONG refcnt;
01917
01918 #ifdef DEBUG_RELEASES
01919 if(_surface) {
01920 LPDIRECTDRAW7 pDD;
01921 _surface->GetDDInterface( (VOID**)&pDD );
01922 pDD->Release();
01923
01924 PRINTREFCNT(pDD,"before DeleteTex, IDDraw7");
01925 RELEASE(_surface,dxgsg7,"texture",false);
01926 PRINTREFCNT(pDD,"after DeleteTex, IDDraw7");
01927 }
01928 #else
01929 RELEASE(_surface,dxgsg7,"texture",false);
01930 #endif
01931 }
01932
01933
01934
01935
01936
01937
01938
01939 DXTextureContext7::
01940 DXTextureContext7(Texture *tex) :
01941 TextureContext(tex) {
01942
01943 if(dxgsg7_cat.is_spam()) {
01944 dxgsg7_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<<PandaFilterNameStrs[tex->get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
01945 }
01946
01947 _surface = NULL;
01948 _bHasMipMaps = FALSE;
01949 _tex = tex;
01950 }
01951
01952 DXTextureContext7::
01953 ~DXTextureContext7() {
01954 DeleteTexture();
01955 TextureContext::~TextureContext();
01956 _tex = NULL;
01957 }
01958