|
@@ -101,6 +101,8 @@
|
|
|
#define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
|
|
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
|
|
|
|
|
+#define _GL_TEXTURE_EXTERNAL_OES 0x8D65
|
|
|
+
|
|
|
#ifndef GLES_OVER_GL
|
|
|
#define glClearDepth glClearDepthf
|
|
|
#endif
|
|
@@ -663,6 +665,10 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
|
|
|
texture->target = GL_TEXTURE_2D;
|
|
|
texture->images.resize(1);
|
|
|
} break;
|
|
|
+ case VS::TEXTURE_TYPE_EXTERNAL: {
|
|
|
+ texture->target = _GL_TEXTURE_EXTERNAL_OES;
|
|
|
+ texture->images.resize(0);
|
|
|
+ } break;
|
|
|
case VS::TEXTURE_TYPE_CUBEMAP: {
|
|
|
texture->target = GL_TEXTURE_CUBE_MAP;
|
|
|
texture->images.resize(6);
|
|
@@ -677,39 +683,55 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
|
|
|
} break;
|
|
|
}
|
|
|
|
|
|
- texture->is_npot_repeat_mipmap = false;
|
|
|
+ if (p_type != VS::TEXTURE_TYPE_EXTERNAL) {
|
|
|
+ texture->is_npot_repeat_mipmap = false;
|
|
|
#ifdef JAVASCRIPT_ENABLED
|
|
|
- // WebGL 2.0 on browsers does not seem to properly support compressed non power-of-two (NPOT)
|
|
|
- // textures with repeat/mipmaps, even though NPOT textures should be supported as per the spec.
|
|
|
- // Force decompressing them to work it around on WebGL 2.0 at a performance cost (GH-33058).
|
|
|
- int po2_width = next_power_of_2(p_width);
|
|
|
- int po2_height = next_power_of_2(p_height);
|
|
|
- bool is_po2 = p_width == po2_width && p_height == po2_height;
|
|
|
-
|
|
|
- if (!is_po2 && (p_flags & VS::TEXTURE_FLAG_REPEAT || p_flags & VS::TEXTURE_FLAG_MIPMAPS)) {
|
|
|
- texture->is_npot_repeat_mipmap = true;
|
|
|
- }
|
|
|
+ // WebGL 2.0 on browsers does not seem to properly support compressed non power-of-two (NPOT)
|
|
|
+ // textures with repeat/mipmaps, even though NPOT textures should be supported as per the spec.
|
|
|
+ // Force decompressing them to work it around on WebGL 2.0 at a performance cost (GH-33058).
|
|
|
+ int po2_width = next_power_of_2(p_width);
|
|
|
+ int po2_height = next_power_of_2(p_height);
|
|
|
+ bool is_po2 = p_width == po2_width && p_height == po2_height;
|
|
|
+
|
|
|
+ if (!is_po2 && (p_flags & VS::TEXTURE_FLAG_REPEAT || p_flags & VS::TEXTURE_FLAG_MIPMAPS)) {
|
|
|
+ texture->is_npot_repeat_mipmap = true;
|
|
|
+ }
|
|
|
#endif // JAVASCRIPT_ENABLED
|
|
|
|
|
|
- Image::Format real_format;
|
|
|
- _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, srgb, texture->is_npot_repeat_mipmap);
|
|
|
+ Image::Format real_format;
|
|
|
+ _get_gl_image_and_format(Ref<Image>(),
|
|
|
+ texture->format,
|
|
|
+ texture->flags,
|
|
|
+ real_format,
|
|
|
+ format,
|
|
|
+ internal_format,
|
|
|
+ type,
|
|
|
+ compressed,
|
|
|
+ srgb,
|
|
|
+ texture->is_npot_repeat_mipmap);
|
|
|
|
|
|
- texture->alloc_width = texture->width;
|
|
|
- texture->alloc_height = texture->height;
|
|
|
- texture->alloc_depth = texture->depth;
|
|
|
+ texture->alloc_width = texture->width;
|
|
|
+ texture->alloc_height = texture->height;
|
|
|
+ texture->alloc_depth = texture->depth;
|
|
|
|
|
|
- texture->gl_format_cache = format;
|
|
|
- texture->gl_type_cache = type;
|
|
|
- texture->gl_internal_format_cache = internal_format;
|
|
|
- texture->compressed = compressed;
|
|
|
- texture->srgb = srgb;
|
|
|
- texture->data_size = 0;
|
|
|
- texture->mipmaps = 1;
|
|
|
+ texture->gl_format_cache = format;
|
|
|
+ texture->gl_type_cache = type;
|
|
|
+ texture->gl_internal_format_cache = internal_format;
|
|
|
+ texture->compressed = compressed;
|
|
|
+ texture->srgb = srgb;
|
|
|
+ texture->data_size = 0;
|
|
|
+ texture->mipmaps = 1;
|
|
|
+ }
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
glBindTexture(texture->target, texture->tex_id);
|
|
|
|
|
|
- if (p_type == VS::TEXTURE_TYPE_3D || p_type == VS::TEXTURE_TYPE_2D_ARRAY) {
|
|
|
+ if (p_type == VS::TEXTURE_TYPE_EXTERNAL) {
|
|
|
+ glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
+ glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
+ glTexParameteri(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
+ glTexParameteri(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
+ } else if (p_type == VS::TEXTURE_TYPE_3D || p_type == VS::TEXTURE_TYPE_2D_ARRAY) {
|
|
|
|
|
|
int width = p_width;
|
|
|
int height = p_height;
|
|
@@ -757,6 +779,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
|
|
|
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(texture->type == VS::TEXTURE_TYPE_EXTERNAL);
|
|
|
|
|
|
GLenum type;
|
|
|
GLenum format;
|
|
@@ -788,7 +811,8 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
|
|
|
GLenum blit_target = GL_TEXTURE_2D;
|
|
|
|
|
|
switch (texture->type) {
|
|
|
- case VS::TEXTURE_TYPE_2D: {
|
|
|
+ case VS::TEXTURE_TYPE_2D:
|
|
|
+ case VS::TEXTURE_TYPE_EXTERNAL: {
|
|
|
blit_target = GL_TEXTURE_2D;
|
|
|
} break;
|
|
|
case VS::TEXTURE_TYPE_CUBEMAP: {
|
|
@@ -989,6 +1013,7 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
|
|
|
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);
|
|
|
+ ERR_FAIL_COND(texture->type == VS::TEXTURE_TYPE_EXTERNAL);
|
|
|
|
|
|
GLenum type;
|
|
|
GLenum format;
|
|
@@ -1008,7 +1033,8 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
|
|
|
GLenum blit_target = GL_TEXTURE_2D;
|
|
|
|
|
|
switch (texture->type) {
|
|
|
- case VS::TEXTURE_TYPE_2D: {
|
|
|
+ case VS::TEXTURE_TYPE_2D:
|
|
|
+ case VS::TEXTURE_TYPE_EXTERNAL: {
|
|
|
blit_target = GL_TEXTURE_2D;
|
|
|
} break;
|
|
|
case VS::TEXTURE_TYPE_CUBEMAP: {
|
|
@@ -2466,6 +2492,7 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
|
|
|
case ShaderLanguage::TYPE_MAT3: pi.type = Variant::BASIS; break;
|
|
|
case ShaderLanguage::TYPE_MAT4: pi.type = Variant::TRANSFORM; break;
|
|
|
case ShaderLanguage::TYPE_SAMPLER2D:
|
|
|
+ case ShaderLanguage::TYPE_SAMPLEREXT:
|
|
|
case ShaderLanguage::TYPE_ISAMPLER2D:
|
|
|
case ShaderLanguage::TYPE_USAMPLER2D: {
|
|
|
|
|
@@ -2524,6 +2551,34 @@ RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const
|
|
|
return E->get();
|
|
|
}
|
|
|
|
|
|
+void RasterizerStorageGLES3::shader_add_custom_define(RID p_shader, const String &p_define) {
|
|
|
+
|
|
|
+ Shader *shader = shader_owner.get(p_shader);
|
|
|
+ ERR_FAIL_COND(!shader);
|
|
|
+
|
|
|
+ shader->shader->add_custom_define(p_define);
|
|
|
+
|
|
|
+ _shader_make_dirty(shader);
|
|
|
+}
|
|
|
+
|
|
|
+void RasterizerStorageGLES3::shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const {
|
|
|
+
|
|
|
+ Shader *shader = shader_owner.get(p_shader);
|
|
|
+ ERR_FAIL_COND(!shader);
|
|
|
+
|
|
|
+ shader->shader->get_custom_defines(p_defines);
|
|
|
+}
|
|
|
+
|
|
|
+void RasterizerStorageGLES3::shader_clear_custom_defines(RID p_shader) {
|
|
|
+
|
|
|
+ Shader *shader = shader_owner.get(p_shader);
|
|
|
+ ERR_FAIL_COND(!shader);
|
|
|
+
|
|
|
+ shader->shader->clear_custom_defines();
|
|
|
+
|
|
|
+ _shader_make_dirty(shader);
|
|
|
+}
|
|
|
+
|
|
|
/* COMMON MATERIAL API */
|
|
|
|
|
|
void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
|