Merge branch 'master' of https://github.com/okamstudio/godot into snapping2
This commit is contained in:
commit
41686d5fdd
|
@ -159,8 +159,8 @@ struct Vector2 {
|
|||
|
||||
operator String() const { return String::num(x)+","+String::num(y); }
|
||||
|
||||
inline Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||
inline Vector2() { x=0; y=0; }
|
||||
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||
_FORCE_INLINE_ Vector2() { x=0; y=0; }
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2& p_vec) const {
|
||||
|
@ -198,6 +198,8 @@ Vector2 Vector2::linear_interpolate(const Vector2& p_a, const Vector2& p_b,float
|
|||
typedef Vector2 Size2;
|
||||
typedef Vector2 Point2;
|
||||
|
||||
struct Matrix32;
|
||||
|
||||
|
||||
struct Rect2 {
|
||||
|
||||
|
@ -224,6 +226,8 @@ struct Rect2 {
|
|||
return true;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const;
|
||||
|
||||
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
|
||||
|
||||
inline bool encloses(const Rect2& p_rect) const {
|
||||
|
@ -597,6 +601,160 @@ struct Matrix32 {
|
|||
|
||||
};
|
||||
|
||||
bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const {
|
||||
|
||||
//SAT intersection between local and transformed rect2
|
||||
|
||||
Vector2 xf_points[4]={
|
||||
p_xform.xform(p_rect.pos),
|
||||
p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y)),
|
||||
p_xform.xform(Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y)),
|
||||
p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y)),
|
||||
};
|
||||
|
||||
real_t low_limit;
|
||||
|
||||
//base rect2 first (faster)
|
||||
|
||||
if (xf_points[0].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[1].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[2].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[3].y>pos.y)
|
||||
goto next1;
|
||||
|
||||
return false;
|
||||
|
||||
next1:
|
||||
|
||||
low_limit=pos.y+size.y;
|
||||
|
||||
if (xf_points[0].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[1].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[2].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[3].y<low_limit)
|
||||
goto next2;
|
||||
|
||||
return false;
|
||||
|
||||
next2:
|
||||
|
||||
if (xf_points[0].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[1].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[2].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[3].x>pos.x)
|
||||
goto next3;
|
||||
|
||||
return false;
|
||||
|
||||
next3:
|
||||
|
||||
low_limit=pos.x+size.x;
|
||||
|
||||
if (xf_points[0].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[1].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[2].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[3].x<low_limit)
|
||||
goto next4;
|
||||
|
||||
return false;
|
||||
|
||||
next4:
|
||||
|
||||
Vector2 xf_points2[4]={
|
||||
pos,
|
||||
Vector2(pos.x+size.x,pos.y),
|
||||
Vector2(pos.x,pos.y+size.y),
|
||||
Vector2(pos.x+size.x,pos.y+size.y),
|
||||
};
|
||||
|
||||
real_t maxa=p_xform.elements[0].dot(xf_points2[0]);
|
||||
real_t mina=maxa;
|
||||
|
||||
real_t dp = p_xform.elements[0].dot(xf_points2[1]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points2[2]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points2[3]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
real_t maxb=p_xform.elements[0].dot(xf_points[0]);
|
||||
real_t minb=maxb;
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[1]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[2]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[3]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
|
||||
if ( mina > maxb )
|
||||
return false;
|
||||
if ( minb > maxa )
|
||||
return false;
|
||||
|
||||
maxa=p_xform.elements[1].dot(xf_points2[0]);
|
||||
mina=maxa;
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[1]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[2]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[3]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
maxb=p_xform.elements[1].dot(xf_points[0]);
|
||||
minb=maxb;
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[1]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[2]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[3]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
|
||||
if ( mina > maxb )
|
||||
return false;
|
||||
if ( minb > maxa )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Vector2 Matrix32::basis_xform(const Vector2& v) const {
|
||||
|
||||
|
|
BIN
demos/2d/navpoly/navigation2.scn
Normal file
BIN
demos/2d/navpoly/navigation2.scn
Normal file
Binary file not shown.
|
@ -6409,7 +6409,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
|
|||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_SUB: {
|
||||
|
||||
glBlendEquation(GL_FUNC_SUBTRACT);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_MUL: {
|
||||
|
@ -7824,8 +7824,10 @@ void RasterizerGLES2::canvas_begin() {
|
|||
//material_shader.unbind();
|
||||
canvas_shader.unbind();
|
||||
canvas_shader.set_custom_shader(0);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false);
|
||||
canvas_shader.bind();
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0);
|
||||
canvas_use_modulate=false;
|
||||
_set_color_attrib(Color(1,1,1));
|
||||
canvas_transform=Transform();
|
||||
canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
|
||||
|
@ -7840,7 +7842,6 @@ void RasterizerGLES2::canvas_begin() {
|
|||
|
||||
canvas_opacity=1.0;
|
||||
canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
|
||||
|
||||
canvas_texscreen_used=false;
|
||||
uses_texpixel_size=false;
|
||||
canvas_last_shader=RID();
|
||||
|
@ -7876,7 +7877,7 @@ void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) {
|
|||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_SUB: {
|
||||
|
||||
glBlendEquation(GL_FUNC_SUBTRACT);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_MUL: {
|
||||
|
@ -8103,7 +8104,7 @@ void RasterizerGLES2::_draw_gui_primitive2(int p_points, const Vector2 *p_vertic
|
|||
_rinfo.ci_draw_commands++;
|
||||
}
|
||||
|
||||
void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip, bool p_v_flip ) {
|
||||
void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip, bool p_v_flip, bool p_transpose ) {
|
||||
|
||||
Vector2 texcoords[4]= {
|
||||
Vector2( p_src_region.pos.x/p_tex_size.width,
|
||||
|
@ -8119,6 +8120,9 @@ void RasterizerGLES2::_draw_textured_quad(const Rect2& p_rect, const Rect2& p_sr
|
|||
(p_src_region.pos.y+p_src_region.size.height)/p_tex_size.height)
|
||||
};
|
||||
|
||||
if (p_transpose) {
|
||||
SWAP( texcoords[1], texcoords[3] );
|
||||
}
|
||||
if (p_h_flip) {
|
||||
SWAP( texcoords[0], texcoords[1] );
|
||||
SWAP( texcoords[2], texcoords[3] );
|
||||
|
@ -8166,11 +8170,11 @@ void RasterizerGLES2::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R
|
|||
if (!(p_flags&CANVAS_RECT_REGION)) {
|
||||
|
||||
Rect2 region = Rect2(0,0,texture->width,texture->height);
|
||||
_draw_textured_quad(p_rect,region,region.size,p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V);
|
||||
_draw_textured_quad(p_rect,region,region.size,p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V,p_flags&CANVAS_RECT_TRANSPOSE);
|
||||
|
||||
} else {
|
||||
|
||||
_draw_textured_quad(p_rect, p_source, Size2(texture->width,texture->height),p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V );
|
||||
_draw_textured_quad(p_rect, p_source, Size2(texture->width,texture->height),p_flags&CANVAS_RECT_FLIP_H,p_flags&CANVAS_RECT_FLIP_V,p_flags&CANVAS_RECT_TRANSPOSE);
|
||||
|
||||
}
|
||||
} else {
|
||||
|
@ -8325,13 +8329,265 @@ void RasterizerGLES2::canvas_set_transform(const Matrix32& p_transform) {
|
|||
//canvas_transform = Variant(p_transform);
|
||||
}
|
||||
|
||||
void RasterizerGLES2::_canvas_normal_set_flip(const Vector2& p_flip) {
|
||||
|
||||
void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
||||
if (p_flip==normal_flip)
|
||||
return;
|
||||
normal_flip=p_flip;
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,normal_flip);
|
||||
}
|
||||
|
||||
|
||||
template<bool use_normalmap>
|
||||
void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip) {
|
||||
|
||||
int cc=p_item->commands.size();
|
||||
CanvasItem::Command **commands = p_item->commands.ptr();
|
||||
|
||||
|
||||
for(int i=0;i<cc;i++) {
|
||||
|
||||
CanvasItem::Command *c=commands[i];
|
||||
|
||||
switch(c->type) {
|
||||
case CanvasItem::Command::TYPE_LINE: {
|
||||
|
||||
CanvasItem::CommandLine* line = static_cast<CanvasItem::CommandLine*>(c);
|
||||
canvas_draw_line(line->from,line->to,line->color,line->width);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_RECT: {
|
||||
|
||||
CanvasItem::CommandRect* rect = static_cast<CanvasItem::CommandRect*>(c);
|
||||
// canvas_draw_rect(rect->rect,rect->region,rect->source,rect->flags&CanvasItem::CommandRect::FLAG_TILE,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V,rect->texture,rect->modulate);
|
||||
#if 0
|
||||
int flags=0;
|
||||
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_REGION) {
|
||||
flags|=Rasterizer::CANVAS_RECT_REGION;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_TILE) {
|
||||
flags|=Rasterizer::CANVAS_RECT_TILE;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H) {
|
||||
|
||||
flags|=Rasterizer::CANVAS_RECT_FLIP_H;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V) {
|
||||
|
||||
flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
}
|
||||
#else
|
||||
|
||||
int flags=rect->flags;
|
||||
#endif
|
||||
if (use_normalmap)
|
||||
_canvas_normal_set_flip(Vector2((flags&CANVAS_RECT_FLIP_H)?-1:1,(flags&CANVAS_RECT_FLIP_V)?-1:1));
|
||||
canvas_draw_rect(rect->rect,flags,rect->source,rect->texture,rect->modulate);
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_STYLE: {
|
||||
|
||||
CanvasItem::CommandStyle* style = static_cast<CanvasItem::CommandStyle*>(c);
|
||||
if (use_normalmap)
|
||||
_canvas_normal_set_flip(Vector2(1,1));
|
||||
canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color);
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_PRIMITIVE: {
|
||||
|
||||
if (use_normalmap)
|
||||
_canvas_normal_set_flip(Vector2(1,1));
|
||||
CanvasItem::CommandPrimitive* primitive = static_cast<CanvasItem::CommandPrimitive*>(c);
|
||||
canvas_draw_primitive(primitive->points,primitive->colors,primitive->uvs,primitive->texture,primitive->width);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_POLYGON: {
|
||||
|
||||
if (use_normalmap)
|
||||
_canvas_normal_set_flip(Vector2(1,1));
|
||||
CanvasItem::CommandPolygon* polygon = static_cast<CanvasItem::CommandPolygon*>(c);
|
||||
canvas_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1);
|
||||
|
||||
} break;
|
||||
|
||||
case CanvasItem::Command::TYPE_POLYGON_PTR: {
|
||||
|
||||
if (use_normalmap)
|
||||
_canvas_normal_set_flip(Vector2(1,1));
|
||||
CanvasItem::CommandPolygonPtr* polygon = static_cast<CanvasItem::CommandPolygonPtr*>(c);
|
||||
canvas_draw_polygon(polygon->count,polygon->indices,polygon->points,polygon->uvs,polygon->colors,polygon->texture,false);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_CIRCLE: {
|
||||
|
||||
CanvasItem::CommandCircle* circle = static_cast<CanvasItem::CommandCircle*>(c);
|
||||
static const int numpoints=32;
|
||||
Vector2 points[numpoints+1];
|
||||
points[numpoints]=circle->pos;
|
||||
int indices[numpoints*3];
|
||||
|
||||
for(int i=0;i<numpoints;i++) {
|
||||
|
||||
points[i]=circle->pos+Vector2( Math::sin(i*Math_PI*2.0/numpoints),Math::cos(i*Math_PI*2.0/numpoints) )*circle->radius;
|
||||
indices[i*3+0]=i;
|
||||
indices[i*3+1]=(i+1)%numpoints;
|
||||
indices[i*3+2]=numpoints;
|
||||
}
|
||||
canvas_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true);
|
||||
//canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_TRANSFORM: {
|
||||
|
||||
CanvasItem::CommandTransform* transform = static_cast<CanvasItem::CommandTransform*>(c);
|
||||
canvas_set_transform(transform->xform);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_BLEND_MODE: {
|
||||
|
||||
CanvasItem::CommandBlendMode* bm = static_cast<CanvasItem::CommandBlendMode*>(c);
|
||||
canvas_set_blend_mode(bm->blend_mode);
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_CLIP_IGNORE: {
|
||||
|
||||
CanvasItem::CommandClipIgnore* ci = static_cast<CanvasItem::CommandClipIgnore*>(c);
|
||||
if (current_clip) {
|
||||
|
||||
if (ci->ignore!=reclip) {
|
||||
if (ci->ignore) {
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
reclip=true;
|
||||
} else {
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
|
||||
current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
|
||||
reclip=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* shader) {
|
||||
|
||||
if (canvas_shader.bind())
|
||||
rebind_texpixel_size=true;
|
||||
|
||||
if (shader_owner->shader_version!=shader->version) {
|
||||
//todo optimize uniforms
|
||||
shader_owner->shader_version=shader->version;
|
||||
}
|
||||
|
||||
if (shader->has_texscreen && framebuffer.active) {
|
||||
|
||||
int x = viewport.x;
|
||||
int y = window_size.height-(viewport.height+viewport.y);
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height));
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1);
|
||||
glActiveTexture(GL_TEXTURE0+max_texture_units-1);
|
||||
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
|
||||
if (framebuffer.scale==1 && !canvas_texscreen_used) {
|
||||
#ifdef GLEW_ENABLED
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
#endif
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
|
||||
// if (current_clip) {
|
||||
// // print_line(" a clip ");
|
||||
// }
|
||||
|
||||
canvas_texscreen_used=true;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
}
|
||||
|
||||
if (shader->has_screen_uv) {
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height));
|
||||
}
|
||||
|
||||
if (shader->uses_time) {
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0));
|
||||
draw_next_frame=true;
|
||||
}
|
||||
//if uses TIME - draw_next_frame=true
|
||||
|
||||
uses_texpixel_size=shader->uses_texpixel_size;
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* shader) {
|
||||
|
||||
//this can be optimized..
|
||||
int tex_id=1;
|
||||
int idx=0;
|
||||
for(Map<StringName,ShaderLanguage::Uniform>::Element *E=shader->uniforms.front();E;E=E->next()) {
|
||||
|
||||
Map<StringName,Variant>::Element *F=shader_owner->shader_param.find(E->key());
|
||||
|
||||
if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) {
|
||||
|
||||
RID rid;
|
||||
if (F) {
|
||||
rid=F->get();
|
||||
}
|
||||
|
||||
if (!rid.is_valid()) {
|
||||
|
||||
Map<StringName,RID>::Element *DT=shader->default_textures.find(E->key());
|
||||
if (DT) {
|
||||
rid=DT->get();
|
||||
}
|
||||
}
|
||||
|
||||
if (rid.is_valid()) {
|
||||
|
||||
int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic..
|
||||
|
||||
glActiveTexture(GL_TEXTURE0+tex_id);
|
||||
Texture *t=texture_owner.get(rid);
|
||||
if (!t)
|
||||
glBindTexture(GL_TEXTURE_2D,white_tex);
|
||||
else
|
||||
glBindTexture(t->target,t->tex_id);
|
||||
|
||||
glUniform1i(loc,tex_id);
|
||||
tex_id++;
|
||||
}
|
||||
} else {
|
||||
Variant &v=F?F->get():E->get().default_value;
|
||||
canvas_shader.set_custom_uniform(idx,v);
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (tex_id>1) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) {
|
||||
|
||||
|
||||
CanvasItem *current_clip=NULL;
|
||||
Shader *shader_cache=NULL;
|
||||
|
||||
bool rebind_shader=true;
|
||||
|
||||
canvas_opacity=1.0;
|
||||
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
|
||||
canvas_modulate=p_modulate;
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
|
||||
|
||||
while(p_item_list) {
|
||||
|
||||
CanvasItem *ci=p_item_list;
|
||||
|
@ -8343,6 +8599,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
memdelete(ci->vp_render);
|
||||
ci->vp_render=NULL;
|
||||
canvas_last_shader=RID();
|
||||
canvas_use_modulate=p_modulate!=Color(1,1,1,1);
|
||||
canvas_modulate=p_modulate;
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
|
||||
rebind_shader=true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (current_clip!=ci->final_clip_owner) {
|
||||
|
@ -8365,7 +8627,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
//begin rect
|
||||
CanvasItem *shader_owner = ci->shader_owner?ci->shader_owner:ci;
|
||||
|
||||
if (shader_owner->shader!=canvas_last_shader) {
|
||||
if (shader_owner->shader!=canvas_last_shader || rebind_shader) {
|
||||
|
||||
Shader *shader = NULL;
|
||||
if (shader_owner->shader.is_valid()) {
|
||||
|
@ -8379,52 +8641,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
|
||||
if (shader) {
|
||||
canvas_shader.set_custom_shader(shader->custom_code_id);
|
||||
if (canvas_shader.bind())
|
||||
rebind_texpixel_size=true;
|
||||
|
||||
if (shader_owner->shader_version!=shader->version) {
|
||||
//todo optimize uniforms
|
||||
shader_owner->shader_version=shader->version;
|
||||
}
|
||||
|
||||
if (shader->has_texscreen && framebuffer.active) {
|
||||
|
||||
int x = viewport.x;
|
||||
int y = window_size.height-(viewport.height+viewport.y);
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height));
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1);
|
||||
glActiveTexture(GL_TEXTURE0+max_texture_units-1);
|
||||
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
|
||||
if (framebuffer.scale==1 && !canvas_texscreen_used) {
|
||||
#ifdef GLEW_ENABLED
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
#endif
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
|
||||
if (current_clip) {
|
||||
// print_line(" a clip ");
|
||||
}
|
||||
|
||||
canvas_texscreen_used=true;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
}
|
||||
|
||||
if (shader->has_screen_uv) {
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height));
|
||||
}
|
||||
|
||||
if (shader->uses_time) {
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0));
|
||||
draw_next_frame=true;
|
||||
}
|
||||
//if uses TIME - draw_next_frame=true
|
||||
|
||||
uses_texpixel_size=shader->uses_texpixel_size;
|
||||
|
||||
_canvas_item_setup_shader_params(shader_owner,shader);
|
||||
} else {
|
||||
shader_cache=NULL;
|
||||
canvas_shader.set_custom_shader(0);
|
||||
|
@ -8435,60 +8652,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
|
||||
if (canvas_use_modulate)
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate);
|
||||
canvas_last_shader=shader_owner->shader;
|
||||
rebind_shader=false;
|
||||
}
|
||||
|
||||
if (shader_cache) {
|
||||
|
||||
Shader *shader = shader_cache;
|
||||
//this can be optimized..
|
||||
int tex_id=1;
|
||||
int idx=0;
|
||||
for(Map<StringName,ShaderLanguage::Uniform>::Element *E=shader->uniforms.front();E;E=E->next()) {
|
||||
|
||||
Map<StringName,Variant>::Element *F=shader_owner->shader_param.find(E->key());
|
||||
|
||||
if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) {
|
||||
|
||||
RID rid;
|
||||
if (F) {
|
||||
rid=F->get();
|
||||
}
|
||||
|
||||
if (!rid.is_valid()) {
|
||||
|
||||
Map<StringName,RID>::Element *DT=shader->default_textures.find(E->key());
|
||||
if (DT) {
|
||||
rid=DT->get();
|
||||
}
|
||||
}
|
||||
|
||||
if (rid.is_valid()) {
|
||||
|
||||
int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic..
|
||||
|
||||
glActiveTexture(GL_TEXTURE0+tex_id);
|
||||
Texture *t=texture_owner.get(rid);
|
||||
if (!t)
|
||||
glBindTexture(GL_TEXTURE_2D,white_tex);
|
||||
else
|
||||
glBindTexture(t->target,t->tex_id);
|
||||
|
||||
glUniform1i(loc,tex_id);
|
||||
tex_id++;
|
||||
}
|
||||
} else {
|
||||
Variant &v=F?F->get():E->get().default_value;
|
||||
canvas_shader.set_custom_uniform(idx,v);
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (tex_id>1) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
_canvas_item_setup_shader_uniforms(shader_owner,shader_cache);
|
||||
}
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform);
|
||||
|
@ -8514,7 +8686,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_SUB: {
|
||||
|
||||
glBlendEquation(GL_FUNC_SUBTRACT);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
} break;
|
||||
case VS::MATERIAL_BLEND_MODE_MUL: {
|
||||
|
@ -8531,127 +8703,113 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
|
|||
canvas_blend_mode=ci->blend_mode;
|
||||
}
|
||||
|
||||
int cc=ci->commands.size();
|
||||
CanvasItem::Command **commands = ci->commands.ptr();
|
||||
|
||||
canvas_opacity = ci->final_opacity;
|
||||
|
||||
for(int i=0;i<cc;i++) {
|
||||
_canvas_item_render_commands<false>(ci,current_clip,reclip);
|
||||
|
||||
CanvasItem::Command *c=commands[i];
|
||||
if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light) {
|
||||
|
||||
switch(c->type) {
|
||||
case CanvasItem::Command::TYPE_LINE: {
|
||||
CanvasLight *light = p_light;
|
||||
bool light_used=false;
|
||||
bool subtract=false;
|
||||
|
||||
CanvasItem::CommandLine* line = static_cast<CanvasItem::CommandLine*>(c);
|
||||
canvas_draw_line(line->from,line->to,line->color,line->width);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_RECT: {
|
||||
|
||||
CanvasItem::CommandRect* rect = static_cast<CanvasItem::CommandRect*>(c);
|
||||
// canvas_draw_rect(rect->rect,rect->region,rect->source,rect->flags&CanvasItem::CommandRect::FLAG_TILE,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V,rect->texture,rect->modulate);
|
||||
#if 0
|
||||
int flags=0;
|
||||
while(light) {
|
||||
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_REGION) {
|
||||
flags|=Rasterizer::CANVAS_RECT_REGION;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_TILE) {
|
||||
flags|=Rasterizer::CANVAS_RECT_TILE;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H) {
|
||||
if (ci->light_mask&light->item_mask && p_z>=light->z_min && p_z<=light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache,light->rect_cache)) {
|
||||
|
||||
flags|=Rasterizer::CANVAS_RECT_FLIP_H;
|
||||
}
|
||||
if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V) {
|
||||
//intersects this light
|
||||
|
||||
flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
}
|
||||
#else
|
||||
if (!light_used || subtract!=light->subtract) {
|
||||
|
||||
int flags=rect->flags;
|
||||
#endif
|
||||
canvas_draw_rect(rect->rect,flags,rect->source,rect->texture,rect->modulate);
|
||||
subtract=light->subtract;
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_STYLE: {
|
||||
if (subtract) {
|
||||
|
||||
CanvasItem::CommandStyle* style = static_cast<CanvasItem::CommandStyle*>(c);
|
||||
canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_PRIMITIVE: {
|
||||
} else {
|
||||
|
||||
CanvasItem::CommandPrimitive* primitive = static_cast<CanvasItem::CommandPrimitive*>(c);
|
||||
canvas_draw_primitive(primitive->points,primitive->colors,primitive->uvs,primitive->texture,primitive->width);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_POLYGON: {
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
|
||||
CanvasItem::CommandPolygon* polygon = static_cast<CanvasItem::CommandPolygon*>(c);
|
||||
canvas_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1);
|
||||
|
||||
} break;
|
||||
|
||||
case CanvasItem::Command::TYPE_POLYGON_PTR: {
|
||||
|
||||
CanvasItem::CommandPolygonPtr* polygon = static_cast<CanvasItem::CommandPolygonPtr*>(c);
|
||||
canvas_draw_polygon(polygon->count,polygon->indices,polygon->points,polygon->uvs,polygon->colors,polygon->texture,false);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_CIRCLE: {
|
||||
|
||||
CanvasItem::CommandCircle* circle = static_cast<CanvasItem::CommandCircle*>(c);
|
||||
static const int numpoints=32;
|
||||
Vector2 points[numpoints+1];
|
||||
points[numpoints]=circle->pos;
|
||||
int indices[numpoints*3];
|
||||
|
||||
for(int i=0;i<numpoints;i++) {
|
||||
|
||||
points[i]=circle->pos+Vector2( Math::sin(i*Math_PI*2.0/numpoints),Math::cos(i*Math_PI*2.0/numpoints) )*circle->radius;
|
||||
indices[i*3+0]=i;
|
||||
indices[i*3+1]=(i+1)%numpoints;
|
||||
indices[i*3+2]=numpoints;
|
||||
}
|
||||
canvas_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true);
|
||||
//canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_TRANSFORM: {
|
||||
|
||||
CanvasItem::CommandTransform* transform = static_cast<CanvasItem::CommandTransform*>(c);
|
||||
canvas_set_transform(transform->xform);
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_BLEND_MODE: {
|
||||
|
||||
CanvasItem::CommandBlendMode* bm = static_cast<CanvasItem::CommandBlendMode*>(c);
|
||||
canvas_set_blend_mode(bm->blend_mode);
|
||||
|
||||
} break;
|
||||
case CanvasItem::Command::TYPE_CLIP_IGNORE: {
|
||||
|
||||
CanvasItem::CommandClipIgnore* ci = static_cast<CanvasItem::CommandClipIgnore*>(c);
|
||||
if (current_clip) {
|
||||
|
||||
if (ci->ignore!=reclip) {
|
||||
if (ci->ignore) {
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
reclip=true;
|
||||
} else {
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
|
||||
current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
|
||||
reclip=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!light_used) {
|
||||
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,true);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false);
|
||||
light_used=true;
|
||||
normal_flip=Vector2(1,1);
|
||||
|
||||
}
|
||||
bool light_rebind = canvas_shader.bind();
|
||||
|
||||
if (light_rebind) {
|
||||
|
||||
if (shader_owner && shader_cache) {
|
||||
_canvas_item_setup_shader_params(shader_owner,shader_cache);
|
||||
_canvas_item_setup_shader_uniforms(shader_owner,shader_cache);
|
||||
}
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
|
||||
if (canvas_use_modulate)
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,Vector2(1,1));
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX,light->light_shader_xform);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height);
|
||||
glActiveTexture(GL_TEXTURE0+max_texture_units-2);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_TEXTURE,max_texture_units-2);
|
||||
Texture *t = texture_owner.get(light->texture);
|
||||
if (!t) {
|
||||
glBindTexture(GL_TEXTURE_2D,white_tex);
|
||||
} else {
|
||||
|
||||
glBindTexture(t->target,t->tex_id);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
_canvas_item_render_commands<true>(ci,current_clip,reclip); //redraw using light
|
||||
|
||||
}
|
||||
|
||||
light=light->next_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (light_used) {
|
||||
|
||||
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,false);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate);
|
||||
|
||||
canvas_shader.bind();
|
||||
|
||||
if (shader_owner && shader_cache) {
|
||||
_canvas_item_setup_shader_params(shader_owner,shader_cache);
|
||||
_canvas_item_setup_shader_uniforms(shader_owner,shader_cache);
|
||||
}
|
||||
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
|
||||
if (canvas_use_modulate)
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate);
|
||||
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (reclip) {
|
||||
|
||||
|
|
|
@ -1127,6 +1127,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
bool active;
|
||||
|
||||
int blur_size;
|
||||
|
||||
struct Blur {
|
||||
|
||||
GLuint fbo;
|
||||
|
@ -1186,11 +1187,15 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
GLuint white_tex;
|
||||
RID canvas_tex;
|
||||
float canvas_opacity;
|
||||
Color canvas_modulate;
|
||||
bool canvas_use_modulate;
|
||||
bool uses_texpixel_size;
|
||||
bool rebind_texpixel_size;
|
||||
Transform canvas_transform;
|
||||
RID canvas_last_shader;
|
||||
bool canvas_texscreen_used;
|
||||
Vector2 normal_flip;
|
||||
_FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2& p_flip);
|
||||
|
||||
|
||||
_FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture);
|
||||
|
@ -1232,7 +1237,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
void _draw_primitive(int p_points, const Vector3 *p_vertices, const Vector3 *p_normals, const Color* p_colors, const Vector3 *p_uvs,const Plane *p_tangents=NULL,int p_instanced=1);
|
||||
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs);
|
||||
_FORCE_INLINE_ void _draw_gui_primitive2(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs, const Vector2 *p_uvs2);
|
||||
void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false );
|
||||
void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false, bool p_transpose=false );
|
||||
void _draw_quad(const Rect2& p_rect);
|
||||
void _copy_screen_quad();
|
||||
void _copy_to_texscreen();
|
||||
|
@ -1247,6 +1252,10 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
GLuint tc0_id_cache;
|
||||
GLuint tc0_idx;
|
||||
|
||||
template<bool use_normalmap>
|
||||
_FORCE_INLINE_ void _canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip);
|
||||
_FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* p_shader);
|
||||
_FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,Shader* p_shader);
|
||||
public:
|
||||
|
||||
/* TEXTURE API */
|
||||
|
@ -1562,7 +1571,8 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor);
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform);
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list);
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light);
|
||||
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
|
|
|
@ -261,6 +261,11 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
|
|||
uses_light=true;
|
||||
}
|
||||
|
||||
if (vnode->name==vname_normal) {
|
||||
uses_normal=true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (vnode->name==vname_time) {
|
||||
|
@ -636,7 +641,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
|
|||
r_flags.uses_light=uses_light;
|
||||
r_flags.uses_time=uses_time;
|
||||
r_flags.uses_normalmap=uses_normalmap;
|
||||
r_flags.uses_normal=uses_normalmap;
|
||||
r_flags.uses_normal=uses_normal;
|
||||
r_flags.uses_texpixel_size=uses_texpixel_size;
|
||||
r_flags.uses_worldvec=uses_worldvec;
|
||||
r_code_line=code;
|
||||
|
|
|
@ -26,7 +26,13 @@ uniform float time;
|
|||
#ifdef USE_LIGHTING
|
||||
|
||||
uniform highp mat4 light_matrix;
|
||||
varying vec4 light_tex_pos;
|
||||
uniform vec2 light_pos;
|
||||
varying vec4 light_uv_interp;
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
varying vec4 local_rot;
|
||||
uniform vec2 normal_flip;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -67,8 +73,13 @@ VERTEX_SHADER_CODE
|
|||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
light_tex_pos.xy = light_matrix * gl_Position;
|
||||
light_tex_pos.zw=outvec.xy - light_matrix[4].xy; //likely wrong
|
||||
light_uv_interp.xy = (light_matrix * outvec).xy;
|
||||
light_uv_interp.zw = outvec.xy-light_pos;
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x;
|
||||
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy )*normal_flip.y;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -121,11 +132,22 @@ varying vec4 var2_interp;
|
|||
uniform float time;
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODULATE
|
||||
|
||||
uniform vec4 modulate;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
uniform sampler2D light_texture;
|
||||
varying vec4 light_tex_pos;
|
||||
uniform vec4 light_color;
|
||||
uniform float light_height;
|
||||
varying vec4 light_uv_interp;
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
varying vec4 local_rot;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHADOWS
|
||||
|
||||
|
@ -151,6 +173,11 @@ void main() {
|
|||
vec3 normal = vec3(0,0,1);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODULATE
|
||||
|
||||
color*=modulate;
|
||||
#endif
|
||||
|
||||
color *= texture2D( texture, uv_interp );
|
||||
#if defined(ENABLE_SCREEN_UV)
|
||||
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
|
||||
|
@ -166,9 +193,13 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
|
||||
#endif
|
||||
|
||||
float att=1.0;
|
||||
|
||||
vec3 light = texture2D(light_texture,light_tex_pos).rgb;
|
||||
vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color;
|
||||
#ifdef USE_SHADOWS
|
||||
//this might not be that great on mobile?
|
||||
float light_dist = length(light_texture.zw);
|
||||
|
@ -183,18 +214,29 @@ FRAGMENT_SHADER_CODE
|
|||
#if defined(USE_LIGHT_SHADER_CODE)
|
||||
//light is written by the light shader
|
||||
{
|
||||
vec2 light_dir = normalize(light_tex_pos.zw);
|
||||
float light_distance = length(light_tex_pos.zw);
|
||||
vec2 light_dir = normalize(light_uv_interp.zw);
|
||||
float light_distance = length(light_uv_interp.zw);
|
||||
LIGHT_SHADER_CODE
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
vec2 light_normal = normalize(light_tex_pos.zw);
|
||||
light = color.rgb * light * max(dot(light_normal,normal),0);
|
||||
vec3 light_normal = normalize(vec3(light_uv_interp.zw,-light_height));
|
||||
light*=max(dot(-light_normal,normal),0);
|
||||
#endif
|
||||
|
||||
color.rgb=light;
|
||||
color*=light;
|
||||
/*
|
||||
#ifdef USE_NORMAL
|
||||
color.xy=local_rot.xy;//normal.xy;
|
||||
color.zw=vec2(0.0,1.0);
|
||||
#endif
|
||||
*/
|
||||
if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) {
|
||||
color.a=0.0; //invisible
|
||||
}
|
||||
|
||||
//light shader code
|
||||
#endif
|
||||
|
||||
|
|
|
@ -538,9 +538,12 @@ void GDTokenizerText::_advance() {
|
|||
is_node_path=true;
|
||||
|
||||
case '\'':
|
||||
string_mode=STRING_SINGLE_QUOTE;
|
||||
case '"': {
|
||||
|
||||
|
||||
if (GETCHAR(0)=='\'')
|
||||
string_mode=STRING_SINGLE_QUOTE;
|
||||
|
||||
|
||||
int i=1;
|
||||
if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') {
|
||||
i+=2;
|
||||
|
|
|
@ -1100,7 +1100,7 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) {
|
|||
NSPoint localPoint = { p_to.x, p_to.y };
|
||||
|
||||
NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil];
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(CGRect){.origin=pointInWindow}];
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(NSRect){.origin=pointInWindow}].origin;
|
||||
|
||||
//point in scren coords
|
||||
CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y};
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "drivers/gles2/rasterizer_gles2.h"
|
||||
#include "drivers/gles1/rasterizer_gles1.h"
|
||||
#include "os_winrt.h"
|
||||
#include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
|
||||
#include "drivers/unix/memory_pool_static_malloc.h"
|
||||
|
@ -62,11 +61,11 @@ using namespace Microsoft::WRL;
|
|||
|
||||
int OSWinrt::get_video_driver_count() const {
|
||||
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
const char * OSWinrt::get_video_driver_name(int p_driver) const {
|
||||
|
||||
return p_driver==0?"GLES2":"GLES1";
|
||||
return "GLES2";
|
||||
}
|
||||
|
||||
OS::VideoMode OSWinrt::get_default_video_mode() const {
|
||||
|
|
|
@ -458,6 +458,16 @@ CanvasItem::BlendMode CanvasItem::get_blend_mode() const {
|
|||
return blend_mode;
|
||||
}
|
||||
|
||||
void CanvasItem::set_light_mask(int p_light_mask) {
|
||||
|
||||
light_mask=p_light_mask;
|
||||
VS::get_singleton()->canvas_item_set_light_mask(canvas_item,p_light_mask);
|
||||
}
|
||||
|
||||
int CanvasItem::get_light_mask() const{
|
||||
|
||||
return light_mask;
|
||||
}
|
||||
|
||||
|
||||
void CanvasItem::item_rect_changed() {
|
||||
|
@ -511,7 +521,7 @@ void CanvasItem::draw_texture(const Ref<Texture>& p_texture,const Point2& p_pos)
|
|||
p_texture->draw(canvas_item,p_pos);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate) {
|
||||
void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) {
|
||||
|
||||
if (!drawing) {
|
||||
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
|
@ -519,17 +529,17 @@ void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_
|
|||
}
|
||||
|
||||
ERR_FAIL_COND(p_texture.is_null());
|
||||
p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate);
|
||||
p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) {
|
||||
void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) {
|
||||
|
||||
if (!drawing) {
|
||||
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
ERR_FAIL_COND(p_texture.is_null());
|
||||
p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate);
|
||||
p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_style_box(const Ref<StyleBox>& p_style_box,const Rect2& p_rect) {
|
||||
|
@ -857,6 +867,9 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity);
|
||||
|
@ -912,6 +925,7 @@ void CanvasItem::_bind_methods() {
|
|||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") );
|
||||
//exporting these two things doesn't really make much sense i think
|
||||
|
@ -992,6 +1006,7 @@ CanvasItem::CanvasItem() : xform_change(this) {
|
|||
canvas_layer=NULL;
|
||||
use_parent_shader=false;
|
||||
global_invalid=true;
|
||||
light_mask=1;
|
||||
|
||||
C=NULL;
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
List<CanvasItem*>::Element *C;
|
||||
|
||||
BlendMode blend_mode;
|
||||
int light_mask;
|
||||
|
||||
bool first_draw;
|
||||
bool hidden;
|
||||
|
@ -80,8 +81,8 @@ private:
|
|||
bool drawing;
|
||||
bool block_transform_notify;
|
||||
bool behind;
|
||||
|
||||
bool use_parent_shader;
|
||||
|
||||
Ref<Shader> shader;
|
||||
|
||||
mutable Matrix32 global_transform;
|
||||
|
@ -158,6 +159,9 @@ public:
|
|||
void set_blend_mode(BlendMode p_blend_mode);
|
||||
BlendMode get_blend_mode() const;
|
||||
|
||||
void set_light_mask(int p_light_mask);
|
||||
int get_light_mask() const;
|
||||
|
||||
void set_opacity(float p_opacity);
|
||||
float get_opacity() const;
|
||||
|
||||
|
@ -170,8 +174,8 @@ public:
|
|||
void draw_rect(const Rect2& p_rect, const Color& p_color);
|
||||
void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color);
|
||||
void draw_texture(const Ref<Texture>& p_texture,const Point2& p_pos);
|
||||
void draw_texture_rect(const Ref<Texture>& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1));
|
||||
void draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1));
|
||||
void draw_texture_rect(const Ref<Texture>& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false);
|
||||
void draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false);
|
||||
void draw_style_box(const Ref<StyleBox>& p_style_box,const Rect2& p_rect);
|
||||
void draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, Ref<Texture> p_texture=Ref<Texture>(),float p_width=1);
|
||||
void draw_polygon(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), Ref<Texture> p_texture=Ref<Texture>());
|
||||
|
|
46
scene/2d/canvas_modulate.cpp
Normal file
46
scene/2d/canvas_modulate.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "canvas_modulate.h"
|
||||
|
||||
|
||||
void CanvasModulate::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),color);
|
||||
} else if (p_what==NOTIFICATION_EXIT_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),Color(1,1,1,1));
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasModulate::_bind_methods(){
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color"),&CanvasModulate::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color"),&CanvasModulate::get_color);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
|
||||
}
|
||||
|
||||
|
||||
void CanvasModulate::set_color(const Color& p_color){
|
||||
|
||||
color=p_color;
|
||||
if (is_inside_tree()) {
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),color);
|
||||
}
|
||||
}
|
||||
Color CanvasModulate::get_color() const {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
CanvasModulate::CanvasModulate()
|
||||
{
|
||||
color=Color(1,1,1,1);
|
||||
}
|
||||
|
||||
CanvasModulate::~CanvasModulate()
|
||||
{
|
||||
|
||||
}
|
||||
|
23
scene/2d/canvas_modulate.h
Normal file
23
scene/2d/canvas_modulate.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef CANVASMODULATE_H
|
||||
#define CANVASMODULATE_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class CanvasModulate : public Node2D {
|
||||
|
||||
OBJ_TYPE(CanvasModulate,Node2D);
|
||||
|
||||
Color color;
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_color(const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
CanvasModulate();
|
||||
~CanvasModulate();
|
||||
};
|
||||
|
||||
#endif // CANVASMODULATE_H
|
267
scene/2d/light_2d.cpp
Normal file
267
scene/2d/light_2d.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
#include "light_2d.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
void Light2D::edit_set_pivot(const Point2& p_pivot) {
|
||||
|
||||
set_texture_offset(p_pivot);
|
||||
|
||||
}
|
||||
|
||||
Point2 Light2D::edit_get_pivot() const {
|
||||
|
||||
return get_texture_offset();
|
||||
}
|
||||
bool Light2D::edit_has_pivot() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect2 Light2D::get_item_rect() const {
|
||||
|
||||
if (texture.is_null())
|
||||
return Rect2(0,0,1,1);
|
||||
|
||||
Size2i s;
|
||||
|
||||
s = texture->get_size();
|
||||
Point2i ofs=texture_offset;
|
||||
ofs-=s/2;
|
||||
|
||||
if (s==Size2(0,0))
|
||||
s=Size2(1,1);
|
||||
|
||||
return Rect2(ofs,s);
|
||||
}
|
||||
|
||||
|
||||
void Light2D::set_enabled( bool p_enabled) {
|
||||
|
||||
VS::get_singleton()->canvas_light_set_enabled(canvas_light,p_enabled);
|
||||
enabled=p_enabled;
|
||||
}
|
||||
|
||||
bool Light2D::is_enabled() const {
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void Light2D::set_texture( const Ref<Texture>& p_texture) {
|
||||
|
||||
texture=p_texture;
|
||||
if (texture.is_valid())
|
||||
VS::get_singleton()->canvas_light_set_texture(canvas_light,texture->get_rid());
|
||||
else
|
||||
VS::get_singleton()->canvas_light_set_texture(canvas_light,RID());
|
||||
}
|
||||
|
||||
Ref<Texture> Light2D::get_texture() const {
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void Light2D::set_texture_offset( const Vector2& p_offset) {
|
||||
|
||||
texture_offset=p_offset;
|
||||
VS::get_singleton()->canvas_light_set_texture_offset(canvas_light,texture_offset);
|
||||
}
|
||||
|
||||
Vector2 Light2D::get_texture_offset() const {
|
||||
|
||||
return texture_offset;
|
||||
}
|
||||
|
||||
void Light2D::set_color( const Color& p_color) {
|
||||
|
||||
color=p_color;
|
||||
VS::get_singleton()->canvas_light_set_color(canvas_light,color);
|
||||
|
||||
}
|
||||
Color Light2D::get_color() const {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void Light2D::set_height( float p_height) {
|
||||
|
||||
height=p_height;
|
||||
VS::get_singleton()->canvas_light_set_height(canvas_light,height);
|
||||
|
||||
}
|
||||
float Light2D::get_height() const {
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void Light2D::set_z_range_min( int p_min_z) {
|
||||
|
||||
z_min=p_min_z;
|
||||
VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max);
|
||||
|
||||
}
|
||||
int Light2D::get_z_range_min() const {
|
||||
|
||||
return z_min;
|
||||
}
|
||||
|
||||
void Light2D::set_z_range_max( int p_max_z) {
|
||||
|
||||
z_max=p_max_z;
|
||||
VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max);
|
||||
|
||||
}
|
||||
int Light2D::get_z_range_max() const {
|
||||
|
||||
return z_max;
|
||||
}
|
||||
|
||||
void Light2D::set_layer_range_min( int p_min_layer) {
|
||||
|
||||
layer_min=p_min_layer;
|
||||
VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max);
|
||||
|
||||
}
|
||||
int Light2D::get_layer_range_min() const {
|
||||
|
||||
return layer_min;
|
||||
}
|
||||
|
||||
void Light2D::set_layer_range_max( int p_max_layer) {
|
||||
|
||||
layer_max=p_max_layer;
|
||||
VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max);
|
||||
|
||||
}
|
||||
int Light2D::get_layer_range_max() const {
|
||||
|
||||
return layer_max;
|
||||
}
|
||||
|
||||
void Light2D::set_item_mask( int p_mask) {
|
||||
|
||||
item_mask=p_mask;
|
||||
VS::get_singleton()->canvas_light_set_item_mask(canvas_light,item_mask);
|
||||
|
||||
}
|
||||
|
||||
int Light2D::get_item_mask() const {
|
||||
|
||||
return item_mask;
|
||||
}
|
||||
|
||||
void Light2D::set_subtract_mode( bool p_enable ) {
|
||||
|
||||
subtract_mode=p_enable;
|
||||
VS::get_singleton()->canvas_light_set_subtract_mode(canvas_light,p_enable);
|
||||
}
|
||||
|
||||
bool Light2D::get_subtract_mode() const {
|
||||
|
||||
return subtract_mode;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_enabled( bool p_enabled) {
|
||||
|
||||
shadow=p_enabled;
|
||||
VS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light,shadow);
|
||||
|
||||
}
|
||||
bool Light2D::is_shadow_enabled() const {
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
void Light2D::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, get_canvas() );
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_TRANSFORM_CHANGED) {
|
||||
|
||||
VS::get_singleton()->canvas_light_set_transform( canvas_light, get_global_transform());
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
|
||||
VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, RID() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Light2D::_bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&Light2D::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"),&Light2D::is_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_texture","texture"),&Light2D::set_texture);
|
||||
ObjectTypeDB::bind_method(_MD("get_texture"),&Light2D::get_texture);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_texture_offset","texture_offset"),&Light2D::set_texture_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_texture_offset"),&Light2D::get_texture_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color"),&Light2D::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color"),&Light2D::get_color);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_height","height"),&Light2D::set_height);
|
||||
ObjectTypeDB::bind_method(_MD("get_height"),&Light2D::get_height);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_z_range_min","z"),&Light2D::set_z_range_min);
|
||||
ObjectTypeDB::bind_method(_MD("get_z_range_min"),&Light2D::get_z_range_min);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_z_range_max","z"),&Light2D::set_z_range_max);
|
||||
ObjectTypeDB::bind_method(_MD("get_z_range_max"),&Light2D::get_z_range_max);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_range_min","layer"),&Light2D::set_layer_range_min);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_range_min"),&Light2D::get_layer_range_min);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_range_max","layer"),&Light2D::set_layer_range_max);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_range_max"),&Light2D::get_layer_range_max);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_item_mask","item_mask"),&Light2D::set_item_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_item_mask"),&Light2D::get_item_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_subtract_mode","enable"),&Light2D::set_subtract_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_subtract_mode"),&Light2D::get_subtract_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"texture_offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"height"),_SCS("set_height"),_SCS("get_height"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"z_range_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"layer_range_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow_enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
Light2D::Light2D() {
|
||||
|
||||
canvas_light=VisualServer::get_singleton()->canvas_light_create();
|
||||
enabled=true;
|
||||
shadow=false;
|
||||
color=Color(1,1,1);
|
||||
height=0;
|
||||
z_min=-1024;
|
||||
z_max=1024;
|
||||
layer_min=0;
|
||||
layer_max=0;
|
||||
item_mask=1;
|
||||
subtract_mode=false;
|
||||
|
||||
}
|
||||
|
||||
Light2D::~Light2D() {
|
||||
|
||||
VisualServer::get_singleton()->free(canvas_light);
|
||||
}
|
78
scene/2d/light_2d.h
Normal file
78
scene/2d/light_2d.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef LIGHT_2D_H
|
||||
#define LIGHT_2D_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class Light2D : public Node2D {
|
||||
|
||||
OBJ_TYPE(Light2D,Node2D);
|
||||
private:
|
||||
RID canvas_light;
|
||||
bool enabled;
|
||||
bool shadow;
|
||||
Color color;
|
||||
float height;
|
||||
int z_min;
|
||||
int z_max;
|
||||
int layer_min;
|
||||
int layer_max;
|
||||
int item_mask;
|
||||
bool subtract_mode;
|
||||
Ref<Texture> texture;
|
||||
Vector2 texture_offset;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
virtual void edit_set_pivot(const Point2& p_pivot);
|
||||
virtual Point2 edit_get_pivot() const;
|
||||
virtual bool edit_has_pivot() const;
|
||||
|
||||
void set_enabled( bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void set_texture( const Ref<Texture>& p_texture);
|
||||
Ref<Texture> get_texture() const;
|
||||
|
||||
void set_texture_offset( const Vector2& p_offset);
|
||||
Vector2 get_texture_offset() const;
|
||||
|
||||
void set_color( const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
void set_height( float p_height);
|
||||
float get_height() const;
|
||||
|
||||
void set_z_range_min( int p_min_z);
|
||||
int get_z_range_min() const;
|
||||
|
||||
void set_z_range_max( int p_max_z);
|
||||
int get_z_range_max() const;
|
||||
|
||||
void set_layer_range_min( int p_min_layer);
|
||||
int get_layer_range_min() const;
|
||||
|
||||
void set_layer_range_max( int p_max_layer);
|
||||
int get_layer_range_max() const;
|
||||
|
||||
void set_item_mask( int p_mask);
|
||||
int get_item_mask() const;
|
||||
|
||||
void set_subtract_mode( bool p_enable );
|
||||
bool get_subtract_mode() const;
|
||||
|
||||
void set_shadow_enabled( bool p_enabled);
|
||||
bool is_shadow_enabled() const;
|
||||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
Light2D();
|
||||
~Light2D();
|
||||
};
|
||||
|
||||
|
||||
#endif // LIGHT_2D_H
|
|
@ -1,5 +1,7 @@
|
|||
#include "navigation2d.h"
|
||||
|
||||
#define USE_ENTRY_POINT
|
||||
|
||||
void Navigation2D::_navpoly_link(int p_id) {
|
||||
|
||||
ERR_FAIL_COND(!navpoly_map.has(p_id));
|
||||
|
@ -336,12 +338,25 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
List<Polygon*> open_list;
|
||||
|
||||
begin_poly->entry=p_start;
|
||||
|
||||
for(int i=0;i<begin_poly->edges.size();i++) {
|
||||
|
||||
if (begin_poly->edges[i].C) {
|
||||
|
||||
begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
Vector2 edge[2]={
|
||||
_get_vertex(begin_poly->edges[i].point),
|
||||
_get_vertex(begin_poly->edges[(i+1)%begin_poly->edges.size()].point)
|
||||
};
|
||||
|
||||
Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry,edge);
|
||||
begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry);
|
||||
begin_poly->edges[i].C->entry=entry;
|
||||
#else
|
||||
begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center);
|
||||
#endif
|
||||
open_list.push_back(begin_poly->edges[i].C);
|
||||
|
||||
if (begin_poly->edges[i].C==end_poly) {
|
||||
|
@ -381,8 +396,9 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
Polygon *p=least_cost_poly->get();
|
||||
//open the neighbours for search
|
||||
int es = p->edges.size();
|
||||
|
||||
for(int i=0;i<p->edges.size();i++) {
|
||||
for(int i=0;i<es;i++) {
|
||||
|
||||
|
||||
Polygon::Edge &e=p->edges[i];
|
||||
|
@ -390,8 +406,22 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
if (!e.C)
|
||||
continue;
|
||||
|
||||
#ifdef USE_ENTRY_POINT
|
||||
Vector2 edge[2]={
|
||||
_get_vertex(p->edges[i].point),
|
||||
_get_vertex(p->edges[(i+1)%es].point)
|
||||
};
|
||||
|
||||
Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry,edge);
|
||||
float distance = p->entry.distance_to(edge_entry) + p->distance;
|
||||
|
||||
#else
|
||||
|
||||
float distance = p->center.distance_to(e.C->center) + p->distance;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (e.C->prev_edge!=-1) {
|
||||
//oh this was visited already, can we win the cost?
|
||||
|
||||
|
@ -399,12 +429,19 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
e.C->entry=edge_entry;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
//add to open neighbours
|
||||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
e.C->entry=edge_entry;
|
||||
#endif
|
||||
|
||||
open_list.push_back(e.C);
|
||||
|
||||
if (e.C==end_poly) {
|
||||
|
|
|
@ -55,6 +55,7 @@ class Navigation2D : public Node2D {
|
|||
Vector<Edge> edges;
|
||||
|
||||
Vector2 center;
|
||||
Vector2 entry;
|
||||
|
||||
float distance;
|
||||
int prev_edge;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "tile_map.h"
|
||||
#include "io/marshalls.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
|
||||
#include "method_bind_ext.inc"
|
||||
void TileMap::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
|
@ -226,11 +226,9 @@ void TileMap::_update_dirty_quadrants() {
|
|||
|
||||
rect.pos+=tile_ofs;
|
||||
if (r==Rect2()) {
|
||||
|
||||
tex->draw_rect(q.canvas_item,rect);
|
||||
tex->draw_rect(q.canvas_item,rect,false,Color(1,1,1),c.transpose);
|
||||
} else {
|
||||
|
||||
tex->draw_rect_region(q.canvas_item,rect,r);
|
||||
tex->draw_rect_region(q.canvas_item,rect,r,Color(1,1,1),c.transpose);
|
||||
}
|
||||
|
||||
Vector< Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id);
|
||||
|
@ -244,20 +242,25 @@ void TileMap::_update_dirty_quadrants() {
|
|||
Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id);
|
||||
Matrix32 xform;
|
||||
xform.set_origin(offset.floor());
|
||||
if (c.transpose) {
|
||||
SWAP(xform.elements[0].x, xform.elements[0].y);
|
||||
SWAP(xform.elements[1].x, xform.elements[1].y);
|
||||
SWAP(shape_ofs.x, shape_ofs.y);
|
||||
SWAP(s.x, s.y);
|
||||
}
|
||||
if (c.flip_h) {
|
||||
xform.elements[0]=-xform.elements[0];
|
||||
xform.elements[2].x+=s.x-shape_ofs.x;
|
||||
} else {
|
||||
|
||||
xform.elements[2].x+=shape_ofs.x;
|
||||
xform.elements[0].x=-xform.elements[0].x;
|
||||
xform.elements[1].x=-xform.elements[1].x;
|
||||
shape_ofs.x=s.x-shape_ofs.x;
|
||||
}
|
||||
if (c.flip_v) {
|
||||
xform.elements[1]=-xform.elements[1];
|
||||
xform.elements[2].y+=s.y-shape_ofs.y;
|
||||
} else {
|
||||
|
||||
xform.elements[2].y+=shape_ofs.y;
|
||||
xform.elements[0].y=-xform.elements[0].y;
|
||||
xform.elements[1].y=-xform.elements[1].y;
|
||||
shape_ofs.y=s.y-shape_ofs.y;
|
||||
}
|
||||
xform.elements[2].x+=shape_ofs.x;
|
||||
xform.elements[2].y+=shape_ofs.y;
|
||||
|
||||
|
||||
|
||||
ps->body_add_shape(q.body,shape->get_rid(),xform);
|
||||
|
@ -386,7 +389,7 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) {
|
|||
}
|
||||
|
||||
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
PosKey pk(p_x,p_y);
|
||||
|
||||
|
@ -422,7 +425,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
|||
} else {
|
||||
ERR_FAIL_COND(!Q); // quadrant should exist...
|
||||
|
||||
if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y)
|
||||
if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y && E->get().transpose==p_transpose)
|
||||
return; //nothing changed
|
||||
|
||||
}
|
||||
|
@ -433,6 +436,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
|||
c.id=p_tile;
|
||||
c.flip_h=p_flip_x;
|
||||
c.flip_v=p_flip_y;
|
||||
c.transpose=p_transpose;
|
||||
|
||||
_make_quadrant_dirty(Q);
|
||||
|
||||
|
@ -472,6 +476,17 @@ bool TileMap::is_cell_y_flipped(int p_x,int p_y) const {
|
|||
|
||||
return E->get().flip_v;
|
||||
}
|
||||
bool TileMap::is_cell_transposed(int p_x,int p_y) const {
|
||||
|
||||
PosKey pk(p_x,p_y);
|
||||
|
||||
const Map<PosKey,Cell>::Element *E=tile_map.find(pk);
|
||||
|
||||
if (!E)
|
||||
return false;
|
||||
|
||||
return E->get().transpose;
|
||||
}
|
||||
|
||||
|
||||
void TileMap::_recreate_quadrants() {
|
||||
|
@ -536,11 +551,12 @@ void TileMap::_set_tile_data(const DVector<int>& p_data) {
|
|||
uint32_t v = decode_uint32(&local[4]);
|
||||
bool flip_h = v&(1<<29);
|
||||
bool flip_v = v&(1<<30);
|
||||
bool transpose = v&(1<<31);
|
||||
v&=(1<<29)-1;
|
||||
|
||||
// if (x<-20 || y <-20 || x>4000 || y>4000)
|
||||
// continue;
|
||||
set_cell(x,y,v,flip_h,flip_v);
|
||||
set_cell(x,y,v,flip_h,flip_v,transpose);
|
||||
|
||||
}
|
||||
|
||||
|
@ -563,6 +579,8 @@ DVector<int> TileMap::_get_tile_data() const {
|
|||
val|=(1<<29);
|
||||
if (E->get().flip_v)
|
||||
val|=(1<<30);
|
||||
if (E->get().transpose)
|
||||
val|=(1<<31);
|
||||
|
||||
encode_uint32(val,&ptr[4]);
|
||||
idx+=2;
|
||||
|
@ -829,7 +847,7 @@ void TileMap::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_collision_bounce","value"),&TileMap::set_collision_bounce);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
int32_t id:24;
|
||||
bool flip_h:1;
|
||||
bool flip_v:1;
|
||||
bool transpose:1;
|
||||
};
|
||||
|
||||
uint32_t _u32t;
|
||||
|
@ -168,10 +169,11 @@ public:
|
|||
void set_center_y(bool p_enable);
|
||||
bool get_center_y() const;
|
||||
|
||||
void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false);
|
||||
void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
|
||||
int get_cell(int p_x,int p_y) const;
|
||||
bool is_cell_x_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_y_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_transposed(int p_x,int p_y) const;
|
||||
|
||||
Rect2 get_item_rect() const;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
void add_icon_check_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0);
|
||||
void add_check_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0);
|
||||
void add_submenu_item(const String& p_label,const String& p_submenu, int p_ID=-1);
|
||||
|
||||
|
||||
void set_item_text(int p_idx,const String& p_text);
|
||||
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
|
||||
void set_item_checked(int p_idx,bool p_checked);
|
||||
|
|
|
@ -972,6 +972,22 @@ bool Viewport::get_render_target_vflip() const{
|
|||
return render_target_vflip;
|
||||
}
|
||||
|
||||
void Viewport::set_render_target_clear_on_new_frame(bool p_enable) {
|
||||
|
||||
render_target_clear_on_new_frame=p_enable;
|
||||
VisualServer::get_singleton()->viewport_set_render_target_clear_on_new_frame(viewport,p_enable);
|
||||
}
|
||||
|
||||
bool Viewport::get_render_target_clear_on_new_frame() const{
|
||||
|
||||
return render_target_clear_on_new_frame;
|
||||
}
|
||||
|
||||
void Viewport::render_target_clear() {
|
||||
|
||||
//render_target_clear=true;
|
||||
VisualServer::get_singleton()->viewport_render_target_clear(viewport);
|
||||
}
|
||||
|
||||
void Viewport::set_render_target_filter(bool p_enable) {
|
||||
|
||||
|
@ -1264,6 +1280,11 @@ void Viewport::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_clear_on_new_frame","enable"), &Viewport::set_render_target_clear_on_new_frame);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_clear_on_new_frame"), &Viewport::get_render_target_clear_on_new_frame);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("render_target_clear"), &Viewport::render_target_clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter);
|
||||
|
@ -1306,6 +1327,7 @@ void Viewport::_bind_methods() {
|
|||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_render_target_clear_on_new_frame"), _SCS("get_render_target_clear_on_new_frame") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/gen_mipmaps"), _SCS("set_render_target_gen_mipmaps"), _SCS("get_render_target_gen_mipmaps") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
|
||||
|
@ -1344,6 +1366,8 @@ Viewport::Viewport() {
|
|||
render_target_gen_mipmaps=false;
|
||||
render_target=false;
|
||||
render_target_vflip=false;
|
||||
render_target_clear_on_new_frame=true;
|
||||
//render_target_clear=true;
|
||||
render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
|
||||
render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ friend class RenderTargetTexture;
|
|||
|
||||
bool transparent_bg;
|
||||
bool render_target_vflip;
|
||||
bool render_target_clear_on_new_frame;
|
||||
bool render_target_filter;
|
||||
bool render_target_gen_mipmaps;
|
||||
|
||||
|
@ -220,6 +221,10 @@ public:
|
|||
void set_render_target_vflip(bool p_enable);
|
||||
bool get_render_target_vflip() const;
|
||||
|
||||
void set_render_target_clear_on_new_frame(bool p_enable);
|
||||
bool get_render_target_clear_on_new_frame() const;
|
||||
void render_target_clear();
|
||||
|
||||
void set_render_target_filter(bool p_enable);
|
||||
bool get_render_target_filter() const;
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "scene/resources/video_stream.h"
|
||||
#include "scene/2d/particles_2d.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
#include "scene/2d/light_2d.h"
|
||||
|
||||
#include "scene/2d/canvas_item.h"
|
||||
#include "scene/2d/sprite.h"
|
||||
|
@ -103,6 +104,7 @@
|
|||
#include "scene/2d/remote_transform_2d.h"
|
||||
#include "scene/2d/y_sort.h"
|
||||
#include "scene/2d/navigation2d.h"
|
||||
#include "scene/2d/canvas_modulate.h"
|
||||
|
||||
#include "scene/2d/position_2d.h"
|
||||
#include "scene/2d/tile_map.h"
|
||||
|
@ -263,6 +265,7 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_virtual_type<RenderTargetTexture>();
|
||||
ObjectTypeDB::register_type<Timer>();
|
||||
ObjectTypeDB::register_type<CanvasLayer>();
|
||||
ObjectTypeDB::register_type<CanvasModulate>();
|
||||
ObjectTypeDB::register_type<ResourcePreloader>();
|
||||
|
||||
/* REGISTER GUI */
|
||||
|
@ -472,6 +475,7 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_type<VisibilityNotifier2D>();
|
||||
ObjectTypeDB::register_type<VisibilityEnabler2D>();
|
||||
ObjectTypeDB::register_type<Polygon2D>();
|
||||
ObjectTypeDB::register_type<Light2D>();
|
||||
ObjectTypeDB::register_type<YSort>();
|
||||
|
||||
ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
|
||||
|
|
|
@ -38,19 +38,19 @@ Size2 Texture::get_size() const {
|
|||
}
|
||||
|
||||
|
||||
void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{
|
||||
void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
bool Texture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
|
||||
|
@ -70,9 +70,9 @@ void Texture::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("has_alpha"),&Texture::has_alpha);
|
||||
ObjectTypeDB::bind_method(_MD("set_flags","flags"),&Texture::set_flags);
|
||||
ObjectTypeDB::bind_method(_MD("get_flags"),&Texture::get_flags);
|
||||
ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
|
||||
BIND_CONSTANT( FLAG_MIPMAPS );
|
||||
BIND_CONSTANT( FLAG_REPEAT );
|
||||
|
@ -327,28 +327,27 @@ bool ImageTexture::has_alpha() const {
|
|||
}
|
||||
|
||||
|
||||
void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{
|
||||
void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
|
||||
void ImageTexture::set_size_override(const Size2& p_size) {
|
||||
|
||||
Size2 s=p_size;
|
||||
|
@ -546,7 +545,7 @@ void AtlasTexture::_bind_methods() {
|
|||
|
||||
|
||||
|
||||
void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
Rect2 rc=region;
|
||||
|
||||
|
@ -561,10 +560,10 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_m
|
|||
rc.size.height=atlas->get_height();
|
||||
}
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
Rect2 rc=region;
|
||||
|
||||
|
@ -582,10 +581,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,
|
|||
Vector2 scale = p_rect.size / (region.size+margin.size);
|
||||
Rect2 dr( p_rect.pos+margin.pos*scale,rc.size*scale );
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const {
|
||||
void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
//this might not necesarily work well if using a rect, needs to be fixed properly
|
||||
Rect2 rc=region;
|
||||
|
@ -615,7 +614,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
}
|
||||
Rect2 dr( p_rect.pos+ofs*scale,src_c.size*scale );
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
bool AtlasTexture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
|
||||
|
@ -801,15 +800,16 @@ void LargeTexture::_bind_methods() {
|
|||
|
||||
|
||||
|
||||
void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
pieces[i].texture->draw(p_canvas_item,pieces[i].offset+p_pos,p_modulate);
|
||||
// TODO
|
||||
pieces[i].texture->draw(p_canvas_item,pieces[i].offset+p_pos,p_modulate,p_transpose);
|
||||
}
|
||||
}
|
||||
|
||||
void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
//tiling not supported for this
|
||||
if (size.x==0 || size.y==0)
|
||||
|
@ -819,11 +819,11 @@ void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,
|
|||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
pieces[i].texture->draw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate);
|
||||
// TODO
|
||||
pieces[i].texture->draw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
}
|
||||
void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const {
|
||||
void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
|
||||
//tiling not supported for this
|
||||
|
@ -834,6 +834,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
// TODO
|
||||
Rect2 rect( pieces[i].offset, pieces[i].texture->get_size());
|
||||
if (!p_src_rect.intersects(rect))
|
||||
continue;
|
||||
|
@ -842,7 +843,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
target.size*=scale;
|
||||
target.pos=p_rect.pos+(p_src_rect.pos+rect.pos)*scale;
|
||||
local.pos-=rect.pos;
|
||||
pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate);
|
||||
pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ public:
|
|||
virtual void set_flags(uint32_t p_flags)=0;
|
||||
virtual uint32_t get_flags() const=0;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
|
||||
|
||||
|
||||
|
@ -135,10 +135,9 @@ public:
|
|||
virtual RID get_rid() const;
|
||||
|
||||
bool has_alpha() const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
void set_storage(Storage p_storage);
|
||||
Storage get_storage() const;
|
||||
|
||||
|
@ -191,9 +190,9 @@ public:
|
|||
void set_margin(const Rect2& p_margin);
|
||||
Rect2 get_margin() const ;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
|
||||
|
||||
|
||||
|
@ -241,9 +240,9 @@ public:
|
|||
Vector2 get_piece_offset(int p_idx) const;
|
||||
Ref<Texture> get_piece_texture(int p_idx) const;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
|
||||
|
||||
LargeTexture();
|
||||
|
|
|
@ -564,9 +564,58 @@ public:
|
|||
CANVAS_RECT_REGION=1,
|
||||
CANVAS_RECT_TILE=2,
|
||||
CANVAS_RECT_FLIP_H=4,
|
||||
CANVAS_RECT_FLIP_V=8
|
||||
CANVAS_RECT_FLIP_V=8,
|
||||
CANVAS_RECT_TRANSPOSE=16
|
||||
};
|
||||
|
||||
|
||||
struct CanvasLight {
|
||||
|
||||
|
||||
bool enabled;
|
||||
bool shadow;
|
||||
Color color;
|
||||
Matrix32 xform;
|
||||
float height;
|
||||
int z_min;
|
||||
int z_max;
|
||||
int layer_min;
|
||||
int layer_max;
|
||||
int item_mask;
|
||||
bool subtract;
|
||||
RID texture;
|
||||
Vector2 texture_offset;
|
||||
RID canvas;
|
||||
|
||||
|
||||
void *texture_cache; // implementation dependent
|
||||
Rect2 rect_cache;
|
||||
Matrix32 xform_cache;
|
||||
|
||||
Matrix32 light_shader_xform;
|
||||
Vector2 light_shader_pos;
|
||||
|
||||
CanvasLight *filter_next_ptr;
|
||||
CanvasLight *next_ptr;
|
||||
|
||||
CanvasLight() {
|
||||
enabled=true;
|
||||
shadow=false;
|
||||
color=Color(1,1,1);
|
||||
height=0;
|
||||
z_min=-1024;
|
||||
z_max=1024;
|
||||
layer_min=0;
|
||||
layer_max=0;
|
||||
item_mask=1;
|
||||
subtract=false;
|
||||
texture_cache=NULL;
|
||||
next_ptr=NULL;
|
||||
filter_next_ptr=NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CanvasItem {
|
||||
|
||||
struct Command {
|
||||
|
@ -689,6 +738,7 @@ public:
|
|||
bool visible;
|
||||
bool ontop;
|
||||
VS::MaterialBlendMode blend_mode;
|
||||
int light_mask;
|
||||
Vector<Command*> commands;
|
||||
mutable bool custom_rect;
|
||||
mutable bool rect_dirty;
|
||||
|
@ -706,8 +756,9 @@ public:
|
|||
CanvasItem* shader_owner;
|
||||
ViewportRender *vp_render;
|
||||
|
||||
const Rect2& get_rect() const {
|
||||
Rect2 global_rect_cache;
|
||||
|
||||
const Rect2& get_rect() const {
|
||||
if (custom_rect || !rect_dirty)
|
||||
return rect;
|
||||
|
||||
|
@ -831,7 +882,7 @@ public:
|
|||
}
|
||||
|
||||
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; shader_owner=NULL;}
|
||||
CanvasItem() { vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0; shader_owner=NULL;}
|
||||
CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0; shader_owner=NULL;}
|
||||
virtual ~CanvasItem() { clear(); }
|
||||
};
|
||||
|
||||
|
@ -853,7 +904,7 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor)=0;
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform)=0;
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list)=0;
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light)=0;
|
||||
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
|
|
@ -1622,7 +1622,7 @@ void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) {
|
|||
|
||||
}
|
||||
|
||||
void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list) {
|
||||
void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -710,7 +710,7 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor);
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform);
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list);
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light);
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
|
|
|
@ -1576,6 +1576,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->render_target_clear_on_new_frame=p_enable;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
|
@ -1594,6 +1603,23 @@ bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{
|
|||
|
||||
}
|
||||
|
||||
bool VisualServerRaster::viewport_get_render_target_clear_on_new_frame(RID p_viewport) const{
|
||||
|
||||
const Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND_V(!viewport,false);
|
||||
|
||||
return viewport->render_target_clear_on_new_frame;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_render_target_clear(RID p_viewport) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->render_target_clear=true;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) {
|
||||
|
||||
|
@ -3195,6 +3221,7 @@ RID VisualServerRaster::canvas_create() {
|
|||
return rid;
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring) {
|
||||
|
||||
Canvas * canvas = canvas_owner.get(p_canvas);
|
||||
|
@ -3220,6 +3247,14 @@ Point2 VisualServerRaster::canvas_get_item_mirroring(RID p_canvas,RID p_item) co
|
|||
return canvas->child_items[idx].mirror;
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color) {
|
||||
|
||||
Canvas * canvas = canvas_owner.get(p_canvas);
|
||||
ERR_FAIL_COND(!canvas);
|
||||
canvas->modulate=p_color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RID VisualServerRaster::canvas_item_create() {
|
||||
|
||||
|
@ -3305,14 +3340,27 @@ bool VisualServerRaster::canvas_item_is_visible(RID p_item) const {
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_light_mask(RID p_canvas_item,int p_mask) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
if (canvas_item->light_mask==p_mask)
|
||||
return;
|
||||
VS_CHANGED;
|
||||
|
||||
canvas_item->light_mask=p_mask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
if (!canvas_item) {
|
||||
printf("!canvas_item\n");
|
||||
};
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
if (canvas_item->blend_mode==p_blend)
|
||||
|
@ -3470,7 +3518,7 @@ void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos,
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate) {
|
||||
void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate,bool p_transpose) {
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -3493,12 +3541,16 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p
|
|||
rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
rect->rect.size.y = -rect->rect.size.y;
|
||||
}
|
||||
if (p_transpose) {
|
||||
rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE;
|
||||
SWAP(rect->rect.size.x, rect->rect.size.y);
|
||||
}
|
||||
rect->texture=p_texture;
|
||||
canvas_item->rect_dirty=true;
|
||||
canvas_item->commands.push_back(rect);
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate) {
|
||||
void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate,bool p_transpose) {
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -3521,12 +3573,17 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R
|
|||
rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
rect->rect.size.y = -rect->rect.size.y;
|
||||
}
|
||||
if (p_transpose) {
|
||||
rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE;
|
||||
SWAP(rect->rect.size.x, rect->rect.size.y);
|
||||
}
|
||||
|
||||
canvas_item->rect_dirty=true;
|
||||
|
||||
canvas_item->commands.push_back(rect);
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
@ -3823,60 +3880,128 @@ void VisualServerRaster::canvas_item_raise(RID p_item) {
|
|||
|
||||
RID VisualServerRaster::canvas_light_create() {
|
||||
|
||||
return RID();
|
||||
Rasterizer::CanvasLight *clight = memnew( Rasterizer::CanvasLight );
|
||||
return canvas_light_owner.make_rid(clight);
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
if (clight->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(clight->canvas);
|
||||
canvas->lights.erase(clight);
|
||||
}
|
||||
|
||||
if (!canvas_owner.owns(p_canvas))
|
||||
p_canvas=RID();
|
||||
clight->canvas=p_canvas;
|
||||
|
||||
if (clight->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(clight->canvas);
|
||||
canvas->lights.insert(clight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->enabled=p_enabled;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& p_transform){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->xform=p_transform;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->texture=p_texture;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->texture_offset=p_offset;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_color(RID p_light, const Color& p_color){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->color=p_color;
|
||||
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_height(RID p_light, float p_height){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->height=p_height;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->z_min=p_min_z;
|
||||
clight->z_max=p_max_z;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer) {
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->layer_min=p_min_layer;
|
||||
clight->layer_max=p_max_layer;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->item_mask=p_mask;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode){
|
||||
void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) {
|
||||
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->subtract=p_enable;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->shadow=p_enabled;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
}
|
||||
|
||||
|
@ -4154,7 +4279,13 @@ void VisualServerRaster::free( RID p_rid ) {
|
|||
|
||||
canvas->child_items[i].item->parent=RID();
|
||||
}
|
||||
|
||||
|
||||
for (Set<Rasterizer::CanvasLight*>::Element *E=canvas->lights.front();E;E=E->next()) {
|
||||
|
||||
E->get()->canvas=RID();
|
||||
}
|
||||
|
||||
|
||||
canvas_owner.free( p_rid );
|
||||
|
||||
memdelete( canvas );
|
||||
|
@ -4186,6 +4317,21 @@ void VisualServerRaster::free( RID p_rid ) {
|
|||
canvas_item_owner.free( p_rid );
|
||||
|
||||
memdelete( canvas_item );
|
||||
|
||||
} else if (canvas_light_owner.owns(p_rid)) {
|
||||
|
||||
Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid);
|
||||
ERR_FAIL_COND(!canvas_light);
|
||||
|
||||
if (canvas_light->canvas.is_valid()) {
|
||||
Canvas* canvas = canvas_owner.get(canvas_light->canvas);
|
||||
if (canvas)
|
||||
canvas->lights.erase(canvas_light);
|
||||
}
|
||||
|
||||
canvas_light_owner.free( p_rid );
|
||||
memdelete( canvas_light );
|
||||
|
||||
} else if (scenario_owner.owns(p_rid)) {
|
||||
|
||||
Scenario *scenario=scenario_owner.get(p_rid);
|
||||
|
@ -6231,7 +6377,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
|
|||
}
|
||||
|
||||
|
||||
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) {
|
||||
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color& p_modulate, Rasterizer::CanvasLight *p_lights) {
|
||||
|
||||
|
||||
static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
|
||||
|
@ -6249,7 +6395,7 @@ void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,cons
|
|||
for(int i=0;i<z_range;i++) {
|
||||
if (!z_list[i])
|
||||
continue;
|
||||
rasterizer->canvas_render_items(z_list[i]);
|
||||
rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_modulate,p_lights);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6355,7 +6501,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
//something to draw?
|
||||
ci->final_transform=xform;
|
||||
ci->final_opacity=opacity * ci->self_opacity;
|
||||
|
||||
ci->global_rect_cache=global_rect;
|
||||
|
||||
int zidx = p_z-CANVAS_ITEM_Z_MIN;
|
||||
|
||||
|
@ -6368,6 +6514,8 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
z_last_list[zidx]=ci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ci->next=NULL;
|
||||
|
||||
}
|
||||
|
@ -6381,7 +6529,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform) {
|
||||
void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) {
|
||||
|
||||
rasterizer->canvas_begin();
|
||||
|
||||
|
@ -6414,30 +6562,30 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
|
|||
for(int i=0;i<z_range;i++) {
|
||||
if (!z_list[i])
|
||||
continue;
|
||||
rasterizer->canvas_render_items(z_list[i]);
|
||||
rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights);
|
||||
}
|
||||
} else {
|
||||
|
||||
for(int i=0;i<l;i++) {
|
||||
|
||||
Canvas::ChildItem& ci=p_canvas->child_items[i];
|
||||
_render_canvas_item_tree(ci.item,p_transform,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,p_transform,clip_rect,p_canvas->modulate,p_lights);
|
||||
|
||||
//mirroring (useful for scrolling backgrounds)
|
||||
if (ci.mirror.x!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
if (ci.mirror.y!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
if (ci.mirror.y!=0 && ci.mirror.x!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6492,7 +6640,10 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
|
|||
} else if (true /*|| !p_viewport->canvas_list.empty()*/){
|
||||
|
||||
//clear the viewport black because of no camera? i seriously should..
|
||||
rasterizer->clear_viewport(clear_color);
|
||||
if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) {
|
||||
rasterizer->clear_viewport(clear_color);
|
||||
p_viewport->render_target_clear=false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_viewport->hide_canvas) {
|
||||
|
@ -6500,7 +6651,43 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
|
|||
|
||||
Map<Viewport::CanvasKey,Viewport::CanvasData*> canvas_map;
|
||||
|
||||
Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height);
|
||||
Rasterizer::CanvasLight *lights=NULL;
|
||||
|
||||
for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) {
|
||||
|
||||
Matrix32 xf = p_viewport->global_transform * E->get().transform;
|
||||
|
||||
//find lights in canvas
|
||||
|
||||
|
||||
for(Set<Rasterizer::CanvasLight*>::Element *F=E->get().canvas->lights.front();F;F=F->next()) {
|
||||
|
||||
Rasterizer::CanvasLight* cl=F->get();
|
||||
if (cl->enabled && cl->texture.is_valid()) {
|
||||
//not super efficient..
|
||||
Size2 tsize(rasterizer->texture_get_width(cl->texture),rasterizer->texture_get_height(cl->texture));
|
||||
Vector2 offset=tsize/2.0;
|
||||
cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize);
|
||||
cl->xform_cache=xf * cl->xform;
|
||||
|
||||
if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) {
|
||||
cl->filter_next_ptr=lights;
|
||||
lights=cl;
|
||||
cl->texture_cache=NULL;
|
||||
Matrix32 scale;
|
||||
scale.scale(cl->rect_cache.size);
|
||||
scale.elements[2]=cl->rect_cache.pos;
|
||||
cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse();
|
||||
cl->light_shader_pos=cl->xform_cache[2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get();
|
||||
|
||||
}
|
||||
|
@ -6511,7 +6698,19 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
|
|||
// print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size()));
|
||||
//print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform);
|
||||
Matrix32 xform = p_viewport->global_transform * E->get()->transform;
|
||||
_render_canvas( E->get()->canvas,xform );
|
||||
|
||||
Rasterizer::CanvasLight *canvas_lights=NULL;
|
||||
|
||||
Rasterizer::CanvasLight *ptr=lights;
|
||||
while(ptr) {
|
||||
if (E->get()->layer>=ptr->layer_min && E->get()->layer<=ptr->layer_max) {
|
||||
ptr->next_ptr=canvas_lights;
|
||||
canvas_lights=ptr;
|
||||
}
|
||||
ptr=ptr->filter_next_ptr;
|
||||
}
|
||||
|
||||
_render_canvas( E->get()->canvas,xform,canvas_lights );
|
||||
i++;
|
||||
|
||||
}
|
||||
|
|
|
@ -410,6 +410,8 @@ class VisualServerRaster : public VisualServer {
|
|||
}
|
||||
};
|
||||
|
||||
struct CanvasLight;
|
||||
|
||||
struct Canvas {
|
||||
|
||||
Set<RID> viewports;
|
||||
|
@ -419,8 +421,10 @@ class VisualServerRaster : public VisualServer {
|
|||
CanvasItem *item;
|
||||
};
|
||||
|
||||
Set<Rasterizer::CanvasLight*> lights;
|
||||
|
||||
Vector<ChildItem> child_items;
|
||||
Color modulate;
|
||||
|
||||
int find_item(CanvasItem *p_item) {
|
||||
for(int i=0;i<child_items.size();i++) {
|
||||
|
@ -435,11 +439,13 @@ class VisualServerRaster : public VisualServer {
|
|||
child_items.remove(idx);
|
||||
}
|
||||
|
||||
Canvas() { }
|
||||
Canvas() { modulate=Color(1,1,1,1); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
RID_Owner<Rasterizer::CanvasLight> canvas_light_owner;
|
||||
|
||||
|
||||
struct Viewport {
|
||||
|
||||
|
@ -462,6 +468,8 @@ class VisualServerRaster : public VisualServer {
|
|||
bool transparent_bg;
|
||||
bool queue_capture;
|
||||
bool render_target_vflip;
|
||||
bool render_target_clear_on_new_frame;
|
||||
bool render_target_clear;
|
||||
Image capture;
|
||||
|
||||
bool rendered_in_prev_frame;
|
||||
|
@ -488,7 +496,7 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
SelfList<Viewport> update_list;
|
||||
|
||||
Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false;}
|
||||
Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true;}
|
||||
};
|
||||
|
||||
SelfList<Viewport>::List viewport_update_list;
|
||||
|
@ -601,9 +609,9 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
|
||||
static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect);
|
||||
void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect);
|
||||
void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights);
|
||||
void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner);
|
||||
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
|
||||
void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights);
|
||||
Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
|
||||
Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
|
||||
|
||||
|
@ -951,6 +959,9 @@ public:
|
|||
virtual RID viewport_get_render_target_texture(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable);
|
||||
virtual bool viewport_get_render_target_vflip(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable);
|
||||
virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const;
|
||||
virtual void viewport_render_target_clear(RID p_viewport);
|
||||
virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect);
|
||||
|
||||
virtual void viewport_queue_screen_capture(RID p_viewport);
|
||||
|
@ -1073,6 +1084,8 @@ public:
|
|||
virtual RID canvas_create();
|
||||
virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring);
|
||||
virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const;
|
||||
virtual void canvas_set_modulate(RID p_canvas,const Color& p_color);
|
||||
|
||||
|
||||
virtual RID canvas_item_create();
|
||||
|
||||
|
@ -1083,6 +1096,8 @@ public:
|
|||
virtual bool canvas_item_is_visible(RID p_item) const;
|
||||
|
||||
virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend);
|
||||
virtual void canvas_item_set_light_mask(RID p_canvas_item,int p_mask);
|
||||
|
||||
|
||||
|
||||
//virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect);
|
||||
|
@ -1102,8 +1117,8 @@ public:
|
|||
virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0);
|
||||
virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color);
|
||||
virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color);
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);
|
||||
virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0);
|
||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID());
|
||||
|
@ -1135,20 +1150,10 @@ public:
|
|||
virtual void canvas_light_set_color(RID p_light, const Color& p_color);
|
||||
virtual void canvas_light_set_height(RID p_light, float p_height);
|
||||
virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z);
|
||||
virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer);
|
||||
virtual void canvas_light_set_item_mask(RID p_light, int p_mask);
|
||||
|
||||
enum CanvasightBlendMode {
|
||||
CANVAS_LIGHT_BLEND_ADD,
|
||||
CANVAS_LIGHT_BLEND_SUB,
|
||||
CANVAS_LIGHT_BLEND_MULTIPLY,
|
||||
CANVAS_LIGHT_BLEND_DODGE,
|
||||
CANVAS_LIGHT_BLEND_BURN,
|
||||
CANVAS_LIGHT_BLEND_LIGHTEN,
|
||||
CANVAS_LIGHT_BLEND_DARKEN,
|
||||
CANVAS_LIGHT_BLEND_OVERLAY,
|
||||
CANVAS_LIGHT_BLEND_SCREEN,
|
||||
};
|
||||
virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode);
|
||||
virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable);
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
|
||||
virtual void canvas_light_set_shadow_filter(RID p_light, int p_size);
|
||||
|
|
|
@ -967,6 +967,10 @@ public:
|
|||
FUNC2(viewport_set_render_target_vflip,RID,bool);
|
||||
FUNC1RC(bool,viewport_get_render_target_vflip,RID);
|
||||
FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&);
|
||||
|
||||
FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool);
|
||||
FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID);
|
||||
FUNC1(viewport_render_target_clear,RID);
|
||||
|
||||
FUNC1(viewport_queue_screen_capture,RID);
|
||||
FUNC1RC(Image,viewport_get_screen_capture,RID);
|
||||
|
@ -1087,6 +1091,8 @@ public:
|
|||
FUNC0R(RID,canvas_create);
|
||||
FUNC3(canvas_set_item_mirroring,RID,RID,const Point2&);
|
||||
FUNC2RC(Point2,canvas_get_item_mirroring,RID,RID);
|
||||
FUNC2(canvas_set_modulate,RID,const Color&);
|
||||
|
||||
|
||||
FUNC0R(RID,canvas_item_create);
|
||||
|
||||
|
@ -1097,7 +1103,7 @@ public:
|
|||
FUNC1RC(bool,canvas_item_is_visible,RID);
|
||||
|
||||
FUNC2(canvas_item_set_blend_mode,RID,MaterialBlendMode );
|
||||
|
||||
FUNC2(canvas_item_set_light_mask,RID,int );
|
||||
|
||||
//FUNC(canvas_item_set_rect,RID, const Rect2& p_rect);
|
||||
FUNC2(canvas_item_set_transform,RID, const Matrix32& );
|
||||
|
@ -1116,9 +1122,8 @@ public:
|
|||
FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float );
|
||||
FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& );
|
||||
FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& );
|
||||
FUNC5(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color& );
|
||||
FUNC5(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color& );
|
||||
|
||||
FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool );
|
||||
FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool );
|
||||
FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& );
|
||||
FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float );
|
||||
FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID );
|
||||
|
@ -1155,10 +1160,11 @@ public:
|
|||
FUNC2(canvas_light_set_texture_offset,RID,const Vector2&);
|
||||
FUNC2(canvas_light_set_color,RID,const Color&);
|
||||
FUNC2(canvas_light_set_height,RID,float);
|
||||
FUNC3(canvas_light_set_layer_range,RID,int,int);
|
||||
FUNC3(canvas_light_set_z_range,RID,int,int);
|
||||
FUNC2(canvas_light_set_item_mask,RID,int);
|
||||
|
||||
FUNC2(canvas_light_set_blend_mode,RID,CanvasLightBlendMode);
|
||||
FUNC2(canvas_light_set_subtract_mode,RID,bool);
|
||||
FUNC2(canvas_light_set_shadow_enabled,RID,bool);
|
||||
FUNC2(canvas_light_set_shadow_buffer_size,RID,int);
|
||||
FUNC2(canvas_light_set_shadow_filter,RID,int);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
/*************************************************************************/
|
||||
#include "visual_server.h"
|
||||
#include "globals.h"
|
||||
#include "method_bind_ext.inc"
|
||||
|
||||
VisualServer *VisualServer::singleton=NULL;
|
||||
VisualServer* (*VisualServer::create_func)()=NULL;
|
||||
|
@ -510,8 +511,9 @@ void VisualServer::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_line"),&VisualServer::canvas_item_add_line, DEFVAL(1.0));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_rect"),&VisualServer::canvas_item_add_rect);
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)), DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)), DEFVAL(false));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_style_box"),&VisualServer::_canvas_item_add_style_box, DEFVAL(Color(1,1,1)));
|
||||
// ObjectTypeDB::bind_method(_MD("canvas_item_add_primitive"),&VisualServer::canvas_item_add_primitive,DEFVAL(Vector<Vector2>()),DEFVAL(RID()));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_circle"),&VisualServer::canvas_item_add_circle);
|
||||
|
|
|
@ -684,6 +684,9 @@ public:
|
|||
virtual RID viewport_get_render_target_texture(RID p_viewport) const=0;
|
||||
virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable)=0;
|
||||
virtual bool viewport_get_render_target_vflip(RID p_viewport) const=0;
|
||||
virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable)=0;
|
||||
virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const=0;
|
||||
virtual void viewport_render_target_clear(RID p_viewport)=0;
|
||||
|
||||
virtual void viewport_queue_screen_capture(RID p_viewport)=0;
|
||||
virtual Image viewport_get_screen_capture(RID p_viewport) const=0;
|
||||
|
@ -944,6 +947,8 @@ public:
|
|||
virtual RID canvas_create()=0;
|
||||
virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring)=0;
|
||||
virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const=0;
|
||||
virtual void canvas_set_modulate(RID p_canvas,const Color& p_color)=0;
|
||||
|
||||
|
||||
|
||||
virtual RID canvas_item_create()=0;
|
||||
|
@ -953,6 +958,8 @@ public:
|
|||
virtual void canvas_item_set_visible(RID p_item,bool p_visible)=0;
|
||||
virtual bool canvas_item_is_visible(RID p_item) const=0;
|
||||
|
||||
virtual void canvas_item_set_light_mask(RID p_item,int p_mask)=0;
|
||||
|
||||
virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend)=0;
|
||||
|
||||
virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport)=0;
|
||||
|
@ -974,8 +981,8 @@ public:
|
|||
virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0)=0;
|
||||
virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0;
|
||||
virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0;
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;
|
||||
virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0)=0;
|
||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID())=0;
|
||||
|
@ -1008,20 +1015,10 @@ public:
|
|||
virtual void canvas_light_set_color(RID p_light, const Color& p_color)=0;
|
||||
virtual void canvas_light_set_height(RID p_light, float p_height)=0;
|
||||
virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z)=0;
|
||||
virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer)=0;
|
||||
virtual void canvas_light_set_item_mask(RID p_light, int p_mask)=0;
|
||||
|
||||
enum CanvasLightBlendMode {
|
||||
CANVAS_LIGHT_BLEND_ADD,
|
||||
CANVAS_LIGHT_BLEND_SUB,
|
||||
CANVAS_LIGHT_BLEND_MULTIPLY,
|
||||
CANVAS_LIGHT_BLEND_DODGE,
|
||||
CANVAS_LIGHT_BLEND_BURN,
|
||||
CANVAS_LIGHT_BLEND_LIGHTEN,
|
||||
CANVAS_LIGHT_BLEND_DARKEN,
|
||||
CANVAS_LIGHT_BLEND_OVERLAY,
|
||||
CANVAS_LIGHT_BLEND_SCREEN,
|
||||
};
|
||||
virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode)=0;
|
||||
virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0;
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0;
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0;
|
||||
virtual void canvas_light_set_shadow_filter(RID p_light, int p_size)=0;
|
||||
|
|
BIN
tools/editor/icons/icon_light_2d.png
Normal file
BIN
tools/editor/icons/icon_light_2d.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
BIN
tools/editor/icons/icon_rotate_0.png
Normal file
BIN
tools/editor/icons/icon_rotate_0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 207 B |
BIN
tools/editor/icons/icon_rotate_180.png
Normal file
BIN
tools/editor/icons/icon_rotate_180.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 303 B |
BIN
tools/editor/icons/icon_rotate_270.png
Normal file
BIN
tools/editor/icons/icon_rotate_270.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 343 B |
BIN
tools/editor/icons/icon_rotate_90.png
Normal file
BIN
tools/editor/icons/icon_rotate_90.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 256 B |
BIN
tools/editor/icons/icon_transpose.png
Normal file
BIN
tools/editor/icons/icon_transpose.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 B |
|
@ -34,7 +34,7 @@
|
|||
#include "os/file_access.h"
|
||||
#include "tools/editor/editor_settings.h"
|
||||
#include "os/input.h"
|
||||
|
||||
#include "method_bind_ext.inc"
|
||||
|
||||
void TileMapEditor::_notification(int p_what) {
|
||||
|
||||
|
@ -42,8 +42,13 @@ void TileMapEditor::_notification(int p_what) {
|
|||
|
||||
case NOTIFICATION_READY: {
|
||||
|
||||
transpose->set_icon( get_icon("Transpose","EditorIcons"));
|
||||
mirror_x->set_icon( get_icon("MirrorX","EditorIcons"));
|
||||
mirror_y->set_icon( get_icon("MirrorY","EditorIcons"));
|
||||
rotate_0->set_icon( get_icon("Rotate0","EditorIcons"));
|
||||
rotate_90->set_icon( get_icon("Rotate90","EditorIcons"));
|
||||
rotate_180->set_icon( get_icon("Rotate180","EditorIcons"));
|
||||
rotate_270->set_icon( get_icon("Rotate270","EditorIcons"));
|
||||
|
||||
} break;
|
||||
}
|
||||
|
@ -85,24 +90,31 @@ void TileMapEditor::set_selected_tile(int p_tile) {
|
|||
}
|
||||
}
|
||||
|
||||
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v,bool p_with_undo) {
|
||||
// Wrapper to workaround five arg limit of undo/redo methods
|
||||
void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose) {
|
||||
ERR_FAIL_COND(!node);
|
||||
node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose);
|
||||
}
|
||||
|
||||
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) {
|
||||
|
||||
ERR_FAIL_COND(!node);
|
||||
|
||||
bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y);
|
||||
bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y);
|
||||
bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y);
|
||||
int prev_val=node->get_cell(p_pos.x,p_pos.y);
|
||||
|
||||
if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v)
|
||||
if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v && p_transpose==prev_transpose)
|
||||
return; //check that it's actually different
|
||||
|
||||
|
||||
if (p_with_undo) {
|
||||
undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v);
|
||||
undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v);
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose);
|
||||
} else {
|
||||
|
||||
node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v);
|
||||
node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,6 +180,7 @@ struct _TileMapEditorCopyData {
|
|||
int cell;
|
||||
bool flip_h;
|
||||
bool flip_v;
|
||||
bool transpose;
|
||||
};
|
||||
|
||||
bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
||||
|
@ -204,6 +217,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
tcd.cell=node->get_cell(j,i);
|
||||
tcd.flip_h=node->is_cell_x_flipped(j,i);
|
||||
tcd.flip_v=node->is_cell_y_flipped(j,i);
|
||||
tcd.transpose=node->is_cell_transposed(j,i);
|
||||
dupdata.push_back(tcd);
|
||||
|
||||
|
||||
|
@ -214,7 +228,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for (List<_TileMapEditorCopyData>::Element *E=dupdata.front();E;E=E->next()) {
|
||||
|
||||
|
||||
_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,true);
|
||||
_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true);
|
||||
}
|
||||
undo_redo->commit_action();
|
||||
|
||||
|
@ -239,6 +253,10 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
} else if (mb.mod.control) {
|
||||
tool=TOOL_PICKING;
|
||||
set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
|
||||
mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
|
||||
mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
|
||||
transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
|
||||
_update_transform_buttons();
|
||||
canvas_item_editor->update();
|
||||
return true;
|
||||
} else {
|
||||
|
@ -248,7 +266,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y))));
|
||||
paint_undo.clear();
|
||||
paint_undo[local]=_get_op_from_cell(local);
|
||||
node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -263,8 +281,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y));
|
||||
undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf);
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
@ -289,7 +307,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
|
||||
paint_undo.clear();
|
||||
paint_undo[local]=_get_op_from_cell(local);
|
||||
//node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
//node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
//return true;
|
||||
_set_cell(local,TileMap::INVALID_CELL);
|
||||
return true;
|
||||
|
@ -302,9 +320,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y));
|
||||
_set_cell(p,TileMap::INVALID_CELL,false,false,true);
|
||||
undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf);
|
||||
//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
_set_cell(p,TileMap::INVALID_CELL,false,false,false,true);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
@ -340,7 +358,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
|
||||
paint_undo[over_tile]=_get_op_from_cell(over_tile);
|
||||
}
|
||||
node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -373,13 +391,17 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
if (!paint_undo.has(over_tile)) {
|
||||
paint_undo[over_tile]=_get_op_from_cell(over_tile);
|
||||
}
|
||||
//node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
//node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
_set_cell(local,TileMap::INVALID_CELL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tool==TOOL_PICKING) {
|
||||
set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
|
||||
mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
|
||||
mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
|
||||
transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
|
||||
_update_transform_buttons();
|
||||
canvas_item_editor->update();
|
||||
return true;
|
||||
}
|
||||
|
@ -627,10 +649,10 @@ void TileMapEditor::_canvas_draw() {
|
|||
sc.y*=-1.0;
|
||||
if (r==Rect2()) {
|
||||
|
||||
canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5));
|
||||
canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5),transpose->is_pressed());
|
||||
} else {
|
||||
|
||||
canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5));
|
||||
canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5),transpose->is_pressed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -697,6 +719,8 @@ void TileMapEditor::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter);
|
||||
ObjectTypeDB::bind_method(_MD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit);
|
||||
ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed);
|
||||
ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons);
|
||||
ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
|
||||
}
|
||||
|
||||
|
@ -709,10 +733,60 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos)
|
|||
op.xf=true;
|
||||
if (node->is_cell_y_flipped(p_pos.x,p_pos.y))
|
||||
op.yf=true;
|
||||
if (node->is_cell_transposed(p_pos.x,p_pos.y))
|
||||
op.tr=true;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
void TileMapEditor::_update_transform_buttons(Object *p_button) {
|
||||
//ERR_FAIL_NULL(p_button);
|
||||
ToolButton *b=p_button->cast_to<ToolButton>();
|
||||
//ERR_FAIL_COND(!b);
|
||||
|
||||
mirror_x->set_block_signals(true);
|
||||
mirror_y->set_block_signals(true);
|
||||
transpose->set_block_signals(true);
|
||||
rotate_0->set_block_signals(true);
|
||||
rotate_90->set_block_signals(true);
|
||||
rotate_180->set_block_signals(true);
|
||||
rotate_270->set_block_signals(true);
|
||||
|
||||
if (b == rotate_0) {
|
||||
mirror_x->set_pressed(false);
|
||||
mirror_y->set_pressed(false);
|
||||
transpose->set_pressed(false);
|
||||
}
|
||||
else if (b == rotate_90) {
|
||||
mirror_x->set_pressed(true);
|
||||
mirror_y->set_pressed(false);
|
||||
transpose->set_pressed(true);
|
||||
}
|
||||
else if (b == rotate_180) {
|
||||
mirror_x->set_pressed(true);
|
||||
mirror_y->set_pressed(true);
|
||||
transpose->set_pressed(false);
|
||||
}
|
||||
else if (b == rotate_270) {
|
||||
mirror_x->set_pressed(false);
|
||||
mirror_y->set_pressed(true);
|
||||
transpose->set_pressed(true);
|
||||
}
|
||||
|
||||
rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed());
|
||||
rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
rotate_270->set_pressed(!mirror_x->is_pressed() && mirror_y->is_pressed() && transpose->is_pressed());
|
||||
|
||||
mirror_x->set_block_signals(false);
|
||||
mirror_y->set_block_signals(false);
|
||||
transpose->set_block_signals(false);
|
||||
rotate_0->set_block_signals(false);
|
||||
rotate_90->set_block_signals(false);
|
||||
rotate_180->set_block_signals(false);
|
||||
rotate_270->set_block_signals(false);
|
||||
}
|
||||
|
||||
TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
||||
|
||||
node=NULL;
|
||||
|
@ -734,18 +808,52 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
|||
canvas_item_editor_hb = memnew( HBoxContainer );
|
||||
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(canvas_item_editor_hb);
|
||||
canvas_item_editor_hb->add_child( memnew( VSeparator ));
|
||||
transpose = memnew( ToolButton );
|
||||
transpose->set_toggle_mode(true);
|
||||
transpose->set_tooltip("Transpose");
|
||||
transpose->set_focus_mode(FOCUS_NONE);
|
||||
transpose->connect("pressed", this, "_update_transform_buttons", make_binds(transpose));
|
||||
canvas_item_editor_hb->add_child(transpose);
|
||||
mirror_x = memnew( ToolButton );
|
||||
mirror_x->set_toggle_mode(true);
|
||||
mirror_x->set_tooltip("Mirror X (A)");
|
||||
mirror_x->set_focus_mode(FOCUS_NONE);
|
||||
mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x));
|
||||
canvas_item_editor_hb->add_child(mirror_x);
|
||||
mirror_y = memnew( ToolButton );
|
||||
mirror_y->set_toggle_mode(true);
|
||||
mirror_y->set_tooltip("Mirror Y (S)");
|
||||
mirror_y->set_focus_mode(FOCUS_NONE);
|
||||
mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y));
|
||||
canvas_item_editor_hb->add_child(mirror_y);
|
||||
canvas_item_editor_hb->add_child(memnew(VSeparator));
|
||||
rotate_0 = memnew( ToolButton );
|
||||
rotate_0->set_toggle_mode(true);
|
||||
rotate_0->set_tooltip("Rotate 0 degrees");
|
||||
rotate_0->set_focus_mode(FOCUS_NONE);
|
||||
rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0));
|
||||
canvas_item_editor_hb->add_child(rotate_0);
|
||||
rotate_90 = memnew( ToolButton );
|
||||
rotate_90->set_toggle_mode(true);
|
||||
rotate_90->set_tooltip("Rotate 90 degrees");
|
||||
rotate_90->set_focus_mode(FOCUS_NONE);
|
||||
rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90));
|
||||
canvas_item_editor_hb->add_child(rotate_90);
|
||||
rotate_180 = memnew( ToolButton );
|
||||
rotate_180->set_toggle_mode(true);
|
||||
rotate_180->set_tooltip("Rotate 180 degrees");
|
||||
rotate_180->set_focus_mode(FOCUS_NONE);
|
||||
rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180));
|
||||
canvas_item_editor_hb->add_child(rotate_180);
|
||||
rotate_270 = memnew( ToolButton );
|
||||
rotate_270->set_toggle_mode(true);
|
||||
rotate_270->set_tooltip("Rotate 270 degrees");
|
||||
rotate_270->set_focus_mode(FOCUS_NONE);
|
||||
rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270));
|
||||
canvas_item_editor_hb->add_child(rotate_270);
|
||||
canvas_item_editor_hb->hide();
|
||||
|
||||
|
||||
rotate_0->set_pressed(true);
|
||||
tool=TOOL_NONE;
|
||||
selection_active=false;
|
||||
mouse_over=false;
|
||||
|
|
|
@ -71,8 +71,13 @@ class TileMapEditor : public VBoxContainer {
|
|||
bool mouse_over;
|
||||
|
||||
Label *mirror_label;
|
||||
ToolButton *transpose;
|
||||
ToolButton *mirror_x;
|
||||
ToolButton *mirror_y;
|
||||
ToolButton *rotate_0;
|
||||
ToolButton *rotate_90;
|
||||
ToolButton *rotate_180;
|
||||
ToolButton *rotate_270;
|
||||
|
||||
HBoxContainer *canvas_item_editor_hb;
|
||||
|
||||
|
@ -81,8 +86,8 @@ class TileMapEditor : public VBoxContainer {
|
|||
int idx;
|
||||
bool xf;
|
||||
bool yf;
|
||||
CellOp() { idx=-1; xf=false; yf=false; }
|
||||
CellOp(const CellOp& p_other) : idx(p_other.idx), xf(p_other.xf), yf(p_other.yf) {}
|
||||
bool tr;
|
||||
CellOp() { idx=-1; xf=false; yf=false; tr=false; }
|
||||
};
|
||||
|
||||
Map<Point2i,CellOp> paint_undo;
|
||||
|
@ -94,7 +99,8 @@ class TileMapEditor : public VBoxContainer {
|
|||
void _canvas_draw();
|
||||
void _menu_option(int p_option);
|
||||
|
||||
void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_with_undo=false);
|
||||
void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false);
|
||||
void _set_cell_shortened(const Point2& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false);
|
||||
|
||||
void _canvas_mouse_enter();
|
||||
void _canvas_mouse_exit();
|
||||
|
@ -106,6 +112,7 @@ protected:
|
|||
void _node_removed(Node *p_node);
|
||||
static void _bind_methods();
|
||||
CellOp _get_op_from_cell(const Point2i& p_pos);
|
||||
void _update_transform_buttons(Object *p_button=0);
|
||||
public:
|
||||
|
||||
HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; }
|
||||
|
|
|
@ -1254,7 +1254,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|||
|
||||
tb = memnew( ToolButton );
|
||||
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false));
|
||||
tb->set_tooltip("Instance a Node from scene file.");
|
||||
tb->set_tooltip("Instance a scene file as a Node.");
|
||||
hbc_top->add_child(tb);
|
||||
tool_buttons[TOOL_INSTANCE]=tb;
|
||||
|
||||
|
|
Loading…
Reference in a new issue