15 #include "config_dxgsg9.h"
16 #include "dxGraphicsStateGuardian9.h"
17 #include "pStatTimer.h"
18 #include "dxTextureContext9.h"
20 #include "graphicsEngine.h"
25 #define DEBUG_SURFACES false
26 #define DEBUG_TEXTURES true
30 static const DWORD g_LowByteMask = 0x000000FF;
41 if (dxgsg9_cat.is_spam()) {
47 _d3d_2d_texture = NULL;
48 _d3d_volume_texture = NULL;
49 _d3d_cube_texture = NULL;
51 _is_render_target =
false;
61 ~DXTextureContext9() {
87 if (dxgsg9_cat.is_debug()) {
113 if (_d3d_2d_texture || _d3d_cube_texture || _d3d_volume_texture) {
120 D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
121 bool needs_luminance =
false;
122 bool compress_texture =
false;
125 nassertr(IS_VALID_PTR(tex),
false);
135 bool texture_wants_compressed =
false;
137 bool texture_stored_compressed = compression_mode != Texture::CM_off;
139 if (texture_stored_compressed) {
140 texture_wants_compressed =
true;
147 if (compressed_textures) {
148 texture_wants_compressed =
true;
151 texture_wants_compressed =
true;
157 case Texture::TT_1d_texture:
158 case Texture::TT_2d_texture:
159 case Texture::TT_cube_map:
163 orig_width >= 4 && orig_height >= 4) {
164 if (texture_wants_compressed){
165 compress_texture =
true;
169 case Texture::TT_3d_texture:
174 if (texture_stored_compressed && !compress_texture) {
190 DWORD target_bpp = get_bits_per_pixel(tex->
get_format(), &num_alpha_bits);
198 if ((tex->
get_format() == Texture::F_luminance_alpha)||
199 (tex->
get_format() == Texture::F_luminance_alphamask) ||
200 (tex->
get_format() == Texture::F_luminance) ||
201 (tex->
get_format() == Texture::F_sluminance_alpha) ||
202 (tex->
get_format() == Texture::F_sluminance)) {
203 needs_luminance =
true;
206 if (num_alpha_bits > 0) {
207 if (num_color_channels == 3) {
209 <<
"texture " << tex->get_name()
210 <<
" has no inherent alpha channel, but alpha format is requested!\n";
214 _d3d_format = D3DFMT_UNKNOWN;
218 switch (num_color_channels) {
220 if (num_alpha_bits > 0) {
221 _d3d_format = D3DFMT_A8;
222 }
else if (needs_luminance) {
223 _d3d_format = D3DFMT_L8;
227 nassertr(needs_luminance && (num_alpha_bits > 0),
false);
228 _d3d_format = D3DFMT_A8L8;
231 _d3d_format = D3DFMT_R8G8B8;
234 _d3d_format = D3DFMT_A8R8G8B8;
239 nassertr(_d3d_format != D3DFMT_UNKNOWN,
false);
241 DWORD target_width = orig_width;
242 DWORD target_height = orig_height;
243 DWORD target_depth = orig_depth;
248 case Texture::TT_1d_texture:
249 case Texture::TT_2d_texture:
250 filter_caps = scrn._d3dcaps.TextureFilterCaps;
252 if (target_width > scrn._d3dcaps.MaxTextureWidth) {
253 target_width = scrn._d3dcaps.MaxTextureWidth;
255 if (target_height > scrn._d3dcaps.MaxTextureHeight) {
256 target_height = scrn._d3dcaps.MaxTextureHeight;
259 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
260 if (!ISPOW2(target_width)) {
261 target_width = down_to_power_2(target_width);
263 if (!ISPOW2(target_height)) {
264 target_height = down_to_power_2(target_height);
269 case Texture::TT_3d_texture:
270 if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) {
272 <<
"3-d textures are not supported by this graphics driver.\n";
276 filter_caps = scrn._d3dcaps.VolumeTextureFilterCaps;
278 if (target_width > scrn._d3dcaps.MaxVolumeExtent) {
279 target_width = scrn._d3dcaps.MaxVolumeExtent;
281 if (target_height > scrn._d3dcaps.MaxVolumeExtent) {
282 target_height = scrn._d3dcaps.MaxVolumeExtent;
284 if (target_depth > scrn._d3dcaps.MaxVolumeExtent) {
285 target_depth = scrn._d3dcaps.MaxVolumeExtent;
288 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) {
289 if (!ISPOW2(target_width)) {
290 target_width = down_to_power_2(target_width);
292 if (!ISPOW2(target_height)) {
293 target_height = down_to_power_2(target_height);
295 if (!ISPOW2(target_depth)) {
296 target_depth = down_to_power_2(target_depth);
301 case Texture::TT_cube_map:
302 if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) {
304 <<
"Cube map textures are not supported by this graphics driver.\n";
308 filter_caps = scrn._d3dcaps.CubeTextureFilterCaps;
310 if (target_width > scrn._d3dcaps.MaxTextureWidth) {
311 target_width = scrn._d3dcaps.MaxTextureWidth;
314 if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) {
315 if (!ISPOW2(target_width)) {
316 target_width = down_to_power_2(target_width);
320 target_height = target_width;
325 if ((target_width != target_height) &&
326 (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0) {
329 int i, width_exp, height_exp;
330 for (i = target_width, width_exp = 0; i > 1; width_exp++, i >>= 1) {
332 for (i = target_height, height_exp = 0; i > 1; height_exp++, i >>= 1) {
334 target_height = target_width = 1<<((width_exp+height_exp)>>1);
337 bool shrink_original =
false;
339 if (orig_width != target_width || orig_height != target_height ||
340 orig_depth != target_depth) {
343 <<
"Reducing size of " << tex->get_name()
344 <<
" from " << orig_width <<
"x" << orig_height <<
"x" << orig_depth
345 <<
" to " << target_width <<
"x" << target_height
346 <<
"x" << target_depth <<
"\n";
349 <<
"Reducing size of " << tex->get_name()
350 <<
" from " << orig_width <<
"x" << orig_height
351 <<
" to " << target_width <<
"x" << target_height <<
"\n";
354 shrink_original =
true;
357 const char *error_message;
359 error_message =
"create_texture failed: couldn't find compatible device Texture Pixel Format for input texture";
361 if (dxgsg9_cat.is_spam()) {
363 <<
"create_texture handling target bitdepth: " << target_bpp
364 <<
" alphabits: " << num_alpha_bits << endl;
371 #define CHECK_FOR_FMT(FMT) \
372 if (scrn._supported_tex_formats_mask & FMT##_FLAG) { \
373 target_pixel_format = D3DFMT_##FMT; \
374 goto found_matching_format; }
376 if (texture_stored_compressed && compress_texture) {
380 switch (compression_mode){
381 case Texture::CM_dxt1:
384 case Texture::CM_dxt2:
387 case Texture::CM_dxt3:
390 case Texture::CM_dxt4:
393 case Texture::CM_dxt5:
401 if (compress_texture) {
402 if (num_alpha_bits <= 1) {
404 }
else if (num_alpha_bits <= 4) {
413 if (texture_stored_compressed) {
416 texture_stored_compressed = compression_mode != Texture::CM_off;
417 compress_texture =
false;
423 switch (target_bpp) {
431 if (scrn._supports_rgba32_texture_format) {
432 target_pixel_format = D3DFMT_A32B32G32R32F;
435 target_pixel_format = scrn._render_to_texture_d3d_format;
437 goto found_matching_format;
441 if (scrn._supports_rgba16f_texture_format) {
442 target_pixel_format = D3DFMT_A16B16G16R16F;
445 target_pixel_format = scrn._render_to_texture_d3d_format;
447 goto found_matching_format;
450 if (!((num_color_channels == 3) || (num_color_channels == 4)))
453 CHECK_FOR_FMT(A8R8G8B8);
455 if (num_alpha_bits>0) {
456 nassertr(num_color_channels == 4,
false);
472 if (num_alpha_bits == 1) {
473 CHECK_FOR_FMT(A1R5G5B5);
477 CHECK_FOR_FMT(A4R4G4B4);
478 CHECK_FOR_FMT(A1R5G5B5);
482 error_message =
"create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
486 if (num_color_channels == 3) {
487 CHECK_FOR_FMT(R5G6B5);
488 CHECK_FOR_FMT(X1R5G5B5);
490 CHECK_FOR_FMT(R5G6B5);
491 CHECK_FOR_FMT(X1R5G5B5);
497 nassertr(num_color_channels == 3,
false);
499 CHECK_FOR_FMT(R8G8B8);
505 CHECK_FOR_FMT(X8R8G8B8);
506 CHECK_FOR_FMT(A8R8G8B8);
509 CHECK_FOR_FMT(R5G6B5);
510 CHECK_FOR_FMT(X1R5G5B5);
511 CHECK_FOR_FMT(A1R5G5B5);
515 if (needs_luminance) {
516 nassertr(num_alpha_bits > 0,
false);
517 nassertr(num_color_channels == 2,
false);
520 CHECK_FOR_FMT(A8R8G8B8);
522 if (num_alpha_bits == 1) {
523 CHECK_FOR_FMT(A1R5G5B5);
527 CHECK_FOR_FMT(A4R4G4B4);
528 CHECK_FOR_FMT(A1R5G5B5);
530 nassertr((num_color_channels == 3)||(num_color_channels == 4),
false);
533 switch(num_alpha_bits) {
535 if (num_color_channels == 3) {
536 CHECK_FOR_FMT(R5G6B5);
537 CHECK_FOR_FMT(X1R5G5B5);
539 nassertr(num_color_channels == 4,
false);
541 CHECK_FOR_FMT(R5G6B5);
542 CHECK_FOR_FMT(X1R5G5B5);
550 nassertr(num_color_channels == 4,
false);
551 CHECK_FOR_FMT(X1R5G5B5);
556 nassertr(num_color_channels == 4,
false);
557 CHECK_FOR_FMT(A4R4G4B4);
560 nassertr(
false,
false);
564 if (needs_luminance) {
567 nassertr(num_color_channels == 1,
false);
573 CHECK_FOR_FMT(R8G8B8);
574 CHECK_FOR_FMT(X8R8G8B8);
576 CHECK_FOR_FMT(R5G6B5);
577 CHECK_FOR_FMT(X1R5G5B5);
579 }
else if (num_alpha_bits == 8) {
588 CHECK_FOR_FMT(A8R8G8B8);
589 CHECK_FOR_FMT(A4R4G4B4);
594 error_message =
"create_texture failed: unhandled pixel bitdepth in DX loader";
599 << error_message <<
": " << tex->get_name() << endl
600 <<
"NumColorChannels: " << num_color_channels <<
"; NumAlphaBits: "
601 << num_alpha_bits <<
"; targetbpp: " <<target_bpp
602 <<
"; _supported_tex_formats_mask: 0x"
603 << (
void*)scrn._supported_tex_formats_mask
604 <<
"; NeedLuminance: " << needs_luminance << endl;
609 found_matching_format:
616 DWORD render_target_index;
617 IDirect3DSurface9 *render_target;
619 render_target_index = 0;
620 hr = scrn._d3d_device->GetRenderTarget(render_target_index, &render_target);
623 <<
"GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
625 D3DSURFACE_DESC surface_desc;
626 hr = render_target->GetDesc(&surface_desc);
629 <<
"GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
631 if (target_pixel_format != surface_desc.Format) {
632 if (dxgsg9_cat.is_debug()) {
634 <<
"Chose format " << D3DFormatStr(surface_desc.Format)
635 <<
" instead of " << D3DFormatStr(target_pixel_format)
636 <<
" for texture to match framebuffer.\n";
638 target_pixel_format = surface_desc.Format;
641 SAFE_RELEASE(render_target);
648 SamplerState::FilterType ft;
651 if ((ft != SamplerState::FT_linear) && ft != SamplerState::FT_nearest) {
653 if (ft == SamplerState::FT_nearest_mipmap_nearest) {
654 ft = SamplerState::FT_nearest;
656 ft = SamplerState::FT_linear;
660 if (ft == SamplerState::FT_linear &&
661 (filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
662 ft = SamplerState::FT_nearest;
668 _has_mipmaps =
false;
670 if (!dx_ignore_mipmaps) {
672 case SamplerState::FT_nearest_mipmap_nearest:
673 case SamplerState::FT_linear_mipmap_nearest:
674 case SamplerState::FT_nearest_mipmap_linear:
675 case SamplerState::FT_linear_mipmap_linear:
679 if (dx_mipmap_everything) {
681 if (dxgsg9_cat.is_spam()) {
682 if (ft != SamplerState::FT_linear_mipmap_linear) {
684 <<
"Forcing trilinear mipmapping on DX texture ["
685 << tex->get_name() <<
"]\n";
688 ft = SamplerState::FT_linear_mipmap_linear;
692 }
else if ((ft == SamplerState::FT_nearest_mipmap_nearest) ||
693 (ft == SamplerState::FT_nearest_mipmap_linear)) {
694 ft = SamplerState::FT_nearest;
696 }
else if ((ft == SamplerState::FT_linear_mipmap_nearest) ||
697 (ft == SamplerState::FT_linear_mipmap_linear)) {
698 ft = SamplerState::FT_linear;
701 nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0,
false);
703 #define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR)
707 case SamplerState::FT_linear_mipmap_linear:
708 if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
709 if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
710 ft = SamplerState::FT_linear_mipmap_nearest;
714 ft = SamplerState::FT_nearest_mipmap_nearest;
719 case SamplerState::FT_nearest_mipmap_linear:
721 if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
722 (filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
723 ft = SamplerState::FT_nearest_mipmap_nearest;
727 case SamplerState::FT_linear_mipmap_nearest:
729 if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
730 ft = SamplerState::FT_nearest_mipmap_nearest;
734 case SamplerState::FT_linear:
735 if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
736 ft = SamplerState::FT_nearest;
746 if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
748 if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
749 dx_force_anisotropic_filtering) {
750 aniso_degree = scrn._d3dcaps.MaxAnisotropy;
757 <<
"create_texture: setting aniso degree for " << tex->get_name()
758 <<
" to: " << aniso_degree << endl;
761 UINT mip_level_count;
766 if (mip_level_count < 2) {
770 if (dxgsg9_cat.is_debug()) {
772 <<
"create_texture: generating mipmaps for " << tex->get_name()
786 _is_render_target =
true;
788 pool = D3DPOOL_DEFAULT;
789 usage = D3DUSAGE_RENDERTARGET;
790 if (target_bpp <= 32 ) {
791 target_pixel_format = scrn._render_to_texture_d3d_format;
795 <<
"*** RENDER TO TEXTURE ***: format "
796 << D3DFormatStr(target_pixel_format)
798 << target_pixel_format
802 _managed = scrn._managed_textures;
804 pool = D3DPOOL_MANAGED;
808 if (scrn._supports_automatic_mipmap_generation) {
809 pool = D3DPOOL_DEFAULT;
810 usage = D3DUSAGE_AUTOGENMIPMAP;
813 if (dx_use_dynamic_textures) {
814 if (scrn._supports_dynamic_textures) {
815 pool = D3DPOOL_DEFAULT;
816 usage = D3DUSAGE_DYNAMIC;
822 pool = D3DPOOL_MANAGED;
827 pool = D3DPOOL_DEFAULT;
834 PN_stdfloat bytes_per_texel;
836 bytes_per_texel =
this -> d3d_format_to_bytes_per_pixel (target_pixel_format);
837 if (bytes_per_texel == 0.0f) {
839 <<
"D3D create_texture ( ) unknown texture format\n";
844 data_size = target_width * target_height * target_depth;
846 data_size = (int) ((PN_stdfloat) data_size * 1.3333333);
848 data_size = (int) ((PN_stdfloat) data_size * bytes_per_texel);
856 if (dxgsg9_cat.is_debug()) {
858 <<
"Creating " << *tex <<
", " << data_size <<
" bytes, "
859 << scrn._d3d_device->GetAvailableTextureMem()
860 <<
" reported available.\n";
862 <<
" size is " << target_width <<
" w * " << target_height <<
" h * "
863 << target_depth <<
" d";
865 dxgsg9_cat.debug(
false)
866 <<
" * 1.3333333 mipmaps";
868 dxgsg9_cat.debug(
false)
869 <<
" * " << bytes_per_texel <<
" bpt";
871 dxgsg9_cat.debug(
false)
874 dxgsg9_cat.debug(
false)
882 case Texture::TT_1d_texture:
883 case Texture::TT_2d_texture:
884 hr = scrn._d3d_device->CreateTexture
885 (target_width, target_height, mip_level_count, usage,
886 target_pixel_format, pool, &_d3d_2d_texture, NULL);
887 _d3d_texture = _d3d_2d_texture;
890 case Texture::TT_3d_texture:
891 hr = scrn._d3d_device->CreateVolumeTexture
892 (target_width, target_height, target_depth, mip_level_count, usage,
893 target_pixel_format, pool, &_d3d_volume_texture, NULL);
894 _d3d_texture = _d3d_volume_texture;
897 case Texture::TT_cube_map:
898 hr = scrn._d3d_device->CreateCubeTexture
899 (target_width, mip_level_count, usage,
900 target_pixel_format, pool, &_d3d_cube_texture, NULL);
901 _d3d_texture = _d3d_cube_texture;
903 target_height = target_width;
908 }
while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts));
912 <<
"D3D create_texture failed!" << D3DERRORSTRING(hr);
914 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
919 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
921 <<
"create_texture: " << tex->get_name()
922 <<
" converting panda equivalent of " << D3DFormatStr(_d3d_format)
923 <<
" => " << D3DFormatStr(target_pixel_format) << endl;
926 hr = fill_d3d_texture_pixels(scrn, compress_texture);
930 <<
"*** fill_d3d_texture_pixels failed ***: format "
931 << target_pixel_format
946 cache->
store(record);
962 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
963 _d3d_2d_texture = NULL;
964 _d3d_volume_texture = NULL;
965 _d3d_cube_texture = NULL;
974 bool DXTextureContext9::
982 _d3d_format = D3DFMT_A8R8G8B8;
983 D3DFORMAT target_pixel_format = D3DFMT_A8R8G8B8;
984 DWORD target_bpp = 32;
985 DWORD num_color_channels = 4;
989 DWORD mip_level_count = 1;
991 D3DPOOL pool = D3DPOOL_MANAGED;
993 int data_size = target_width * target_height * 4;
995 hr = scrn._d3d_device->CreateTexture
996 (target_width, target_height, mip_level_count, usage,
997 target_pixel_format, pool, &_d3d_2d_texture, NULL);
998 _d3d_texture = _d3d_2d_texture;
1001 <<
"D3D create_simple_texture failed!" << D3DERRORSTRING(hr);
1003 <<
" width = " << target_width <<
" height = " << target_height <<
" target_pixel_format = " << target_pixel_format <<
"\n";
1008 if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
1010 <<
"create_simple_texture: " <<
get_texture()->get_name()
1020 IDirect3DSurface9 *surface = NULL;
1021 _d3d_2d_texture->GetSurfaceLevel(0, &surface);
1024 source_size.left = source_size.top = 0;
1025 source_size.right = target_width;
1026 source_size.bottom = target_height;
1028 DWORD mip_filter = D3DX_FILTER_LINEAR;
1030 hr = D3DXLoadSurfaceFromMemory
1031 (surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)image.
p(),
1032 target_pixel_format, target_width * 4, (PALETTEENTRY*)NULL,
1033 &source_size, mip_filter, (D3DCOLOR)0x0);
1035 RELEASE(surface, dxgsg9,
"create_simple_texture Surface", RELEASE_ONCE);
1040 <<
"*** fill_d3d_texture_pixels failed ***: format "
1041 << target_pixel_format
1051 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1052 _d3d_2d_texture = NULL;
1053 _d3d_volume_texture = NULL;
1054 _d3d_cube_texture = NULL;
1066 if (_d3d_texture == NULL) {
1071 RELEASE(_d3d_texture, dxgsg9,
"texture", RELEASE_ONCE);
1072 _d3d_2d_texture = NULL;
1073 _d3d_volume_texture = NULL;
1074 _d3d_cube_texture = NULL;
1098 nassertr(IS_VALID_PTR(_d3d_2d_texture),
false);
1100 D3DSURFACE_DESC desc;
1101 hr = _d3d_2d_texture->GetLevelDesc(0, &desc);
1104 <<
"Texture::GetLevelDesc() failed!" << D3DERRORSTRING(hr);
1109 Texture::Format format = Texture::F_rgba;
1110 Texture::CompressionMode compression = Texture::CM_off;
1112 switch (desc.Format) {
1114 format = Texture::F_rgb;
1117 case D3DFMT_A8R8G8B8:
1118 case D3DFMT_X8R8G8B8:
1122 format = Texture::F_luminance;
1126 format = Texture::F_luminance_alpha;
1130 compression = Texture::CM_dxt1;
1134 compression = Texture::CM_dxt2;
1138 compression = Texture::CM_dxt3;
1142 compression = Texture::CM_dxt4;
1146 compression = Texture::CM_dxt5;
1152 <<
"Cannot extract texture data: unhandled surface format "
1153 << desc.Format <<
"\n";
1157 int num_levels = _d3d_2d_texture->GetLevelCount();
1166 if (_is_render_target) {
1167 IDirect3DSurface9* source_surface;
1168 IDirect3DSurface9* destination_surface;
1171 destination_surface = 0;
1173 hr = _d3d_2d_texture -> GetSurfaceLevel (0, &source_surface);
1177 D3DSURFACE_DESC surface_description;
1179 pool = D3DPOOL_SYSTEMMEM;
1180 source_surface -> GetDesc (&surface_description);
1182 hr = screen._d3d_device->CreateOffscreenPlainSurface (
1183 surface_description.Width,
1184 surface_description.Height,
1185 surface_description.Format,
1187 &destination_surface,
1190 if (source_surface && destination_surface) {
1191 hr = screen._d3d_device -> GetRenderTargetData (source_surface, destination_surface);
1194 D3DLOCKED_RECT rect;
1196 hr = destination_surface -> LockRect (&rect, NULL, D3DLOCK_READONLY);
1203 int surface_bytes_per_line;
1204 unsigned char *surface_pointer;
1206 bytes_per_line = surface_description.Width *
this -> d3d_format_to_bytes_per_pixel (surface_description.Format);
1207 size = bytes_per_line * surface_description.Height;
1209 surface_bytes_per_line = rect.Pitch;
1210 surface_pointer = (
unsigned char *) rect.pBits;
1212 PTA_uchar image = PTA_uchar::empty_array(size);
1217 for (y = 0; y < surface_description.Height; y++)
1219 memcpy (&image [offset], surface_pointer, bytes_per_line);
1221 offset += bytes_per_line;
1222 surface_pointer += surface_bytes_per_line;
1229 destination_surface -> UnlockRect();
1234 destination_surface -> Release ( );
1238 <<
"CreateImageSurface failed in extract_texture_data()"
1239 << D3DERRORSTRING(hr);
1241 source_surface -> Release ( );
1245 for (
int n = 0; n < num_levels; ++n) {
1246 D3DLOCKED_RECT rect;
1247 hr = _d3d_2d_texture->LockRect(n, &rect, NULL, D3DLOCK_READONLY);
1250 <<
"Texture::LockRect() failed! level = " << n <<
" " << D3DERRORSTRING(hr);
1258 if (compression == Texture::CM_off) {
1261 pitch = min(pitch, (
int)rect.Pitch);
1262 int size = pitch * y_size;
1263 image = PTA_uchar::empty_array(size);
1264 if (pitch == rect.Pitch) {
1266 memcpy(image.p(), rect.pBits, size);
1270 unsigned char *dest = image.p();
1271 unsigned char *source = (
unsigned char *)rect.pBits;
1272 for (
int yi = 0; yi < y_size; ++yi) {
1273 memcpy(dest, source, pitch);
1275 source += rect.Pitch;
1281 int size = rect.Pitch * (y_size / div);
1282 image = PTA_uchar::empty_array(size);
1283 memcpy(image.p(), rect.pBits, size);
1286 _d3d_2d_texture->UnlockRect(n);
1308 bool inverted,
Texture *result,
int view,
int z) {
1318 nassertr((num_components == 3) || (num_components == 4), E_FAIL);
1319 nassertr(IS_VALID_PTR(d3d_surface), E_FAIL);
1323 nassertr(z < result->get_z_size(), E_FAIL);
1330 if (IsBadWritePtr(d3d_surface,
sizeof(DWORD))) {
1332 <<
"d3d_surface_to_texture failed: bad pD3DSurf ptr value ("
1333 << ((
void*)d3d_surface) <<
")\n";
1337 DWORD x_window_offset, y_window_offset;
1338 DWORD copy_width, copy_height;
1340 D3DLOCKED_RECT locked_rect;
1341 D3DSURFACE_DESC surface_desc;
1343 hr = d3d_surface->GetDesc(&surface_desc);
1345 x_window_offset = source_rect.left, y_window_offset = source_rect.top;
1346 copy_width = RECT_XSIZE(source_rect);
1347 copy_height = RECT_YSIZE(source_rect);
1354 <<
"d3d_surface_to_texture, Texture size (" << result->
get_x_size()
1356 <<
") too small to hold display surface ("
1357 << copy_width <<
", " << copy_height <<
")\n";
1358 nassertr(
false, E_FAIL);
1362 hr = d3d_surface->LockRect(&locked_rect, (CONST RECT*)NULL, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE));
1365 <<
"d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
1370 nassertr((surface_desc.Format == D3DFMT_A8R8G8B8) ||
1371 (surface_desc.Format == D3DFMT_X8R8G8B8) ||
1372 (surface_desc.Format == D3DFMT_R8G8B8) ||
1373 (surface_desc.Format == D3DFMT_R5G6B5) ||
1374 (surface_desc.Format == D3DFMT_X1R5G5B5) ||
1375 (surface_desc.Format == D3DFMT_A1R5G5B5) ||
1376 (surface_desc.Format == D3DFMT_A4R4G4B4), E_FAIL);
1380 int byte_pitch = locked_rect.Pitch;
1381 BYTE *surface_bytes = (BYTE *)locked_rect.pBits;
1384 surface_bytes += byte_pitch * (y_window_offset + copy_height - 1);
1385 byte_pitch = -byte_pitch;
1387 surface_bytes += byte_pitch * y_window_offset;
1393 if (DEBUG_SURFACES && dxgsg9_cat.is_debug()) {
1395 <<
"d3d_surface_to_texture converting "
1396 << D3DFormatStr(surface_desc.Format)
1397 <<
" DDSurf to " << num_components <<
"-channel panda Texture\n";
1400 DWORD *dest_word = (DWORD *)buf;
1401 BYTE *dest_byte = (BYTE *)buf;
1403 switch(surface_desc.Format) {
1404 case D3DFMT_A8R8G8B8:
1405 case D3DFMT_X8R8G8B8: {
1406 if (num_components == 4) {
1408 BYTE *dest_line = (BYTE*)dest_word;
1410 for (DWORD y = 0; y < copy_height; y++) {
1411 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1412 memcpy(dest_line, source_word, byte_pitch);
1413 dest_line += byte_pitch;
1414 surface_bytes += byte_pitch;
1419 for (DWORD y = 0; y < copy_height; y++) {
1420 source_word = ((DWORD*)surface_bytes) + x_window_offset;
1422 for (DWORD x = 0; x < copy_width; x++) {
1424 DWORD
pixel = *source_word;
1426 r = (BYTE)((pixel>>16) & g_LowByteMask);
1427 g = (BYTE)((pixel>> 8) & g_LowByteMask);
1428 b = (BYTE)((pixel ) & g_LowByteMask);
1435 surface_bytes += byte_pitch;
1441 case D3DFMT_R8G8B8: {
1444 if (num_components == 4) {
1445 for (DWORD y = 0; y < copy_height; y++) {
1446 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1447 for (DWORD x = 0; x < copy_width; x++) {
1454 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1457 surface_bytes += byte_pitch;
1461 for (DWORD y = 0; y < copy_height; y++) {
1462 source_byte = surface_bytes + x_window_offset * 3 *
sizeof(BYTE);
1463 memcpy(dest_byte, source_byte, byte_pitch);
1464 dest_byte += byte_pitch;
1465 surface_bytes += byte_pitch;
1472 case D3DFMT_X1R5G5B5:
1473 case D3DFMT_A1R5G5B5:
1474 case D3DFMT_A4R4G4B4: {
1478 BYTE redshift, greenshift, blueshift;
1479 DWORD redmask, greenmask, bluemask;
1481 if (surface_desc.Format == D3DFMT_R5G6B5) {
1488 }
else if (surface_desc.Format == D3DFMT_A4R4G4B4) {
1504 if (num_components == 4) {
1511 for (DWORD y = 0; y < copy_height; y++) {
1512 source_word = ((WORD*)surface_bytes) + x_window_offset;
1513 for (DWORD x = 0; x < copy_width; x++) {
1514 WORD
pixel = *source_word;
1517 b = (pixel & bluemask) << blueshift;
1518 g = (pixel & greenmask) >> greenshift;
1519 r = (pixel & redmask) >> redshift;
1523 *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
1527 surface_bytes += byte_pitch;
1531 for (DWORD y = 0; y < copy_height; y++) {
1532 source_word = ((WORD*)surface_bytes) + x_window_offset;
1533 for (DWORD x = 0; x < copy_width; x++) {
1534 WORD
pixel = *source_word;
1537 b = (pixel & bluemask) << blueshift;
1538 g = (pixel & greenmask) >> greenshift;
1539 r = (pixel & redmask) >> redshift;
1547 surface_bytes += byte_pitch;
1555 <<
"d3d_surface_to_texture: unsupported D3DFORMAT!\n";
1558 d3d_surface->UnlockRect();
1570 static UINT calculate_row_byte_length (
int width,
int num_color_channels, D3DFORMAT tex_format)
1572 UINT source_row_byte_length = 0;
1575 switch (tex_format) {
1579 source_row_byte_length = max(1,width / 4)*8;
1586 source_row_byte_length = max(1,width / 4)*16;
1590 source_row_byte_length = width*num_color_channels;
1593 return source_row_byte_length;
1604 HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(
int mip_level,
int depth_index, D3DFORMAT source_format)
1608 IDirect3DSurface9 *mip_surface = NULL;
1609 bool using_temp_buffer =
false;
1610 HRESULT hr = E_FAIL;
1612 nassertr(!image.
is_null(), E_FAIL);
1613 BYTE *pixels = (BYTE*) image.
p();
1621 pixels += page_size * depth_index;
1623 if (
get_texture()->get_texture_type() == Texture::TT_cube_map) {
1624 nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
1625 hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface);
1627 nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
1628 hr = _d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface);
1633 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1634 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
1639 source_size.left = source_size.top = 0;
1640 source_size.right = width;
1641 source_size.bottom = height;
1643 UINT source_row_byte_length = calculate_row_byte_length(width,
get_texture()->get_num_components(), source_format);
1648 mip_filter = D3DX_FILTER_LINEAR ;
1651 mip_filter |= D3DX_FILTER_SRGB;
1656 if (_d3d_format == D3DFMT_A8) {
1658 USHORT *temp_buffer =
new USHORT[width * height];
1659 if (!IS_VALID_PTR(temp_buffer)) {
1661 <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1662 goto exit_FillMipmapSurf;
1664 using_temp_buffer =
true;
1666 USHORT *out_pixels = temp_buffer;
1667 BYTE *source_pixels = pixels + component_width - 1;
1668 for (UINT y = 0; y < height; y++) {
1669 for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) {
1673 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
1677 source_format = D3DFMT_A8L8;
1678 source_row_byte_length = width *
sizeof(USHORT);
1679 pixels = (BYTE*)temp_buffer;
1681 else if (component_width != 1) {
1688 int num_pixels = width * height * num_components;
1689 BYTE *temp_buffer =
new BYTE[num_pixels];
1690 if (!IS_VALID_PTR(temp_buffer)) {
1691 dxgsg9_cat.error() <<
"FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
1692 goto exit_FillMipmapSurf;
1694 using_temp_buffer =
true;
1696 BYTE *source_pixels = pixels + component_width - 1;
1697 for (
int i = 0; i < num_pixels; i++) {
1698 temp_buffer[i] = *source_pixels;
1699 source_pixels += component_width;
1701 pixels = (BYTE*)temp_buffer;
1706 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height);
1708 hr = D3DXLoadSurfaceFromMemory
1709 (mip_surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
1710 source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
1711 &source_size, mip_filter, (D3DCOLOR)0x0);
1714 <<
"FillDDTextureMipmapPixels failed for " <<
get_texture()->get_name()
1715 <<
", mip_level " << mip_level
1716 <<
", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
1719 exit_FillMipmapSurf:
1720 if (using_temp_buffer) {
1721 SAFE_DELETE_ARRAY(pixels);
1724 RELEASE(mip_surface, dxgsg9,
"FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE);
1733 HRESULT DXTextureContext9::
1734 fill_d3d_texture_pixels(
DXScreenData &scrn,
bool compress_texture) {
1735 IDirect3DDevice9 *device = scrn._d3d_device;
1737 nassertr(IS_VALID_PTR(tex), E_FAIL);
1739 return fill_d3d_volume_texture_pixels(scrn);
1742 HRESULT hr = E_FAIL;
1745 Texture::CompressionMode image_compression = Texture::CM_off;
1746 if (compress_texture) {
1768 if (_d3d_2d_texture) {
1770 IDirect3DSurface9 *surface;
1772 result = _d3d_2d_texture -> GetSurfaceLevel (0, &surface);
1773 if (result == D3D_OK) {
1774 D3DSURFACE_DESC surface_description;
1776 if (surface -> GetDesc (&surface_description) == D3D_OK) {
1777 IDirect3DSurface9 *current_render_target;
1779 if (device -> GetRenderTarget (0, ¤t_render_target) == D3D_OK) {
1780 IDirect3DSurface9 *depth_stencil_surface;
1783 depth_stencil_surface = 0;
1784 if (device -> GetDepthStencilSurface (&depth_stencil_surface) == D3D_OK) {
1785 if (device -> SetDepthStencilSurface (NULL) == D3D_OK) {
1790 if (device -> SetRenderTarget (0, surface) == D3D_OK) {
1795 flags = D3DCLEAR_TARGET;
1796 if (device -> Clear (NULL, NULL, flags, color, 0.0f, 0) == D3D_OK) {
1801 if (depth_stencil_surface) {
1802 device -> SetDepthStencilSurface (depth_stencil_surface);
1803 depth_stencil_surface -> Release();
1807 device -> SetRenderTarget (0, current_render_target);
1808 current_render_target -> Release();
1812 surface -> Release();
1820 nassertr(IS_VALID_PTR((BYTE*)image.
p()), E_FAIL);
1821 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
1823 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
1825 DWORD orig_depth = (DWORD) tex->
get_z_size();
1826 D3DFORMAT source_format = _d3d_format;
1829 switch (image_compression) {
1830 case Texture::CM_dxt1:
1831 source_format = D3DFMT_DXT1;
1833 case Texture::CM_dxt2:
1834 source_format = D3DFMT_DXT2;
1836 case Texture::CM_dxt3:
1837 source_format = D3DFMT_DXT3;
1839 case Texture::CM_dxt4:
1840 source_format = D3DFMT_DXT4;
1842 case Texture::CM_dxt5:
1843 source_format = D3DFMT_DXT5;
1850 for (
unsigned int di = 0; di < orig_depth; di++) {
1853 hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
1860 int miplevel_count = _d3d_texture->GetLevelCount();
1861 if (miplevel_count <= tex->get_num_loadable_ram_mipmap_images()) {
1863 <<
"Using pre-calculated mipmap levels for texture " << tex->get_name() <<
"\n";
1865 for (
int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
1866 hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
1875 if (_managed ==
false && scrn._supports_automatic_mipmap_generation) {
1881 hr = _d3d_texture -> SetAutoGenFilterType (D3DTEXF_LINEAR);
1883 dxgsg9_cat.error() <<
"SetAutoGenFilterType failed " << D3DERRORSTRING(hr);
1886 _d3d_texture -> GenerateMipSubLevels ( );
1890 DWORD mip_filter_flags;
1891 if (!dx_use_triangle_mipgen_filter) {
1892 mip_filter_flags = D3DX_FILTER_BOX;
1894 mip_filter_flags = D3DX_FILTER_TRIANGLE;
1898 mip_filter_flags |= D3DX_FILTER_SRGB;
1902 hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
1907 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
1908 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
1924 HRESULT DXTextureContext9::
1927 HRESULT hr = E_FAIL;
1928 nassertr(IS_VALID_PTR(tex), E_FAIL);
1937 Texture::CompressionMode image_compression;
1939 image_compression = Texture::CM_off;
1946 image_compression = Texture::CM_off;
1956 PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
1958 nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
1961 DWORD orig_width = (DWORD) tex->
get_x_size();
1962 DWORD orig_height = (DWORD) tex->
get_y_size();
1963 DWORD orig_depth = (DWORD) tex->
get_z_size();
1965 D3DFORMAT source_format = _d3d_format;
1966 BYTE *image_pixels = (BYTE*)image.
p();
1969 nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
1972 image_pixels += view_size *
get_view();
1974 IDirect3DVolume9 *mip_level_0 = NULL;
1975 bool using_temp_buffer =
false;
1976 BYTE *pixels = image_pixels;
1978 nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL);
1979 hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0);
1983 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
1984 <<
", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
1989 source_size.Left = source_size.Top = source_size.Front = 0;
1990 source_size.Right = orig_width;
1991 source_size.Bottom = orig_height;
1992 source_size.Back = orig_depth;
1994 UINT source_row_byte_length = orig_width * num_color_channels;
1995 UINT source_page_byte_length = orig_height * source_row_byte_length;
1997 DWORD level_0_filter, mip_filter_flags;
1998 using_temp_buffer =
false;
2002 level_0_filter = D3DX_FILTER_LINEAR ;
2005 level_0_filter |= D3DX_FILTER_SRGB;
2010 if (_d3d_format == D3DFMT_A8) {
2012 USHORT *temp_buffer =
new USHORT[orig_width * orig_height * orig_depth];
2013 if (!IS_VALID_PTR(temp_buffer)) {
2015 <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2016 goto exit_FillDDSurf;
2018 using_temp_buffer =
true;
2020 USHORT *out_pixels = temp_buffer;
2021 BYTE *source_pixels = pixels + component_width - 1;
2022 for (UINT z = 0; z < orig_depth; z++) {
2023 for (UINT y = 0; y < orig_height; y++) {
2026 x++, source_pixels += component_width, out_pixels++) {
2030 *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
2035 source_format = D3DFMT_A8L8;
2036 source_row_byte_length = orig_width *
sizeof(USHORT);
2037 source_page_byte_length = orig_height * source_row_byte_length;
2038 pixels = (BYTE*)temp_buffer;
2040 }
else if (component_width != 1) {
2047 int num_pixels = orig_width * orig_height * orig_depth * num_components;
2048 BYTE *temp_buffer =
new BYTE[num_pixels];
2049 if (!IS_VALID_PTR(temp_buffer)) {
2050 dxgsg9_cat.error() <<
"FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
2051 goto exit_FillDDSurf;
2053 using_temp_buffer =
true;
2055 BYTE *source_pixels = pixels + component_width - 1;
2056 for (
int i = 0; i < num_pixels; i++) {
2057 temp_buffer[i] = *source_pixels;
2058 source_pixels += component_width;
2060 pixels = (BYTE*)temp_buffer;
2066 GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth);
2068 hr = D3DXLoadVolumeFromMemory
2069 (mip_level_0, (PALETTEENTRY*)NULL, (D3DBOX*)NULL, (LPCVOID)pixels,
2070 source_format, source_row_byte_length, source_page_byte_length,
2071 (PALETTEENTRY*)NULL,
2072 &source_size, level_0_filter, (D3DCOLOR)0x0);
2075 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2076 <<
", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
2077 goto exit_FillDDSurf;
2081 if (!dx_use_triangle_mipgen_filter) {
2082 mip_filter_flags = D3DX_FILTER_BOX;
2084 mip_filter_flags = D3DX_FILTER_TRIANGLE;
2088 mip_filter_flags |= D3DX_FILTER_SRGB;
2093 hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
2097 <<
"FillDDSurfaceTexturePixels failed for " << tex->get_name()
2098 <<
", D3DXFilterTex failed" << D3DERRORSTRING(hr);
2099 goto exit_FillDDSurf;
2104 if (using_temp_buffer) {
2105 SAFE_DELETE_ARRAY(pixels);
2107 RELEASE(mip_level_0, dxgsg9,
"FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
2118 int DXTextureContext9::
2119 down_to_power_2(
int value) {
2121 while ((x << 1) <= value) {
2135 unsigned int DXTextureContext9::
2136 get_bits_per_pixel(Texture::Format format,
int *alphbits) {
2139 case Texture::F_alpha:
2141 case Texture::F_color_index:
2142 case Texture::F_red:
2143 case Texture::F_green:
2144 case Texture::F_blue:
2145 case Texture::F_rgb332:
2147 case Texture::F_luminance_alphamask:
2150 case Texture::F_luminance_alpha:
2153 case Texture::F_luminance:
2155 case Texture::F_rgba4:
2158 case Texture::F_rgba5:
2161 case Texture::F_depth_component:
2163 case Texture::F_depth_stencil:
2165 case Texture::F_rgb5:
2167 case Texture::F_rgb8:
2168 case Texture::F_rgb:
2170 case Texture::F_rgba8:
2171 case Texture::F_rgba:
2174 case Texture::F_rgbm:
2177 case Texture::F_rgb12:
2179 case Texture::F_rgba12:
2182 case Texture::F_rgba16:
2185 case Texture::F_rgba32:
2189 case Texture::F_srgb:
2191 case Texture::F_srgb_alpha:
2194 case Texture::F_sluminance:
2196 case Texture::F_sluminance_alpha:
2208 PN_stdfloat DXTextureContext9::
2209 d3d_format_to_bytes_per_pixel (D3DFORMAT format)
2211 PN_stdfloat bytes_per_pixel;
2213 bytes_per_pixel = 0.0f;
2222 bytes_per_pixel = 1.0f;
2229 case D3DFMT_X1R5G5B5:
2230 case D3DFMT_A1R5G5B5:
2231 case D3DFMT_A4R4G4B4:
2234 case D3DFMT_A8R3G3B2:
2235 case D3DFMT_X4R4G4B4:
2236 bytes_per_pixel = 2.0f;
2240 bytes_per_pixel = 3.0f;
2243 case D3DFMT_G16R16F:
2244 case D3DFMT_Q8W8V8U8:
2247 case D3DFMT_A8R8G8B8:
2248 case D3DFMT_X8R8G8B8:
2249 case D3DFMT_A2B10G10R10:
2250 case D3DFMT_A8B8G8R8:
2251 case D3DFMT_X8B8G8R8:
2253 case D3DFMT_A2R10G10B10:
2254 bytes_per_pixel = 4.0f;
2257 case D3DFMT_G32R32F:
2258 case D3DFMT_A16B16G16R16F:
2259 case D3DFMT_Q16W16V16U16:
2260 case D3DFMT_A16B16G16R16:
2261 bytes_per_pixel = 8.0f;
2264 case D3DFMT_A32B32G32R32F:
2265 bytes_per_pixel = 16.0f;
2269 bytes_per_pixel = 0.5f;
2275 bytes_per_pixel = 1.0f;
2279 return bytes_per_pixel;
CPTA_uchar get_ram_image()
Returns the system-RAM image data associated with the texture.
void set_data(TypedWritable *ptr, ReferenceCount *ref_ptr)
Stores a new data object on the record.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise. ...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
int get_simple_x_size() const
Returns the width of the "simple" image in texels.
int get_anisotropic_degree() const
Returns the degree of anisotropic filtering that should be applied to the texture.
This class maintains a cache of Bam and/or Txo objects generated from model files and texture images ...
ComponentType get_component_type() const
Returns the numeric interpretation of each component of the texture.
CPTA_uchar get_uncompressed_ram_image()
Returns the system-RAM image associated with the texture, in an uncompressed form if at all possible...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void set_format(Format format)
Changes the format value for the texture components.
void set_post_load_store_cache(bool flag)
Sets the post_load_store_cache flag.
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool get_match_framebuffer_format() const
Returns true if the special flag was set that indicates to the GSG that the Texture's format should b...
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
void set_magfilter(FilterType filter)
Sets the filtering method that should be used when viewing the texture up close.
A table of objects that are saved within the graphics context for reference by handle later...
void texture_uploaded(Texture *tex)
This method is called by the GraphicsStateGuardian after a texture has been successfully uploaded to ...
void dequeue_lru()
Removes the page from its AdaptiveLru.
int get_expected_mipmap_x_size(int n) const
Returns the x_size that the nth mipmap level should have, based on the texture's size.
bool store(BamCacheRecord *record)
Flushes a cache entry to disk.
int get_num_loadable_ram_mipmap_images() const
Returns the number of contiguous mipmap levels that exist in RAM, up until the first gap in the seque...
void set_ram_mipmap_image(int n, CPTA_uchar image, size_t page_size=0)
Replaces the current system-RAM image for the indicated mipmap level with the new data...
bool extract_texture_data(DXScreenData &scrn)
This method will be called in the draw thread to download the texture memory's image into its ram_ima...
CompressionMode get_compression() const
Returns the compression mode requested for this particular texture, or CM_off if the texture is not t...
int get_z_size() const
Returns the depth of the texture image in texels.
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
int get_num_components() const
Returns the number of color components for each texel of the texture image.
CompressionMode get_ram_image_compression() const
Returns the compression mode in which the ram image is already stored pre-compressed.
virtual bool get_supports_compressed_texture_format(int compression_mode) const
Returns true if this GSG can accept textures pre-compressed in the indicated format.
CPTA_uchar get_simple_ram_image() const
Returns the image data associated with the "simple" texture image.
CPTA_uchar get_ram_mipmap_image(int n) const
Returns the system-RAM image data associated with the nth mipmap level, if present.
size_t get_ram_mipmap_view_size(int n) const
Returns the number of bytes used by the in-memory image per view for mipmap level n...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
bool get_render_to_texture() const
Returns a flag on the texture that indicates whether the texture is intended to be used as a direct-r...
void clear_ram_image()
Discards the current system-RAM image.
SamplerState::FilterType get_magfilter() const
Returns the filter mode of the texture for magnification.
void set_anisotropic_degree(int anisotropic_degree)
Specifies the level of anisotropic filtering to apply to the texture.
void set_ram_image(CPTA_uchar image, CompressionMode compression=CM_off, size_t page_size=0)
Replaces the current system-RAM image with the new data.
void set_component_type(ComponentType component_type)
Changes the data value for the texture components.
bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
bool get_post_load_store_cache() const
Returns the setting of the post_load_store_cache flag.
void update_data_size_bytes(size_t new_data_size_bytes)
Should be called (usually by a derived class) when the on-card size of this object has changed...
int get_expected_mipmap_y_size(int n) const
Returns the y_size that the nth mipmap level should have, based on the texture's size.
void set_y_size(int y_size)
Changes the y size indicated for the texture.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
int get_view() const
Returns the specific view of a multiview texture this context represents.
void set_minfilter(FilterType filter)
Sets the filtering method that should be used when viewing the texture from a distance.
virtual void evict_lru()
Evicts the page from the LRU.
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
void mark_used_lru() const
To be called when the page is used; this will move it to the tail of the AdaptiveLru queue it is alre...
int get_simple_y_size() const
Returns the height of the "simple" image in texels.
int get_component_width() const
Returns the number of bytes stored for each color component of a texel.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
SamplerState::FilterType get_minfilter() const
Returns the filter mode of the texture for minification.
size_t get_expected_ram_mipmap_page_size(int n) const
Returns the number of bytes that should be used per each Z page of the 3-d texture, for mipmap level n.
TypeHandle is the identifier used to differentiate C++ class types.
PTA_uchar modify_ram_image()
Returns a modifiable pointer to the system-RAM image.
void set_z_size(int z_size)
Changes the z size indicated for the texture.
void mark_simple_loaded()
Should be called after the texture's "simple" image has been loaded into graphics memory...
bool get_supports_compressed_texture() const
Returns true if this GSG can compress textures as it loads them into texture memory, and/or accept pre-compressed textures for storing.
void set_x_size(int x_size)
Changes the x size indicated for the texture.
size_t get_expected_ram_page_size() const
Returns the number of bytes that should be used per each Z page of the 3-d texture.
int get_y_size() const
Returns the height of the texture image in texels.
int get_x_size() const
Returns the width of the texture image in texels.
void delete_texture()
Release the surface used to store the texture.
static BamCache * get_global_ptr()
Returns a pointer to the global BamCache object, which is used automatically by the ModelPool and Tex...
const Filename & get_fullpath() const
Returns the fullpath that has been set.
static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, bool inverted, Texture *result, int view, int z)
copies source_rect in pD3DSurf to upper left of texture