1 | /**************************************************************************/ |
2 | /* texture_rd.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 "texture_rd.h" |
32 | |
33 | //////////////////////////////////////////////////////////////////////////// |
34 | // Texture2DRD |
35 | |
36 | void Texture2DRD::_bind_methods() { |
37 | ClassDB::bind_method(D_METHOD("set_texture_rd_rid" , "texture_rd_rid" ), &Texture2DRD::set_texture_rd_rid); |
38 | ClassDB::bind_method(D_METHOD("get_texture_rd_rid" ), &Texture2DRD::get_texture_rd_rid); |
39 | |
40 | ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid" ), "set_texture_rd_rid" , "get_texture_rd_rid" ); |
41 | } |
42 | |
43 | int Texture2DRD::get_width() const { |
44 | return size.width; |
45 | } |
46 | |
47 | int Texture2DRD::get_height() const { |
48 | return size.height; |
49 | } |
50 | |
51 | RID Texture2DRD::get_rid() const { |
52 | if (texture_rid.is_null()) { |
53 | // We are in trouble, create something temporary. |
54 | texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create(); |
55 | } |
56 | |
57 | return texture_rid; |
58 | } |
59 | |
60 | bool Texture2DRD::has_alpha() const { |
61 | return false; |
62 | } |
63 | |
64 | Ref<Image> Texture2DRD::get_image() const { |
65 | ERR_FAIL_NULL_V(RS::get_singleton(), Ref<Image>()); |
66 | if (texture_rid.is_valid()) { |
67 | return RS::get_singleton()->texture_2d_get(texture_rid); |
68 | } else { |
69 | return Ref<Image>(); |
70 | } |
71 | } |
72 | |
73 | void Texture2DRD::set_texture_rd_rid(RID p_texture_rd_rid) { |
74 | ERR_FAIL_NULL(RS::get_singleton()); |
75 | |
76 | if (p_texture_rd_rid.is_valid()) { |
77 | ERR_FAIL_NULL(RD::get_singleton()); |
78 | ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid)); |
79 | |
80 | RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid); |
81 | ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D); |
82 | ERR_FAIL_COND(tf.depth > 1); |
83 | ERR_FAIL_COND(tf.array_layers > 1); |
84 | |
85 | size.width = tf.width; |
86 | size.height = tf.height; |
87 | |
88 | texture_rd_rid = p_texture_rd_rid; |
89 | |
90 | if (texture_rid.is_valid()) { |
91 | RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid)); |
92 | } else { |
93 | texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid); |
94 | } |
95 | |
96 | notify_property_list_changed(); |
97 | emit_changed(); |
98 | } else if (texture_rid.is_valid()) { |
99 | RS::get_singleton()->free(texture_rid); |
100 | texture_rid = RID(); |
101 | size = Size2i(); |
102 | |
103 | notify_property_list_changed(); |
104 | emit_changed(); |
105 | } |
106 | } |
107 | |
108 | RID Texture2DRD::get_texture_rd_rid() const { |
109 | return texture_rd_rid; |
110 | } |
111 | |
112 | Texture2DRD::Texture2DRD() { |
113 | size = Size2i(); |
114 | } |
115 | |
116 | Texture2DRD::~Texture2DRD() { |
117 | if (texture_rid.is_valid()) { |
118 | ERR_FAIL_NULL(RS::get_singleton()); |
119 | RS::get_singleton()->free(texture_rid); |
120 | texture_rid = RID(); |
121 | } |
122 | } |
123 | |
124 | //////////////////////////////////////////////////////////////////////////// |
125 | // TextureLayeredRD |
126 | |
127 | void TextureLayeredRD::_bind_methods() { |
128 | ClassDB::bind_method(D_METHOD("set_texture_rd_rid" , "texture_rd_rid" ), &TextureLayeredRD::set_texture_rd_rid); |
129 | ClassDB::bind_method(D_METHOD("get_texture_rd_rid" ), &TextureLayeredRD::get_texture_rd_rid); |
130 | |
131 | ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid" ), "set_texture_rd_rid" , "get_texture_rd_rid" ); |
132 | } |
133 | |
134 | TextureLayered::LayeredType TextureLayeredRD::get_layered_type() const { |
135 | return layer_type; |
136 | } |
137 | |
138 | Image::Format TextureLayeredRD::get_format() const { |
139 | return image_format; |
140 | } |
141 | |
142 | int TextureLayeredRD::get_width() const { |
143 | return size.width; |
144 | } |
145 | |
146 | int TextureLayeredRD::get_height() const { |
147 | return size.height; |
148 | } |
149 | |
150 | int TextureLayeredRD::get_layers() const { |
151 | return (int)layers; |
152 | } |
153 | |
154 | bool TextureLayeredRD::has_mipmaps() const { |
155 | return mipmaps > 1; |
156 | } |
157 | |
158 | RID TextureLayeredRD::get_rid() const { |
159 | if (texture_rid.is_null()) { |
160 | // We are in trouble, create something temporary. |
161 | texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create(); |
162 | } |
163 | |
164 | return texture_rid; |
165 | } |
166 | |
167 | Ref<Image> TextureLayeredRD::get_layer_data(int p_layer) const { |
168 | ERR_FAIL_INDEX_V(p_layer, (int)layers, Ref<Image>()); |
169 | return RS::get_singleton()->texture_2d_layer_get(texture_rid, p_layer); |
170 | } |
171 | |
172 | void TextureLayeredRD::set_texture_rd_rid(RID p_texture_rd_rid) { |
173 | ERR_FAIL_NULL(RS::get_singleton()); |
174 | |
175 | if (p_texture_rd_rid.is_valid()) { |
176 | ERR_FAIL_NULL(RD::get_singleton()); |
177 | ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid)); |
178 | |
179 | RS::TextureLayeredType rs_layer_type; |
180 | RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid); |
181 | ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY); |
182 | ERR_FAIL_COND(tf.depth > 1); |
183 | switch (layer_type) { |
184 | case LAYERED_TYPE_2D_ARRAY: { |
185 | ERR_FAIL_COND(tf.array_layers <= 1); |
186 | rs_layer_type = RS::TEXTURE_LAYERED_2D_ARRAY; |
187 | } break; |
188 | case LAYERED_TYPE_CUBEMAP: { |
189 | ERR_FAIL_COND(tf.array_layers != 6); |
190 | rs_layer_type = RS::TEXTURE_LAYERED_CUBEMAP; |
191 | } break; |
192 | case LAYERED_TYPE_CUBEMAP_ARRAY: { |
193 | ERR_FAIL_COND((tf.array_layers == 0) || ((tf.array_layers % 6) != 0)); |
194 | rs_layer_type = RS::TEXTURE_LAYERED_CUBEMAP_ARRAY; |
195 | } break; |
196 | default: { |
197 | ERR_FAIL_MSG("Unknown layer type selected" ); |
198 | } break; |
199 | } |
200 | |
201 | size.width = tf.width; |
202 | size.height = tf.height; |
203 | layers = tf.array_layers; |
204 | mipmaps = tf.mipmaps; |
205 | |
206 | texture_rd_rid = p_texture_rd_rid; |
207 | |
208 | if (texture_rid.is_valid()) { |
209 | RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid, rs_layer_type)); |
210 | } else { |
211 | texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid, rs_layer_type); |
212 | } |
213 | |
214 | image_format = RS::get_singleton()->texture_get_format(texture_rid); |
215 | |
216 | notify_property_list_changed(); |
217 | emit_changed(); |
218 | } else if (texture_rid.is_valid()) { |
219 | RS::get_singleton()->free(texture_rid); |
220 | texture_rid = RID(); |
221 | image_format = Image::FORMAT_MAX; |
222 | size = Size2i(); |
223 | layers = 0; |
224 | mipmaps = 0; |
225 | |
226 | notify_property_list_changed(); |
227 | emit_changed(); |
228 | } |
229 | } |
230 | |
231 | RID TextureLayeredRD::get_texture_rd_rid() const { |
232 | return texture_rd_rid; |
233 | } |
234 | |
235 | TextureLayeredRD::TextureLayeredRD(LayeredType p_layer_type) { |
236 | layer_type = p_layer_type; |
237 | size = Size2i(); |
238 | image_format = Image::FORMAT_MAX; |
239 | layers = 0; |
240 | mipmaps = 0; |
241 | } |
242 | |
243 | TextureLayeredRD::~TextureLayeredRD() { |
244 | if (texture_rid.is_valid()) { |
245 | ERR_FAIL_NULL(RS::get_singleton()); |
246 | RS::get_singleton()->free(texture_rid); |
247 | texture_rid = RID(); |
248 | } |
249 | } |
250 | |
251 | //////////////////////////////////////////////////////////////////////////// |
252 | // Texture3DRD |
253 | |
254 | void Texture3DRD::_bind_methods() { |
255 | ClassDB::bind_method(D_METHOD("set_texture_rd_rid" , "texture_rd_rid" ), &Texture3DRD::set_texture_rd_rid); |
256 | ClassDB::bind_method(D_METHOD("get_texture_rd_rid" ), &Texture3DRD::get_texture_rd_rid); |
257 | |
258 | ADD_PROPERTY(PropertyInfo(Variant::RID, "texture_rd_rid" ), "set_texture_rd_rid" , "get_texture_rd_rid" ); |
259 | } |
260 | |
261 | Image::Format Texture3DRD::get_format() const { |
262 | return image_format; |
263 | } |
264 | |
265 | int Texture3DRD::get_width() const { |
266 | return size.x; |
267 | } |
268 | |
269 | int Texture3DRD::get_height() const { |
270 | return size.y; |
271 | } |
272 | |
273 | int Texture3DRD::get_depth() const { |
274 | return size.z; |
275 | } |
276 | |
277 | bool Texture3DRD::has_mipmaps() const { |
278 | return mipmaps > 1; |
279 | } |
280 | |
281 | RID Texture3DRD::get_rid() const { |
282 | if (texture_rid.is_null()) { |
283 | // We are in trouble, create something temporary. |
284 | texture_rid = RenderingServer::get_singleton()->texture_2d_placeholder_create(); |
285 | } |
286 | |
287 | return texture_rid; |
288 | } |
289 | |
290 | void Texture3DRD::set_texture_rd_rid(RID p_texture_rd_rid) { |
291 | ERR_FAIL_NULL(RS::get_singleton()); |
292 | |
293 | if (p_texture_rd_rid.is_valid()) { |
294 | ERR_FAIL_NULL(RD::get_singleton()); |
295 | ERR_FAIL_COND(!RD::get_singleton()->texture_is_valid(p_texture_rd_rid)); |
296 | |
297 | RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid); |
298 | ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_3D); |
299 | ERR_FAIL_COND(tf.array_layers > 1); |
300 | |
301 | size.x = tf.width; |
302 | size.y = tf.height; |
303 | size.z = tf.depth; |
304 | mipmaps = tf.mipmaps; |
305 | |
306 | texture_rd_rid = p_texture_rd_rid; |
307 | |
308 | if (texture_rid.is_valid()) { |
309 | RS::get_singleton()->texture_replace(texture_rid, RS::get_singleton()->texture_rd_create(p_texture_rd_rid)); |
310 | } else { |
311 | texture_rid = RS::get_singleton()->texture_rd_create(p_texture_rd_rid); |
312 | } |
313 | |
314 | image_format = RS::get_singleton()->texture_get_format(texture_rid); |
315 | |
316 | notify_property_list_changed(); |
317 | emit_changed(); |
318 | } else if (texture_rid.is_valid()) { |
319 | RS::get_singleton()->free(texture_rid); |
320 | texture_rid = RID(); |
321 | image_format = Image::FORMAT_MAX; |
322 | size = Vector3i(); |
323 | mipmaps = 0; |
324 | |
325 | notify_property_list_changed(); |
326 | emit_changed(); |
327 | } |
328 | } |
329 | |
330 | RID Texture3DRD::get_texture_rd_rid() const { |
331 | return texture_rd_rid; |
332 | } |
333 | |
334 | Texture3DRD::Texture3DRD() { |
335 | image_format = Image::FORMAT_MAX; |
336 | size = Vector3i(); |
337 | mipmaps = 0; |
338 | } |
339 | |
340 | Texture3DRD::~Texture3DRD() { |
341 | if (texture_rid.is_valid()) { |
342 | ERR_FAIL_NULL(RS::get_singleton()); |
343 | RS::get_singleton()->free(texture_rid); |
344 | texture_rid = RID(); |
345 | } |
346 | } |
347 | |