diff --git a/panda/src/display/graphicsBuffer.cxx b/panda/src/display/graphicsBuffer.cxx index 3e63d02aee..7ab4fa61e7 100644 --- a/panda/src/display/graphicsBuffer.cxx +++ b/panda/src/display/graphicsBuffer.cxx @@ -42,15 +42,15 @@ GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg, << " using GSG " << (void *)gsg << "\n"; } - if (want_texture) { - setup_copy_texture(_name); - } - _x_size = x_size; _y_size = y_size; _has_size = true; _default_display_region->compute_pixels(_x_size, _y_size); _open_request = OR_none; + + if (want_texture) { + setup_copy_texture(_name); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index e26783accd..efe40651f5 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1196,7 +1196,7 @@ do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg, _app.add_window(_app._window, window); display_cat.info() - << "Created " << window->get_type() << "\n"; + << "Created " << window->get_type() << " " << (void *)window << "\n"; // By default, try to open each window as it is added. window->request_open(); @@ -1230,6 +1230,11 @@ do_remove_window(GraphicsOutput *window) { // If the window happened to be controlled by the app thread, we // might as well close it now rather than waiting for next frame. _app.do_pending(this); + + if (display_cat.is_debug()) { + display_cat.debug() + << "Removed " << window->get_type() << " " << (void *)window << "\n"; + } } //////////////////////////////////////////////////////////////////// @@ -1450,6 +1455,19 @@ resort_windows() { _cdraw.sort(); _draw.sort(); _window.sort(); + + if (display_cat.is_debug()) { + display_cat.debug() + << "Windows resorted:"; + Windows::const_iterator wi; + for (wi = _window.begin(); wi != _window.end(); ++wi) { + GraphicsOutput *win = (*wi); + display_cat.debug(false) + << " " << (void *)win; + } + display_cat.debug(false) + << "\n"; + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 24d1d1e9b5..666864a8f2 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -164,6 +164,13 @@ setup_copy_texture(const string &name) { _texture->set_wrapu(Texture::WM_clamp); _texture->set_wrapv(Texture::WM_clamp); + if (has_size()) { + // If we know our size now, go ahead and tell the texture. + PixelBuffer *pb = _texture->_pbuffer; + pb->set_xsize(get_x_size()); + pb->set_ysize(get_y_size()); + } + _copy_texture = true; nassertv(_gsg != (GraphicsStateGuardian *)NULL); @@ -587,6 +594,10 @@ end_frame() { // directly into texture memory don't need to do this; they will set // _copy_texture to false. if (_copy_texture) { + if (display_cat.is_debug()) { + display_cat.debug() + << "Copying texture for " << (void *)this << " at frame end.\n"; + } PStatTimer timer(_copy_texture_pcollector); nassertv(has_texture()); RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type()); diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 4792724ebc..65caac6acf 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -168,6 +168,20 @@ get_copy_texture_inverted() const { return _copy_texture_inverted; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_supports_generate_mipmap +// Access: Published +// Description: Returns true if this particular GSG can generate +// mipmaps for a texture automatically, or if they must +// be generated in software. If this is true, then +// mipmaps can safely be enabled for rendered textures +// (e.g. using the MultitexReducer). +//////////////////////////////////////////////////////////////////// +INLINE bool GraphicsStateGuardian:: +get_supports_generate_mipmap() const { + return _supports_generate_mipmap; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::set_scene diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index b2a6d71687..65afb95c85 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -92,6 +92,10 @@ GraphicsStateGuardian(const FrameBufferProperties &properties, // Initially, we set this to false; a GSG that knows it has this // property should set it to true. _copy_texture_inverted = false; + + // Similarly with these capabilities flags. + _supports_multisample = false; + _supports_generate_mipmap = false; } //////////////////////////////////////////////////////////////////// @@ -103,6 +107,24 @@ GraphicsStateGuardian:: ~GraphicsStateGuardian() { } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_supports_multisample +// Access: Published, Virtual +// Description: Returns true if this particular GSG supports using +// the multisample bits to provide antialiasing, and +// also supports M_multisample and M_multisample_mask +// transparency modes. If this is not true for a +// particular GSG, Panda will map the M_multisample +// modes to M_binary. +// +// This method is declared virtual solely so that it can +// be queried from cullResult.cxx. +//////////////////////////////////////////////////////////////////// +bool GraphicsStateGuardian:: +get_supports_multisample() const { + return _supports_multisample; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::reset // Access: Public, Virtual diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 1563081271..fb464bb246 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -84,6 +84,8 @@ PUBLISHED: INLINE int get_max_texture_stages() const; INLINE bool get_copy_texture_inverted() const; + virtual bool get_supports_multisample() const; + INLINE bool get_supports_generate_mipmap() const; public: INLINE bool set_scene(SceneSetup *scene_setup); @@ -280,6 +282,8 @@ protected: PT(PreparedGraphicsObjects) _prepared_objects; int _max_texture_stages; bool _copy_texture_inverted; + bool _supports_multisample; + bool _supports_generate_mipmap; public: // Statistics diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx index b9f78e6d18..0a017aefac 100644 --- a/panda/src/display/parasiteBuffer.cxx +++ b/panda/src/display/parasiteBuffer.cxx @@ -44,8 +44,6 @@ ParasiteBuffer(GraphicsOutput *host, const string &name, << " on " << _host->get_name() << "\n"; } - setup_copy_texture(_name); - _x_size = x_size; _y_size = y_size; _has_size = true; @@ -53,6 +51,8 @@ ParasiteBuffer(GraphicsOutput *host, const string &name, _is_valid = true; + setup_copy_texture(_name); + nassertv(_x_size <= host->get_x_size() && _y_size <= host->get_y_size()); } diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx index 4527e1be88..0118701d95 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx @@ -4590,7 +4590,6 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, break; case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: case TransparencyAttrib::M_multisample: case TransparencyAttrib::M_multisample_mask: case TransparencyAttrib::M_dual: diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 9ba2cf8d94..a5a3baca02 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -4316,7 +4316,6 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, break; case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: case TransparencyAttrib::M_multisample: case TransparencyAttrib::M_multisample_mask: case TransparencyAttrib::M_dual: diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 721c3f7496..40034a1eae 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -4319,7 +4319,6 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, break; case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: case TransparencyAttrib::M_multisample: case TransparencyAttrib::M_multisample_mask: case TransparencyAttrib::M_dual: diff --git a/panda/src/express/ordered_vector.I b/panda/src/express/ordered_vector.I index af9f6406a0..a8ba4fd93e 100644 --- a/panda/src/express/ordered_vector.I +++ b/panda/src/express/ordered_vector.I @@ -616,7 +616,7 @@ sort_unique() { template INLINE void ordered_vector:: sort_nonunique() { - sort(begin(), end(), _compare); + stable_sort(begin(), end(), _compare); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.I b/panda/src/glstuff/glGraphicsStateGuardian_src.I index 5e9964d8b2..f620969d74 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.I +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.I @@ -191,23 +191,15 @@ enable_scissor(bool val) //////////////////////////////////////////////////////////////////// INLINE void CLP(GraphicsStateGuardian):: enable_multisample_alpha_one(bool val) { - if (_multisample_alpha_one_enabled != val) { - _multisample_alpha_one_enabled = val; -#ifdef GL_SAMPLE_ALPHA_TO_ONE_SGIS - if (val) { -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glEnable(GL_SAMPLE_ALPHA_TO_ONE_SGIS)" << endl; -#endif - GLP(Enable)(GL_SAMPLE_ALPHA_TO_ONE_SGIS); - } else { -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glDisable(GL_SAMPLE_ALPHA_TO_ONE_SGIS)" << endl; -#endif - GLP(Disable)(GL_SAMPLE_ALPHA_TO_ONE_SGIS); + if (_supports_multisample) { + if (_multisample_alpha_one_enabled != val) { + _multisample_alpha_one_enabled = val; + if (val) { + GLP(Enable)(GL_SAMPLE_ALPHA_TO_ONE); + } else { + GLP(Disable)(GL_SAMPLE_ALPHA_TO_ONE); + } } -#endif // GL_SAMPLE_ALPHA_TO_ONE_SGIS } } @@ -220,21 +212,11 @@ INLINE void CLP(GraphicsStateGuardian):: enable_multisample_alpha_mask(bool val) { if (_multisample_alpha_mask_enabled != val) { _multisample_alpha_mask_enabled = val; -#ifdef GL_SAMPLE_ALPHA_TO_MASK_SGIS if (val) { -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glEnable(GL_SAMPLE_ALPHA_TO_MASK_SGIS)" << endl; -#endif - GLP(Enable)(GL_SAMPLE_ALPHA_TO_MASK_SGIS); + GLP(Enable)(GL_SAMPLE_ALPHA_TO_COVERAGE); } else { -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glDisable(GL_SAMPLE_ALPHA_TO_MASK_SGIS)" << endl; -#endif - GLP(Disable)(GL_SAMPLE_ALPHA_TO_MASK_SGIS); + GLP(Disable)(GL_SAMPLE_ALPHA_TO_COVERAGE); } -#endif // GL_SAMPLE_ALPHA_TO_MASK_SGIS } } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 2346cce00f..87c2584fd2 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -4345,15 +4345,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, break; case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: case TransparencyAttrib::M_dual: - // Should we really have an "alpha" and an "alpha_sorted" - // mode, like Performer does? (The difference is that - // "alpha_sorted" is with the write to the depth buffer - // disabled.) Or should we just use the separate depth write - // transition to control this? Doing it implicitly requires a - // bit more logic here and in the state management; for now we - // require the user to explicitly turn off the depth write. enable_multisample_alpha_one(false); enable_multisample_alpha_mask(false); enable_blend(true); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 2579854ce9..173b0b103e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -281,8 +281,6 @@ protected: public: bool _supports_bgr; - bool _supports_multisample; - bool _supports_generate_mipmap; bool _supports_multitexture; PFNGLACTIVETEXTUREPROC _glActiveTexture; diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index cae2456091..ae45611c93 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -105,6 +105,7 @@ clear() { _view_vector.set(0.0f, 1.0f, 0.0f); _up_vector.set(0.0f, 0.0f, 1.0f); _iod_offset = 0.0f; + _keystone.set(0.0f, 0.0f, 0.0f); _user_flags = 0; _comp_flags = CF_fov; @@ -574,6 +575,66 @@ get_view_mat() const { return _lens_mat; } +//////////////////////////////////////////////////////////////////// +// Function: Lens::clear_view_mat +// Access: Published +// Description: Resets the lens transform to identity. +//////////////////////////////////////////////////////////////////// +void Lens:: +clear_view_mat() { + _lens_mat = LMatrix4f::ident_mat(); + adjust_user_flags(0, UF_view_vector | UF_view_hpr | UF_iod_offset | UF_view_mat); + adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset, + CF_lens_mat); + throw_change_event(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_keystone +// Access: Published +// Description: Indicates the ratio of keystone correction to perform +// on the lens, in each of three axes. This will build +// a special non-affine scale factor into the projection +// matrix that will compensate for keystoning of a +// projected image; this can be used to compensate for a +// projector that for physical reasons cannot be aimed +// directly at it screen. The default value of 0, 0, 0 +// indicates no keystone correction; specify a small +// value (usually in the range -1 .. 1) in one of the +// three axes to generate a keystone correction in that +// axis. +//////////////////////////////////////////////////////////////////// +void Lens:: +set_keystone(const LVecBase3f &keystone) { + _keystone = keystone; + adjust_user_flags(0, UF_keystone); + adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0); + throw_change_event(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_keystone +// Access: Published +// Description: Returns the direction in which the lens is facing. +//////////////////////////////////////////////////////////////////// +const LVecBase3f &Lens:: +get_keystone() const { + return _keystone; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::clear_keystone +// Access: Published +// Description: Resets the lens transform to identity. +//////////////////////////////////////////////////////////////////// +void Lens:: +clear_keystone() { + _keystone = LVecBase3f(0.0f, 0.0f, 0.0f); + adjust_user_flags(UF_keystone, 0); + adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0); + throw_change_event(); +} + //////////////////////////////////////////////////////////////////// // Function: Lens::set_frustum_from_corners // Access: Published @@ -1098,21 +1159,25 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point) { LVecBase4f full(point2d[0], point2d[1], -1.0f, 1.0f); full = projection_mat_inv.xform(full); - if (full[3] == 0.0f) { - return false; - } - float recip_full3 = 1.0f/full[3]; - near_point.set(full[0] * recip_full3, full[1] * recip_full3, full[2] * recip_full3); + float recip_full3 = 1.0f / max(full[3], 0.001f); + near_point.set(full[0] * recip_full3, + full[1] * recip_full3, + full[2] * recip_full3); } { LVecBase4f full(point2d[0], point2d[1], 1.0f, 1.0f); full = projection_mat_inv.xform(full); - if (full[3] == 0.0f) { - return false; - } - float recip_full3 = 1.0f/full[3]; - far_point.set(full[0] * recip_full3, full[1] * recip_full3, full[2] * recip_full3); + + // We can truncate the weight factor at near 0. If it goes too + // close to zero, or becomes negative, the far plane moves out + // past infinity and comes back in behind the lens, which is just + // crazy. Truncating it to zero keeps the far plane from moving + // too far out. + float recip_full3 = 1.0f / max(full[3], 0.001f); + far_point.set(full[0] * recip_full3, + full[1] * recip_full3, + full[2] * recip_full3); } return true; } @@ -1376,12 +1441,6 @@ compute_film_mat() { LVecBase2f film_size = get_film_size(); LVector2f film_offset = get_film_offset(); - /* this line triggers a VC7 opt bug, so explicitly set matrix below instead - _film_mat = - LMatrix4f::translate_mat(-film_offset[0], -film_offset[1], 0.0f) * - LMatrix4f::scale_mat(2.0f / film_size[0], 2.0f / film_size[1], 1.0f); - */ - float scale_x = 2.0f / film_size[0]; float scale_y = 2.0f / film_size[1]; _film_mat.set(scale_x, 0.0f, 0.0f, 0.0f, @@ -1389,6 +1448,13 @@ compute_film_mat() { 0.0f, 0.0f, 1.0f, 0.0f, -film_offset[0] * scale_x, -film_offset[1] * scale_y, 0.0f, 1.0f); + if ((_user_flags & UF_keystone) != 0) { + _film_mat = LMatrix4f(csqrt(1.0f - _keystone[0] * _keystone[0]), 0.0f, 0.0f, _keystone[0], + 0.0f, csqrt(1.0f - _keystone[1] * _keystone[1]), 0.0f, _keystone[1], + 0.0f, 0.0f, csqrt(1.0f - _keystone[2] * _keystone[2]), _keystone[2], + 0.0f, 0.0f, 0.0f, 1.0f) * _film_mat; + } + adjust_comp_flags(CF_film_mat_inv, CF_film_mat); } diff --git a/panda/src/gobj/lens.h b/panda/src/gobj/lens.h index 64f8c4d27c..543400199a 100644 --- a/panda/src/gobj/lens.h +++ b/panda/src/gobj/lens.h @@ -110,6 +110,11 @@ PUBLISHED: void set_view_mat(const LMatrix4f &view_mat); const LMatrix4f &get_view_mat() const; + void clear_view_mat(); + + void set_keystone(const LVecBase3f &keystone); + const LVecBase3f &get_keystone() const; + void clear_keystone(); // These flags are passed in as the last parameter to control the // behavior of set_frustum_from_corners(). See the documentation @@ -197,6 +202,7 @@ protected: LVecBase3f _view_hpr; LVector3f _view_vector, _up_vector; float _iod_offset; + LVecBase3f _keystone; LMatrix4f _film_mat, _film_mat_inv; LMatrix4f _lens_mat, _lens_mat_inv; @@ -214,6 +220,7 @@ protected: UF_view_vector = 0x0080, UF_iod_offset = 0x0100, UF_view_mat = 0x0200, + UF_keystone = 0x0400, }; enum CompFlags { diff --git a/panda/src/grutil/Sources.pp b/panda/src/grutil/Sources.pp index 5d0f401172..039ec15571 100644 --- a/panda/src/grutil/Sources.pp +++ b/panda/src/grutil/Sources.pp @@ -24,7 +24,8 @@ #define INSTALL_HEADERS \ cardMaker.I cardMaker.h \ frameRateMeter.I frameRateMeter.h \ - lineSegs.I lineSegs.h + lineSegs.I lineSegs.h \ + multitexReducer.I multitexReducer.h #define IGATESCAN all diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index ecd46ab4b2..d0ca3c3e71 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -418,11 +418,22 @@ scan_geom_node(GeomNode *node, const RenderState *state, int num_stages = ta->get_num_on_stages(); for (int si = 0; si < num_stages; si++) { TextureStage *stage = ta->get_on_stage(si); - - stage_list.push_back(StageInfo(stage, ta, tma)); + Texture *tex = ta->get_on_texture(stage); + PixelBuffer *tex_pbuffer = tex->_pbuffer; + if (tex_pbuffer != (PixelBuffer *)NULL && + tex_pbuffer->get_xsize() != 0 && + tex_pbuffer->get_ysize() != 0) { + stage_list.push_back(StageInfo(stage, ta, tma)); + + } else { + grutil_cat.info() + << "Ignoring invalid texture stage " << stage->get_name() << "\n"; + } } - record_stage_list(stage_list, GeomInfo(state, geom_net_state, node, gi)); + if (stage_list.size() >= 2) { + record_stage_list(stage_list, GeomInfo(state, geom_net_state, node, gi)); + } } } } diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index d1a7196dbc..7ac8c47a89 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -103,6 +103,8 @@ class Lens; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA GraphicsStateGuardianBase : public TypedWritableReferenceCount { public: + virtual bool get_supports_multisample() const=0; + // These functions will be queried by the GeomIssuer to determine if // it should issue normals, texcoords, and/or colors, based on the // GSG's current state. diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index 8c7558e85b..52c1e000f5 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -97,6 +97,15 @@ add_object(CullableObject *object) { object->_state = state->compose(get_binary_state()); break; + case TransparencyAttrib::M_multisample: + case TransparencyAttrib::M_multisample_mask: + // The multisample modes are implemented using M_binary if the + // GSG in use doesn't support multisample. + if (!_gsg->get_supports_multisample()) { + object->_state = state->compose(get_binary_state()); + } + break; + case TransparencyAttrib::M_dual: if (m_dual) { // M_dual is implemented by drawing the opaque parts first, diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 464cc703c9..b8a8630ca9 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1371,7 +1371,6 @@ determine_bin_index() { if (trans != (const TransparencyAttrib *)NULL) { switch (trans->get_mode()) { case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: case TransparencyAttrib::M_dual: // These transparency modes require special back-to-front sorting. bin_name = "transparent"; diff --git a/panda/src/pgraph/texMatrixAttrib.cxx b/panda/src/pgraph/texMatrixAttrib.cxx index b610400c47..799024fc14 100644 --- a/panda/src/pgraph/texMatrixAttrib.cxx +++ b/panda/src/pgraph/texMatrixAttrib.cxx @@ -257,7 +257,7 @@ compare_to_impl(const RenderAttrib *other) const { } } - if (bi != _stages.end()) { + if (bi != ta->_stages.end()) { // a ran out first; b was longer. return -1; } diff --git a/panda/src/pgraph/transparencyAttrib.cxx b/panda/src/pgraph/transparencyAttrib.cxx index 53de1e7f00..c97c73db3e 100644 --- a/panda/src/pgraph/transparencyAttrib.cxx +++ b/panda/src/pgraph/transparencyAttrib.cxx @@ -68,10 +68,6 @@ output(ostream &out) const { out << "alpha"; break; - case M_alpha_sorted: - out << "alpha sorted"; - break; - case M_multisample: out << "multisample"; break; diff --git a/panda/src/pgraph/transparencyAttrib.h b/panda/src/pgraph/transparencyAttrib.h index 50419beb1f..de658a8072 100644 --- a/panda/src/pgraph/transparencyAttrib.h +++ b/panda/src/pgraph/transparencyAttrib.h @@ -31,8 +31,8 @@ class FactoryParams; // setting an alpha component to non-1 does not in // itself make an object transparent; you must also // enable transparency mode with a suitable -// TransparencyTransition. Similarly, it is wasteful to -// render an object with a TransparencyTransition in +// TransparencyAttrib. Similarly, it is wasteful to +// render an object with a TransparencyAttrib in // effect unless you actually want it to be at least // partially transparent (and it has alpha components // less than 1). @@ -40,13 +40,13 @@ class FactoryParams; class EXPCL_PANDA TransparencyAttrib : public RenderAttrib { PUBLISHED: enum Mode { - M_none, // No transparency in effect. - M_alpha, // Writes to depth buffer of transp objects disabled - M_alpha_sorted, // Assumes transp objects are depth sorted - M_multisample, // Source alpha values modified to 1.0 before writing - M_multisample_mask, // Source alpha values not modified - M_binary, // Only writes pixels with alpha = 1.0 - M_dual, // 2-pass: draws opaque, then draws transparent + M_none, // No transparency. + M_alpha, // Normal transparency, panda will sort back-to-front. + M_notused, // Unused placeholder. Do not use this. + M_multisample, // Uses ms buffer, alpha values modified to 1.0. + M_multisample_mask, // Uses ms buffer, alpha values not modified. + M_binary, // Only writes pixels with alpha >= 0.5. + M_dual, // opaque parts first, then sorted transparent parts. }; private: diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index 235cb8fc6e..d898f09bb3 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -20,6 +20,7 @@ #include "textNode.h" #include "multitexReducer.h" #include "configVariableBool.h" +#include "texturePool.h" #ifndef HAVE_GETOPT #include "gnu_getopt.h" @@ -108,24 +109,50 @@ event_2(CPT_Event event, void *) { void event_0(CPT_Event event, void *) { // 0: run hacky test. - static bool first = true; + static int count = 0; - if (first) { + static PT(TextureStage) ts; + if (ts == (TextureStage *)NULL) { + ts = new TextureStage("ts"); + } + + NodePath models = framework.get_models(); + + if (count == 0) { cerr << "applying scale\n"; - framework.get_models().set_color_scale(0.7, 0.7, 0.1, 1.0); - first = false; + models.set_color_scale(0.7, 0.7, 0.1, 1.0); } else { cerr << "flattening\n"; MultitexReducer mr; mr.set_use_geom(true); - - mr.scan(framework.get_models()); + mr.scan(models); WindowFramework *wf = framework.get_window(0); GraphicsWindow *win = wf->get_graphics_window(); mr.flatten(win); + + if (count > 1) { + PT(Texture) tex = TexturePool::load_texture("maps/cmss12.rgb"); + if (tex != (Texture *)NULL) { + cerr << "Reapplying\n"; + + ts->set_mode(TextureStage::M_decal); + models.set_texture(ts, tex); + + if (count > 3 && (count % 2) == 1) { + cerr << "Reflattening\n"; + MultitexReducer mr; + mr.scan(models); + + WindowFramework *wf = framework.get_window(0); + GraphicsWindow *win = wf->get_graphics_window(); + mr.flatten(win); + } + } + } } + count++; } void