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.
static bool is_srgb(Format format)
Returns true if the indicated format is in the sRGB color space, false otherwise. ...
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
const Filename & get_fullpath() const
Returns the fullpath that has been set.
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.
int get_z_size() const
Returns the depth of the texture image in texels.
CompressionMode get_compression() const
Returns the compression mode requested for this particular texture, or CM_off if the texture is not t...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
int get_anisotropic_degree() const
Returns the degree of anisotropic filtering that should be applied to 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...
int get_view() const
Returns the specific view of a multiview texture this context represents.
This class maintains a cache of Bam and/or Txo objects generated from model files and texture images ...
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.
SamplerState::FilterType get_magfilter() const
Returns the filter mode of the texture for magnification.
This is a special class object that holds all the information returned by a particular GSG to indicat...
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...
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_magfilter(FilterType filter)
Sets the filtering method that should be used when viewing the texture up close.
int get_component_width() const
Returns the number of bytes stored for each color component of a texel.
A table of objects that are saved within the graphics context for reference by handle later...
bool has_ram_image() const
Returns true if the Texture has its image contents available in main RAM, false if it exists only in ...
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.
ComponentType get_component_type() const
Returns the numeric interpretation of each component of the texture.
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.
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.
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...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
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...
CPTA_uchar get_ram_mipmap_image(int n) const
Returns the system-RAM image data associated with the nth mipmap level, if present.
bool store(BamCacheRecord *record)
Flushes a cache entry to disk.
CPTA_uchar get_simple_ram_image() const
Returns the image data associated with the "simple" texture image.
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...
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...
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
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.
void clear_ram_image()
Discards the current system-RAM image.
CompressionMode get_ram_image_compression() const
Returns the compression mode in which the ram image is already stored pre-compressed.
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.
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.
void set_component_type(ComponentType component_type)
Changes the data value for the texture components.
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...
void set_y_size(int y_size)
Changes the y size indicated for the texture.
int get_y_size() const
Returns the height of the texture image in texels.
void mark_loaded()
Should be called after the texture has been loaded into graphics memory, this updates the internal fl...
bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
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.
int get_num_components() const
Returns the number of color components for each texel of the texture image.
void mark_unloaded()
Should be called after the texture has been forced out of texture memory.
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...
void set_x_size(int x_size)
Changes the x size indicated for the texture.
int get_simple_x_size() const
Returns the width of the "simple" 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...
SamplerState::FilterType get_minfilter() const
Returns the filter mode of the texture for minification.
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.
bool get_post_load_store_cache() const
Returns the setting of the post_load_store_cache flag.
int get_x_size() const
Returns the width of the texture image in texels.
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