fix dx resize crash some more; first pass at dx cube map support
This commit is contained in:
parent
0b8f6c1f3f
commit
af49897d5e
|
|
@ -273,6 +273,27 @@ get_supports_texture_dot3() const {
|
|||
return _supports_texture_dot3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_3d_texture
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can render 3-d (volumetric)
|
||||
// textures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_3d_texture() const {
|
||||
return _supports_3d_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_cube_map
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can render cube map textures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_cube_map() const {
|
||||
return _supports_cube_map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_lights
|
||||
// Access: Published
|
||||
|
|
@ -690,6 +711,17 @@ get_cs_transform() const {
|
|||
return _cs_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_inv_cs_transform
|
||||
// Access: Public
|
||||
// Description: Returns the inverse of the transform returned by
|
||||
// get_cs_transform().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformState *GraphicsStateGuardian::
|
||||
get_inv_cs_transform() const {
|
||||
return _inv_cs_transform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_light
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||
_supports_texture_saved_result = false;
|
||||
_supports_texture_dot3 = false;
|
||||
|
||||
_supports_3d_texture = false;
|
||||
_supports_cube_map = false;
|
||||
|
||||
// Assume no limits on number of lights or clip planes.
|
||||
_max_lights = -1;
|
||||
_max_clip_planes = -1;
|
||||
|
|
@ -946,12 +949,17 @@ set_coordinate_system(CoordinateSystem cs) {
|
|||
if (_internal_coordinate_system == CS_default ||
|
||||
_internal_coordinate_system == _coordinate_system) {
|
||||
_cs_transform = TransformState::make_identity();
|
||||
_inv_cs_transform = TransformState::make_identity();
|
||||
|
||||
} else {
|
||||
_cs_transform =
|
||||
TransformState::make_mat
|
||||
(LMatrix4f::convert_mat(_coordinate_system,
|
||||
_internal_coordinate_system));
|
||||
_inv_cs_transform =
|
||||
TransformState::make_mat
|
||||
(LMatrix4f::convert_mat(_internal_coordinate_system,
|
||||
_coordinate_system));
|
||||
}
|
||||
_internal_transform = _cs_transform->compose(_external_transform);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ PUBLISHED:
|
|||
INLINE bool get_supports_texture_saved_result() const;
|
||||
INLINE bool get_supports_texture_dot3() const;
|
||||
|
||||
INLINE bool get_supports_3d_texture() const;
|
||||
INLINE bool get_supports_cube_map() const;
|
||||
|
||||
INLINE int get_max_lights() const;
|
||||
INLINE int get_max_clip_planes() const;
|
||||
|
||||
|
|
@ -205,6 +208,7 @@ public:
|
|||
virtual CoordinateSystem get_internal_coordinate_system() const;
|
||||
|
||||
INLINE const TransformState *get_cs_transform() const;
|
||||
INLINE const TransformState *get_inv_cs_transform() const;
|
||||
|
||||
virtual void issue_transform(const TransformState *transform);
|
||||
virtual void issue_color_scale(const ColorScaleAttrib *attrib);
|
||||
|
|
@ -317,6 +321,7 @@ protected:
|
|||
CoordinateSystem _coordinate_system;
|
||||
CoordinateSystem _internal_coordinate_system;
|
||||
CPT(TransformState) _cs_transform;
|
||||
CPT(TransformState) _inv_cs_transform;
|
||||
|
||||
Colorf _scene_graph_color;
|
||||
bool _has_scene_graph_color;
|
||||
|
|
@ -370,6 +375,9 @@ protected:
|
|||
bool _supports_texture_saved_result;
|
||||
bool _supports_texture_dot3;
|
||||
|
||||
bool _supports_3d_texture;
|
||||
bool _supports_cube_map;
|
||||
|
||||
int _max_lights;
|
||||
int _max_clip_planes;
|
||||
|
||||
|
|
|
|||
|
|
@ -295,7 +295,6 @@ appear before they are referenced.
|
|||
WORLD_NORMAL
|
||||
EYE_NORMAL
|
||||
WORLD_POSITION
|
||||
OBJECT_POSITION
|
||||
EYE_POSITION
|
||||
POINT_SPRITE
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ munge_format_impl(const GeomVertexFormat *orig,
|
|||
int num_stages = _texture->get_num_on_stages();
|
||||
for (int i = 0; i < num_stages; ++i) {
|
||||
TextureStage *stage = _texture->get_on_stage(i);
|
||||
|
||||
|
||||
const InternalName *name = stage->get_texcoord_name();
|
||||
if (used_stages.insert(name).second) {
|
||||
// This is the first time we've encountered this texcoord name.
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ DXGraphicsStateGuardian8::
|
|||
TextureContext *DXGraphicsStateGuardian8::
|
||||
prepare_texture(Texture *tex) {
|
||||
DXTextureContext8 *dtc = new DXTextureContext8(tex);
|
||||
if (dtc->create_texture(*_screen) == (IDirect3DTexture8 *)NULL) {
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
delete dtc;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ apply_texture(int i, TextureContext *tc) {
|
|||
<< "Texture " << *dtc->_texture << " has changed mipmap state.\n";
|
||||
}
|
||||
|
||||
if (dtc->create_texture(*_screen) == (IDirect3DTexture8 *)NULL) {
|
||||
if (!dtc->create_texture(*_screen)) {
|
||||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg8_cat.error()
|
||||
<< "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
|
|
@ -1320,8 +1320,11 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, const
|
|||
}
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
|
||||
nassertv(tex->get_texture_type() == Texture::TT_2d_texture);
|
||||
nassertv(dtc->get_d3d_2d_texture() != NULL);
|
||||
|
||||
IDirect3DSurface8 *tex_level_0, *render_target;
|
||||
hr = dtc->get_d3d_texture()->GetSurfaceLevel(0, &tex_level_0);
|
||||
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
return;
|
||||
|
|
@ -1519,6 +1522,9 @@ reset() {
|
|||
_supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
|
||||
_supports_texture_dot3 = true;
|
||||
|
||||
_supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
|
||||
_supports_cube_map = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) != 0);
|
||||
|
||||
ZeroMemory(&_lmodel_ambient, sizeof(Colorf));
|
||||
_d3d_device->SetRenderState(D3DRS_AMBIENT, 0x0);
|
||||
|
||||
|
|
@ -2225,26 +2231,22 @@ do_issue_texture() {
|
|||
apply_texture(i, tc);
|
||||
set_texture_blend_mode(i, stage);
|
||||
|
||||
bool has_tex_mat = false;
|
||||
LMatrix4f tex_mat;
|
||||
|
||||
bool texcoords_3d = false;
|
||||
|
||||
CPT(TransformState) tex_mat = TransformState::make_identity();
|
||||
if (_current_tex_mat->has_stage(stage)) {
|
||||
// We have to reorder the elements of the matrix for some reason.
|
||||
const LMatrix4f &m = _current_tex_mat->get_mat(stage);
|
||||
tex_mat.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
|
||||
m(1, 0), m(1, 1), m(1, 3), 0.0f,
|
||||
m(3, 0), m(3, 1), m(3, 3), 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
has_tex_mat = true;
|
||||
tex_mat = _current_tex_mat->get_transform(stage);
|
||||
}
|
||||
|
||||
// Issue the texgen mode.
|
||||
TexGenAttrib::Mode mode = _current_tex_gen->get_mode(stage);
|
||||
bool any_point_sprite = false;
|
||||
|
||||
switch (mode) {
|
||||
case TexGenAttrib::M_off:
|
||||
case TexGenAttrib::M_light_vector:
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index);
|
||||
texcoords_3d = false;
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_sphere_map:
|
||||
|
|
@ -2254,20 +2256,75 @@ do_issue_texture() {
|
|||
// This texture matrix, applied on top of the texcoord
|
||||
// computed by D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR,
|
||||
// approximates the effect produced by OpenGL's GL_SPHERE_MAP.
|
||||
static const LMatrix4f sphere_map
|
||||
(0.33f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.33f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f);
|
||||
|
||||
if (has_tex_mat) {
|
||||
tex_mat = sphere_map * tex_mat;
|
||||
} else {
|
||||
tex_mat = sphere_map;
|
||||
has_tex_mat = true;
|
||||
}
|
||||
static CPT(TransformState) sphere_map =
|
||||
TransformState::make_mat(LMatrix4f(0.33f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.33f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f));
|
||||
tex_mat = tex_mat->compose(sphere_map);
|
||||
texcoords_3d = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_world_cube_map:
|
||||
// To achieve world reflection vector, we must transform camera
|
||||
// coordinates to world coordinates; i.e. apply the camera
|
||||
// transform. In the case of a vector, we should not apply the
|
||||
// pos component of the transform.
|
||||
{
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
|
||||
texcoords_3d = true;
|
||||
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
|
||||
tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero()));
|
||||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_cube_map:
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
|
||||
texcoords_3d = true;
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_world_normal:
|
||||
// To achieve world normal, we must transform camera coordinates
|
||||
// to world coordinates; i.e. apply the camera transform. In
|
||||
// the case of a normal, we should not apply the pos component
|
||||
// of the transform.
|
||||
{
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
|
||||
texcoords_3d = true;
|
||||
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
|
||||
tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero()));
|
||||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_normal:
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
|
||||
texcoords_3d = true;
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_world_position:
|
||||
// To achieve world position, we must transform camera
|
||||
// coordinates to world coordinates; i.e. apply the
|
||||
// inverse root_transform.
|
||||
{
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
texcoords_3d = true;
|
||||
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
|
||||
tex_mat = tex_mat->compose(camera_transform);
|
||||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_position:
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
|
||||
texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
texcoords_3d = true;
|
||||
tex_mat = tex_mat->compose(_inv_cs_transform);
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_point_sprite:
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index);
|
||||
|
|
@ -2277,8 +2334,17 @@ do_issue_texture() {
|
|||
|
||||
_d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite);
|
||||
|
||||
if (has_tex_mat) {
|
||||
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)tex_mat.get_data());
|
||||
if (!tex_mat->is_identity()) {
|
||||
LMatrix4f m = tex_mat->get_mat();
|
||||
if (!texcoords_3d) {
|
||||
// For 2-d texture coordinates, we have to reorder the matrix.
|
||||
m.set(m(0, 0), m(0, 1), m(0, 3), 0.0f,
|
||||
m(1, 0), m(1, 1), m(1, 3), 0.0f,
|
||||
m(3, 0), m(3, 1), m(3, 3), 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data());
|
||||
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
|
||||
D3DTTFF_COUNT2);
|
||||
} else {
|
||||
|
|
@ -2964,10 +3030,10 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
|
|||
assert(IS_VALID_PTR(_screen->_d3d8));
|
||||
assert(IS_VALID_PTR(_d3d_device));
|
||||
|
||||
// It is not clear whether we need to call this or not. Calling
|
||||
// this forces all of the textures and vbuffers to be regenerated,
|
||||
// but it doesn't appear to be necessary.
|
||||
//release_all();
|
||||
// Calling this forces all of the textures and vbuffers to be
|
||||
// regenerated. It appears to be necessary on some cards but not
|
||||
// on others.
|
||||
release_all();
|
||||
|
||||
// for windowed mode make sure our format matches the desktop fmt,
|
||||
// in case the desktop mode has been changed
|
||||
|
|
|
|||
|
|
@ -32,9 +32,42 @@ has_mipmaps() const {
|
|||
// Function: DXTextureContext8::get_d3d_texture
|
||||
// Access: Public
|
||||
// Description: Returns the Direct3D object that represents the
|
||||
// texture.
|
||||
// texture, whatever kind of texture it is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE IDirect3DTexture8 *DXTextureContext8::
|
||||
INLINE IDirect3DBaseTexture8 *DXTextureContext8::
|
||||
get_d3d_texture() const {
|
||||
return _d3d_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::get_d3d_2d_texture
|
||||
// Access: Public
|
||||
// Description: Returns the Direct3D object that represents the
|
||||
// texture, in the case of a 1-d or 2-d texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE IDirect3DTexture8 *DXTextureContext8::
|
||||
get_d3d_2d_texture() const {
|
||||
return _d3d_2d_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::get_d3d_volume_texture
|
||||
// Access: Public
|
||||
// Description: Returns the Direct3D object that represents the
|
||||
// texture, in the case of a 3-d texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE IDirect3DVolumeTexture8 *DXTextureContext8::
|
||||
get_d3d_volume_texture() const {
|
||||
return _d3d_volume_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::get_d3d_cube_texture
|
||||
// Access: Public
|
||||
// Description: Returns the Direct3D object that represents the
|
||||
// texture, in the case of a cube map texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE IDirect3DCubeTexture8 *DXTextureContext8::
|
||||
get_d3d_cube_texture() const {
|
||||
return _d3d_cube_texture;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,10 @@ DXTextureContext8(Texture *tex) :
|
|||
}
|
||||
|
||||
_d3d_texture = NULL;
|
||||
_d3d_2d_texture = NULL;
|
||||
_d3d_volume_texture = NULL;
|
||||
_d3d_cube_texture = NULL;
|
||||
_has_mipmaps = false;
|
||||
_tex = tex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -56,11 +58,10 @@ DXTextureContext8::
|
|||
~DXTextureContext8() {
|
||||
if (dxgsg8_cat.is_spam()) {
|
||||
dxgsg8_cat.spam()
|
||||
<< "Deleting texture context for " << _tex->get_name() << "\n";
|
||||
<< "Deleting texture context for " << _texture->get_name() << "\n";
|
||||
}
|
||||
delete_texture();
|
||||
TextureContext::~TextureContext();
|
||||
_tex = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -70,16 +71,17 @@ DXTextureContext8::
|
|||
// for the specified device. This code gets the
|
||||
// attributes of the texture from the bitmap, creates
|
||||
// the texture, and then copies the bitmap into the
|
||||
// texture.
|
||||
// texture. The return value is true if the texture is
|
||||
// successfully created, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IDirect3DTexture8 *DXTextureContext8::
|
||||
bool DXTextureContext8::
|
||||
create_texture(DXScreenData &scrn) {
|
||||
HRESULT hr;
|
||||
int num_alpha_bits; // number of alpha bits in texture pixfmt
|
||||
D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
|
||||
bool needs_luminance = false;
|
||||
|
||||
nassertr(IS_VALID_PTR(_texture), NULL);
|
||||
nassertr(IS_VALID_PTR(_texture), false);
|
||||
|
||||
delete_texture();
|
||||
|
||||
|
|
@ -93,6 +95,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
DWORD orig_width = (DWORD)_texture->get_x_size();
|
||||
DWORD orig_height = (DWORD)_texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD)_texture->get_z_size();
|
||||
|
||||
if ((_texture->get_format() == Texture::F_luminance_alpha)||
|
||||
(_texture->get_format() == Texture::F_luminance_alphamask) ||
|
||||
|
|
@ -103,7 +106,7 @@ create_texture(DXScreenData &scrn) {
|
|||
if (num_alpha_bits > 0) {
|
||||
if (num_color_channels == 3) {
|
||||
dxgsg8_cat.error()
|
||||
<< "texture " << _tex->get_name()
|
||||
<< "texture " << _texture->get_name()
|
||||
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -121,7 +124,7 @@ create_texture(DXScreenData &scrn) {
|
|||
}
|
||||
break;
|
||||
case 2:
|
||||
assert(needs_luminance && (num_alpha_bits > 0));
|
||||
nassertr(needs_luminance && (num_alpha_bits > 0), false);
|
||||
_d3d_format = D3DFMT_A8L8;
|
||||
break;
|
||||
case 3:
|
||||
|
|
@ -133,43 +136,120 @@ create_texture(DXScreenData &scrn) {
|
|||
}
|
||||
|
||||
// make sure we handled all the possible cases
|
||||
assert(_d3d_format != D3DFMT_UNKNOWN);
|
||||
nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
|
||||
|
||||
DWORD target_width = orig_width;
|
||||
DWORD target_height = orig_height;
|
||||
DWORD target_depth = orig_depth;
|
||||
|
||||
if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
|
||||
if (!ISPOW2(target_width)) {
|
||||
target_width = down_to_power_2(target_width);
|
||||
}
|
||||
if (!ISPOW2(target_height)) {
|
||||
target_height = down_to_power_2(target_height);
|
||||
}
|
||||
}
|
||||
DWORD filter_caps;
|
||||
|
||||
if (target_width > scrn._d3dcaps.MaxTextureWidth) {
|
||||
target_width = scrn._d3dcaps.MaxTextureWidth;
|
||||
}
|
||||
if (target_height > scrn._d3dcaps.MaxTextureHeight) {
|
||||
target_height = scrn._d3dcaps.MaxTextureHeight;
|
||||
switch (_texture->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
||||
|
||||
if (target_width > scrn._d3dcaps.MaxTextureWidth) {
|
||||
target_width = scrn._d3dcaps.MaxTextureWidth;
|
||||
}
|
||||
if (target_height > scrn._d3dcaps.MaxTextureHeight) {
|
||||
target_height = scrn._d3dcaps.MaxTextureHeight;
|
||||
}
|
||||
|
||||
if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
|
||||
if (!ISPOW2(target_width)) {
|
||||
target_width = down_to_power_2(target_width);
|
||||
}
|
||||
if (!ISPOW2(target_height)) {
|
||||
target_height = down_to_power_2(target_height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) {
|
||||
dxgsg8_cat.warning()
|
||||
<< "3-d textures are not supported by this graphics driver.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
filter_caps = scrn._d3dcaps.VolumeTextureFilterCaps;
|
||||
|
||||
if (target_width > scrn._d3dcaps.MaxVolumeExtent) {
|
||||
target_width = scrn._d3dcaps.MaxVolumeExtent;
|
||||
}
|
||||
if (target_height > scrn._d3dcaps.MaxVolumeExtent) {
|
||||
target_height = scrn._d3dcaps.MaxVolumeExtent;
|
||||
}
|
||||
if (target_depth > scrn._d3dcaps.MaxVolumeExtent) {
|
||||
target_depth = scrn._d3dcaps.MaxVolumeExtent;
|
||||
}
|
||||
|
||||
if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) {
|
||||
if (!ISPOW2(target_width)) {
|
||||
target_width = down_to_power_2(target_width);
|
||||
}
|
||||
if (!ISPOW2(target_height)) {
|
||||
target_height = down_to_power_2(target_height);
|
||||
}
|
||||
if (!ISPOW2(target_depth)) {
|
||||
target_depth = down_to_power_2(target_depth);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::TT_cube_map:
|
||||
if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) {
|
||||
dxgsg8_cat.warning()
|
||||
<< "Cube map textures are not supported by this graphics driver.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
filter_caps = scrn._d3dcaps.CubeTextureFilterCaps;
|
||||
|
||||
if (target_width > scrn._d3dcaps.MaxTextureWidth) {
|
||||
target_width = scrn._d3dcaps.MaxTextureWidth;
|
||||
}
|
||||
|
||||
if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) {
|
||||
if (!ISPOW2(target_width)) {
|
||||
target_width = down_to_power_2(target_width);
|
||||
}
|
||||
}
|
||||
|
||||
target_height = target_width;
|
||||
break;
|
||||
}
|
||||
|
||||
// checks for SQUARE reqmt (nvidia riva128 needs this)
|
||||
if ((target_width != target_height) && (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) {
|
||||
// assume pow2 textures. sum exponents, divide by 2 rounding down to get sq size
|
||||
if ((target_width != target_height) &&
|
||||
(scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0) {
|
||||
// assume pow2 textures. sum exponents, divide by 2 rounding down
|
||||
// to get sq size
|
||||
int i, width_exp, height_exp;
|
||||
for (i = target_width, width_exp = 0; i > 1; width_exp++, i >>= 1);
|
||||
for (i = target_height, height_exp = 0; i > 1; height_exp++, i >>= 1);
|
||||
for (i = target_width, width_exp = 0; i > 1; width_exp++, i >>= 1) {
|
||||
}
|
||||
for (i = target_height, height_exp = 0; i > 1; height_exp++, i >>= 1) {
|
||||
}
|
||||
target_height = target_width = 1<<((width_exp+height_exp)>>1);
|
||||
}
|
||||
|
||||
bool shrink_original = false;
|
||||
|
||||
if (orig_width != target_width || orig_height != target_height) {
|
||||
dxgsg8_cat.info()
|
||||
<< "Reducing size of " << _tex->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height
|
||||
<< " to " << target_width << "x" << target_height << "\n";
|
||||
if (orig_width != target_width || orig_height != target_height ||
|
||||
orig_depth != target_depth) {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
dxgsg8_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
||||
<< " to " << target_width << "x" << target_height
|
||||
<< "x" << target_depth << "\n";
|
||||
} else {
|
||||
dxgsg8_cat.info()
|
||||
<< "Reducing size of " << _texture->get_name()
|
||||
<< " from " << orig_width << "x" << orig_height
|
||||
<< " to " << target_width << "x" << target_height << "\n";
|
||||
}
|
||||
|
||||
shrink_original = true;
|
||||
}
|
||||
|
|
@ -218,7 +298,7 @@ create_texture(DXScreenData &scrn) {
|
|||
}
|
||||
|
||||
if (num_alpha_bits>0) {
|
||||
assert(num_color_channels == 4);
|
||||
nassertr(num_color_channels == 4, false);
|
||||
|
||||
// no 32-bit fmt, look for 16 bit w/alpha (1-15)
|
||||
|
||||
|
|
@ -262,7 +342,7 @@ create_texture(DXScreenData &scrn) {
|
|||
break;
|
||||
|
||||
case 24:
|
||||
assert(num_color_channels == 3);
|
||||
nassertr(num_color_channels == 3, false);
|
||||
|
||||
if (!dx_force_16bpptextures) {
|
||||
CHECK_FOR_FMT(R8G8B8, Conv24to24);
|
||||
|
|
@ -281,8 +361,8 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
case 16:
|
||||
if (needs_luminance) {
|
||||
assert(num_alpha_bits>0);
|
||||
assert(num_color_channels == 2);
|
||||
nassertr(num_alpha_bits > 0, false);
|
||||
nassertr(num_color_channels == 2, false);
|
||||
|
||||
CHECK_FOR_FMT(A8L8, ConvLum16to16);
|
||||
|
||||
|
|
@ -301,7 +381,7 @@ create_texture(DXScreenData &scrn) {
|
|||
CHECK_FOR_FMT(A4R4G4B4, ConvLum16to16_4444);
|
||||
CHECK_FOR_FMT(A1R5G5B5, ConvLum16to16_1555);
|
||||
} else {
|
||||
assert((num_color_channels == 3)||(num_color_channels == 4));
|
||||
nassertr((num_color_channels == 3)||(num_color_channels == 4), false);
|
||||
// look for compatible 16bit fmts, if none then give up
|
||||
// (dont worry about other bitdepths for 16 bit)
|
||||
switch(num_alpha_bits) {
|
||||
|
|
@ -310,7 +390,7 @@ create_texture(DXScreenData &scrn) {
|
|||
CHECK_FOR_FMT(R5G6B5, Conv24to16_0565);
|
||||
CHECK_FOR_FMT(X1R5G5B5, Conv24to16_X555);
|
||||
} else {
|
||||
assert(num_color_channels == 4);
|
||||
nassertr(num_color_channels == 4, false);
|
||||
// it could be 4 if user asks us to throw away the alpha channel
|
||||
CHECK_FOR_FMT(R5G6B5, Conv32to16_0565);
|
||||
CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
|
||||
|
|
@ -321,23 +401,24 @@ create_texture(DXScreenData &scrn) {
|
|||
// explicitly want 1-5-5-5 fmt, as opposed to F_rgbm, which
|
||||
// could use 32bpp ARGB. fail if this particular fmt not
|
||||
// avail.
|
||||
assert(num_color_channels == 4);
|
||||
nassertr(num_color_channels == 4, false);
|
||||
CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
|
||||
break;
|
||||
case 4:
|
||||
// app specifically requests 4-4-4-4 F_rgba4 case, as opposed
|
||||
// to F_rgba, which could use 32bpp ARGB
|
||||
assert(num_color_channels == 4);
|
||||
nassertr(num_color_channels == 4, false);
|
||||
CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
|
||||
break;
|
||||
default: assert(0); // problem in get_bits_per_pixel()?
|
||||
default:
|
||||
nassertr(false, false); // problem in get_bits_per_pixel()?
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
if (needs_luminance) {
|
||||
// dont bother handling those other 8bit lum fmts like 4-4,
|
||||
// since 16 8-8 is usually supported too
|
||||
assert(num_color_channels == 1);
|
||||
nassertr(num_color_channels == 1, false);
|
||||
|
||||
// look for native lum fmt first
|
||||
CHECK_FOR_FMT(L8, ConvLum8to8);
|
||||
|
|
@ -375,9 +456,11 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
// if we've gotten here, haven't found a match
|
||||
dxgsg8_cat.error()
|
||||
<< error_message << ": " << _tex->get_name() << endl
|
||||
<< "NumColorChannels: " <<num_color_channels << "; NumAlphaBits: " << num_alpha_bits
|
||||
<< "; targetbpp: " <<target_bpp << "; _supported_tex_formats_mask: 0x" << (void*)scrn._supported_tex_formats_mask
|
||||
<< error_message << ": " << _texture->get_name() << endl
|
||||
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
||||
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
||||
<< "; _supported_tex_formats_mask: 0x"
|
||||
<< (void*)scrn._supported_tex_formats_mask
|
||||
<< "; NeedLuminance: " << needs_luminance << endl;
|
||||
goto error_exit;
|
||||
|
||||
|
|
@ -421,7 +504,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
Texture::FilterType ft;
|
||||
|
||||
ft = _tex->get_magfilter();
|
||||
ft = _texture->get_magfilter();
|
||||
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
||||
// mipmap settings make no sense for magfilter
|
||||
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
||||
|
|
@ -431,13 +514,14 @@ create_texture(DXScreenData &scrn) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((ft == Texture::FT_linear) && !(scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR)) {
|
||||
if (ft == Texture::FT_linear &&
|
||||
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
||||
ft = Texture::FT_nearest;
|
||||
}
|
||||
_tex->set_magfilter(ft);
|
||||
_texture->set_magfilter(ft);
|
||||
|
||||
// figure out if we are mipmapping this texture
|
||||
ft = _tex->get_minfilter();
|
||||
ft = _texture->get_minfilter();
|
||||
_has_mipmaps = false;
|
||||
|
||||
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
||||
|
|
@ -453,11 +537,13 @@ create_texture(DXScreenData &scrn) {
|
|||
_has_mipmaps = true;
|
||||
if (dxgsg8_cat.is_spam()) {
|
||||
if (ft != Texture::FT_linear_mipmap_linear) {
|
||||
dxgsg8_cat.spam() << "Forcing trilinear mipmapping on DX texture [" << _tex->get_name() << "]\n";
|
||||
dxgsg8_cat.spam()
|
||||
<< "Forcing trilinear mipmapping on DX texture ["
|
||||
<< _texture->get_name() << "]\n";
|
||||
}
|
||||
}
|
||||
ft = Texture::FT_linear_mipmap_linear;
|
||||
_tex->set_minfilter(ft);
|
||||
_texture->set_minfilter(ft);
|
||||
}
|
||||
|
||||
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
||||
|
|
@ -469,15 +555,15 @@ create_texture(DXScreenData &scrn) {
|
|||
ft = Texture::FT_linear;
|
||||
}
|
||||
|
||||
assert((scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT) != 0);
|
||||
nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0, false);
|
||||
|
||||
#define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR)
|
||||
|
||||
// do any other filter type degradations necessary
|
||||
switch(ft) {
|
||||
case Texture::FT_linear_mipmap_linear:
|
||||
if ((scrn._d3dcaps.TextureFilterCaps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
|
||||
if (scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) {
|
||||
if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
|
||||
if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
|
||||
ft = Texture::FT_linear_mipmap_nearest;
|
||||
} else {
|
||||
// if you cant do linear in a level, you probably cant do
|
||||
|
|
@ -489,43 +575,43 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
case Texture::FT_nearest_mipmap_linear:
|
||||
// if we dont have bilinear, do nearest_nearest
|
||||
if (!((scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFPOINT) &&
|
||||
(scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))) {
|
||||
if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
|
||||
(filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
|
||||
ft = Texture::FT_nearest_mipmap_nearest;
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::FT_linear_mipmap_nearest:
|
||||
// if we dont have mip linear, do nearest_nearest
|
||||
if (!(scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) {
|
||||
if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
|
||||
ft = Texture::FT_nearest_mipmap_nearest;
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::FT_linear:
|
||||
if (!(scrn._d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
|
||||
ft = Texture::FT_nearest;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_tex->set_minfilter(ft);
|
||||
_texture->set_minfilter(ft);
|
||||
|
||||
uint aniso_degree;
|
||||
|
||||
aniso_degree = 1;
|
||||
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
||||
aniso_degree = _tex->get_anisotropic_degree();
|
||||
aniso_degree = _texture->get_anisotropic_degree();
|
||||
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
||||
dx_force_anisotropic_filtering) {
|
||||
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
||||
}
|
||||
}
|
||||
_tex->set_anisotropic_degree(aniso_degree);
|
||||
_texture->set_anisotropic_degree(aniso_degree);
|
||||
|
||||
#ifdef _DEBUG
|
||||
dxgsg8_cat.spam()
|
||||
<< "create_texture: setting aniso degree for " << _tex->get_name()
|
||||
<< "create_texture: setting aniso degree for " << _texture->get_name()
|
||||
<< " to: " << aniso_degree << endl;
|
||||
#endif
|
||||
|
||||
|
|
@ -537,15 +623,37 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "create_texture: generating mipmaps for " << _tex->get_name()
|
||||
<< "create_texture: generating mipmaps for " << _texture->get_name()
|
||||
<< endl;
|
||||
}
|
||||
} else {
|
||||
mip_level_count = 1;
|
||||
}
|
||||
|
||||
hr = scrn._d3d_device->CreateTexture(target_width, target_height, mip_level_count, 0x0,
|
||||
target_pixel_format, D3DPOOL_MANAGED, &_d3d_texture);
|
||||
switch (_texture->get_texture_type()) {
|
||||
case Texture::TT_1d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
hr = scrn._d3d_device->CreateTexture
|
||||
(target_width, target_height, mip_level_count, 0x0,
|
||||
target_pixel_format, D3DPOOL_MANAGED, &_d3d_2d_texture);
|
||||
_d3d_texture = _d3d_2d_texture;
|
||||
break;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
hr = scrn._d3d_device->CreateVolumeTexture
|
||||
(target_width, target_height, target_depth, mip_level_count, 0x0,
|
||||
target_pixel_format, D3DPOOL_MANAGED, &_d3d_volume_texture);
|
||||
_d3d_texture = _d3d_volume_texture;
|
||||
break;
|
||||
|
||||
case Texture::TT_cube_map:
|
||||
hr = scrn._d3d_device->CreateCubeTexture
|
||||
(target_width, mip_level_count, 0x0,
|
||||
target_pixel_format, D3DPOOL_MANAGED, &_d3d_cube_texture);
|
||||
_d3d_texture = _d3d_cube_texture;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "D3D create_texture failed!" << D3DERRORSTRING(hr);
|
||||
|
|
@ -554,7 +662,7 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "create_texture: " << _tex->get_name()
|
||||
<< "create_texture: " << _texture->get_name()
|
||||
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
||||
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
||||
}
|
||||
|
|
@ -566,13 +674,15 @@ create_texture(DXScreenData &scrn) {
|
|||
|
||||
// PRINT_REFCNT(dxgsg8, scrn._d3d8);
|
||||
|
||||
// Return the newly created texture
|
||||
return _d3d_texture;
|
||||
return true;
|
||||
|
||||
error_exit:
|
||||
|
||||
RELEASE(_d3d_texture, dxgsg8, "texture", RELEASE_ONCE);
|
||||
return NULL;
|
||||
_d3d_2d_texture = NULL;
|
||||
_d3d_volume_texture = NULL;
|
||||
_d3d_cube_texture = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -587,11 +697,10 @@ delete_texture() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (dxgsg8_cat.is_spam()) {
|
||||
dxgsg8_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n";
|
||||
}
|
||||
|
||||
RELEASE(_d3d_texture, dxgsg8, "texture", RELEASE_ONCE);
|
||||
_d3d_2d_texture = NULL;
|
||||
_d3d_volume_texture = NULL;
|
||||
_d3d_cube_texture = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -616,7 +725,9 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
|
|||
BYTE *buf = result->modify_ram_image().p();
|
||||
|
||||
if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) {
|
||||
dxgsg8_cat.error() << "d3d_surface_to_texture failed: bad pD3DSurf ptr value (" << ((void*)d3d_surface) << ")\n";
|
||||
dxgsg8_cat.error()
|
||||
<< "d3d_surface_to_texture failed: bad pD3DSurf ptr value ("
|
||||
<< ((void*)d3d_surface) << ")\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -632,18 +743,20 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
|
|||
copy_width = RECT_XSIZE(source_rect);
|
||||
copy_height = RECT_YSIZE(source_rect);
|
||||
|
||||
//make sure there's enough space in the texture, its size must match
|
||||
//(especially xsize) or scanlines will be too long
|
||||
// make sure there's enough space in the texture, its size must
|
||||
// match (especially xsize) or scanlines will be too long
|
||||
|
||||
if (!((copy_width == result->get_x_size()) && (copy_height <= (DWORD)result->get_y_size()))) {
|
||||
dxgsg8_cat.error() << "d3d_surface_to_texture, Texture size too small to hold display surface!\n";
|
||||
dxgsg8_cat.error()
|
||||
<< "d3d_surface_to_texture, Texture size too small to hold display surface!\n";
|
||||
nassertr(false, E_FAIL);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = d3d_surface->LockRect(&locked_rect, (CONST RECT*)NULL, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE /* | D3DLOCK_NOSYSLOCK */));
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
|
||||
dxgsg8_cat.error()
|
||||
<< "d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -816,7 +929,8 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
|
|||
}
|
||||
|
||||
default:
|
||||
dxgsg8_cat.error() << "d3d_surface_to_texture: unsupported D3DFORMAT!\n";
|
||||
dxgsg8_cat.error()
|
||||
<< "d3d_surface_to_texture: unsupported D3DFORMAT!\n";
|
||||
}
|
||||
|
||||
d3d_surface->UnlockRect();
|
||||
|
|
@ -830,8 +944,12 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
|
|||
////////////////////////////////////////////////////////////////////
|
||||
HRESULT DXTextureContext8::
|
||||
fill_d3d_texture_pixels() {
|
||||
if (_texture->get_texture_type() == Texture::TT_3d_texture) {
|
||||
return fill_d3d_volume_texture_pixels();
|
||||
}
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
assert(IS_VALID_PTR(_texture));
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
|
|
@ -843,80 +961,266 @@ fill_d3d_texture_pixels() {
|
|||
|
||||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||
|
||||
assert(IS_VALID_PTR(_d3d_texture));
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *pixels = (BYTE*)image.p();
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
|
||||
assert(IS_VALID_PTR(pixels));
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
IDirect3DSurface8 *mip_level_0 = NULL;
|
||||
bool using_temp_buffer = false;
|
||||
BYTE *pixels = NULL;
|
||||
|
||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||
pixels = image_pixels + di * _texture->get_expected_ram_page_size();
|
||||
mip_level_0 = NULL;
|
||||
|
||||
if (_texture->get_texture_type() == Texture::TT_cube_map) {
|
||||
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
||||
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)di, 0, &mip_level_0);
|
||||
} else {
|
||||
nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
|
||||
hr = _d3d_2d_texture->GetSurfaceLevel(0, &mip_level_0);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RECT source_size;
|
||||
source_size.left = source_size.top = 0;
|
||||
source_size.right = orig_width;
|
||||
source_size.bottom = orig_height;
|
||||
|
||||
UINT source_row_byte_length = orig_width * num_color_channels;
|
||||
|
||||
DWORD level_0_filter, mip_filter_flags;
|
||||
using_temp_buffer = false;
|
||||
|
||||
// need filtering if size changes, (also if bitdepth reduced (need
|
||||
// dithering)??)
|
||||
level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
||||
|
||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
||||
// full white, so convert to explicit luminance-alpha format
|
||||
if (_d3d_format == D3DFMT_A8) {
|
||||
// alloc buffer for explicit D3DFMT_A8L8
|
||||
USHORT *temp_buffer = new USHORT[orig_width * orig_height];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
using_temp_buffer = true;
|
||||
|
||||
USHORT *out_pixels = temp_buffer;
|
||||
BYTE *source_pixels = pixels + component_width - 1;
|
||||
for (UINT y = 0; y < orig_height; y++) {
|
||||
for (UINT x = 0;
|
||||
x < orig_width;
|
||||
x++, source_pixels += component_width, out_pixels++) {
|
||||
// add full white, which is our interpretation of alpha-only
|
||||
// (similar to default adding full opaque alpha 0xFF to
|
||||
// RGB-only textures)
|
||||
*out_pixels = ((*source_pixels) << 8 ) | 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
source_format = D3DFMT_A8L8;
|
||||
source_row_byte_length = orig_width * sizeof(USHORT);
|
||||
pixels = (BYTE*)temp_buffer;
|
||||
|
||||
} else if (component_width != 1) {
|
||||
// Convert from 16-bit per channel (or larger) format down to
|
||||
// 8-bit per channel. This throws away precision in the
|
||||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
using_temp_buffer = true;
|
||||
|
||||
BYTE *source_pixels = pixels + component_width - 1;
|
||||
for (int i = 0; i < num_pixels; i++) {
|
||||
temp_buffer[i] = *source_pixels;
|
||||
source_pixels += component_width;
|
||||
}
|
||||
pixels = (BYTE*)temp_buffer;
|
||||
}
|
||||
|
||||
|
||||
// filtering may be done here if texture if targetsize != origsize
|
||||
#ifdef DO_PSTATS
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * orig_height);
|
||||
#endif
|
||||
hr = D3DXLoadSurfaceFromMemory
|
||||
(mip_level_0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
|
||||
source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
|
||||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
||||
if (_has_mipmaps) {
|
||||
if (!dx_use_triangle_mipgen_filter) {
|
||||
mip_filter_flags = D3DX_FILTER_BOX;
|
||||
} else {
|
||||
mip_filter_flags = D3DX_FILTER_TRIANGLE;
|
||||
}
|
||||
|
||||
// mip_filter_flags| = D3DX_FILTER_DITHER;
|
||||
|
||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
||||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
}
|
||||
if (using_temp_buffer) {
|
||||
SAFE_DELETE_ARRAY(pixels);
|
||||
}
|
||||
RELEASE(mip_level_0, dxgsg8, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
|
||||
}
|
||||
return hr;
|
||||
|
||||
exit_FillDDSurf:
|
||||
if (using_temp_buffer) {
|
||||
SAFE_DELETE_ARRAY(pixels);
|
||||
}
|
||||
RELEASE(mip_level_0, dxgsg8, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
|
||||
return hr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXTextureContext8::fill_d3d_volume_texture_pixels
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HRESULT DXTextureContext8::
|
||||
fill_d3d_volume_texture_pixels() {
|
||||
HRESULT hr = E_FAIL;
|
||||
nassertr(IS_VALID_PTR(_texture), E_FAIL);
|
||||
|
||||
CPTA_uchar image = _texture->get_ram_image();
|
||||
if (image.is_null()) {
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
// operations or something.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||
|
||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||
nassertr(_texture->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
|
||||
|
||||
DWORD orig_width = (DWORD) _texture->get_x_size();
|
||||
DWORD orig_height = (DWORD) _texture->get_y_size();
|
||||
DWORD orig_depth = (DWORD) _texture->get_z_size();
|
||||
DWORD num_color_channels = _texture->get_num_components();
|
||||
D3DFORMAT source_format = _d3d_format;
|
||||
BYTE *image_pixels = (BYTE*)image.p();
|
||||
int component_width = _texture->get_component_width();
|
||||
|
||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
||||
|
||||
IDirect3DVolume8 *mip_level_0 = NULL;
|
||||
bool using_temp_buffer = false;
|
||||
BYTE *pixels = image_pixels;
|
||||
|
||||
nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL);
|
||||
hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0);
|
||||
|
||||
IDirect3DSurface8 *mip_level_0;
|
||||
hr = _d3d_texture->GetSurfaceLevel(0, &mip_level_0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RECT source_size;
|
||||
source_size.left = source_size.top = 0;
|
||||
source_size.right = orig_width;
|
||||
source_size.bottom = orig_height;
|
||||
|
||||
D3DBOX source_size;
|
||||
source_size.Left = source_size.Top = source_size.Front = 0;
|
||||
source_size.Right = orig_width;
|
||||
source_size.Bottom = orig_height;
|
||||
source_size.Back = orig_depth;
|
||||
|
||||
UINT source_row_byte_length = orig_width * num_color_channels;
|
||||
|
||||
UINT source_page_byte_length = orig_height * source_row_byte_length;
|
||||
|
||||
DWORD level_0_filter, mip_filter_flags;
|
||||
bool using_temp_buffer = false;
|
||||
|
||||
// need filtering if size changes, (also if bitdepth reduced (need dithering)??)
|
||||
using_temp_buffer = false;
|
||||
|
||||
// need filtering if size changes, (also if bitdepth reduced (need
|
||||
// dithering)??)
|
||||
level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
||||
|
||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want full white,
|
||||
// so convert to explicit luminance-alpha format
|
||||
|
||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
||||
// full white, so convert to explicit luminance-alpha format
|
||||
if (_d3d_format == D3DFMT_A8) {
|
||||
// alloc buffer for explicit D3DFMT_A8L8
|
||||
USHORT *temp_buffer = new USHORT[orig_width*orig_height];
|
||||
USHORT *temp_buffer = new USHORT[orig_width * orig_height * orig_depth];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
using_temp_buffer = true;
|
||||
|
||||
|
||||
USHORT *out_pixels = temp_buffer;
|
||||
BYTE *source_pixels = pixels + component_width - 1;
|
||||
for (UINT y = 0; y < orig_height; y++) {
|
||||
for (UINT x = 0;
|
||||
x < orig_width;
|
||||
x++, source_pixels += component_width, out_pixels++) {
|
||||
// add full white, which is our interpretation of alpha-only
|
||||
// (similar to default adding full opaque alpha 0xFF to
|
||||
// RGB-only textures)
|
||||
*out_pixels = ((*source_pixels) << 8 ) | 0xFF;
|
||||
for (UINT z = 0; z < orig_depth; z++) {
|
||||
for (UINT y = 0; y < orig_height; y++) {
|
||||
for (UINT x = 0;
|
||||
x < orig_width;
|
||||
x++, source_pixels += component_width, out_pixels++) {
|
||||
// add full white, which is our interpretation of alpha-only
|
||||
// (similar to default adding full opaque alpha 0xFF to
|
||||
// RGB-only textures)
|
||||
*out_pixels = ((*source_pixels) << 8 ) | 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
source_format = D3DFMT_A8L8;
|
||||
source_row_byte_length = orig_width*sizeof(USHORT);
|
||||
source_row_byte_length = orig_width * sizeof(USHORT);
|
||||
source_page_byte_length = orig_height * source_row_byte_length;
|
||||
pixels = (BYTE*)temp_buffer;
|
||||
|
||||
|
||||
} else if (component_width != 1) {
|
||||
// Convert from 16-bit per channel (or larger) format down to
|
||||
// 8-bit per channel. This throws away precision in the
|
||||
// original image, but dx8 doesn't support high-precision images
|
||||
// anyway.
|
||||
|
||||
|
||||
int num_components = _texture->get_num_components();
|
||||
int num_pixels = orig_width * orig_height * num_components;
|
||||
int num_pixels = orig_width * orig_height * orig_depth * num_components;
|
||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||
if (!IS_VALID_PTR(temp_buffer)) {
|
||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
using_temp_buffer = true;
|
||||
|
||||
|
||||
BYTE *source_pixels = pixels + component_width - 1;
|
||||
for (int i = 0; i < num_pixels; i++) {
|
||||
temp_buffer[i] = *source_pixels;
|
||||
|
|
@ -924,36 +1228,43 @@ fill_d3d_texture_pixels() {
|
|||
}
|
||||
pixels = (BYTE*)temp_buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// filtering may be done here if texture if targetsize != origsize
|
||||
#ifdef DO_PSTATS
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * orig_height);
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth);
|
||||
#endif
|
||||
hr = D3DXLoadSurfaceFromMemory(mip_level_0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels, source_format,
|
||||
source_row_byte_length, (PALETTEENTRY*)NULL, &source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
hr = D3DXLoadVolumeFromMemory
|
||||
(mip_level_0, (PALETTEENTRY*)NULL, (D3DBOX*)NULL, (LPCVOID)pixels,
|
||||
source_format, source_row_byte_length, source_page_byte_length,
|
||||
(PALETTEENTRY*)NULL,
|
||||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
|
||||
|
||||
if (_has_mipmaps) {
|
||||
if (!dx_use_triangle_mipgen_filter) {
|
||||
mip_filter_flags = D3DX_FILTER_BOX;
|
||||
} else {
|
||||
mip_filter_flags = D3DX_FILTER_TRIANGLE;
|
||||
}
|
||||
|
||||
|
||||
// mip_filter_flags| = D3DX_FILTER_DITHER;
|
||||
|
||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0, mip_filter_flags);
|
||||
|
||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
||||
mip_filter_flags);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
<< "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
|
||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||
goto exit_FillDDSurf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exit_FillDDSurf:
|
||||
if (using_temp_buffer) {
|
||||
SAFE_DELETE_ARRAY(pixels);
|
||||
|
|
|
|||
|
|
@ -32,23 +32,29 @@ public:
|
|||
DXTextureContext8(Texture *tex);
|
||||
virtual ~DXTextureContext8();
|
||||
|
||||
IDirect3DTexture8 *create_texture(DXScreenData &scrn);
|
||||
bool create_texture(DXScreenData &scrn);
|
||||
void delete_texture();
|
||||
|
||||
INLINE bool has_mipmaps() const;
|
||||
INLINE IDirect3DTexture8 *get_d3d_texture() const;
|
||||
INLINE IDirect3DBaseTexture8 *get_d3d_texture() const;
|
||||
INLINE IDirect3DTexture8 *get_d3d_2d_texture() const;
|
||||
INLINE IDirect3DVolumeTexture8 *get_d3d_volume_texture() const;
|
||||
INLINE IDirect3DCubeTexture8 *get_d3d_cube_texture() const;
|
||||
|
||||
static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Texture *result);
|
||||
|
||||
private:
|
||||
HRESULT fill_d3d_texture_pixels();
|
||||
HRESULT fill_d3d_volume_texture_pixels();
|
||||
static int down_to_power_2(int value);
|
||||
unsigned int get_bits_per_pixel(Texture::Format format, int *alphbits);
|
||||
|
||||
private:
|
||||
Texture *_tex; // ptr to parent, primarily for access to namestr
|
||||
D3DFORMAT _d3d_format; // the 'D3DFORMAT' the Panda TextureBuffer fmt corresponds to
|
||||
IDirect3DTexture8 *_d3d_texture;
|
||||
IDirect3DBaseTexture8 *_d3d_texture;
|
||||
IDirect3DTexture8 *_d3d_2d_texture;
|
||||
IDirect3DVolumeTexture8 *_d3d_volume_texture;
|
||||
IDirect3DCubeTexture8 *_d3d_cube_texture;
|
||||
|
||||
bool _has_mipmaps;
|
||||
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,7 @@ search_for_device(wdxGraphicsPipe8 *dxpipe, DXDeviceInfo *device_info) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool wdxGraphicsWindow8::
|
||||
reset_device_resize_window(UINT new_xsize, UINT new_ysize) {
|
||||
assert((new_xsize > 0) && (new_ysize > 0));
|
||||
nassertr((new_xsize > 0) && (new_ysize > 0), false);
|
||||
bool retval = true;
|
||||
|
||||
DXScreenData *screen = NULL;
|
||||
|
|
|
|||
|
|
@ -836,9 +836,6 @@ string_tex_gen(const string &string) {
|
|||
} else if (cmp_nocase_uh(string, "world_position") == 0) {
|
||||
return TG_world_position;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "object_position") == 0) {
|
||||
return TG_object_position;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "eye_position") == 0) {
|
||||
return TG_eye_position;
|
||||
|
||||
|
|
@ -1161,9 +1158,6 @@ operator << (ostream &out, EggTexture::TexGen tex_gen) {
|
|||
case EggTexture::TG_world_position:
|
||||
return out << "world_position";
|
||||
|
||||
case EggTexture::TG_object_position:
|
||||
return out << "object_position";
|
||||
|
||||
case EggTexture::TG_eye_position:
|
||||
return out << "eye_position";
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,6 @@ PUBLISHED:
|
|||
TG_eye_normal,
|
||||
|
||||
TG_world_position,
|
||||
TG_object_position,
|
||||
TG_eye_position,
|
||||
|
||||
TG_point_sprite,
|
||||
|
|
|
|||
|
|
@ -515,9 +515,6 @@ get_tex_gen(const EggTexture *egg_tex) {
|
|||
case EggTexture::TG_world_position:
|
||||
return TexGenAttrib::M_world_position;
|
||||
|
||||
case EggTexture::TG_object_position:
|
||||
return TexGenAttrib::M_object_position;
|
||||
|
||||
case EggTexture::TG_eye_position:
|
||||
return TexGenAttrib::M_eye_position;
|
||||
|
||||
|
|
|
|||
|
|
@ -4300,23 +4300,6 @@ finish_modify_state() {
|
|||
}
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_object_position:
|
||||
GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
|
||||
GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
|
||||
GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
|
||||
GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
|
||||
|
||||
GLP(TexGenfv)(GL_S, GL_OBJECT_PLANE, s_data);
|
||||
GLP(TexGenfv)(GL_T, GL_OBJECT_PLANE, t_data);
|
||||
GLP(TexGenfv)(GL_R, GL_OBJECT_PLANE, r_data);
|
||||
GLP(TexGenfv)(GL_Q, GL_OBJECT_PLANE, q_data);
|
||||
|
||||
GLP(Enable)(GL_TEXTURE_GEN_S);
|
||||
GLP(Enable)(GL_TEXTURE_GEN_T);
|
||||
GLP(Enable)(GL_TEXTURE_GEN_R);
|
||||
GLP(Enable)(GL_TEXTURE_GEN_Q);
|
||||
break;
|
||||
|
||||
case TexGenAttrib::M_eye_position:
|
||||
// To represent eye position correctly, we need to temporarily
|
||||
// load the coordinate-system transform.
|
||||
|
|
|
|||
|
|
@ -330,12 +330,9 @@ public:
|
|||
bool _supports_draw_range_elements;
|
||||
PFNGLDRAWRANGEELEMENTSPROC _glDrawRangeElements;
|
||||
|
||||
bool _supports_3d_texture;
|
||||
PFNGLTEXIMAGE3DPROC _glTexImage3D;
|
||||
PFNGLTEXSUBIMAGE3DPROC _glTexSubImage3D;
|
||||
|
||||
bool _supports_cube_map;
|
||||
|
||||
bool _supports_bgr;
|
||||
bool _supports_rescale_normal;
|
||||
|
||||
|
|
|
|||
|
|
@ -1008,7 +1008,11 @@ release(PreparedGraphicsObjects *prepared_objects) {
|
|||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
TextureContext *tc = (*ci).second;
|
||||
prepared_objects->release_texture(tc);
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
prepared_objects->release_texture(tc);
|
||||
} else {
|
||||
_contexts.erase(ci);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1036,12 +1040,14 @@ release_all() {
|
|||
for (ci = temp.begin(); ci != temp.end(); ++ci) {
|
||||
PreparedGraphicsObjects *prepared_objects = (*ci).first;
|
||||
TextureContext *tc = (*ci).second;
|
||||
prepared_objects->release_texture(tc);
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
prepared_objects->release_texture(tc);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've called release_texture() on every known context,
|
||||
// the _contexts list should have completely emptied itself.
|
||||
nassertr(_contexts.empty(), num_freed);
|
||||
// There might still be some outstanding contexts in the map, if
|
||||
// there were any NULL pointers there. Eliminate them.
|
||||
_contexts.clear();
|
||||
|
||||
return num_freed;
|
||||
}
|
||||
|
|
@ -1163,9 +1169,9 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
}
|
||||
|
||||
TextureContext *tc = prepared_objects->prepare_texture_now(this, gsg);
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
_contexts[prepared_objects] = tc;
|
||||
_contexts[prepared_objects] = tc;
|
||||
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
// Now that we have a new TextureContext with zero dirty flags, our
|
||||
// intersection of all dirty flags must be zero. This doesn't mean
|
||||
// that some other contexts aren't still dirty, but at least one
|
||||
|
|
@ -1213,7 +1219,10 @@ mark_dirty(int flags_to_set) {
|
|||
// Otherwise, iterate through the contexts and mark them all dirty.
|
||||
Contexts::iterator ci;
|
||||
for (ci = _contexts.begin(); ci != _contexts.end(); ++ci) {
|
||||
(*ci).second->mark_dirty(flags_to_set);
|
||||
TextureContext *tc = (*ci).second;
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
tc->mark_dirty(flags_to_set);
|
||||
}
|
||||
}
|
||||
|
||||
_all_dirty_flags |= flags_to_set;
|
||||
|
|
|
|||
|
|
@ -99,8 +99,7 @@ PUBLISHED:
|
|||
M_off,
|
||||
|
||||
// In the types below, "eye" means the coordinate space of the
|
||||
// observing camera, "object" means the local coordinate space of
|
||||
// the object, and "world" means world coordinates, e.g. the
|
||||
// observing camera, and "world" means world coordinates, e.g. the
|
||||
// coordinate space of the root of the graph.
|
||||
|
||||
// Sphere maps are classic static reflection maps. They are
|
||||
|
|
@ -114,9 +113,8 @@ PUBLISHED:
|
|||
// texture images. They can also be generated dynamically for
|
||||
// real-time reflections (see GraphicsOutput::make_cube_map()).
|
||||
// Typically, a statically-generated cube map will be in eye
|
||||
// space, while a dynamically-generated map will be in world space
|
||||
// or object space (depending on where the camera rig that
|
||||
// generates the map is parented).
|
||||
// space, while a dynamically-generated map will be in world
|
||||
// space.
|
||||
|
||||
// Cube mapping is not supported on all hardware.
|
||||
M_world_cube_map,
|
||||
|
|
@ -131,7 +129,7 @@ PUBLISHED:
|
|||
// coordinates. This is particularly useful for implementing
|
||||
// projective texturing (see NodePath::project_texture()).
|
||||
M_world_position,
|
||||
M_object_position,
|
||||
M_unused, // formerly M_object_position, now deprecated.
|
||||
M_eye_position,
|
||||
|
||||
// With M_point_sprite, texture coordinates will be generated for
|
||||
|
|
|
|||
|
|
@ -283,9 +283,6 @@ output(ostream &out) const {
|
|||
case M_world_position:
|
||||
out << "world_position";
|
||||
break;
|
||||
case M_object_position:
|
||||
out << "object_position";
|
||||
break;
|
||||
case M_eye_position:
|
||||
out << "eye_position";
|
||||
break;
|
||||
|
|
@ -298,6 +295,9 @@ output(ostream &out) const {
|
|||
out << "light_vector: \"" << mode_def._source_name << "\", "
|
||||
<< mode_def._light;
|
||||
break;
|
||||
|
||||
case M_unused:
|
||||
break;
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue