mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
directx extract_texture_data
This commit is contained in:
parent
ea3f6a2206
commit
4074c2717a
@ -304,6 +304,27 @@ release_texture(TextureContext *tc) {
|
|||||||
delete dtc;
|
delete dtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DXGraphicsStateGuardian8::extract_texture_data
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: This method should only be called by the
|
||||||
|
// GraphicsEngine. Do not call it directly; call
|
||||||
|
// GraphicsEngine::extract_texture_data() instead.
|
||||||
|
//
|
||||||
|
// This method will be called in the draw thread to
|
||||||
|
// download the texture memory's image into its
|
||||||
|
// ram_image value. It returns true on success, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DXGraphicsStateGuardian8::
|
||||||
|
extract_texture_data(Texture *tex) {
|
||||||
|
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||||
|
nassertr(tc != (TextureContext *)NULL, false);
|
||||||
|
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||||
|
|
||||||
|
return dtc->extract_texture_data();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DXGraphicsStateGuardian8::prepare_vertex_buffer
|
// Function: DXGraphicsStateGuardian8::prepare_vertex_buffer
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
void apply_texture(int i, TextureContext *tc);
|
void apply_texture(int i, TextureContext *tc);
|
||||||
bool upload_texture(DXTextureContext8 *dtc);
|
bool upload_texture(DXTextureContext8 *dtc);
|
||||||
virtual void release_texture(TextureContext *tc);
|
virtual void release_texture(TextureContext *tc);
|
||||||
|
virtual bool extract_texture_data(Texture *tex);
|
||||||
|
|
||||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||||
bool apply_vertex_buffer(VertexBufferContext *vbc,
|
bool apply_vertex_buffer(VertexBufferContext *vbc,
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "dxGraphicsStateGuardian8.h"
|
#include "dxGraphicsStateGuardian8.h"
|
||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
#include "dxgsg8base.h"
|
#include "dxgsg8base.h"
|
||||||
|
#include "bamCache.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -684,6 +685,9 @@ create_texture(DXScreenData &scrn) {
|
|||||||
UINT mip_level_count;
|
UINT mip_level_count;
|
||||||
|
|
||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
|
tex->get_ram_image();
|
||||||
|
mip_level_count = tex->get_num_loadable_ram_mipmap_images();
|
||||||
|
if (mip_level_count < 2) {
|
||||||
// tell CreateTex to alloc space for all mip levels down to 1x1
|
// tell CreateTex to alloc space for all mip levels down to 1x1
|
||||||
mip_level_count = 0;
|
mip_level_count = 0;
|
||||||
|
|
||||||
@ -692,6 +696,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
<< "create_texture: generating mipmaps for " << tex->get_name()
|
<< "create_texture: generating mipmaps for " << tex->get_name()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mip_level_count = 1;
|
mip_level_count = 1;
|
||||||
}
|
}
|
||||||
@ -753,6 +758,21 @@ create_texture(DXScreenData &scrn) {
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tex->get_post_load_store_cache()) {
|
||||||
|
tex->set_post_load_store_cache(false);
|
||||||
|
// OK, get the RAM image, and save it in a BamCache record.
|
||||||
|
if (extract_texture_data()) {
|
||||||
|
if (tex->has_ram_image()) {
|
||||||
|
BamCache *cache = BamCache::get_global_ptr();
|
||||||
|
PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
|
||||||
|
if (record != (BamCacheRecord *)NULL) {
|
||||||
|
record->set_data(tex, false);
|
||||||
|
cache->store(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tex->texture_uploaded(scrn._dxgsg8);
|
tex->texture_uploaded(scrn._dxgsg8);
|
||||||
mark_loaded();
|
mark_loaded();
|
||||||
return true;
|
return true;
|
||||||
@ -873,6 +893,119 @@ delete_texture() {
|
|||||||
_d3d_cube_texture = NULL;
|
_d3d_cube_texture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DXTextureContext8::extract_texture_data
|
||||||
|
// Access: Public
|
||||||
|
// Description: This method will be called in the draw thread to
|
||||||
|
// download the texture memory's image into its
|
||||||
|
// ram_image value. It returns true on success, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DXTextureContext8::
|
||||||
|
extract_texture_data() {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
Texture *tex = get_texture();
|
||||||
|
if (tex->get_texture_type() != Texture::TT_2d_texture) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "Not supported: extract_texture_data for " << tex->get_texture_type()
|
||||||
|
<< "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nassertr(IS_VALID_PTR(_d3d_2d_texture), false);
|
||||||
|
|
||||||
|
D3DSURFACE_DESC desc;
|
||||||
|
hr = _d3d_2d_texture->GetLevelDesc(0, &desc);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int div = 1;
|
||||||
|
Texture::Format format = Texture::F_rgba;
|
||||||
|
Texture::CompressionMode compression = Texture::CM_off;
|
||||||
|
|
||||||
|
switch (desc.Format) {
|
||||||
|
case D3DFMT_R8G8B8:
|
||||||
|
format = Texture::F_rgb;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_A8R8G8B8:
|
||||||
|
case D3DFMT_X8R8G8B8:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_L8:
|
||||||
|
format = Texture::F_luminance;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_A8L8:
|
||||||
|
format = Texture::F_luminance_alpha;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_DXT1:
|
||||||
|
compression = Texture::CM_dxt1;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT2:
|
||||||
|
compression = Texture::CM_dxt2;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT3:
|
||||||
|
compression = Texture::CM_dxt3;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT4:
|
||||||
|
compression = Texture::CM_dxt4;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT5:
|
||||||
|
compression = Texture::CM_dxt5;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "Cannot extract texture data: unhandled surface format "
|
||||||
|
<< desc.Format << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_levels = _d3d_2d_texture->GetLevelCount();
|
||||||
|
|
||||||
|
tex->set_x_size(desc.Width);
|
||||||
|
tex->set_y_size(desc.Height);
|
||||||
|
tex->set_z_size(1);
|
||||||
|
tex->set_component_type(Texture::T_unsigned_byte);
|
||||||
|
tex->set_format(format);
|
||||||
|
tex->clear_ram_image();
|
||||||
|
|
||||||
|
for (int n = 0; n < num_levels; ++n) {
|
||||||
|
D3DLOCKED_RECT rect;
|
||||||
|
hr = _d3d_2d_texture->LockRect(n, &rect, NULL, D3DLOCK_READONLY);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "Texture::LockRect() failed!" << D3DERRORSTRING(hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y_size = tex->get_expected_mipmap_y_size(n);
|
||||||
|
int size = rect.Pitch * (y_size / div);
|
||||||
|
size = min(size, (int)tex->get_expected_ram_mipmap_image_size(n));
|
||||||
|
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||||
|
memcpy(image.p(), rect.pBits, size);
|
||||||
|
|
||||||
|
_d3d_2d_texture->UnlockRect(n);
|
||||||
|
if (n == 0) {
|
||||||
|
tex->set_ram_image(image, compression);
|
||||||
|
} else {
|
||||||
|
tex->set_ram_mipmap_image(n, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DXTextureContext8::d3d_surface_to_texture
|
// Function: DXTextureContext8::d3d_surface_to_texture
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -1181,6 +1314,7 @@ HRESULT DXTextureContext8::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||||||
bool using_temp_buffer = false;
|
bool using_temp_buffer = false;
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level);
|
CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level);
|
||||||
|
nassertr(!image.is_null(), E_FAIL);
|
||||||
BYTE *pixels = (BYTE*) image.p();
|
BYTE *pixels = (BYTE*) image.p();
|
||||||
DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level);
|
DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level);
|
||||||
DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level);
|
DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level);
|
||||||
@ -1276,6 +1410,7 @@ HRESULT DXTextureContext8::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg8_cat.error()
|
dxgsg8_cat.error()
|
||||||
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
||||||
|
<< ", mip_level " << mip_level
|
||||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1295,14 +1430,16 @@ exit_FillMipmapSurf:
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
HRESULT DXTextureContext8::
|
HRESULT DXTextureContext8::
|
||||||
fill_d3d_texture_pixels() {
|
fill_d3d_texture_pixels() {
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
Texture *tex = get_texture();
|
||||||
|
nassertr(IS_VALID_PTR(tex), E_FAIL);
|
||||||
|
if (tex->get_texture_type() == Texture::TT_3d_texture) {
|
||||||
return fill_d3d_volume_texture_pixels();
|
return fill_d3d_volume_texture_pixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
nassertr(IS_VALID_PTR(tex), E_FAIL);
|
||||||
|
|
||||||
CPTA_uchar image = get_texture()->get_ram_image();
|
CPTA_uchar image = tex->get_ram_image();
|
||||||
if (image.is_null()) {
|
if (image.is_null()) {
|
||||||
// The texture doesn't have an image to load. That's ok; it
|
// The texture doesn't have an image to load. That's ok; it
|
||||||
// might be a texture we've rendered to by frame buffer
|
// might be a texture we've rendered to by frame buffer
|
||||||
@ -1314,11 +1451,11 @@ fill_d3d_texture_pixels() {
|
|||||||
|
|
||||||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||||
|
|
||||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD) tex->get_z_size();
|
||||||
D3DFORMAT source_format = _d3d_format;
|
D3DFORMAT source_format = _d3d_format;
|
||||||
|
|
||||||
// check for compressed textures and adjust source_format accordingly
|
// check for compressed textures and adjust source_format accordingly
|
||||||
switch (get_texture()->get_ram_image_compression()) {
|
switch (tex->get_ram_image_compression()) {
|
||||||
case Texture::CM_dxt1:
|
case Texture::CM_dxt1:
|
||||||
source_format = D3DFMT_DXT1;
|
source_format = D3DFMT_DXT1;
|
||||||
break;
|
break;
|
||||||
@ -1350,10 +1487,9 @@ fill_d3d_texture_pixels() {
|
|||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
// if we have pre-calculated mipmap levels, use them, otherwise generate on the fly
|
// if we have pre-calculated mipmap levels, use them, otherwise generate on the fly
|
||||||
int miplevel_count = _d3d_2d_texture->GetLevelCount(); // what if it's not a 2d texture?
|
int miplevel_count = _d3d_2d_texture->GetLevelCount(); // what if it's not a 2d texture?
|
||||||
|
if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) {
|
||||||
if (miplevel_count <= get_texture()->get_num_ram_mipmap_images()) {
|
|
||||||
dxgsg8_cat.debug()
|
dxgsg8_cat.debug()
|
||||||
<< "Using pre-calculated mipmap levels for texture " << get_texture()->get_name();
|
<< "Using pre-calculated mipmap levels for texture " << tex->get_name();
|
||||||
|
|
||||||
for (int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
|
for (int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
|
||||||
hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
|
hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
|
||||||
@ -1378,7 +1514,7 @@ fill_d3d_texture_pixels() {
|
|||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg8_cat.error()
|
dxgsg8_cat.error()
|
||||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
<< "FillDDSurfaceTexturePixels failed for " << tex->get_name()
|
||||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
bool create_texture(DXScreenData &scrn);
|
bool create_texture(DXScreenData &scrn);
|
||||||
bool create_simple_texture(DXScreenData &scrn);
|
bool create_simple_texture(DXScreenData &scrn);
|
||||||
void delete_texture();
|
void delete_texture();
|
||||||
|
bool extract_texture_data();
|
||||||
|
|
||||||
INLINE bool has_mipmaps() const;
|
INLINE bool has_mipmaps() const;
|
||||||
INLINE IDirect3DBaseTexture8 *get_d3d_texture() const;
|
INLINE IDirect3DBaseTexture8 *get_d3d_texture() const;
|
||||||
|
@ -366,6 +366,27 @@ release_texture(TextureContext *tc) {
|
|||||||
delete dtc;
|
delete dtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DXGraphicsStateGuardian9::extract_texture_data
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: This method should only be called by the
|
||||||
|
// GraphicsEngine. Do not call it directly; call
|
||||||
|
// GraphicsEngine::extract_texture_data() instead.
|
||||||
|
//
|
||||||
|
// This method will be called in the draw thread to
|
||||||
|
// download the texture memory's image into its
|
||||||
|
// ram_image value. It returns true on success, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DXGraphicsStateGuardian9::
|
||||||
|
extract_texture_data(Texture *tex) {
|
||||||
|
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||||
|
nassertr(tc != (TextureContext *)NULL, false);
|
||||||
|
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||||
|
|
||||||
|
return dtc->extract_texture_data();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DXGraphicsStateGuardian9::prepare_shader
|
// Function: DXGraphicsStateGuardian9::prepare_shader
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
void apply_texture(int i, TextureContext *tc);
|
void apply_texture(int i, TextureContext *tc);
|
||||||
bool upload_texture(DXTextureContext9 *dtc);
|
bool upload_texture(DXTextureContext9 *dtc);
|
||||||
virtual void release_texture(TextureContext *tc);
|
virtual void release_texture(TextureContext *tc);
|
||||||
|
virtual bool extract_texture_data(Texture *tex);
|
||||||
|
|
||||||
ShaderContext *prepare_shader(Shader *se);
|
ShaderContext *prepare_shader(Shader *se);
|
||||||
void release_shader(ShaderContext *sc);
|
void release_shader(ShaderContext *sc);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "dxGraphicsStateGuardian9.h"
|
#include "dxGraphicsStateGuardian9.h"
|
||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
#include "dxTextureContext9.h"
|
#include "dxTextureContext9.h"
|
||||||
|
#include "bamCache.h"
|
||||||
#include <d3dx9tex.h>
|
#include <d3dx9tex.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -718,6 +719,9 @@ create_texture(DXScreenData &scrn) {
|
|||||||
UINT mip_level_count;
|
UINT mip_level_count;
|
||||||
|
|
||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
|
tex->get_ram_image();
|
||||||
|
mip_level_count = tex->get_num_loadable_ram_mipmap_images();
|
||||||
|
if (mip_level_count < 2) {
|
||||||
// tell CreateTex to alloc space for all mip levels down to 1x1
|
// tell CreateTex to alloc space for all mip levels down to 1x1
|
||||||
mip_level_count = 0;
|
mip_level_count = 0;
|
||||||
|
|
||||||
@ -726,6 +730,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
<< "create_texture: generating mipmaps for " << tex->get_name()
|
<< "create_texture: generating mipmaps for " << tex->get_name()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mip_level_count = 1;
|
mip_level_count = 1;
|
||||||
}
|
}
|
||||||
@ -926,6 +931,21 @@ create_texture(DXScreenData &scrn) {
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tex->get_post_load_store_cache()) {
|
||||||
|
tex->set_post_load_store_cache(false);
|
||||||
|
// OK, get the RAM image, and save it in a BamCache record.
|
||||||
|
if (extract_texture_data()) {
|
||||||
|
if (tex->has_ram_image()) {
|
||||||
|
BamCache *cache = BamCache::get_global_ptr();
|
||||||
|
PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
|
||||||
|
if (record != (BamCacheRecord *)NULL) {
|
||||||
|
record->set_data(tex, false);
|
||||||
|
cache->store(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// must not put render to texture into LRU
|
// must not put render to texture into LRU
|
||||||
if (!_managed && !tex->get_render_to_texture()) {
|
if (!_managed && !tex->get_render_to_texture()) {
|
||||||
if (_lru_page == 0) {
|
if (_lru_page == 0) {
|
||||||
@ -1069,6 +1089,119 @@ delete_texture() {
|
|||||||
_d3d_cube_texture = NULL;
|
_d3d_cube_texture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DXTextureContext9::extract_texture_data
|
||||||
|
// Access: Public
|
||||||
|
// Description: This method will be called in the draw thread to
|
||||||
|
// download the texture memory's image into its
|
||||||
|
// ram_image value. It returns true on success, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool DXTextureContext9::
|
||||||
|
extract_texture_data() {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
Texture *tex = get_texture();
|
||||||
|
if (tex->get_texture_type() != Texture::TT_2d_texture) {
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Not supported: extract_texture_data for " << tex->get_texture_type()
|
||||||
|
<< "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nassertr(IS_VALID_PTR(_d3d_2d_texture), false);
|
||||||
|
|
||||||
|
D3DSURFACE_DESC desc;
|
||||||
|
hr = _d3d_2d_texture->GetLevelDesc(0, &desc);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int div = 1;
|
||||||
|
Texture::Format format = Texture::F_rgba;
|
||||||
|
Texture::CompressionMode compression = Texture::CM_off;
|
||||||
|
|
||||||
|
switch (desc.Format) {
|
||||||
|
case D3DFMT_R8G8B8:
|
||||||
|
format = Texture::F_rgb;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_A8R8G8B8:
|
||||||
|
case D3DFMT_X8R8G8B8:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_L8:
|
||||||
|
format = Texture::F_luminance;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_A8L8:
|
||||||
|
format = Texture::F_luminance_alpha;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3DFMT_DXT1:
|
||||||
|
compression = Texture::CM_dxt1;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT2:
|
||||||
|
compression = Texture::CM_dxt2;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT3:
|
||||||
|
compression = Texture::CM_dxt3;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT4:
|
||||||
|
compression = Texture::CM_dxt4;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT5:
|
||||||
|
compression = Texture::CM_dxt5;
|
||||||
|
div = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Cannot extract texture data: unhandled surface format "
|
||||||
|
<< desc.Format << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_levels = _d3d_2d_texture->GetLevelCount();
|
||||||
|
|
||||||
|
tex->set_x_size(desc.Width);
|
||||||
|
tex->set_y_size(desc.Height);
|
||||||
|
tex->set_z_size(1);
|
||||||
|
tex->set_component_type(Texture::T_unsigned_byte);
|
||||||
|
tex->set_format(format);
|
||||||
|
tex->clear_ram_image();
|
||||||
|
|
||||||
|
for (int n = 0; n < num_levels; ++n) {
|
||||||
|
D3DLOCKED_RECT rect;
|
||||||
|
hr = _d3d_2d_texture->LockRect(n, &rect, NULL, D3DLOCK_READONLY);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg9_cat.error()
|
||||||
|
<< "Texture::LockRect() failed!" << D3DERRORSTRING(hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y_size = tex->get_expected_mipmap_y_size(n);
|
||||||
|
int size = rect.Pitch * (y_size / div);
|
||||||
|
size = min(size, (int)tex->get_expected_ram_mipmap_image_size(n));
|
||||||
|
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||||
|
memcpy(image.p(), rect.pBits, size);
|
||||||
|
|
||||||
|
_d3d_2d_texture->UnlockRect(n);
|
||||||
|
if (n == 0) {
|
||||||
|
tex->set_ram_image(image, compression);
|
||||||
|
} else {
|
||||||
|
tex->set_ram_mipmap_image(n, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DXTextureContext9::d3d_surface_to_texture
|
// Function: DXTextureContext9::d3d_surface_to_texture
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -1377,6 +1510,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||||||
bool using_temp_buffer = false;
|
bool using_temp_buffer = false;
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level);
|
CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level);
|
||||||
|
nassertr(!image.is_null(), E_FAIL);
|
||||||
BYTE *pixels = (BYTE*) image.p();
|
BYTE *pixels = (BYTE*) image.p();
|
||||||
DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level);
|
DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level);
|
||||||
DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level);
|
DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level);
|
||||||
@ -1472,6 +1606,7 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
|
|||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
||||||
|
<< ", mip_level " << mip_level
|
||||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1491,19 +1626,20 @@ exit_FillMipmapSurf:
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
HRESULT DXTextureContext9::
|
HRESULT DXTextureContext9::
|
||||||
fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDevice9 *device) {
|
fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDevice9 *device) {
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
Texture *tex = get_texture();
|
||||||
|
nassertr(IS_VALID_PTR(tex), E_FAIL);
|
||||||
|
if (tex->get_texture_type() == Texture::TT_3d_texture) {
|
||||||
return fill_d3d_volume_texture_pixels();
|
return fill_d3d_volume_texture_pixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
|
||||||
|
|
||||||
CPTA_uchar image = get_texture()->get_ram_image();
|
CPTA_uchar image = tex->get_ram_image();
|
||||||
if (image.is_null()) {
|
if (image.is_null()) {
|
||||||
// The texture doesn't have an image to load. That's ok; it
|
// The texture doesn't have an image to load. That's ok; it
|
||||||
// might be a texture we've rendered to by frame buffer
|
// might be a texture we've rendered to by frame buffer
|
||||||
// operations or something.
|
// operations or something.
|
||||||
if (get_texture()->get_render_to_texture()) {
|
if (tex->get_render_to_texture()) {
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
if (_d3d_2d_texture) {
|
if (_d3d_2d_texture) {
|
||||||
@ -1546,11 +1682,11 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
|
|
||||||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||||
|
|
||||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD) tex->get_z_size();
|
||||||
D3DFORMAT source_format = _d3d_format;
|
D3DFORMAT source_format = _d3d_format;
|
||||||
|
|
||||||
// check for compressed textures and adjust source_format accordingly
|
// check for compressed textures and adjust source_format accordingly
|
||||||
switch (get_texture()->get_ram_image_compression()) {
|
switch (tex->get_ram_image_compression()) {
|
||||||
case Texture::CM_dxt1:
|
case Texture::CM_dxt1:
|
||||||
source_format = D3DFMT_DXT1;
|
source_format = D3DFMT_DXT1;
|
||||||
break;
|
break;
|
||||||
@ -1582,10 +1718,9 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
// if we have pre-calculated mipmap levels, use them, otherwise generate on the fly
|
// if we have pre-calculated mipmap levels, use them, otherwise generate on the fly
|
||||||
int miplevel_count = _d3d_2d_texture->GetLevelCount(); // what if it's not a 2d texture?
|
int miplevel_count = _d3d_2d_texture->GetLevelCount(); // what if it's not a 2d texture?
|
||||||
|
if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) {
|
||||||
if (miplevel_count <= get_texture()->get_num_ram_mipmap_images()) {
|
|
||||||
dxgsg9_cat.debug()
|
dxgsg9_cat.debug()
|
||||||
<< "Using pre-calculated mipmap levels for texture " << get_texture()->get_name();
|
<< "Using pre-calculated mipmap levels for texture " << tex->get_name();
|
||||||
|
|
||||||
for (int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
|
for (int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
|
||||||
hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
|
hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
|
||||||
@ -1625,7 +1760,7 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
<< "FillDDSurfaceTexturePixels failed for " << tex->get_name()
|
||||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ public:
|
|||||||
bool create_texture(DXScreenData &scrn);
|
bool create_texture(DXScreenData &scrn);
|
||||||
bool create_simple_texture(DXScreenData &scrn);
|
bool create_simple_texture(DXScreenData &scrn);
|
||||||
void delete_texture();
|
void delete_texture();
|
||||||
|
bool extract_texture_data();
|
||||||
|
|
||||||
INLINE bool has_mipmaps() const;
|
INLINE bool has_mipmaps() const;
|
||||||
INLINE IDirect3DBaseTexture9 *get_d3d_texture() const;
|
INLINE IDirect3DBaseTexture9 *get_d3d_texture() const;
|
||||||
|
@ -7104,9 +7104,11 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||||||
for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
|
for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
|
||||||
CPTA_uchar ptimage = tex->get_ram_mipmap_image(n);
|
CPTA_uchar ptimage = tex->get_ram_mipmap_image(n);
|
||||||
if (ptimage == (const unsigned char *)NULL) {
|
if (ptimage == (const unsigned char *)NULL) {
|
||||||
GLCAT.warning()
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug()
|
||||||
<< "No mipmap level " << n << " defined for " << tex->get_name()
|
<< "No mipmap level " << n << " defined for " << tex->get_name()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
}
|
||||||
// No mipmap level n; stop here.
|
// No mipmap level n; stop here.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -7651,25 +7653,13 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// We don't want to call setup_texture() again; that resets too
|
||||||
switch (target) {
|
// much. Instead, we'll just set the individual components.
|
||||||
case GL_TEXTURE_1D:
|
tex->set_x_size(width);
|
||||||
tex->setup_1d_texture(width, type, format);
|
tex->set_y_size(height);
|
||||||
break;
|
tex->set_z_size(depth);
|
||||||
|
tex->set_component_type(type);
|
||||||
case GL_TEXTURE_2D:
|
tex->set_format(format);
|
||||||
tex->setup_2d_texture(width, height, type, format);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_TEXTURE_3D:
|
|
||||||
tex->setup_3d_texture(width, height, depth, type, format);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
|
||||||
tex->setup_cube_map(width, type, format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
|
tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
|
||||||
tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
|
tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user