2D Rewrite Step [1]

-=-=-=-=-=-=-=-=-=-

-Moved drawing code to a single function that takes linked list (should make it easier to optimize in the future).
-Implemented Z ordering of 2D nodes. Node2D and those that inherit have a visibility/Z property that affects drawing order (besides the tree order)
-Removed OpenGL ES 1.x support. Good riddance!
This commit is contained in:
Juan Linietsky 2015-01-10 17:35:26 -03:00
parent 78f4b93703
commit 8997084831
35 changed files with 653 additions and 7694 deletions

View file

@ -12,7 +12,7 @@
#include "context_gl.h"
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED) || defined(GLES1_ENABLED)
#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)

View file

@ -29,7 +29,7 @@
#ifndef CONTEXT_GL_H
#define CONTEXT_GL_H
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED) || defined(GLES1_ENABLED)
#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
#include "typedefs.h"

View file

@ -1,5 +0,0 @@
Import('env')
Export('env');
env.add_source_files(env.drivers_sources,"*.cpp")

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -8215,6 +8215,217 @@ void RasterizerGLES2::canvas_set_transform(const Matrix32& p_transform) {
//canvas_transform = Variant(p_transform);
}
void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
CanvasItem *current_clip=NULL;
while(p_item_list) {
CanvasItem *ci=p_item_list;
if (ci->vp_render) {
if (draw_viewport_func) {
draw_viewport_func(ci->vp_render->owner,ci->vp_render->udata,ci->vp_render->rect);
}
memdelete(ci->vp_render);
ci->vp_render=NULL;
}
if (current_clip!=ci->final_clip_owner) {
current_clip=ci->final_clip_owner;
//setup clip
if (current_clip) {
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);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
//begin rect
canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform);
canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
bool reclip=false;
if (ci==p_item_list || ci->blend_mode!=canvas_blend_mode) {
switch(ci->blend_mode) {
case VS::MATERIAL_BLEND_MODE_MIX: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
} break;
case VS::MATERIAL_BLEND_MODE_ADD: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} break;
case VS::MATERIAL_BLEND_MODE_SUB: {
glBlendEquation(GL_FUNC_SUBTRACT);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
} break;
case VS::MATERIAL_BLEND_MODE_MUL: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_DST_COLOR,GL_ZERO);
} break;
case VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
} break;
}
canvas_blend_mode=ci->blend_mode;
}
int cc=ci->commands.size();
CanvasItem::Command **commands = ci->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
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);
canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color);
} break;
case CanvasItem::Command::TYPE_PRIMITIVE: {
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: {
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;
}
}
}
} break;
}
}
if (reclip) {
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);
}
p_item_list=p_item_list->next;
}
if (current_clip) {
glDisable(GL_SCISSOR_TEST);
}
}
/* ENVIRONMENT */
RID RasterizerGLES2::environment_create() {

View file

@ -1535,6 +1535,7 @@ public:
virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);
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);
/* ENVIRONMENT */

View file

@ -124,11 +124,11 @@ def configure(env):
# env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ')
if env['x86']=='yes':
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED')
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
elif env["armv6"]!="no":
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED')
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
else:
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED')
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
env.Append(LDPATH=[ld_path])
env.Append(LIBS=['OpenSLES'])

View file

@ -10,5 +10,5 @@ void register_android_global_defaults() {
GLOBAL_DEF("display.Android/driver","GLES2");
// GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
Globals::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
Globals::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2"));
}

View file

@ -821,10 +821,7 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
String vd = Globals::get_singleton()->get("display/driver");
if (vd.to_upper()=="GLES1")
env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean)false);
else
env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean)true);
env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean)true);
__android_log_print(ANDROID_LOG_INFO,"godot","**START");

View file

@ -28,7 +28,7 @@
/*************************************************************************/
#include "os_android.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles1/rasterizer_gles1.h"
#include "core/io/file_access_buffered_fa.h"
#include "drivers/unix/file_access_unix.h"
#include "drivers/unix/dir_access_unix.h"
@ -49,11 +49,11 @@
int OS_Android::get_video_driver_count() const {
return 2;
return 1;
}
const char * OS_Android::get_video_driver_name(int p_driver) const {
return p_driver==0?"GLES2":"GLES1";
return "GLES2";
}
OS::VideoMode OS_Android::get_default_video_mode() const {
@ -123,13 +123,13 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_
AudioDriverManagerSW::add_driver(&audio_driver_android);
if (use_gl2) {
if (true) {
RasterizerGLES2 *rasterizer_gles22=memnew( RasterizerGLES2(false,use_reload_hooks,false,use_reload_hooks ) );
if (gl_extensions)
rasterizer_gles22->set_extensions(gl_extensions);
rasterizer = rasterizer_gles22;
} else {
rasterizer = memnew( RasterizerGLES1(use_reload_hooks, use_reload_hooks) );
//rasterizer = memnew( RasterizerGLES1(use_reload_hooks, use_reload_hooks) );
}

View file

@ -25,8 +25,6 @@ env_ios = env.Clone();
if env['ios_gles22_override'] == "yes":
env_ios.Append(CPPFLAGS=['-DGLES2_OVERRIDE'])
if env['ios_GLES1_override'] == "yes":
env_ios.Append(CPPFLAGS=['-DGLES1_OVERRIDE'])
if env['ios_appirater'] == "yes":
env_ios.Append(CPPFLAGS=['-DAPPIRATER_ENABLED'])

View file

@ -26,7 +26,6 @@ def get_opts():
('game_center', 'Support for game center', 'yes'),
('store_kit', 'Support for in-app store', 'yes'),
('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'),
('ios_GLES1_override', 'Force legacy GLES (1.1) on iOS', 'no'),
('ios_appirater', 'Enable Appirater', 'no'),
('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'),
]
@ -130,7 +129,7 @@ def configure(env):
env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate'
env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES1_ENABLED', '-DMPC_FIXED_POINT'])
env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT'])
if env['ios_exceptions'] == 'yes':
env.Append(CPPFLAGS=['-fexceptions'])
else:

View file

@ -307,11 +307,7 @@ static void clear_touches() {
nil];
// Create our EAGLContext, and if successful make it current and create our framebuffer.
#ifdef GLES1_OVERRIDE
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
#else
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
#endif
if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer])
{

View file

@ -31,7 +31,7 @@
#include "os_iphone.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles1/rasterizer_gles1.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
@ -52,7 +52,7 @@ int OSIPhone::get_video_driver_count() const {
const char * OSIPhone::get_video_driver_name(int p_driver) const {
return "openglES";
return "GLES2";
};
OSIPhone* OSIPhone::get_singleton() {
@ -106,13 +106,9 @@ void OSIPhone::initialize(const VideoMode& p_desired,int p_video_driver,int p_au
supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical", false)?1:0) << PortraitDown);
supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical_flipped", false)?1:0) << PortraitUp);
#ifdef GLES1_OVERRIDE
rasterizer = memnew( RasterizerGLES1 );
#else
rasterizer_gles22 = memnew( RasterizerGLES2(false, false, false) );
rasterizer = rasterizer_gles22;
rasterizer_gles22->set_base_framebuffer(gl_view_base_fb);
#endif
visual_server = memnew( VisualServerRaster(rasterizer) );
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {

View file

@ -28,6 +28,6 @@
/*************************************************************************/
#include <alloca.h>
#define GLES2_INCLUDE_H <ES2/gl.h>
#define GLES1_INCLUDE_H <ES1/gl.h>
#define PLATFORM_REFCOUNT

View file

@ -25,8 +25,6 @@ env_ios = env.Clone();
if env['ios_gles22_override'] == "yes":
env_ios.Append(CPPFLAGS=['-DGLES2_OVERRIDE'])
if env['ios_GLES1_override'] == "yes":
env_ios.Append(CPPFLAGS=['-DGLES1_OVERRIDE'])
if env['ios_appirater'] == "yes":
env_ios.Append(CPPFLAGS=['-DAPPIRATER_ENABLED'])

View file

@ -64,7 +64,7 @@ int OSNacl::get_video_driver_count() const {
};
const char * OSNacl::get_video_driver_name(int p_driver) const {
return "gles2";
return "GLES2";
};
OS::VideoMode OSNacl::get_default_video_mode() const {

View file

@ -113,7 +113,7 @@ def configure(env):
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
env.Append(CCFLAGS=['/DGLES2_ENABLED'])
env.Append(CCFLAGS=['/DGLES1_ENABLED'])
env.Append(CCFLAGS=['/DGLEW_ENABLED'])
LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32']
env.Append(LINKFLAGS=[p+env["LIBSUFFIX"] for p in LIBS])
@ -228,7 +228,7 @@ def configure(env):
env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows'])
env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLEW_ENABLED'])
env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED'])
env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32'])
if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"):

View file

@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles1/rasterizer_gles1.h"
#include "os_windows.h"
#include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
#include "drivers/unix/memory_pool_static_malloc.h"
@ -130,11 +130,11 @@ void RedirectIOToConsole() {
int OS_Windows::get_video_driver_count() const {
return 2;
return 1;
}
const char * OS_Windows::get_video_driver_name(int p_driver) const {
return p_driver==0?"GLES2":"GLES1";
return p_driver=="GLES2";
}
OS::VideoMode OS_Windows::get_default_video_mode() const {

View file

@ -31,5 +31,5 @@
//#include <alloca.h>
//#endif
#define GLES2_INCLUDE_H "gl_context/glew.h"
#define GLES1_INCLUDE_H "gl_context/glew.h"

View file

@ -122,7 +122,7 @@ def configure(env):
else:
print("PulseAudio development libraries not found, disabling driver")
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLES_OVER_GL'])
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL'])
env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD!
#env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])

View file

@ -28,7 +28,6 @@
/*************************************************************************/
#include "servers/visual/visual_server_raster.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles1/rasterizer_gles1.h"
#include "os_x11.h"
#include "key_mapping_x11.h"
#include <stdio.h>
@ -63,11 +62,11 @@
int OS_X11::get_video_driver_count() const {
return 2;
return 1;
}
const char * OS_X11::get_video_driver_name(int p_driver) const {
return p_driver==0?"GLES2":"GLES1";
return "GLES2";
}
OS::VideoMode OS_X11::get_default_video_mode() const {
@ -166,10 +165,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) );
context_gl->initialize();
if (p_video_driver == 0) {
if (true) {
rasterizer = memnew( RasterizerGLES2 );
} else {
rasterizer = memnew( RasterizerGLES1 );
//rasterizer = memnew( RasterizerGLES1 );
};
#endif

View file

@ -34,5 +34,5 @@
#endif
#define GLES2_INCLUDE_H "gl_context/glew.h"
#define GLES1_INCLUDE_H "gl_context/glew.h"

View file

@ -289,6 +289,21 @@ void Node2D::set_global_transform(const Matrix32& p_transform) {
}
void Node2D::set_z(int p_z) {
ERR_FAIL_COND(p_z<-VS::CANVAS_ITEM_Z_DEFAULT);
ERR_FAIL_COND(p_z>=VS::CANVAS_ITEM_Z_DEFAULT);
z=p_z;
VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z+VS::CANVAS_ITEM_Z_DEFAULT);
}
int Node2D::get_z() const{
return z;
}
void Node2D::_bind_methods() {
@ -308,17 +323,21 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move_local_x","delta","scaled"),&Node2D::move_x,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("move_local_y","delta","scaled"),&Node2D::move_y,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_global_pos","pos"),&Node2D::set_global_pos);
ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos);
ObjectTypeDB::bind_method(_MD("set_global_pos"),&Node2D::set_global_pos);
ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform);
ObjectTypeDB::bind_method(_MD("set_global_transform","xform"),&Node2D::set_global_transform);
ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z);
ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z);
ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos"));
ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"visibility/z",PROPERTY_HINT_RANGE,"-512,511,1"),_SCS("set_z"),_SCS("get_z"));
@ -331,6 +350,7 @@ Node2D::Node2D() {
angle=0;
scale=Vector2(1,1);
_xform_dirty=false;
z=0;
}

View file

@ -38,6 +38,7 @@ class Node2D : public CanvasItem {
Point2 pos;
float angle;
Size2 scale;
int z;
Matrix32 _mat;
@ -85,6 +86,9 @@ public:
void set_global_transform(const Matrix32& p_transform);
void set_global_pos(const Point2& p_pos);
void set_z(int p_z);
int get_z() const;
Matrix32 get_transform() const;

View file

@ -28,9 +28,6 @@
/*************************************************************************/
#include "shader_graph.h"
#include "scene/scene_string_names.h"
//todo
//-RGB ops
//-mostrar error de conexion
Array ShaderGraph::_get_node_list(ShaderType p_type) const {

View file

@ -568,8 +568,9 @@ void Rasterizer::_update_fixed_materials() {
}
material_set_param(fm.self,_fixed_material_uv_xform_name,fm.uv_xform);
if (fm.use_pointsize)
if (fm.use_pointsize) {
material_set_param(fm.self,_fixed_material_point_size_name,fm.point_size);
}
}
fixed_material_dirty_list.remove(fixed_material_dirty_list.first());
@ -620,6 +621,8 @@ Rasterizer::Rasterizer() {
_fixed_material_uv_xform_name="fmp_uv_xform";
_fixed_material_point_size_name="fmp_point_size";
draw_viewport_func=NULL;
ERR_FAIL_COND( sizeof(FixedMaterialShaderKey)!=4);
}

View file

@ -40,6 +40,9 @@
class Rasterizer {
protected:
typedef void (*CanvasItemDrawViewportFunc)(VisualServer*owner,void*ud,const Rect2& p_rect);
RID create_default_material();
RID create_overdraw_debug_material();
@ -561,7 +564,275 @@ public:
CANVAS_RECT_FLIP_H=4,
CANVAS_RECT_FLIP_V=8
};
struct CanvasItem {
struct Command {
enum Type {
TYPE_LINE,
TYPE_RECT,
TYPE_STYLE,
TYPE_PRIMITIVE,
TYPE_POLYGON,
TYPE_POLYGON_PTR,
TYPE_CIRCLE,
TYPE_TRANSFORM,
TYPE_BLEND_MODE,
TYPE_CLIP_IGNORE,
};
Type type;
};
struct CommandLine : public Command {
Point2 from,to;
Color color;
float width;
CommandLine() { type = TYPE_LINE; }
};
struct CommandRect : public Command {
Rect2 rect;
RID texture;
Color modulate;
Rect2 source;
uint8_t flags;
CommandRect() { flags=0; type = TYPE_RECT; }
};
struct CommandStyle : public Command {
Rect2 rect;
RID texture;
float margin[4];
float draw_center;
Color color;
CommandStyle() { draw_center=true; type = TYPE_STYLE; }
};
struct CommandPrimitive : public Command {
Vector<Point2> points;
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
float width;
CommandPrimitive() { type = TYPE_PRIMITIVE; width=1;}
};
struct CommandPolygon : public Command {
Vector<int> indices;
Vector<Point2> points;
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
int count;
CommandPolygon() { type = TYPE_POLYGON; count = 0; }
};
struct CommandPolygonPtr : public Command {
const int* indices;
const Point2* points;
const Point2* uvs;
const Color* colors;
RID texture;
int count;
CommandPolygonPtr() { type = TYPE_POLYGON_PTR; count = 0; }
};
struct CommandCircle : public Command {
Point2 pos;
float radius;
Color color;
CommandCircle() { type = TYPE_CIRCLE; }
};
struct CommandTransform : public Command {
Matrix32 xform;
CommandTransform() { type = TYPE_TRANSFORM; }
};
struct CommandBlendMode : public Command {
VS::MaterialBlendMode blend_mode;
CommandBlendMode() { type = TYPE_BLEND_MODE; blend_mode = VS::MATERIAL_BLEND_MODE_MIX; }
};
struct CommandClipIgnore : public Command {
bool ignore;
CommandClipIgnore() { type = TYPE_CLIP_IGNORE; ignore=false; }
};
struct ViewportRender {
VisualServer*owner;
void* udata;
Rect2 rect;
};
Matrix32 xform;
bool clip;
bool visible;
bool ontop;
VS::MaterialBlendMode blend_mode;
Vector<Command*> commands;
mutable bool custom_rect;
mutable bool rect_dirty;
mutable Rect2 rect;
CanvasItem*next;
float final_opacity;
Matrix32 final_transform;
Rect2 final_clip_rect;
CanvasItem* final_clip_owner;
ViewportRender *vp_render;
const Rect2& get_rect() const {
if (custom_rect || !rect_dirty)
return rect;
//must update rect
int s=commands.size();
if (s==0) {
rect=Rect2();
rect_dirty=false;
return rect;
}
Matrix32 xf;
bool found_xform=false;
bool first=true;
const CanvasItem::Command * const *cmd = &commands[0];
for (int i=0;i<s;i++) {
const CanvasItem::Command *c=cmd[i];
Rect2 r;
switch(c->type) {
case CanvasItem::Command::TYPE_LINE: {
const CanvasItem::CommandLine* line = static_cast< const CanvasItem::CommandLine*>(c);
r.pos=line->from;
r.expand_to(line->to);
} break;
case CanvasItem::Command::TYPE_RECT: {
const CanvasItem::CommandRect* crect = static_cast< const CanvasItem::CommandRect*>(c);
r=crect->rect;
} break;
case CanvasItem::Command::TYPE_STYLE: {
const CanvasItem::CommandStyle* style = static_cast< const CanvasItem::CommandStyle*>(c);
r=style->rect;
} break;
case CanvasItem::Command::TYPE_PRIMITIVE: {
const CanvasItem::CommandPrimitive* primitive = static_cast< const CanvasItem::CommandPrimitive*>(c);
r.pos=primitive->points[0];
for(int i=1;i<primitive->points.size();i++) {
r.expand_to(primitive->points[i]);
}
} break;
case CanvasItem::Command::TYPE_POLYGON: {
const CanvasItem::CommandPolygon* polygon = static_cast< const CanvasItem::CommandPolygon*>(c);
int l = polygon->points.size();
const Point2*pp=&polygon->points[0];
r.pos=pp[0];
for(int i=1;i<l;i++) {
r.expand_to(pp[i]);
}
} break;
case CanvasItem::Command::TYPE_POLYGON_PTR: {
const CanvasItem::CommandPolygonPtr* polygon = static_cast< const CanvasItem::CommandPolygonPtr*>(c);
int l = polygon->count;
if (polygon->indices != NULL) {
r.pos=polygon->points[polygon->indices[0]];
for (int i=1; i<polygon->count; i++) {
r.expand_to(polygon->points[polygon->indices[i]]);
};
} else {
r.pos=polygon->points[0];
for (int i=1; i<polygon->count; i++) {
r.expand_to(polygon->points[i]);
};
};
} break;
case CanvasItem::Command::TYPE_CIRCLE: {
const CanvasItem::CommandCircle* circle = static_cast< const CanvasItem::CommandCircle*>(c);
r.pos=Point2(-circle->radius,-circle->radius)+circle->pos;
r.size=Point2(circle->radius*2.0,circle->radius*2.0);
} break;
case CanvasItem::Command::TYPE_TRANSFORM: {
const CanvasItem::CommandTransform* transform = static_cast<const CanvasItem::CommandTransform*>(c);
xf=transform->xform;
found_xform=true;
continue;
} break;
case CanvasItem::Command::TYPE_BLEND_MODE: {
} break;
case CanvasItem::Command::TYPE_CLIP_IGNORE: {
} break;
}
if (found_xform) {
r = xf.xform(r);
found_xform=false;
}
if (first) {
rect=r;
first=false;
} else
rect=rect.merge(r);
}
rect_dirty=false;
return rect;
}
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_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; }
virtual ~CanvasItem() { clear(); }
};
CanvasItemDrawViewportFunc draw_viewport_func;
virtual void canvas_begin()=0;
virtual void canvas_disable_blending()=0;
virtual void canvas_set_opacity(float p_opacity)=0;
@ -575,7 +846,9 @@ public:
virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width)=0;
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;
/* ENVIRONMENT */

View file

@ -1615,6 +1615,11 @@ void RasterizerDummy::canvas_draw_polygon(int p_vertex_count, const int* p_indic
void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) {
}
void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list) {
}
/* ENVIRONMENT */

View file

@ -707,6 +707,7 @@ public:
virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width);
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);
/* ENVIRONMENT */

View file

@ -3352,129 +3352,6 @@ void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip) {
canvas_item->clip=p_clip;
}
const Rect2& VisualServerRaster::CanvasItem::get_rect() const {
if (custom_rect || !rect_dirty)
return rect;
//must update rect
int s=commands.size();
if (s==0) {
rect=Rect2();
rect_dirty=false;
return rect;
}
Matrix32 xf;
bool found_xform=false;
bool first=true;
const CanvasItem::Command * const *cmd = &commands[0];
for (int i=0;i<s;i++) {
const CanvasItem::Command *c=cmd[i];
Rect2 r;
switch(c->type) {
case CanvasItem::Command::TYPE_LINE: {
const CanvasItem::CommandLine* line = static_cast< const CanvasItem::CommandLine*>(c);
r.pos=line->from;
r.expand_to(line->to);
} break;
case CanvasItem::Command::TYPE_RECT: {
const CanvasItem::CommandRect* crect = static_cast< const CanvasItem::CommandRect*>(c);
r=crect->rect;
} break;
case CanvasItem::Command::TYPE_STYLE: {
const CanvasItem::CommandStyle* style = static_cast< const CanvasItem::CommandStyle*>(c);
r=style->rect;
} break;
case CanvasItem::Command::TYPE_PRIMITIVE: {
const CanvasItem::CommandPrimitive* primitive = static_cast< const CanvasItem::CommandPrimitive*>(c);
r.pos=primitive->points[0];
for(int i=1;i<primitive->points.size();i++) {
r.expand_to(primitive->points[i]);
}
} break;
case CanvasItem::Command::TYPE_POLYGON: {
const CanvasItem::CommandPolygon* polygon = static_cast< const CanvasItem::CommandPolygon*>(c);
int l = polygon->points.size();
const Point2*pp=&polygon->points[0];
r.pos=pp[0];
for(int i=1;i<l;i++) {
r.expand_to(pp[i]);
}
} break;
case CanvasItem::Command::TYPE_POLYGON_PTR: {
const CanvasItem::CommandPolygonPtr* polygon = static_cast< const CanvasItem::CommandPolygonPtr*>(c);
int l = polygon->count;
if (polygon->indices != NULL) {
r.pos=polygon->points[polygon->indices[0]];
for (int i=1; i<polygon->count; i++) {
r.expand_to(polygon->points[polygon->indices[i]]);
};
} else {
r.pos=polygon->points[0];
for (int i=1; i<polygon->count; i++) {
r.expand_to(polygon->points[i]);
};
};
} break;
case CanvasItem::Command::TYPE_CIRCLE: {
const CanvasItem::CommandCircle* circle = static_cast< const CanvasItem::CommandCircle*>(c);
r.pos=Point2(-circle->radius,-circle->radius)+circle->pos;
r.size=Point2(circle->radius*2.0,circle->radius*2.0);
} break;
case CanvasItem::Command::TYPE_TRANSFORM: {
const CanvasItem::CommandTransform* transform = static_cast<const CanvasItem::CommandTransform*>(c);
xf=transform->xform;
found_xform=true;
continue;
} break;
case CanvasItem::Command::TYPE_BLEND_MODE: {
} break;
case CanvasItem::Command::TYPE_CLIP_IGNORE: {
} break;
}
if (found_xform) {
r = xf.xform(r);
found_xform=false;
}
if (first) {
rect=r;
first=false;
} else
rect=rect.merge(r);
}
rect_dirty=false;
return rect;
}
void VisualServerRaster::canvas_item_set_transform(RID p_item, const Matrix32& p_transform) {
@ -3812,6 +3689,17 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen
canvas_item->commands.push_back(bm);
};
void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
ERR_FAIL_COND(p_z<0 || p_z>=CANVAS_ITEM_Z_MAX);
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
canvas_item->z=p_z;
}
void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
VS_CHANGED;
@ -6200,7 +6088,38 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
rasterizer->end_scene();
}
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity) {
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) {
Rasterizer::CanvasItem *z_list[CANVAS_ITEM_Z_MAX];
Rasterizer::CanvasItem *z_last_list[CANVAS_ITEM_Z_MAX];
for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) {
z_list[i]=NULL;
z_last_list[i]=NULL;
}
_render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,z_list,z_last_list,NULL);
for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) {
if (!z_list[i])
continue;
rasterizer->canvas_render_items(z_list[i]);
}
}
void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect) {
VisualServerRaster *self=(VisualServerRaster*)(p_self);
Viewport *vp=(Viewport*)p_vp;
self->_draw_viewport(vp,p_rect.pos.x,p_rect.pos.y,p_rect.size.x,p_rect.size.y);
self->rasterizer->canvas_begin();
}
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip) {
CanvasItem *ci = p_canvas_item;
@ -6219,24 +6138,33 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (global_rect.intersects(p_clip_rect) && ci->viewport.is_valid() && viewport_owner.owns(ci->viewport)) {
Viewport *vp = viewport_owner.get(ci->viewport);
Viewport *vp = viewport_owner.get(ci->viewport);
Point2i from = xform.get_origin() + Point2(viewport_rect.x,viewport_rect.y);
Point2i size = rect.size;
size.x *= xform[0].length();
size.y *= xform[1].length();
ci->vp_render = memnew( Rasterizer::CanvasItem::ViewportRender );
ci->vp_render->owner=this;
ci->vp_render->udata=vp;
ci->vp_render->rect=Rect2(from.x,
from.y,
size.x,
size.y);
/*
_draw_viewport(vp,
from.x,
from.y,
size.x,
size.y);
rasterizer->canvas_begin();
*/
//rasterizer->canvas_begin();
} else {
ci->vp_render=NULL;
}
int s = ci->commands.size();
bool reclip=false;
float opacity = ci->opacity * p_opacity;
@ -6246,8 +6174,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*));
if (ci->clip) {
rasterizer->canvas_set_clip(true,global_rect);
canvas_clip=global_rect;
ci->final_clip_rect=global_rect;
ci->final_clip_owner=ci;
} else {
ci->final_clip_owner=p_canvas_clip;
}
if (ci->sort_y) {
@ -6261,155 +6192,33 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (child_items[i]->ontop)
continue;
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner);
}
if (s!=0) {
if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render) {
//something to draw?
ci->final_transform=xform;
ci->final_opacity=opacity * ci->self_opacity;
//Rect2 rect( ci->rect.pos + p_ofs, ci->rect.size);
if (z_last_list[ci->z]) {
z_last_list[ci->z]->next=ci;
z_last_list[ci->z]=ci;
if (p_clip_rect.intersects(global_rect)) {
rasterizer->canvas_begin_rect(xform);
rasterizer->canvas_set_opacity( opacity * ci->self_opacity );
rasterizer->canvas_set_blend_mode( ci->blend_mode );
CanvasItem::Command **commands = &ci->commands[0];
for (int i=0;i<s;i++) {
CanvasItem::Command *c=commands[i];
switch(c->type) {
case CanvasItem::Command::TYPE_LINE: {
CanvasItem::CommandLine* line = static_cast<CanvasItem::CommandLine*>(c);
rasterizer->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);
// rasterizer->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
rasterizer->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);
rasterizer->canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color);
} break;
case CanvasItem::Command::TYPE_PRIMITIVE: {
CanvasItem::CommandPrimitive* primitive = static_cast<CanvasItem::CommandPrimitive*>(c);
rasterizer->canvas_draw_primitive(primitive->points,primitive->colors,primitive->uvs,primitive->texture,primitive->width);
} break;
case CanvasItem::Command::TYPE_POLYGON: {
CanvasItem::CommandPolygon* polygon = static_cast<CanvasItem::CommandPolygon*>(c);
rasterizer->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);
rasterizer->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;
}
rasterizer->canvas_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true);
//rasterizer->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);
rasterizer->canvas_set_transform(transform->xform);
} break;
case CanvasItem::Command::TYPE_BLEND_MODE: {
CanvasItem::CommandBlendMode* bm = static_cast<CanvasItem::CommandBlendMode*>(c);
rasterizer->canvas_set_blend_mode(bm->blend_mode);
} break;
case CanvasItem::Command::TYPE_CLIP_IGNORE: {
CanvasItem::CommandClipIgnore* ci = static_cast<CanvasItem::CommandClipIgnore*>(c);
if (canvas_clip!=Rect2()) {
if (ci->ignore!=reclip) {
if (ci->ignore) {
rasterizer->canvas_set_clip(false,Rect2());
reclip=true;
} else {
rasterizer->canvas_set_clip(true,canvas_clip);
reclip=false;
}
}
}
} break;
}
}
rasterizer->canvas_end_rect();
} else {
z_list[ci->z]=ci;
z_last_list[ci->z]=ci;
}
}
ci->next=NULL;
if (reclip) {
rasterizer->canvas_set_clip(true,canvas_clip);
}
for(int i=0;i<child_item_count;i++) {
if (!child_items[i]->ontop)
continue;
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
}
if (ci->clip) {
rasterizer->canvas_set_clip(false,Rect2());
canvas_clip=Rect2();
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner);
}
}
@ -6423,23 +6232,23 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
for(int i=0;i<l;i++) {
Canvas::ChildItem& ci=p_canvas->child_items[i];
_render_canvas_item(ci.item,p_transform,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height),1);
_render_canvas_item_tree(ci.item,p_transform,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
//mirroring (useful for scrolling backgrounds)
if (ci.mirror.x!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
_render_canvas_item(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height),1);
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
}
if (ci.mirror.y!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
_render_canvas_item(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height),1);
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
}
if (ci.mirror.y!=0 && ci.mirror.x!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
_render_canvas_item(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height),1);
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
}
}
@ -6859,6 +6668,7 @@ RID VisualServerRaster::get_test_cube() {
VisualServerRaster::VisualServerRaster(Rasterizer *p_rasterizer) {
rasterizer=p_rasterizer;
rasterizer->draw_viewport_func=_render_canvas_item_viewport;
instance_update_list=NULL;
render_pass=0;
clear_color=Color(0.3,0.3,0.3,1.0);

View file

@ -372,139 +372,28 @@ class VisualServerRaster : public VisualServer {
struct CanvasItem {
struct Command {
enum Type {
TYPE_LINE,
TYPE_RECT,
TYPE_STYLE,
TYPE_PRIMITIVE,
TYPE_POLYGON,
TYPE_POLYGON_PTR,
TYPE_CIRCLE,
TYPE_TRANSFORM,
TYPE_BLEND_MODE,
TYPE_CLIP_IGNORE,
};
Type type;
};
struct CommandLine : public Command {
Point2 from,to;
Color color;
float width;
CommandLine() { type = TYPE_LINE; }
};
struct CommandRect : public Command {
Rect2 rect;
RID texture;
Color modulate;
Rect2 source;
uint8_t flags;
CommandRect() { flags=0; type = TYPE_RECT; }
};
struct CommandStyle : public Command {
Rect2 rect;
RID texture;
float margin[4];
float draw_center;
Color color;
CommandStyle() { draw_center=true; type = TYPE_STYLE; }
};
struct CommandPrimitive : public Command {
Vector<Point2> points;
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
float width;
CommandPrimitive() { type = TYPE_PRIMITIVE; width=1;}
};
struct CanvasItem : public Rasterizer::CanvasItem {
struct CommandPolygon : public Command {
Vector<int> indices;
Vector<Point2> points;
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
int count;
CommandPolygon() { type = TYPE_POLYGON; count = 0; }
};
struct CommandPolygonPtr : public Command {
const int* indices;
const Point2* points;
const Point2* uvs;
const Color* colors;
RID texture;
int count;
CommandPolygonPtr() { type = TYPE_POLYGON_PTR; count = 0; }
};
struct CommandCircle : public Command {
Point2 pos;
float radius;
Color color;
CommandCircle() { type = TYPE_CIRCLE; }
};
struct CommandTransform : public Command {
Matrix32 xform;
CommandTransform() { type = TYPE_TRANSFORM; }
};
struct CommandBlendMode : public Command {
MaterialBlendMode blend_mode;
CommandBlendMode() { type = TYPE_BLEND_MODE; blend_mode = MATERIAL_BLEND_MODE_MIX; };
};
struct CommandClipIgnore : public Command {
bool ignore;
CommandClipIgnore() { type = TYPE_CLIP_IGNORE; ignore=false; };
};
RID parent; // canvas it belongs to
List<CanvasItem*>::Element *E;
Matrix32 xform;
bool clip;
bool visible;
bool ontop;
RID viewport;
int z;
bool sort_y;
float opacity;
float self_opacity;
MaterialBlendMode blend_mode;
RID viewport;
mutable bool custom_rect;
mutable bool rect_dirty;
mutable Rect2 rect;
Vector<Command*> commands;
Vector<CanvasItem*> child_items;
const Rect2& get_rect() const;
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true;};
CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; sort_y=false;}
~CanvasItem() { clear(); }
CanvasItem() {
E=NULL;
z=CANVAS_ITEM_Z_MAX/2;
opacity=1;
self_opacity=1;
sort_y=false;
}
};
@ -706,7 +595,9 @@ class VisualServerRaster : public VisualServer {
void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace);
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity);
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(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip);
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
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);
@ -1217,6 +1108,8 @@ public:
virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend);
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
virtual void canvas_item_set_z(RID p_item, int p_z);
virtual void canvas_item_clear(RID p_item);
virtual void canvas_item_raise(RID p_item);

View file

@ -1131,6 +1131,8 @@ public:
FUNC2(canvas_item_add_clip_ignore,RID, bool );
FUNC2(canvas_item_set_sort_children_by_y,RID,bool);
FUNC2(canvas_item_set_z,RID,int);
FUNC1(canvas_item_clear,RID);
FUNC1(canvas_item_raise,RID);

View file

@ -86,6 +86,8 @@ public:
ARRAY_WEIGHTS_SIZE=4,
MAX_PARTICLE_COLOR_PHASES=4,
MAX_PARTICLE_ATTRACTORS=4,
CANVAS_ITEM_Z_MAX=1024,
CANVAS_ITEM_Z_DEFAULT=512,
MAX_CURSORS = 8,
@ -982,6 +984,7 @@ public:
virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend)=0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0;
virtual void canvas_item_set_z(RID p_item, int p_z)=0;
virtual void canvas_item_clear(RID p_item)=0;
virtual void canvas_item_raise(RID p_item)=0;