Backport some GL tweaks to 1.9, particularly gl-support-texture-lod

This commit is contained in:
rdb 2015-12-16 21:07:07 +01:00
parent 81691e3103
commit 5b1cfd115c
4 changed files with 86 additions and 40 deletions

View File

@ -506,17 +506,21 @@ reset() {
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
} }
GLCAT.debug() << "gl-debug enabled.\n"; GLCAT.info() << "gl-debug enabled.\n";
} else { } else {
GLCAT.debug() << "gl-debug enabled, but NOT supported.\n"; GLCAT.warning() << "gl-debug enabled, but NOT supported.\n";
} }
} else { } else {
GLCAT.debug() << "gl-debug NOT enabled.\n";
// However, still check if it is supported. // However, still check if it is supported.
_supports_debug = is_at_least_gl_version(4, 3) _supports_debug = is_at_least_gl_version(4, 3)
|| has_extension("GL_KHR_debug") || has_extension("GL_KHR_debug")
|| has_extension("GL_ARB_debug_output"); || has_extension("GL_ARB_debug_output");
if (_supports_debug) {
GLCAT.debug() << "gl-debug supported, but NOT enabled.\n";
} else {
GLCAT.debug() << "gl-debug disabled and unsupported.\n";
}
} }
#endif // OPENGLES_1 #endif // OPENGLES_1
@ -561,7 +565,8 @@ reset() {
#elif defined(OPENGLES_1) #elif defined(OPENGLES_1)
_supports_point_sprite = has_extension("GL_OES_point_sprite"); _supports_point_sprite = has_extension("GL_OES_point_sprite");
#else #else
_supports_point_sprite = has_extension("GL_ARB_point_sprite"); _supports_point_sprite = is_at_least_gl_version(2, 0) ||
has_extension("GL_ARB_point_sprite");
#endif #endif
if (_supports_point_sprite) { if (_supports_point_sprite) {
@ -852,7 +857,8 @@ reset() {
_supports_cube_map = true; _supports_cube_map = true;
#else #else
_supports_cube_map = _supports_cube_map =
has_extension("GL_ARB_texture_cube_map") || is_at_least_gl_version(1, 3) || is_at_least_gl_version(1, 3) ||
has_extension("GL_ARB_texture_cube_map") ||
has_extension("GL_OES_texture_cube_map"); has_extension("GL_OES_texture_cube_map");
#endif #endif
@ -872,8 +878,6 @@ reset() {
_supports_texture_srgb = true; _supports_texture_srgb = true;
} }
_supports_compressed_texture = false;
#ifdef OPENGLES #ifdef OPENGLES
_supports_compressed_texture = true; _supports_compressed_texture = true;
@ -931,6 +935,9 @@ reset() {
get_extension_func("glCompressedTexSubImage3DARB"); get_extension_func("glCompressedTexSubImage3DARB");
_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
get_extension_func("glGetCompressedTexImageARB"); get_extension_func("glGetCompressedTexImageARB");
} else {
_supports_compressed_texture = false;
} }
if (_supports_compressed_texture) { if (_supports_compressed_texture) {
@ -955,7 +962,7 @@ reset() {
GLint num_compressed_formats = 0; GLint num_compressed_formats = 0;
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats); glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
GLint *formats = (GLint *)PANDA_MALLOC_ARRAY(num_compressed_formats * sizeof(GLint)); GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
for (int i = 0; i < num_compressed_formats; ++i) { for (int i = 0; i < num_compressed_formats; ++i) {
switch (formats[i]) { switch (formats[i]) {
@ -991,7 +998,6 @@ reset() {
break; break;
} }
} }
PANDA_FREE_ARRAY(formats);
} }
#ifdef OPENGLES_2 #ifdef OPENGLES_2
@ -1024,18 +1030,20 @@ reset() {
_supports_multisample = _supports_multisample =
has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3); has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3);
#ifdef OPENGLES_2 #ifdef OPENGLES_1
_supports_generate_mipmap = is_at_least_gles_version(1, 1);
#elif defined(OPENGLES)
_supports_generate_mipmap = true; _supports_generate_mipmap = true;
#else #else
_supports_generate_mipmap = _supports_generate_mipmap = is_at_least_gl_version(1, 4) ||
has_extension("GL_SGIS_generate_mipmap") || is_at_least_gl_version(1, 4) || is_at_least_gles_version(1, 1); has_extension("GL_SGIS_generate_mipmap");
#endif #endif
#ifdef OPENGLES #ifdef OPENGLES
_supports_tex_non_pow2 = _supports_tex_non_pow2 =
has_extension("GL_OES_texture_npot"); has_extension("GL_OES_texture_npot");
#else #else
_supports_tex_non_pow2 = _supports_tex_non_pow2 = is_at_least_gl_version(2, 0) ||
has_extension("GL_ARB_texture_non_power_of_two"); has_extension("GL_ARB_texture_non_power_of_two");
#endif #endif
@ -1142,7 +1150,7 @@ reset() {
#else #else
if (gl_support_shadow_filter && if (gl_support_shadow_filter &&
_supports_depth_texture && _supports_depth_texture &&
has_extension("GL_ARB_shadow") && (is_at_least_gl_version(1, 4) || has_extension("GL_ARB_shadow")) &&
has_extension("GL_ARB_fragment_program_shadow")) { has_extension("GL_ARB_fragment_program_shadow")) {
_supports_shadow_filter = true; _supports_shadow_filter = true;
} }
@ -1405,7 +1413,8 @@ reset() {
} else { } else {
_glVertexAttribIPointer = NULL; _glVertexAttribIPointer = NULL;
} }
if (has_extension("GL_ARB_vertex_attrib_64bit")) { if (is_at_least_gl_version(4, 1) ||
has_extension("GL_ARB_vertex_attrib_64bit")) {
_glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) _glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)
get_extension_func("glVertexAttribLPointer"); get_extension_func("glVertexAttribLPointer");
} else { } else {
@ -1691,7 +1700,7 @@ reset() {
#endif #endif
_supports_framebuffer_multisample = false; _supports_framebuffer_multisample = false;
if ( has_extension("GL_EXT_framebuffer_multisample") ) { if (has_extension("GL_EXT_framebuffer_multisample")) {
_supports_framebuffer_multisample = true; _supports_framebuffer_multisample = true;
_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
get_extension_func("glRenderbufferStorageMultisampleEXT"); get_extension_func("glRenderbufferStorageMultisampleEXT");
@ -1699,7 +1708,7 @@ reset() {
#ifndef OPENGLES #ifndef OPENGLES
_supports_framebuffer_multisample_coverage_nv = false; _supports_framebuffer_multisample_coverage_nv = false;
if ( has_extension("GL_NV_framebuffer_multisample_coverage") ) { if (has_extension("GL_NV_framebuffer_multisample_coverage")) {
_supports_framebuffer_multisample_coverage_nv = true; _supports_framebuffer_multisample_coverage_nv = true;
_glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
get_extension_func("glRenderbufferStorageMultisampleCoverageNV"); get_extension_func("glRenderbufferStorageMultisampleCoverageNV");
@ -1708,7 +1717,7 @@ reset() {
#ifndef OPENGLES_1 #ifndef OPENGLES_1
_supports_framebuffer_blit = false; _supports_framebuffer_blit = false;
if ( has_extension("GL_EXT_framebuffer_blit") ) { if (has_extension("GL_EXT_framebuffer_blit")) {
_supports_framebuffer_blit = true; _supports_framebuffer_blit = true;
_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC) _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
get_extension_func("glBlitFramebufferEXT"); get_extension_func("glBlitFramebufferEXT");
@ -1922,8 +1931,8 @@ reset() {
_edge_clamp = GL_CLAMP_TO_EDGE; _edge_clamp = GL_CLAMP_TO_EDGE;
#else #else
_edge_clamp = GL_CLAMP; _edge_clamp = GL_CLAMP;
if (has_extension("GL_SGIS_texture_edge_clamp") || if (is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1) ||
is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1)) { has_extension("GL_SGIS_texture_edge_clamp")) {
_edge_clamp = GL_CLAMP_TO_EDGE; _edge_clamp = GL_CLAMP_TO_EDGE;
} }
#endif #endif
@ -1959,6 +1968,20 @@ reset() {
} }
#endif #endif
#ifndef OPENGLES
_supports_texture_lod = false;
_supports_texture_lod_bias = false;
if (gl_support_texture_lod &&
(is_at_least_gl_version(1, 2) || has_extension("GL_SGIS_texture_lod"))) {
_supports_texture_lod = true;
if (is_at_least_gl_version(1, 4) || has_extension("GL_EXT_texture_lod_bias")) {
_supports_texture_lod_bias = true;
}
}
#endif
if (_supports_multisample) { if (_supports_multisample) {
GLint sample_buffers = 0; GLint sample_buffers = 0;
glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers); glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
@ -4762,9 +4785,14 @@ prepare_sampler(const SamplerState &sampler) {
} }
} }
if (_supports_texture_lod) {
_glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod()); _glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
_glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod()); _glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
}
if (_supports_texture_lod_bias) {
_glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias()); _glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
}
gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru); gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
@ -6880,13 +6908,15 @@ get_error_string(GLenum error_code) {
// We used to use gluErrorString here, but I (rdb) took it out // We used to use gluErrorString here, but I (rdb) took it out
// because that was really the only function we used from GLU. // because that was really the only function we used from GLU.
// The idea with the error table was taken from SGI's sample implementation. // The idea with the error table was taken from SGI's sample implementation.
static const char *error_strings[GL_OUT_OF_MEMORY - GL_INVALID_ENUM + 1] = { static const char *error_strings[] = {
"invalid enumerant", "invalid enumerant",
"invalid value", "invalid value",
"invalid operation", "invalid operation",
"stack overflow", "stack overflow",
"stack underflow", "stack underflow",
"out of memory", "out of memory",
"invalid framebuffer operation",
"context lost",
}; };
if (error_code == GL_NO_ERROR) { if (error_code == GL_NO_ERROR) {
@ -6895,8 +6925,8 @@ get_error_string(GLenum error_code) {
} else if (error_code == GL_TABLE_TOO_LARGE) { } else if (error_code == GL_TABLE_TOO_LARGE) {
return "table too large"; return "table too large";
#endif #endif
} else if (error_code >= GL_INVALID_ENUM && error_code <= GL_OUT_OF_MEMORY) { } else if (error_code >= 0x0500 && error_code <= 0x0507) {
return error_strings[error_code - GL_INVALID_ENUM]; return error_strings[error_code - 0x0500];
} }
// Other error, somehow? Just display the error code then. // Other error, somehow? Just display the error code then.
@ -7019,7 +7049,7 @@ query_gl_version() {
_gl_shadlang_ver_minor = 0; _gl_shadlang_ver_minor = 0;
const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
if (verstr == NULL || if (verstr == NULL ||
sscanf(verstr, "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major, sscanf(verstr, "OpenGL ES GLSL ES %d.%d", &_gl_shadlang_ver_major,
&_gl_shadlang_ver_minor) != 2) { &_gl_shadlang_ver_minor) != 2) {
GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n"; GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
} }
@ -10402,9 +10432,14 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
#endif #endif
#ifndef OPENGLES #ifndef OPENGLES
if (_supports_texture_lod) {
glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod()); glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod()); glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
}
if (_supports_texture_lod_bias) {
glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias()); glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
}
#endif #endif
report_my_gl_errors(); report_my_gl_errors();
@ -10771,7 +10806,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
} }
#ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL. #ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL.
if (is_at_least_gl_version(1, 2)) { if (_supports_texture_lod) {
// By the time we get here, we have a pretty good prediction for // By the time we get here, we have a pretty good prediction for
// the number of mipmaps we're going to have, so tell the GL that's // the number of mipmaps we're going to have, so tell the GL that's
// all it's going to get. // all it's going to get.
@ -11227,12 +11262,12 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
GLCAT.warning() GLCAT.warning()
<< "No mipmap level " << n << " defined for " << tex->get_name() << "No mipmap level " << n << " defined for " << tex->get_name()
<< "\n"; << "\n";
#ifndef OPENGLES #ifndef OPENGLES
if (is_at_least_gl_version(1, 2)) { if (_supports_texture_lod) {
// Tell the GL we have no more mipmaps for it to use. // Tell the GL we have no more mipmaps for it to use.
glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias); glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
} }
#endif #endif
break; break;
} }
@ -11409,11 +11444,9 @@ upload_simple_texture(CLP(TextureContext) *gtc) {
#ifndef OPENGLES #ifndef OPENGLES
// Turn off mipmaps for the simple texture. // Turn off mipmaps for the simple texture.
if (tex->uses_mipmaps()) { if (tex->uses_mipmaps() && _supports_texture_lod) {
if (is_at_least_gl_version(1, 2)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
} }
}
#endif #endif
#ifdef DO_PSTATS #ifdef DO_PSTATS
@ -12046,7 +12079,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
GLint num_expected_levels = tex->get_expected_num_mipmap_levels(); GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
GLint highest_level = num_expected_levels; GLint highest_level = num_expected_levels;
#ifndef OPENGLES #ifndef OPENGLES
if (is_at_least_gl_version(1, 2)) { if (_supports_texture_lod) {
glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level); glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
highest_level = min(highest_level, num_expected_levels); highest_level = min(highest_level, num_expected_levels);
} }

View File

@ -875,6 +875,12 @@ public:
GLenum _mirror_clamp; GLenum _mirror_clamp;
GLenum _mirror_edge_clamp; GLenum _mirror_edge_clamp;
GLenum _mirror_border_clamp; GLenum _mirror_border_clamp;
#ifndef OPENGLES
bool _supports_texture_lod;
bool _supports_texture_lod_bias;
#endif
#ifndef OPENGLES_1 #ifndef OPENGLES_1
GLsizei _instance_count; GLsizei _instance_count;
#endif #endif

View File

@ -44,6 +44,12 @@ ConfigVariableBool gl_support_rescale_normal
"it even if it appears to be available. (This appears to be " "it even if it appears to be available. (This appears to be "
"buggy on some drivers.)")); "buggy on some drivers.)"));
ConfigVariableBool gl_support_texture_lod
("gl-support-texture-lod", true,
PRC_DESC("Configure this true to enable the use of minmax LOD settings "
"and texture LOD bias settings. Set this to false if you "
"suspect a driver bug."));
ConfigVariableBool gl_ignore_filters ConfigVariableBool gl_ignore_filters
("gl-ignore-filters", false, ("gl-ignore-filters", false,
PRC_DESC("Configure this true to disable any texture filters at all (forcing " PRC_DESC("Configure this true to disable any texture filters at all (forcing "

View File

@ -45,6 +45,7 @@ extern EXPCL_PANDAGL ConfigVariableBool gl_support_fbo;
extern ConfigVariableBool gl_cheap_textures; extern ConfigVariableBool gl_cheap_textures;
extern ConfigVariableBool gl_ignore_clamp; extern ConfigVariableBool gl_ignore_clamp;
extern ConfigVariableBool gl_support_clamp_to_border; extern ConfigVariableBool gl_support_clamp_to_border;
extern ConfigVariableBool gl_support_texture_lod;
extern ConfigVariableBool gl_ignore_filters; extern ConfigVariableBool gl_ignore_filters;
extern ConfigVariableBool gl_ignore_mipmaps; extern ConfigVariableBool gl_ignore_mipmaps;
extern ConfigVariableBool gl_force_mipmaps; extern ConfigVariableBool gl_force_mipmaps;