glx support for multisample

This commit is contained in:
David Rose 2004-12-17 23:08:58 +00:00
parent 03dfb6dea0
commit 8bbda67e2a
6 changed files with 86 additions and 43 deletions

View File

@ -78,6 +78,7 @@ GraphicsEngine(Pipeline *pipeline) :
_frame_buffer_properties.set_frame_buffer_mode
(FrameBufferProperties::FM_rgba |
FrameBufferProperties::FM_double_buffer |
FrameBufferProperties::FM_multisample |
FrameBufferProperties::FM_depth);
set_threading_model(GraphicsThreadingModel(threading_model));

View File

@ -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
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
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.
If you don't use egg-palettize (you really should, you know), you can
just hand-edit the egg files to put the line:
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
represent something that is barely visible, like glass or a soap
bubble. Doing this doesn't improve the likelihood of correct sorting,

View File

@ -89,18 +89,12 @@ report_my_errors(int line, const char *source_file) {
////////////////////////////////////////////////////////////////////
INLINE void CLP(GraphicsStateGuardian)::
enable_multisample(bool val) {
if (_multisample_enabled != val) {
if (_multisample_enabled != val && _supports_multisample) {
_multisample_enabled = val;
if (val) {
if (_supports_multisample) {
GLP(Enable)(GL_MULTISAMPLE);
}
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
GLP(Enable)(GL_MULTISAMPLE);
} else {
if (_supports_multisample) {
GLP(Disable)(GL_MULTISAMPLE);
}
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
GLP(Disable)(GL_MULTISAMPLE);
}
}
}
@ -116,7 +110,7 @@ enable_line_smooth(bool val) {
_line_smooth_enabled = val;
if (val) {
GLP(Enable)(GL_LINE_SMOOTH);
GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_FASTEST);
GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_NICEST);
} else {
GLP(Disable)(GL_LINE_SMOOTH);
}
@ -137,7 +131,6 @@ enable_point_smooth(bool val) {
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
} else {
GLP(Disable)(GL_POINT_SMOOTH);
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
}
}
}

View File

@ -311,6 +311,7 @@ reset() {
_supports_bgr = has_extension("GL_EXT_bgra");
_supports_multisample = has_extension("GL_ARB_multisample");
_supports_generate_mipmap =
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;
}
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();
_buffer_mask = 0;
@ -458,6 +476,7 @@ reset() {
// Antialiasing.
enable_line_smooth(false);
enable_point_smooth(false);
enable_multisample(true);
#ifdef HAVE_CGGL

View File

@ -430,7 +430,7 @@ choose_fbconfig(FrameBufferProperties &properties) const {
// Now update our framebuffer_mode and bit depth appropriately.
int render_mode, double_buffer, stereo, red_size, green_size, blue_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_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_DEPTH_SIZE, &depth_size);
glXGetFBConfigAttrib(_display, fbconfig, GLX_STENCIL_SIZE, &stencil_size);
glXGetFBConfigAttrib(_display, fbconfig, GLX_SAMPLES, &samples);
frame_buffer_mode = 0;
if (double_buffer) {
@ -468,6 +469,9 @@ choose_fbconfig(FrameBufferProperties &properties) const {
if (ared_size + agreen_size + ablue_size != 0) {
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_color_bits(red_size + green_size + blue_size + alpha_size);
@ -482,6 +486,7 @@ choose_fbconfig(FrameBufferProperties &properties) const {
<< ablue_size << " " << aalpha_size << endl
<< " Depth: " << depth_size << endl
<< " Stencil: " << stencil_size << endl
<< " Samples: " << samples << endl
<< " DoubleBuffer? " << double_buffer << endl
<< " Stereo? " << stereo << endl;
}
@ -578,14 +583,13 @@ try_for_fbconfig(int framebuffer_mode,
attrib_list[n++] = want_color_component_bits;
}
}
/*
if (framebuffer_mode & FrameBufferProperties::FM_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
attrib_list[n++] = 4;
}
*/
// Terminate the list
nassertr(n < max_attrib_list, None);
@ -650,16 +654,6 @@ choose_visual(FrameBufferProperties &properties) const {
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 =
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.
int render_mode, double_buffer, stereo, red_size, green_size, blue_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_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_DEPTH_SIZE, &depth_size);
glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &stencil_size);
glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &samples);
frame_buffer_mode = 0;
if (double_buffer) {
@ -816,6 +811,9 @@ choose_visual(FrameBufferProperties &properties) const {
if (ared_size + agreen_size + ablue_size != 0) {
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_color_bits(red_size + green_size + blue_size + alpha_size);
@ -830,6 +828,7 @@ choose_visual(FrameBufferProperties &properties) const {
<< ablue_size << " " << aalpha_size << endl
<< " Depth: " << depth_size << endl
<< " Stencil: " << stencil_size << endl
<< " Samples: " << samples << endl
<< " DoubleBuffer? " << double_buffer << endl
<< " Stereo? " << stereo << endl;
}
@ -911,14 +910,12 @@ try_for_visual(int framebuffer_mode,
attrib_list[n++] = want_color_component_bits;
}
}
/*
if (framebuffer_mode & FrameBufferProperties::FM_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
attrib_list[n++] = 4;
}
*/
// Terminate the list
nassertr(n < max_attrib_list, NULL);

View File

@ -730,6 +730,12 @@ make_texture_layer(const NodePath &render,
geom.set_texture(stage_info._tex);
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);
}
}
////////////////////////////////////////////////////////////////////