Merge pull request #18495 from Zylann/partial_texture_update
Added partial texture update to VisualServer
This commit is contained in:
commit
b96cd25305
9 changed files with 64 additions and 0 deletions
|
@ -452,6 +452,11 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
|
|||
texture->mipmaps = mipmaps;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES2::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side) {
|
||||
// TODO
|
||||
ERR_PRINT("Not implemented (ask Karroffel to do it :p)");
|
||||
}
|
||||
|
||||
Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
|
||||
|
||||
Texture *texture = texture_owner.getornull(p_texture);
|
||||
|
|
|
@ -237,6 +237,7 @@ public:
|
|||
virtual RID texture_create();
|
||||
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
|
||||
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
|
||||
virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
|
||||
virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
|
||||
virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
|
||||
virtual uint32_t texture_get_flags(RID p_texture) const;
|
||||
|
|
|
@ -828,6 +828,58 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
|
|||
//texture_set_flags(p_texture,texture->flags);
|
||||
}
|
||||
|
||||
// Uploads pixel data to a sub-region of a texture, for the specified mipmap.
|
||||
// The texture pixels must have been allocated before, because most features seen in texture_set_data() make no sense in a partial update.
|
||||
// TODO If we want this to be usable without pre-filling pixels with a full image, we have to call glTexImage2D() with null data.
|
||||
void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side) {
|
||||
|
||||
Texture *texture = texture_owner.get(p_texture);
|
||||
|
||||
ERR_FAIL_COND(!texture);
|
||||
ERR_FAIL_COND(!texture->active);
|
||||
ERR_FAIL_COND(texture->render_target);
|
||||
ERR_FAIL_COND(texture->format != p_image->get_format());
|
||||
ERR_FAIL_COND(p_image.is_null());
|
||||
ERR_FAIL_COND(src_w <= 0 || src_h <= 0);
|
||||
ERR_FAIL_COND(src_x < 0 || src_y < 0 || src_x + src_w > p_image->get_width() || src_y + src_h > p_image->get_height());
|
||||
ERR_FAIL_COND(dst_x < 0 || dst_y < 0 || dst_x + src_w > texture->alloc_width || dst_y + src_h > texture->alloc_height);
|
||||
ERR_FAIL_COND(p_dst_mip < 0 || p_dst_mip >= texture->mipmaps);
|
||||
|
||||
GLenum type;
|
||||
GLenum format;
|
||||
GLenum internal_format;
|
||||
bool compressed;
|
||||
bool srgb;
|
||||
|
||||
// Because OpenGL wants data as a dense array, we have to extract the sub-image if the source rect isn't the full image
|
||||
Ref<Image> p_sub_img = p_image;
|
||||
if (src_x > 0 || src_y > 0 || src_w != p_image->get_width() || src_h != p_image->get_height()) {
|
||||
p_sub_img = p_image->get_rect(Rect2(src_x, src_y, src_w, src_h));
|
||||
}
|
||||
|
||||
Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
|
||||
|
||||
GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
|
||||
|
||||
PoolVector<uint8_t>::Read read = img->get_data().read();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(texture->target, texture->tex_id);
|
||||
|
||||
int src_data_size = img->get_data().size();
|
||||
int src_ofs = 0;
|
||||
|
||||
if (texture->compressed) {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glCompressedTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, internal_format, src_data_size, &read[src_ofs]);
|
||||
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
// `format` has to match the internal_format used when the texture was created
|
||||
glTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, format, type, &read[src_ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
|
||||
|
||||
Texture *texture = texture_owner.get(p_texture);
|
||||
|
|
|
@ -340,6 +340,7 @@ public:
|
|||
virtual RID texture_create();
|
||||
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
|
||||
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
|
||||
virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
|
||||
virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
|
||||
virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
|
||||
virtual uint32_t texture_get_flags(RID p_texture) const;
|
||||
|
|
|
@ -175,6 +175,7 @@ public:
|
|||
virtual RID texture_create() = 0;
|
||||
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT) = 0;
|
||||
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
|
||||
virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
|
||||
virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
|
||||
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
|
||||
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
|
||||
|
|
|
@ -148,6 +148,7 @@ public:
|
|||
BIND0R(RID, texture_create)
|
||||
BIND5(texture_allocate, RID, int, int, Image::Format, uint32_t)
|
||||
BIND3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
|
||||
BIND10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
|
||||
BIND2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
|
||||
BIND2(texture_set_flags, RID, uint32_t)
|
||||
BIND1RC(uint32_t, texture_get_flags, RID)
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
FUNCRID(texture)
|
||||
FUNC5(texture_allocate, RID, int, int, Image::Format, uint32_t)
|
||||
FUNC3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
|
||||
FUNC10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
|
||||
FUNC2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
|
||||
FUNC2(texture_set_flags, RID, uint32_t)
|
||||
FUNC1RC(uint32_t, texture_get_flags, RID)
|
||||
|
|
|
@ -1528,6 +1528,7 @@ void VisualServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
|
||||
ClassDB::bind_method(D_METHOD("texture_allocate", "texture", "width", "height", "format", "flags"), &VisualServer::texture_allocate, DEFVAL(TEXTURE_FLAGS_DEFAULT));
|
||||
ClassDB::bind_method(D_METHOD("texture_set_data", "texture", "image", "cube_side"), &VisualServer::texture_set_data, DEFVAL(CUBEMAP_LEFT));
|
||||
ClassDB::bind_method(D_METHOD("texture_set_data_partial", "texture", "image", "src_x", "src_y", "src_w", "src_h", "dst_x", "dst_y", "dst_mip", "cube_side"), &VisualServer::texture_set_data_partial, DEFVAL(CUBEMAP_LEFT));
|
||||
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "cube_side"), &VisualServer::texture_get_data, DEFVAL(CUBEMAP_LEFT));
|
||||
ClassDB::bind_method(D_METHOD("texture_set_flags", "texture", "flags"), &VisualServer::texture_set_flags);
|
||||
ClassDB::bind_method(D_METHOD("texture_get_flags", "texture"), &VisualServer::texture_get_flags);
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
RID texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
|
||||
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT) = 0;
|
||||
virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
|
||||
virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
|
||||
virtual Ref<Image> texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
|
||||
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
|
||||
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
|
||||
|
|
Loading…
Reference in a new issue