summaryrefslogtreecommitdiffstats
path: root/scene/resources/texture_rd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/texture_rd.cpp')
-rw-r--r--scene/resources/texture_rd.cpp346
1 files changed, 346 insertions, 0 deletions
diff --git a/scene/resources/texture_rd.cpp b/scene/resources/texture_rd.cpp
new file mode 100644
index 0000000000..6f25af6863
--- /dev/null
+++ b/scene/resources/texture_rd.cpp
@@ -0,0 +1,346 @@
+/**************************************************************************/
+/* texture_rd.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "texture_rd.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Texture2DRD
+
+void Texture2DRD::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture_rd_rid", "texture_rd_rid"), &Texture2DRD::set_texture_rd_rid);
+ ClassDB::bind_method(D_METHOD("get_texture_rd_rid"), &Texture2DRD::get_texture_rd_rid);
+
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid"), "set_texture_rd_rid", "get_texture_rd_rid");
+}
+
+int Texture2DRD::get_width() const {
+ return size.width;
+}
+
+int Texture2DRD::get_height() const {
+ return size.height;
+}
+
+RID Texture2DRD::get_rid() const {
+ if (texture_rid.is_null()) {
+ // We are in trouble, create something temporary.
+ texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create();
+ }
+
+ return texture_rid;
+}
+
+bool Texture2DRD::has_alpha() const {
+ return false;
+}
+
+Ref<Image> Texture2DRD::get_image() const {
+ ERR_FAIL_NULL_V(RS::get_singleton(), Ref<Image>());
+ if (texture_rid.is_valid()) {
+ return RS::get_singleton()->texture_2d_get(texture_rid);
+ } else {
+ return Ref<Image>();
+ }
+}
+
+void Texture2DRD::set_texture_rd_rid(RID p_texture_rd_rid) {
+ ERR_FAIL_NULL(RS::get_singleton());
+
+ if (p_texture_rd_rid.is_valid()) {
+ ERR_FAIL_NULL(RD::get_singleton());
+ ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid));
+
+ RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid);
+ ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D);
+ ERR_FAIL_COND(tf.depth > 1);
+ ERR_FAIL_COND(tf.array_layers > 1);
+
+ size.width = tf.width;
+ size.height = tf.height;
+
+ texture_rd_rid = p_texture_rd_rid;
+
+ if (texture_rid.is_valid()) {
+ RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid));
+ } else {
+ texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid);
+ }
+
+ notify_property_list_changed();
+ emit_changed();
+ } else if (texture_rid.is_valid()) {
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ size = Size2i();
+
+ notify_property_list_changed();
+ emit_changed();
+ }
+}
+
+RID Texture2DRD::get_texture_rd_rid() const {
+ return texture_rd_rid;
+}
+
+Texture2DRD::Texture2DRD() {
+ size = Size2i();
+}
+
+Texture2DRD::~Texture2DRD() {
+ if (texture_rid.is_valid()) {
+ ERR_FAIL_NULL(RS::get_singleton());
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+// TextureLayeredRD
+
+void TextureLayeredRD::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture_rd_rid", "texture_rd_rid"), &TextureLayeredRD::set_texture_rd_rid);
+ ClassDB::bind_method(D_METHOD("get_texture_rd_rid"), &TextureLayeredRD::get_texture_rd_rid);
+
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid"), "set_texture_rd_rid", "get_texture_rd_rid");
+}
+
+TextureLayered::LayeredType TextureLayeredRD::get_layered_type() const {
+ return layer_type;
+}
+
+Image::Format TextureLayeredRD::get_format() const {
+ return image_format;
+}
+
+int TextureLayeredRD::get_width() const {
+ return size.width;
+}
+
+int TextureLayeredRD::get_height() const {
+ return size.height;
+}
+
+int TextureLayeredRD::get_layers() const {
+ return (int)layers;
+}
+
+bool TextureLayeredRD::has_mipmaps() const {
+ return mipmaps > 1;
+}
+
+RID TextureLayeredRD::get_rid() const {
+ if (texture_rid.is_null()) {
+ // We are in trouble, create something temporary.
+ texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create();
+ }
+
+ return texture_rid;
+}
+
+Ref<Image> TextureLayeredRD::get_layer_data(int p_layer) const {
+ ERR_FAIL_INDEX_V(p_layer, (int)layers, Ref<Image>());
+ return RS::get_singleton()->texture_2d_layer_get(texture_rid, p_layer);
+}
+
+void TextureLayeredRD::set_texture_rd_rid(RID p_texture_rd_rid) {
+ ERR_FAIL_NULL(RS::get_singleton());
+
+ if (p_texture_rd_rid.is_valid()) {
+ ERR_FAIL_NULL(RD::get_singleton());
+ ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid));
+
+ RS::TextureLayeredType rs_layer_type;
+ RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid);
+ ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY);
+ ERR_FAIL_COND(tf.depth > 1);
+ switch (layer_type) {
+ case LAYERED_TYPE_2D_ARRAY: {
+ ERR_FAIL_COND(tf.array_layers <= 1);
+ rs_layer_type = RS::TEXTURE_LAYERED_2D_ARRAY;
+ } break;
+ case LAYERED_TYPE_CUBEMAP: {
+ ERR_FAIL_COND(tf.array_layers != 6);
+ rs_layer_type = RS::TEXTURE_LAYERED_CUBEMAP;
+ } break;
+ case LAYERED_TYPE_CUBEMAP_ARRAY: {
+ ERR_FAIL_COND((tf.array_layers == 0) || ((tf.array_layers % 6) != 0));
+ rs_layer_type = RS::TEXTURE_LAYERED_CUBEMAP_ARRAY;
+ } break;
+ default: {
+ ERR_FAIL_MSG("Unknown layer type selected");
+ } break;
+ }
+
+ size.width = tf.width;
+ size.height = tf.height;
+ layers = tf.array_layers;
+ mipmaps = tf.mipmaps;
+
+ texture_rd_rid = p_texture_rd_rid;
+
+ if (texture_rid.is_valid()) {
+ RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid, rs_layer_type));
+ } else {
+ texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid, rs_layer_type);
+ }
+
+ image_format = RS::get_singleton()->texture_get_format(texture_rid);
+
+ notify_property_list_changed();
+ emit_changed();
+ } else if (texture_rid.is_valid()) {
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ image_format = Image::FORMAT_MAX;
+ size = Size2i();
+ layers = 0;
+ mipmaps = 0;
+
+ notify_property_list_changed();
+ emit_changed();
+ }
+}
+
+RID TextureLayeredRD::get_texture_rd_rid() const {
+ return texture_rd_rid;
+}
+
+TextureLayeredRD::TextureLayeredRD(LayeredType p_layer_type) {
+ layer_type = p_layer_type;
+ size = Size2i();
+ image_format = Image::FORMAT_MAX;
+ layers = 0;
+ mipmaps = 0;
+}
+
+TextureLayeredRD::~TextureLayeredRD() {
+ if (texture_rid.is_valid()) {
+ ERR_FAIL_NULL(RS::get_singleton());
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Texture3DRD
+
+void Texture3DRD::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture_rd_rid", "texture_rd_rid"), &Texture3DRD::set_texture_rd_rid);
+ ClassDB::bind_method(D_METHOD("get_texture_rd_rid"), &Texture3DRD::get_texture_rd_rid);
+
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid"), "set_texture_rd_rid", "get_texture_rd_rid");
+}
+
+Image::Format Texture3DRD::get_format() const {
+ return image_format;
+}
+
+int Texture3DRD::get_width() const {
+ return size.x;
+}
+
+int Texture3DRD::get_height() const {
+ return size.y;
+}
+
+int Texture3DRD::get_depth() const {
+ return size.z;
+}
+
+bool Texture3DRD::has_mipmaps() const {
+ return mipmaps > 1;
+}
+
+RID Texture3DRD::get_rid() const {
+ if (texture_rid.is_null()) {
+ // We are in trouble, create something temporary.
+ texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create();
+ }
+
+ return texture_rid;
+}
+
+void Texture3DRD::set_texture_rd_rid(RID p_texture_rd_rid) {
+ ERR_FAIL_NULL(RS::get_singleton());
+
+ if (p_texture_rd_rid.is_valid()) {
+ ERR_FAIL_NULL(RD::get_singleton());
+ ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid));
+
+ RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid);
+ ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_3D);
+ ERR_FAIL_COND(tf.array_layers > 1);
+
+ size.x = tf.width;
+ size.y = tf.height;
+ size.z = tf.depth;
+ mipmaps = tf.mipmaps;
+
+ texture_rd_rid = p_texture_rd_rid;
+
+ if (texture_rid.is_valid()) {
+ RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid));
+ } else {
+ texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid);
+ }
+
+ image_format = RS::get_singleton()->texture_get_format(texture_rid);
+
+ notify_property_list_changed();
+ emit_changed();
+ } else if (texture_rid.is_valid()) {
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ image_format = Image::FORMAT_MAX;
+ size = Vector3i();
+ mipmaps = 0;
+
+ notify_property_list_changed();
+ emit_changed();
+ }
+}
+
+RID Texture3DRD::get_texture_rd_rid() const {
+ return texture_rd_rid;
+}
+
+Texture3DRD::Texture3DRD() {
+ image_format = Image::FORMAT_MAX;
+ size = Vector3i();
+ mipmaps = 0;
+}
+
+Texture3DRD::~Texture3DRD() {
+ if (texture_rid.is_valid()) {
+ ERR_FAIL_NULL(RS::get_singleton());
+ RS::get_singleton()->free(texture_rid);
+ texture_rid = RID();
+ }
+}