mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-18 12:43:44 -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// Access: Published
|
||||
@ -469,6 +485,16 @@ get_supports_cube_map() const {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -185,6 +185,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
_max_3d_texture_dimension = 0;
|
||||
_max_2d_texture_array_layers = 0;
|
||||
_max_cube_map_dimension = 0;
|
||||
_max_buffer_texture_size = 0;
|
||||
|
||||
// Assume we don't support these fairly advanced texture combiner
|
||||
// modes.
|
||||
@ -195,6 +196,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
_supports_3d_texture = false;
|
||||
_supports_2d_texture_array = false;
|
||||
_supports_cube_map = false;
|
||||
_supports_buffer_texture = false;
|
||||
_supports_tex_non_pow2 = false;
|
||||
_supports_texture_srgb = false;
|
||||
_supports_compressed_texture = false;
|
||||
|
@ -121,6 +121,7 @@ PUBLISHED:
|
||||
INLINE int get_max_3d_texture_dimension() const;
|
||||
INLINE int get_max_2d_texture_array_layers() const; //z axis
|
||||
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_saved_result() const;
|
||||
@ -129,6 +130,7 @@ PUBLISHED:
|
||||
INLINE bool get_supports_3d_texture() const;
|
||||
INLINE bool get_supports_2d_texture_array() 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_texture_srgb() const;
|
||||
|
||||
@ -476,6 +478,7 @@ protected:
|
||||
int _max_3d_texture_dimension;
|
||||
int _max_2d_texture_array_layers; //on the z axis
|
||||
int _max_cube_map_dimension;
|
||||
int _max_buffer_texture_size;
|
||||
|
||||
bool _supports_texture_combine;
|
||||
bool _supports_texture_saved_result;
|
||||
@ -484,6 +487,7 @@ protected:
|
||||
bool _supports_3d_texture;
|
||||
bool _supports_2d_texture_array;
|
||||
bool _supports_cube_map;
|
||||
bool _supports_buffer_texture;
|
||||
bool _supports_tex_non_pow2;
|
||||
bool _supports_texture_srgb;
|
||||
|
||||
|
@ -854,6 +854,17 @@ reset() {
|
||||
}
|
||||
#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;
|
||||
if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
|
||||
_supports_texture_srgb = true;
|
||||
@ -1941,6 +1952,7 @@ reset() {
|
||||
GLint max_3d_texture_size = 0;
|
||||
GLint max_2d_texture_array_layers = 0;
|
||||
GLint max_cube_map_size = 0;
|
||||
GLint max_buffer_texture_size = 0;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
_max_texture_dimension = max_texture_size;
|
||||
@ -1966,6 +1978,15 @@ reset() {
|
||||
_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;
|
||||
#ifndef OPENGLES
|
||||
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";
|
||||
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:
|
||||
break;
|
||||
@ -7362,27 +7392,35 @@ get_texture_target(Texture::TextureType texture_type) const {
|
||||
return GL_TEXTURE_2D;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
if (_supports_3d_texture) {
|
||||
#ifndef OPENGLES_1
|
||||
if (_supports_3d_texture) {
|
||||
return GL_TEXTURE_3D;
|
||||
#endif
|
||||
} else {
|
||||
return GL_NONE;
|
||||
}
|
||||
#endif
|
||||
return GL_NONE;
|
||||
|
||||
case Texture::TT_2d_texture_array:
|
||||
if (_supports_2d_texture_array) {
|
||||
#ifndef OPENGLES
|
||||
if (_supports_2d_texture_array) {
|
||||
return GL_TEXTURE_2D_ARRAY_EXT;
|
||||
#endif
|
||||
} else {
|
||||
return GL_NONE;
|
||||
}
|
||||
#endif
|
||||
return GL_NONE;
|
||||
|
||||
case Texture::TT_cube_map:
|
||||
if (_supports_cube_map) {
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
} else {
|
||||
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";
|
||||
@ -10252,6 +10290,12 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
|
||||
// Unsupported target (e.g. 3-d texturing on GL 1.1).
|
||||
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.
|
||||
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
|
||||
// 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 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;
|
||||
break;
|
||||
|
||||
case Texture::TT_buffer_texture:
|
||||
max_dimension_x = _max_buffer_texture_size;
|
||||
max_dimension_y = 1;
|
||||
max_dimension_z = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
max_dimension_x = _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());
|
||||
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;
|
||||
if (!gtc->_has_storage ||
|
||||
gtc->_uses_mipmaps != uses_mipmaps ||
|
||||
@ -10640,6 +10698,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
gtc->_depth != depth) {
|
||||
// We need to reload a new GL Texture object.
|
||||
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) {
|
||||
@ -10648,13 +10712,26 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
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
|
||||
// Panda (or not at all), and how many mipmap levels should be created.
|
||||
gtc->_generate_mipmaps = false;
|
||||
@ -10736,6 +10813,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
}
|
||||
|
||||
switch (tex->get_texture_type()) {
|
||||
case Texture::TT_buffer_texture:
|
||||
// Won't get here, but squelch compiler warning
|
||||
case Texture::TT_1d_texture:
|
||||
_glTexStorage1D(target, num_levels, internal_format, width);
|
||||
break;
|
||||
@ -11095,6 +11174,17 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
break;
|
||||
#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:
|
||||
if (image_compression == Texture::CM_off) {
|
||||
if (n==0) {
|
||||
@ -11248,6 +11338,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_2D_ARRAY_EXT:
|
||||
if (_supports_2d_texture_array) {
|
||||
@ -11265,7 +11356,19 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
return false;
|
||||
}
|
||||
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:
|
||||
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.
|
||||
page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
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;
|
||||
@ -11431,20 +11540,20 @@ get_texture_memory_size(Texture *tex) {
|
||||
luminance_size, intensity_size;
|
||||
GLint depth_size = 0;
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_RED_SIZE, &red_size);
|
||||
GL_TEXTURE_RED_SIZE, &red_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
if (_supports_depth_texture) {
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
||||
GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
||||
}
|
||||
|
||||
GLint width = 1, height = 1, depth = 1;
|
||||
|
@ -693,6 +693,10 @@ public:
|
||||
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
|
||||
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
|
||||
|
||||
#ifndef OPENGLES
|
||||
PFNGLTEXBUFFERPROC _glTexBuffer;
|
||||
#endif
|
||||
|
||||
bool _supports_clear_texture;
|
||||
#ifndef OPENGLES
|
||||
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
|
||||
|
@ -602,16 +602,19 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_BUFFER:
|
||||
case GL_UNSIGNED_INT_SAMPLER_1D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||
case GL_SAMPLER_1D_SHADOW:
|
||||
case GL_SAMPLER_1D:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_SAMPLER_BUFFER:
|
||||
#endif // !OPENGLES
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
@ -620,7 +623,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
Shader::ShaderTexSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._name = InternalName::make(param_name);
|
||||
bind._desired_type = Texture::TT_2d_texture_array;
|
||||
bind._desired_type = Texture::TT_2d_texture;
|
||||
bind._stage = texunitno++;
|
||||
if (get_sampler_texture_type(bind._desired_type, param_type)) {
|
||||
_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_CUBE_EXT:
|
||||
case GL_IMAGE_2D_ARRAY_EXT:
|
||||
case GL_IMAGE_BUFFER_EXT:
|
||||
case GL_INT_IMAGE_1D_EXT:
|
||||
case GL_INT_IMAGE_2D_EXT:
|
||||
case GL_INT_IMAGE_3D_EXT:
|
||||
case GL_INT_IMAGE_CUBE_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_2D_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE_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
|
||||
// bind once and then forget about it.
|
||||
_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";
|
||||
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
|
||||
|
||||
default:
|
||||
@ -1509,6 +1527,12 @@ disable_shader_texture_bindings() {
|
||||
case Texture::TT_cube_map:
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
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;
|
||||
|
||||
glGenTextures(1, &_index);
|
||||
_buffer = 0;
|
||||
|
||||
_handle = 0;
|
||||
_has_storage = false;
|
||||
|
@ -34,6 +34,11 @@ CLP(TextureContext)::
|
||||
|
||||
glDeleteTextures(1, &_index);
|
||||
_index = 0;
|
||||
|
||||
if (_buffer != 0) {
|
||||
_glgsg->_glDeleteBuffers(1, &_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -88,6 +93,11 @@ reset_data() {
|
||||
// Free the texture resources.
|
||||
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
|
||||
// re-load the texture later.
|
||||
glGenTextures(1, &_index);
|
||||
|
@ -48,6 +48,9 @@ public:
|
||||
// This is the GL "name" of the texture object.
|
||||
GLuint _index;
|
||||
|
||||
// This is only used for buffer textures.
|
||||
GLuint _buffer;
|
||||
|
||||
// This is the bindless "handle" to the texture object.
|
||||
GLuint64 _handle;
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// Access: Published
|
||||
@ -886,6 +906,18 @@ get_component_type() const {
|
||||
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
|
||||
// Access: Published
|
||||
|
@ -1524,6 +1524,10 @@ write(ostream &out, int indent_level) const {
|
||||
case TT_cube_map:
|
||||
out << "cube map, " << cdata->_x_size << " x " << cdata->_y_size;
|
||||
break;
|
||||
|
||||
case TT_buffer_texture:
|
||||
out << "buffer, " << cdata->_x_size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cdata->_num_views > 1) {
|
||||
@ -1924,6 +1928,8 @@ format_texture_type(TextureType tt) {
|
||||
return "2d_texture_array";
|
||||
case TT_cube_map:
|
||||
return "cube_map";
|
||||
case TT_buffer_texture:
|
||||
return "buffer_texture";
|
||||
}
|
||||
return "**invalid**";
|
||||
}
|
||||
@ -1946,6 +1952,8 @@ string_texture_type(const string &str) {
|
||||
return TT_2d_texture_array;
|
||||
} else if (cmp_nocase(str, "cube_map") == 0) {
|
||||
return TT_cube_map;
|
||||
} else if (cmp_nocase(str, "buffer_texture") == 0) {
|
||||
return TT_buffer_texture;
|
||||
}
|
||||
|
||||
gobj_cat->error()
|
||||
@ -2673,6 +2681,7 @@ do_read(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
switch (cdata->_texture_type) {
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
case TT_buffer_texture:
|
||||
z_size = 1;
|
||||
break;
|
||||
|
||||
@ -4854,7 +4863,8 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com
|
||||
}
|
||||
|
||||
#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);
|
||||
} else if (cdata->_texture_type == TT_cube_map) {
|
||||
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_w(SamplerState::WM_clamp);
|
||||
break;
|
||||
|
||||
case TT_buffer_texture:
|
||||
nassertv(y_size == 1 && z_size == 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (texture_type != TT_2d_texture) {
|
||||
@ -5199,7 +5213,8 @@ do_set_x_size(CData *cdata, int x_size) {
|
||||
void Texture::
|
||||
do_set_y_size(CData *cdata, int 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->inc_image_modified();
|
||||
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->_num_components);
|
||||
|
||||
if (cdata->_texture_type == TT_buffer_texture) {
|
||||
me.add_uint8(cdata->_usage_hint);
|
||||
}
|
||||
|
||||
me.add_uint8(cdata->_auto_texture_scale);
|
||||
me.add_uint32(cdata->_orig_file_x_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);
|
||||
|
||||
switch (texture_type) {
|
||||
case TT_buffer_texture:
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
if (alpha_filename.empty()) {
|
||||
@ -8124,6 +8144,10 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
|
||||
cdata->_format = (Format)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->_auto_texture_scale = ATS_unspecified;
|
||||
@ -8304,6 +8328,9 @@ CData() {
|
||||
// check in do_set_format depending on an uninitialized value.
|
||||
_format = F_rgba;
|
||||
|
||||
// Only used for buffer textures.
|
||||
_usage_hint = GeomEnums::UH_unspecified;
|
||||
|
||||
_pad_x_size = 0;
|
||||
_pad_y_size = 0;
|
||||
_pad_z_size = 0;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "samplerState.h"
|
||||
#include "pnmImage.h"
|
||||
#include "colorSpace.h"
|
||||
#include "geomEnums.h"
|
||||
|
||||
class PNMImage;
|
||||
class PfmFile;
|
||||
@ -82,6 +83,7 @@ PUBLISHED:
|
||||
TT_3d_texture,
|
||||
TT_2d_texture_array,
|
||||
TT_cube_map,
|
||||
TT_buffer_texture,
|
||||
};
|
||||
|
||||
enum ComponentType {
|
||||
@ -240,6 +242,8 @@ PUBLISHED:
|
||||
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,
|
||||
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_alpha_scale_map();
|
||||
|
||||
@ -304,6 +308,7 @@ PUBLISHED:
|
||||
INLINE TextureType get_texture_type() const;
|
||||
INLINE Format get_format() 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_v(WrapMode wrap);
|
||||
@ -829,6 +834,7 @@ protected:
|
||||
TextureType _texture_type;
|
||||
Format _format;
|
||||
ComponentType _component_type;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
bool _loaded_from_image;
|
||||
bool _loaded_from_txo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user