glgsg: support gl-depth-zero-to-one to get same NDC Z range as D3D

This commit is contained in:
rdb 2018-07-12 11:39:57 +02:00
parent 16daf08e42
commit 828233a8f2
4 changed files with 87 additions and 3 deletions

View File

@ -864,14 +864,22 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
case RTP_depth_stencil:
if (_fb_properties.get_depth_bits() > 24 ||
_fb_properties.get_float_depth()) {
gl_format = GL_DEPTH32F_STENCIL8;
if (!glgsg->_use_remapped_depth_range) {
gl_format = GL_DEPTH32F_STENCIL8;
} else {
gl_format = GL_DEPTH32F_STENCIL8_NV;
}
} else {
gl_format = GL_DEPTH24_STENCIL8;
}
break;
case RTP_depth:
if (_fb_properties.get_float_depth()) {
gl_format = GL_DEPTH_COMPONENT32F;
if (!glgsg->_use_remapped_depth_range) {
gl_format = GL_DEPTH_COMPONENT32F;
} else {
gl_format = GL_DEPTH_COMPONENT32F_NV;
}
} else if (_fb_properties.get_depth_bits() > 24) {
gl_format = GL_DEPTH_COMPONENT32;
} else if (_fb_properties.get_depth_bits() > 16) {

View File

@ -2997,6 +2997,50 @@ reset() {
}
#endif
// Set depth range from zero to one if requested.
#ifndef OPENGLES
_use_depth_zero_to_one = false;
_use_remapped_depth_range = false;
if (gl_depth_zero_to_one) {
if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_clip_control")) {
PFNGLCLIPCONTROLPROC pglClipControl =
(PFNGLCLIPCONTROLPROC)get_extension_func("glClipControl");
if (pglClipControl != nullptr) {
pglClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
_use_depth_zero_to_one = true;
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Set zero-to-one depth using glClipControl\n";
}
}
}/* else if (has_extension("GL_NV_depth_buffer_float")) {
// Alternatively, all GeForce 8+ and even some AMD drivers support this
// extension, which (unlike the core glDepthRange, which clamps its
// input parameters) can compensate for the built-in depth remapping.
_glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)get_extension_func("glDepthRangedNV");
if (_glDepthRangedNV != nullptr) {
_glDepthRangedNV(-1.0, 1.0);
_use_depth_zero_to_one = true;
_use_remapped_depth_range = true;
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Set zero-to-one depth using glDepthRangedNV\n";
}
}
}*/
if (!_use_depth_zero_to_one) {
GLCAT.warning()
<< "Zero-to-one depth was requested, but driver does not support it.\n";
}
}
#endif
// Set up all the enableddisabled flags to GL's known initial values:
// everything off.
_multisample_mode = 0;
@ -3646,6 +3690,19 @@ calc_projection_mat(const Lens *lens) {
lens->get_coordinate_system()) *
lens->get_projection_mat(_current_stereo_channel);
#ifndef OPENGLES
if (_use_depth_zero_to_one) {
// If we requested that the OpenGL NDC Z goes from zero to one like in
// Direct3D, we need to scale the projection matrix, which assumes -1..1.
static const LMatrix4 rescale_mat
(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0.5, 0,
0, 0, 0.5, 1);
result *= rescale_mat;
}
#endif
if (_scene_setup->get_inverted()) {
// If the scene is supposed to be inverted, then invert the projection
// matrix.
@ -7452,7 +7509,13 @@ do_issue_depth_offset() {
glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
#else
// Mainline OpenGL uses a double-precision call.
glDepthRange((GLclampd)min_value, (GLclampd)max_value);
if (!_use_remapped_depth_range) {
glDepthRange((GLclampd)min_value, (GLclampd)max_value);
} else {
// If we have a remapped depth range, we should adjust the values to range
// from -1 to 1. We need to use an NV extension to pass unclamped values.
_glDepthRangedNV(min_value * 2.0 - 1.0, max_value * 2.0 - 1.0);
}
#endif // OPENGLES
report_my_gl_errors();

View File

@ -743,6 +743,12 @@ protected:
#endif
public:
#ifndef OPENGLES
bool _use_depth_zero_to_one;
bool _use_remapped_depth_range;
PFNGLDEPTHRANGEDNVPROC _glDepthRangedNV;
#endif
bool _supports_point_parameters;
PFNGLPOINTPARAMETERFVPROC _glPointParameterfv;
bool _supports_point_sprite;

View File

@ -313,6 +313,13 @@ ConfigVariableEnum<CoordinateSystem> gl_coordinate_system
"creating a shader-only application, it may be easier and "
"more efficient to set this to default."));
ConfigVariableBool gl_depth_zero_to_one
("gl-depth-zero-to-one", false,
PRC_DESC("Normally, OpenGL uses an NDC coordinate space wherein the Z "
"ranges from -1 to 1. This setting can be used to instead use a "
"range from 0 to 1, matching other graphics APIs. This setting "
"requires OpenGL 4.5, or NVIDIA GeForce 8+ hardware."));
extern ConfigVariableBool gl_parallel_arrays;
void CLP(init_classes)() {