|
|
@@ -306,19 +306,23 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-// Name: CreateTexture()
|
|
|
+// Name: create_texture()
|
|
|
// Desc: Use panda texture's pixelbuffer to create a texture for the specified device.
|
|
|
// This code gets the attributes of the texture from the bitmap, creates the
|
|
|
// texture, and then copies the bitmap into the texture.
|
|
|
//-----------------------------------------------------------------------------
|
|
|
IDirect3DTexture8 *DXTextureContext8::
|
|
|
-CreateTexture(DXScreenData &scrn) {
|
|
|
+create_texture(DXScreenData &scrn) {
|
|
|
HRESULT hr;
|
|
|
int cNumAlphaBits; // number of alpha bits in texture pixfmt
|
|
|
D3DFORMAT TargetPixFmt = D3DFMT_UNKNOWN;
|
|
|
bool bNeedLuminance = false;
|
|
|
|
|
|
- assert(IS_VALID_PTR(_texture));
|
|
|
+ nassertr(IS_VALID_PTR(_texture), NULL);
|
|
|
+
|
|
|
+ delete_texture();
|
|
|
+
|
|
|
+ clear_dirty_flags(Texture::DF_image | Texture::DF_mipmap);
|
|
|
|
|
|
// bpp indicates requested fmt, not texture fmt
|
|
|
DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &cNumAlphaBits);
|
|
|
@@ -326,7 +330,7 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
|
|
|
//PRINT_REFCNT(dxgsg8, scrn.pD3D8);
|
|
|
|
|
|
- DWORD dwOrigWidth = (DWORD)_texture->get_x_size();
|
|
|
+ DWORD dwOrigWidth = (DWORD)_texture->get_x_size();
|
|
|
DWORD dwOrigHeight = (DWORD)_texture->get_y_size();
|
|
|
|
|
|
if ((_texture->get_format() == Texture::F_luminance_alpha)||
|
|
|
@@ -335,10 +339,11 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
bNeedLuminance = true;
|
|
|
}
|
|
|
|
|
|
- if (cNumAlphaBits>0) {
|
|
|
+ if (cNumAlphaBits > 0) {
|
|
|
if (cNumColorChannels == 3) {
|
|
|
- dxgsg8_cat.error() << "ERROR: texture " << _tex->get_name() << " has no inherent alpha channel, but alpha format is requested (that would be wasteful)!\n";
|
|
|
- exit(1);
|
|
|
+ dxgsg8_cat.error()
|
|
|
+ << "texture " << _tex->get_name()
|
|
|
+ << " has no inherent alpha channel, but alpha format is requested!\n";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -346,15 +351,16 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
|
|
|
// figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
|
|
|
|
|
|
- switch(cNumColorChannels) {
|
|
|
+ switch (cNumColorChannels) {
|
|
|
case 1:
|
|
|
- if (cNumAlphaBits>0)
|
|
|
+ if (cNumAlphaBits > 0) {
|
|
|
_d3d_format = D3DFMT_A8;
|
|
|
- else if (bNeedLuminance)
|
|
|
+ } else if (bNeedLuminance) {
|
|
|
_d3d_format = D3DFMT_L8;
|
|
|
+ }
|
|
|
break;
|
|
|
case 2:
|
|
|
- assert(bNeedLuminance && (cNumAlphaBits>0));
|
|
|
+ assert(bNeedLuminance && (cNumAlphaBits > 0));
|
|
|
_d3d_format = D3DFMT_A8L8;
|
|
|
break;
|
|
|
case 3:
|
|
|
@@ -371,54 +377,54 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
DWORD TargetWidth = dwOrigWidth;
|
|
|
DWORD TargetHeight = dwOrigHeight;
|
|
|
|
|
|
- if (!ISPOW2(dwOrigWidth) || !ISPOW2(dwOrigHeight)) {
|
|
|
- dxgsg8_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "! Please rescale them so it doesnt have to be done at runtime.\n";
|
|
|
-#ifndef NDEBUG
|
|
|
- exit(1); // want to catch badtexsize errors
|
|
|
-#else
|
|
|
- goto error_exit;
|
|
|
-#endif
|
|
|
+ if (scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
|
|
|
+ if (!ISPOW2(TargetWidth)) {
|
|
|
+ TargetWidth = down_to_power_2(TargetWidth);
|
|
|
+ }
|
|
|
+ if (!ISPOW2(TargetHeight)) {
|
|
|
+ TargetHeight = down_to_power_2(TargetHeight);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- bool bShrinkOriginal;
|
|
|
- bShrinkOriginal = false;
|
|
|
-
|
|
|
- if ((dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)||(dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)) {
|
|
|
-#ifdef _DEBUG
|
|
|
- dxgsg8_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << scrn.d3dcaps.MaxTextureWidth << ", " << scrn.d3dcaps.MaxTextureHeight << ") !!\n"
|
|
|
- << "Scaling " << _tex->get_name() << " (" << dwOrigWidth<< ", " <<dwOrigHeight << ") = > (" << scrn.d3dcaps.MaxTextureWidth << ", " << scrn.d3dcaps.MaxTextureHeight << ") !\n";
|
|
|
-#endif
|
|
|
-
|
|
|
- if (dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)
|
|
|
- TargetWidth = scrn.d3dcaps.MaxTextureWidth;
|
|
|
- if (dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)
|
|
|
- TargetHeight = scrn.d3dcaps.MaxTextureHeight;
|
|
|
- bShrinkOriginal = true;
|
|
|
+ if (TargetWidth > scrn.d3dcaps.MaxTextureWidth) {
|
|
|
+ TargetWidth = scrn.d3dcaps.MaxTextureWidth;
|
|
|
+ }
|
|
|
+ if (TargetHeight > scrn.d3dcaps.MaxTextureHeight) {
|
|
|
+ TargetHeight = scrn.d3dcaps.MaxTextureHeight;
|
|
|
}
|
|
|
|
|
|
// checks for SQUARE reqmt (nvidia riva128 needs this)
|
|
|
if ((TargetWidth != TargetHeight) && (scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) {
|
|
|
// assume pow2 textures. sum exponents, divide by 2 rounding down to get sq size
|
|
|
int i, width_exp, height_exp;
|
|
|
- for(i = TargetWidth, width_exp = 0; i>1; width_exp++, i >>= 1);
|
|
|
- for(i = TargetHeight, height_exp = 0; i>1; height_exp++, i >>= 1);
|
|
|
+ for (i = TargetWidth, width_exp = 0; i > 1; width_exp++, i >>= 1);
|
|
|
+ for (i = TargetHeight, height_exp = 0; i > 1; height_exp++, i >>= 1);
|
|
|
TargetHeight = TargetWidth = 1<<((width_exp+height_exp)>>1);
|
|
|
- bShrinkOriginal = true;
|
|
|
+ }
|
|
|
|
|
|
-#ifdef _DEBUG
|
|
|
- dxgsg8_cat.debug() << "Scaling " << _tex->get_name() << " (" << dwOrigWidth<< ", " <<dwOrigHeight << ") = > (" << TargetWidth<< ", " << TargetHeight << ") to meet HW square texture reqmt\n";
|
|
|
-#endif
|
|
|
+ bool bShrinkOriginal = false;
|
|
|
+
|
|
|
+ if (dwOrigWidth != TargetWidth || dwOrigHeight != TargetHeight) {
|
|
|
+ dxgsg8_cat.info()
|
|
|
+ << "Reducing size of " << _tex->get_name()
|
|
|
+ << " from " << dwOrigWidth << "x" << dwOrigHeight
|
|
|
+ << " to " << TargetWidth << "x" << TargetHeight << "\n";
|
|
|
+
|
|
|
+ bShrinkOriginal = true;
|
|
|
}
|
|
|
|
|
|
char *szErrorMsg;
|
|
|
|
|
|
- szErrorMsg = "CreateTexture failed: couldn't find compatible device Texture Pixel Format for input texture";
|
|
|
+ szErrorMsg = "create_texture failed: couldn't find compatible device Texture Pixel Format for input texture";
|
|
|
|
|
|
if (dxgsg8_cat.is_spam())
|
|
|
- dxgsg8_cat.spam() << "CreateTexture handling target bitdepth: " << target_bpp << " alphabits: " << cNumAlphaBits << endl;
|
|
|
+ dxgsg8_cat.spam()
|
|
|
+ << "create_texture handling target bitdepth: " << target_bpp
|
|
|
+ << " alphabits: " << cNumAlphaBits << endl;
|
|
|
|
|
|
- // I could possibly replace some of this logic with D3DXCheckTextureRequirements(), but
|
|
|
- // it wouldnt handle all my specialized low-memory cases perfectly
|
|
|
+ // I could possibly replace some of this logic with
|
|
|
+ // D3DXCheckTextureRequirements(), but it wouldnt handle all my
|
|
|
+ // specialized low-memory cases perfectly
|
|
|
|
|
|
#define CONVTYPE_STMT
|
|
|
|
|
|
@@ -428,12 +434,14 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
TargetPixFmt = D3DFMT_##FMT; \
|
|
|
goto found_matching_format; }
|
|
|
|
|
|
- // handle each target bitdepth separately. might be less confusing to reorg by cNumColorChannels (input type, rather
|
|
|
- // than desired 1st target)
|
|
|
- switch(target_bpp) {
|
|
|
+ // handle each target bitdepth separately. might be less confusing
|
|
|
+ // to reorg by cNumColorChannels (input type, rather than desired
|
|
|
+ // 1st target)
|
|
|
+ switch (target_bpp) {
|
|
|
|
|
|
// IMPORTANT NOTE:
|
|
|
- // target_bpp is REQUESTED bpp, not what exists in the texture array (the texture array contains cNumColorChannels*8bits)
|
|
|
+ // target_bpp is REQUESTED bpp, not what exists in the texture
|
|
|
+ // array (the texture array contains cNumColorChannels*8bits)
|
|
|
|
|
|
case 32:
|
|
|
if (!((cNumColorChannels == 3) || (cNumColorChannels == 4)))
|
|
|
@@ -452,14 +460,17 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
|
|
|
// no 32-bit fmt, look for 16 bit w/alpha (1-15)
|
|
|
|
|
|
- // 32 bit RGBA was requested, but only 16 bit alpha fmts are avail
|
|
|
- // by default, convert to 4-4-4-4 which has 4-bit alpha for blurry edges
|
|
|
- // if we know tex only needs 1 bit alpha (i.e. for a mask), use 1555 instead
|
|
|
+ // 32 bit RGBA was requested, but only 16 bit alpha fmts are
|
|
|
+ // avail. By default, convert to 4-4-4-4 which has 4-bit alpha
|
|
|
+ // for blurry edges. If we know tex only needs 1 bit alpha
|
|
|
+ // (i.e. for a mask), use 1555 instead.
|
|
|
|
|
|
- // ConversionType ConvTo1 = Conv32to16_4444, ConvTo2 = Conv32to16_1555;
|
|
|
- // DWORD dwAlphaMask1 = 0xF000, dwAlphaMask2 = 0x8000;
|
|
|
- // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify 32->16 conversion
|
|
|
- // this should be true on most cards.
|
|
|
+
|
|
|
+ // ConversionType ConvTo1 = Conv32to16_4444, ConvTo2 = Conv32to16_1555;
|
|
|
+ // DWORD dwAlphaMask1 = 0xF000, dwAlphaMask2 = 0x8000;
|
|
|
+
|
|
|
+ // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify
|
|
|
+ // 32->16 conversion. This should be true on most cards.
|
|
|
|
|
|
#ifndef FORCE_16bpp_1555
|
|
|
if (cNumAlphaBits == 1)
|
|
|
@@ -472,9 +483,9 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
|
|
|
CHECK_FOR_FMT(A1R5G5B5, Conv32to16_1555);
|
|
|
|
|
|
- // at this point, bail. dont worry about converting to non-alpha formats yet,
|
|
|
- // I think this will be a very rare case
|
|
|
- szErrorMsg = "CreateTexture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
|
|
|
+ // At this point, bail. Don't worry about converting to
|
|
|
+ // non-alpha formats yet, I think this will be a very rare case.
|
|
|
+ szErrorMsg = "create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
|
|
|
} else {
|
|
|
// convert 3 or 4 channel to closest 16bpp color fmt
|
|
|
|
|
|
@@ -494,8 +505,9 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
if (!dx_force_16bpptextures) {
|
|
|
CHECK_FOR_FMT(R8G8B8, Conv24to24);
|
|
|
|
|
|
- // no 24-bit fmt. look for 32 bit fmt (note: this is memory-hogging choice
|
|
|
- // instead I could look for memory-conserving 16-bit fmt).
|
|
|
+ // no 24-bit fmt. look for 32 bit fmt (note: this is
|
|
|
+ // memory-hogging choice instead I could look for
|
|
|
+ // memory-conserving 16-bit fmt).
|
|
|
|
|
|
CHECK_FOR_FMT(X8R8G8B8, Conv24to32);
|
|
|
}
|
|
|
@@ -543,13 +555,16 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
}
|
|
|
break;
|
|
|
case 1:
|
|
|
- // app specifically requests 1-5-5-5 F_rgba5 case, where you explicitly want 1-5-5-5 fmt, as opposed
|
|
|
- // to F_rgbm, which could use 32bpp ARGB. fail if this particular fmt not avail.
|
|
|
+ // app specifically requests 1-5-5-5 F_rgba5 case, where you
|
|
|
+ // explicitly want 1-5-5-5 fmt, as opposed to F_rgbm, which
|
|
|
+ // could use 32bpp ARGB. fail if this particular fmt not
|
|
|
+ // avail.
|
|
|
assert(cNumColorChannels == 4);
|
|
|
CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
|
|
|
break;
|
|
|
case 4:
|
|
|
- // app specifically requests 4-4-4-4 F_rgba4 case, as opposed to F_rgba, which could use 32bpp ARGB
|
|
|
+ // app specifically requests 4-4-4-4 F_rgba4 case, as opposed
|
|
|
+ // to F_rgba, which could use 32bpp ARGB
|
|
|
assert(cNumColorChannels == 4);
|
|
|
CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
|
|
|
break;
|
|
|
@@ -558,7 +573,8 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
}
|
|
|
case 8:
|
|
|
if (bNeedLuminance) {
|
|
|
- // dont bother handling those other 8bit lum fmts like 4-4, since 16 8-8 is usually supported too
|
|
|
+ // dont bother handling those other 8bit lum fmts like 4-4,
|
|
|
+ // since 16 8-8 is usually supported too
|
|
|
assert(cNumColorChannels == 1);
|
|
|
|
|
|
// look for native lum fmt first
|
|
|
@@ -576,9 +592,10 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
} else if (cNumAlphaBits == 8) {
|
|
|
// look for 16bpp A8L8, else 32-bit ARGB, else 16-4444.
|
|
|
|
|
|
- // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo supports it
|
|
|
- // and the voodoo support isn't the kind of blending model we need somehow
|
|
|
- // (is it that voodoo assumes color is white? isnt that what we do in ConvAlpha8to32 anyway?)
|
|
|
+ // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo
|
|
|
+ // supports it and the voodoo support isn't the kind of blending
|
|
|
+ // model we need somehow (is it that voodoo assumes color is
|
|
|
+ // white? isnt that what we do in ConvAlpha8to32 anyway?)
|
|
|
|
|
|
CHECK_FOR_FMT(A8L8, ConvAlpha8to16_A8L8);
|
|
|
|
|
|
@@ -591,14 +608,15 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- szErrorMsg = "CreateTexture failed: unhandled pixel bitdepth in DX loader";
|
|
|
+ szErrorMsg = "create_texture failed: unhandled pixel bitdepth in DX loader";
|
|
|
}
|
|
|
|
|
|
// if we've gotten here, haven't found a match
|
|
|
- dxgsg8_cat.error() << szErrorMsg << ": " << _tex->get_name() << endl
|
|
|
- << "NumColorChannels: " <<cNumColorChannels << "; NumAlphaBits: " << cNumAlphaBits
|
|
|
- << "; targetbpp: " <<target_bpp << "; SupportedTexFmtsMask: 0x" << (void*)scrn.SupportedTexFmtsMask
|
|
|
- << "; NeedLuminance: " << bNeedLuminance << endl;
|
|
|
+ dxgsg8_cat.error()
|
|
|
+ << szErrorMsg << ": " << _tex->get_name() << endl
|
|
|
+ << "NumColorChannels: " <<cNumColorChannels << "; NumAlphaBits: " << cNumAlphaBits
|
|
|
+ << "; targetbpp: " <<target_bpp << "; SupportedTexFmtsMask: 0x" << (void*)scrn.SupportedTexFmtsMask
|
|
|
+ << "; NeedLuminance: " << bNeedLuminance << endl;
|
|
|
goto error_exit;
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
@@ -613,13 +631,14 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
IDirect3DSurface8 *pCurRenderTarget;
|
|
|
hr = scrn.pD3DDevice->GetRenderTarget(&pCurRenderTarget);
|
|
|
if (FAILED(hr)) {
|
|
|
- dxgsg8_cat.error() << "GetRenderTgt failed in CreateTexture: " << D3DERRORSTRING(hr);
|
|
|
+ dxgsg8_cat.error()
|
|
|
+ << "GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
|
|
|
} else {
|
|
|
D3DSURFACE_DESC SurfDesc;
|
|
|
hr = pCurRenderTarget->GetDesc(&SurfDesc);
|
|
|
if (FAILED(hr)) {
|
|
|
dxgsg8_cat.error()
|
|
|
- << "GetDesc failed in CreateTexture: " << D3DERRORSTRING(hr);
|
|
|
+ << "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
|
|
|
} else {
|
|
|
if (TargetPixFmt != SurfDesc.Format) {
|
|
|
if (dxgsg8_cat.is_debug()) {
|
|
|
@@ -648,8 +667,9 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
else ft = Texture::FT_linear;
|
|
|
}
|
|
|
|
|
|
- if ((ft == Texture::FT_linear) && !(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR))
|
|
|
+ if ((ft == Texture::FT_linear) && !(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR)) {
|
|
|
ft = Texture::FT_nearest;
|
|
|
+ }
|
|
|
_tex->set_magfilter(ft);
|
|
|
|
|
|
// figure out if we are mipmapping this texture
|
|
|
@@ -668,15 +688,18 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
if (dx_mipmap_everything) { // debug toggle, ok to leave in since its just a creation cost
|
|
|
_has_mipmaps = true;
|
|
|
if (dxgsg8_cat.is_spam()) {
|
|
|
- if (ft != Texture::FT_linear_mipmap_linear)
|
|
|
+ if (ft != Texture::FT_linear_mipmap_linear) {
|
|
|
dxgsg8_cat.spam() << "Forcing trilinear mipmapping on DX texture [" << _tex->get_name() << "]\n";
|
|
|
+ }
|
|
|
}
|
|
|
ft = Texture::FT_linear_mipmap_linear;
|
|
|
_tex->set_minfilter(ft);
|
|
|
}
|
|
|
+
|
|
|
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
|
|
- (ft == Texture::FT_nearest_mipmap_linear)) {
|
|
|
+ (ft == Texture::FT_nearest_mipmap_linear)) {
|
|
|
ft = Texture::FT_nearest;
|
|
|
+
|
|
|
} else if ((ft == Texture::FT_linear_mipmap_nearest) ||
|
|
|
(ft == Texture::FT_linear_mipmap_linear)) {
|
|
|
ft = Texture::FT_linear;
|
|
|
@@ -690,25 +713,35 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
switch(ft) {
|
|
|
case Texture::FT_linear_mipmap_linear:
|
|
|
if ((scrn.d3dcaps.TextureFilterCaps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
|
|
|
- if (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)
|
|
|
+ if (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) {
|
|
|
ft = Texture::FT_linear_mipmap_nearest;
|
|
|
- else ft = Texture::FT_nearest_mipmap_nearest; // if you cant do linear in a level, you probably cant do linear b/w levels, so just do nearest-all
|
|
|
+ } else {
|
|
|
+ // if you cant do linear in a level, you probably cant do
|
|
|
+ // linear b/w levels, so just do nearest-all
|
|
|
+ ft = Texture::FT_nearest_mipmap_nearest;
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
+
|
|
|
case Texture::FT_nearest_mipmap_linear:
|
|
|
// if we dont have bilinear, do nearest_nearest
|
|
|
if (!((scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFPOINT) &&
|
|
|
- (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)))
|
|
|
+ (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))) {
|
|
|
ft = Texture::FT_nearest_mipmap_nearest;
|
|
|
+ }
|
|
|
break;
|
|
|
+
|
|
|
case Texture::FT_linear_mipmap_nearest:
|
|
|
// if we dont have mip linear, do nearest_nearest
|
|
|
- if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR))
|
|
|
+ if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) {
|
|
|
ft = Texture::FT_nearest_mipmap_nearest;
|
|
|
+ }
|
|
|
break;
|
|
|
+
|
|
|
case Texture::FT_linear:
|
|
|
- if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))
|
|
|
+ if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)) {
|
|
|
ft = Texture::FT_nearest;
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -719,35 +752,50 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
aniso_degree = 1;
|
|
|
if (scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
|
|
aniso_degree = _tex->get_anisotropic_degree();
|
|
|
- if ((aniso_degree>scrn.d3dcaps.MaxAnisotropy) || dx_force_anisotropic_filtering)
|
|
|
+ if ((aniso_degree>scrn.d3dcaps.MaxAnisotropy) ||
|
|
|
+ dx_force_anisotropic_filtering) {
|
|
|
aniso_degree = scrn.d3dcaps.MaxAnisotropy;
|
|
|
+ }
|
|
|
}
|
|
|
_tex->set_anisotropic_degree(aniso_degree);
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
- dxgsg8_cat.spam() << "CreateTexture: setting aniso degree for " << _tex->get_name() << " to: " << aniso_degree << endl;
|
|
|
+ dxgsg8_cat.spam()
|
|
|
+ << "create_texture: setting aniso degree for " << _tex->get_name()
|
|
|
+ << " to: " << aniso_degree << endl;
|
|
|
#endif
|
|
|
|
|
|
UINT cMipLevelCount;
|
|
|
|
|
|
if (_has_mipmaps) {
|
|
|
- cMipLevelCount = 0; // tell CreateTex to alloc space for all mip levels down to 1x1
|
|
|
+ // tell CreateTex to alloc space for all mip levels down to 1x1
|
|
|
+ cMipLevelCount = 0;
|
|
|
|
|
|
- if (dxgsg8_cat.is_debug())
|
|
|
- dxgsg8_cat.debug() << "CreateTexture: generating mipmaps for " << _tex->get_name() << endl;
|
|
|
- } else cMipLevelCount = 1;
|
|
|
+ if (dxgsg8_cat.is_debug()) {
|
|
|
+ dxgsg8_cat.debug()
|
|
|
+ << "create_texture: generating mipmaps for " << _tex->get_name()
|
|
|
+ << endl;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cMipLevelCount = 1;
|
|
|
+ }
|
|
|
|
|
|
- if (FAILED( hr = scrn.pD3DDevice->CreateTexture(TargetWidth, TargetHeight, cMipLevelCount, 0x0,
|
|
|
- TargetPixFmt, D3DPOOL_MANAGED, &_d3d_texture) )) {
|
|
|
- dxgsg8_cat.error() << "D3D CreateTexture failed!" << D3DERRORSTRING(hr);
|
|
|
+ hr = scrn.pD3DDevice->CreateTexture(TargetWidth, TargetHeight, cMipLevelCount, 0x0,
|
|
|
+ TargetPixFmt, D3DPOOL_MANAGED, &_d3d_texture);
|
|
|
+ if (FAILED(hr)) {
|
|
|
+ dxgsg8_cat.error()
|
|
|
+ << "D3D create_texture failed!" << D3DERRORSTRING(hr);
|
|
|
goto error_exit;
|
|
|
}
|
|
|
|
|
|
if (dxgsg8_cat.is_debug()) {
|
|
|
- dxgsg8_cat.debug() << "CreateTexture: " << _tex->get_name() << " converting panda equivalent of " << D3DFormatStr(_d3d_format) << " = > " << D3DFormatStr(TargetPixFmt) << endl;
|
|
|
+ dxgsg8_cat.debug()
|
|
|
+ << "create_texture: " << _tex->get_name()
|
|
|
+ << " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
|
|
+ << " => " << D3DFormatStr(TargetPixFmt) << endl;
|
|
|
}
|
|
|
|
|
|
- hr = FillDDSurfTexturePixels();
|
|
|
+ hr = fill_d3d_texture_pixels();
|
|
|
if (FAILED(hr)) {
|
|
|
goto error_exit;
|
|
|
}
|
|
|
@@ -764,7 +812,7 @@ CreateTexture(DXScreenData &scrn) {
|
|
|
}
|
|
|
|
|
|
HRESULT DXTextureContext8::
|
|
|
-FillDDSurfTexturePixels() {
|
|
|
+fill_d3d_texture_pixels() {
|
|
|
HRESULT hr = E_FAIL;
|
|
|
assert(IS_VALID_PTR(_texture));
|
|
|
|
|
|
@@ -866,22 +914,25 @@ FillDDSurfTexturePixels() {
|
|
|
GraphicsStateGuardian::_data_transferred_pcollector.add_level(SrcPixBufRowByteLength * OrigHeight);
|
|
|
#endif
|
|
|
hr = D3DXLoadSurfaceFromMemory(pMipLevel0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pPixels, SrcFormat,
|
|
|
- SrcPixBufRowByteLength, (PALETTEENTRY*)NULL, &SrcSize, Lev0Filter, (D3DCOLOR)0x0);
|
|
|
+ SrcPixBufRowByteLength, (PALETTEENTRY*)NULL, &SrcSize, Lev0Filter, (D3DCOLOR)0x0);
|
|
|
if (FAILED(hr)) {
|
|
|
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
|
|
goto exit_FillDDSurf;
|
|
|
}
|
|
|
|
|
|
if (_has_mipmaps) {
|
|
|
- if (!dx_use_triangle_mipgen_filter)
|
|
|
+ if (!dx_use_triangle_mipgen_filter) {
|
|
|
MipFilterFlags = D3DX_FILTER_BOX;
|
|
|
- else MipFilterFlags = D3DX_FILTER_TRIANGLE;
|
|
|
+ } else {
|
|
|
+ MipFilterFlags = D3DX_FILTER_TRIANGLE;
|
|
|
+ }
|
|
|
|
|
|
// MipFilterFlags| = D3DX_FILTER_DITHER;
|
|
|
|
|
|
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0, MipFilterFlags);
|
|
|
if (FAILED(hr)) {
|
|
|
- dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
|
|
+ dxgsg8_cat.error()
|
|
|
+ << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
|
|
goto exit_FillDDSurf;
|
|
|
}
|
|
|
}
|
|
|
@@ -895,11 +946,11 @@ FillDDSurfTexturePixels() {
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-// Name: DeleteTexture()
|
|
|
+// Name: delete_texture()
|
|
|
// Desc: Release the surface used to store the texture
|
|
|
//-----------------------------------------------------------------------------
|
|
|
void DXTextureContext8::
|
|
|
-DeleteTexture( ) {
|
|
|
+delete_texture( ) {
|
|
|
if (_d3d_texture == NULL) {
|
|
|
// dont bother printing the msg below, since we already released it.
|
|
|
return;
|
|
|
@@ -923,7 +974,8 @@ DXTextureContext8(Texture *tex) :
|
|
|
TextureContext(tex) {
|
|
|
|
|
|
if (dxgsg8_cat.is_spam()) {
|
|
|
- dxgsg8_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
|
|
|
+ dxgsg8_cat.spam()
|
|
|
+ << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
|
|
|
}
|
|
|
|
|
|
_d3d_texture = NULL;
|
|
|
@@ -934,10 +986,26 @@ DXTextureContext8(Texture *tex) :
|
|
|
DXTextureContext8::
|
|
|
~DXTextureContext8() {
|
|
|
if (dxgsg8_cat.is_spam()) {
|
|
|
- dxgsg8_cat.spam() << "Deleting DX8 TexContext for " << _tex->get_name() << "\n";
|
|
|
+ dxgsg8_cat.spam()
|
|
|
+ << "Deleting DX8 TexContext for " << _tex->get_name() << "\n";
|
|
|
}
|
|
|
- DeleteTexture();
|
|
|
+ delete_texture();
|
|
|
TextureContext::~TextureContext();
|
|
|
_tex = NULL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: DXTextureContext8::down_to_power_2
|
|
|
+// Access: Private, Static
|
|
|
+// Description: Returns the largest power of 2 less than or equal
|
|
|
+// to value.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+int DXTextureContext8::
|
|
|
+down_to_power_2(int value) {
|
|
|
+ int x = 1;
|
|
|
+ while ((x << 1) <= value) {
|
|
|
+ x = (x << 1);
|
|
|
+ }
|
|
|
+ return x;
|
|
|
+}
|