mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-22 07:01:45 -04:00
Add support for buffer textures
This commit is contained in:
parent
38ac0401ce
commit
2ff9083812
@ -397,6 +397,22 @@ get_max_cube_map_dimension() const {
|
|||||||
return _max_cube_map_dimension;
|
return _max_cube_map_dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::get_max_buffer_texture_size
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the largest possible buffer texture size,
|
||||||
|
// or -1 if there is no particular limit. Returns 0
|
||||||
|
// if cube map textures are not supported.
|
||||||
|
//
|
||||||
|
// The value returned may not be meaningful until after
|
||||||
|
// the graphics context has been fully created (e.g. the
|
||||||
|
// window has been opened).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int GraphicsStateGuardian::
|
||||||
|
get_max_buffer_texture_size() const {
|
||||||
|
return _max_buffer_texture_size;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::get_supports_texture_combine
|
// Function: GraphicsStateGuardian::get_supports_texture_combine
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -469,6 +485,16 @@ get_supports_cube_map() const {
|
|||||||
return _supports_cube_map;
|
return _supports_cube_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::get_supports_buffer_texture
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if this GSG can render buffer textures.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool GraphicsStateGuardian::
|
||||||
|
get_supports_buffer_texture() const {
|
||||||
|
return _supports_buffer_texture;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::get_supports_tex_non_pow2
|
// Function: GraphicsStateGuardian::get_supports_tex_non_pow2
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -185,6 +185,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||||||
_max_3d_texture_dimension = 0;
|
_max_3d_texture_dimension = 0;
|
||||||
_max_2d_texture_array_layers = 0;
|
_max_2d_texture_array_layers = 0;
|
||||||
_max_cube_map_dimension = 0;
|
_max_cube_map_dimension = 0;
|
||||||
|
_max_buffer_texture_size = 0;
|
||||||
|
|
||||||
// Assume we don't support these fairly advanced texture combiner
|
// Assume we don't support these fairly advanced texture combiner
|
||||||
// modes.
|
// modes.
|
||||||
@ -195,6 +196,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||||||
_supports_3d_texture = false;
|
_supports_3d_texture = false;
|
||||||
_supports_2d_texture_array = false;
|
_supports_2d_texture_array = false;
|
||||||
_supports_cube_map = false;
|
_supports_cube_map = false;
|
||||||
|
_supports_buffer_texture = false;
|
||||||
_supports_tex_non_pow2 = false;
|
_supports_tex_non_pow2 = false;
|
||||||
_supports_texture_srgb = false;
|
_supports_texture_srgb = false;
|
||||||
_supports_compressed_texture = false;
|
_supports_compressed_texture = false;
|
||||||
|
@ -121,6 +121,7 @@ PUBLISHED:
|
|||||||
INLINE int get_max_3d_texture_dimension() const;
|
INLINE int get_max_3d_texture_dimension() const;
|
||||||
INLINE int get_max_2d_texture_array_layers() const; //z axis
|
INLINE int get_max_2d_texture_array_layers() const; //z axis
|
||||||
INLINE int get_max_cube_map_dimension() const;
|
INLINE int get_max_cube_map_dimension() const;
|
||||||
|
INLINE int get_max_buffer_texture_size() const;
|
||||||
|
|
||||||
INLINE bool get_supports_texture_combine() const;
|
INLINE bool get_supports_texture_combine() const;
|
||||||
INLINE bool get_supports_texture_saved_result() const;
|
INLINE bool get_supports_texture_saved_result() const;
|
||||||
@ -129,6 +130,7 @@ PUBLISHED:
|
|||||||
INLINE bool get_supports_3d_texture() const;
|
INLINE bool get_supports_3d_texture() const;
|
||||||
INLINE bool get_supports_2d_texture_array() const;
|
INLINE bool get_supports_2d_texture_array() const;
|
||||||
INLINE bool get_supports_cube_map() const;
|
INLINE bool get_supports_cube_map() const;
|
||||||
|
INLINE bool get_supports_buffer_texture() const;
|
||||||
INLINE bool get_supports_tex_non_pow2() const;
|
INLINE bool get_supports_tex_non_pow2() const;
|
||||||
INLINE bool get_supports_texture_srgb() const;
|
INLINE bool get_supports_texture_srgb() const;
|
||||||
|
|
||||||
@ -476,6 +478,7 @@ protected:
|
|||||||
int _max_3d_texture_dimension;
|
int _max_3d_texture_dimension;
|
||||||
int _max_2d_texture_array_layers; //on the z axis
|
int _max_2d_texture_array_layers; //on the z axis
|
||||||
int _max_cube_map_dimension;
|
int _max_cube_map_dimension;
|
||||||
|
int _max_buffer_texture_size;
|
||||||
|
|
||||||
bool _supports_texture_combine;
|
bool _supports_texture_combine;
|
||||||
bool _supports_texture_saved_result;
|
bool _supports_texture_saved_result;
|
||||||
@ -484,6 +487,7 @@ protected:
|
|||||||
bool _supports_3d_texture;
|
bool _supports_3d_texture;
|
||||||
bool _supports_2d_texture_array;
|
bool _supports_2d_texture_array;
|
||||||
bool _supports_cube_map;
|
bool _supports_cube_map;
|
||||||
|
bool _supports_buffer_texture;
|
||||||
bool _supports_tex_non_pow2;
|
bool _supports_tex_non_pow2;
|
||||||
bool _supports_texture_srgb;
|
bool _supports_texture_srgb;
|
||||||
|
|
||||||
|
@ -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) {
|
#ifndef OPENGLES
|
||||||
if (_use_object_labels) {
|
if (target == GL_TEXTURE_BUFFER) {
|
||||||
// This seems like a good time to assign a label for the debug messages.
|
// Buffer textures don't support mipmappping.
|
||||||
const string &name = tex->get_name();
|
gtc->_generate_mipmaps = false;
|
||||||
_glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -693,6 +693,10 @@ public:
|
|||||||
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
|
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
|
||||||
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
|
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
|
||||||
|
|
||||||
|
#ifndef OPENGLES
|
||||||
|
PFNGLTEXBUFFERPROC _glTexBuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool _supports_clear_texture;
|
bool _supports_clear_texture;
|
||||||
#ifndef OPENGLES
|
#ifndef OPENGLES
|
||||||
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
|
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
|
||||||
|
@ -602,16 +602,19 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||||||
case GL_INT_SAMPLER_3D:
|
case GL_INT_SAMPLER_3D:
|
||||||
case GL_INT_SAMPLER_2D_ARRAY:
|
case GL_INT_SAMPLER_2D_ARRAY:
|
||||||
case GL_INT_SAMPLER_CUBE:
|
case GL_INT_SAMPLER_CUBE:
|
||||||
|
case GL_INT_SAMPLER_BUFFER:
|
||||||
case GL_UNSIGNED_INT_SAMPLER_1D:
|
case GL_UNSIGNED_INT_SAMPLER_1D:
|
||||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||||
|
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||||
case GL_SAMPLER_1D_SHADOW:
|
case GL_SAMPLER_1D_SHADOW:
|
||||||
case GL_SAMPLER_1D:
|
case GL_SAMPLER_1D:
|
||||||
case GL_SAMPLER_CUBE_SHADOW:
|
case GL_SAMPLER_CUBE_SHADOW:
|
||||||
case GL_SAMPLER_2D_ARRAY:
|
case GL_SAMPLER_2D_ARRAY:
|
||||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||||
|
case GL_SAMPLER_BUFFER:
|
||||||
#endif // !OPENGLES
|
#endif // !OPENGLES
|
||||||
case GL_SAMPLER_2D:
|
case GL_SAMPLER_2D:
|
||||||
case GL_SAMPLER_2D_SHADOW:
|
case GL_SAMPLER_2D_SHADOW:
|
||||||
@ -620,7 +623,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||||||
Shader::ShaderTexSpec bind;
|
Shader::ShaderTexSpec bind;
|
||||||
bind._id = arg_id;
|
bind._id = arg_id;
|
||||||
bind._name = InternalName::make(param_name);
|
bind._name = InternalName::make(param_name);
|
||||||
bind._desired_type = Texture::TT_2d_texture_array;
|
bind._desired_type = Texture::TT_2d_texture;
|
||||||
bind._stage = texunitno++;
|
bind._stage = texunitno++;
|
||||||
if (get_sampler_texture_type(bind._desired_type, param_type)) {
|
if (get_sampler_texture_type(bind._desired_type, param_type)) {
|
||||||
_glgsg->_glUniform1i(p, s->_tex_spec.size());
|
_glgsg->_glUniform1i(p, s->_tex_spec.size());
|
||||||
@ -761,16 +764,19 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||||||
case GL_IMAGE_3D_EXT:
|
case GL_IMAGE_3D_EXT:
|
||||||
case GL_IMAGE_CUBE_EXT:
|
case GL_IMAGE_CUBE_EXT:
|
||||||
case GL_IMAGE_2D_ARRAY_EXT:
|
case GL_IMAGE_2D_ARRAY_EXT:
|
||||||
|
case GL_IMAGE_BUFFER_EXT:
|
||||||
case GL_INT_IMAGE_1D_EXT:
|
case GL_INT_IMAGE_1D_EXT:
|
||||||
case GL_INT_IMAGE_2D_EXT:
|
case GL_INT_IMAGE_2D_EXT:
|
||||||
case GL_INT_IMAGE_3D_EXT:
|
case GL_INT_IMAGE_3D_EXT:
|
||||||
case GL_INT_IMAGE_CUBE_EXT:
|
case GL_INT_IMAGE_CUBE_EXT:
|
||||||
case GL_INT_IMAGE_2D_ARRAY_EXT:
|
case GL_INT_IMAGE_2D_ARRAY_EXT:
|
||||||
|
case GL_INT_IMAGE_BUFFER_EXT:
|
||||||
case GL_UNSIGNED_INT_IMAGE_1D_EXT:
|
case GL_UNSIGNED_INT_IMAGE_1D_EXT:
|
||||||
case GL_UNSIGNED_INT_IMAGE_2D_EXT:
|
case GL_UNSIGNED_INT_IMAGE_2D_EXT:
|
||||||
case GL_UNSIGNED_INT_IMAGE_3D_EXT:
|
case GL_UNSIGNED_INT_IMAGE_3D_EXT:
|
||||||
case GL_UNSIGNED_INT_IMAGE_CUBE_EXT:
|
case GL_UNSIGNED_INT_IMAGE_CUBE_EXT:
|
||||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT:
|
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_BUFFER_EXT:
|
||||||
// This won't really change at runtime, so we might as well
|
// This won't really change at runtime, so we might as well
|
||||||
// bind once and then forget about it.
|
// bind once and then forget about it.
|
||||||
_glgsg->_glUniform1i(p, imgunitno++);
|
_glgsg->_glUniform1i(p, imgunitno++);
|
||||||
@ -1076,6 +1082,18 @@ get_sampler_texture_type(int &out, GLenum param_type) {
|
|||||||
<< "GLSL shader uses 2D texture array, which is unsupported by the driver.\n";
|
<< "GLSL shader uses 2D texture array, which is unsupported by the driver.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GL_INT_SAMPLER_BUFFER:
|
||||||
|
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||||
|
case GL_SAMPLER_BUFFER:
|
||||||
|
out = Texture::TT_buffer_texture;
|
||||||
|
if (_glgsg->_supports_buffer_texture) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
GLCAT.error()
|
||||||
|
<< "GLSL shader uses buffer texture, which is unsupported by the driver.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1509,6 +1527,12 @@ disable_shader_texture_bindings() {
|
|||||||
case Texture::TT_cube_map:
|
case Texture::TT_cube_map:
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Texture::TT_buffer_texture:
|
||||||
|
#ifndef OPENGLES
|
||||||
|
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg,
|
|||||||
_glgsg = glgsg;
|
_glgsg = glgsg;
|
||||||
|
|
||||||
glGenTextures(1, &_index);
|
glGenTextures(1, &_index);
|
||||||
|
_buffer = 0;
|
||||||
|
|
||||||
_handle = 0;
|
_handle = 0;
|
||||||
_has_storage = false;
|
_has_storage = false;
|
||||||
|
@ -34,6 +34,11 @@ CLP(TextureContext)::
|
|||||||
|
|
||||||
glDeleteTextures(1, &_index);
|
glDeleteTextures(1, &_index);
|
||||||
_index = 0;
|
_index = 0;
|
||||||
|
|
||||||
|
if (_buffer != 0) {
|
||||||
|
_glgsg->_glDeleteBuffers(1, &_buffer);
|
||||||
|
_buffer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -88,6 +93,11 @@ reset_data() {
|
|||||||
// Free the texture resources.
|
// Free the texture resources.
|
||||||
glDeleteTextures(1, &_index);
|
glDeleteTextures(1, &_index);
|
||||||
|
|
||||||
|
if (_buffer != 0) {
|
||||||
|
_glgsg->_glDeleteBuffers(1, &_buffer);
|
||||||
|
_buffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// We still need a valid index number, though, in case we want to
|
// We still need a valid index number, though, in case we want to
|
||||||
// re-load the texture later.
|
// re-load the texture later.
|
||||||
glGenTextures(1, &_index);
|
glGenTextures(1, &_index);
|
||||||
|
@ -48,6 +48,9 @@ public:
|
|||||||
// This is the GL "name" of the texture object.
|
// This is the GL "name" of the texture object.
|
||||||
GLuint _index;
|
GLuint _index;
|
||||||
|
|
||||||
|
// This is only used for buffer textures.
|
||||||
|
GLuint _buffer;
|
||||||
|
|
||||||
// This is the bindless "handle" to the texture object.
|
// This is the bindless "handle" to the texture object.
|
||||||
GLuint64 _handle;
|
GLuint64 _handle;
|
||||||
bool _handle_resident;
|
bool _handle_resident;
|
||||||
|
@ -215,6 +215,26 @@ setup_cube_map(int size, ComponentType component_type, Format format) {
|
|||||||
setup_texture(TT_cube_map, size, size, 6, component_type, format);
|
setup_texture(TT_cube_map, size, size, 6, component_type, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::setup_buffer_texture
|
||||||
|
// Access: Published
|
||||||
|
// Description: Sets the texture as an empty buffer texture with
|
||||||
|
// the specified size and properties. Follow up
|
||||||
|
// with set_ram_image() or modify_ram_image() to fill
|
||||||
|
// the image data, or use set_clear_color to let the
|
||||||
|
// texture be cleared to a solid color.
|
||||||
|
//
|
||||||
|
// Note that a buffer texture's format needs to match
|
||||||
|
// the component type.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void Texture::
|
||||||
|
setup_buffer_texture(int size, ComponentType component_type, Format format,
|
||||||
|
GeomEnums::UsageHint usage) {
|
||||||
|
setup_texture(TT_buffer_texture, size, 1, 1, component_type, format);
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
cdata->_usage_hint = usage;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Texture::clear_image
|
// Function: Texture::clear_image
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -886,6 +906,18 @@ get_component_type() const {
|
|||||||
return cdata->_component_type;
|
return cdata->_component_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Texture::get_usage_hint
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the usage hint specified for buffer textures,
|
||||||
|
// or UH_unspecified for all other texture types.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE GeomEnums::UsageHint Texture::
|
||||||
|
get_usage_hint() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return cdata->_usage_hint;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Texture::set_wrap_u
|
// Function: Texture::set_wrap_u
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -1524,6 +1524,10 @@ write(ostream &out, int indent_level) const {
|
|||||||
case TT_cube_map:
|
case TT_cube_map:
|
||||||
out << "cube map, " << cdata->_x_size << " x " << cdata->_y_size;
|
out << "cube map, " << cdata->_x_size << " x " << cdata->_y_size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TT_buffer_texture:
|
||||||
|
out << "buffer, " << cdata->_x_size;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdata->_num_views > 1) {
|
if (cdata->_num_views > 1) {
|
||||||
@ -1924,6 +1928,8 @@ format_texture_type(TextureType tt) {
|
|||||||
return "2d_texture_array";
|
return "2d_texture_array";
|
||||||
case TT_cube_map:
|
case TT_cube_map:
|
||||||
return "cube_map";
|
return "cube_map";
|
||||||
|
case TT_buffer_texture:
|
||||||
|
return "buffer_texture";
|
||||||
}
|
}
|
||||||
return "**invalid**";
|
return "**invalid**";
|
||||||
}
|
}
|
||||||
@ -1946,6 +1952,8 @@ string_texture_type(const string &str) {
|
|||||||
return TT_2d_texture_array;
|
return TT_2d_texture_array;
|
||||||
} else if (cmp_nocase(str, "cube_map") == 0) {
|
} else if (cmp_nocase(str, "cube_map") == 0) {
|
||||||
return TT_cube_map;
|
return TT_cube_map;
|
||||||
|
} else if (cmp_nocase(str, "buffer_texture") == 0) {
|
||||||
|
return TT_buffer_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
gobj_cat->error()
|
gobj_cat->error()
|
||||||
@ -2673,6 +2681,7 @@ do_read(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpath,
|
|||||||
switch (cdata->_texture_type) {
|
switch (cdata->_texture_type) {
|
||||||
case TT_1d_texture:
|
case TT_1d_texture:
|
||||||
case TT_2d_texture:
|
case TT_2d_texture:
|
||||||
|
case TT_buffer_texture:
|
||||||
z_size = 1;
|
z_size = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4854,7 +4863,8 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (cdata->_texture_type == TT_1d_texture) {
|
if (cdata->_texture_type == TT_1d_texture ||
|
||||||
|
cdata->_texture_type == TT_buffer_texture) {
|
||||||
nassertr(y_size == 1, false);
|
nassertr(y_size == 1, false);
|
||||||
} else if (cdata->_texture_type == TT_cube_map) {
|
} else if (cdata->_texture_type == TT_cube_map) {
|
||||||
nassertr(x_size == y_size, false);
|
nassertr(x_size == y_size, false);
|
||||||
@ -5051,6 +5061,10 @@ do_setup_texture(CData *cdata, Texture::TextureType texture_type,
|
|||||||
cdata->_default_sampler.set_wrap_v(SamplerState::WM_clamp);
|
cdata->_default_sampler.set_wrap_v(SamplerState::WM_clamp);
|
||||||
cdata->_default_sampler.set_wrap_w(SamplerState::WM_clamp);
|
cdata->_default_sampler.set_wrap_w(SamplerState::WM_clamp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TT_buffer_texture:
|
||||||
|
nassertv(y_size == 1 && z_size == 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture_type != TT_2d_texture) {
|
if (texture_type != TT_2d_texture) {
|
||||||
@ -5199,7 +5213,8 @@ do_set_x_size(CData *cdata, int x_size) {
|
|||||||
void Texture::
|
void Texture::
|
||||||
do_set_y_size(CData *cdata, int y_size) {
|
do_set_y_size(CData *cdata, int y_size) {
|
||||||
if (cdata->_y_size != y_size) {
|
if (cdata->_y_size != y_size) {
|
||||||
nassertv(cdata->_texture_type != Texture::TT_1d_texture || y_size == 1);
|
nassertv((cdata->_texture_type != Texture::TT_buffer_texture &&
|
||||||
|
cdata->_texture_type != Texture::TT_1d_texture) || y_size == 1);
|
||||||
cdata->_y_size = y_size;
|
cdata->_y_size = y_size;
|
||||||
cdata->inc_image_modified();
|
cdata->inc_image_modified();
|
||||||
do_clear_ram_image(cdata);
|
do_clear_ram_image(cdata);
|
||||||
@ -7897,6 +7912,10 @@ do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) {
|
|||||||
me.add_uint8(cdata->_format);
|
me.add_uint8(cdata->_format);
|
||||||
me.add_uint8(cdata->_num_components);
|
me.add_uint8(cdata->_num_components);
|
||||||
|
|
||||||
|
if (cdata->_texture_type == TT_buffer_texture) {
|
||||||
|
me.add_uint8(cdata->_usage_hint);
|
||||||
|
}
|
||||||
|
|
||||||
me.add_uint8(cdata->_auto_texture_scale);
|
me.add_uint8(cdata->_auto_texture_scale);
|
||||||
me.add_uint32(cdata->_orig_file_x_size);
|
me.add_uint32(cdata->_orig_file_x_size);
|
||||||
me.add_uint32(cdata->_orig_file_y_size);
|
me.add_uint32(cdata->_orig_file_y_size);
|
||||||
@ -8063,6 +8082,7 @@ make_this_from_bam(const FactoryParams ¶ms) {
|
|||||||
options.set_auto_texture_scale(auto_texture_scale);
|
options.set_auto_texture_scale(auto_texture_scale);
|
||||||
|
|
||||||
switch (texture_type) {
|
switch (texture_type) {
|
||||||
|
case TT_buffer_texture:
|
||||||
case TT_1d_texture:
|
case TT_1d_texture:
|
||||||
case TT_2d_texture:
|
case TT_2d_texture:
|
||||||
if (alpha_filename.empty()) {
|
if (alpha_filename.empty()) {
|
||||||
@ -8124,6 +8144,10 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
|
|||||||
cdata->_format = (Format)scan.get_uint8();
|
cdata->_format = (Format)scan.get_uint8();
|
||||||
cdata->_num_components = scan.get_uint8();
|
cdata->_num_components = scan.get_uint8();
|
||||||
|
|
||||||
|
if (cdata->_texture_type == TT_buffer_texture) {
|
||||||
|
cdata->_usage_hint = (GeomEnums::UsageHint)scan.get_uint8();
|
||||||
|
}
|
||||||
|
|
||||||
cdata->inc_properties_modified();
|
cdata->inc_properties_modified();
|
||||||
|
|
||||||
cdata->_auto_texture_scale = ATS_unspecified;
|
cdata->_auto_texture_scale = ATS_unspecified;
|
||||||
@ -8304,6 +8328,9 @@ CData() {
|
|||||||
// check in do_set_format depending on an uninitialized value.
|
// check in do_set_format depending on an uninitialized value.
|
||||||
_format = F_rgba;
|
_format = F_rgba;
|
||||||
|
|
||||||
|
// Only used for buffer textures.
|
||||||
|
_usage_hint = GeomEnums::UH_unspecified;
|
||||||
|
|
||||||
_pad_x_size = 0;
|
_pad_x_size = 0;
|
||||||
_pad_y_size = 0;
|
_pad_y_size = 0;
|
||||||
_pad_z_size = 0;
|
_pad_z_size = 0;
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "samplerState.h"
|
#include "samplerState.h"
|
||||||
#include "pnmImage.h"
|
#include "pnmImage.h"
|
||||||
#include "colorSpace.h"
|
#include "colorSpace.h"
|
||||||
|
#include "geomEnums.h"
|
||||||
|
|
||||||
class PNMImage;
|
class PNMImage;
|
||||||
class PfmFile;
|
class PfmFile;
|
||||||
@ -82,6 +83,7 @@ PUBLISHED:
|
|||||||
TT_3d_texture,
|
TT_3d_texture,
|
||||||
TT_2d_texture_array,
|
TT_2d_texture_array,
|
||||||
TT_cube_map,
|
TT_cube_map,
|
||||||
|
TT_buffer_texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ComponentType {
|
enum ComponentType {
|
||||||
@ -240,6 +242,8 @@ PUBLISHED:
|
|||||||
INLINE void setup_2d_texture_array(int z_size = 1);
|
INLINE void setup_2d_texture_array(int z_size = 1);
|
||||||
INLINE void setup_2d_texture_array(int x_size, int y_size, int z_size,
|
INLINE void setup_2d_texture_array(int x_size, int y_size, int z_size,
|
||||||
ComponentType component_type, Format format);
|
ComponentType component_type, Format format);
|
||||||
|
INLINE void setup_buffer_texture(int size, ComponentType component_type,
|
||||||
|
Format format, GeomEnums::UsageHint usage);
|
||||||
void generate_normalization_cube_map(int size);
|
void generate_normalization_cube_map(int size);
|
||||||
void generate_alpha_scale_map();
|
void generate_alpha_scale_map();
|
||||||
|
|
||||||
@ -304,6 +308,7 @@ PUBLISHED:
|
|||||||
INLINE TextureType get_texture_type() const;
|
INLINE TextureType get_texture_type() const;
|
||||||
INLINE Format get_format() const;
|
INLINE Format get_format() const;
|
||||||
INLINE ComponentType get_component_type() const;
|
INLINE ComponentType get_component_type() const;
|
||||||
|
INLINE GeomEnums::UsageHint get_usage_hint() const;
|
||||||
|
|
||||||
INLINE void set_wrap_u(WrapMode wrap);
|
INLINE void set_wrap_u(WrapMode wrap);
|
||||||
INLINE void set_wrap_v(WrapMode wrap);
|
INLINE void set_wrap_v(WrapMode wrap);
|
||||||
@ -829,6 +834,7 @@ protected:
|
|||||||
TextureType _texture_type;
|
TextureType _texture_type;
|
||||||
Format _format;
|
Format _format;
|
||||||
ComponentType _component_type;
|
ComponentType _component_type;
|
||||||
|
GeomEnums::UsageHint _usage_hint;
|
||||||
|
|
||||||
bool _loaded_from_image;
|
bool _loaded_from_image;
|
||||||
bool _loaded_from_txo;
|
bool _loaded_from_txo;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user