Finally figured out how to implement AnimatedTexture properly.
This commit is contained in:
parent
9eb082004d
commit
de910f8c26
18 changed files with 483 additions and 3 deletions
|
@ -235,6 +235,7 @@ public:
|
||||||
void textures_keep_original(bool p_enable) {}
|
void textures_keep_original(bool p_enable) {}
|
||||||
|
|
||||||
void texture_set_proxy(RID p_proxy, RID p_base) {}
|
void texture_set_proxy(RID p_proxy, RID p_base) {}
|
||||||
|
void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {}
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
|
||||||
|
|
||||||
texture = texture->get_ptr();
|
texture = texture->get_ptr();
|
||||||
|
|
||||||
|
if (texture->redraw_if_visible) {
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
if (texture->render_target) {
|
if (texture->render_target) {
|
||||||
texture->render_target->used_in_frame = true;
|
texture->render_target->used_in_frame = true;
|
||||||
}
|
}
|
||||||
|
@ -909,6 +913,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
|
|
||||||
t = t->get_ptr();
|
t = t->get_ptr();
|
||||||
|
|
||||||
|
if (t->redraw_if_visible) {
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
glBindTexture(t->target, t->tex_id);
|
glBindTexture(t->target, t->tex_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -674,6 +674,15 @@ void RasterizerStorageGLES2::texture_set_proxy(RID p_texture, RID p_proxy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerStorageGLES2::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
|
||||||
|
|
||||||
|
Texture *texture = texture_owner.getornull(p_texture);
|
||||||
|
ERR_FAIL_COND(!texture);
|
||||||
|
|
||||||
|
texture->redraw_if_visible = p_enable;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerStorageGLES2::texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) {
|
void RasterizerStorageGLES2::texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,12 +176,15 @@ public:
|
||||||
bool active;
|
bool active;
|
||||||
GLenum tex_id;
|
GLenum tex_id;
|
||||||
|
|
||||||
|
|
||||||
uint16_t stored_cube_sides;
|
uint16_t stored_cube_sides;
|
||||||
|
|
||||||
RenderTarget *render_target;
|
RenderTarget *render_target;
|
||||||
|
|
||||||
Ref<Image> images[6];
|
Ref<Image> images[6];
|
||||||
|
|
||||||
|
bool redraw_if_visible;
|
||||||
|
|
||||||
Texture() {
|
Texture() {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
|
@ -205,6 +208,8 @@ public:
|
||||||
proxy = NULL;
|
proxy = NULL;
|
||||||
|
|
||||||
render_target = NULL;
|
render_target = NULL;
|
||||||
|
|
||||||
|
redraw_if_visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ALWAYS_INLINE_ Texture *get_ptr() {
|
_ALWAYS_INLINE_ Texture *get_ptr() {
|
||||||
|
@ -264,6 +269,8 @@ public:
|
||||||
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
||||||
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
||||||
|
|
||||||
|
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable);
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
virtual RID sky_create();
|
virtual RID sky_create();
|
||||||
|
|
|
@ -211,6 +211,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (texture->redraw_if_visible) { //check before proxy, because this is usually used with proxies
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
texture = texture->get_ptr();
|
texture = texture->get_ptr();
|
||||||
|
|
||||||
if (texture->render_target)
|
if (texture->render_target)
|
||||||
|
@ -248,6 +252,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
normal_map = normal_map->get_ptr();
|
normal_map = normal_map->get_ptr();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
|
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
|
||||||
|
@ -1266,6 +1274,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t->redraw_if_visible) { //check before proxy, because this is usually used with proxies
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
t = t->get_ptr();
|
t = t->get_ptr();
|
||||||
|
|
||||||
if (storage->config.srgb_decode_supported && t->using_srgb) {
|
if (storage->config.srgb_decode_supported && t->using_srgb) {
|
||||||
|
|
|
@ -1225,7 +1225,12 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
t = t->get_ptr(); //resolve for proxies
|
t = t->get_ptr(); //resolve for proxies
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (t->detect_3d) {
|
if (t->detect_3d) {
|
||||||
t->detect_3d(t->detect_3d_ud);
|
t->detect_3d(t->detect_3d_ud);
|
||||||
|
@ -1569,6 +1574,11 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
|
||||||
RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture);
|
RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture);
|
||||||
|
|
||||||
t = t->get_ptr(); //resolve for proxies
|
t = t->get_ptr(); //resolve for proxies
|
||||||
|
|
||||||
|
if (t->redraw_if_visible) {
|
||||||
|
VisualServerRaster::redraw_request();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (t->detect_3d) {
|
if (t->detect_3d) {
|
||||||
t->detect_3d(t->detect_3d_ud);
|
t->detect_3d(t->detect_3d_ud);
|
||||||
|
|
|
@ -1328,6 +1328,13 @@ void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerStorageGLES3::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
|
||||||
|
|
||||||
|
Texture *texture = texture_owner.get(p_texture);
|
||||||
|
ERR_FAIL_COND(!texture);
|
||||||
|
texture->redraw_if_visible = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
RID RasterizerStorageGLES3::sky_create() {
|
RID RasterizerStorageGLES3::sky_create() {
|
||||||
|
|
||||||
Sky *sky = memnew(Sky);
|
Sky *sky = memnew(Sky);
|
||||||
|
|
|
@ -268,6 +268,7 @@ public:
|
||||||
GLuint tex_id;
|
GLuint tex_id;
|
||||||
|
|
||||||
bool using_srgb;
|
bool using_srgb;
|
||||||
|
bool redraw_if_visible;
|
||||||
|
|
||||||
uint16_t stored_cube_sides;
|
uint16_t stored_cube_sides;
|
||||||
|
|
||||||
|
@ -306,6 +307,7 @@ public:
|
||||||
detect_normal = NULL;
|
detect_normal = NULL;
|
||||||
detect_normal_ud = NULL;
|
detect_normal_ud = NULL;
|
||||||
proxy = NULL;
|
proxy = NULL;
|
||||||
|
redraw_if_visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ALWAYS_INLINE_ Texture *get_ptr() {
|
_ALWAYS_INLINE_ Texture *get_ptr() {
|
||||||
|
@ -366,6 +368,7 @@ public:
|
||||||
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
|
||||||
|
|
||||||
virtual void texture_set_proxy(RID p_texture, RID p_proxy);
|
virtual void texture_set_proxy(RID p_texture, RID p_proxy);
|
||||||
|
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable);
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
|
74
editor/icons/icon_animated_texture.svg
Normal file
74
editor/icons/icon_animated_texture.svg
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="icon_animated_texture.svg"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||||
|
<metadata
|
||||||
|
id="metadata12">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs10">
|
||||||
|
<filter
|
||||||
|
inkscape:collect="always"
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter822"
|
||||||
|
x="-0.012"
|
||||||
|
width="1.024"
|
||||||
|
y="-0.012"
|
||||||
|
height="1.024">
|
||||||
|
<feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="0.07"
|
||||||
|
id="feGaussianBlur824" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="836"
|
||||||
|
inkscape:window-height="480"
|
||||||
|
id="namedview8"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="14.75"
|
||||||
|
inkscape:cx="8"
|
||||||
|
inkscape:cy="8"
|
||||||
|
inkscape:window-x="67"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g4" />
|
||||||
|
<g
|
||||||
|
transform="translate(0 -1036.4)"
|
||||||
|
id="g4">
|
||||||
|
<path
|
||||||
|
d="m1 1037.4v14h1.1667v-2h1.8333v2h8v-2h2v2h1v-14h-1v2h-2v-2h-8v2h-1.8333v-2zm1.1667 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2zm-9.8333 4h1.8333v2h-1.8333zm9.8333 0h2v2h-2z"
|
||||||
|
fill="#cea4f1"
|
||||||
|
id="path2"
|
||||||
|
style="fill:#e0e0e0;fill-opacity:1;filter:url(#filter822)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
69
editor/icons/icon_new_root.svg
Normal file
69
editor/icons/icon_new_root.svg
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="icon_new_root.svg"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||||
|
<metadata
|
||||||
|
id="metadata14">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs12" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1474"
|
||||||
|
inkscape:window-height="755"
|
||||||
|
id="namedview10"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="29.5"
|
||||||
|
inkscape:cx="9.9306919"
|
||||||
|
inkscape:cy="7.2213369"
|
||||||
|
inkscape:window-x="67"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg8" />
|
||||||
|
<path
|
||||||
|
style="fill:#e0e0e0"
|
||||||
|
d="m 2,4.7813475 v 2.0494746 c -0.6177049,0.3566305 -0.998733,1.0152377 -1,1.7285 0,1.1045694 0.8954305,1.9999999 2,1.9999999 0.7139771,-5.54e-4 1.3735116,-0.381678 1.7305,-0.9999995 h 1.3545593 c 0.3566306,0.6177035 1.0152377,0.9987325 1.7285,0.9999995 1.1045696,0 1.9999996,-0.8954305 1.9999996,-1.9999999 0,-1.1045695 -0.89543,-2 -1.9999996,-2 -0.7139771,5.537e-4 -1.3735116,0.3816774 -1.7305,1 H 4.7285 C 4.5537191,7.2563119 4.3025219,7.0044423 3.99998,6.8288521 V 4.7793775 C 3.4615087,4.8084067 2.7017179,4.8161838 2,4.7813475 Z"
|
||||||
|
id="path2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccscccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#e0e0e0"
|
||||||
|
d="m 6.8474576,9.6288045 v 1.2020165 c -0.617705,0.35663 -0.998733,1.015237 -1,1.7285 0,1.104569 0.89543,2 2,2 0.713977,-5.54e-4 1.373512,-0.381678 1.7305,-1 h 1.2867634 c 0.35663,0.617704 1.015237,0.998733 1.7285,1 1.104569,0 1.999999,-0.895431 1.999999,-2 0,-1.10457 -0.89543,-2 -1.999999,-2 -0.713977,5.53e-4 -1.373512,0.381677 -1.7305,1 H 9.5759576 c -0.174781,-0.303011 -0.425978,-0.55488 -0.72852,-0.73047 V 9.6268345 c 0,0 -1.264363,0.03681 -1.99998,0.002 z"
|
||||||
|
id="path827"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccsccccccc" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path829"
|
||||||
|
d="m 2.7966098,1.3559322 c -1.104569,0 -2.00000003,0.8954305 -2.00000003,2 5.54e-4,0.7139771 0.38167803,1.3735116 1.00000003,1.7305 0.757716,0.266212 0.949133,0.2840609 1.99998,-0.00197 0.617705,-0.3566306 0.998733,-1.0152377 1,-1.7285 0,-1.1045695 -0.89543,-2 -2,-2 z"
|
||||||
|
style="fill:#84ffb1;fill-opacity:1" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -603,6 +603,7 @@ void register_scene_types() {
|
||||||
ClassDB::register_class<CurveTexture>();
|
ClassDB::register_class<CurveTexture>();
|
||||||
ClassDB::register_class<GradientTexture>();
|
ClassDB::register_class<GradientTexture>();
|
||||||
ClassDB::register_class<ProxyTexture>();
|
ClassDB::register_class<ProxyTexture>();
|
||||||
|
ClassDB::register_class<AnimatedTexture>();
|
||||||
ClassDB::register_class<CubeMap>();
|
ClassDB::register_class<CubeMap>();
|
||||||
ClassDB::register_class<Animation>();
|
ClassDB::register_class<Animation>();
|
||||||
ClassDB::register_virtual_class<Font>();
|
ClassDB::register_virtual_class<Font>();
|
||||||
|
|
|
@ -1669,3 +1669,208 @@ ProxyTexture::~ProxyTexture() {
|
||||||
|
|
||||||
VS::get_singleton()->free(proxy);
|
VS::get_singleton()->free(proxy);
|
||||||
}
|
}
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
void AnimatedTexture::_update_proxy() {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
float delta;
|
||||||
|
if (prev_ticks == 0) {
|
||||||
|
delta = 0;
|
||||||
|
prev_ticks = OS::get_singleton()->get_ticks_usec();
|
||||||
|
} else {
|
||||||
|
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
|
||||||
|
delta = float(double(ticks - prev_ticks) / 1000000.0);
|
||||||
|
prev_ticks = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
time += delta;
|
||||||
|
|
||||||
|
float limit;
|
||||||
|
|
||||||
|
if (fps == 0) {
|
||||||
|
limit = 0;
|
||||||
|
} else {
|
||||||
|
limit = 1.0 / fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iter_max = frame_count;
|
||||||
|
while (iter_max) {
|
||||||
|
float frame_limit = limit + frames[current_frame].delay_sec;
|
||||||
|
|
||||||
|
if (time > frame_limit) {
|
||||||
|
current_frame++;
|
||||||
|
if (current_frame >= frame_count) {
|
||||||
|
current_frame = 0;
|
||||||
|
}
|
||||||
|
time -= frame_limit;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iter_max--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frames[current_frame].texture.is_valid()) {
|
||||||
|
VisualServer::get_singleton()->texture_set_proxy(proxy, frames[current_frame].texture->get_rid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::set_frames(int p_frames) {
|
||||||
|
ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
frame_count = p_frames;
|
||||||
|
}
|
||||||
|
int AnimatedTexture::get_frames() const {
|
||||||
|
return frame_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
|
||||||
|
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
frames[p_frame].texture = p_texture;
|
||||||
|
}
|
||||||
|
Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
return frames[p_frame].texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
|
||||||
|
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
frames[p_frame].delay_sec = p_delay_sec;
|
||||||
|
}
|
||||||
|
float AnimatedTexture::get_frame_delay(int p_frame) const {
|
||||||
|
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
return frames[p_frame].delay_sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::set_fps(float p_fps) {
|
||||||
|
ERR_FAIL_COND(p_fps < 0 || p_fps >= 1000);
|
||||||
|
|
||||||
|
fps = p_fps;
|
||||||
|
}
|
||||||
|
float AnimatedTexture::get_fps() const {
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnimatedTexture::get_width() const {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (!frames[current_frame].texture.is_valid()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames[current_frame].texture->get_width();
|
||||||
|
}
|
||||||
|
int AnimatedTexture::get_height() const {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (!frames[current_frame].texture.is_valid()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames[current_frame].texture->get_height();
|
||||||
|
}
|
||||||
|
RID AnimatedTexture::get_rid() const {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnimatedTexture::has_alpha() const {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (!frames[current_frame].texture.is_valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames[current_frame].texture->has_alpha();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Image> AnimatedTexture::get_data() const {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (!frames[current_frame].texture.is_valid()) {
|
||||||
|
return Ref<Image>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames[current_frame].texture->get_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::set_flags(uint32_t p_flags) {
|
||||||
|
}
|
||||||
|
uint32_t AnimatedTexture::get_flags() const {
|
||||||
|
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (!frames[current_frame].texture.is_valid()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames[current_frame].texture->get_flags();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::_validate_property(PropertyInfo &property) const {
|
||||||
|
|
||||||
|
String prop = property.name;
|
||||||
|
if (prop.begins_with("frame_")) {
|
||||||
|
int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
|
||||||
|
if (frame >= frame_count) {
|
||||||
|
property.usage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_frame_texture", "frame", "texture"), &AnimatedTexture::set_frame_texture);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_frame_texture", "frame"), &AnimatedTexture::get_frame_texture);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_update_proxy"), &AnimatedTexture::_update_proxy);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_FRAMES; i++) {
|
||||||
|
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_frame_texture", "get_frame_texture", i);
|
||||||
|
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01"), "set_frame_delay", "get_frame_delay", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedTexture::AnimatedTexture() {
|
||||||
|
proxy = VS::get_singleton()->texture_create();
|
||||||
|
VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
|
||||||
|
time = 0;
|
||||||
|
frame_count = 1;
|
||||||
|
fps = 4;
|
||||||
|
prev_ticks = 0;
|
||||||
|
current_frame = 0;
|
||||||
|
VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedTexture::~AnimatedTexture() {
|
||||||
|
VS::get_singleton()->free(proxy);
|
||||||
|
}
|
||||||
|
|
|
@ -34,10 +34,11 @@
|
||||||
#include "curve.h"
|
#include "curve.h"
|
||||||
#include "io/resource_loader.h"
|
#include "io/resource_loader.h"
|
||||||
#include "math_2d.h"
|
#include "math_2d.h"
|
||||||
|
#include "os/mutex.h"
|
||||||
|
#include "os/thread_safe.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "scene/resources/color_ramp.h"
|
#include "scene/resources/color_ramp.h"
|
||||||
#include "servers/visual_server.h"
|
#include "servers/visual_server.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -521,4 +522,70 @@ public:
|
||||||
~ProxyTexture();
|
~ProxyTexture();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AnimatedTexture : public Texture {
|
||||||
|
GDCLASS(AnimatedTexture, Texture)
|
||||||
|
|
||||||
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
MAX_FRAMES = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
RID proxy;
|
||||||
|
|
||||||
|
struct Frame {
|
||||||
|
|
||||||
|
Ref<Texture> texture;
|
||||||
|
float delay_sec;
|
||||||
|
|
||||||
|
Frame() {
|
||||||
|
delay_sec = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Frame frames[MAX_FRAMES];
|
||||||
|
int frame_count;
|
||||||
|
int current_frame;
|
||||||
|
|
||||||
|
float fps;
|
||||||
|
|
||||||
|
float time;
|
||||||
|
|
||||||
|
uint64_t prev_ticks;
|
||||||
|
|
||||||
|
void _update_proxy();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
void _validate_property(PropertyInfo &property) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_frames(int p_frames);
|
||||||
|
int get_frames() const;
|
||||||
|
|
||||||
|
void set_frame_texture(int p_frame, const Ref<Texture> &p_texture);
|
||||||
|
Ref<Texture> get_frame_texture(int p_frame) const;
|
||||||
|
|
||||||
|
void set_frame_delay(int p_frame, float p_delay_sec);
|
||||||
|
float get_frame_delay(int p_frame) const;
|
||||||
|
|
||||||
|
void set_fps(float p_fps);
|
||||||
|
float get_fps() const;
|
||||||
|
|
||||||
|
virtual int get_width() const;
|
||||||
|
virtual int get_height() const;
|
||||||
|
virtual RID get_rid() const;
|
||||||
|
|
||||||
|
virtual bool has_alpha() const;
|
||||||
|
|
||||||
|
virtual void set_flags(uint32_t p_flags);
|
||||||
|
virtual uint32_t get_flags() const;
|
||||||
|
|
||||||
|
virtual Ref<Image> get_data() const;
|
||||||
|
|
||||||
|
AnimatedTexture();
|
||||||
|
~AnimatedTexture();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -201,6 +201,7 @@ public:
|
||||||
virtual void textures_keep_original(bool p_enable) = 0;
|
virtual void textures_keep_original(bool p_enable) = 0;
|
||||||
|
|
||||||
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
|
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
|
||||||
|
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
|
|
@ -95,10 +95,11 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str
|
||||||
|
|
||||||
void VisualServerRaster::draw(bool p_swap_buffers) {
|
void VisualServerRaster::draw(bool p_swap_buffers) {
|
||||||
|
|
||||||
changes = 0;
|
//needs to be done before changes is reset to 0, to not force the editor to redraw
|
||||||
|
|
||||||
VS::get_singleton()->emit_signal("frame_pre_draw");
|
VS::get_singleton()->emit_signal("frame_pre_draw");
|
||||||
|
|
||||||
|
changes = 0;
|
||||||
|
|
||||||
VSG::rasterizer->begin_frame();
|
VSG::rasterizer->begin_frame();
|
||||||
|
|
||||||
VSG::scene->update_dirty_instances(); //update scene stuff
|
VSG::scene->update_dirty_instances(); //update scene stuff
|
||||||
|
|
|
@ -173,6 +173,8 @@ public:
|
||||||
|
|
||||||
BIND2(texture_set_proxy, RID, RID)
|
BIND2(texture_set_proxy, RID, RID)
|
||||||
|
|
||||||
|
BIND2(texture_set_force_redraw_if_visible, RID, bool)
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
BIND0R(RID, sky_create)
|
BIND0R(RID, sky_create)
|
||||||
|
|
|
@ -107,6 +107,8 @@ public:
|
||||||
|
|
||||||
FUNC2(texture_set_proxy, RID, RID)
|
FUNC2(texture_set_proxy, RID, RID)
|
||||||
|
|
||||||
|
FUNC2(texture_set_force_redraw_if_visible, RID, bool)
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
FUNCRID(sky)
|
FUNCRID(sky)
|
||||||
|
|
|
@ -144,6 +144,7 @@ public:
|
||||||
virtual void textures_keep_original(bool p_enable) = 0;
|
virtual void textures_keep_original(bool p_enable) = 0;
|
||||||
|
|
||||||
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
|
virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
|
||||||
|
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue