mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
initial experiments with keystone correction, revisit M_multisample transparency, robustify MultitexReducer
This commit is contained in:
parent
12821e21f5
commit
b1375f32a4
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -616,7 +616,7 @@ sort_unique() {
|
||||
template<class Key, class Compare>
|
||||
INLINE void ordered_vector<Key, Compare>::
|
||||
sort_nonunique() {
|
||||
sort(begin(), end(), _compare);
|
||||
stable_sort(begin(), end(), _compare);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -281,8 +281,6 @@ protected:
|
||||
|
||||
public:
|
||||
bool _supports_bgr;
|
||||
bool _supports_multisample;
|
||||
bool _supports_generate_mipmap;
|
||||
|
||||
bool _supports_multitexture;
|
||||
PFNGLACTIVETEXTUREPROC _glActiveTexture;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user