|
@@ -854,6 +854,17 @@ reset() {
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (is_at_least_gl_version(3, 0)) {
|
|
|
|
|
+ _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer");
|
|
|
|
|
+ _supports_buffer_texture = true;
|
|
|
|
|
+
|
|
|
|
|
+ } else if (has_extension("GL_ARB_texture_buffer_object")) {
|
|
|
|
|
+ _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB");
|
|
|
|
|
+ _supports_buffer_texture = true;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
_supports_texture_srgb = false;
|
|
_supports_texture_srgb = false;
|
|
|
if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
|
|
if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
|
|
|
_supports_texture_srgb = true;
|
|
_supports_texture_srgb = true;
|
|
@@ -1941,6 +1952,7 @@ reset() {
|
|
|
GLint max_3d_texture_size = 0;
|
|
GLint max_3d_texture_size = 0;
|
|
|
GLint max_2d_texture_array_layers = 0;
|
|
GLint max_2d_texture_array_layers = 0;
|
|
|
GLint max_cube_map_size = 0;
|
|
GLint max_cube_map_size = 0;
|
|
|
|
|
+ GLint max_buffer_texture_size = 0;
|
|
|
|
|
|
|
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
|
|
_max_texture_dimension = max_texture_size;
|
|
_max_texture_dimension = max_texture_size;
|
|
@@ -1966,6 +1978,15 @@ reset() {
|
|
|
_max_cube_map_dimension = 0;
|
|
_max_cube_map_dimension = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (_supports_buffer_texture) {
|
|
|
|
|
+ glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_buffer_texture_size);
|
|
|
|
|
+ _max_buffer_texture_size = max_buffer_texture_size;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _max_buffer_texture_size = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif // !OPENGLES
|
|
|
|
|
+
|
|
|
GLint max_elements_vertices = 0, max_elements_indices = 0;
|
|
GLint max_elements_vertices = 0, max_elements_indices = 0;
|
|
|
#ifndef OPENGLES
|
|
#ifndef OPENGLES
|
|
|
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
|
|
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
|
|
@@ -4510,6 +4531,15 @@ prepare_texture(Texture *tex, int view) {
|
|
|
<< "Cube map textures are not supported by this OpenGL driver.\n";
|
|
<< "Cube map textures are not supported by this OpenGL driver.\n";
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case Texture::TT_buffer_texture:
|
|
|
|
|
+ if (!_supports_buffer_texture) {
|
|
|
|
|
+ GLCAT.warning()
|
|
|
|
|
+ << "Buffer textures are not supported by this OpenGL driver.\n";
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
@@ -7362,27 +7392,35 @@ get_texture_target(Texture::TextureType texture_type) const {
|
|
|
return GL_TEXTURE_2D;
|
|
return GL_TEXTURE_2D;
|
|
|
|
|
|
|
|
case Texture::TT_3d_texture:
|
|
case Texture::TT_3d_texture:
|
|
|
- if (_supports_3d_texture) {
|
|
|
|
|
#ifndef OPENGLES_1
|
|
#ifndef OPENGLES_1
|
|
|
|
|
+ if (_supports_3d_texture) {
|
|
|
return GL_TEXTURE_3D;
|
|
return GL_TEXTURE_3D;
|
|
|
-#endif
|
|
|
|
|
- } else {
|
|
|
|
|
- return GL_NONE;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+#endif
|
|
|
|
|
+ return GL_NONE;
|
|
|
|
|
+
|
|
|
case Texture::TT_2d_texture_array:
|
|
case Texture::TT_2d_texture_array:
|
|
|
- if (_supports_2d_texture_array) {
|
|
|
|
|
#ifndef OPENGLES
|
|
#ifndef OPENGLES
|
|
|
|
|
+ if (_supports_2d_texture_array) {
|
|
|
return GL_TEXTURE_2D_ARRAY_EXT;
|
|
return GL_TEXTURE_2D_ARRAY_EXT;
|
|
|
-#endif
|
|
|
|
|
- } else {
|
|
|
|
|
- return GL_NONE;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+#endif
|
|
|
|
|
+ return GL_NONE;
|
|
|
|
|
+
|
|
|
case Texture::TT_cube_map:
|
|
case Texture::TT_cube_map:
|
|
|
if (_supports_cube_map) {
|
|
if (_supports_cube_map) {
|
|
|
return GL_TEXTURE_CUBE_MAP;
|
|
return GL_TEXTURE_CUBE_MAP;
|
|
|
} else {
|
|
} else {
|
|
|
return GL_NONE;
|
|
return GL_NONE;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ case Texture::TT_buffer_texture:
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (_supports_buffer_texture) {
|
|
|
|
|
+ return GL_TEXTURE_BUFFER;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+ return GL_NONE;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
GLCAT.error() << "Invalid Texture::TextureType value!\n";
|
|
GLCAT.error() << "Invalid Texture::TextureType value!\n";
|
|
@@ -10252,6 +10290,12 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
|
|
|
// Unsupported target (e.g. 3-d texturing on GL 1.1).
|
|
// Unsupported target (e.g. 3-d texturing on GL 1.1).
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (target == GL_TEXTURE_BUFFER) {
|
|
|
|
|
+ // Buffer textures may not receive texture parameters.
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif // OPENGLES
|
|
|
|
|
|
|
|
// Record the active sampler settings.
|
|
// Record the active sampler settings.
|
|
|
gtc->_active_sampler = sampler;
|
|
gtc->_active_sampler = sampler;
|
|
@@ -10505,7 +10549,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
|
|
|
|
|
// If we'll use immutable texture storage, we have to pick a sized
|
|
// If we'll use immutable texture storage, we have to pick a sized
|
|
|
// image format.
|
|
// image format.
|
|
|
- bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage);
|
|
|
|
|
|
|
+ bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) ||
|
|
|
|
|
+ (tex->get_texture_type() == Texture::TT_buffer_texture);
|
|
|
|
|
|
|
|
GLint internal_format = get_internal_image_format(tex, force_sized);
|
|
GLint internal_format = get_internal_image_format(tex, force_sized);
|
|
|
GLint external_format = get_external_image_format(tex);
|
|
GLint external_format = get_external_image_format(tex);
|
|
@@ -10553,6 +10598,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
max_dimension_z = _max_2d_texture_array_layers;
|
|
max_dimension_z = _max_2d_texture_array_layers;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case Texture::TT_buffer_texture:
|
|
|
|
|
+ max_dimension_x = _max_buffer_texture_size;
|
|
|
|
|
+ max_dimension_y = 1;
|
|
|
|
|
+ max_dimension_z = 1;
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
max_dimension_x = _max_texture_dimension;
|
|
max_dimension_x = _max_texture_dimension;
|
|
|
max_dimension_y = _max_texture_dimension;
|
|
max_dimension_y = _max_texture_dimension;
|
|
@@ -10631,6 +10682,13 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
|
|
|
|
|
GLenum target = get_texture_target(tex->get_texture_type());
|
|
GLenum target = get_texture_target(tex->get_texture_type());
|
|
|
uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
|
|
uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (target == GL_TEXTURE_BUFFER) {
|
|
|
|
|
+ // Buffer textures may not have mipmaps.
|
|
|
|
|
+ uses_mipmaps = false;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif // OPENGLES
|
|
|
|
|
+
|
|
|
bool needs_reload = false;
|
|
bool needs_reload = false;
|
|
|
if (!gtc->_has_storage ||
|
|
if (!gtc->_has_storage ||
|
|
|
gtc->_uses_mipmaps != uses_mipmaps ||
|
|
gtc->_uses_mipmaps != uses_mipmaps ||
|
|
@@ -10640,6 +10698,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
gtc->_depth != depth) {
|
|
gtc->_depth != depth) {
|
|
|
// We need to reload a new GL Texture object.
|
|
// We need to reload a new GL Texture object.
|
|
|
needs_reload = true;
|
|
needs_reload = true;
|
|
|
|
|
+
|
|
|
|
|
+ if (_use_object_labels) {
|
|
|
|
|
+ // This seems like a good time to assign a label for the debug messages.
|
|
|
|
|
+ const string &name = tex->get_name();
|
|
|
|
|
+ _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (needs_reload && gtc->_immutable) {
|
|
if (needs_reload && gtc->_immutable) {
|
|
@@ -10648,13 +10712,26 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
glBindTexture(target, gtc->_index);
|
|
glBindTexture(target, gtc->_index);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (needs_reload) {
|
|
|
|
|
- if (_use_object_labels) {
|
|
|
|
|
- // This seems like a good time to assign a label for the debug messages.
|
|
|
|
|
- const string &name = tex->get_name();
|
|
|
|
|
- _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
|
|
|
|
|
- }
|
|
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ if (target == GL_TEXTURE_BUFFER) {
|
|
|
|
|
+ // Buffer textures don't support mipmappping.
|
|
|
|
|
+ gtc->_generate_mipmaps = false;
|
|
|
|
|
|
|
|
|
|
+ if (gtc->_buffer == 0) {
|
|
|
|
|
+ // The buffer object wasn't created yet.
|
|
|
|
|
+ _glGenBuffers(1, >c->_buffer);
|
|
|
|
|
+ _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
|
|
|
|
|
+ _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
|
|
|
|
|
+ needs_reload = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
|
|
|
|
|
+ if (gtc->_internal_format != internal_format) {
|
|
|
|
|
+ _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else
|
|
|
|
|
+#endif // !OPENGLES
|
|
|
|
|
+ if (needs_reload) {
|
|
|
// Figure out whether mipmaps will be generated by the GPU or by
|
|
// Figure out whether mipmaps will be generated by the GPU or by
|
|
|
// Panda (or not at all), and how many mipmap levels should be created.
|
|
// Panda (or not at all), and how many mipmap levels should be created.
|
|
|
gtc->_generate_mipmaps = false;
|
|
gtc->_generate_mipmaps = false;
|
|
@@ -10736,6 +10813,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
switch (tex->get_texture_type()) {
|
|
switch (tex->get_texture_type()) {
|
|
|
|
|
+ case Texture::TT_buffer_texture:
|
|
|
|
|
+ // Won't get here, but squelch compiler warning
|
|
|
case Texture::TT_1d_texture:
|
|
case Texture::TT_1d_texture:
|
|
|
_glTexStorage1D(target, num_levels, internal_format, width);
|
|
_glTexStorage1D(target, num_levels, internal_format, width);
|
|
|
break;
|
|
break;
|
|
@@ -11095,6 +11174,17 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|
|
break;
|
|
break;
|
|
|
#endif // OPENGLES
|
|
#endif // OPENGLES
|
|
|
|
|
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ case GL_TEXTURE_BUFFER:
|
|
|
|
|
+ if (_supports_buffer_texture) {
|
|
|
|
|
+ _glBufferSubData(GL_TEXTURE_BUFFER, 0, width, image_ptr);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ report_my_gl_errors();
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+#endif // OPENGLES
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
if (image_compression == Texture::CM_off) {
|
|
if (image_compression == Texture::CM_off) {
|
|
|
if (n==0) {
|
|
if (n==0) {
|
|
@@ -11248,6 +11338,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+
|
|
|
#ifndef OPENGLES
|
|
#ifndef OPENGLES
|
|
|
case GL_TEXTURE_2D_ARRAY_EXT:
|
|
case GL_TEXTURE_2D_ARRAY_EXT:
|
|
|
if (_supports_2d_texture_array) {
|
|
if (_supports_2d_texture_array) {
|
|
@@ -11265,7 +11356,19 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
-#endif
|
|
|
|
|
|
|
+#endif // OPENGLES
|
|
|
|
|
+
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
|
|
+ case GL_TEXTURE_BUFFER:
|
|
|
|
|
+ if (_supports_buffer_texture) {
|
|
|
|
|
+ _glBufferData(GL_TEXTURE_BUFFER, width, image_ptr,
|
|
|
|
|
+ get_usage(tex->get_usage_hint()));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ report_my_gl_errors();
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+#endif // OPENGLES
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
if (image_compression == Texture::CM_off) {
|
|
if (image_compression == Texture::CM_off) {
|
|
@@ -11396,6 +11499,12 @@ get_texture_memory_size(Texture *tex) {
|
|
|
// We need a particular page to get the level parameter from.
|
|
// We need a particular page to get the level parameter from.
|
|
|
page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
|
scale = 6;
|
|
scale = 6;
|
|
|
|
|
+
|
|
|
|
|
+ } else if (target == GL_TEXTURE_BUFFER) {
|
|
|
|
|
+ // In the case of buffer textures, we provided the size to begin with,
|
|
|
|
|
+ // so no point in querying anything. Plus, glGetTexParameter is not even
|
|
|
|
|
+ // supported for buffer textures.
|
|
|
|
|
+ return tex->get_expected_ram_image_size();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
GLint minfilter;
|
|
GLint minfilter;
|
|
@@ -11431,20 +11540,20 @@ get_texture_memory_size(Texture *tex) {
|
|
|
luminance_size, intensity_size;
|
|
luminance_size, intensity_size;
|
|
|
GLint depth_size = 0;
|
|
GLint depth_size = 0;
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_RED_SIZE, &red_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_RED_SIZE, &red_size);
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_GREEN_SIZE, &green_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_GREEN_SIZE, &green_size);
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_BLUE_SIZE, &blue_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_BLUE_SIZE, &blue_size);
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
|
|
if (_supports_depth_texture) {
|
|
if (_supports_depth_texture) {
|
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
glGetTexLevelParameteriv(page_target, 0,
|
|
|
- GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
|
|
|
|
|
|
+ GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
GLint width = 1, height = 1, depth = 1;
|
|
GLint width = 1, height = 1, depth = 1;
|