mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
async texture loading support for dx8,9
This commit is contained in:
parent
f6b0191067
commit
93cef9c3bf
@ -160,7 +160,9 @@ prepare_texture(Texture *tex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
if (!upload_texture(dtc)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to create texture " << *tex << endl;
|
||||
delete dtc;
|
||||
return NULL;
|
||||
}
|
||||
@ -186,28 +188,21 @@ apply_texture(int i, TextureContext *tc) {
|
||||
tc->set_active(true);
|
||||
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
Texture *tex = tc->get_texture();
|
||||
|
||||
// If the texture image has changed, or if its use of mipmaps has
|
||||
// changed, we need to re-create the image.
|
||||
|
||||
if (dtc->was_modified()) {
|
||||
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
if (!upload_texture(dtc)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
<< "Unable to re-create texture " << *tex << endl;
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Texture *tex = tc->get_texture();
|
||||
Texture::WrapMode wrap_u, wrap_v, wrap_w;
|
||||
wrap_u = tex->get_wrap_u();
|
||||
wrap_v = tex->get_wrap_v();
|
||||
@ -249,16 +244,10 @@ apply_texture(int i, TextureContext *tc) {
|
||||
new_mip_filter = D3DTEXF_NONE;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// sanity check
|
||||
if ((!dtc->has_mipmaps()) && (new_mip_filter != D3DTEXF_NONE)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "Trying to set mipmap filtering for texture with no generated mipmaps!! texname["
|
||||
<< tex->get_name() << "], filter("
|
||||
<< tex->get_minfilter() << ")\n";
|
||||
if (!dtc->has_mipmaps()) {
|
||||
new_mip_filter = D3DTEXF_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aniso_degree >= 2) {
|
||||
new_min_filter = D3DTEXF_ANISOTROPIC;
|
||||
@ -270,6 +259,39 @@ apply_texture(int i, TextureContext *tc) {
|
||||
_d3d_device->SetTexture(i, dtc->get_d3d_texture());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::upload_texture
|
||||
// Access: Public
|
||||
// Description: Creates a texture surface on the graphics card and
|
||||
// fills it with its pixel data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian8::
|
||||
upload_texture(DXTextureContext8 *dtc) {
|
||||
Texture *tex = dtc->get_texture();
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg8_cat.error()
|
||||
<< *tex << " is stored in an unsupported compressed format.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_incomplete_render &&
|
||||
!tex->has_ram_image() && tex->might_have_ram_image() &&
|
||||
tex->has_simple_ram_image() &&
|
||||
!_loader.is_null()) {
|
||||
// If we don't have the texture data right now, go get it, but in
|
||||
// the meantime load a temporary simple image in its place.
|
||||
async_reload_texture(dtc);
|
||||
if (!tex->has_ram_image()) {
|
||||
if (dtc->was_simple_image_modified()) {
|
||||
return dtc->create_simple_texture(*_screen);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return dtc->create_texture(*_screen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::release_texture
|
||||
// Access: Public, Virtual
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
class Light;
|
||||
|
||||
class DXTextureContext8;
|
||||
class DXVertexBufferContext8;
|
||||
class DXIndexBufferContext8;
|
||||
|
||||
@ -49,6 +50,7 @@ public:
|
||||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
void apply_texture(int i, TextureContext *tc);
|
||||
bool upload_texture(DXTextureContext8 *dtc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||
|
@ -722,6 +722,95 @@ create_texture(DXScreenData &scrn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::create_simple_texture
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXTextureContext8::
|
||||
create_simple_texture(DXScreenData &scrn) {
|
||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
delete_texture();
|
||||
|
||||
_d3d_format = D3DFMT_A8R8G8B8;
|
||||
D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
|
||||
DWORD target_bpp = 32;
|
||||
DWORD num_color_channels = 4;
|
||||
|
||||
DWORD target_width = (DWORD)get_texture()->get_simple_x_size();
|
||||
DWORD target_height = (DWORD)get_texture()->get_simple_y_size();
|
||||
DWORD mip_level_count = 1;
|
||||
DWORD usage = 0;
|
||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||
|
||||
int data_size = target_width * target_height * 4;
|
||||
|
||||
hr = scrn._d3d_device->CreateTexture
|
||||
(target_width, target_height, mip_level_count, usage,
|
||||
target_pixel_format, pool, &_d3d_2d_texture);
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg8_cat.error()
|
||||
<< " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n";
|
||||
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "create_simple_texture: " << get_texture()->get_name()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
{
|
||||
CPTA_uchar image = get_texture()->get_simple_ram_image();
|
||||
|
||||
hr = -1;
|
||||
// hr = fill_d3d_texture_pixels(scrn._supports_automatic_mipmap_generation, scrn._d3d_device);
|
||||
|
||||
IDirect3DSurface8 *surface = NULL;
|
||||
_d3d_2d_texture->GetSurfaceLevel(0, &surface);
|
||||
|
||||
RECT source_size;
|
||||
source_size.left = source_size.top = 0;
|
||||
source_size.right = target_width;
|
||||
source_size.bottom = target_height;
|
||||
|
||||
DWORD mip_filter = D3DX_FILTER_LINEAR;
|
||||
|
||||
hr = D3DXLoadSurfaceFromMemory
|
||||
(surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)image.p(),
|
||||
target_pixel_format, target_width * 4, (PALETTEENTRY*)NULL,
|
||||
&source_size, mip_filter, (D3DCOLOR)0x0);
|
||||
|
||||
RELEASE(surface, dxgsg8, "create_simple_texture Surface", RELEASE_ONCE);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.debug ()
|
||||
<< "*** fill_d3d_texture_pixels failed ***: format "
|
||||
<< target_pixel_format
|
||||
<< "\n";
|
||||
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
mark_simple_loaded();
|
||||
return true;
|
||||
|
||||
error_exit:
|
||||
RELEASE(_d3d_texture, dxgsg8, "texture", RELEASE_ONCE);
|
||||
_d3d_2d_texture = NULL;
|
||||
_d3d_volume_texture = NULL;
|
||||
_d3d_cube_texture = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::delete_texture
|
||||
// Access: Public
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
virtual ~DXTextureContext8();
|
||||
|
||||
bool create_texture(DXScreenData &scrn);
|
||||
bool create_simple_texture(DXScreenData &scrn);
|
||||
void delete_texture();
|
||||
|
||||
INLINE bool has_mipmaps() const;
|
||||
|
@ -207,7 +207,9 @@ prepare_texture(Texture *tex) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
if (!upload_texture(dtc)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to create texture " << *tex << endl;
|
||||
delete dtc;
|
||||
return NULL;
|
||||
}
|
||||
@ -237,28 +239,21 @@ apply_texture(int i, TextureContext *tc) {
|
||||
if (_lru) {
|
||||
_lru -> access_page (dtc -> _lru_page);
|
||||
}
|
||||
Texture *tex = tc->get_texture();
|
||||
|
||||
// If the texture image has changed, or if its use of mipmaps has
|
||||
// changed, we need to re-create the image.
|
||||
|
||||
if (dtc->was_modified()) {
|
||||
if (!get_supports_compressed_texture_format(tc->get_texture()->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *dtc->get_texture() << " is stored in an unsupported compressed format.\n";
|
||||
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
if (!upload_texture(dtc)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg9_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
|
||||
<< "Unable to re-create texture " << *tex << endl;
|
||||
set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Texture *tex = tc->get_texture();
|
||||
Texture::WrapMode wrap_u, wrap_v, wrap_w;
|
||||
|
||||
DWORD address_u;
|
||||
@ -311,16 +306,10 @@ apply_texture(int i, TextureContext *tc) {
|
||||
new_mip_filter = D3DTEXF_NONE;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// sanity check
|
||||
if ((!dtc->has_mipmaps()) && (new_mip_filter != D3DTEXF_NONE)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "Trying to set mipmap filtering for texture with no generated mipmaps!! texname["
|
||||
<< tex->get_name() << "], filter("
|
||||
<< tex->get_minfilter() << ")\n";
|
||||
if (!dtc->has_mipmaps()) {
|
||||
new_mip_filter = D3DTEXF_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aniso_degree >= 2) {
|
||||
new_min_filter = D3DTEXF_ANISOTROPIC;
|
||||
@ -332,6 +321,39 @@ apply_texture(int i, TextureContext *tc) {
|
||||
_d3d_device->SetTexture(i, dtc->get_d3d_texture());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian9::upload_texture
|
||||
// Access: Public
|
||||
// Description: Creates a texture surface on the graphics card and
|
||||
// fills it with its pixel data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
upload_texture(DXTextureContext9 *dtc) {
|
||||
Texture *tex = dtc->get_texture();
|
||||
if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) {
|
||||
dxgsg9_cat.error()
|
||||
<< *tex << " is stored in an unsupported compressed format.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_incomplete_render &&
|
||||
!tex->has_ram_image() && tex->might_have_ram_image() &&
|
||||
tex->has_simple_ram_image() &&
|
||||
!_loader.is_null()) {
|
||||
// If we don't have the texture data right now, go get it, but in
|
||||
// the meantime load a temporary simple image in its place.
|
||||
async_reload_texture(dtc);
|
||||
if (!tex->has_ram_image()) {
|
||||
if (dtc->was_simple_image_modified()) {
|
||||
return dtc->create_simple_texture(*_screen);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return dtc->create_texture(*_screen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian9::release_texture
|
||||
// Access: Public, Virtual
|
||||
|
@ -64,6 +64,7 @@ enum GsgPageType
|
||||
|
||||
class Light;
|
||||
|
||||
class DXTextureContext9;
|
||||
class DXVertexBufferContext9;
|
||||
class DXIndexBufferContext9;
|
||||
|
||||
@ -83,6 +84,7 @@ public:
|
||||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
void apply_texture(int i, TextureContext *tc);
|
||||
bool upload_texture(DXTextureContext9 *dtc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
ShaderContext *prepare_shader(Shader *se);
|
||||
|
@ -88,7 +88,6 @@ create_texture(DXScreenData &scrn) {
|
||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
||||
|
||||
delete_texture();
|
||||
mark_loaded();
|
||||
|
||||
// bpp indicates requested fmt, not texture fmt
|
||||
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
|
||||
@ -968,6 +967,95 @@ create_texture(DXScreenData &scrn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext9::create_simple_texture
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXTextureContext9::
|
||||
create_simple_texture(DXScreenData &scrn) {
|
||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
delete_texture();
|
||||
|
||||
_d3d_format = D3DFMT_A8R8G8B8;
|
||||
D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
|
||||
DWORD target_bpp = 32;
|
||||
DWORD num_color_channels = 4;
|
||||
|
||||
DWORD target_width = (DWORD)get_texture()->get_simple_x_size();
|
||||
DWORD target_height = (DWORD)get_texture()->get_simple_y_size();
|
||||
DWORD mip_level_count = 1;
|
||||
DWORD usage = 0;
|
||||
D3DPOOL pool = D3DPOOL_MANAGED;
|
||||
|
||||
int data_size = target_width * target_height * 4;
|
||||
|
||||
hr = scrn._d3d_device->CreateTexture
|
||||
(target_width, target_height, mip_level_count, usage,
|
||||
target_pixel_format, pool, &_d3d_2d_texture, NULL);
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.error()
|
||||
<< "D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg9_cat.error()
|
||||
<< " width = " << target_width << " height = " << target_height << " target_pixel_format = " << target_pixel_format << "\n";
|
||||
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
|
||||
dxgsg9_cat.debug()
|
||||
<< "create_simple_texture: " << get_texture()->get_name()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
{
|
||||
CPTA_uchar image = get_texture()->get_simple_ram_image();
|
||||
|
||||
hr = -1;
|
||||
// hr = fill_d3d_texture_pixels(scrn._supports_automatic_mipmap_generation, scrn._d3d_device);
|
||||
|
||||
IDirect3DSurface9 *surface = NULL;
|
||||
_d3d_2d_texture->GetSurfaceLevel(0, &surface);
|
||||
|
||||
RECT source_size;
|
||||
source_size.left = source_size.top = 0;
|
||||
source_size.right = target_width;
|
||||
source_size.bottom = target_height;
|
||||
|
||||
DWORD mip_filter = D3DX_FILTER_LINEAR;
|
||||
|
||||
hr = D3DXLoadSurfaceFromMemory
|
||||
(surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)image.p(),
|
||||
target_pixel_format, target_width * 4, (PALETTEENTRY*)NULL,
|
||||
&source_size, mip_filter, (D3DCOLOR)0x0);
|
||||
|
||||
RELEASE(surface, dxgsg9, "create_simple_texture Surface", RELEASE_ONCE);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg9_cat.debug ()
|
||||
<< "*** fill_d3d_texture_pixels failed ***: format "
|
||||
<< target_pixel_format
|
||||
<< "\n";
|
||||
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
mark_simple_loaded();
|
||||
return true;
|
||||
|
||||
error_exit:
|
||||
RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE);
|
||||
_d3d_2d_texture = NULL;
|
||||
_d3d_volume_texture = NULL;
|
||||
_d3d_cube_texture = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext9::delete_texture
|
||||
// Access: Public
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
virtual ~DXTextureContext9();
|
||||
|
||||
bool create_texture(DXScreenData &scrn);
|
||||
bool create_simple_texture(DXScreenData &scrn);
|
||||
void delete_texture();
|
||||
|
||||
INLINE bool has_mipmaps() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user