Merge pull request #23125 from JFonS/fix_texture_get_data
Implement rasterizer texture_get_data on OpenGL ES
This commit is contained in:
commit
9c195b57a0
|
@ -613,8 +613,72 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
|
|||
return Ref<Image>(img);
|
||||
#else
|
||||
|
||||
ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
|
||||
ERR_FAIL_V(Ref<Image>());
|
||||
Image::Format real_format;
|
||||
GLenum gl_format;
|
||||
GLenum gl_internal_format;
|
||||
GLenum gl_type;
|
||||
bool compressed;
|
||||
_get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed);
|
||||
|
||||
PoolVector<uint8_t> data;
|
||||
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
|
||||
|
||||
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
|
||||
PoolVector<uint8_t>::Write wb = data.write();
|
||||
|
||||
GLuint temp_framebuffer;
|
||||
glGenFramebuffers(1, &temp_framebuffer);
|
||||
|
||||
GLuint temp_color_texture;
|
||||
glGenTextures(1, &temp_color_texture);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, temp_color_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
|
||||
|
||||
glViewport(0, 0, texture->alloc_width, texture->alloc_height);
|
||||
|
||||
shaders.copy.bind();
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
bind_quad_array();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]);
|
||||
|
||||
glDeleteTextures(1, &temp_color_texture);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &temp_framebuffer);
|
||||
|
||||
wb = PoolVector<uint8_t>::Write();
|
||||
|
||||
data.resize(data_size);
|
||||
|
||||
Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data));
|
||||
if (!texture->compressed) {
|
||||
img->convert(real_format);
|
||||
}
|
||||
|
||||
return Ref<Image>(img);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1116,8 +1116,78 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
|
|||
return Ref<Image>(img);
|
||||
#else
|
||||
|
||||
ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES");
|
||||
ERR_FAIL_V(Ref<Image>());
|
||||
Image::Format real_format;
|
||||
GLenum gl_format;
|
||||
GLenum gl_internal_format;
|
||||
GLenum gl_type;
|
||||
bool compressed;
|
||||
bool srgb;
|
||||
_get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb);
|
||||
|
||||
PoolVector<uint8_t> data;
|
||||
|
||||
int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
|
||||
|
||||
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
|
||||
PoolVector<uint8_t>::Write wb = data.write();
|
||||
|
||||
GLuint temp_framebuffer;
|
||||
glGenFramebuffers(1, &temp_framebuffer);
|
||||
|
||||
GLuint temp_color_texture;
|
||||
glGenTextures(1, &temp_color_texture);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, temp_color_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
print_line(itos(texture->alloc_width) + " xx " + itos(texture->alloc_height) + " -> " + itos(real_format));
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
|
||||
|
||||
glViewport(0, 0, texture->alloc_width, texture->alloc_height);
|
||||
|
||||
shaders.copy.bind();
|
||||
|
||||
shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, !srgb);
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glBindVertexArray(resources.quadie_array);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &wb[0]);
|
||||
|
||||
shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false);
|
||||
|
||||
glDeleteTextures(1, &temp_color_texture);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &temp_framebuffer);
|
||||
|
||||
wb = PoolVector<uint8_t>::Write();
|
||||
|
||||
data.resize(data_size);
|
||||
|
||||
Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data));
|
||||
if (!texture->compressed) {
|
||||
img->convert(real_format);
|
||||
}
|
||||
|
||||
return Ref<Image>(img);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue