Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/resources/drawable_texture_2d.cpp
20934 views
1
/**************************************************************************/
2
/* drawable_texture_2d.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "drawable_texture_2d.h"
32
33
DrawableTexture2D::DrawableTexture2D() {
34
default_material = RS::get_singleton()->texture_drawable_get_default_material();
35
}
36
37
DrawableTexture2D::~DrawableTexture2D() {
38
if (texture.is_valid()) {
39
ERR_FAIL_NULL(RenderingServer::get_singleton());
40
RenderingServer::get_singleton()->free_rid(texture);
41
}
42
}
43
44
// Initialize Texture Resource with a call to rendering server. Overwrite existing.
45
void DrawableTexture2D::_initialize() {
46
if (texture.is_valid()) {
47
RID new_texture = RS::get_singleton()->texture_drawable_create(width, height, (RS::TextureDrawableFormat)format, base_color, mipmaps);
48
RS::get_singleton()->texture_replace(texture, new_texture);
49
} else {
50
texture = RS::get_singleton()->texture_drawable_create(width, height, (RS::TextureDrawableFormat)format, base_color, mipmaps);
51
}
52
}
53
54
// Setup basic parameters on the Drawable Texture
55
void DrawableTexture2D::setup(int p_width, int p_height, DrawableFormat p_format, const Color &p_color, bool p_use_mipmaps) {
56
ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be in the 1 to 16384 range.");
57
ERR_FAIL_COND_MSG(p_height <= 0 || p_height > 16384, "Texture dimensions have to be in the 1 to 16384 range.");
58
width = p_width;
59
height = p_height;
60
format = p_format;
61
mipmaps = p_use_mipmaps;
62
base_color = p_color;
63
_initialize();
64
notify_property_list_changed();
65
emit_changed();
66
}
67
68
void DrawableTexture2D::set_width(int p_width) {
69
ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be in the 1 to 16384 range.");
70
if (width == p_width) {
71
return;
72
}
73
width = p_width;
74
notify_property_list_changed();
75
emit_changed();
76
}
77
78
int DrawableTexture2D::get_width() const {
79
return width;
80
}
81
82
void DrawableTexture2D::set_height(int p_height) {
83
ERR_FAIL_COND_MSG(p_height <= 0 || p_height > 16384, "Texture dimensions have to be in the 1 to 16384 range.");
84
if (height == p_height) {
85
return;
86
}
87
height = p_height;
88
notify_property_list_changed();
89
emit_changed();
90
}
91
92
int DrawableTexture2D::get_height() const {
93
return height;
94
}
95
96
void DrawableTexture2D::set_format(DrawableFormat p_format) {
97
if (format == p_format) {
98
return;
99
}
100
format = p_format;
101
notify_property_list_changed();
102
emit_changed();
103
}
104
105
DrawableTexture2D::DrawableFormat DrawableTexture2D::get_format() const {
106
return format;
107
}
108
109
void DrawableTexture2D::set_use_mipmaps(bool p_mipmaps) {
110
if (mipmaps == p_mipmaps) {
111
return;
112
}
113
mipmaps = p_mipmaps;
114
notify_property_list_changed();
115
emit_changed();
116
}
117
118
bool DrawableTexture2D::get_use_mipmaps() const {
119
return mipmaps;
120
}
121
122
RID DrawableTexture2D::get_rid() const {
123
if (texture.is_null()) {
124
// We are in trouble, create something temporary.
125
// 4, 4, false, Image::FORMAT_RGBA8
126
texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
127
}
128
return texture;
129
}
130
131
void DrawableTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
132
if ((width | height) == 0) {
133
return;
134
}
135
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(width, height)), texture, false, p_modulate, p_transpose);
136
}
137
138
void DrawableTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
139
if ((width | height) == 0) {
140
return;
141
}
142
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
143
}
144
145
void DrawableTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
146
if ((width | height) == 0) {
147
return;
148
}
149
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);
150
}
151
152
// Perform a blit operation from the given source to the given rect on self.
153
void DrawableTexture2D::blit_rect(const Rect2i p_rect, const Ref<Texture2D> &p_source, const Color &p_modulate, int p_mipmap, const Ref<Material> &p_material) {
154
// Use user Shader if exists.
155
RID material = default_material;
156
if (p_material.is_valid()) {
157
material = p_material->get_rid();
158
if (p_material->get_shader_mode() != Shader::MODE_TEXTURE_BLIT) {
159
WARN_PRINT("ShaderMaterial passed to blit_rect() is not a texture_blit shader. Using default instead.");
160
}
161
}
162
163
// Rendering server expects textureParameters as a TypedArray[RID]
164
Array textures;
165
textures.push_back(texture);
166
167
if (p_source.is_valid()) {
168
ERR_FAIL_COND_MSG(texture == p_source->get_rid(), "Cannot use self as a source.");
169
}
170
Array src_textures;
171
if (Ref<AtlasTexture>(p_source).is_valid()) {
172
WARN_PRINT("AtlasTexture not supported as a source for blit_rect. Using default White.");
173
src_textures.push_back(RID());
174
} else {
175
src_textures.push_back(p_source);
176
}
177
178
RS::get_singleton()->texture_drawable_blit_rect(textures, p_rect, material, p_modulate, src_textures, p_mipmap);
179
notify_property_list_changed();
180
}
181
182
// Perform a blit operation from the given sources to the given rect on self and extra targets
183
void DrawableTexture2D::blit_rect_multi(const Rect2i p_rect, const TypedArray<Texture2D> &p_sources, const TypedArray<DrawableTexture2D> &p_extra_targets, const Color &p_modulate, int p_mipmap, const Ref<Material> &p_material) {
184
RID material = default_material;
185
if (p_material.is_valid()) {
186
material = p_material->get_rid();
187
if (p_material->get_shader_mode() != Shader::MODE_TEXTURE_BLIT) {
188
WARN_PRINT("ShaderMaterial passed to blit_rect_multi() is not a texture_blit shader. Using default instead.");
189
}
190
}
191
192
// Rendering server expects textureParameters as a TypedArray[RID]
193
Array textures;
194
textures.push_back(texture);
195
int i = 0;
196
while (i < p_extra_targets.size()) {
197
textures.push_back(RID(p_extra_targets[i]));
198
i += 1;
199
}
200
i = 0;
201
Array src_textures;
202
while (i < p_sources.size()) {
203
if (Ref<AtlasTexture>(p_sources[i]).is_valid()) {
204
WARN_PRINT("AtlasTexture not supported as a source for blit_rect. Using default White.");
205
src_textures.push_back(RID());
206
} else {
207
src_textures.push_back(RID(p_sources[i]));
208
}
209
ERR_FAIL_COND_MSG(textures.has(RID(src_textures[i])), "Cannot use self as a source.");
210
i += 1;
211
}
212
213
RS::get_singleton()->texture_drawable_blit_rect(textures, p_rect, material, p_modulate, src_textures, p_mipmap);
214
notify_property_list_changed();
215
}
216
217
Ref<Image> DrawableTexture2D::get_image() const {
218
if (texture.is_valid()) {
219
return RS::get_singleton()->texture_2d_get(texture);
220
} else {
221
return Ref<Image>();
222
}
223
}
224
225
void DrawableTexture2D::generate_mipmaps() {
226
if (texture.is_valid()) {
227
RS::get_singleton()->texture_drawable_generate_mipmaps(texture);
228
}
229
}
230
231
void DrawableTexture2D::_bind_methods() {
232
ClassDB::bind_method(D_METHOD("setup", "width", "height", "format", "color", "use_mipmaps"), &DrawableTexture2D::setup, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false));
233
ClassDB::bind_method(D_METHOD("blit_rect", "rect", "source", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref<Material>()));
234
ClassDB::bind_method(D_METHOD("blit_rect_multi", "rect", "sources", "extra_targets", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect_multi, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref<Material>()));
235
ClassDB::bind_method(D_METHOD("generate_mipmaps"), &DrawableTexture2D::generate_mipmaps);
236
237
BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBA8);
238
BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBA8_SRGB);
239
BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBAH);
240
BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBAF);
241
}
242
243