mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
glx support for multisample
This commit is contained in:
parent
03dfb6dea0
commit
8bbda67e2a
@ -78,6 +78,7 @@ GraphicsEngine(Pipeline *pipeline) :
|
|||||||
_frame_buffer_properties.set_frame_buffer_mode
|
_frame_buffer_properties.set_frame_buffer_mode
|
||||||
(FrameBufferProperties::FM_rgba |
|
(FrameBufferProperties::FM_rgba |
|
||||||
FrameBufferProperties::FM_double_buffer |
|
FrameBufferProperties::FM_double_buffer |
|
||||||
|
FrameBufferProperties::FM_multisample |
|
||||||
FrameBufferProperties::FM_depth);
|
FrameBufferProperties::FM_depth);
|
||||||
|
|
||||||
set_threading_model(GraphicsThreadingModel(threading_model));
|
set_threading_model(GraphicsThreadingModel(threading_model));
|
||||||
|
@ -44,21 +44,48 @@ on automatically for a particular model if it detects textures that
|
|||||||
appear to be cutouts of the appropriate nature, which is another
|
appear to be cutouts of the appropriate nature, which is another
|
||||||
reason to use egg-palettize if you are not using it already.
|
reason to use egg-palettize if you are not using it already.
|
||||||
|
|
||||||
Second, an easy thing to do is to chop up one or both competing models
|
If you don't use egg-palettize (you really should, you know), you can
|
||||||
into smaller pieces, each of which can be sorted independently by
|
just hand-edit the egg files to put the line:
|
||||||
Panda. For instance, you can split one big polygon into a grid of
|
|
||||||
little polygons, and the sorting is more likely to be accurate for
|
|
||||||
each piece (because the center of the bounding volume is closer to the
|
|
||||||
pixels). You can draw a picture to see how this works. In order to
|
|
||||||
do this properly, you can't just make it one big mesh of small
|
|
||||||
polygons, since Panda will make a mesh into a single Geom of
|
|
||||||
tristrips; instead, it needs to be separate meshes, so that each one
|
|
||||||
will become its own Geom. Obviously, this is slightly more expensive
|
|
||||||
too, since you are introducing additional vertices and adding more
|
|
||||||
objects to the sort list; so you don't want to go too crazy with the
|
|
||||||
smallness of your polygons.
|
|
||||||
|
|
||||||
A third option is simply to disable the depth write on your
|
<Scalar> alpha { dual }
|
||||||
|
|
||||||
|
within the <Texture> reference for the textures in question.
|
||||||
|
|
||||||
|
A second easy option is to use M_multisample transparency, which
|
||||||
|
doesn't have any ordering issues at all, but it only looks good on
|
||||||
|
very high-end cards that have special multisample bits to support
|
||||||
|
full-screen antialiasing. Also, at the present it only looks good on
|
||||||
|
these high-end cards in OpenGL mode (since our pandadx drivers don't
|
||||||
|
support M_multisample explicitly right now). But if M_multisample is
|
||||||
|
not supported by a particular hardware or panda driver, it
|
||||||
|
automatically falls back to M_binary, which also doesn't have any
|
||||||
|
ordering issues, but it always has jaggy edges along the cutout edge.
|
||||||
|
This only works well on texture images that represent cutouts, like
|
||||||
|
M_dual, above.
|
||||||
|
|
||||||
|
If you use egg-palettize, you can engage M_multisample mode by putting
|
||||||
|
the keyword "ms" on the line with the texture(s). Without
|
||||||
|
egg-palettize, hand-edit the egg files to put the line:
|
||||||
|
|
||||||
|
<Scalar> alpha { ms }
|
||||||
|
|
||||||
|
within the <Texture> reference for the textures in question.
|
||||||
|
|
||||||
|
A third easy option is to chop up one or both competing models into
|
||||||
|
smaller pieces, each of which can be sorted independently by Panda.
|
||||||
|
For instance, you can split one big polygon into a grid of little
|
||||||
|
polygons, and the sorting is more likely to be accurate for each piece
|
||||||
|
(because the center of the bounding volume is closer to the pixels).
|
||||||
|
You can draw a picture to see how this works. In order to do this
|
||||||
|
properly, you can't just make it one big mesh of small polygons, since
|
||||||
|
Panda will make a mesh into a single Geom of tristrips; instead, it
|
||||||
|
needs to be separate meshes, so that each one will become its own
|
||||||
|
Geom. Obviously, this is slightly more expensive too, since you are
|
||||||
|
introducing additional vertices and adding more objects to the sort
|
||||||
|
list; so you don't want to go too crazy with the smallness of your
|
||||||
|
polygons.
|
||||||
|
|
||||||
|
A fourth option is simply to disable the depth write on your
|
||||||
transparent objects. This is most effective when you are trying to
|
transparent objects. This is most effective when you are trying to
|
||||||
represent something that is barely visible, like glass or a soap
|
represent something that is barely visible, like glass or a soap
|
||||||
bubble. Doing this doesn't improve the likelihood of correct sorting,
|
bubble. Doing this doesn't improve the likelihood of correct sorting,
|
||||||
|
@ -89,19 +89,13 @@ report_my_errors(int line, const char *source_file) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void CLP(GraphicsStateGuardian)::
|
INLINE void CLP(GraphicsStateGuardian)::
|
||||||
enable_multisample(bool val) {
|
enable_multisample(bool val) {
|
||||||
if (_multisample_enabled != val) {
|
if (_multisample_enabled != val && _supports_multisample) {
|
||||||
_multisample_enabled = val;
|
_multisample_enabled = val;
|
||||||
if (val) {
|
if (val) {
|
||||||
if (_supports_multisample) {
|
|
||||||
GLP(Enable)(GL_MULTISAMPLE);
|
GLP(Enable)(GL_MULTISAMPLE);
|
||||||
}
|
|
||||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
|
||||||
} else {
|
} else {
|
||||||
if (_supports_multisample) {
|
|
||||||
GLP(Disable)(GL_MULTISAMPLE);
|
GLP(Disable)(GL_MULTISAMPLE);
|
||||||
}
|
}
|
||||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +110,7 @@ enable_line_smooth(bool val) {
|
|||||||
_line_smooth_enabled = val;
|
_line_smooth_enabled = val;
|
||||||
if (val) {
|
if (val) {
|
||||||
GLP(Enable)(GL_LINE_SMOOTH);
|
GLP(Enable)(GL_LINE_SMOOTH);
|
||||||
GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_FASTEST);
|
GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
} else {
|
} else {
|
||||||
GLP(Disable)(GL_LINE_SMOOTH);
|
GLP(Disable)(GL_LINE_SMOOTH);
|
||||||
}
|
}
|
||||||
@ -137,7 +131,6 @@ enable_point_smooth(bool val) {
|
|||||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||||
} else {
|
} else {
|
||||||
GLP(Disable)(GL_POINT_SMOOTH);
|
GLP(Disable)(GL_POINT_SMOOTH);
|
||||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,6 +311,7 @@ reset() {
|
|||||||
|
|
||||||
_supports_bgr = has_extension("GL_EXT_bgra");
|
_supports_bgr = has_extension("GL_EXT_bgra");
|
||||||
_supports_multisample = has_extension("GL_ARB_multisample");
|
_supports_multisample = has_extension("GL_ARB_multisample");
|
||||||
|
|
||||||
_supports_generate_mipmap =
|
_supports_generate_mipmap =
|
||||||
has_extension("GL_SGIS_generate_mipmap") || is_at_least_version(1, 4);
|
has_extension("GL_SGIS_generate_mipmap") || is_at_least_version(1, 4);
|
||||||
|
|
||||||
@ -397,6 +398,23 @@ reset() {
|
|||||||
_mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
|
_mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_supports_multisample) {
|
||||||
|
GLint sample_buffers;
|
||||||
|
GLP(GetIntegerv)(GL_SAMPLE_BUFFERS, &sample_buffers);
|
||||||
|
if (sample_buffers != 1) {
|
||||||
|
_supports_multisample = false;
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< "Selected frame buffer does not provide antialiasing support.\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< "Selected frame buffer provides antialiasing support.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
_buffer_mask = 0;
|
_buffer_mask = 0;
|
||||||
@ -458,6 +476,7 @@ reset() {
|
|||||||
|
|
||||||
// Antialiasing.
|
// Antialiasing.
|
||||||
enable_line_smooth(false);
|
enable_line_smooth(false);
|
||||||
|
enable_point_smooth(false);
|
||||||
enable_multisample(true);
|
enable_multisample(true);
|
||||||
|
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
|
@ -430,7 +430,7 @@ choose_fbconfig(FrameBufferProperties &properties) const {
|
|||||||
// Now update our framebuffer_mode and bit depth appropriately.
|
// Now update our framebuffer_mode and bit depth appropriately.
|
||||||
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
||||||
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
||||||
depth_size, stencil_size;
|
depth_size, stencil_size, samples;
|
||||||
|
|
||||||
glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &render_mode);
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &render_mode);
|
||||||
glXGetFBConfigAttrib(_display, fbconfig, GLX_DOUBLEBUFFER, &double_buffer);
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_DOUBLEBUFFER, &double_buffer);
|
||||||
@ -445,6 +445,7 @@ choose_fbconfig(FrameBufferProperties &properties) const {
|
|||||||
glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
||||||
glXGetFBConfigAttrib(_display, fbconfig, GLX_DEPTH_SIZE, &depth_size);
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_DEPTH_SIZE, &depth_size);
|
||||||
glXGetFBConfigAttrib(_display, fbconfig, GLX_STENCIL_SIZE, &stencil_size);
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_STENCIL_SIZE, &stencil_size);
|
||||||
|
glXGetFBConfigAttrib(_display, fbconfig, GLX_SAMPLES, &samples);
|
||||||
|
|
||||||
frame_buffer_mode = 0;
|
frame_buffer_mode = 0;
|
||||||
if (double_buffer) {
|
if (double_buffer) {
|
||||||
@ -468,6 +469,9 @@ choose_fbconfig(FrameBufferProperties &properties) const {
|
|||||||
if (ared_size + agreen_size + ablue_size != 0) {
|
if (ared_size + agreen_size + ablue_size != 0) {
|
||||||
frame_buffer_mode |= FrameBufferProperties::FM_accum;
|
frame_buffer_mode |= FrameBufferProperties::FM_accum;
|
||||||
}
|
}
|
||||||
|
if (samples != 0) {
|
||||||
|
frame_buffer_mode |= FrameBufferProperties::FM_multisample;
|
||||||
|
}
|
||||||
|
|
||||||
properties.set_frame_buffer_mode(frame_buffer_mode);
|
properties.set_frame_buffer_mode(frame_buffer_mode);
|
||||||
properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
|
properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
|
||||||
@ -482,6 +486,7 @@ choose_fbconfig(FrameBufferProperties &properties) const {
|
|||||||
<< ablue_size << " " << aalpha_size << endl
|
<< ablue_size << " " << aalpha_size << endl
|
||||||
<< " Depth: " << depth_size << endl
|
<< " Depth: " << depth_size << endl
|
||||||
<< " Stencil: " << stencil_size << endl
|
<< " Stencil: " << stencil_size << endl
|
||||||
|
<< " Samples: " << samples << endl
|
||||||
<< " DoubleBuffer? " << double_buffer << endl
|
<< " DoubleBuffer? " << double_buffer << endl
|
||||||
<< " Stereo? " << stereo << endl;
|
<< " Stereo? " << stereo << endl;
|
||||||
}
|
}
|
||||||
@ -578,14 +583,13 @@ try_for_fbconfig(int framebuffer_mode,
|
|||||||
attrib_list[n++] = want_color_component_bits;
|
attrib_list[n++] = want_color_component_bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (framebuffer_mode & FrameBufferProperties::FM_multisample) {
|
if (framebuffer_mode & FrameBufferProperties::FM_multisample) {
|
||||||
glxdisplay_cat.debug(false) << " MULTISAMPLE";
|
glxdisplay_cat.debug(false) << " MULTISAMPLE";
|
||||||
attrib_list[n++] = GLX_SAMPLES_SGIS;
|
attrib_list[n++] = GLX_SAMPLES;
|
||||||
// We decide 4 is minimum number of samples
|
// We decide 4 is minimum number of samples
|
||||||
attrib_list[n++] = 4;
|
attrib_list[n++] = 4;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Terminate the list
|
// Terminate the list
|
||||||
nassertr(n < max_attrib_list, None);
|
nassertr(n < max_attrib_list, None);
|
||||||
@ -650,16 +654,6 @@ choose_visual(FrameBufferProperties &properties) const {
|
|||||||
want_color_bits = properties.get_color_bits();
|
want_color_bits = properties.get_color_bits();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (frame_buffer_mode & FrameBufferProperties::FM_multisample) {
|
|
||||||
if (!glx_supports("GLX_SGIS_multisample")) {
|
|
||||||
glxdisplay_cat.info()
|
|
||||||
<< "multisample not supported by this glx implementation.\n";
|
|
||||||
frame_buffer_mode &= ~FrameBufferProperties::FM_multisample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
XVisualInfo *visual =
|
XVisualInfo *visual =
|
||||||
try_for_visual(frame_buffer_mode, want_depth_bits, want_color_bits);
|
try_for_visual(frame_buffer_mode, want_depth_bits, want_color_bits);
|
||||||
|
|
||||||
@ -778,7 +772,7 @@ choose_visual(FrameBufferProperties &properties) const {
|
|||||||
// Now update our framebuffer_mode and bit depth appropriately.
|
// Now update our framebuffer_mode and bit depth appropriately.
|
||||||
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
|
||||||
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
|
||||||
depth_size, stencil_size;
|
depth_size, stencil_size, samples;
|
||||||
|
|
||||||
glXGetConfig(_display, visual, GLX_RGBA, &render_mode);
|
glXGetConfig(_display, visual, GLX_RGBA, &render_mode);
|
||||||
glXGetConfig(_display, visual, GLX_DOUBLEBUFFER, &double_buffer);
|
glXGetConfig(_display, visual, GLX_DOUBLEBUFFER, &double_buffer);
|
||||||
@ -793,6 +787,7 @@ choose_visual(FrameBufferProperties &properties) const {
|
|||||||
glXGetConfig(_display, visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
glXGetConfig(_display, visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
|
||||||
glXGetConfig(_display, visual, GLX_DEPTH_SIZE, &depth_size);
|
glXGetConfig(_display, visual, GLX_DEPTH_SIZE, &depth_size);
|
||||||
glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &stencil_size);
|
glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &stencil_size);
|
||||||
|
glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &samples);
|
||||||
|
|
||||||
frame_buffer_mode = 0;
|
frame_buffer_mode = 0;
|
||||||
if (double_buffer) {
|
if (double_buffer) {
|
||||||
@ -816,6 +811,9 @@ choose_visual(FrameBufferProperties &properties) const {
|
|||||||
if (ared_size + agreen_size + ablue_size != 0) {
|
if (ared_size + agreen_size + ablue_size != 0) {
|
||||||
frame_buffer_mode |= FrameBufferProperties::FM_accum;
|
frame_buffer_mode |= FrameBufferProperties::FM_accum;
|
||||||
}
|
}
|
||||||
|
if (samples != 0) {
|
||||||
|
frame_buffer_mode |= FrameBufferProperties::FM_multisample;
|
||||||
|
}
|
||||||
|
|
||||||
properties.set_frame_buffer_mode(frame_buffer_mode);
|
properties.set_frame_buffer_mode(frame_buffer_mode);
|
||||||
properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
|
properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
|
||||||
@ -830,6 +828,7 @@ choose_visual(FrameBufferProperties &properties) const {
|
|||||||
<< ablue_size << " " << aalpha_size << endl
|
<< ablue_size << " " << aalpha_size << endl
|
||||||
<< " Depth: " << depth_size << endl
|
<< " Depth: " << depth_size << endl
|
||||||
<< " Stencil: " << stencil_size << endl
|
<< " Stencil: " << stencil_size << endl
|
||||||
|
<< " Samples: " << samples << endl
|
||||||
<< " DoubleBuffer? " << double_buffer << endl
|
<< " DoubleBuffer? " << double_buffer << endl
|
||||||
<< " Stereo? " << stereo << endl;
|
<< " Stereo? " << stereo << endl;
|
||||||
}
|
}
|
||||||
@ -911,14 +910,12 @@ try_for_visual(int framebuffer_mode,
|
|||||||
attrib_list[n++] = want_color_component_bits;
|
attrib_list[n++] = want_color_component_bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (framebuffer_mode & FrameBufferProperties::FM_multisample) {
|
if (framebuffer_mode & FrameBufferProperties::FM_multisample) {
|
||||||
glxdisplay_cat.debug(false) << " MULTISAMPLE";
|
glxdisplay_cat.debug(false) << " MULTISAMPLE";
|
||||||
attrib_list[n++] = GLX_SAMPLES_SGIS;
|
attrib_list[n++] = GLX_SAMPLES;
|
||||||
// We decide 4 is minimum number of samples
|
// We decide 4 is minimum number of samples
|
||||||
attrib_list[n++] = 4;
|
attrib_list[n++] = 4;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Terminate the list
|
// Terminate the list
|
||||||
nassertr(n < max_attrib_list, NULL);
|
nassertr(n < max_attrib_list, NULL);
|
||||||
|
@ -730,6 +730,12 @@ make_texture_layer(const NodePath &render,
|
|||||||
|
|
||||||
geom.set_texture(stage_info._tex);
|
geom.set_texture(stage_info._tex);
|
||||||
geom.node()->set_attrib(cba);
|
geom.node()->set_attrib(cba);
|
||||||
|
|
||||||
|
if (grutil_cat.is_debug()) {
|
||||||
|
GeomNode *geom_node;
|
||||||
|
DCAST_INTO_V(geom_node, geom.node());
|
||||||
|
geom_node->write_verbose(grutil_cat.debug(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user