diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 2a0438cd96..cb9ce71f98 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -2417,7 +2417,7 @@ do_issue_texture() { apply_texture(i, tc); set_texture_blend_mode(i, stage); - bool texcoords_3d = false; + int texcoord_dimensions = 0; CPT(TransformState) tex_mat = TransformState::make_identity(); if (_state._tex_matrix->has_stage(stage)) { @@ -2432,7 +2432,6 @@ do_issue_texture() { 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: @@ -2448,7 +2447,7 @@ do_issue_texture() { 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; + texcoord_dimensions = 3; } break; @@ -2460,7 +2459,7 @@ do_issue_texture() { { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - texcoords_3d = true; + texcoord_dimensions = 3; CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero())); } @@ -2470,7 +2469,7 @@ do_issue_texture() { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); tex_mat = tex_mat->compose(_inv_cs_transform); - texcoords_3d = true; + texcoord_dimensions = 3; break; case TexGenAttrib::M_world_normal: @@ -2481,7 +2480,7 @@ do_issue_texture() { { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL); - texcoords_3d = true; + texcoord_dimensions = 3; CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero())); } @@ -2490,7 +2489,7 @@ do_issue_texture() { case TexGenAttrib::M_eye_normal: _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL); - texcoords_3d = true; + texcoord_dimensions = 3; tex_mat = tex_mat->compose(_inv_cs_transform); break; @@ -2501,7 +2500,7 @@ do_issue_texture() { { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); - texcoords_3d = true; + texcoord_dimensions = 4; CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); tex_mat = tex_mat->compose(camera_transform); } @@ -2510,7 +2509,7 @@ do_issue_texture() { case TexGenAttrib::M_eye_position: _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); - texcoords_3d = true; + texcoord_dimensions = 4; tex_mat = tex_mat->compose(_inv_cs_transform); break; @@ -2523,7 +2522,7 @@ do_issue_texture() { _d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite); if (!tex_mat->is_identity()) { - if (tex_mat->is_2d() && !texcoords_3d) { + if (tex_mat->is_2d() && texcoord_dimensions <= 2) { // For 2-d texture coordinates, we have to reorder the matrix. LMatrix4f m = tex_mat->get_mat(); m.set(m(0, 0), m(0, 1), m(0, 3), 0.0f, @@ -2536,8 +2535,12 @@ do_issue_texture() { } else { LMatrix4f m = tex_mat->get_mat(); _d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data()); + DWORD transform_flags = texcoord_dimensions; + if (m.get_col3(3) != LVecBase3f::zero()) { + transform_flags |= D3DTTFF_PROJECTED; + } _d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, - D3DTTFF_COUNT3); + transform_flags); } } else { diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index b1fe99aa7b..3c24092ad0 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -47,6 +47,7 @@ depthWriteAttrib.I depthWriteAttrib.h \ directionalLight.I directionalLight.h \ drawCullHandler.I drawCullHandler.h \ + drawMaskAttrib.I drawMaskAttrib.h \ fadeLodNode.I fadeLodNode.h fadeLodNodeData.h \ findApproxLevelEntry.I findApproxLevelEntry.h \ findApproxPath.I findApproxPath.h \ @@ -151,6 +152,7 @@ depthWriteAttrib.cxx \ directionalLight.cxx \ drawCullHandler.cxx \ + drawMaskAttrib.cxx \ fadeLodNode.cxx fadeLodNodeData.cxx \ findApproxLevelEntry.cxx \ findApproxPath.cxx \ @@ -251,6 +253,7 @@ depthWriteAttrib.I depthWriteAttrib.h \ directionalLight.I directionalLight.h \ drawCullHandler.I drawCullHandler.h \ + drawMaskAttrib.I drawMaskAttrib.h \ fadeLodNode.I fadeLodNode.h fadeLodNodeData.h \ fog.I fog.h \ fogAttrib.I fogAttrib.h \ diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index c65cb522b8..4f3aa147d3 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -45,6 +45,7 @@ #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "directionalLight.h" +#include "drawMaskAttrib.h" #include "fadeLodNode.h" #include "fadeLodNodeData.h" #include "fog.h" @@ -287,6 +288,7 @@ init_libpgraph() { DepthTestAttrib::init_type(); DepthWriteAttrib::init_type(); DirectionalLight::init_type(); + DrawMaskAttrib::init_type(); FadeLODNode::init_type(); FadeLODNodeData::init_type(); Fog::init_type(); @@ -362,6 +364,7 @@ init_libpgraph() { DepthTestAttrib::register_with_read_factory(); DepthWriteAttrib::register_with_read_factory(); DirectionalLight::register_with_read_factory(); + DrawMaskAttrib::register_with_read_factory(); Fog::register_with_read_factory(); FogAttrib::register_with_read_factory(); GeomNode::register_with_read_factory(); diff --git a/panda/src/pgraph/drawMaskAttrib.I b/panda/src/pgraph/drawMaskAttrib.I new file mode 100644 index 0000000000..970f5b450d --- /dev/null +++ b/panda/src/pgraph/drawMaskAttrib.I @@ -0,0 +1,96 @@ +// Filename: drawMaskAttrib.I +// Created by: drose (28Sep05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::Constructor +// Access: Protected +// Description: Use DrawMaskAttrib::make() to construct a new +// DrawMaskAttrib object. +//////////////////////////////////////////////////////////////////// +INLINE DrawMaskAttrib:: +DrawMaskAttrib(DrawMask new_mask, DrawMask bits_to_change) : + _new_mask(new_mask & bits_to_change), + _bits_to_change(bits_to_change) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::Copy Constructor +// Access: Protected +// Description: Use DrawMaskAttrib::make() to construct a new +// DrawMaskAttrib object. +//////////////////////////////////////////////////////////////////// +INLINE DrawMaskAttrib:: +DrawMaskAttrib(const DrawMaskAttrib ©) : + _new_mask(copy._new_mask), + _bits_to_change(copy._bits_to_change) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::make_hide +// Access: Published, Static +// Description: Constructs a new DrawMaskAttrib that removes the +// indicated draw bits from the visibility mask. That +// is, it makes any nodes invisible to cameras that have +// any bits in common with draw_mask. This is similar +// to (but not quite identical to) +// NodePath.hide(draw_mask). +//////////////////////////////////////////////////////////////////// +INLINE CPT(RenderAttrib) DrawMaskAttrib:: +make_hide(DrawMask draw_mask) { + return make(DrawMask::all_off(), draw_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::make_show +// Access: Published, Static +// Description: Constructs a new DrawMaskAttrib that adds the +// indicated draw bits to the visibility mask. That +// is, it makes any nodes visible to cameras that have +// any bits in common with draw_mask. This is similar +// to (but not quite identical to) +// NodePath.show(draw_mask). +//////////////////////////////////////////////////////////////////// +INLINE CPT(RenderAttrib) DrawMaskAttrib:: +make_show(DrawMask draw_mask) { + return make(draw_mask, draw_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::get_new_mask +// Access: Published +// Description: Returns the new DrawMask that will be set after the +// attrib has been applied. +//////////////////////////////////////////////////////////////////// +INLINE DrawMask DrawMaskAttrib:: +get_new_mask() const { + return _new_mask; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::get_bits_to_change +// Access: Published +// Description: Returns the set of bits that will be allowed to be +// changed by this DrawMaskAttrib. +//////////////////////////////////////////////////////////////////// +INLINE DrawMask DrawMaskAttrib:: +get_bits_to_change() const { + return _bits_to_change; +} diff --git a/panda/src/pgraph/drawMaskAttrib.cxx b/panda/src/pgraph/drawMaskAttrib.cxx new file mode 100644 index 0000000000..d2c0757c81 --- /dev/null +++ b/panda/src/pgraph/drawMaskAttrib.cxx @@ -0,0 +1,230 @@ +// Filename: drawMaskAttrib.cxx +// Created by: drose (28Sep05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "drawMaskAttrib.h" +#include "dcast.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "cullTraverser.h" +#include "config_pgraph.h" + +TypeHandle DrawMaskAttrib::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::make +// Access: Published, Static +// Description: Constructs a new DrawMaskAttrib that changes the +// bits_to_change bits in the current DrawMask to the +// values of the corresponding bits in new_mask. Only +// those bits in common with bits_to_change are +// affected. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) DrawMaskAttrib:: +make(DrawMask new_mask, DrawMask bits_to_change) { + DrawMaskAttrib *attrib = new DrawMaskAttrib(new_mask, bits_to_change); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::output +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void DrawMaskAttrib:: +output(ostream &out) const { + out << get_type() << ":" << get_new_mask() << "/" << get_bits_to_change(); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::compare_to_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived DrawMaskAttrib +// types to return a unique number indicating whether +// this DrawMaskAttrib is equivalent to the other one. +// +// This should return 0 if the two DrawMaskAttrib objects +// are equivalent, a number less than zero if this one +// should be sorted before the other one, and a number +// greater than zero otherwise. +// +// This will only be called with two DrawMaskAttrib +// objects whose get_type() functions return the same. +//////////////////////////////////////////////////////////////////// +int DrawMaskAttrib:: +compare_to_impl(const RenderAttrib *other) const { + const DrawMaskAttrib *ta; + DCAST_INTO_R(ta, other, 0); + + int compare = get_new_mask().compare_to(ta->get_new_mask()); + if (compare != 0) { + return compare; + } + compare = get_bits_to_change().compare_to(ta->get_bits_to_change()); + return compare; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::compose_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived RenderAttrib +// types to specify how two consecutive RenderAttrib +// objects of the same type interact. +// +// This should return the result of applying the other +// RenderAttrib to a node in the scene graph below this +// RenderAttrib, which was already applied. In most +// cases, the result is the same as the other +// RenderAttrib (that is, a subsequent RenderAttrib +// completely replaces the preceding one). On the other +// hand, some kinds of RenderAttrib (for instance, +// ColorTransformAttrib) might combine in meaningful +// ways. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) DrawMaskAttrib:: +compose_impl(const RenderAttrib *other) const { + const DrawMaskAttrib *ta; + DCAST_INTO_R(ta, other, 0); + + DrawMask mask = get_new_mask(); + mask = (mask & ~ta->get_bits_to_change()) | ta->get_new_mask(); + + DrawMaskAttrib *attrib = new DrawMaskAttrib(mask, DrawMask::all_on()); + return return_new(attrib); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::make_default_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived DrawMaskAttrib +// types to specify what the default property for a +// DrawMaskAttrib of this type should be. +// +// This should return a newly-allocated DrawMaskAttrib of +// the same type that corresponds to whatever the +// standard default for this kind of DrawMaskAttrib is. +//////////////////////////////////////////////////////////////////// +RenderAttrib *DrawMaskAttrib:: +make_default_impl() const { + return new DrawMaskAttrib(DrawMask::all_on(), DrawMask::all_on()); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::store_into_slot +// Access: Public, Virtual +// Description: Stores this attrib into the appropriate slot of +// an object of class AttribSlots. +//////////////////////////////////////////////////////////////////// +void DrawMaskAttrib:: +store_into_slot(AttribSlots *) const { + // There's no need to store a DrawMaskAttrib at the moment, since it + // doesn't actually change any rendering state. +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::has_cull_callback +// Access: Public, Virtual +// Description: Should be overridden by derived classes to return +// true if cull_callback() has been defined. Otherwise, +// returns false to indicate cull_callback() does not +// need to be called for this node during the cull +// traversal. +//////////////////////////////////////////////////////////////////// +bool DrawMaskAttrib:: +has_cull_callback() const { + return (_new_mask != DrawMask::all_on()); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::cull_callback +// Access: Public, Virtual +// Description: If has_cull_callback() returns true, this function +// will be called during the cull traversal to perform +// any additional operations that should be performed at +// cull time. +// +// This is called each time the RenderAttrib is +// discovered applied to a Geom in the traversal. It +// should return true if the Geom is visible, false if +// it should be omitted. +//////////////////////////////////////////////////////////////////// +bool DrawMaskAttrib:: +cull_callback(CullTraverser *trav, const CullTraverserData &) const { + return (trav->get_camera_mask() & _new_mask) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// DrawMaskAttrib. +//////////////////////////////////////////////////////////////////// +void DrawMaskAttrib:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void DrawMaskAttrib:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderAttrib::write_datagram(manager, dg); + + dg.add_uint32(_new_mask.get_word()); + dg.add_uint32(_bits_to_change.get_word()); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type DrawMaskAttrib is encountered +// in the Bam file. It should create the DrawMaskAttrib +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *DrawMaskAttrib:: +make_from_bam(const FactoryParams ¶ms) { + DrawMaskAttrib *attrib = new DrawMaskAttrib(0, 0); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + attrib->fillin(scan, manager); + + return attrib; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawMaskAttrib::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new DrawMaskAttrib. +//////////////////////////////////////////////////////////////////// +void DrawMaskAttrib:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderAttrib::fillin(scan, manager); + + _new_mask.set_word(scan.get_uint32()); + _bits_to_change.set_word(scan.get_uint32()); +} diff --git a/panda/src/pgraph/drawMaskAttrib.h b/panda/src/pgraph/drawMaskAttrib.h new file mode 100644 index 0000000000..d335274726 --- /dev/null +++ b/panda/src/pgraph/drawMaskAttrib.h @@ -0,0 +1,102 @@ +// Filename: drawMaskAttrib.h +// Created by: drose (28Sep05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef DRAWMASKATTRIB_H +#define DRAWMASKATTRIB_H + +#include "pandabase.h" + +#include "renderAttrib.h" +#include "drawMask.h" + +class FactoryParams; + +//////////////////////////////////////////////////////////////////// +// Class : DrawMaskAttrib +// Description : This attrib can be used to control the visibility of +// certain Geoms from certain cameras. It is similar in +// principle to the PandaNode::set_draw_mask() +// interface, except it does not cause an early prune in +// the cull traversal; thus, it can be used to show a +// node even though its parent has been hidden (if the +// parent was hidden using the same interface). +// +// It is mainly useful for unusual circumstances in +// which the visibility of a node is not easy to +// determine from examining the static hierarchy of the +// graph. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA DrawMaskAttrib : public RenderAttrib { +protected: + INLINE DrawMaskAttrib(DrawMask new_mask, DrawMask bits_to_change); + INLINE DrawMaskAttrib(const DrawMaskAttrib ©); + +PUBLISHED: + INLINE static CPT(RenderAttrib) make_hide(DrawMask draw_mask = DrawMask::all_on()); + INLINE static CPT(RenderAttrib) make_show(DrawMask draw_mask = DrawMask::all_on()); + static CPT(RenderAttrib) make(DrawMask new_mask, DrawMask bits_to_change); + + INLINE DrawMask get_new_mask() const; + INLINE DrawMask get_bits_to_change() const; + +public: + virtual void output(ostream &out) const; + virtual void store_into_slot(AttribSlots *slots) const; + + virtual bool has_cull_callback() const; + virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const; + +protected: + virtual int compare_to_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; + virtual RenderAttrib *make_default_impl() const; + +private: + DrawMask _new_mask; + DrawMask _bits_to_change; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderAttrib::init_type(); + register_type(_type_handle, "DrawMaskAttrib", + RenderAttrib::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "drawMaskAttrib.I" + +#endif + diff --git a/panda/src/pgraph/pgraph_composite2.cxx b/panda/src/pgraph/pgraph_composite2.cxx index 711ad83bdb..a597223834 100644 --- a/panda/src/pgraph/pgraph_composite2.cxx +++ b/panda/src/pgraph/pgraph_composite2.cxx @@ -20,6 +20,7 @@ #include "alphaTestAttrib.cxx" #include "directionalLight.cxx" #include "drawCullHandler.cxx" +#include "drawMaskAttrib.cxx" #include "fadeLodNode.cxx" #include "fadeLodNodeData.cxx" #include "findApproxPath.cxx"