summaryrefslogtreecommitdiff
path: root/servers/visual
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2016-10-03 16:33:42 -0300
committerJuan Linietsky <reduzio@gmail.com>2016-10-03 21:35:16 +0200
commit22d83bc9f655d5ae7a1b49709c4c1b663725daf5 (patch)
treea817195c08d4713a70ca014a3f63f5937934fe36 /servers/visual
parent78d97b060a6873a454e710380cb9ef1bde5e4c65 (diff)
Begining of GLES3 renderer:
-Most 2D drawing is implemented -Missing shaders -Missing all 3D -Editor needs to be set on update always to be used, otherwise it does not refresh -Large parts of editor not working
Diffstat (limited to 'servers/visual')
-rw-r--r--servers/visual/particle_system_sw.cpp412
-rw-r--r--servers/visual/particle_system_sw.h131
-rw-r--r--servers/visual/rasterizer.cpp19
-rw-r--r--servers/visual/rasterizer.h760
-rw-r--r--servers/visual/rasterizer_dummy.cpp1961
-rw-r--r--servers/visual/rasterizer_dummy.h791
-rw-r--r--servers/visual/shader_language.cpp3910
-rw-r--r--servers/visual/shader_language.h375
-rw-r--r--servers/visual/visual_server_canvas.cpp1268
-rw-r--r--servers/visual/visual_server_canvas.h214
-rw-r--r--servers/visual/visual_server_global.cpp10
-rw-r--r--servers/visual/visual_server_global.h26
-rw-r--r--servers/visual/visual_server_raster.cpp1329
-rw-r--r--servers/visual/visual_server_raster.h592
-rw-r--r--servers/visual/visual_server_viewport.cpp489
-rw-r--r--servers/visual/visual_server_viewport.h118
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp212
-rw-r--r--servers/visual/visual_server_wrap_mt.h739
18 files changed, 6719 insertions, 6637 deletions
diff --git a/servers/visual/particle_system_sw.cpp b/servers/visual/particle_system_sw.cpp
deleted file mode 100644
index 07cc6d8a2a..0000000000
--- a/servers/visual/particle_system_sw.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/*************************************************************************/
-/* particle_system_sw.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "particle_system_sw.h"
-#include "sort.h"
-
-
-ParticleSystemSW::ParticleSystemSW() {
-
- amount=8;
- emitting=true;
-
- for (int i=0;i<VS::PARTICLE_VAR_MAX;i++) {
- particle_randomness[i]=0.0;
- }
-
- particle_vars[VS::PARTICLE_LIFETIME]=2.0;//
- particle_vars[VS::PARTICLE_SPREAD]=0.2;//
- particle_vars[VS::PARTICLE_GRAVITY]=9.8;//
- particle_vars[VS::PARTICLE_LINEAR_VELOCITY]=0.2;//
- particle_vars[VS::PARTICLE_ANGULAR_VELOCITY]=0.0;//
- particle_vars[VS::PARTICLE_LINEAR_ACCELERATION]=0.0;//
- particle_vars[VS::PARTICLE_RADIAL_ACCELERATION]=0.0;//
- particle_vars[VS::PARTICLE_TANGENTIAL_ACCELERATION]=1.0;//
- particle_vars[VS::PARTICLE_DAMPING]=0.0;//
- particle_vars[VS::PARTICLE_INITIAL_SIZE]=1.0;
- particle_vars[VS::PARTICLE_FINAL_SIZE]=0.8;
- particle_vars[VS::PARTICLE_HEIGHT]=1;
- particle_vars[VS::PARTICLE_HEIGHT_SPEED_SCALE]=1;
-
- height_from_velocity=false;
- local_coordinates=false;
-
- particle_vars[VS::PARTICLE_INITIAL_ANGLE]=0.0;//
-
- gravity_normal=Vector3(0,-1.0,0);
- //emission_half_extents=Vector3(0.1,0.1,0.1);
- emission_half_extents=Vector3(1,1,1);
- color_phase_count=0;
- color_phases[0].pos=0.0;
- color_phases[0].color=Color(1.0,0.0,0.0);
- visibility_aabb=AABB(Vector3(-64,-64,-64),Vector3(128,128,128));
-
- attractor_count=0;
-
-}
-
-
-ParticleSystemSW::~ParticleSystemSW()
-{
-}
-
-
-#define DEFAULT_SEED 1234567
-
-_FORCE_INLINE_ static float _rand_from_seed(uint32_t *seed) {
-
- uint32_t k;
- uint32_t s = (*seed);
- if (s == 0)
- s = 0x12345987;
- k = s / 127773;
- s = 16807 * (s - k * 127773) - 2836 * k;
- if (s < 0)
- s += 2147483647;
- (*seed) = s;
-
- float v=((float)((*seed) & 0xFFFFF))/(float)0xFFFFF;
- v=v*2.0-1.0;
- return v;
-}
-
-_FORCE_INLINE_ static uint32_t _irand_from_seed(uint32_t *seed) {
-
- uint32_t k;
- uint32_t s = (*seed);
- if (s == 0)
- s = 0x12345987;
- k = s / 127773;
- s = 16807 * (s - k * 127773) - 2836 * k;
- if (s < 0)
- s += 2147483647;
- (*seed) = s;
-
- return s;
-}
-
-void ParticleSystemProcessSW::process(const ParticleSystemSW *p_system,const Transform& p_transform,float p_time) {
-
- valid=false;
- if (p_system->amount<=0) {
- ERR_EXPLAIN("Invalid amount of particles: "+itos(p_system->amount));
- ERR_FAIL_COND(p_system->amount<=0);
- }
- if (p_system->attractor_count<0 || p_system->attractor_count>VS::MAX_PARTICLE_ATTRACTORS) {
- ERR_EXPLAIN("Invalid amount of particle attractors.");
- ERR_FAIL_COND(p_system->attractor_count<0 || p_system->attractor_count>VS::MAX_PARTICLE_ATTRACTORS);
- }
- float lifetime = p_system->particle_vars[VS::PARTICLE_LIFETIME];
- if (lifetime<CMP_EPSILON) {
- ERR_EXPLAIN("Particle system lifetime too small.");
- ERR_FAIL_COND(lifetime<CMP_EPSILON);
- }
- valid=true;
- int particle_count=MIN(p_system->amount,ParticleSystemSW::MAX_PARTICLES);;
-
-
- int emission_point_count = p_system->emission_points.size();
- DVector<Vector3>::Read r;
- if (emission_point_count)
- r=p_system->emission_points.read();
-
- if (particle_count!=particle_data.size()) {
-
- //clear the whole system if particle amount changed
- particle_data.clear();
- particle_data.resize(p_system->amount);
- particle_system_time=0;
- }
-
- float next_time = particle_system_time+p_time;
-
- if (next_time > lifetime)
- next_time=Math::fmod(next_time,lifetime);
-
-
- ParticleData *pdata=&particle_data[0];
- Vector3 attractor_positions[VS::MAX_PARTICLE_ATTRACTORS];
-
- for(int i=0;i<p_system->attractor_count;i++) {
-
- attractor_positions[i]=p_transform.xform(p_system->attractors[i].pos);
- }
-
-
- for(int i=0;i<particle_count;i++) {
-
- ParticleData &p=pdata[i];
-
- float restart_time = (i * lifetime / p_system->amount);
-
- bool restart=false;
-
- if ( next_time < particle_system_time ) {
-
- if (restart_time > particle_system_time || restart_time < next_time )
- restart=true;
-
- } else if (restart_time > particle_system_time && restart_time < next_time ) {
- restart=true;
- }
-
- if (restart) {
-
-
- if (p_system->emitting) {
- if (emission_point_count==0) { //use AABB
- if (p_system->local_coordinates)
- p.pos = p_system->emission_half_extents * Vector3( _rand_from_seed(&rand_seed), _rand_from_seed(&rand_seed), _rand_from_seed(&rand_seed) );
- else
- p.pos = p_transform.xform( p_system->emission_half_extents * Vector3( _rand_from_seed(&rand_seed), _rand_from_seed(&rand_seed), _rand_from_seed(&rand_seed) ) );
- } else {
- //use preset positions
- if (p_system->local_coordinates)
- p.pos = r[_irand_from_seed(&rand_seed)%emission_point_count];
- else
- p.pos = p_transform.xform( r[_irand_from_seed(&rand_seed)%emission_point_count] );
- }
-
-
- float angle1 = _rand_from_seed(&rand_seed)*p_system->particle_vars[VS::PARTICLE_SPREAD]*Math_PI;
- float angle2 = _rand_from_seed(&rand_seed)*20.0*Math_PI; // make it more random like
-
- Vector3 rot_xz=Vector3( Math::sin(angle1), 0.0, Math::cos(angle1) );
- Vector3 rot = Vector3( Math::cos(angle2)*rot_xz.x,Math::sin(angle2)*rot_xz.x, rot_xz.z);
-
- p.vel=(rot*p_system->particle_vars[VS::PARTICLE_LINEAR_VELOCITY]+rot*p_system->particle_randomness[VS::PARTICLE_LINEAR_VELOCITY]*_rand_from_seed(&rand_seed));
- if (!p_system->local_coordinates)
- p.vel=p_transform.basis.xform( p.vel );
-
- p.vel+=p_system->emission_base_velocity;
-
- p.rot=p_system->particle_vars[VS::PARTICLE_INITIAL_ANGLE]+p_system->particle_randomness[VS::PARTICLE_INITIAL_ANGLE]*_rand_from_seed(&rand_seed);
- p.active=true;
- for(int r=0;r<PARTICLE_RANDOM_NUMBERS;r++)
- p.random[r]=_rand_from_seed(&rand_seed);
-
- } else {
-
- p.pos=Vector3();
- p.rot=0;
- p.vel=Vector3();
- p.active=false;
- }
-
- } else {
-
- if (!p.active)
- continue;
-
- Vector3 force;
- //apply gravity
- force=p_system->gravity_normal * (p_system->particle_vars[VS::PARTICLE_GRAVITY]+(p_system->particle_randomness[VS::PARTICLE_GRAVITY]*p.random[0]));
- //apply linear acceleration
- force+=p.vel.normalized() * (p_system->particle_vars[VS::PARTICLE_LINEAR_ACCELERATION]+p_system->particle_randomness[VS::PARTICLE_LINEAR_ACCELERATION]*p.random[1]);
- //apply radial acceleration
- Vector3 org;
- if (!p_system->local_coordinates)
- org=p_transform.origin;
- force+=(p.pos-org).normalized() * (p_system->particle_vars[VS::PARTICLE_RADIAL_ACCELERATION]+p_system->particle_randomness[VS::PARTICLE_RADIAL_ACCELERATION]*p.random[2]);
- //apply tangential acceleration
- force+=(p.pos-org).cross(p_system->gravity_normal).normalized() * (p_system->particle_vars[VS::PARTICLE_TANGENTIAL_ACCELERATION]+p_system->particle_randomness[VS::PARTICLE_TANGENTIAL_ACCELERATION]*p.random[3]);
- //apply attractor forces
- for(int a=0;a<p_system->attractor_count;a++) {
-
- force+=(p.pos-attractor_positions[a]).normalized() * p_system->attractors[a].force;
- }
-
-
- p.vel+=force * p_time;
- if (p_system->particle_vars[VS::PARTICLE_DAMPING]) {
-
- float v = p.vel.length();
- float damp = p_system->particle_vars[VS::PARTICLE_DAMPING] + p_system->particle_vars[VS::PARTICLE_DAMPING] * p_system->particle_randomness[VS::PARTICLE_DAMPING];
- v -= damp * p_time;
- if (v<0) {
- p.vel=Vector3();
- } else {
- p.vel=p.vel.normalized() * v;
- }
-
- }
- p.rot+=(p_system->particle_vars[VS::PARTICLE_ANGULAR_VELOCITY]+p_system->particle_randomness[VS::PARTICLE_ANGULAR_VELOCITY]*p.random[4]) *p_time;
- p.pos+=p.vel * p_time;
- }
- }
-
- particle_system_time=Math::fmod( particle_system_time+p_time, lifetime );
-
-
-}
-
-ParticleSystemProcessSW::ParticleSystemProcessSW() {
-
- particle_system_time=0;
- rand_seed=1234567;
- valid=false;
-}
-
-
-struct _ParticleSorterSW {
-
-
- _FORCE_INLINE_ bool operator()(const ParticleSystemDrawInfoSW::ParticleDrawInfo *p_a,const ParticleSystemDrawInfoSW::ParticleDrawInfo *p_b) const {
-
- return p_a->d > p_b->d; // draw from further away to closest
- }
-};
-
-void ParticleSystemDrawInfoSW::prepare(const ParticleSystemSW *p_system,const ParticleSystemProcessSW *p_process,const Transform& p_system_transform,const Transform& p_camera_transform) {
-
- ERR_FAIL_COND(p_process->particle_data.size() != p_system->amount);
- ERR_FAIL_COND(p_system->amount<=0 || p_system->amount>=ParticleSystemSW::MAX_PARTICLES);
-
- const ParticleSystemProcessSW::ParticleData *pdata=&p_process->particle_data[0];
- float time_pos=p_process->particle_system_time/p_system->particle_vars[VS::PARTICLE_LIFETIME];
-
- ParticleSystemSW::ColorPhase cphase[VS::MAX_PARTICLE_COLOR_PHASES];
-
- float last=-1;
- int col_count=0;
-
- for(int i=0;i<p_system->color_phase_count;i++) {
-
- if (p_system->color_phases[i].pos<=last)
- break;
- cphase[i]=p_system->color_phases[i];
- col_count++;
- }
-
-
-
-
-
- Vector3 camera_z_axis = p_camera_transform.basis.get_axis(2);
-
- for(int i=0;i<p_system->amount;i++) {
-
- ParticleDrawInfo &pdi=draw_info[i];
- pdi.data=&pdata[i];
- pdi.transform.origin=pdi.data->pos;
- if (p_system->local_coordinates)
- pdi.transform.origin=p_system_transform.xform(pdi.transform.origin);
-
- pdi.d=-camera_z_axis.dot(pdi.transform.origin);
-
- // adjust particle size, color and rotation
-
- float time = ((float)i / p_system->amount);
- if (time<time_pos)
- time=time_pos-time;
- else
- time=(1.0-time)+time_pos;
-
- Vector3 up=p_camera_transform.basis.get_axis(1); // up determines the rotation
- float up_scale=1.0;
-
- if (p_system->height_from_velocity) {
-
- Vector3 veld = pdi.data->vel;
- Vector3 cam_z = camera_z_axis.normalized();
- float vc = Math::abs(veld.normalized().dot(cam_z));
-
- if (vc<(1.0-CMP_EPSILON)) {
- up = Plane(cam_z,0).project(veld).normalized();
- float h = p_system->particle_vars[VS::PARTICLE_HEIGHT]+p_system->particle_randomness[VS::PARTICLE_HEIGHT]*pdi.data->random[7];
- float velh = veld.length();
- h+=velh*(p_system->particle_vars[VS::PARTICLE_HEIGHT_SPEED_SCALE]+p_system->particle_randomness[VS::PARTICLE_HEIGHT_SPEED_SCALE]*pdi.data->random[7]);
-
-
- up_scale=Math::lerp(1.0,h,(1.0-vc));
- }
-
- } else if (pdi.data->rot) {
-
- up.rotate(camera_z_axis,pdi.data->rot);
- }
-
- {
- // matrix
- Vector3 v_z = (p_camera_transform.origin-pdi.transform.origin).normalized();
-// Vector3 v_z = (p_camera_transform.origin-pdi.data->pos).normalized();
- Vector3 v_y = up;
- Vector3 v_x = v_y.cross(v_z);
- v_y = v_z.cross(v_x);
- v_x.normalize();
- v_y.normalize();
-
-
- float initial_scale, final_scale;
- initial_scale = p_system->particle_vars[VS::PARTICLE_INITIAL_SIZE]+p_system->particle_randomness[VS::PARTICLE_INITIAL_SIZE]*pdi.data->random[5];
- final_scale = p_system->particle_vars[VS::PARTICLE_FINAL_SIZE]+p_system->particle_randomness[VS::PARTICLE_FINAL_SIZE]*pdi.data->random[6];
- float scale = initial_scale + time * (final_scale - initial_scale);
-
- pdi.transform.basis.set_axis(0,v_x * scale);
- pdi.transform.basis.set_axis(1,v_y * scale * up_scale);
- pdi.transform.basis.set_axis(2,v_z * scale);
- }
-
-
-
- int cpos=0;
-
- while(cpos<col_count) {
-
- if (cphase[cpos].pos > time)
- break;
- cpos++;
- }
-
- cpos--;
-
-
- if (cpos==-1)
- pdi.color=Color(1,1,1,1);
- else {
- if (cpos==col_count-1)
- pdi.color=cphase[cpos].color;
- else {
- float diff = (cphase[cpos+1].pos-cphase[cpos].pos);
- if (diff>0)
- pdi.color=cphase[cpos].color.linear_interpolate(cphase[cpos+1].color, (time - cphase[cpos].pos) / diff );
- else
- pdi.color=cphase[cpos+1].color;
- }
- }
-
-
- draw_info_order[i]=&pdi;
-
- }
-
-
- SortArray<ParticleDrawInfo*,_ParticleSorterSW> particle_sort;
- particle_sort.sort(&draw_info_order[0],p_system->amount);
-
-}
diff --git a/servers/visual/particle_system_sw.h b/servers/visual/particle_system_sw.h
deleted file mode 100644
index 4edcecaaa9..0000000000
--- a/servers/visual/particle_system_sw.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*************************************************************************/
-/* particle_system_sw.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifndef PARTICLE_SYSTEM_SW_H
-#define PARTICLE_SYSTEM_SW_H
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-#include "servers/visual_server.h"
-
-struct ParticleSystemSW {
- enum {
-
- MAX_PARTICLES=1024
- };
-
- float particle_vars[VS::PARTICLE_VAR_MAX];
- float particle_randomness[VS::PARTICLE_VAR_MAX];
-
- Vector3 emission_half_extents;
- DVector<Vector3> emission_points;
- Vector3 gravity_normal;
- Vector3 emission_base_velocity;
- int amount;
- bool emitting;
- bool height_from_velocity;
- AABB visibility_aabb;
- bool sort;
- bool local_coordinates;
-
- struct ColorPhase {
-
- float pos;
- Color color;
- ColorPhase() { pos=1.0; color=Color(0.0,0.0,1.0,1.0); }
- };
-
- int color_phase_count;
- ColorPhase color_phases[VS::MAX_PARTICLE_COLOR_PHASES];
-
-
- struct Attractor {
-
- Vector3 pos;
- float force;
- };
-
- int attractor_count;
- Attractor attractors[VS::MAX_PARTICLE_ATTRACTORS];
-
-
- ParticleSystemSW();
- ~ParticleSystemSW();
-
-};
-
-
-struct ParticleSystemProcessSW {
-
- enum {
- PARTICLE_RANDOM_NUMBERS = 8,
- };
-
- struct ParticleData {
-
- Vector3 pos;
- Vector3 vel;
- float rot;
- bool active;
- float random[PARTICLE_RANDOM_NUMBERS];
-
- ParticleData() { active=0; rot=0; }
- };
-
-
- bool valid;
- float particle_system_time;
- uint32_t rand_seed;
- Vector<ParticleData> particle_data;
-
- void process(const ParticleSystemSW *p_system,const Transform& p_transform,float p_time);
-
- ParticleSystemProcessSW();
-};
-
-struct ParticleSystemDrawInfoSW {
-
- struct ParticleDrawInfo {
-
- const ParticleSystemProcessSW::ParticleData *data;
- float d;
- Transform transform;
- Color color;
-
- };
-
- ParticleDrawInfo draw_info[ParticleSystemSW::MAX_PARTICLES];
- ParticleDrawInfo *draw_info_order[ParticleSystemSW::MAX_PARTICLES];
-
- void prepare(const ParticleSystemSW *p_system,const ParticleSystemProcessSW *p_process,const Transform& p_system_transform,const Transform& p_camera_transform);
-
-};
-
-#endif
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index a4b91e17fe..2952098a3c 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -30,6 +30,23 @@
#include "print_string.h"
#include "os/os.h"
+
+Rasterizer* (*Rasterizer::_create_func)()=NULL;
+
+Rasterizer *Rasterizer::create() {
+
+ return _create_func();
+}
+
+RasterizerStorage*RasterizerStorage::base_signleton=NULL;
+
+RasterizerStorage::RasterizerStorage() {
+
+ base_signleton=this;
+}
+
+#if 0
+
RID Rasterizer::create_default_material() {
return material_create();
@@ -636,3 +653,5 @@ RID Rasterizer::create_overdraw_debug_material() {
return mat;
}
+
+#endif
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 8cc567072f..df18dd1679 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -29,6 +29,670 @@
#ifndef RASTERIZER_H
#define RASTERIZER_H
+
+#include "servers/visual_server.h"
+#include "camera_matrix.h"
+
+
+
+class RasterizerStorage {
+public:
+ /* TEXTURE API */
+
+ virtual RID texture_create()=0;
+ virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=VS::TEXTURE_FLAGS_DEFAULT)=0;
+ virtual void texture_set_data(RID p_texture,const Image& p_image,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT)=0;
+ virtual Image texture_get_data(RID p_texture,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT) const=0;
+ virtual void texture_set_flags(RID p_texture,uint32_t p_flags)=0;
+ virtual uint32_t texture_get_flags(RID p_texture) const=0;
+ virtual Image::Format texture_get_format(RID p_texture) const=0;
+ virtual uint32_t texture_get_width(RID p_texture) const=0;
+ virtual uint32_t texture_get_height(RID p_texture) const=0;
+ virtual void texture_set_size_override(RID p_texture,int p_width, int p_height)=0;
+
+ virtual void texture_set_path(RID p_texture,const String& p_path)=0;
+ virtual String texture_get_path(RID p_texture) const=0;
+
+ virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0;
+
+ virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0;
+
+
+ /* SHADER API */
+
+
+ virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_SPATIAL)=0;
+
+ virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode)=0;
+ virtual VS::ShaderMode shader_get_mode(RID p_shader) const=0;
+
+ virtual void shader_set_code(RID p_shader, const String& p_code)=0;
+ virtual String shader_get_code(RID p_shader) const=0;
+ virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const=0;
+
+ virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
+ virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
+
+
+ /* COMMON MATERIAL API */
+
+ virtual RID material_create()=0;
+
+ virtual void material_set_shader(RID p_shader_material, RID p_shader)=0;
+ virtual RID material_get_shader(RID p_shader_material) const=0;
+
+ virtual void material_set_param(RID p_material, const StringName& p_param, const Variant& p_value)=0;
+ virtual Variant material_get_param(RID p_material, const StringName& p_param) const=0;
+
+ /* MESH API */
+
+ virtual RID mesh_create()=0;
+
+ virtual void mesh_add_surface(RID p_mesh,uint32_t p_format,VS::PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const Vector<DVector<uint8_t> >& p_blend_shapes=Vector<DVector<uint8_t> >())=0;
+
+ virtual void mesh_set_morph_target_count(RID p_mesh,int p_amount)=0;
+ virtual int mesh_get_morph_target_count(RID p_mesh) const=0;
+
+
+ virtual void mesh_set_morph_target_mode(RID p_mesh,VS::MorphTargetMode p_mode)=0;
+ virtual VS::MorphTargetMode mesh_get_morph_target_mode(RID p_mesh) const=0;
+
+ virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material)=0;
+ virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const=0;
+
+ virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const=0;
+ virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const=0;
+
+ virtual DVector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const=0;
+ virtual DVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const=0;
+
+
+ virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const=0;
+ virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const=0;
+
+ virtual void mesh_remove_surface(RID p_mesh,int p_index)=0;
+ virtual int mesh_get_surface_count(RID p_mesh) const=0;
+
+ virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb)=0;
+ virtual AABB mesh_get_custom_aabb(RID p_mesh) const=0;
+
+ virtual AABB mesh_get_aabb(RID p_mesh) const=0;
+ virtual void mesh_clear(RID p_mesh)=0;
+
+ /* MULTIMESH API */
+
+
+ virtual RID multimesh_create()=0;
+
+ virtual void multimesh_allocate(RID p_multimesh,int p_instances,VS::MultimeshTransformFormat p_transform_format,VS::MultimeshColorFormat p_color_format,bool p_gen_aabb=true)=0;
+ virtual int multimesh_get_instance_count(RID p_multimesh) const=0;
+
+ virtual void multimesh_set_mesh(RID p_multimesh,RID p_mesh)=0;
+ virtual void multimesh_set_custom_aabb(RID p_multimesh,const AABB& p_aabb)=0;
+ virtual void multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform& p_transform)=0;
+ virtual void multimesh_instance_set_transform_2d(RID p_multimesh,int p_index,const Matrix32& p_transform)=0;
+ virtual void multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color)=0;
+
+ virtual RID multimesh_get_mesh(RID p_multimesh) const=0;
+ virtual AABB multimesh_get_custom_aabb(RID p_multimesh,const AABB& p_aabb) const=0;
+
+ virtual Transform multimesh_instance_get_transform(RID p_multimesh,int p_index) const=0;
+ virtual Matrix32 multimesh_instance_get_transform_2d(RID p_multimesh,int p_index) const=0;
+ virtual Color multimesh_instance_get_color(RID p_multimesh,int p_index) const=0;
+
+ virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible)=0;
+ virtual int multimesh_get_visible_instances(RID p_multimesh) const=0;
+
+ virtual AABB multimesh_get_aabb(RID p_mesh) const=0;
+
+ /* IMMEDIATE API */
+
+ virtual RID immediate_create()=0;
+ virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID())=0;
+ virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex)=0;
+ virtual void immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex)=0;
+ virtual void immediate_normal(RID p_immediate,const Vector3& p_normal)=0;
+ virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent)=0;
+ virtual void immediate_color(RID p_immediate,const Color& p_color)=0;
+ virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv)=0;
+ virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv)=0;
+ virtual void immediate_end(RID p_immediate)=0;
+ virtual void immediate_clear(RID p_immediate)=0;
+ virtual void immediate_set_material(RID p_immediate,RID p_material)=0;
+ virtual RID immediate_get_material(RID p_immediate) const=0;
+
+ /* SKELETON API */
+
+ virtual RID skeleton_create()=0;
+ virtual void skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton=false)=0;
+ virtual int skeleton_get_bone_count(RID p_skeleton) const=0;
+ virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform)=0;
+ virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone)=0;
+ virtual void skeleton_bone_set_transform_2d(RID p_skeleton,int p_bone, const Matrix32& p_transform)=0;
+ virtual Matrix32 skeleton_bone_get_transform_2d(RID p_skeleton,int p_bone)=0;
+
+ /* Light API */
+
+ virtual RID light_create(VS::LightType p_type)=0;
+
+ virtual void light_set_color(RID p_light,const Color& p_color)=0;
+ virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value)=0;
+ virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
+ virtual void light_set_projector(RID p_light,RID p_texture)=0;
+ virtual void light_set_attenuation_texure(RID p_light,RID p_texture)=0;
+ virtual void light_set_negative(RID p_light,bool p_enable)=0;
+ virtual void light_set_cull_mask(RID p_light,uint32_t p_mask)=0;
+ virtual void light_set_shader(RID p_light,RID p_shader)=0;
+
+
+ virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode)=0;
+
+ /* PROBE API */
+
+ virtual RID reflection_probe_create()=0;
+
+ virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity)=0;
+ virtual void reflection_probe_set_clip(RID p_probe, float p_near, float p_far)=0;
+ virtual void reflection_probe_set_min_blend_distance(RID p_probe, float p_distance)=0;
+ virtual void reflection_probe_set_extents(RID p_probe, const Vector3& p_extents)=0;
+ virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3& p_offset)=0;
+ virtual void reflection_probe_set_enable_parallax_correction(RID p_probe, bool p_enable)=0;
+ virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution)=0;
+ virtual void reflection_probe_set_hide_skybox(RID p_probe, bool p_hide)=0;
+ virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers)=0;
+
+
+ /* ROOM API */
+
+ virtual RID room_create()=0;
+ virtual void room_add_bounds(RID p_room, const DVector<Vector2>& p_convex_polygon,float p_height,const Transform& p_transform)=0;
+ virtual void room_clear_bounds()=0;
+
+ /* PORTAL API */
+
+ // portals are only (x/y) points, forming a convex shape, which its clockwise
+ // order points outside. (z is 0)=0;
+
+ virtual RID portal_create()=0;
+ virtual void portal_set_shape(RID p_portal, const Vector<Point2>& p_shape)=0;
+ virtual void portal_set_enabled(RID p_portal, bool p_enabled)=0;
+ virtual void portal_set_disable_distance(RID p_portal, float p_distance)=0;
+ virtual void portal_set_disabled_color(RID p_portal, const Color& p_color)=0;
+
+
+ /* RENDER TARGET */
+
+ enum RenderTargetFlags {
+ RENDER_TARGET_VFLIP,
+ RENDER_TARGET_TRANSPARENT,
+ RENDER_TARGET_NO_3D,
+ RENDER_TARGET_NO_SAMPLING,
+ RENDER_TARGET_FLAG_MAX
+ };
+
+ virtual RID render_target_create()=0;
+ virtual void render_target_set_size(RID p_render_target,int p_width, int p_height)=0;
+ virtual RID render_target_get_texture(RID p_render_target) const=0;
+ virtual Image render_target_get_image(RID p_render_target) const=0;
+ virtual void render_target_set_flag(RID p_render_target,RenderTargetFlags p_flag,bool p_value)=0;
+ virtual bool render_target_renedered_in_frame(RID p_render_target)=0;
+
+
+ /* CANVAS SHADOW */
+
+ virtual RID canvas_light_shadow_buffer_create(int p_width)=0;
+
+ /* LIGHT SHADOW MAPPING */
+
+ virtual RID canvas_light_occluder_create()=0;
+ virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines)=0;
+
+ virtual bool free(RID p_rid)=0;
+
+
+ static RasterizerStorage*base_signleton;
+ RasterizerStorage();
+ virtual ~RasterizerStorage() {}
+};
+
+
+
+
+class RasterizerCanvas {
+public:
+
+ enum CanvasRectFlags {
+
+ CANVAS_RECT_REGION=1,
+ CANVAS_RECT_TILE=2,
+ CANVAS_RECT_FLIP_H=4,
+ CANVAS_RECT_FLIP_V=8,
+ CANVAS_RECT_TRANSPOSE=16
+ };
+
+
+ struct Light : public RID_Data {
+
+
+
+ bool enabled;
+ Color color;
+ Matrix32 xform;
+ float height;
+ float energy;
+ float scale;
+ int z_min;
+ int z_max;
+ int layer_min;
+ int layer_max;
+ int item_mask;
+ int item_shadow_mask;
+ VS::CanvasLightMode mode;
+ RID texture;
+ Vector2 texture_offset;
+ RID canvas;
+ RID shadow_buffer;
+ int shadow_buffer_size;
+ float shadow_gradient_length;
+ VS::CanvasLightShadowFilter shadow_filter;
+ Color shadow_color;
+
+
+ void *texture_cache; // implementation dependent
+ Rect2 rect_cache;
+ Matrix32 xform_cache;
+ float radius_cache; //used for shadow far plane
+ CameraMatrix shadow_matrix_cache;
+
+ Matrix32 light_shader_xform;
+ Vector2 light_shader_pos;
+
+ Light *shadows_next_ptr;
+ Light *filter_next_ptr;
+ Light *next_ptr;
+ Light *mask_next_ptr;
+
+ RID light_internal;
+
+ Light() {
+ enabled=true;
+ color=Color(1,1,1);
+ shadow_color=Color(0,0,0,0);
+ height=0;
+ z_min=-1024;
+ z_max=1024;
+ layer_min=0;
+ layer_max=0;
+ item_mask=1;
+ scale=1.0;
+ energy=1.0;
+ item_shadow_mask=-1;
+ mode=VS::CANVAS_LIGHT_MODE_ADD;
+ texture_cache=NULL;
+ next_ptr=NULL;
+ mask_next_ptr=NULL;
+ filter_next_ptr=NULL;
+ shadow_buffer_size=256;
+ shadow_gradient_length=0;
+ shadow_filter=VS::CANVAS_LIGHT_FILTER_NONE;
+
+ }
+ };
+
+ virtual RID light_internal_create()=0;
+ virtual void light_internal_update(RID p_rid, Light* p_light)=0;
+ virtual void light_internal_free(RID p_rid)=0;
+
+ struct Item : public RID_Data {
+
+ struct Command {
+
+ enum Type {
+
+ TYPE_LINE,
+ TYPE_RECT,
+ TYPE_NINEPATCH,
+ TYPE_PRIMITIVE,
+ TYPE_POLYGON,
+ TYPE_MESH,
+ TYPE_MULTIMESH,
+ TYPE_CIRCLE,
+ TYPE_TRANSFORM,
+ TYPE_CLIP_IGNORE,
+ };
+
+ Type type;
+ virtual ~Command(){}
+ };
+
+ struct CommandLine : public Command {
+
+ Point2 from,to;
+ Color color;
+ float width;
+ bool antialiased;
+ 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 CommandNinePatch : public Command {
+
+ Rect2 rect;
+ Rect2 source;
+ RID texture;
+ float margin[4];
+ bool draw_center;
+ Color color;
+ VS::NinePatchAxisMode axis_x;
+ VS::NinePatchAxisMode axis_y;
+ CommandNinePatch() { draw_center=true; type = TYPE_NINEPATCH; }
+ };
+
+ 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 CommandMesh : public Command {
+
+ RID mesh;
+ RID skeleton;
+ CommandMesh() { type = TYPE_MESH; }
+ };
+
+ struct CommandMultiMesh : public Command {
+
+ RID multimesh;
+ RID skeleton;
+ CommandMultiMesh() { type = TYPE_MULTIMESH; }
+ };
+
+ 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 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 behind;
+ //VS::MaterialBlendMode blend_mode;
+ int light_mask;
+ Vector<Command*> commands;
+ mutable bool custom_rect;
+ mutable bool rect_dirty;
+ mutable Rect2 rect;
+ RID material;
+ Item*next;
+
+ struct CopyBackBuffer {
+ Rect2 rect;
+ Rect2 screen_rect;
+ bool full;
+ };
+ CopyBackBuffer *copy_back_buffer;
+
+
+ Color final_modulate;
+ Matrix32 final_transform;
+ Rect2 final_clip_rect;
+ Item* final_clip_owner;
+ Item* material_owner;
+ ViewportRender *vp_render;
+ bool distance_field;
+ bool light_masked;
+
+ Rect2 global_rect_cache;
+
+ 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 Item::Command * const *cmd = &commands[0];
+
+
+ for (int i=0;i<s;i++) {
+
+ const Item::Command *c=cmd[i];
+ Rect2 r;
+
+ switch(c->type) {
+ case Item::Command::TYPE_LINE: {
+
+ const Item::CommandLine* line = static_cast< const Item::CommandLine*>(c);
+ r.pos=line->from;
+ r.expand_to(line->to);
+ } break;
+ case Item::Command::TYPE_RECT: {
+
+ const Item::CommandRect* crect = static_cast< const Item::CommandRect*>(c);
+ r=crect->rect;
+
+ } break;
+ case Item::Command::TYPE_NINEPATCH: {
+
+ const Item::CommandNinePatch* style = static_cast< const Item::CommandNinePatch*>(c);
+ r=style->rect;
+ } break;
+ case Item::Command::TYPE_PRIMITIVE: {
+
+ const Item::CommandPrimitive* primitive = static_cast< const Item::CommandPrimitive*>(c);
+ r.pos=primitive->points[0];
+ for(int i=1;i<primitive->points.size();i++) {
+
+ r.expand_to(primitive->points[i]);
+
+ }
+ } break;
+ case Item::Command::TYPE_POLYGON: {
+
+ const Item::CommandPolygon* polygon = static_cast< const Item::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 Item::Command::TYPE_MESH: {
+
+ const Item::CommandMesh* mesh = static_cast< const Item::CommandMesh*>(c);
+ AABB aabb = RasterizerStorage::base_signleton->mesh_get_aabb(mesh->mesh);
+
+ r=Rect2(aabb.pos.x,aabb.pos.y,aabb.size.x,aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_MULTIMESH: {
+
+ const Item::CommandMultiMesh* multimesh = static_cast< const Item::CommandMultiMesh*>(c);
+ AABB aabb = RasterizerStorage::base_signleton->multimesh_get_aabb(multimesh->multimesh);
+
+ r=Rect2(aabb.pos.x,aabb.pos.y,aabb.size.x,aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_CIRCLE: {
+
+ const Item::CommandCircle* circle = static_cast< const Item::CommandCircle*>(c);
+ r.pos=Point2(-circle->radius,-circle->radius)+circle->pos;
+ r.size=Point2(circle->radius*2.0,circle->radius*2.0);
+ } break;
+ case Item::Command::TYPE_TRANSFORM: {
+
+ const Item::CommandTransform* transform = static_cast<const Item::CommandTransform*>(c);
+ xf=transform->xform;
+ found_xform=true;
+ continue;
+ } break;
+
+ case Item::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; material_owner=NULL; light_masked=false; }
+ Item() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_modulate=Color(1,1,1,1); visible=true; rect_dirty=true; custom_rect=false; behind=false; material_owner=NULL; copy_back_buffer=NULL; distance_field=false; light_masked=false; }
+ virtual ~Item() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); }
+ };
+
+
+ virtual void canvas_begin()=0;
+
+ virtual void canvas_render_items(Item *p_item_list,int p_z,const Color& p_modulate,Light *p_light)=0;
+ virtual void canvas_debug_viewport_shadows(Light* p_lights_with_shadow)=0;
+
+
+
+ struct LightOccluderInstance : public RID_Data {
+
+
+ bool enabled;
+ RID canvas;
+ RID polygon;
+ RID polygon_buffer;
+ Rect2 aabb_cache;
+ Matrix32 xform;
+ Matrix32 xform_cache;
+ int light_mask;
+ VS::CanvasOccluderPolygonCullMode cull_cache;
+
+ LightOccluderInstance *next;
+
+ LightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
+ };
+
+
+
+ virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, LightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0;
+
+
+ virtual void reset_canvas()=0;
+
+ virtual ~RasterizerCanvas() {}
+};
+
+
+
+class RasterizerScene {
+public:
+
+
+
+ virtual ~RasterizerScene() {}
+};
+
+
+
+class Rasterizer {
+protected:
+ static Rasterizer* (*_create_func)();
+public:
+ static Rasterizer *create();
+
+ virtual RasterizerStorage *get_storage()=0;
+ virtual RasterizerCanvas *get_canvas()=0;
+ virtual RasterizerScene *get_scene()=0;
+
+ virtual void initialize()=0;
+ virtual void begin_frame()=0;
+ virtual void set_current_render_target(RID p_render_target)=0;
+ virtual void restore_render_target()=0;
+ virtual void clear_render_target(const Color& p_color)=0;
+ virtual void blit_render_target_to_screen(RID p_render_target,const Rect2& p_screen_rect,int p_screen=0)=0;
+ virtual void end_frame()=0;
+ virtual void finalize()=0;
+
+
+ virtual ~Rasterizer() {}
+};
+
+
+
+
+#if 0
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -41,7 +705,7 @@ class Rasterizer {
protected:
- typedef void (*CanvasItemDrawViewportFunc)(VisualServer*owner,void*ud,const Rect2& p_rect);
+ typedef void (*ItemDrawViewportFunc)(VisualServer*owner,void*ud,const Rect2& p_rect);
RID create_default_material();
RID create_overdraw_debug_material();
@@ -581,7 +1245,7 @@ public:
};
- struct CanvasLight {
+ struct Light {
@@ -597,7 +1261,7 @@ public:
int layer_max;
int item_mask;
int item_shadow_mask;
- VS::CanvasLightMode mode;
+ VS::LightMode mode;
RID texture;
Vector2 texture_offset;
RID canvas;
@@ -616,12 +1280,12 @@ public:
Matrix32 light_shader_xform;
Vector2 light_shader_pos;
- CanvasLight *shadows_next_ptr;
- CanvasLight *filter_next_ptr;
- CanvasLight *next_ptr;
- CanvasLight *mask_next_ptr;
+ Light *shadows_next_ptr;
+ Light *filter_next_ptr;
+ Light *next_ptr;
+ Light *mask_next_ptr;
- CanvasLight() {
+ Light() {
enabled=true;
color=Color(1,1,1);
shadow_color=Color(0,0,0,0);
@@ -645,20 +1309,20 @@ public:
}
};
- struct CanvasItem;
+ struct Item;
- struct CanvasItemMaterial {
+ struct ItemMaterial {
RID shader;
Map<StringName,Variant> shader_param;
uint32_t shader_version;
- Set<CanvasItem*> owners;
- VS::CanvasItemShadingMode shading_mode;
+ Set<Item*> owners;
+ VS::ItemShadingMode shading_mode;
- CanvasItemMaterial() {shading_mode=VS::CANVAS_ITEM_SHADING_NORMAL; shader_version=0; }
+ ItemMaterial() {shading_mode=VS::CANVAS_ITEM_SHADING_NORMAL; shader_version=0; }
};
- struct CanvasItem {
+ struct Item {
struct Command {
@@ -788,8 +1452,8 @@ public:
mutable bool custom_rect;
mutable bool rect_dirty;
mutable Rect2 rect;
- CanvasItem*next;
- CanvasItemMaterial* material;
+ Item*next;
+ ItemMaterial* material;
struct CopyBackBuffer {
Rect2 rect;
Rect2 screen_rect;
@@ -801,8 +1465,8 @@ public:
float final_opacity;
Matrix32 final_transform;
Rect2 final_clip_rect;
- CanvasItem* final_clip_owner;
- CanvasItem* material_owner;
+ Item* final_clip_owner;
+ Item* material_owner;
ViewportRender *vp_render;
bool distance_field;
bool light_masked;
@@ -826,35 +1490,35 @@ public:
bool found_xform=false;
bool first=true;
- const CanvasItem::Command * const *cmd = &commands[0];
+ const Item::Command * const *cmd = &commands[0];
for (int i=0;i<s;i++) {
- const CanvasItem::Command *c=cmd[i];
+ const Item::Command *c=cmd[i];
Rect2 r;
switch(c->type) {
- case CanvasItem::Command::TYPE_LINE: {
+ case Item::Command::TYPE_LINE: {
- const CanvasItem::CommandLine* line = static_cast< const CanvasItem::CommandLine*>(c);
+ const Item::CommandLine* line = static_cast< const Item::CommandLine*>(c);
r.pos=line->from;
r.expand_to(line->to);
} break;
- case CanvasItem::Command::TYPE_RECT: {
+ case Item::Command::TYPE_RECT: {
- const CanvasItem::CommandRect* crect = static_cast< const CanvasItem::CommandRect*>(c);
+ const Item::CommandRect* crect = static_cast< const Item::CommandRect*>(c);
r=crect->rect;
} break;
- case CanvasItem::Command::TYPE_STYLE: {
+ case Item::Command::TYPE_STYLE: {
- const CanvasItem::CommandStyle* style = static_cast< const CanvasItem::CommandStyle*>(c);
+ const Item::CommandStyle* style = static_cast< const Item::CommandStyle*>(c);
r=style->rect;
} break;
- case CanvasItem::Command::TYPE_PRIMITIVE: {
+ case Item::Command::TYPE_PRIMITIVE: {
- const CanvasItem::CommandPrimitive* primitive = static_cast< const CanvasItem::CommandPrimitive*>(c);
+ const Item::CommandPrimitive* primitive = static_cast< const Item::CommandPrimitive*>(c);
r.pos=primitive->points[0];
for(int i=1;i<primitive->points.size();i++) {
@@ -862,9 +1526,9 @@ public:
}
} break;
- case CanvasItem::Command::TYPE_POLYGON: {
+ case Item::Command::TYPE_POLYGON: {
- const CanvasItem::CommandPolygon* polygon = static_cast< const CanvasItem::CommandPolygon*>(c);
+ const Item::CommandPolygon* polygon = static_cast< const Item::CommandPolygon*>(c);
int l = polygon->points.size();
const Point2*pp=&polygon->points[0];
r.pos=pp[0];
@@ -875,9 +1539,9 @@ public:
}
} break;
- case CanvasItem::Command::TYPE_POLYGON_PTR: {
+ case Item::Command::TYPE_POLYGON_PTR: {
- const CanvasItem::CommandPolygonPtr* polygon = static_cast< const CanvasItem::CommandPolygonPtr*>(c);
+ const Item::CommandPolygonPtr* polygon = static_cast< const Item::CommandPolygonPtr*>(c);
int l = polygon->count;
if (polygon->indices != NULL) {
@@ -894,23 +1558,23 @@ public:
}
}
} break;
- case CanvasItem::Command::TYPE_CIRCLE: {
+ case Item::Command::TYPE_CIRCLE: {
- const CanvasItem::CommandCircle* circle = static_cast< const CanvasItem::CommandCircle*>(c);
+ const Item::CommandCircle* circle = static_cast< const Item::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: {
+ case Item::Command::TYPE_TRANSFORM: {
- const CanvasItem::CommandTransform* transform = static_cast<const CanvasItem::CommandTransform*>(c);
+ const Item::CommandTransform* transform = static_cast<const Item::CommandTransform*>(c);
xf=transform->xform;
found_xform=true;
continue;
} break;
- case CanvasItem::Command::TYPE_BLEND_MODE: {
+ case Item::Command::TYPE_BLEND_MODE: {
} break;
- case CanvasItem::Command::TYPE_CLIP_IGNORE: {
+ case Item::Command::TYPE_CLIP_IGNORE: {
} break;
}
@@ -933,12 +1597,12 @@ 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; material_owner=NULL; light_masked=false; }
- 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; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; light_masked=false; }
- virtual ~CanvasItem() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); }
+ Item() { 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; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; light_masked=false; }
+ virtual ~Item() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); }
};
- CanvasItemDrawViewportFunc draw_viewport_func;
+ ItemDrawViewportFunc draw_viewport_func;
virtual void begin_canvas_bg()=0;
@@ -956,8 +1620,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)=0;
virtual void canvas_set_transform(const Matrix32& p_transform)=0;
- virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light)=0;
- virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow)=0;
+ virtual void canvas_render_items(Item *p_item_list,int p_z,const Color& p_modulate,Light *p_light)=0;
+ virtual void canvas_debug_viewport_shadows(Light* p_lights_with_shadow)=0;
/* LIGHT SHADOW MAPPING */
virtual RID canvas_light_occluder_create()=0;
@@ -966,7 +1630,7 @@ public:
virtual RID canvas_light_shadow_buffer_create(int p_width)=0;
- struct CanvasLightOccluderInstance {
+ struct LightOccluderInstance {
bool enabled;
@@ -979,14 +1643,14 @@ public:
int light_mask;
VS::CanvasOccluderPolygonCullMode cull_cache;
- CanvasLightOccluderInstance *next;
+ LightOccluderInstance *next;
- CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
+ LightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
};
- virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0;
+ virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, LightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0;
/* ENVIRONMENT */
@@ -1050,5 +1714,5 @@ public:
};
-
+#endif
#endif
diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp
deleted file mode 100644
index edbdc2fe23..0000000000
--- a/servers/visual/rasterizer_dummy.cpp
+++ /dev/null
@@ -1,1961 +0,0 @@
-/*************************************************************************/
-/* rasterizer_dummy.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "rasterizer_dummy.h"
-
-/* TEXTURE API */
-
-
-RID RasterizerDummy::texture_create() {
-
- Texture *texture = memnew(Texture);
- ERR_FAIL_COND_V(!texture,RID());
- return texture_owner.make_rid( texture );
-
-}
-
-void RasterizerDummy::texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags) {
-
-
- Texture *texture = texture_owner.get( p_texture );
- ERR_FAIL_COND(!texture);
- texture->width=p_width;
- texture->height=p_height;
- texture->format=p_format;
- texture->flags=p_flags;
-}
-
-void RasterizerDummy::texture_set_data(RID p_texture,const Image& p_image,VS::CubeMapSide p_cube_side) {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND(!texture);
- ERR_FAIL_COND(texture->format != p_image.get_format() );
-
- texture->image[p_cube_side]=p_image;
-
-}
-
-Image RasterizerDummy::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_side) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,Image());
-
- return texture->image[p_cube_side];
-}
-
-void RasterizerDummy::texture_set_flags(RID p_texture,uint32_t p_flags) {
-
- Texture *texture = texture_owner.get( p_texture );
- ERR_FAIL_COND(!texture);
- uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
- texture->flags=p_flags|cube; // can't remove a cube from being a cube
-
-}
-uint32_t RasterizerDummy::texture_get_flags(RID p_texture) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,0);
-
- return texture->flags;
-
-}
-Image::Format RasterizerDummy::texture_get_format(RID p_texture) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,Image::FORMAT_GRAYSCALE);
-
- return texture->format;
-}
-uint32_t RasterizerDummy::texture_get_width(RID p_texture) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,0);
-
- return texture->width;
-}
-uint32_t RasterizerDummy::texture_get_height(RID p_texture) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,0);
-
- return texture->height;
-}
-
-bool RasterizerDummy::texture_has_alpha(RID p_texture) const {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture,0);
-
- return false;
-
-}
-
-void RasterizerDummy::texture_set_size_override(RID p_texture,int p_width, int p_height) {
-
- Texture * texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND(!texture);
-
- ERR_FAIL_COND(p_width<=0 || p_width>4096);
- ERR_FAIL_COND(p_height<=0 || p_height>4096);
- //real texture size is in alloc width and height
-// texture->width=p_width;
-// texture->height=p_height;
-
-}
-
-void RasterizerDummy::texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const {
-
-
-}
-
-/* SHADER API */
-
-/* SHADER API */
-
-RID RasterizerDummy::shader_create(VS::ShaderMode p_mode) {
-
- Shader *shader = memnew( Shader );
- shader->mode=p_mode;
- shader->fragment_line=0;
- shader->vertex_line=0;
- shader->light_line=0;
- RID rid = shader_owner.make_rid(shader);
-
- return rid;
-
-}
-
-
-
-void RasterizerDummy::shader_set_mode(RID p_shader,VS::ShaderMode p_mode) {
-
- ERR_FAIL_INDEX(p_mode,3);
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND(!shader);
- shader->mode=p_mode;
-
-}
-VS::ShaderMode RasterizerDummy::shader_get_mode(RID p_shader) const {
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND_V(!shader,VS::SHADER_MATERIAL);
- return shader->mode;
-}
-
-void RasterizerDummy::shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs) {
-
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND(!shader);
- shader->fragment_code=p_fragment;
- shader->vertex_code=p_vertex;
- shader->light_code=p_light;
- shader->fragment_line=p_fragment_ofs;
- shader->vertex_line=p_vertex_ofs;
- shader->light_line=p_vertex_ofs;
-
-}
-
-
-String RasterizerDummy::shader_get_vertex_code(RID p_shader) const {
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND_V(!shader,String());
- return shader->vertex_code;
-
-}
-
-String RasterizerDummy::shader_get_fragment_code(RID p_shader) const {
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND_V(!shader,String());
- return shader->fragment_code;
-
-}
-
-String RasterizerDummy::shader_get_light_code(RID p_shader) const {
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND_V(!shader,String());
- return shader->light_code;
-
-}
-
-void RasterizerDummy::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
-
- Shader *shader=shader_owner.get(p_shader);
- ERR_FAIL_COND(!shader);
-
-}
-
-
-void RasterizerDummy::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture) {
-
-}
-
-RID RasterizerDummy::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const {
-
- return RID();
-}
-
-Variant RasterizerDummy::shader_get_default_param(RID p_shader, const StringName& p_name) {
-
- return Variant();
-}
-
-/* COMMON MATERIAL API */
-
-
-RID RasterizerDummy::material_create() {
-
- return material_owner.make_rid( memnew( Material ) );
-}
-
-void RasterizerDummy::material_set_shader(RID p_material, RID p_shader) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
- material->shader=p_shader;
-
-}
-
-RID RasterizerDummy::material_get_shader(RID p_material) const {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,RID());
- return material->shader;
-}
-
-void RasterizerDummy::material_set_param(RID p_material, const StringName& p_param, const Variant& p_value) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
-
- if (p_value.get_type()==Variant::NIL)
- material->shader_params.erase(p_param);
- else
- material->shader_params[p_param]=p_value;
-}
-Variant RasterizerDummy::material_get_param(RID p_material, const StringName& p_param) const {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,Variant());
-
- if (material->shader_params.has(p_param))
- return material->shader_params[p_param];
- else
- return Variant();
-}
-
-
-void RasterizerDummy::material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
- ERR_FAIL_INDEX(p_flag,VS::MATERIAL_FLAG_MAX);
- material->flags[p_flag]=p_enabled;
-
-}
-bool RasterizerDummy::material_get_flag(RID p_material,VS::MaterialFlag p_flag) const {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,false);
- ERR_FAIL_INDEX_V(p_flag,VS::MATERIAL_FLAG_MAX,false);
- return material->flags[p_flag];
-
-
-}
-
-void RasterizerDummy::material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
- material->depth_draw_mode=p_mode;
-}
-
-VS::MaterialDepthDrawMode RasterizerDummy::material_get_depth_draw_mode(RID p_material) const{
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,VS::MATERIAL_DEPTH_DRAW_ALWAYS);
- return material->depth_draw_mode;
-
-}
-
-
-void RasterizerDummy::material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
- material->blend_mode=p_mode;
-
-}
-VS::MaterialBlendMode RasterizerDummy::material_get_blend_mode(RID p_material) const {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,VS::MATERIAL_BLEND_MODE_ADD);
- return material->blend_mode;
-}
-
-void RasterizerDummy::material_set_line_width(RID p_material,float p_line_width) {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND(!material);
- material->line_width=p_line_width;
-
-}
-float RasterizerDummy::material_get_line_width(RID p_material) const {
-
- Material *material = material_owner.get(p_material);
- ERR_FAIL_COND_V(!material,0);
-
- return material->line_width;
-}
-
-/* MESH API */
-
-
-RID RasterizerDummy::mesh_create() {
-
-
- return mesh_owner.make_rid( memnew( Mesh ) );
-}
-
-
-void RasterizerDummy::mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,bool p_alpha_sort) {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
-
- ERR_FAIL_INDEX( p_primitive, VS::PRIMITIVE_MAX );
- ERR_FAIL_COND(p_arrays.size()!=VS::ARRAY_MAX);
-
- Surface s;
-
-
- s.format=0;
-
- for(int i=0;i<p_arrays.size();i++) {
-
- if (p_arrays[i].get_type()==Variant::NIL)
- continue;
-
- s.format|=(1<<i);
-
- if (i==VS::ARRAY_VERTEX) {
-
- Vector3Array v = p_arrays[i];
- int len = v.size();
- ERR_FAIL_COND(len==0);
- Vector3Array::Read r = v.read();
-
-
- for(int i=0;i<len;i++) {
-
- if (i==0)
- s.aabb.pos=r[0];
- else
- s.aabb.expand_to(r[i]);
- }
-
- }
- }
-
- ERR_FAIL_COND((s.format&VS::ARRAY_FORMAT_VERTEX)==0); // mandatory
-
- s.data=p_arrays;
- s.morph_data=p_blend_shapes;
- s.primitive=p_primitive;
- s.alpha_sort=p_alpha_sort;
- s.morph_target_count=mesh->morph_target_count;
- s.morph_format=s.format;
-
-
- Surface *surface = memnew( Surface );
- *surface=s;
-
- mesh->surfaces.push_back(surface);
-
-
-}
-
-
-
-void RasterizerDummy::mesh_add_custom_surface(RID p_mesh,const Variant& p_dat) {
-
- ERR_EXPLAIN("Dummy Rasterizer does not support custom surfaces. Running on wrong platform?");
- ERR_FAIL_V();
-}
-
-Array RasterizerDummy::mesh_get_surface_arrays(RID p_mesh,int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,Array());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Array() );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, Array() );
-
- return surface->data;
-
-
-}
-Array RasterizerDummy::mesh_get_surface_morph_arrays(RID p_mesh,int p_surface) const{
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,Array());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Array() );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, Array() );
-
- return surface->morph_data;
-
-}
-
-
-void RasterizerDummy::mesh_set_morph_target_count(RID p_mesh,int p_amount) {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_COND( mesh->surfaces.size()!=0 );
-
- mesh->morph_target_count=p_amount;
-
-}
-
-int RasterizerDummy::mesh_get_morph_target_count(RID p_mesh) const{
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,-1);
-
- return mesh->morph_target_count;
-
-}
-
-void RasterizerDummy::mesh_set_morph_target_mode(RID p_mesh,VS::MorphTargetMode p_mode) {
-
- ERR_FAIL_INDEX(p_mode,2);
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
-
- mesh->morph_target_mode=p_mode;
-
-}
-
-VS::MorphTargetMode RasterizerDummy::mesh_get_morph_target_mode(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,VS::MORPH_MODE_NORMALIZED);
-
- return mesh->morph_target_mode;
-
-}
-
-
-
-void RasterizerDummy::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material,bool p_owned) {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_surface, mesh->surfaces.size() );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND( !surface);
-
- if (surface->material_owned && surface->material.is_valid())
- free(surface->material);
-
- surface->material_owned=p_owned;
- surface->material=p_material;
-}
-
-RID RasterizerDummy::mesh_surface_get_material(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,RID());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID() );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, RID() );
-
- return surface->material;
-}
-
-int RasterizerDummy::mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,-1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1 );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, -1 );
-
- Vector3Array arr = surface->data[VS::ARRAY_VERTEX];
- return arr.size();
-
-}
-
-int RasterizerDummy::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,-1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1 );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, -1 );
-
- IntArray arr = surface->data[VS::ARRAY_INDEX];
- return arr.size();
-
-}
-uint32_t RasterizerDummy::mesh_surface_get_format(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,0);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0 );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, 0 );
-
- return surface->format;
-}
-VS::PrimitiveType RasterizerDummy::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,VS::PRIMITIVE_POINTS);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS );
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V( !surface, VS::PRIMITIVE_POINTS );
-
- return surface->primitive;
-}
-
-void RasterizerDummy::mesh_remove_surface(RID p_mesh,int p_index) {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_index, mesh->surfaces.size() );
- Surface *surface = mesh->surfaces[p_index];
- ERR_FAIL_COND( !surface);
-
- memdelete( mesh->surfaces[p_index] );
- mesh->surfaces.remove(p_index);
-
-}
-int RasterizerDummy::mesh_get_surface_count(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,-1);
-
- return mesh->surfaces.size();
-}
-
-AABB RasterizerDummy::mesh_get_aabb(RID p_mesh,RID p_skeleton) const {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,AABB());
-
- AABB aabb;
-
- for (int i=0;i<mesh->surfaces.size();i++) {
-
- if (i==0)
- aabb=mesh->surfaces[i]->aabb;
- else
- aabb.merge_with(mesh->surfaces[i]->aabb);
- }
-
- return aabb;
-}
-
-void RasterizerDummy::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) {
-
- Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND(!mesh);
-
- mesh->custom_aabb=p_aabb;
-}
-
-AABB RasterizerDummy::mesh_get_custom_aabb(RID p_mesh) const {
-
- const Mesh *mesh = mesh_owner.get( p_mesh );
- ERR_FAIL_COND_V(!mesh,AABB());
-
- return mesh->custom_aabb;
-
-}
-
-/* MULTIMESH API */
-
-RID RasterizerDummy::multimesh_create() {
-
- return multimesh_owner.make_rid( memnew( MultiMesh ));
-}
-
-void RasterizerDummy::multimesh_set_instance_count(RID p_multimesh,int p_count) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh);
-
- multimesh->elements.clear(); // make sure to delete everything, so it "fails" in all implementations
- multimesh->elements.resize(p_count);
-
-}
-int RasterizerDummy::multimesh_get_instance_count(RID p_multimesh) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,-1);
-
- return multimesh->elements.size();
-}
-
-void RasterizerDummy::multimesh_set_mesh(RID p_multimesh,RID p_mesh) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh);
-
- multimesh->mesh=p_mesh;
-
-}
-void RasterizerDummy::multimesh_set_aabb(RID p_multimesh,const AABB& p_aabb) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh);
- multimesh->aabb=p_aabb;
-}
-void RasterizerDummy::multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform& p_transform) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh);
- ERR_FAIL_INDEX(p_index,multimesh->elements.size());
- multimesh->elements[p_index].xform=p_transform;
-
-}
-void RasterizerDummy::multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh)
- ERR_FAIL_INDEX(p_index,multimesh->elements.size());
- multimesh->elements[p_index].color=p_color;
-
-}
-
-RID RasterizerDummy::multimesh_get_mesh(RID p_multimesh) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,RID());
-
- return multimesh->mesh;
-}
-AABB RasterizerDummy::multimesh_get_aabb(RID p_multimesh) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,AABB());
-
- return multimesh->aabb;
-}
-
-Transform RasterizerDummy::multimesh_instance_get_transform(RID p_multimesh,int p_index) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,Transform());
-
- ERR_FAIL_INDEX_V(p_index,multimesh->elements.size(),Transform());
-
- return multimesh->elements[p_index].xform;
-
-}
-Color RasterizerDummy::multimesh_instance_get_color(RID p_multimesh,int p_index) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,Color());
- ERR_FAIL_INDEX_V(p_index,multimesh->elements.size(),Color());
-
- return multimesh->elements[p_index].color;
-}
-
-void RasterizerDummy::multimesh_set_visible_instances(RID p_multimesh,int p_visible) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND(!multimesh);
- multimesh->visible=p_visible;
-
-}
-
-int RasterizerDummy::multimesh_get_visible_instances(RID p_multimesh) const {
-
- MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
- ERR_FAIL_COND_V(!multimesh,-1);
- return multimesh->visible;
-
-}
-
-/* IMMEDIATE API */
-
-
-RID RasterizerDummy::immediate_create() {
-
- Immediate *im = memnew( Immediate );
- return immediate_owner.make_rid(im);
-
-}
-
-void RasterizerDummy::immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture){
-
-
-}
-void RasterizerDummy::immediate_vertex(RID p_immediate,const Vector3& p_vertex){
-
-
-}
-void RasterizerDummy::immediate_normal(RID p_immediate,const Vector3& p_normal){
-
-
-}
-void RasterizerDummy::immediate_tangent(RID p_immediate,const Plane& p_tangent){
-
-
-}
-void RasterizerDummy::immediate_color(RID p_immediate,const Color& p_color){
-
-
-}
-void RasterizerDummy::immediate_uv(RID p_immediate,const Vector2& tex_uv){
-
-
-}
-void RasterizerDummy::immediate_uv2(RID p_immediate,const Vector2& tex_uv){
-
-
-}
-
-void RasterizerDummy::immediate_end(RID p_immediate){
-
-
-}
-void RasterizerDummy::immediate_clear(RID p_immediate) {
-
-
-}
-
-AABB RasterizerDummy::immediate_get_aabb(RID p_immediate) const {
-
- return AABB(Vector3(-1,-1,-1),Vector3(2,2,2));
-}
-
-void RasterizerDummy::immediate_set_material(RID p_immediate,RID p_material) {
-
- Immediate *im = immediate_owner.get(p_immediate);
- ERR_FAIL_COND(!im);
- im->material=p_material;
-
-}
-
-RID RasterizerDummy::immediate_get_material(RID p_immediate) const {
-
- const Immediate *im = immediate_owner.get(p_immediate);
- ERR_FAIL_COND_V(!im,RID());
- return im->material;
-
-}
-
-/* PARTICLES API */
-
-RID RasterizerDummy::particles_create() {
-
- Particles *particles = memnew( Particles );
- ERR_FAIL_COND_V(!particles,RID());
- return particles_owner.make_rid(particles);
-}
-
-void RasterizerDummy::particles_set_amount(RID p_particles, int p_amount) {
-
- ERR_FAIL_COND(p_amount<1);
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.amount=p_amount;
-
-}
-
-int RasterizerDummy::particles_get_amount(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.amount;
-
-}
-
-void RasterizerDummy::particles_set_emitting(RID p_particles, bool p_emitting) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.emitting=p_emitting;;
-
-}
-bool RasterizerDummy::particles_is_emitting(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,false);
- return particles->data.emitting;
-
-}
-
-void RasterizerDummy::particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.visibility_aabb=p_visibility;
-
-}
-
-void RasterizerDummy::particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
-
- particles->data.emission_half_extents=p_half_extents;
-}
-Vector3 RasterizerDummy::particles_get_emission_half_extents(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,Vector3());
-
- return particles->data.emission_half_extents;
-}
-
-void RasterizerDummy::particles_set_emission_base_velocity(RID p_particles, const Vector3& p_base_velocity) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
-
- particles->data.emission_base_velocity=p_base_velocity;
-}
-
-Vector3 RasterizerDummy::particles_get_emission_base_velocity(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,Vector3());
-
- return particles->data.emission_base_velocity;
-}
-
-
-void RasterizerDummy::particles_set_emission_points(RID p_particles, const DVector<Vector3>& p_points) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
-
- particles->data.emission_points=p_points;
-}
-
-DVector<Vector3> RasterizerDummy::particles_get_emission_points(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,DVector<Vector3>());
-
- return particles->data.emission_points;
-
-}
-
-void RasterizerDummy::particles_set_gravity_normal(RID p_particles, const Vector3& p_normal) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
-
- particles->data.gravity_normal=p_normal;
-
-}
-Vector3 RasterizerDummy::particles_get_gravity_normal(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,Vector3());
-
- return particles->data.gravity_normal;
-}
-
-
-AABB RasterizerDummy::particles_get_visibility_aabb(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,AABB());
- return particles->data.visibility_aabb;
-
-}
-
-void RasterizerDummy::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable,float p_value) {
-
- ERR_FAIL_INDEX(p_variable,VS::PARTICLE_VAR_MAX);
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.particle_vars[p_variable]=p_value;
-
-}
-float RasterizerDummy::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.particle_vars[p_variable];
-}
-
-void RasterizerDummy::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable,float p_randomness) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.particle_randomness[p_variable]=p_randomness;
-
-}
-float RasterizerDummy::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.particle_randomness[p_variable];
-
-}
-
-void RasterizerDummy::particles_set_color_phases(RID p_particles, int p_phases) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- ERR_FAIL_COND( p_phases<0 || p_phases>VS::MAX_PARTICLE_COLOR_PHASES );
- particles->data.color_phase_count=p_phases;
-
-}
-int RasterizerDummy::particles_get_color_phases(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.color_phase_count;
-}
-
-
-void RasterizerDummy::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) {
-
- ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
- if (p_pos<0.0)
- p_pos=0.0;
- if (p_pos>1.0)
- p_pos=1.0;
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.color_phases[p_phase].pos=p_pos;
-
-}
-float RasterizerDummy::particles_get_color_phase_pos(RID p_particles, int p_phase) const {
-
- ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, -1.0);
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.color_phases[p_phase].pos;
-
-}
-
-void RasterizerDummy::particles_set_color_phase_color(RID p_particles, int p_phase, const Color& p_color) {
-
- ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.color_phases[p_phase].color=p_color;
-
- //update alpha
- particles->has_alpha=false;
- for(int i=0;i<VS::MAX_PARTICLE_COLOR_PHASES;i++) {
- if (particles->data.color_phases[i].color.a<0.99)
- particles->has_alpha=true;
- }
-
-}
-
-Color RasterizerDummy::particles_get_color_phase_color(RID p_particles, int p_phase) const {
-
- ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, Color());
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,Color());
- return particles->data.color_phases[p_phase].color;
-
-}
-
-void RasterizerDummy::particles_set_attractors(RID p_particles, int p_attractors) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- ERR_FAIL_COND( p_attractors<0 || p_attractors>VisualServer::MAX_PARTICLE_ATTRACTORS );
- particles->data.attractor_count=p_attractors;
-
-}
-int RasterizerDummy::particles_get_attractors(RID p_particles) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,-1);
- return particles->data.attractor_count;
-}
-
-void RasterizerDummy::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3& p_pos) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- ERR_FAIL_INDEX(p_attractor,particles->data.attractor_count);
- particles->data.attractors[p_attractor].pos=p_pos;;
-}
-Vector3 RasterizerDummy::particles_get_attractor_pos(RID p_particles,int p_attractor) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,Vector3());
- ERR_FAIL_INDEX_V(p_attractor,particles->data.attractor_count,Vector3());
- return particles->data.attractors[p_attractor].pos;
-}
-
-void RasterizerDummy::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- ERR_FAIL_INDEX(p_attractor,particles->data.attractor_count);
- particles->data.attractors[p_attractor].force=p_force;
-}
-
-float RasterizerDummy::particles_get_attractor_strength(RID p_particles,int p_attractor) const {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,0);
- ERR_FAIL_INDEX_V(p_attractor,particles->data.attractor_count,0);
- return particles->data.attractors[p_attractor].force;
-}
-
-void RasterizerDummy::particles_set_material(RID p_particles, RID p_material,bool p_owned) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- if (particles->material_owned && particles->material.is_valid())
- free(particles->material);
-
- particles->material_owned=p_owned;
-
- particles->material=p_material;
-
-}
-RID RasterizerDummy::particles_get_material(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,RID());
- return particles->material;
-
-}
-
-void RasterizerDummy::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.local_coordinates=p_enable;
-
-}
-
-bool RasterizerDummy::particles_is_using_local_coordinates(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,false);
- return particles->data.local_coordinates;
-}
-bool RasterizerDummy::particles_has_height_from_velocity(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,false);
- return particles->data.height_from_velocity;
-}
-
-void RasterizerDummy::particles_set_height_from_velocity(RID p_particles, bool p_enable) {
-
- Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND(!particles);
- particles->data.height_from_velocity=p_enable;
-
-}
-
-AABB RasterizerDummy::particles_get_aabb(RID p_particles) const {
-
- const Particles* particles = particles_owner.get( p_particles );
- ERR_FAIL_COND_V(!particles,AABB());
- return particles->data.visibility_aabb;
-}
-
-/* SKELETON API */
-
-RID RasterizerDummy::skeleton_create() {
-
- Skeleton *skeleton = memnew( Skeleton );
- ERR_FAIL_COND_V(!skeleton,RID());
- return skeleton_owner.make_rid( skeleton );
-}
-void RasterizerDummy::skeleton_resize(RID p_skeleton,int p_bones) {
-
- Skeleton *skeleton = skeleton_owner.get( p_skeleton );
- ERR_FAIL_COND(!skeleton);
- if (p_bones == skeleton->bones.size()) {
- return;
- };
-
- skeleton->bones.resize(p_bones);
-
-}
-int RasterizerDummy::skeleton_get_bone_count(RID p_skeleton) const {
-
- Skeleton *skeleton = skeleton_owner.get( p_skeleton );
- ERR_FAIL_COND_V(!skeleton, -1);
- return skeleton->bones.size();
-}
-void RasterizerDummy::skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform) {
-
- Skeleton *skeleton = skeleton_owner.get( p_skeleton );
- ERR_FAIL_COND(!skeleton);
- ERR_FAIL_INDEX( p_bone, skeleton->bones.size() );
-
- skeleton->bones[p_bone] = p_transform;
-}
-
-Transform RasterizerDummy::skeleton_bone_get_transform(RID p_skeleton,int p_bone) {
-
- Skeleton *skeleton = skeleton_owner.get( p_skeleton );
- ERR_FAIL_COND_V(!skeleton, Transform());
- ERR_FAIL_INDEX_V( p_bone, skeleton->bones.size(), Transform() );
-
- // something
- return skeleton->bones[p_bone];
-}
-
-
-/* LIGHT API */
-
-RID RasterizerDummy::light_create(VS::LightType p_type) {
-
- Light *light = memnew( Light );
- light->type=p_type;
- return light_owner.make_rid(light);
-}
-
-VS::LightType RasterizerDummy::light_get_type(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light,VS::LIGHT_OMNI);
- return light->type;
-}
-
-void RasterizerDummy::light_set_color(RID p_light,VS::LightColor p_type, const Color& p_color) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX( p_type, 3 );
- light->colors[p_type]=p_color;
-}
-Color RasterizerDummy::light_get_color(RID p_light,VS::LightColor p_type) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, Color());
- ERR_FAIL_INDEX_V( p_type, 3, Color() );
- return light->colors[p_type];
-}
-
-void RasterizerDummy::light_set_shadow(RID p_light,bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->shadow_enabled=p_enabled;
-}
-
-bool RasterizerDummy::light_has_shadow(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light,false);
- return light->shadow_enabled;
-}
-
-void RasterizerDummy::light_set_volumetric(RID p_light,bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->volumetric_enabled=p_enabled;
-
-}
-bool RasterizerDummy::light_is_volumetric(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light,false);
- return light->volumetric_enabled;
-}
-
-void RasterizerDummy::light_set_projector(RID p_light,RID p_texture) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->projector=p_texture;
-}
-RID RasterizerDummy::light_get_projector(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light,RID());
- return light->projector;
-}
-
-void RasterizerDummy::light_set_var(RID p_light, VS::LightParam p_var, float p_value) {
-
- Light * light = light_owner.get( p_light );
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX( p_var, VS::LIGHT_PARAM_MAX );
-
- light->vars[p_var]=p_value;
-}
-float RasterizerDummy::light_get_var(RID p_light, VS::LightParam p_var) const {
-
- Light * light = light_owner.get( p_light );
- ERR_FAIL_COND_V(!light,0);
-
- ERR_FAIL_INDEX_V( p_var, VS::LIGHT_PARAM_MAX,0 );
-
- return light->vars[p_var];
-}
-
-void RasterizerDummy::light_set_operator(RID p_light,VS::LightOp p_op) {
-
- Light * light = light_owner.get( p_light );
- ERR_FAIL_COND(!light);
-
-
-};
-
-VS::LightOp RasterizerDummy::light_get_operator(RID p_light) const {
-
- return VS::LightOp(0);
-};
-
-void RasterizerDummy::light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode) {
-
-
-}
-
-VS::LightOmniShadowMode RasterizerDummy::light_omni_get_shadow_mode(RID p_light) const{
-
- return VS::LightOmniShadowMode(0);
-}
-
-void RasterizerDummy::light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode) {
-
-
-}
-
-VS::LightDirectionalShadowMode RasterizerDummy::light_directional_get_shadow_mode(RID p_light) const {
-
- return VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
-}
-
-void RasterizerDummy::light_directional_set_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param, float p_value) {
-
-
-}
-
-float RasterizerDummy::light_directional_get_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param) const {
-
- return 0;
-}
-
-
-AABB RasterizerDummy::light_get_aabb(RID p_light) const {
-
- Light *light = light_owner.get( p_light );
- ERR_FAIL_COND_V(!light,AABB());
-
- switch( light->type ) {
-
- case VS::LIGHT_SPOT: {
-
- float len=light->vars[VS::LIGHT_PARAM_RADIUS];
- float size=Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE]))*len;
- return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
- } break;
- case VS::LIGHT_OMNI: {
-
- float r = light->vars[VS::LIGHT_PARAM_RADIUS];
- return AABB( -Vector3(r,r,r), Vector3(r,r,r)*2 );
- } break;
- case VS::LIGHT_DIRECTIONAL: {
-
- return AABB();
- } break;
- default: {}
- }
-
- ERR_FAIL_V( AABB() );
-}
-
-
-RID RasterizerDummy::light_instance_create(RID p_light) {
-
- Light *light = light_owner.get( p_light );
- ERR_FAIL_COND_V(!light, RID());
-
- LightInstance *light_instance = memnew( LightInstance );
-
- light_instance->light=p_light;
- light_instance->base=light;
-
-
- return light_instance_owner.make_rid( light_instance );
-}
-void RasterizerDummy::light_instance_set_transform(RID p_light_instance,const Transform& p_transform) {
-
- LightInstance *lighti = light_instance_owner.get( p_light_instance );
- ERR_FAIL_COND(!lighti);
- lighti->transform=p_transform;
-
-}
-
-bool RasterizerDummy::light_instance_has_shadow(RID p_light_instance) const {
-
- return false;
-
-}
-
-
-bool RasterizerDummy::light_instance_assign_shadow(RID p_light_instance) {
-
- return false;
-
-}
-
-
-Rasterizer::ShadowType RasterizerDummy::light_instance_get_shadow_type(RID p_light_instance) const {
-
- LightInstance *lighti = light_instance_owner.get( p_light_instance );
- ERR_FAIL_COND_V(!lighti,Rasterizer::SHADOW_NONE);
-
- switch(lighti->base->type) {
-
- case VS::LIGHT_DIRECTIONAL: return SHADOW_PSM; break;
- case VS::LIGHT_OMNI: return SHADOW_DUAL_PARABOLOID; break;
- case VS::LIGHT_SPOT: return SHADOW_SIMPLE; break;
- }
-
- return Rasterizer::SHADOW_NONE;
-}
-
-Rasterizer::ShadowType RasterizerDummy::light_instance_get_shadow_type(RID p_light_instance,bool p_far) const {
-
- return SHADOW_NONE;
-}
-void RasterizerDummy::light_instance_set_shadow_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near,float p_split_far) {
-
-
-}
-
-int RasterizerDummy::light_instance_get_shadow_passes(RID p_light_instance) const {
-
- return 0;
-}
-
-bool RasterizerDummy::light_instance_get_pssm_shadow_overlap(RID p_light_instance) const {
-
- return false;
-}
-
-
-void RasterizerDummy::light_instance_set_custom_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near,float p_split_far) {
-
- LightInstance *lighti = light_instance_owner.get( p_light_instance );
- ERR_FAIL_COND(!lighti);
-
- ERR_FAIL_COND(lighti->base->type!=VS::LIGHT_DIRECTIONAL);
- ERR_FAIL_INDEX(p_index,1);
-
- lighti->custom_projection=p_camera;
- lighti->custom_transform=p_transform;
-
-}
-void RasterizerDummy::shadow_clear_near() {
-
-
-}
-
-bool RasterizerDummy::shadow_allocate_near(RID p_light) {
-
- return false;
-}
-
-bool RasterizerDummy::shadow_allocate_far(RID p_light) {
-
- return false;
-}
-
-/* PARTICLES INSTANCE */
-
-RID RasterizerDummy::particles_instance_create(RID p_particles) {
-
- ERR_FAIL_COND_V(!particles_owner.owns(p_particles),RID());
- ParticlesInstance *particles_instance = memnew( ParticlesInstance );
- ERR_FAIL_COND_V(!particles_instance, RID() );
- particles_instance->particles=p_particles;
- return particles_instance_owner.make_rid(particles_instance);
-}
-
-void RasterizerDummy::particles_instance_set_transform(RID p_particles_instance,const Transform& p_transform) {
-
- ParticlesInstance *particles_instance=particles_instance_owner.get(p_particles_instance);
- ERR_FAIL_COND(!particles_instance);
- particles_instance->transform=p_transform;
-}
-
-
-/* RENDER API */
-/* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
-
-RID RasterizerDummy::viewport_data_create() {
-
- return RID();
-}
-
-RID RasterizerDummy::render_target_create(){
-
- return RID();
-
-}
-void RasterizerDummy::render_target_set_size(RID p_render_target, int p_width, int p_height){
-
-
-}
-RID RasterizerDummy::render_target_get_texture(RID p_render_target) const{
-
- return RID();
-
-}
-bool RasterizerDummy::render_target_renedered_in_frame(RID p_render_target){
-
- return false;
-}
-
-
-void RasterizerDummy::begin_frame() {
-
-
-
-}
-
-void RasterizerDummy::capture_viewport(Image* r_capture) {
-
-
-}
-
-
-void RasterizerDummy::clear_viewport(const Color& p_color) {
-
-
-};
-
-void RasterizerDummy::set_viewport(const VS::ViewportRect& p_viewport) {
-
-
-
-}
-
-void RasterizerDummy::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) {
-
-
-}
-
-
-void RasterizerDummy::begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug) {
-
-
-};
-
-void RasterizerDummy::begin_shadow_map( RID p_light_instance, int p_shadow_pass ) {
-
-}
-
-void RasterizerDummy::set_camera(const Transform& p_world, const CameraMatrix& p_projection, bool p_ortho_hint) {
-
-
-}
-
-void RasterizerDummy::add_light( RID p_light_instance ) {
-
-
-
-}
-
-
-
-
-void RasterizerDummy::add_mesh( const RID& p_mesh, const InstanceData *p_data) {
-
-
-}
-
-void RasterizerDummy::add_multimesh( const RID& p_multimesh, const InstanceData *p_data){
-
-
-
-
-}
-
-void RasterizerDummy::add_particles( const RID& p_particle_instance, const InstanceData *p_data){
-
-
-
-}
-
-
-
-void RasterizerDummy::end_scene() {
-
-
-}
-void RasterizerDummy::end_shadow_map() {
-
-}
-
-
-void RasterizerDummy::end_frame() {
-
-
-}
-
-RID RasterizerDummy::canvas_light_occluder_create() {
- return RID();
-}
-
-void RasterizerDummy::canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines) {
-
-
-}
-
-RID RasterizerDummy::canvas_light_shadow_buffer_create(int p_width) {
-
- return RID();
-}
-
-void RasterizerDummy::canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache) {
-
-
-}
-
-void RasterizerDummy::canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow) {
-
-
-}
-
-/* CANVAS API */
-
-
-void RasterizerDummy::begin_canvas_bg() {
-
-}
-void RasterizerDummy::canvas_begin() {
-
-
-
-}
-void RasterizerDummy::canvas_disable_blending() {
-
-
-
-}
-
-void RasterizerDummy::canvas_set_opacity(float p_opacity) {
-
-
-}
-
-void RasterizerDummy::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) {
-
-
-}
-
-
-void RasterizerDummy::canvas_begin_rect(const Matrix32& p_transform) {
-
-
-
-}
-
-void RasterizerDummy::canvas_set_clip(bool p_clip, const Rect2& p_rect) {
-
-
-
-
-}
-
-void RasterizerDummy::canvas_end_rect() {
-
-
-}
-
-void RasterizerDummy::canvas_draw_line(const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width, bool p_antialiased) {
-
-
-
-}
-
-void RasterizerDummy::canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate) {
-
-
-
-
-}
-void RasterizerDummy::canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) {
-
-
-}
-void RasterizerDummy::canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width) {
-
-
-
-}
-
-
-void RasterizerDummy::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) {
-
-
-
-}
-
-void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) {
-
-
-}
-
-void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) {
-
-
-}
-
-/* ENVIRONMENT */
-
-RID RasterizerDummy::environment_create() {
-
- Environment * env = memnew( Environment );
- return environment_owner.make_rid(env);
-}
-
-void RasterizerDummy::environment_set_background(RID p_env,VS::EnvironmentBG p_bg) {
-
- ERR_FAIL_INDEX(p_bg,VS::ENV_BG_MAX);
- Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND(!env);
- env->bg_mode=p_bg;
-}
-
-VS::EnvironmentBG RasterizerDummy::environment_get_background(RID p_env) const{
-
- const Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND_V(!env,VS::ENV_BG_MAX);
- return env->bg_mode;
-}
-
-void RasterizerDummy::environment_set_background_param(RID p_env,VS::EnvironmentBGParam p_param, const Variant& p_value){
-
- ERR_FAIL_INDEX(p_param,VS::ENV_BG_PARAM_MAX);
- Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND(!env);
- env->bg_param[p_param]=p_value;
-
-}
-Variant RasterizerDummy::environment_get_background_param(RID p_env,VS::EnvironmentBGParam p_param) const{
-
- ERR_FAIL_INDEX_V(p_param,VS::ENV_BG_PARAM_MAX,Variant());
- const Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND_V(!env,Variant());
- return env->bg_param[p_param];
-
-}
-
-void RasterizerDummy::environment_set_enable_fx(RID p_env,VS::EnvironmentFx p_effect,bool p_enabled){
-
- ERR_FAIL_INDEX(p_effect,VS::ENV_FX_MAX);
- Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND(!env);
- env->fx_enabled[p_effect]=p_enabled;
-}
-bool RasterizerDummy::environment_is_fx_enabled(RID p_env,VS::EnvironmentFx p_effect) const{
-
- ERR_FAIL_INDEX_V(p_effect,VS::ENV_FX_MAX,false);
- const Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND_V(!env,false);
- return env->fx_enabled[p_effect];
-
-}
-
-void RasterizerDummy::environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value){
-
- ERR_FAIL_INDEX(p_param,VS::ENV_FX_PARAM_MAX);
- Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND(!env);
- env->fx_param[p_param]=p_value;
-}
-Variant RasterizerDummy::environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const{
-
- ERR_FAIL_INDEX_V(p_param,VS::ENV_FX_PARAM_MAX,Variant());
- const Environment * env = environment_owner.get(p_env);
- ERR_FAIL_COND_V(!env,Variant());
- return env->fx_param[p_param];
-
-}
-
-
-RID RasterizerDummy::sampled_light_dp_create(int p_width,int p_height) {
-
- return sampled_light_owner.make_rid(memnew(SampledLight));
-}
-
-void RasterizerDummy::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) {
-
-
-}
-
-
-/*MISC*/
-
-bool RasterizerDummy::is_texture(const RID& p_rid) const {
-
- return texture_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_material(const RID& p_rid) const {
-
- return material_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_mesh(const RID& p_rid) const {
-
- return mesh_owner.owns(p_rid);
-}
-
-bool RasterizerDummy::is_immediate(const RID& p_rid) const {
-
- return immediate_owner.owns(p_rid);
-}
-
-bool RasterizerDummy::is_multimesh(const RID& p_rid) const {
-
- return multimesh_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_particles(const RID &p_beam) const {
-
- return particles_owner.owns(p_beam);
-}
-
-bool RasterizerDummy::is_light(const RID& p_rid) const {
-
- return light_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_light_instance(const RID& p_rid) const {
-
- return light_instance_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_particles_instance(const RID& p_rid) const {
-
- return particles_instance_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_skeleton(const RID& p_rid) const {
-
- return skeleton_owner.owns(p_rid);
-}
-bool RasterizerDummy::is_environment(const RID& p_rid) const {
-
- return environment_owner.owns(p_rid);
-}
-
-bool RasterizerDummy::is_canvas_light_occluder(const RID& p_rid) const {
-
- return false;
-}
-
-bool RasterizerDummy::is_shader(const RID& p_rid) const {
-
- return false;
-}
-
-void RasterizerDummy::free(const RID& p_rid) {
-
- if (texture_owner.owns(p_rid)) {
-
- // delete the texture
- Texture *texture = texture_owner.get(p_rid);
- texture_owner.free(p_rid);
- memdelete(texture);
-
- } else if (shader_owner.owns(p_rid)) {
-
- // delete the texture
- Shader *shader = shader_owner.get(p_rid);
- shader_owner.free(p_rid);
- memdelete(shader);
-
- } else if (material_owner.owns(p_rid)) {
-
- Material *material = material_owner.get( p_rid );
- material_owner.free(p_rid);
- memdelete(material);
-
- } else if (mesh_owner.owns(p_rid)) {
-
- Mesh *mesh = mesh_owner.get(p_rid);
-
- for (int i=0;i<mesh->surfaces.size();i++) {
-
- memdelete( mesh->surfaces[i] );
- };
-
- mesh->surfaces.clear();
- mesh_owner.free(p_rid);
- memdelete(mesh);
-
- } else if (multimesh_owner.owns(p_rid)) {
-
- MultiMesh *multimesh = multimesh_owner.get(p_rid);
- multimesh_owner.free(p_rid);
- memdelete(multimesh);
-
- } else if (immediate_owner.owns(p_rid)) {
-
- Immediate *immediate = immediate_owner.get(p_rid);
- immediate_owner.free(p_rid);
- memdelete(immediate);
-
- } else if (particles_owner.owns(p_rid)) {
-
- Particles *particles = particles_owner.get(p_rid);
- particles_owner.free(p_rid);
- memdelete(particles);
- } else if (particles_instance_owner.owns(p_rid)) {
-
- ParticlesInstance *particles_isntance = particles_instance_owner.get(p_rid);
- particles_instance_owner.free(p_rid);
- memdelete(particles_isntance);
-
- } else if (skeleton_owner.owns(p_rid)) {
-
- Skeleton *skeleton = skeleton_owner.get( p_rid );
- skeleton_owner.free(p_rid);
- memdelete(skeleton);
-
- } else if (light_owner.owns(p_rid)) {
-
- Light *light = light_owner.get( p_rid );
- light_owner.free(p_rid);
- memdelete(light);
-
- } else if (light_instance_owner.owns(p_rid)) {
-
- LightInstance *light_instance = light_instance_owner.get( p_rid );
- light_instance_owner.free(p_rid);
- memdelete( light_instance );
-
-
- } else if (environment_owner.owns(p_rid)) {
-
- Environment *env = environment_owner.get( p_rid );
- environment_owner.free(p_rid);
- memdelete( env );
- } else if (sampled_light_owner.owns(p_rid)) {
-
- SampledLight *sampled_light = sampled_light_owner.get( p_rid );
- ERR_FAIL_COND(!sampled_light);
-
- sampled_light_owner.free(p_rid);
- memdelete( sampled_light );
-
- };
-}
-
-
-void RasterizerDummy::custom_shade_model_set_shader(int p_model, RID p_shader) {
-
-
-};
-
-RID RasterizerDummy::custom_shade_model_get_shader(int p_model) const {
-
- return RID();
-};
-
-void RasterizerDummy::custom_shade_model_set_name(int p_model, const String& p_name) {
-
-};
-
-String RasterizerDummy::custom_shade_model_get_name(int p_model) const {
-
- return String();
-};
-
-void RasterizerDummy::custom_shade_model_set_param_info(int p_model, const List<PropertyInfo>& p_info) {
-
-};
-
-void RasterizerDummy::custom_shade_model_get_param_info(int p_model, List<PropertyInfo>* p_info) const {
-
-};
-
-
-
-void RasterizerDummy::init() {
-
-
-}
-
-void RasterizerDummy::finish() {
-
-
-}
-
-int RasterizerDummy::get_render_info(VS::RenderInfo p_info) {
-
- return 0;
-}
-
-bool RasterizerDummy::needs_to_draw_next_frame() const {
-
- return false;
-}
-
-
-bool RasterizerDummy::has_feature(VS::Features p_feature) const {
-
- return false;
-
-}
-
-void RasterizerDummy::restore_framebuffer() {
-
-}
-
-RasterizerDummy::RasterizerDummy() {
-
-};
-
-RasterizerDummy::~RasterizerDummy() {
-
-};
diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h
deleted file mode 100644
index cac36eb6fc..0000000000
--- a/servers/visual/rasterizer_dummy.h
+++ /dev/null
@@ -1,791 +0,0 @@
-/*************************************************************************/
-/* rasterizer_dummy.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifndef RASTERIZER_DUMMY_H
-#define RASTERIZER_DUMMY_H
-
-#include "servers/visual/rasterizer.h"
-
-
-#include "image.h"
-#include "rid.h"
-#include "servers/visual_server.h"
-#include "list.h"
-#include "map.h"
-#include "camera_matrix.h"
-#include "sort.h"
-
-
-#include "servers/visual/particle_system_sw.h"
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class RasterizerDummy : public Rasterizer {
-
- struct Texture {
-
- uint32_t flags;
- int width,height;
- Image::Format format;
- Image image[6];
- Texture() {
-
- flags=width=height=0;
- format=Image::FORMAT_GRAYSCALE;
- }
-
- ~Texture() {
-
- }
- };
-
- mutable RID_Owner<Texture> texture_owner;
-
- struct Shader {
-
- String vertex_code;
- String fragment_code;
- String light_code;
- VS::ShaderMode mode;
- Map<StringName,Variant> params;
- int fragment_line;
- int vertex_line;
- int light_line;
- bool valid;
- bool has_alpha;
- bool use_world_transform;
-
- };
-
- mutable RID_Owner<Shader> shader_owner;
-
-
- struct Material {
-
- bool flags[VS::MATERIAL_FLAG_MAX];
-
- VS::MaterialDepthDrawMode depth_draw_mode;
-
- VS::MaterialBlendMode blend_mode;
-
- float line_width;
- float point_size;
-
- RID shader; // shader material
-
- Map<StringName,Variant> shader_params;
-
-
- Material() {
-
-
- for(int i=0;i<VS::MATERIAL_FLAG_MAX;i++)
- flags[i]=false;
- flags[VS::MATERIAL_FLAG_VISIBLE]=true;
-
- depth_draw_mode=VS::MATERIAL_DEPTH_DRAW_OPAQUE_ONLY;
- line_width=1;
- blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
- point_size = 1.0;
-
- }
- };
- mutable RID_Owner<Material> material_owner;
-
- void _material_check_alpha(Material *p_material);
-
-
- struct Geometry {
-
- enum Type {
- GEOMETRY_INVALID,
- GEOMETRY_SURFACE,
- GEOMETRY_POLY,
- GEOMETRY_PARTICLES,
- GEOMETRY_MULTISURFACE,
- };
-
- Type type;
- RID material;
- bool has_alpha;
- bool material_owned;
-
- Geometry() { has_alpha=false; material_owned = false; }
- virtual ~Geometry() {};
- };
-
- struct GeometryOwner {
-
- virtual ~GeometryOwner() {}
- };
-
- class Mesh;
-
- struct Surface : public Geometry {
-
- Array data;
- Array morph_data;
-
- bool packed;
- bool alpha_sort;
- int morph_target_count;
- AABB aabb;
-
- VS::PrimitiveType primitive;
-
- uint32_t format;
- uint32_t morph_format;
-
- Surface() {
-
- packed=false;
- morph_target_count=0;
- material_owned=false;
- format=0;
- morph_format=0;
-
- primitive=VS::PRIMITIVE_POINTS;
- }
-
- ~Surface() {
-
- }
- };
-
-
- struct Mesh {
-
- bool active;
- Vector<Surface*> surfaces;
- int morph_target_count;
- VS::MorphTargetMode morph_target_mode;
- AABB custom_aabb;
-
- mutable uint64_t last_pass;
- Mesh() {
- morph_target_mode=VS::MORPH_MODE_NORMALIZED;
- morph_target_count=0;
- last_pass=0;
- active=false;
- }
- };
- mutable RID_Owner<Mesh> mesh_owner;
-
- struct MultiMesh;
-
- struct MultiMeshSurface : public Geometry {
-
- Surface *surface;
- MultiMeshSurface() { type=GEOMETRY_MULTISURFACE; }
- };
-
- struct MultiMesh : public GeometryOwner {
-
- struct Element {
-
- Transform xform;
- Color color;
- };
-
- AABB aabb;
- RID mesh;
- int visible;
-
- //IDirect3DVertexBuffer9* instance_buffer;
- Vector<Element> elements;
-
- MultiMesh() {
- visible=-1;
- }
-
-
- };
-
-
- mutable RID_Owner<MultiMesh> multimesh_owner;
-
- struct Immediate {
-
-
- RID material;
- int empty;
- };
-
- mutable RID_Owner<Immediate> immediate_owner;
-
- struct Particles : public Geometry {
-
- ParticleSystemSW data; // software particle system
-
- Particles() {
- type=GEOMETRY_PARTICLES;
-
- }
- };
-
- mutable RID_Owner<Particles> particles_owner;
-
- struct ParticlesInstance : public GeometryOwner {
-
- RID particles;
-
- ParticleSystemProcessSW particles_process;
- Transform transform;
-
- ParticlesInstance() { }
- };
-
- mutable RID_Owner<ParticlesInstance> particles_instance_owner;
- ParticleSystemDrawInfoSW particle_draw_info;
-
- struct Skeleton {
-
- Vector<Transform> bones;
-
- };
-
- mutable RID_Owner<Skeleton> skeleton_owner;
-
-
- struct Light {
-
- VS::LightType type;
- float vars[VS::LIGHT_PARAM_MAX];
- Color colors[3];
- bool shadow_enabled;
- RID projector;
- bool volumetric_enabled;
- Color volumetric_color;
-
-
- Light() {
-
- vars[VS::LIGHT_PARAM_SPOT_ATTENUATION]=1;
- vars[VS::LIGHT_PARAM_SPOT_ANGLE]=45;
- vars[VS::LIGHT_PARAM_ATTENUATION]=1.0;
- vars[VS::LIGHT_PARAM_ENERGY]=1.0;
- vars[VS::LIGHT_PARAM_RADIUS]=1.0;
- vars[VS::LIGHT_PARAM_SHADOW_Z_OFFSET]=0.05;
-
- colors[VS::LIGHT_COLOR_DIFFUSE]=Color(1,1,1);
- colors[VS::LIGHT_COLOR_SPECULAR]=Color(1,1,1);
- shadow_enabled=false;
- volumetric_enabled=false;
- }
- };
-
-
- struct Environment {
-
-
- VS::EnvironmentBG bg_mode;
- Variant bg_param[VS::ENV_BG_PARAM_MAX];
- bool fx_enabled[VS::ENV_FX_MAX];
- Variant fx_param[VS::ENV_FX_PARAM_MAX];
-
- Environment() {
-
- bg_mode=VS::ENV_BG_DEFAULT_COLOR;
- bg_param[VS::ENV_BG_PARAM_COLOR]=Color(0,0,0);
- bg_param[VS::ENV_BG_PARAM_TEXTURE]=RID();
- bg_param[VS::ENV_BG_PARAM_CUBEMAP]=RID();
- bg_param[VS::ENV_BG_PARAM_ENERGY]=1.0;
-
- for(int i=0;i<VS::ENV_FX_MAX;i++)
- fx_enabled[i]=false;
-
- fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]=1;
- fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM]=0.0;
- fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD]=0.5;
- fx_param[VS::ENV_FX_PARAM_DOF_BLUR_PASSES]=1;
- fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN]=100.0;
- fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE]=10.0;
- fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]=0.4;
- fx_param[VS::ENV_FX_PARAM_HDR_WHITE]=1.0;
- fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]=0.95;
- fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]=0.2;
- fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE]=0.4;
- fx_param[VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE]=8.0;
- fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED]=0.5;
- fx_param[VS::ENV_FX_PARAM_FOG_BEGIN]=100.0;
- fx_param[VS::ENV_FX_PARAM_FOG_ATTENUATION]=1.0;
- fx_param[VS::ENV_FX_PARAM_FOG_BEGIN_COLOR]=Color(0,0,0);
- fx_param[VS::ENV_FX_PARAM_FOG_END_COLOR]=Color(0,0,0);
- fx_param[VS::ENV_FX_PARAM_FOG_BG]=true;
- fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS]=1.0;
- fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST]=1.0;
- fx_param[VS::ENV_FX_PARAM_BCS_SATURATION]=1.0;
-
-
- }
-
- };
-
- mutable RID_Owner<Environment> environment_owner;
-
- struct SampledLight {
-
- int w,h;
- };
-
- mutable RID_Owner<SampledLight> sampled_light_owner;
-
- struct ShadowBuffer;
-
- struct LightInstance {
-
- struct SplitInfo {
-
- CameraMatrix camera;
- Transform transform;
- float near;
- float far;
- };
-
- RID light;
- Light *base;
- Transform transform;
- CameraMatrix projection;
-
- Transform custom_transform;
- CameraMatrix custom_projection;
-
- Vector3 light_vector;
- Vector3 spot_vector;
- float linear_att;
-
-
- LightInstance() { linear_att=1.0; }
-
- };
-
- mutable RID_Owner<Light> light_owner;
- mutable RID_Owner<LightInstance> light_instance_owner;
-
-
- RID default_material;
-
-
-
-
-public:
-
- /* TEXTURE API */
-
- virtual RID texture_create();
- virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=VS::TEXTURE_FLAGS_DEFAULT);
- virtual void texture_set_data(RID p_texture,const Image& p_image,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT);
- virtual Image texture_get_data(RID p_texture,VS::CubeMapSide p_cube_side=VS::CUBEMAP_LEFT) const;
- virtual void texture_set_flags(RID p_texture,uint32_t p_flags);
- virtual uint32_t texture_get_flags(RID p_texture) const;
- virtual Image::Format texture_get_format(RID p_texture) const;
- virtual uint32_t texture_get_width(RID p_texture) const;
- virtual uint32_t texture_get_height(RID p_texture) const;
- virtual bool texture_has_alpha(RID p_texture) const;
- virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
- virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
-
- virtual void texture_set_path(RID p_texture,const String& p_path) {}
- virtual String texture_get_path(RID p_texture) const { return String(); }
- virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {}
-
- virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable) {}
-
- /* SHADER API */
-
- virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL);
-
- virtual void shader_set_mode(RID p_shader,VS::ShaderMode p_mode);
- virtual VS::ShaderMode shader_get_mode(RID p_shader) const;
-
- virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs=0,int p_fragment_ofs=0,int p_light_ofs=0);
- virtual String shader_get_fragment_code(RID p_shader) const;
- virtual String shader_get_vertex_code(RID p_shader) const;
- virtual String shader_get_light_code(RID p_shader) const;
-
- virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
-
-
- virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
- virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
-
- virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name);
-
- /* COMMON MATERIAL API */
-
- virtual RID material_create();
-
- virtual void material_set_shader(RID p_shader_material, RID p_shader);
- virtual RID material_get_shader(RID p_shader_material) const;
-
- virtual void material_set_param(RID p_material, const StringName& p_param, const Variant& p_value);
- virtual Variant material_get_param(RID p_material, const StringName& p_param) const;
-
- virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag,bool p_enabled);
- virtual bool material_get_flag(RID p_material,VS::MaterialFlag p_flag) const;
-
- virtual void material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode);
- virtual VS::MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const;
-
- virtual void material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode);
- virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const;
-
- virtual void material_set_line_width(RID p_material,float p_line_width);
- virtual float material_get_line_width(RID p_material) const;
-
- /* MESH API */
-
-
- virtual RID mesh_create();
-
- virtual void mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alpha_sort=false);
- virtual Array mesh_get_surface_arrays(RID p_mesh,int p_surface) const;
- virtual Array mesh_get_surface_morph_arrays(RID p_mesh,int p_surface) const;
- virtual void mesh_add_custom_surface(RID p_mesh,const Variant& p_dat);
-
- virtual void mesh_set_morph_target_count(RID p_mesh,int p_amount);
- virtual int mesh_get_morph_target_count(RID p_mesh) const;
-
- virtual void mesh_set_morph_target_mode(RID p_mesh,VS::MorphTargetMode p_mode);
- virtual VS::MorphTargetMode mesh_get_morph_target_mode(RID p_mesh) const;
-
- virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material,bool p_owned=false);
- virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
-
- virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const;
- virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const;
- virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
- virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
-
- virtual void mesh_remove_surface(RID p_mesh,int p_index);
- virtual int mesh_get_surface_count(RID p_mesh) const;
-
- virtual AABB mesh_get_aabb(RID p_mesh,RID p_skeleton=RID()) const;
-
- virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
- virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
-
-
- /* MULTIMESH API */
-
- virtual RID multimesh_create();
-
- virtual void multimesh_set_instance_count(RID p_multimesh,int p_count);
- virtual int multimesh_get_instance_count(RID p_multimesh) const;
-
- virtual void multimesh_set_mesh(RID p_multimesh,RID p_mesh);
- virtual void multimesh_set_aabb(RID p_multimesh,const AABB& p_aabb);
- virtual void multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform& p_transform);
- virtual void multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color);
-
- virtual RID multimesh_get_mesh(RID p_multimesh) const;
- virtual AABB multimesh_get_aabb(RID p_multimesh) const;;
-
- virtual Transform multimesh_instance_get_transform(RID p_multimesh,int p_index) const;
- virtual Color multimesh_instance_get_color(RID p_multimesh,int p_index) const;
-
- virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible);
- virtual int multimesh_get_visible_instances(RID p_multimesh) const;
-
- /* IMMEDIATE API */
-
- virtual RID immediate_create();
- virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID());
- virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex);
- virtual void immediate_normal(RID p_immediate,const Vector3& p_normal);
- virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent);
- virtual void immediate_color(RID p_immediate,const Color& p_color);
- virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv);
- virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv);
- virtual void immediate_end(RID p_immediate);
- virtual void immediate_clear(RID p_immediate);
- virtual void immediate_set_material(RID p_immediate,RID p_material);
- virtual RID immediate_get_material(RID p_immediate) const;
-
- virtual AABB immediate_get_aabb(RID p_mesh) const;
-
- /* PARTICLES API */
-
- virtual RID particles_create();
-
- virtual void particles_set_amount(RID p_particles, int p_amount);
- virtual int particles_get_amount(RID p_particles) const;
-
- virtual void particles_set_emitting(RID p_particles, bool p_emitting);
- virtual bool particles_is_emitting(RID p_particles) const;
-
- virtual void particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility);
- virtual AABB particles_get_visibility_aabb(RID p_particles) const;
-
- virtual void particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents);
- virtual Vector3 particles_get_emission_half_extents(RID p_particles) const;
-
- virtual void particles_set_emission_base_velocity(RID p_particles, const Vector3& p_base_velocity);
- virtual Vector3 particles_get_emission_base_velocity(RID p_particles) const;
-
- virtual void particles_set_emission_points(RID p_particles, const DVector<Vector3>& p_points);
- virtual DVector<Vector3> particles_get_emission_points(RID p_particles) const;
-
- virtual void particles_set_gravity_normal(RID p_particles, const Vector3& p_normal);
- virtual Vector3 particles_get_gravity_normal(RID p_particles) const;
-
- virtual void particles_set_variable(RID p_particles, VS::ParticleVariable p_variable,float p_value);
- virtual float particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable,float p_randomness);
- virtual float particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos);
- virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const;
-
- virtual void particles_set_color_phases(RID p_particles, int p_phases);
- virtual int particles_get_color_phases(RID p_particles) const;
-
- virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color& p_color);
- virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const;
-
- virtual void particles_set_attractors(RID p_particles, int p_attractors);
- virtual int particles_get_attractors(RID p_particles) const;
-
- virtual void particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3& p_pos);
- virtual Vector3 particles_get_attractor_pos(RID p_particles,int p_attractor) const;
-
- virtual void particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force);
- virtual float particles_get_attractor_strength(RID p_particles,int p_attractor) const;
-
- virtual void particles_set_material(RID p_particles, RID p_material,bool p_owned=false);
- virtual RID particles_get_material(RID p_particles) const;
-
- virtual AABB particles_get_aabb(RID p_particles) const;
-
- virtual void particles_set_height_from_velocity(RID p_particles, bool p_enable);
- virtual bool particles_has_height_from_velocity(RID p_particles) const;
-
- virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
- virtual bool particles_is_using_local_coordinates(RID p_particles) const;
-
- /* SKELETON API */
-
- virtual RID skeleton_create();
- virtual void skeleton_resize(RID p_skeleton,int p_bones);
- virtual int skeleton_get_bone_count(RID p_skeleton) const;
- virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform);
- virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone);
-
-
- /* LIGHT API */
-
- virtual RID light_create(VS::LightType p_type);
- virtual VS::LightType light_get_type(RID p_light) const;
-
- virtual void light_set_color(RID p_light,VS::LightColor p_type, const Color& p_color);
- virtual Color light_get_color(RID p_light,VS::LightColor p_type) const;
-
- virtual void light_set_shadow(RID p_light,bool p_enabled);
- virtual bool light_has_shadow(RID p_light) const;
-
- virtual void light_set_volumetric(RID p_light,bool p_enabled);
- virtual bool light_is_volumetric(RID p_light) const;
-
- virtual void light_set_projector(RID p_light,RID p_texture);
- virtual RID light_get_projector(RID p_light) const;
-
- virtual void light_set_var(RID p_light, VS::LightParam p_var, float p_value);
- virtual float light_get_var(RID p_light, VS::LightParam p_var) const;
-
- virtual void light_set_operator(RID p_light,VS::LightOp p_op);
- virtual VS::LightOp light_get_operator(RID p_light) const;
-
- virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode);
- virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) const;
-
-
- virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode);
- virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) const;
- virtual void light_directional_set_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param, float p_value);
- virtual float light_directional_get_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param) const;
-
- virtual AABB light_get_aabb(RID p_poly) const;
-
-
- virtual RID light_instance_create(RID p_light);
- virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform);
-
- virtual bool light_instance_has_shadow(RID p_light_instance) const;
- virtual bool light_instance_assign_shadow(RID p_light_instance);
- virtual ShadowType light_instance_get_shadow_type(RID p_light_instance) const;
- virtual int light_instance_get_shadow_passes(RID p_light_instance) const;
- virtual bool light_instance_get_pssm_shadow_overlap(RID p_light_instance) const;
- virtual void light_instance_set_custom_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near=0,float p_split_far=0);
- virtual int light_instance_get_shadow_size(RID p_light_instance, int p_index=0) const { return 1; }
-
- virtual ShadowType light_instance_get_shadow_type(RID p_light_instance,bool p_far=false) const;
- virtual void light_instance_set_shadow_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near=0,float p_split_far=0);
-
- virtual void shadow_clear_near();
- virtual bool shadow_allocate_near(RID p_light);
- virtual bool shadow_allocate_far(RID p_light);
-
-
- /* PARTICLES INSTANCE */
-
- virtual RID particles_instance_create(RID p_particles);
- virtual void particles_instance_set_transform(RID p_particles_instance,const Transform& p_transform);
-
- /* VIEWPORT */
-
- virtual RID viewport_data_create();
-
- virtual RID render_target_create();
- virtual void render_target_set_size(RID p_render_target, int p_width, int p_height);
- virtual RID render_target_get_texture(RID p_render_target) const;
- virtual bool render_target_renedered_in_frame(RID p_render_target);
-
- /* RENDER API */
- /* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
- virtual void begin_frame();
-
- virtual void set_viewport(const VS::ViewportRect& p_viewport);
- virtual void set_render_target(RID p_render_target,bool p_transparent_bg=false,bool p_vflip=false);
- virtual void clear_viewport(const Color& p_color);
- virtual void capture_viewport(Image* r_capture);
-
-
- virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug);
- virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass );
-
- virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint);
-
- virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls
-
-
- virtual void add_mesh( const RID& p_mesh, const InstanceData *p_data);
- virtual void add_multimesh( const RID& p_multimesh, const InstanceData *p_data);
- virtual void add_immediate( const RID& p_immediate, const InstanceData *p_data) {}
- virtual void add_particles( const RID& p_particle_instance, const InstanceData *p_data);
-
- virtual void end_scene();
- virtual void end_shadow_map();
-
- virtual void end_frame();
-
- /* CANVAS API */
-
- virtual void begin_canvas_bg();
- virtual void canvas_begin();
- virtual void canvas_disable_blending();
- virtual void canvas_set_opacity(float p_opacity);
- virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode);
- virtual void canvas_begin_rect(const Matrix32& p_transform);
- virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect);
- virtual void canvas_end_rect();
- virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased);
- virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate);
- virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
- 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,int p_z,const Color& p_modulate,CanvasLight *p_light);
-
- virtual RID canvas_light_occluder_create();
- virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines);
-
- virtual RID canvas_light_shadow_buffer_create(int p_width);
- virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache);
-
- virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow);
-
- /* ENVIRONMENT */
-
- virtual RID environment_create();
-
- virtual void environment_set_background(RID p_env,VS::EnvironmentBG p_bg);
- virtual VS::EnvironmentBG environment_get_background(RID p_env) const;
-
- virtual void environment_set_background_param(RID p_env,VS::EnvironmentBGParam p_param, const Variant& p_value);
- virtual Variant environment_get_background_param(RID p_env,VS::EnvironmentBGParam p_param) const;
-
- virtual void environment_set_enable_fx(RID p_env,VS::EnvironmentFx p_effect,bool p_enabled);
- virtual bool environment_is_fx_enabled(RID p_env,VS::EnvironmentFx p_effect) const;
-
- virtual void environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant& p_value);
- virtual Variant environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const;
-
- /* SAMPLED LIGHT */
- virtual RID sampled_light_dp_create(int p_width,int p_height);
- virtual void sampled_light_dp_update(RID p_sampled_light,const Color *p_data,float p_multiplier);
-
-
- /*MISC*/
-
- virtual bool is_texture(const RID& p_rid) const;
- virtual bool is_material(const RID& p_rid) const;
- virtual bool is_mesh(const RID& p_rid) const;
- virtual bool is_immediate(const RID& p_rid) const;
- virtual bool is_multimesh(const RID& p_rid) const;
- virtual bool is_particles(const RID &p_beam) const;
-
- virtual bool is_light(const RID& p_rid) const;
- virtual bool is_light_instance(const RID& p_rid) const;
- virtual bool is_particles_instance(const RID& p_rid) const;
- virtual bool is_skeleton(const RID& p_rid) const;
- virtual bool is_environment(const RID& p_rid) const;
- virtual bool is_canvas_light_occluder(const RID& p_rid) const;
-
- virtual bool is_shader(const RID& p_rid) const;
-
- virtual void free(const RID& p_rid);
-
- virtual void custom_shade_model_set_shader(int p_model, RID p_shader);
- virtual RID custom_shade_model_get_shader(int p_model) const;
- virtual void custom_shade_model_set_name(int p_model, const String& p_name);
- virtual String custom_shade_model_get_name(int p_model) const;
- virtual void custom_shade_model_set_param_info(int p_model, const List<PropertyInfo>& p_info);
- virtual void custom_shade_model_get_param_info(int p_model, List<PropertyInfo>* p_info) const;
-
-
- virtual void init();
- virtual void finish();
-
- virtual int get_render_info(VS::RenderInfo p_info);
-
- virtual bool needs_to_draw_next_frame() const;
-
- virtual bool has_feature(VS::Features p_feature) const;
-
- virtual void restore_framebuffer();
-
- RasterizerDummy();
- virtual ~RasterizerDummy();
-};
-
-
-#endif // RASTERIZER_DUMMY_H
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index fdf3cb622d..287293a437 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -46,7 +46,7 @@ static bool _is_hex(CharType c) {
const char * ShaderLanguage::token_names[TK_MAX]={
"EMPTY",
- "INDENTIFIER",
+ "IDENTIFIER",
"TRUE",
"FALSE",
"REAL_CONSTANT",
@@ -97,401 +97,402 @@ const char * ShaderLanguage::token_names[TK_MAX]={
"ERROR",
};
-ShaderLanguage::Token ShaderLanguage::read_token(const CharType* p_text,int p_len,int &r_line,int &r_chars) {
+String ShaderLanguage::get_token_text(Token p_token) {
-#define GETCHAR(m_idx) ((m_idx<p_len)?p_text[m_idx]:CharType(0))
-
- r_chars=1; //by default everything eats one char
- switch(GETCHAR(0)) {
-
- case '\t':
- case '\r':
- case ' ':
- return Token();
- case '\n':
- r_line++;
- return Token();
- case '/': {
+ String name=token_names[p_token.type];
+ if (p_token.type==TK_INT_CONSTANT || p_token.type==TK_REAL_CONSTANT) {
+ name+="("+rtos(p_token.constant)+")";
+ } else if (p_token.type==TK_IDENTIFIER) {
+ name+="("+String(p_token.text)+")";
+ }
- switch(GETCHAR(1)) {
- case '*': { // block comment
+ return name;
+}
+ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type,const StringName& p_text) {
- while(true) {
- if (GETCHAR(r_chars+1)==0) {
- r_chars+=1;
- break;
- } if (GETCHAR(r_chars+1)=='*' && GETCHAR(r_chars+2)=='/') {
- r_chars+=3;
- break;
- } if (GETCHAR(r_chars+1)=='\n') {
- r_line++;
- }
+ Token tk;
+ tk.type=p_type;
+ tk.text=p_text;
+ tk.line=tk_line;
+ return tk;
+}
- r_chars++;
- }
- return Token();
+ShaderLanguage::Token ShaderLanguage::_get_token() {
- } break;
- case '/': { // line comment skip
+#define GETCHAR(m_idx) ((char_idx<code.length())?code[char_idx]:CharType(0))
- while(GETCHAR(r_chars+1)!='\n' && GETCHAR(r_chars+1)!=0) {
- r_chars++;
- }
- r_chars++;
- //r_line++;
+ while(true) {
+ char_idx++;
+ switch(GETCHAR(-1)) {
- return Token();
+ case '\t':
+ case '\r':
+ case ' ':
+ continue;
+ case '\n':
+ tk_line++;
+ continue;
+ case '/': {
- } break;
- case '=': { // diveq
+ switch(GETCHAR(0)) {
+ case '*': { // block comment
- r_chars=2;
- return Token(TK_OP_ASSIGN_DIV);
+ char_idx++;
+ while(true) {
+ if (GETCHAR(0)==0) {
+ return _make_token(TK_EOF);
+ } if (GETCHAR(0)=='*' && GETCHAR(1)=='/') {
+ char_idx+=2;
+ break;
+ } if (GETCHAR(r_chars+1)=='\n') {
+ tk_line++;
+ }
- } break;
- default:
- return Token(TK_OP_DIV);
+ char_idx++;
+ }
- }
- } break;
- case '=': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_EQUAL);
- }
+ } break;
+ case '/': { // line comment skip
- return Token(TK_OP_ASSIGN);
- } break;
- case '<': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_LESS_EQUAL);
- } /*else if (GETCHAR(1)=='<') {
- r_chars++;
- if (GETCHAR(2)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_SHIFT_LEFT);
- }
+ while(true) {
+ if (GETCHAR(0)=='\n') {
+ char_idx++;
+ break;
+ }
+ if (GETCHAR(0)==0) {
+ return _make_token(TK_EOF);
+ }
+ char_idx++;
+ }
- return Token(TK_OP_SHIFT_LEFT);
- }*/
+ } break;
+ case '=': { // diveq
- return Token(TK_OP_LESS);
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_DIV);
- } break;
- case '>': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_GREATER_EQUAL);
- }/* else if (GETCHAR(1)=='<') {
- r_chars++;
- if (GETCHAR(2)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_SHIFT_RIGHT);
+ } break;
+ default:
+ return _make_token(TK_OP_DIV);
}
- return Token(TK_OP_SHIFT_RIGHT);
- }*/
+ continue; //a comment, continue to next token
+ } break;
+ case '=': {
- return Token(TK_OP_GREATER);
-
- } break;
- case '!': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_NOT_EQUAL);
- }
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_EQUAL);
+ }
- return Token(TK_OP_NOT);
+ return _make_token(TK_OP_ASSIGN);
+
+ } break;
+ case '<': {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_LESS_EQUAL);
+ } else if (GETCHAR(0)=='<') {
+ char_idx++;
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_SHIFT_LEFT);
+ }
- } break;
- //case '"' //string - no strings in shader
- //case '\'' //string - no strings in shader
- case '{':
- return Token(TK_CURLY_BRACKET_OPEN);
- case '}':
- return Token(TK_CURLY_BRACKET_CLOSE);
- //case '[':
- // return Token(TK_BRACKET_OPEN);
- //case ']':
- // return Token(TK_BRACKET_CLOSE);
- case '(':
- return Token(TK_PARENTHESIS_OPEN);
- case ')':
- return Token(TK_PARENTHESIS_CLOSE);
- case ',':
- return Token(TK_COMMA);
- case ';':
- return Token(TK_SEMICOLON);
- //case '?':
- // return Token(TK_QUESTION_MARK);
- //case ':':
- // return Token(TK_COLON); //for methods maybe but now useless.
- //case '^':
- // return Token(TK_OP_BIT_XOR);
- //case '~':
- // return Token(TK_OP_BIT_INVERT);
- case '&': {
-
- if (GETCHAR(1)=='&') {
-
- r_chars++;
- return Token(TK_OP_AND);
- }
+ return _make_token(TK_OP_SHIFT_LEFT);
+ }
- return Token(TK_ERROR,"Unknown character");
+ return _make_token(TK_OP_LESS);
+
+ } break;
+ case '>': {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_GREATER_EQUAL);
+ } else if (GETCHAR(0)=='<') {
+ char_idx++;;
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_SHIFT_RIGHT);
+ }
-/*
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_BIT_AND);
- } else if (GETCHAR(1)=='&') {
- r_chars++;
- return Token(TK_OP_AND);
- }
- return TK_OP_BIT_AND;*/
- } break;
- case '|': {
+ return _make_token(TK_OP_SHIFT_RIGHT);
+ }
- if (GETCHAR(1)=='|') {
+ return _make_token(TK_OP_GREATER);
- r_chars++;
- return Token(TK_OP_OR);
- }
+ } break;
+ case '!': {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_NOT_EQUAL);
+ }
- return Token(TK_ERROR,"Unknown character");
+ return _make_token(TK_OP_NOT);
+
+ } break;
+ //case '"' //string - no strings in shader
+ //case '\'' //string - no strings in shader
+ case '{':
+ return _make_token(TK_CURLY_BRACKET_OPEN);
+ case '}':
+ return _make_token(TK_CURLY_BRACKET_CLOSE);
+ case '[':
+ return _make_token(TK_BRACKET_OPEN);
+ case ']':
+ return _make_token(TK_BRACKET_CLOSE);
+ case '(':
+ return _make_token(TK_PARENTHESIS_OPEN);
+ case ')':
+ return _make_token(TK_PARENTHESIS_CLOSE);
+ case ',':
+ return _make_token(TK_COMMA);
+ case ';':
+ return _make_token(TK_SEMICOLON);
+ case '?':
+ return _make_token(TK_QUESTION);
+ case ':':
+ return _make_token(TK_COLON);
+ case '^':
+ return _make_token(TK_OP_BIT_XOR);
+ case '~':
+ return _make_token(TK_OP_BIT_INVERT);
+ case '&': {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_AND);
+ } else if (GETCHAR(0)=='&') {
+ char_idx++;
+ return _make_token(TK_OP_AND);
+ }
+ return _make_token(TK_OP_BIT_AND);
+ } break;
+ case '|': {
+
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_OR);
+ } else if (GETCHAR(0)=='|') {
+ char_idx++;
+ return _make_token(TK_OP_OR);
+ }
+ return _make_token(TK_OP_BIT_OR);
- /*
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_BIT_OR);
- } else if (GETCHAR(1)=='|') {
- r_chars++;
- return Token(TK_OP_OR);
- }
- return TK_OP_BIT_OR;
- */
- } break;
- case '*': {
+ } break;
+ case '*': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_MUL);
- }
- return TK_OP_MUL;
- } break;
- case '+': {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_MUL);
+ }
+ return _make_token(TK_OP_MUL);
+ } break;
+ case '+': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_ADD);
- } /*else if (GETCHAR(1)=='+') {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_ADD);
+ } else if (GETCHAR(0)=='+') {
- r_chars++;
- return Token(TK_OP_PLUS_PLUS);
- }*/
+ char_idx++;
+ return _make_token(TK_OP_INCREMENT);
+ }
- return TK_OP_ADD;
- } break;
- case '-': {
+ return _make_token(TK_OP_ADD);
+ } break;
+ case '-': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_SUB);
- }/* else if (GETCHAR(1)=='-') {
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_SUB);
+ }else if (GETCHAR(0)=='-') {
- r_chars++;
- return Token(TK_OP_MINUS_MINUS);
- }*/
+ char_idx++;
+ return _make_token(TK_OP_DECREMENT);
+ }
- return TK_OP_SUB;
- } break;
- /*case '%': {
+ return _make_token(TK_OP_SUB);
+ } break;
+ case '%': {
- if (GETCHAR(1)=='=') {
- r_chars++;
- return Token(TK_OP_ASSIGN_MOD);
- }
+ if (GETCHAR(0)=='=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_MOD);
+ }
- return TK_OP_MOD;
- } break;*/
- default: {
+ return _make_token(TK_OP_MOD);
+ } break;
+ default: {
- if (_is_number(GETCHAR(0)) || (GETCHAR(0)=='.' && _is_number(GETCHAR(1)))) {
- // parse number
- bool period_found=false;
- bool exponent_found=false;
- bool hexa_found=false;
- bool sign_found=false;
+ char_idx--; //go back one, since we have no idea what this is
- String str;
- int i=0;
+ if (_is_number(GETCHAR(0)) || (GETCHAR(0)=='.' && _is_number(GETCHAR(1)))) {
+ // parse number
+ bool period_found=false;
+ bool exponent_found=false;
+ bool hexa_found=false;
+ bool sign_found=false;
+ bool minus_exponent_found=false;
- while(true) {
- if (GETCHAR(i)=='.') {
- if (period_found || exponent_found)
- return Token(TK_ERROR,"Invalid numeric constant");
- period_found=true;
- } else if (GETCHAR(i)=='x') {
- if (hexa_found || str.length()!=1 || str[0]!='0')
- return Token(TK_ERROR,"Invalid numeric constant");
- hexa_found=true;
- } else if (GETCHAR(i)=='e') {
- if (hexa_found || exponent_found)
- return Token(TK_ERROR,"Invalid numeric constant");
- exponent_found=true;
- } else if (_is_number(GETCHAR(i))) {
- //all ok
- } else if (hexa_found && _is_hex(GETCHAR(i))) {
-
- } else if ((GETCHAR(i)=='-' || GETCHAR(i)=='+') && exponent_found) {
- if (sign_found)
- return Token(TK_ERROR,"Invalid numeric constant");
- sign_found=true;
- } else
- break;
+ String str;
+ int i=0;
- str+=CharType(GETCHAR(i));
- i++;
- }
+ while(true) {
+ if (GETCHAR(i)=='.') {
+ if (period_found || exponent_found)
+ return _make_token(TK_ERROR,"Invalid numeric constant");
+ period_found=true;
+ } else if (GETCHAR(i)=='x') {
+ if (hexa_found || str.length()!=1 || str[0]!='0')
+ return _make_token(TK_ERROR,"Invalid numeric constant");
+ hexa_found=true;
+ } else if (GETCHAR(i)=='e') {
+ if (hexa_found || exponent_found)
+ return _make_token(TK_ERROR,"Invalid numeric constant");
+ exponent_found=true;
+ } else if (_is_number(GETCHAR(i))) {
+ //all ok
+ } else if (hexa_found && _is_hex(GETCHAR(i))) {
+
+ } else if ((GETCHAR(i)=='-' || GETCHAR(i)=='+') && exponent_found) {
+ if (sign_found)
+ return _make_token(TK_ERROR,"Invalid numeric constant");
+ sign_found=true;
+ if (GETCHAR(i)=='-')
+ minus_exponent_found=true;
+ } else
+ break;
- if (!_is_number(str[str.length()-1]))
- return Token(TK_ERROR,"Invalid numeric constant");
+ str+=CharType(GETCHAR(i));
+ i++;
+ }
- r_chars+=str.length()-1;
- return Token(TK_REAL_CONSTANT,str);
- /*
- if (period_found)
- return Token(TK_NUMBER_REAL,str);
- else
- return Token(TK_NUMBER_INTEGER,str);*/
+ if (!_is_number(str[str.length()-1]))
+ return _make_token(TK_ERROR,"Invalid numeric constant");
- }
+ char_idx+=str.length()-1;
+ Token tk;
+ if (period_found || minus_exponent_found)
+ tk.type=TK_REAL_CONSTANT;
+ else
+ tk.type=TK_INT_CONSTANT;
- if (GETCHAR(0)=='.') {
- //parse period
- return Token(TK_PERIOD);
- }
+ if (!str.is_valid_float()) {
+ return _make_token(TK_ERROR,"Invalid numeric constant");
+ }
- if (_is_text_char(GETCHAR(0))) {
- // parse identifier
- String str;
- str+=CharType(GETCHAR(0));
+ tk.constant=str.to_double();
+ tk.line=tk_line;
- while(_is_text_char(GETCHAR(r_chars))) {
+ return tk;
- str+=CharType(GETCHAR(r_chars));
- r_chars++;
}
- //see if keyword
- struct _kws { TokenType token; const char *text;};
- static const _kws keyword_list[]={
- {TK_TRUE,"true"},
- {TK_FALSE,"false"},
- {TK_TYPE_VOID,"void"},
- {TK_TYPE_BOOL,"bool"},
- /*{TK_TYPE_INT,"int"},
- {TK_TYPE_INT2,"int2"},
- {TK_TYPE_INT3,"int3"},
- {TK_TYPE_INT4,"int4"},*/
- {TK_TYPE_FLOAT,"float"},
- /*{TK_TYPE_FLOAT2,"float2"},
- {TK_TYPE_FLOAT3,"float3"},
- {TK_TYPE_FLOAT4,"float4"},*/
- {TK_TYPE_VEC2,"vec2"},
- {TK_TYPE_VEC3,"vec3"},
- {TK_TYPE_VEC4,"vec4"},
- {TK_TYPE_TEXTURE,"texture"},
- {TK_TYPE_CUBEMAP,"cubemap"},
- {TK_TYPE_COLOR,"color"},
-
- {TK_TYPE_MAT2,"mat2"},
- /*{TK_TYPE_MAT3,"mat3"},
- {TK_TYPE_MAT4,"mat3"},*/
- {TK_TYPE_MAT3,"mat3"},
- {TK_TYPE_MAT4,"mat4"},
- {TK_CF_IF,"if"},
- {TK_CF_ELSE,"else"},
- /*
- {TK_CF_FOR,"for"},
- {TK_CF_WHILE,"while"},
- {TK_CF_DO,"do"},
- {TK_CF_SWITCH,"switch"},
- {TK_CF_BREAK,"break"},
- {TK_CF_CONTINUE,"continue"},*/
- {TK_CF_RETURN,"return"},
- {TK_UNIFORM,"uniform"},
- {TK_ERROR,NULL}
- };
-
- int idx=0;
-
- while(keyword_list[idx].text) {
-
- if (str==keyword_list[idx].text)
- return Token(keyword_list[idx].token);
- idx++;
+ if (GETCHAR(0)=='.') {
+ //parse period
+ return _make_token(TK_PERIOD);
}
+ if (_is_text_char(GETCHAR(0))) {
+ // parse identifier
+ String str;
+ str+=CharType(GETCHAR(0));
- return Token(TK_INDENTIFIER,str);
- }
-
- if (GETCHAR(0)>32)
- return Token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0))+": '"+String::chr(GETCHAR(0))+"'");
- else
- return Token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0)));
-
- } break;
- }
- ERR_PRINT("BUG");
- return Token();
-}
+ while(_is_text_char(GETCHAR(1))) {
-Error ShaderLanguage::tokenize(const String& p_text,Vector<Token> *p_tokens,String *r_error,int *r_err_line,int *r_err_column) {
-
-
- int len =p_text.length();
- int pos=0;
+ str+=CharType(GETCHAR(1));
+ char_idx++;
+ }
- int line=0;
+ //see if keyword
+ //should be converted to a static map
+ struct _kws { TokenType token; const char *text;};
+ static const _kws keyword_list[]={
+ {TK_TRUE,"true"},
+ {TK_FALSE,"false"},
+ {TK_TYPE_VOID,"void"},
+ {TK_TYPE_BOOL,"bool"},
+ {TK_TYPE_BVEC2,"bvec2"},
+ {TK_TYPE_BVEC3,"bvec3"},
+ {TK_TYPE_BVEC4,"bvec4"},
+ {TK_TYPE_INT,"int"},
+ {TK_TYPE_IVEC2,"ivec2"},
+ {TK_TYPE_IVEC3,"ivec3"},
+ {TK_TYPE_IVEC4,"ivec4"},
+ {TK_TYPE_UINT,"uint"},
+ {TK_TYPE_UVEC2,"uvec2"},
+ {TK_TYPE_UVEC3,"uvec3"},
+ {TK_TYPE_UVEC4,"uvec4"},
+ {TK_TYPE_FLOAT,"float"},
+ {TK_TYPE_VEC2,"vec2"},
+ {TK_TYPE_VEC3,"vec3"},
+ {TK_TYPE_VEC4,"vec4"},
+ {TK_TYPE_MAT2,"mat2"},
+ {TK_TYPE_MAT3,"mat3"},
+ {TK_TYPE_MAT4,"mat4"},
+ {TK_TYPE_SAMPLER2D,"sampler2D"},
+ {TK_TYPE_ISAMPLER2D,"isampler2D"},
+ {TK_TYPE_USAMPLER2D,"usampler2D"},
+ {TK_TYPE_SAMPLERCUBE,"samplerCube"},
+ {TK_PRECISION_LOW,"lowp"},
+ {TK_PRECISION_MID,"mediump"},
+ {TK_PRECISION_HIGH,"highp"},
+ {TK_CF_IF,"if"},
+ {TK_CF_ELSE,"else"},
+ {TK_CF_FOR,"for"},
+ {TK_CF_WHILE,"while"},
+ {TK_CF_DO,"do"},
+ {TK_CF_SWITCH,"switch"},
+ {TK_CF_CASE,"case"},
+ {TK_CF_BREAK,"break"},
+ {TK_CF_CONTINUE,"continue"},
+ {TK_CF_RETURN,"return"},
+ {TK_UNIFORM,"uniform"},
+ {TK_VARYING,"varying"},
+ {TK_RENDER_MODE,"render_mode"},
+ {TK_HINT_WHITE_TEXTURE,"hint_white"},
+ {TK_HINT_BLACK_TEXTURE,"hint_black"},
+ {TK_HINT_NORMAL_TEXTURE,"hint_normal"},
+ {TK_HINT_RANGE,"hint_range"},
+
+ {TK_ERROR,NULL}
+ };
+
+ int idx=0;
+
+ while(keyword_list[idx].text) {
+
+ if (str==keyword_list[idx].text) {
+
+ _make_token(keyword_list[idx].token);
+ }
+ idx++;
+ }
- while(pos<len) {
- int advance=0;
- int prev_line=line;
- Token t = read_token(&p_text[pos],len-pos,line,advance);
- t.line=prev_line;
+ return _make_token(TK_IDENTIFIER,str);
+ }
- if (t.type==TK_ERROR) {
+ if (GETCHAR(0)>32)
+ return _make_token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0))+": '"+String::chr(GETCHAR(0))+"'");
+ else
+ return _make_token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0)));
- if (r_error) {
- *r_error=t.text;
- *r_err_line=line;
- return ERR_COMPILATION_FAILED;
- }
+ } break;
}
-
- if (t.type!=TK_EMPTY)
- p_tokens->push_back(t);
- //if (prev_line!=line)
- // p_tokens->push_back(Token(TK_LINE,itos(line)));
-
- pos+=advance;
-
}
-
- return OK;
-
+ ERR_PRINT("BUG");
+ return Token();
}
+
String ShaderLanguage::lex_debug(const String& p_code) {
+#if 0
Vector<Token> tokens;
String error;
int errline,errcol;
@@ -503,47 +504,64 @@ String ShaderLanguage::lex_debug(const String& p_code) {
}
return ret;
+#endif
+ return String();
}
bool ShaderLanguage::is_token_datatype(TokenType p_type) {
- return
- (p_type==TK_TYPE_VOID) ||
- (p_type==TK_TYPE_BOOL) ||
- (p_type==TK_TYPE_FLOAT) ||
- (p_type==TK_TYPE_VEC2) ||
- (p_type==TK_TYPE_VEC3) ||
- (p_type==TK_TYPE_VEC4) ||
- (p_type==TK_TYPE_COLOR) ||
- (p_type==TK_TYPE_MAT2) ||
- (p_type==TK_TYPE_MAT3) ||
- (p_type==TK_TYPE_MAT4) ||
- (p_type==TK_TYPE_CUBEMAP) ||
- (p_type==TK_TYPE_TEXTURE);
+ return (
+ p_type==TK_TYPE_VOID ||
+ p_type==TK_TYPE_BOOL ||
+ p_type==TK_TYPE_BVEC2 ||
+ p_type==TK_TYPE_BVEC3 ||
+ p_type==TK_TYPE_BVEC4 ||
+ p_type==TK_TYPE_INT ||
+ p_type==TK_TYPE_IVEC2 ||
+ p_type==TK_TYPE_IVEC3 ||
+ p_type==TK_TYPE_IVEC4 ||
+ p_type==TK_TYPE_UINT ||
+ p_type==TK_TYPE_UVEC2 ||
+ p_type==TK_TYPE_UVEC3 ||
+ p_type==TK_TYPE_UVEC4 ||
+ p_type==TK_TYPE_FLOAT ||
+ p_type==TK_TYPE_VEC2 ||
+ p_type==TK_TYPE_VEC3 ||
+ p_type==TK_TYPE_VEC4 ||
+ p_type==TK_TYPE_MAT2 ||
+ p_type==TK_TYPE_MAT3 ||
+ p_type==TK_TYPE_MAT4 ||
+ p_type==TK_TYPE_SAMPLER2D ||
+ p_type==TK_TYPE_ISAMPLER2D ||
+ p_type==TK_TYPE_USAMPLER2D ||
+ p_type==TK_TYPE_SAMPLERCUBE );
}
ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
- switch(p_type) {
+ return DataType(p_type-TK_TYPE_VOID);
+}
- case TK_TYPE_VOID: return TYPE_VOID;
- case TK_TYPE_BOOL: return TYPE_BOOL;
- case TK_TYPE_FLOAT: return TYPE_FLOAT;
- case TK_TYPE_VEC2: return TYPE_VEC2;
- case TK_TYPE_VEC3: return TYPE_VEC3;
- case TK_TYPE_VEC4: return TYPE_VEC4;
- case TK_TYPE_COLOR: return TYPE_VEC4;
- case TK_TYPE_MAT2: return TYPE_MAT2;
- case TK_TYPE_MAT3: return TYPE_MAT3;
- case TK_TYPE_MAT4: return TYPE_MAT4;
- case TK_TYPE_TEXTURE: return TYPE_TEXTURE;
- case TK_TYPE_CUBEMAP: return TYPE_CUBEMAP;
- default: return TYPE_VOID;
- }
- return TYPE_VOID;
+bool ShaderLanguage::is_token_precision(TokenType p_type) {
+
+ return (
+ p_type==TK_PRECISION_LOW ||
+ p_type==TK_PRECISION_MID ||
+ p_type==TK_PRECISION_HIGH );
+
+}
+
+ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) {
+
+ if (p_type==TK_PRECISION_LOW)
+ return PRECISION_LOWP;
+ else if (p_type==TK_PRECISION_HIGH)
+ return PRECISION_HIGHP;
+ else
+ return PRECISION_MEDIUMP;
}
@@ -553,16 +571,28 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
case TYPE_VOID: return "void";
case TYPE_BOOL: return "bool";
+ case TYPE_BVEC2: return "bvec2";
+ case TYPE_BVEC3: return "bvec3";
+ case TYPE_BVEC4: return "bvec4";
+ case TYPE_INT: return "int";
+ case TYPE_IVEC2: return "ivec2";
+ case TYPE_IVEC3: return "ivec3";
+ case TYPE_IVEC4: return "ivec4";
+ case TYPE_UINT: return "uint";
+ case TYPE_UVEC2: return "uvec2";
+ case TYPE_UVEC3: return "uvec3";
+ case TYPE_UVEC4: return "uvec4";
case TYPE_FLOAT: return "float";
case TYPE_VEC2: return "vec2";
case TYPE_VEC3: return "vec3";
- case TYPE_VEC4: return "vec4";
+ case TYPE_VEC4: return "vec5";
case TYPE_MAT2: return "mat2";
case TYPE_MAT3: return "mat3";
case TYPE_MAT4: return "mat4";
- case TYPE_TEXTURE: return "texture";
- case TYPE_CUBEMAP: return "cubemap";
- default: return "";
+ case TYPE_SAMPLER2D: return "sampler2D";
+ case TYPE_ISAMPLER2D: return "isampler2D";
+ case TYPE_USAMPLER2D: return "usampler2D";
+ case TYPE_SAMPLERCUBE: return "samplerCube";
}
return "";
@@ -571,211 +601,488 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
- return
- (p_type==TK_TYPE_BOOL) ||
- (p_type==TK_TYPE_FLOAT) ||
- (p_type==TK_TYPE_VEC2) ||
- (p_type==TK_TYPE_VEC3) ||
- (p_type==TK_TYPE_VEC4) ||
- (p_type==TK_TYPE_COLOR) ||
- (p_type==TK_TYPE_MAT2) ||
- (p_type==TK_TYPE_MAT3) ||
- (p_type==TK_TYPE_MAT4) ||
- (p_type==TK_TYPE_TEXTURE) ||
- (p_type==TK_TYPE_CUBEMAP);
+ return is_token_datatype(p_type) && p_type!=TK_TYPE_VOID;
}
-bool ShaderLanguage::parser_is_at_function(Parser& parser) {
+void ShaderLanguage::clear() {
- return (is_token_datatype(parser.get_token_type(0)) && parser.get_token_type(1)==TK_INDENTIFIER && parser.get_token_type(2)==TK_PARENTHESIS_OPEN);
-}
+ tk_line=0;
+ char_idx=0;
+ error_set=false;
+ error_str="";
+ while(nodes) {
+ Node *n = nodes;
+ nodes=nodes->next;
+ memdelete(n);
+ }
+}
-bool ShaderLanguage::test_existing_identifier(Node *p_node,const StringName p_identifier,bool p_func,bool p_var,bool p_builtin) {
+bool ShaderLanguage::_find_identifier(const BlockNode* p_block,const Map<StringName, DataType> &p_builtin_types,const StringName& p_identifier, DataType *r_data_type, IdentifierType *r_type) {
- Node *node = p_node;
- while(node) {
+ if (p_builtin_types.has(p_identifier)) {
- if (node->type==Node::TYPE_BLOCK) {
+ if (r_data_type) {
+ *r_data_type=p_builtin_types[p_identifier];
+ }
+ if (r_type) {
+ *r_type=IDENTIFIER_BUILTIN_VAR;
+ }
- BlockNode *block = (BlockNode*)node;
- if (block->variables.has(p_identifier))
- return true;
- } else if (node->type==Node::TYPE_PROGRAM) {
+ return true;
+ }
- ProgramNode *program = (ProgramNode*)node;
- for(int i=0;i<program->functions.size();i++) {
+ FunctionNode *function=NULL;
- if (program->functions[i].name==p_identifier) {
- return true;
- }
- }
+ while(p_block) {
- if(program->builtin_variables.has(p_identifier)) {
- return true;
+ if (p_block->variables.has(p_identifier)) {
+ if (r_data_type) {
+ *r_data_type=p_block->variables[p_identifier].type;
}
- if(program->uniforms.has(p_identifier)) {
- return true;
+ if (r_type) {
+ *r_type=IDENTIFIER_LOCAL_VAR;
}
- } else if (node->type==Node::TYPE_FUNCTION) {
-
- FunctionNode *func=(FunctionNode*)node;
- for(int i=0;i<func->arguments.size();i++)
- if (func->arguments[i].name==p_identifier)
- return true;
+ return true;
}
- node=node->parent;
+ if (p_block->parent_function) {
+ function=p_block->parent_function;
+ break;
+ } else {
+ ERR_FAIL_COND_V(!p_block->parent_block,false);
+ p_block=p_block->parent_block;
+ }
}
- // try keywords
-
- int idx=0;
-
- //todo optimize
- while(intrinsic_func_defs[idx].name) {
+ if (function) {
+ for(int i=0;i<function->arguments.size();i++) {
+ if (function->arguments[i].name==p_identifier) {
+ if (r_data_type) {
+ *r_data_type=function->arguments[i].type;
+ }
+ if (r_type) {
+ *r_type=IDENTIFIER_FUNCTION_ARGUMENT;
+ }
- if (p_identifier.operator String()==intrinsic_func_defs[idx].name)
- return true;
- idx++;
+ return true;
+ }
+ }
}
- return false;
-
-}
+ if (shader->varyings.has(p_identifier)) {
+ if (r_data_type) {
+ *r_data_type=shader->varyings[p_identifier].type;
+ }
+ if (r_type) {
+ *r_type=IDENTIFIER_VARYING;
+ }
+ return true;
+ }
+ if (shader->uniforms.has(p_identifier)) {
+ if (r_data_type) {
+ *r_data_type=shader->uniforms[p_identifier].type;
+ }
+ if (r_type) {
+ *r_type=IDENTIFIER_UNIFORM;
+ }
+ return true;
+ }
-Error ShaderLanguage::parse_function(Parser& parser,BlockNode *p_block) {
+ for(int i=0;i<shader->functions.size();i++) {
- if (!p_block->parent || p_block->parent->type!=Node::TYPE_PROGRAM) {
- parser.set_error("Misplaced function");
- return ERR_PARSE_ERROR;
+ if (!shader->functions[i].callable)
+ continue;
+ if (shader->functions[i].name==p_identifier) {
+ if (r_data_type) {
+ *r_data_type=shader->functions[i].function->return_type;
+ }
+ if (r_type) {
+ *r_type=IDENTIFIER_FUNCTION;
+ }
+ }
}
+ return false;
- ProgramNode *program = (ProgramNode*)p_block->parent;
+}
- StringName name = parser.get_token(1).text;
- if (test_existing_identifier(p_block,name)) {
+bool ShaderLanguage::_validate_operator(OperatorNode *p_op,DataType *r_ret_type) {
- parser.set_error("Duplicate Identifier (existing variable/builtin/function): "+name);
- return ERR_PARSE_ERROR;
+ bool valid=false;
+ DataType ret_type;
+
+ switch(p_op->op) {
+ case OP_EQUAL:
+ case OP_NOT_EQUAL: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
+ valid=na==nb;
+ ret_type=TYPE_BOOL;
+ } break;
+ case OP_LESS:
+ case OP_LESS_EQUAL:
+ case OP_GREATER:
+ case OP_GREATER_EQUAL: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- }
+ valid = na==nb && (na==TYPE_UINT || na==TYPE_INT || na==TYPE_FLOAT);
+ ret_type=TYPE_BOOL;
+ } break;
+ case OP_AND:
+ case OP_OR: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- FunctionNode *function = parser.create_node<FunctionNode>(program);
- function->body = parser.create_node<BlockNode>(function);
+ valid = na==nb && na==TYPE_BOOL;
+ ret_type=TYPE_BOOL;
- function->name=name;
+ } break;
+ case OP_NOT: {
- function->return_type=get_token_datatype(parser.get_token_type(0));
+ DataType na = p_op->arguments[0]->get_datatype();
+ valid = na==TYPE_BOOL;
+ ret_type=TYPE_BOOL;
- { //add to programnode
- ProgramNode::Function f;
- f.name=name;
- f.function=function;
- program->functions.push_back(f);
- }
+ } break;
+ case OP_INCREMENT:
+ case OP_DECREMENT:
+ case OP_POST_INCREMENT:
+ case OP_POST_DECREMENT:
+ case OP_NEGATE: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ valid = na>TYPE_BOOL && na<TYPE_MAT2;
+ ret_type=na;
+ } break;
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
+
+ if (na>nb) {
+ //make things easier;
+ SWAP(na,nb);
+ }
+
+ if (na==nb) {
+ valid = (na>TYPE_BOOL && na<TYPE_MAT2) || (p_op->op==OP_MUL && na>=TYPE_MAT2 && na<=TYPE_MAT4);
+ ret_type=na;
+ } else if (na==TYPE_INT && nb==TYPE_IVEC2) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_INT && nb==TYPE_IVEC3) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_INT && nb==TYPE_IVEC4) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ } else if (na==TYPE_UINT && nb==TYPE_UVEC2) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UINT && nb==TYPE_UVEC3) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UINT && nb==TYPE_UVEC4) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
+ } else if (na==TYPE_FLOAT && nb==TYPE_VEC2) {
+ valid=true;
+ ret_type=TYPE_VEC2;
+ } else if (na==TYPE_FLOAT && nb==TYPE_VEC3) {
+ valid=true;
+ ret_type=TYPE_VEC3;
+ } else if (na==TYPE_FLOAT && nb==TYPE_VEC4) {
+ valid=true;
+ ret_type=TYPE_VEC4;
+ } else if (p_op->op==OP_MUL && na==TYPE_VEC2 && nb==TYPE_MAT2) {
+ valid=true;
+ ret_type=TYPE_MAT2;
+ } else if (p_op->op==OP_MUL && na==TYPE_VEC3 && nb==TYPE_MAT3) {
+ valid=true;
+ ret_type=TYPE_MAT3;
+ } else if (p_op->op==OP_MUL && na==TYPE_VEC4 && nb==TYPE_MAT4) {
+ valid=true;
+ ret_type=TYPE_MAT4;
+ }
+ } break;
+ case OP_ASSIGN_MOD:
+ case OP_MOD: {
+ /*
+ * The operator modulus (%) operates on signed or unsigned integers or integer vectors. The operand
+ * types must both be signed or both be unsigned. The operands cannot be vectors of differing size. If
+ * one operand is a scalar and the other vector, then the scalar is applied component-wise to the vector,
+ * resulting in the same type as the vector. If both are vectors of the same size, the result is computed
+ * component-wise.
+ */
- int ofs=3;
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- while(true) {
- //end of arguments
- if (parser.get_token_type(ofs)==TK_PARENTHESIS_CLOSE) {
- ofs++;
- break;
- }
- //next argument awaits
- if (parser.get_token_type(ofs)==TK_COMMA) {
- if (!is_token_nonvoid_datatype(parser.get_token_type(ofs+1))) {
- parser.set_error("Expected Identifier or ')' following ','");
- return ERR_PARSE_ERROR;
+ if (na==TYPE_INT && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_INT;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_IVEC2) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_IVEC3) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_IVEC4) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ /////
+ } else if (na==TYPE_UINT && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UINT;
+ } else if (na==TYPE_UVEC2 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UVEC3 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UVEC4 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
+ } else if (na==TYPE_UVEC2 && nb==TYPE_UVEC2) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UVEC3 && nb==TYPE_UVEC3) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UVEC4 && nb==TYPE_UVEC4) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
}
- ofs++;
- continue;
- }
-
+ } break;
+ case OP_ASSIGN_SHIFT_LEFT:
+ case OP_ASSIGN_SHIFT_RIGHT:
+ case OP_SHIFT_LEFT:
+ case OP_SHIFT_RIGHT: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- if (!is_token_nonvoid_datatype(parser.get_token_type(ofs+0))) {
- parser.set_error("Invalid Argument Type");
- return ERR_PARSE_ERROR;
- }
-
- DataType identtype=get_token_datatype(parser.get_token_type(ofs+0));
+ if (na>=TYPE_UINT && na<=TYPE_UVEC4) {
+ na=DataType(na-4);
+ }
- if (parser.get_token_type(ofs+1)!=TK_INDENTIFIER) {
- parser.set_error("Expected Argument Identifier");
- return ERR_PARSE_ERROR;
- }
+ if (nb>=TYPE_UINT && nb<=TYPE_UVEC4) {
+ nb=DataType(nb-4);
+ }
- StringName identname=parser.get_token(ofs+1).text;
+ if (na==TYPE_INT && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_INT;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_IVEC2) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_IVEC3) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_IVEC4) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ }
+ } break;
+ case OP_ASSIGN: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
+ valid=na==nb;
+ ret_type=na;
+ } break;
+ case OP_ASSIGN_ADD:
+ case OP_ASSIGN_SUB:
+ case OP_ASSIGN_MUL:
+ case OP_ASSIGN_DIV: {
- if (test_existing_identifier(function,identname)) {
- parser.set_error("Duplicate Argument Identifier: "+identname);
- return ERR_DUPLICATE_SYMBOL;
- }
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- FunctionNode::Argument arg;
- arg.name=identname;
- arg.type=identtype;
- //function->body->variables[arg.name]=arg.type;
- function->arguments.push_back(arg);
- ofs+=2;
- }
+ if (na==nb) {
+ valid = (na>TYPE_BOOL && na<TYPE_MAT2) || (p_op->op==OP_ASSIGN_MUL && na>=TYPE_MAT2 && na<=TYPE_MAT4);
+ ret_type=na;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_INT ) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ } else if (na==TYPE_UVEC2 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UVEC3 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UVEC4 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
+ } else if (na==TYPE_VEC2 && nb==TYPE_FLOAT ) {
+ valid=true;
+ ret_type=TYPE_VEC2;
+ } else if (na==TYPE_VEC3 && nb==TYPE_FLOAT) {
+ valid=true;
+ ret_type=TYPE_VEC3;
+ } else if (na==TYPE_VEC4 && nb==TYPE_FLOAT) {
+ valid=true;
+ ret_type=TYPE_VEC4;
+ } else if (p_op->op==OP_ASSIGN_MUL && na==TYPE_MAT2 && nb==TYPE_VEC2) {
+ valid=true;
+ ret_type=TYPE_MAT2;
+ } else if (p_op->op==OP_ASSIGN_MUL && na==TYPE_MAT3 && nb==TYPE_VEC3) {
+ valid=true;
+ ret_type=TYPE_MAT3;
+ } else if (p_op->op==OP_ASSIGN_MUL && na==TYPE_MAT4 && nb==TYPE_VEC4) {
+ valid=true;
+ ret_type=TYPE_MAT4;
+ }
+ } break;
+ case OP_ASSIGN_BIT_AND:
+ case OP_ASSIGN_BIT_OR:
+ case OP_ASSIGN_BIT_XOR:
+ case OP_BIT_AND:
+ case OP_BIT_OR:
+ case OP_BIT_XOR: {
- parser.advance(ofs);
- // match {
- if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
- parser.set_error("Expected '{'");
- return ERR_PARSE_ERROR;
- }
+ /*
+ * The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type
+ * signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If
+ * one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector,
+ * resulting in the same type as the vector. The fundamental types of the operands (signed or unsigned)
+ * must match.
+ */
- parser.advance();
- Error err = parse_block(parser,function->body);
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
- if (err)
- return err;
+ if (na>nb && p_op->op>=OP_BIT_AND) {
+ //can swap for non assign
+ SWAP(na,nb);
+ }
- // make sure that if the function has a return type, it does return something..
- if (function->return_type!=TYPE_VOID) {
- bool found=false;
- for(int i=0;i<function->body->statements.size();i++) {
- if (function->body->statements[i]->type==Node::TYPE_CONTROL_FLOW) {
-
- ControlFlowNode *cf = (ControlFlowNode*)function->body->statements[i];
- if (cf->flow_op==FLOW_OP_RETURN) {
- // type of return was already checked when inserted
- // no need to check here
- found=true;
- }
+ if (na==TYPE_INT && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_INT;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_INT) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ } else if (na==TYPE_IVEC2 && nb==TYPE_IVEC2) {
+ valid=true;
+ ret_type=TYPE_IVEC2;
+ } else if (na==TYPE_IVEC3 && nb==TYPE_IVEC3) {
+ valid=true;
+ ret_type=TYPE_IVEC3;
+ } else if (na==TYPE_IVEC4 && nb==TYPE_IVEC4) {
+ valid=true;
+ ret_type=TYPE_IVEC4;
+ /////
+ } else if (na==TYPE_UINT && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UINT;
+ } else if (na==TYPE_UVEC2 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UVEC3 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UVEC4 && nb==TYPE_UINT) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
+ } else if (na==TYPE_UVEC2 && nb==TYPE_UVEC2) {
+ valid=true;
+ ret_type=TYPE_UVEC2;
+ } else if (na==TYPE_UVEC3 && nb==TYPE_UVEC3) {
+ valid=true;
+ ret_type=TYPE_UVEC3;
+ } else if (na==TYPE_UVEC4 && nb==TYPE_UVEC4) {
+ valid=true;
+ ret_type=TYPE_UVEC4;
}
- }
+ } break;
+ case OP_BIT_INVERT: { //unaries
+ DataType na = p_op->arguments[0]->get_datatype();
+ valid = na>=TYPE_INT && na<TYPE_FLOAT;
+ ret_type=na;
+ } break;
+ case OP_SELECT_IF: {
+ DataType na = p_op->arguments[0]->get_datatype();
+ DataType nb = p_op->arguments[1]->get_datatype();
+ DataType nc = p_op->arguments[2]->get_datatype();
- if (!found) {
- parser.set_error("Function must return a value (use the main block)");
- return ERR_PARSE_ERROR;
+ valid = na==TYPE_BOOL && (nb==nc);
+ ret_type=nb;
+ } break;
+ default: {
+ ERR_FAIL_V(false);
}
}
- return OK;
-}
+ if (r_ret_type)
+ *r_ret_type=ret_type;
+ return valid;
+}
const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
//constructors
{"bool",TYPE_BOOL,{TYPE_BOOL,TYPE_VOID}},
+ {"bvec2",TYPE_BVEC2,{TYPE_BOOL,TYPE_VOID}},
+ {"bvec2",TYPE_BVEC2,{TYPE_BOOL,TYPE_BOOL,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_BOOL,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_BOOL,TYPE_BOOL,TYPE_BOOL,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_BVEC2,TYPE_BOOL,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_BOOL,TYPE_BVEC2,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BOOL,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BOOL,TYPE_BOOL,TYPE_BOOL,TYPE_BOOL,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BOOL,TYPE_BVEC2,TYPE_BOOL,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BVEC2,TYPE_BOOL,TYPE_BOOL,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BOOL,TYPE_BOOL,TYPE_BVEC2,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BOOL,TYPE_BVEC3,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BVEC3,TYPE_BOOL,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_BVEC2,TYPE_BVEC2,TYPE_VOID}},
+
+
{"float",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
{"vec2",TYPE_VEC2,{TYPE_FLOAT,TYPE_VOID}},
{"vec2",TYPE_VEC2,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
@@ -791,9 +1098,131 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}},
{"vec4",TYPE_VEC4,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
{"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+
+ {"int",TYPE_INT,{TYPE_INT,TYPE_VOID}},
+ {"ivec2",TYPE_IVEC2,{TYPE_INT,TYPE_VOID}},
+ {"ivec2",TYPE_IVEC2,{TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_INT,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_INT,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_IVEC2,TYPE_INT,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_INT,TYPE_IVEC2,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_INT,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_INT,TYPE_INT,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_INT,TYPE_IVEC2,TYPE_INT,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_IVEC2,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_INT,TYPE_INT,TYPE_IVEC2,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_INT,TYPE_IVEC3,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_IVEC3,TYPE_INT,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+
+ {"uint",TYPE_UINT,{TYPE_UINT,TYPE_VOID}},
+ {"uvec2",TYPE_UVEC2,{TYPE_UINT,TYPE_VOID}},
+ {"uvec2",TYPE_UVEC2,{TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_UINT,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_UINT,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_UVEC2,TYPE_UINT,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_UINT,TYPE_UVEC2,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UINT,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UINT,TYPE_UINT,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UINT,TYPE_UVEC2,TYPE_UINT,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UVEC2,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UINT,TYPE_UINT,TYPE_UVEC2,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UINT,TYPE_UVEC3,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UVEC3,TYPE_UINT,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+
{"mat2",TYPE_MAT2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
{"mat3",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
{"mat4",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+
+ {"mat2",TYPE_MAT2,{TYPE_FLOAT,TYPE_VOID}},
+ {"mat3",TYPE_MAT3,{TYPE_FLOAT,TYPE_VOID}},
+ {"mat4",TYPE_MAT4,{TYPE_FLOAT,TYPE_VOID}},
+
+ //conversion scalars
+
+ {"int",TYPE_INT,{TYPE_BOOL,TYPE_VOID}},
+ {"int",TYPE_INT,{TYPE_INT,TYPE_VOID}},
+ {"int",TYPE_INT,{TYPE_UINT,TYPE_VOID}},
+ {"int",TYPE_INT,{TYPE_FLOAT,TYPE_VOID}},
+
+ {"float",TYPE_FLOAT,{TYPE_BOOL,TYPE_VOID}},
+ {"float",TYPE_FLOAT,{TYPE_INT,TYPE_VOID}},
+ {"float",TYPE_FLOAT,{TYPE_UINT,TYPE_VOID}},
+ {"float",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
+
+ {"uint",TYPE_UINT,{TYPE_BOOL,TYPE_VOID}},
+ {"uint",TYPE_UINT,{TYPE_INT,TYPE_VOID}},
+ {"uint",TYPE_UINT,{TYPE_UINT,TYPE_VOID}},
+ {"uint",TYPE_UINT,{TYPE_FLOAT,TYPE_VOID}},
+
+ {"bool",TYPE_BOOL,{TYPE_BOOL,TYPE_VOID}},
+ {"bool",TYPE_BOOL,{TYPE_INT,TYPE_VOID}},
+ {"bool",TYPE_BOOL,{TYPE_UINT,TYPE_VOID}},
+ {"bool",TYPE_BOOL,{TYPE_FLOAT,TYPE_VOID}},
+
+ //conversion vectors
+
+ {"ivec2",TYPE_IVEC2,{TYPE_BVEC2,TYPE_VOID}},
+ {"ivec2",TYPE_IVEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"ivec2",TYPE_IVEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"ivec2",TYPE_IVEC2,{TYPE_VEC2,TYPE_VOID}},
+
+ {"vec2",TYPE_VEC2,{TYPE_BVEC2,TYPE_VOID}},
+ {"vec2",TYPE_VEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"vec2",TYPE_VEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"vec2",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
+
+ {"uvec2",TYPE_UVEC2,{TYPE_BVEC2,TYPE_VOID}},
+ {"uvec2",TYPE_UVEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"uvec2",TYPE_UVEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"uvec2",TYPE_UVEC2,{TYPE_VEC2,TYPE_VOID}},
+
+ {"bvec2",TYPE_BVEC2,{TYPE_BVEC2,TYPE_VOID}},
+ {"bvec2",TYPE_BVEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"bvec2",TYPE_BVEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"bvec2",TYPE_BVEC2,{TYPE_VEC2,TYPE_VOID}},
+
+ {"ivec3",TYPE_IVEC3,{TYPE_BVEC3,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"ivec3",TYPE_IVEC3,{TYPE_VEC3,TYPE_VOID}},
+
+ {"vec3",TYPE_VEC3,{TYPE_BVEC3,TYPE_VOID}},
+ {"vec3",TYPE_VEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"vec3",TYPE_VEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"vec3",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
+
+ {"uvec3",TYPE_UVEC3,{TYPE_BVEC3,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"uvec3",TYPE_UVEC3,{TYPE_VEC3,TYPE_VOID}},
+
+ {"bvec3",TYPE_BVEC3,{TYPE_BVEC3,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"bvec3",TYPE_BVEC3,{TYPE_VEC3,TYPE_VOID}},
+
+ {"ivec4",TYPE_IVEC4,{TYPE_BVEC4,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_IVEC4,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_UVEC4,TYPE_VOID}},
+ {"ivec4",TYPE_IVEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"vec4",TYPE_VEC4,{TYPE_BVEC4,TYPE_VOID}},
+ {"vec4",TYPE_VEC4,{TYPE_IVEC4,TYPE_VOID}},
+ {"vec4",TYPE_VEC4,{TYPE_UVEC4,TYPE_VOID}},
+ {"vec4",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"uvec4",TYPE_UVEC4,{TYPE_BVEC4,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_IVEC4,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_UVEC4,TYPE_VOID}},
+ {"uvec4",TYPE_UVEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"bvec4",TYPE_BVEC4,{TYPE_BVEC4,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_IVEC4,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_UVEC4,TYPE_VOID}},
+ {"bvec4",TYPE_BVEC4,{TYPE_VEC4,TYPE_VOID}},
+
//intrinsics - trigonometry
{"sin",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
{"cos",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
@@ -830,10 +1259,29 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"abs",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
{"abs",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
{"abs",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"abs",TYPE_INT,{TYPE_INT,TYPE_VOID}},
+ {"abs",TYPE_IVEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"abs",TYPE_IVEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"abs",TYPE_IVEC4,{TYPE_IVEC4,TYPE_VOID}},
+
+ {"abs",TYPE_UINT,{TYPE_UINT,TYPE_VOID}},
+ {"abs",TYPE_UVEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"abs",TYPE_UVEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"abs",TYPE_UVEC4,{TYPE_UVEC4,TYPE_VOID}},
+
+
{"sign",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
{"sign",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
{"sign",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
{"sign",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"sign",TYPE_INT,{TYPE_INT,TYPE_VOID}},
+ {"sign",TYPE_IVEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"sign",TYPE_IVEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"sign",TYPE_IVEC4,{TYPE_IVEC4,TYPE_VOID}},
+
+
{"floor",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
{"floor",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
{"floor",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
@@ -854,18 +1302,51 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"fract",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
{"fract",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
{"fract",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
{"mod",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"mod",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"mod",TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}},
{"mod",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"mod",TYPE_VEC3,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
{"mod",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+ {"mod",TYPE_VEC4,{TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"modf",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
+ {"modf",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"modf",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"modf",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+
{"min",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"min",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
{"min",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
{"min",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+
+ {"min",TYPE_INT,{TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"min",TYPE_IVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"min",TYPE_IVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"min",TYPE_IVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+
+ {"min",TYPE_UINT,{TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"min",TYPE_UVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"min",TYPE_UVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"min",TYPE_UVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
+
{"max",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"max",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
{"max",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
{"max",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+
+ {"max",TYPE_INT,{TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"max",TYPE_IVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"max",TYPE_IVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"max",TYPE_IVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+
+ {"max",TYPE_UINT,{TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"max",TYPE_UVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"max",TYPE_UVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"max",TYPE_UVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
+
+
{"clamp",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"clamp",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
{"clamp",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
@@ -873,6 +1354,24 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"clamp",TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"clamp",TYPE_VEC3,{TYPE_VEC3,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"clamp",TYPE_VEC4,{TYPE_VEC4,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
+
+
+ {"clamp",TYPE_INT,{TYPE_INT,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"clamp",TYPE_IVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"clamp",TYPE_IVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"clamp",TYPE_IVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+ {"clamp",TYPE_IVEC2,{TYPE_IVEC2,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"clamp",TYPE_IVEC3,{TYPE_IVEC3,TYPE_INT,TYPE_INT,TYPE_VOID}},
+ {"clamp",TYPE_IVEC4,{TYPE_IVEC4,TYPE_INT,TYPE_INT,TYPE_VOID}},
+
+ {"clamp",TYPE_UINT,{TYPE_UINT,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"clamp",TYPE_UVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"clamp",TYPE_UVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"clamp",TYPE_UVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
+ {"clamp",TYPE_UVEC2,{TYPE_UVEC2,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"clamp",TYPE_UVEC3,{TYPE_UVEC3,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+ {"clamp",TYPE_UVEC4,{TYPE_UVEC4,TYPE_UINT,TYPE_UINT,TYPE_VOID}},
+
{"mix",TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT,TYPE_FLOAT,TYPE_VOID}},
{"mix",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}},
{"mix",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
@@ -895,6 +1394,36 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"smoothstep",TYPE_VEC3,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}},
{"smoothstep",TYPE_VEC4,{TYPE_FLOAT,TYPE_FLOAT,TYPE_VEC4,TYPE_VOID}},
+ {"isnan",TYPE_BOOL,{TYPE_FLOAT,TYPE_VOID}},
+ {"isnan",TYPE_BOOL,{TYPE_VEC2,TYPE_VOID}},
+ {"isnan",TYPE_BOOL,{TYPE_VEC3,TYPE_VOID}},
+ {"isnan",TYPE_BOOL,{TYPE_VEC4,TYPE_VOID}},
+
+ {"isinf",TYPE_BOOL,{TYPE_FLOAT,TYPE_VOID}},
+ {"isinf",TYPE_BOOL,{TYPE_VEC2,TYPE_VOID}},
+ {"isinf",TYPE_BOOL,{TYPE_VEC3,TYPE_VOID}},
+ {"isinf",TYPE_BOOL,{TYPE_VEC4,TYPE_VOID}},
+
+ {"floatBitsToInt",TYPE_INT,{TYPE_FLOAT,TYPE_VOID}},
+ {"floatBitsToInt",TYPE_IVEC2,{TYPE_VEC2,TYPE_VOID}},
+ {"floatBitsToInt",TYPE_IVEC3,{TYPE_VEC3,TYPE_VOID}},
+ {"floatBitsToInt",TYPE_IVEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"floatBitsToUInt",TYPE_UINT,{TYPE_FLOAT,TYPE_VOID}},
+ {"floatBitsToUInt",TYPE_UVEC2,{TYPE_VEC2,TYPE_VOID}},
+ {"floatBitsToUInt",TYPE_UVEC3,{TYPE_VEC3,TYPE_VOID}},
+ {"floatBitsToUInt",TYPE_UVEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"intBitsToFloat",TYPE_FLOAT,{TYPE_INT,TYPE_VOID}},
+ {"intBitsToFloat",TYPE_VEC2,{TYPE_IVEC2,TYPE_VOID}},
+ {"intBitsToFloat",TYPE_VEC3,{TYPE_IVEC3,TYPE_VOID}},
+ {"intBitsToFloat",TYPE_VEC4,{TYPE_IVEC4,TYPE_VOID}},
+
+ {"uintBitsToFloat",TYPE_FLOAT,{TYPE_UINT,TYPE_VOID}},
+ {"uintBitsToFloat",TYPE_VEC2,{TYPE_UVEC2,TYPE_VOID}},
+ {"uintBitsToFloat",TYPE_VEC3,{TYPE_UVEC3,TYPE_VOID}},
+ {"uintBitsToFloat",TYPE_VEC4,{TYPE_UVEC4,TYPE_VOID}},
+
//intrinsics - geometric
{"length",TYPE_FLOAT,{TYPE_VEC2,TYPE_VOID}},
{"length",TYPE_FLOAT,{TYPE_VEC3,TYPE_VOID}},
@@ -911,318 +1440,211 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"normalize",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
{"reflect",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
{"refract",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
- //intrinsics - texture
- {"tex",TYPE_VEC4,{TYPE_TEXTURE,TYPE_VEC2,TYPE_VOID}},
- {"texcube",TYPE_VEC4,{TYPE_CUBEMAP,TYPE_VEC3,TYPE_VOID}},
- {"texscreen",TYPE_VEC3,{TYPE_VEC2,TYPE_VOID}},
- {"texpos",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
- {NULL,TYPE_VOID,{TYPE_VOID}}
+ {"facefordward",TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"facefordward",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"facefordward",TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
-};
+ {"matrixCompMult",TYPE_MAT2,{TYPE_MAT2,TYPE_MAT2,TYPE_VOID}},
+ {"matrixCompMult",TYPE_MAT3,{TYPE_MAT3,TYPE_MAT3,TYPE_VOID}},
+ {"matrixCompMult",TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4,TYPE_VOID}},
-const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={
-
- {OP_ASSIGN,TYPE_VOID,{TYPE_BOOL,TYPE_BOOL}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}},
- {OP_ASSIGN,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}},
- {OP_ADD,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ADD,TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ADD,TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ADD,TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4}},
- {OP_SUB,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_SUB,TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2}},
- {OP_SUB,TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3}},
- {OP_SUB,TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4}},
- {OP_MUL,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2}},
- {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_MUL,TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2}},
- {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT3}},
- {OP_MUL,TYPE_VEC2,{TYPE_MAT2,TYPE_VEC2}},
- {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT2}},
- {OP_MUL,TYPE_VEC2,{TYPE_MAT3,TYPE_VEC2}},
- {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT4}},
- {OP_MUL,TYPE_VEC2,{TYPE_MAT4,TYPE_VEC2}},
- {OP_MUL,TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3}},
- {OP_MUL,TYPE_VEC3,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_MUL,TYPE_VEC3,{TYPE_FLOAT,TYPE_VEC3}},
- {OP_MUL,TYPE_VEC3,{TYPE_MAT3,TYPE_VEC3}},
- {OP_MUL,TYPE_VEC3,{TYPE_MAT4,TYPE_VEC3}},
- {OP_MUL,TYPE_VEC3,{TYPE_VEC3,TYPE_MAT3}},
- {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4}},
- {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_MUL,TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4}},
- {OP_MUL,TYPE_VEC4,{TYPE_MAT4,TYPE_VEC4}},
- {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_MAT4}},
- {OP_MUL,TYPE_MAT2,{TYPE_MAT2,TYPE_MAT2}},
- {OP_MUL,TYPE_MAT3,{TYPE_MAT3,TYPE_MAT3}},
- {OP_MUL,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}},
- {OP_DIV,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_DIV,TYPE_VEC2,{TYPE_VEC2,TYPE_VEC2}},
- {OP_DIV,TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_DIV,TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2}},
- {OP_DIV,TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3}},
- {OP_DIV,TYPE_VEC3,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_DIV,TYPE_VEC3,{TYPE_FLOAT,TYPE_VEC3}},
- {OP_DIV,TYPE_VEC4,{TYPE_VEC4,TYPE_VEC4}},
- {OP_DIV,TYPE_VEC4,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_DIV,TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_MAT2}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT3}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT4}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_MAT4}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}},
- {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}},
- {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}},
- {OP_NEG,TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
- {OP_NEG,TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
- {OP_NEG,TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
- {OP_NEG,TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
- {OP_NOT,TYPE_BOOL,{TYPE_BOOL,TYPE_VOID}},
- {OP_CMP_EQ,TYPE_BOOL,{TYPE_BOOL,TYPE_BOOL}},
- {OP_CMP_EQ,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_EQ,TYPE_BOOL,{TYPE_VEC3,TYPE_VEC2}},
- {OP_CMP_EQ,TYPE_BOOL,{TYPE_VEC3,TYPE_VEC3}},
- {OP_CMP_EQ,TYPE_BOOL,{TYPE_VEC3,TYPE_VEC4}},
- //{OP_CMP_EQ,TYPE_MAT3,{TYPE_MAT4,TYPE_MAT3}}, ??
- //{OP_CMP_EQ,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, ??
- {OP_CMP_NEQ,TYPE_BOOL,{TYPE_BOOL,TYPE_BOOL}},
- {OP_CMP_NEQ,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_NEQ,TYPE_BOOL,{TYPE_VEC2,TYPE_VEC2}},
- {OP_CMP_NEQ,TYPE_BOOL,{TYPE_VEC3,TYPE_VEC3}},
- {OP_CMP_NEQ,TYPE_BOOL,{TYPE_VEC4,TYPE_VEC4}},
- //{OP_CMP_NEQ,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, //?
- {OP_CMP_LEQ,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_GEQ,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_LESS,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_GREATER,TYPE_BOOL,{TYPE_FLOAT,TYPE_FLOAT}},
- {OP_CMP_OR,TYPE_BOOL,{TYPE_BOOL,TYPE_BOOL}},
- {OP_CMP_AND,TYPE_BOOL,{TYPE_BOOL,TYPE_BOOL}},
- {OP_MAX,TYPE_VOID,{TYPE_VOID,TYPE_VOID}}
-};
+ {"outerProduct",TYPE_MAT2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"outerProduct",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"outerProduct",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+ {"transpose",TYPE_MAT2,{TYPE_MAT2,TYPE_VOID}},
+ {"transpose",TYPE_MAT3,{TYPE_MAT3,TYPE_VOID}},
+ {"transpose",TYPE_MAT4,{TYPE_MAT4,TYPE_VOID}},
-const ShaderLanguage::BuiltinsDef ShaderLanguage::vertex_builtins_defs[]={
-
- { "SRC_VERTEX", TYPE_VEC3},
- { "SRC_NORMAL", TYPE_VEC3},
- { "SRC_TANGENT", TYPE_VEC3},
- { "SRC_BINORMALF", TYPE_FLOAT},
-
- { "POSITION", TYPE_VEC4 },
- { "VERTEX", TYPE_VEC3},
- { "NORMAL", TYPE_VEC3},
- { "TANGENT", TYPE_VEC3},
- { "BINORMAL", TYPE_VEC3},
- { "UV", TYPE_VEC2},
- { "UV2", TYPE_VEC2},
- { "COLOR", TYPE_VEC4},
- { "BONES", TYPE_VEC4},
- { "WEIGHTS", TYPE_VEC4},
- { "VAR1", TYPE_VEC4},
- { "VAR2", TYPE_VEC4},
- { "SPEC_EXP", TYPE_FLOAT},
- { "POINT_SIZE", TYPE_FLOAT},
-
- //builtins
- { "WORLD_MATRIX", TYPE_MAT4},
- { "INV_CAMERA_MATRIX", TYPE_MAT4},
- { "PROJECTION_MATRIX", TYPE_MAT4},
- { "MODELVIEW_MATRIX", TYPE_MAT4},
- { "INSTANCE_ID", TYPE_FLOAT},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID},
-};
-const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[]={
-
- { "VERTEX", TYPE_VEC3},
- { "POSITION", TYPE_VEC4},
- { "NORMAL", TYPE_VEC3},
- { "TANGENT", TYPE_VEC3},
- { "BINORMAL", TYPE_VEC3},
- { "NORMALMAP", TYPE_VEC3},
- { "NORMALMAP_DEPTH", TYPE_FLOAT},
- { "UV", TYPE_VEC2},
- { "UV2", TYPE_VEC2},
- { "COLOR", TYPE_VEC4},
- { "NORMAL", TYPE_VEC3},
- { "VAR1", TYPE_VEC4},
- { "VAR2", TYPE_VEC4},
- { "DIFFUSE", TYPE_VEC3},
- { "DIFFUSE_ALPHA", TYPE_VEC4},
- { "SPECULAR", TYPE_VEC3},
- { "EMISSION", TYPE_VEC3},
- { "SPEC_EXP", TYPE_FLOAT},
- { "GLOW", TYPE_FLOAT},
- { "SHADE_PARAM", TYPE_FLOAT},
- { "DISCARD", TYPE_BOOL},
- { "SCREEN_UV", TYPE_VEC2},
- { "POINT_COORD", TYPE_VEC2},
- { "INV_CAMERA_MATRIX", TYPE_MAT4},
-
-// { "SCREEN_POS", TYPE_VEC2},
-// { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID}
+ {"determinant",TYPE_FLOAT,{TYPE_MAT2,TYPE_VOID}},
+ {"determinant",TYPE_FLOAT,{TYPE_MAT3,TYPE_VOID}},
+ {"determinant",TYPE_FLOAT,{TYPE_MAT4,TYPE_VOID}},
-};
+ {"inverse",TYPE_MAT2,{TYPE_MAT2,TYPE_VOID}},
+ {"inverse",TYPE_MAT3,{TYPE_MAT3,TYPE_VOID}},
+ {"inverse",TYPE_MAT4,{TYPE_MAT4,TYPE_VOID}},
-const ShaderLanguage::BuiltinsDef ShaderLanguage::light_builtins_defs[]={
-
- { "NORMAL", TYPE_VEC3},
- { "LIGHT_DIR", TYPE_VEC3},
- { "LIGHT_DIFFUSE", TYPE_VEC3},
- { "LIGHT_SPECULAR", TYPE_VEC3},
- { "EYE_VEC", TYPE_VEC3},
- { "DIFFUSE", TYPE_VEC3},
- { "SPECULAR", TYPE_VEC3},
- { "SPECULAR_EXP", TYPE_FLOAT},
- { "SHADE_PARAM", TYPE_FLOAT},
- { "LIGHT", TYPE_VEC3},
- { "SHADOW", TYPE_VEC3 },
- { "POINT_COORD", TYPE_VEC2 },
-// { "SCREEN_POS", TYPE_VEC2},
-// { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID}
-};
+ {"lessThan",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"lessThan",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
-const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[]={
+ {"greaterThan",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
- { "SRC_VERTEX", TYPE_VEC2},
- { "VERTEX", TYPE_VEC2},
- { "WORLD_VERTEX", TYPE_VEC2},
- { "UV", TYPE_VEC2},
- { "COLOR", TYPE_VEC4},
- { "VAR1", TYPE_VEC4},
- { "VAR2", TYPE_VEC4},
- { "POINT_SIZE", TYPE_FLOAT},
+ {"greaterThan",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
- //builtins
- { "WORLD_MATRIX", TYPE_MAT4},
- { "PROJECTION_MATRIX", TYPE_MAT4},
- { "EXTRA_MATRIX", TYPE_MAT4},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID},
-};
-const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={
-
- { "SRC_COLOR", TYPE_VEC4},
- { "POSITION", TYPE_VEC4},
- { "NORMAL", TYPE_VEC3},
- { "NORMALMAP", TYPE_VEC3},
- { "NORMALMAP_DEPTH", TYPE_FLOAT},
- { "UV", TYPE_VEC2},
- { "COLOR", TYPE_VEC4},
- { "TEXTURE", TYPE_TEXTURE},
- { "TEXTURE_PIXEL_SIZE", TYPE_VEC2},
- { "VAR1", TYPE_VEC4},
- { "VAR2", TYPE_VEC4},
- { "SCREEN_UV", TYPE_VEC2},
- { "POINT_COORD", TYPE_VEC2},
-
-// { "SCREEN_POS", TYPE_VEC2},
-// { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID}
+ {"greaterThan",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"greaterThan",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
-};
+ {"lessThanEqual",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
-const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={
-
- { "POSITION", TYPE_VEC4},
- { "NORMAL", TYPE_VEC3},
- { "UV", TYPE_VEC2},
- { "COLOR", TYPE_VEC4},
- { "TEXTURE", TYPE_TEXTURE},
- { "TEXTURE_PIXEL_SIZE", TYPE_VEC2},
- { "VAR1", TYPE_VEC4},
- { "VAR2", TYPE_VEC4},
- { "SCREEN_UV", TYPE_VEC2},
- { "LIGHT_VEC", TYPE_VEC2},
- { "LIGHT_HEIGHT", TYPE_FLOAT},
- { "LIGHT_COLOR", TYPE_VEC4},
- { "LIGHT_UV", TYPE_VEC2},
- { "LIGHT_SHADOW", TYPE_VEC4},
- { "LIGHT", TYPE_VEC4},
- { "SHADOW", TYPE_VEC4},
- { "POINT_COORD", TYPE_VEC2},
-// { "SCREEN_POS", TYPE_VEC2},
-// { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID}
+ {"lessThanEqual",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
-};
+ {"lessThanEqual",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"lessThanEqual",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
-const ShaderLanguage::BuiltinsDef ShaderLanguage::postprocess_fragment_builtins_defs[]={
+ {"greaterThanEqual",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
- { "IN_COLOR", TYPE_VEC3},
- { "IN_POSITION", TYPE_VEC3},
- { "OUT_COLOR", TYPE_VEC3},
- { "SCREEN_POS", TYPE_VEC2},
- { "SCREEN_TEXEL_SIZE", TYPE_VEC2},
- { "TIME", TYPE_FLOAT},
- { NULL, TYPE_VOID}
-};
+ {"greaterThanEqual",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"greaterThanEqual",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
+ {"equal",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"equal",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"equal",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
-ShaderLanguage::DataType ShaderLanguage::compute_node_type(Node *p_node) {
+ {"equal",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"equal",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"equal",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
- switch(p_node->type) {
+ {"equal",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"equal",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"equal",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
- case Node::TYPE_PROGRAM: ERR_FAIL_V(TYPE_VOID);
- case Node::TYPE_FUNCTION: return static_cast<FunctionNode*>(p_node)->return_type;
- case Node::TYPE_BLOCK: ERR_FAIL_V(TYPE_VOID);
- case Node::TYPE_VARIABLE: return static_cast<VariableNode*>(p_node)->datatype_cache;
- case Node::TYPE_CONSTANT: return static_cast<ConstantNode*>(p_node)->datatype;
- case Node::TYPE_OPERATOR: return static_cast<OperatorNode*>(p_node)->return_cache;
- case Node::TYPE_CONTROL_FLOW: ERR_FAIL_V(TYPE_VOID);
- case Node::TYPE_MEMBER: return static_cast<MemberNode*>(p_node)->datatype;
- }
+ {"equal",TYPE_BVEC2,{TYPE_BVEC2,TYPE_BVEC2,TYPE_VOID}},
+ {"equal",TYPE_BVEC3,{TYPE_BVEC3,TYPE_BVEC3,TYPE_VOID}},
+ {"equal",TYPE_BVEC4,{TYPE_BVEC4,TYPE_BVEC4,TYPE_VOID}},
- return TYPE_VOID;
-}
+ {"notEqual",TYPE_BVEC2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC4,{TYPE_VEC4,TYPE_VEC4,TYPE_VOID}},
+
+ {"notEqual",TYPE_BVEC2,{TYPE_IVEC2,TYPE_IVEC2,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC3,{TYPE_IVEC3,TYPE_IVEC3,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC4,{TYPE_IVEC4,TYPE_IVEC4,TYPE_VOID}},
+
+ {"notEqual",TYPE_BVEC2,{TYPE_UVEC2,TYPE_UVEC2,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC3,{TYPE_UVEC3,TYPE_UVEC3,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC4,{TYPE_UVEC4,TYPE_UVEC4,TYPE_VOID}},
+
+ {"notEqual",TYPE_BVEC2,{TYPE_BVEC2,TYPE_BVEC2,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC3,{TYPE_BVEC3,TYPE_BVEC3,TYPE_VOID}},
+ {"notEqual",TYPE_BVEC4,{TYPE_BVEC4,TYPE_BVEC4,TYPE_VOID}},
+
+ {"any",TYPE_BOOL,{TYPE_BVEC2,TYPE_VOID}},
+ {"any",TYPE_BOOL,{TYPE_BVEC3,TYPE_VOID}},
+ {"any",TYPE_BOOL,{TYPE_BVEC4,TYPE_VOID}},
+
+ {"all",TYPE_BOOL,{TYPE_BVEC2,TYPE_VOID}},
+ {"all",TYPE_BOOL,{TYPE_BVEC3,TYPE_VOID}},
+ {"all",TYPE_BOOL,{TYPE_BVEC4,TYPE_VOID}},
+
+ {"not",TYPE_BOOL,{TYPE_BVEC2,TYPE_VOID}},
+ {"not",TYPE_BOOL,{TYPE_BVEC3,TYPE_VOID}},
+ {"not",TYPE_BOOL,{TYPE_BVEC4,TYPE_VOID}},
+
+ //intrinsics - texture
+ {"textureSize",TYPE_VEC2,{TYPE_SAMPLER2D,TYPE_INT,TYPE_VOID}},
+ {"textureSize",TYPE_VEC2,{TYPE_ISAMPLER2D,TYPE_INT,TYPE_VOID}},
+ {"textureSize",TYPE_VEC2,{TYPE_USAMPLER2D,TYPE_INT,TYPE_VOID}},
+ {"textureSize",TYPE_VEC2,{TYPE_SAMPLERCUBE,TYPE_INT,TYPE_VOID}},
+
+ {"texture",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC2,TYPE_VOID}},
+ {"texture",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"texture",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}},
+ {"texture",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+
+ {"texture",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC2,TYPE_VOID}},
+ {"texture",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"texture",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}},
+ {"texture",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"texture",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC2,TYPE_VOID}},
+ {"texture",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"texture",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC2,TYPE_FLOAT,TYPE_VOID}},
+ {"texture",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
-ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, OperatorNode *p_func) {
+ {"texture",TYPE_VEC4,{TYPE_SAMPLERCUBE,TYPE_VEC3,TYPE_VOID}},
+ {"texture",TYPE_VEC4,{TYPE_SAMPLERCUBE,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureProj",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"textureProj",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC4,TYPE_VOID}},
+ {"textureProj",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProj",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureProj",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"textureProj",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC4,TYPE_VOID}},
+ {"textureProj",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProj",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureProj",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_VOID}},
+ {"textureProj",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC4,TYPE_VOID}},
+ {"textureProj",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProj",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureLod",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureLod",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureLod",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureLod",TYPE_VEC4,{TYPE_SAMPLERCUBE,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+
+ {"texelFetch",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_IVEC2,TYPE_INT,TYPE_VOID}},
+ {"texelFetch",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_IVEC2,TYPE_INT,TYPE_VOID}},
+ {"texelFetch",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_IVEC2,TYPE_INT,TYPE_VOID}},
+
+ {"textureProjLod",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProjLod",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureProjLod",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProjLod",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureProjLod",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
+ {"textureProjLod",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC4,TYPE_FLOAT,TYPE_VOID}},
+
+ {"textureGrad",TYPE_VEC4,{TYPE_SAMPLER2D,TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"textureGrad",TYPE_IVEC4,{TYPE_ISAMPLER2D,TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"textureGrad",TYPE_UVEC4,{TYPE_USAMPLER2D,TYPE_VEC2,TYPE_VEC2,TYPE_VEC2,TYPE_VOID}},
+ {"textureGrad",TYPE_VEC4,{TYPE_SAMPLERCUBE,TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
+
+ {"textureScreen",TYPE_VEC4,{TYPE_VEC2,TYPE_VOID}},
+
+ {"dFdx",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
+ {"dFdx",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
+ {"dFdx",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
+ {"dFdx",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"dFdy",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
+ {"dFdy",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
+ {"dFdy",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
+ {"dFdy",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+ {"fwidth",TYPE_FLOAT,{TYPE_FLOAT,TYPE_VOID}},
+ {"fwidth",TYPE_VEC2,{TYPE_VEC2,TYPE_VOID}},
+ {"fwidth",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
+ {"fwidth",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
+
+
+ {NULL,TYPE_VOID,{TYPE_VOID}}
+
+};
+
+
+
+bool ShaderLanguage::_validate_function_call(BlockNode* p_block, OperatorNode *p_func,DataType *r_ret_type) {
ERR_FAIL_COND_V(p_func->op!=OP_CALL && p_func->op!=OP_CONSTRUCT,NULL);
@@ -1231,13 +1653,13 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
ERR_FAIL_COND_V( p_func->arguments[0]->type!=Node::TYPE_VARIABLE, NULL );
- String name = static_cast<VariableNode*>(p_func->arguments[0])->name.operator String();
+ StringName name = static_cast<VariableNode*>(p_func->arguments[0])->name.operator String();
bool all_const=true;
for(int i=1;i<p_func->arguments.size();i++) {
if (p_func->arguments[i]->type!=Node::TYPE_CONSTANT)
all_const=false;
- args.push_back(compute_node_type(p_func->arguments[i]));
+ args.push_back(p_func->arguments[i]->get_datatype());
}
int argcount=args.size();
@@ -1265,10 +1687,11 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
fail=true; //make sure the number of arguments matches
if (!fail) {
- p_func->return_cache=intrinsic_func_defs[idx].rettype;
found_intrinsic=true;
- break;
+ if (r_ret_type)
+ *r_ret_type=intrinsic_func_defs[idx].rettype;
+ return true;
}
}
@@ -1277,7 +1700,7 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
}
}
-
+#if 0
if (found_intrinsic) {
if (p_func->op==OP_CONSTRUCT && all_const) {
@@ -1290,6 +1713,7 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
switch(v.get_type()) {
case Variant::REAL: cdata.push_back(v); break;
+ case Variant::INT: cdata.push_back(v); break;
case Variant::VECTOR2: { Vector2 v2=v; cdata.push_back(v2.x); cdata.push_back(v2.y); } break;
case Variant::VECTOR3: { Vector3 v3=v; cdata.push_back(v3.x); cdata.push_back(v3.y); cdata.push_back(v3.z);} break;
case Variant::PLANE: { Plane v4=v; cdata.push_back(v4.normal.x); cdata.push_back(v4.normal.y); cdata.push_back(v4.normal.z); cdata.push_back(v4.d); } break;
@@ -1331,39 +1755,45 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
}
return p_func;
}
-
+#endif
// try existing functions..
- FunctionNode *exclude_function=NULL; //exclude current function (in case inside one)
+ StringName exclude_function;
+ BlockNode *block = p_block;
+ while(block) {
- Node *node = p_func;
+ if (block->parent_function) {
+ exclude_function=block->parent_function->name;
+ }
+ block=block->parent_block;
+ }
- while(node->parent) {
- if (node->type==Node::TYPE_FUNCTION) {
+ for(int i=0;i<shader->functions.size();i++) {
- exclude_function = (FunctionNode*)node;
+ if (shader->functions[i].name==exclude_function) {
+ _set_error("Recursion is not allowed");
+ return false;
}
- node=node->parent;
- }
-
- ERR_FAIL_COND_V(node->type!=Node::TYPE_PROGRAM,NULL);
- ProgramNode *program = (ProgramNode*)node;
-
- for(int i=0;i<program->functions.size();i++) {
+ if (!shader->functions[i].callable) {
+ _set_error("Function '"+String(name)+" can't be called from source code.");
+ return false;
+ }
- if (program->functions[i].function==exclude_function)
+ if (name != shader->functions[i].name)
continue;
- FunctionNode *pfunc = program->functions[i].function;
+ FunctionNode *pfunc = shader->functions[i].function;
+
if (pfunc->arguments.size()!=args.size())
continue;
bool fail=false;
+
for(int i=0;i<args.size();i++) {
if (args[i]!=pfunc->arguments[i].type) {
fail=true;
@@ -1371,153 +1801,94 @@ ShaderLanguage::Node* ShaderLanguage::validate_function_call(Parser&parser, Oper
}
}
- if (!fail && name == program->functions[i].name) {
+ if (!fail) {
p_func->return_cache=pfunc->return_type;
- return p_func;
+ return true;
}
}
- return NULL;
+ return false;
}
-ShaderLanguage::Node * ShaderLanguage::validate_operator(Parser& parser,OperatorNode *p_func) {
-
- int argcount = p_func->arguments.size();
- ERR_FAIL_COND_V(argcount>2,NULL);
-
- DataType argtype[2]={TYPE_VOID,TYPE_VOID};
- bool all_const=true;
-
- for(int i=0;i<argcount;i++) {
+bool ShaderLanguage::_parse_function_arguments(BlockNode* p_block,const Map<StringName,DataType> &p_builtin_types,OperatorNode* p_func) {
- argtype[i]=compute_node_type(p_func->arguments[i]);
- if (p_func->arguments[i]->type!=Node::TYPE_CONSTANT)
- all_const=false;
+ Token tk = _get_token();
- }
- int idx=0;
- bool valid=false;
- while(operator_defs[idx].op!=OP_MAX) {
+ while(true) {
- if (p_func->op==operator_defs[idx].op) {
+ if (tk.type==TK_PARENTHESIS_CLOSE) {
+ return true;
+ }
+ Node *arg= _parse_expression(p_block,p_builtin_types);
+ if (!arg)
+ return false;
+ p_func->arguments.push_back(arg);
- if (operator_defs[idx].args[0]==argtype[0] && operator_defs[idx].args[1]==argtype[1]) {
+ tk = _get_token();
- p_func->return_cache=operator_defs[idx].rettype;
- valid=true;
- break;
- }
+ if (tk.type==TK_PARENTHESIS_CLOSE) {
+ //none
+ } else if (tk.type==TK_COMMA) {
+ tk = _get_token(); //next
+ } else {
+ // something is broken
+ _set_error("Expected ',' or ')' after argument");
+ return false;
}
- idx++;
- }
-
- if (!valid)
- return NULL;
-
-#define _RCO2(m_op,m_vop)\
-case m_op: {\
- ConstantNode *cn = parser.create_node<ConstantNode>(p_func->parent);\
- cn->datatype=p_func->return_cache; \
- Variant::evaluate(m_vop,static_cast<ConstantNode*>(p_func->arguments[0])->value,static_cast<ConstantNode*>(p_func->arguments[1])->value,cn->value,valid);\
- if (!valid)\
- return NULL;\
- return cn;\
-} break;
-
-#define _RCO1(m_op,m_vop)\
-case m_op: {\
- ConstantNode *cn = parser.create_node<ConstantNode>(p_func->parent);\
- cn->datatype=p_func->return_cache; \
- Variant::evaluate(m_vop,static_cast<ConstantNode*>(p_func->arguments[0])->value,Variant(),cn->value,valid);\
- if (!valid)\
- return NULL;\
- return cn;\
-} break;
-
- if (all_const) {
- //reduce constant operator
- switch(p_func->op) {
- _RCO2(OP_ADD,Variant::OP_ADD);
- _RCO2(OP_SUB,Variant::OP_SUBSTRACT);
- _RCO2(OP_MUL,Variant::OP_MULTIPLY);
- _RCO2(OP_DIV,Variant::OP_DIVIDE);
- _RCO1(OP_NEG,Variant::OP_NEGATE);
- _RCO1(OP_NOT,Variant::OP_NOT);
- _RCO2(OP_CMP_EQ,Variant::OP_EQUAL);
- _RCO2(OP_CMP_NEQ,Variant::OP_NOT_EQUAL);
- _RCO2(OP_CMP_LEQ,Variant::OP_LESS_EQUAL);
- _RCO2(OP_CMP_GEQ,Variant::OP_GREATER_EQUAL);
- _RCO2(OP_CMP_LESS,Variant::OP_LESS);
- _RCO2(OP_CMP_GREATER,Variant::OP_GREATER);
- _RCO2(OP_CMP_OR,Variant::OP_OR);
- _RCO2(OP_CMP_AND,Variant::OP_AND);
- default: {}
- }
}
-
- return p_func;
-
+ return true;
}
bool ShaderLanguage::is_token_operator(TokenType p_type) {
- return (p_type==TK_OP_EQUAL) ||
- (p_type==TK_OP_NOT_EQUAL) ||
- (p_type==TK_OP_LESS) ||
- (p_type==TK_OP_LESS_EQUAL) ||
- (p_type==TK_OP_GREATER) ||
- (p_type==TK_OP_GREATER_EQUAL) ||
- (p_type==TK_OP_AND) ||
- (p_type==TK_OP_OR) ||
- (p_type==TK_OP_NOT) ||
- (p_type==TK_OP_ADD) ||
- (p_type==TK_OP_SUB) ||
- (p_type==TK_OP_MUL) ||
- (p_type==TK_OP_DIV) ||
- (p_type==TK_OP_NEG) ||
- (p_type==TK_OP_ASSIGN) ||
- (p_type==TK_OP_ASSIGN_ADD) ||
- (p_type==TK_OP_ASSIGN_SUB) ||
- (p_type==TK_OP_ASSIGN_MUL) ||
- (p_type==TK_OP_ASSIGN_DIV);
-}
-ShaderLanguage::Operator ShaderLanguage::get_token_operator(TokenType p_type) {
+ return (p_type==TK_OP_EQUAL ||
+ p_type==TK_OP_NOT_EQUAL ||
+ p_type==TK_OP_LESS ||
+ p_type==TK_OP_LESS_EQUAL ||
+ p_type==TK_OP_GREATER ||
+ p_type==TK_OP_GREATER_EQUAL ||
+ p_type==TK_OP_AND ||
+ p_type==TK_OP_OR ||
+ p_type==TK_OP_NOT ||
+ p_type==TK_OP_ADD ||
+ p_type==TK_OP_SUB ||
+ p_type==TK_OP_MUL ||
+ p_type==TK_OP_DIV ||
+ p_type==TK_OP_MOD ||
+ p_type==TK_OP_SHIFT_LEFT ||
+ p_type==TK_OP_SHIFT_RIGHT ||
+ p_type==TK_OP_ASSIGN ||
+ p_type==TK_OP_ASSIGN_ADD ||
+ p_type==TK_OP_ASSIGN_SUB ||
+ p_type==TK_OP_ASSIGN_MUL ||
+ p_type==TK_OP_ASSIGN_DIV ||
+ p_type==TK_OP_ASSIGN_MOD ||
+ p_type==TK_OP_ASSIGN_SHIFT_LEFT ||
+ p_type==TK_OP_ASSIGN_SHIFT_RIGHT ||
+ p_type==TK_OP_ASSIGN_BIT_AND ||
+ p_type==TK_OP_ASSIGN_BIT_OR ||
+ p_type==TK_OP_ASSIGN_BIT_XOR ||
+ p_type==TK_OP_BIT_AND ||
+ p_type==TK_OP_BIT_OR ||
+ p_type==TK_OP_BIT_XOR ||
+ p_type==TK_OP_BIT_INVERT ||
+ p_type==TK_OP_INCREMENT ||
+ p_type==TK_OP_DECREMENT ||
+ p_type==TK_QUESTION ||
+ p_type==TK_COLON );
- switch(p_type) {
- case TK_OP_EQUAL: return OP_CMP_EQ ;
- case TK_OP_NOT_EQUAL: return OP_CMP_NEQ;
- case TK_OP_LESS: return OP_CMP_LESS ;
- case TK_OP_LESS_EQUAL: return OP_CMP_LEQ ;
- case TK_OP_GREATER: return OP_CMP_GREATER ;
- case TK_OP_GREATER_EQUAL: return OP_CMP_GEQ ;
- case TK_OP_AND: return OP_CMP_AND ;
- case TK_OP_OR: return OP_CMP_OR ;
- case TK_OP_NOT: return OP_NOT ;
- case TK_OP_ADD: return OP_ADD ;
- case TK_OP_SUB: return OP_SUB ;
- case TK_OP_MUL: return OP_MUL ;
- case TK_OP_DIV: return OP_DIV ;
- case TK_OP_NEG: return OP_NEG ;
- case TK_OP_ASSIGN: return OP_ASSIGN ;
- case TK_OP_ASSIGN_ADD: return OP_ASSIGN_ADD ;
- case TK_OP_ASSIGN_SUB: return OP_ASSIGN_SUB ;
- case TK_OP_ASSIGN_MUL: return OP_ASSIGN_MUL ;
- case TK_OP_ASSIGN_DIV: return OP_ASSIGN_DIV ;
- default: ERR_FAIL_V(OP_MAX);
- }
-
- return OP_MAX;
}
-Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_expr) {
+
+ShaderLanguage::Node* ShaderLanguage::_parse_expression(BlockNode* p_block,const Map<StringName,DataType> &p_builtin_types) {
Vector<Expression> expression;
//Vector<TokenType> operators;
@@ -1525,416 +1896,413 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
while(true) {
Node *expr=NULL;
+ int pos = char_idx;
+ Token tk = _get_token();
- if (parser.get_token_type()==TK_PARENTHESIS_OPEN) {
+ if (tk.type==TK_PARENTHESIS_OPEN) {
//handle subexpression
- parser.advance();
- Error err = parse_expression(parser,p_parent,&expr);
- if (err)
- return err;
- if (parser.get_token_type()!=TK_PARENTHESIS_CLOSE) {
+ expr = _parse_expression(p_block,p_builtin_types);
+ if (!expr)
+ return NULL;
- parser.set_error("Expected ')' in expression");
- return ERR_PARSE_ERROR;
- }
+ tk = _get_token();
- parser.advance();
+ if (tk.type!=TK_PARENTHESIS_CLOSE) {
- } else if (parser.get_token_type()==TK_REAL_CONSTANT) {
+ _set_error("Expected ')' in expression");
+ return NULL;
+ }
+ } else if (tk.type==TK_REAL_CONSTANT) {
- ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
- constant->value=parser.get_token().text.operator String().to_double();
+
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ constant->value=tk.constant;
constant->datatype=TYPE_FLOAT;
expr=constant;
- parser.advance();
- } else if (parser.get_token_type()==TK_TRUE) {
+
+ } else if (tk.type==TK_REAL_CONSTANT) {
+
+
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ constant->value=int(tk.constant);
+ constant->datatype=TYPE_INT;
+ expr=constant;
+
+ } else if (tk.type==TK_TRUE) {
//print_line("found true");
//handle true constant
- ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
+ ConstantNode *constant = alloc_node<ConstantNode>();
constant->value=true;
constant->datatype=TYPE_BOOL;
expr=constant;
- parser.advance();
- } else if (parser.get_token_type()==TK_FALSE) {
+
+ } else if (tk.type==TK_FALSE) {
//handle false constant
- ConstantNode *constant = parser.create_node<ConstantNode>(p_parent);
+ ConstantNode *constant = alloc_node<ConstantNode>();
constant->value=false;
constant->datatype=TYPE_BOOL;
expr=constant;
- parser.advance();
- } else if (parser.get_token_type()==TK_TYPE_VOID) {
-
- //make sure void is not used in expression
- parser.set_error("Void value not allowed in Expression");
- return ERR_PARSE_ERROR;
- } else if (parser.get_token_type(1)==TK_PARENTHESIS_OPEN && (is_token_nonvoid_datatype(parser.get_token_type()) || parser.get_token_type()==TK_INDENTIFIER)) {
-
-
- //function or constructor
- StringName name;
- DataType constructor=TYPE_VOID;
- if (is_token_nonvoid_datatype(parser.get_token_type())) {
-
- constructor=get_token_datatype(parser.get_token_type());
- switch(get_token_datatype(parser.get_token_type())) {
- case TYPE_BOOL: name="bool"; break;
- case TYPE_FLOAT: name="float"; break;
- case TYPE_VEC2: name="vec2"; break;
- case TYPE_VEC3: name="vec3"; break;
- case TYPE_VEC4: name="vec4"; break;
- case TYPE_MAT2: name="mat2"; break;
- case TYPE_MAT3: name="mat3"; break;
- case TYPE_MAT4: name="mat4"; break;
- default: ERR_FAIL_V(ERR_BUG);
- }
- } else {
- name=parser.get_token().text;
- }
+ } else if (tk.type==TK_TYPE_VOID) {
- if (!test_existing_identifier(p_parent,name)) {
+ //make sure void is not used in expression
+ _set_error("Void value not allowed in Expression");
+ return NULL;
+ } else if (is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) {
+ //basic type constructor
- parser.set_error("Unknown identifier in expression: "+name);
- return ERR_PARSE_ERROR;
- }
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op=OP_CONSTRUCT;
- parser.advance(2);
- OperatorNode *func = parser.create_node<OperatorNode>(p_parent);
+ if (is_token_precision(tk.type)) {
- func->op=constructor!=TYPE_VOID?OP_CONSTRUCT:OP_CALL;
+ func->return_precision_cache=get_token_precision(tk.type);
+ tk=_get_token();
+ }
- VariableNode *funcname = parser.create_node<VariableNode>(func);
- funcname->name=name;
+ VariableNode *funcname = alloc_node<VariableNode>();
+ funcname->name=get_datatype_name(get_token_datatype(tk.type));
func->arguments.push_back(funcname);
- //parse parameters
-
- if (parser.get_token_type()==TK_PARENTHESIS_CLOSE) {
- parser.advance();
- } else {
-
- while(true) {
-
-
- Node *arg=NULL;
- Error err = parse_expression(parser,func,&arg);
- if (err)
- return err;
- func->arguments.push_back(arg);
-
- if (parser.get_token_type()==TK_PARENTHESIS_CLOSE) {
- parser.advance();
- break;
-
- } else if (parser.get_token_type()==TK_COMMA) {
-
- if (parser.get_token_type(1)==TK_PARENTHESIS_CLOSE) {
-
- parser.set_error("Expression expected");
- return ERR_PARSE_ERROR;
- }
-
- parser.advance();
- } else {
- // something is broken
- parser.set_error("Expected ',' or ')'");
- return ERR_PARSE_ERROR;
- }
-
- }
+ tk=_get_token();
+ if (tk.type!=TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after type name");
+ return NULL;
}
- expr=validate_function_call(parser,func);
- if (!expr) {
+ if (!_parse_function_arguments(p_block,p_builtin_types,func))
+ return NULL;
- parser.set_error("Invalid arguments to function/constructor: "+StringName(name));
- return ERR_PARSE_ERROR;
+ if (!_validate_function_call(p_block,func,&func->return_cache)) {
+ _set_error("No matching constructor found for: '"+String(funcname->name)+"'");
+ return NULL;
}
+ //validate_Function_call()
- } else if (parser.get_token_type()==TK_INDENTIFIER) {
- //probably variable
+ expr=func;
- Node *node =p_parent;
- bool existing=false;
- DataType datatype;
- StringName identifier=parser.get_token().text;
+ } else if (tk.type==TK_IDENTIFIER) {
- while(node) {
- if (node->type==Node::TYPE_BLOCK) {
+ tk=_get_token();
+ if (tk.type==TK_PARENTHESIS_OPEN) {
+ //a function
+ StringName name = tk.text;
- BlockNode *block = (BlockNode*)node;
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op=OP_CALL;
+ VariableNode *funcname = alloc_node<VariableNode>();
+ funcname->name=name;
+ func->arguments.push_back(funcname);
- if (block->variables.has(identifier)) {
- existing=true;
- datatype=block->variables[identifier];
- break;
- }
- }
+ if (!_parse_function_arguments(p_block,p_builtin_types,func))
+ return NULL;
- if (node->type==Node::TYPE_FUNCTION) {
- FunctionNode *function=(FunctionNode*)node;
- for(int i=0;i<function->arguments.size();i++) {
- if (function->arguments[i].name==identifier) {
- existing=true;
- datatype=function->arguments[i].type;
- break;
- }
- }
+ if (!_validate_function_call(p_block,func,&func->return_cache)) {
+ _set_error("No matching function found for: '"+String(funcname->name)+"'");
+ return NULL;
+ }
- if (existing)
- break;
+ expr=func;
- }
+ } else {
+ //an identifier
+ char_idx=pos; //rollback
- if (node->type==Node::TYPE_PROGRAM) {
+ StringName identifier = tk.text;
- ProgramNode *program = (ProgramNode*)node;
- if (program->builtin_variables.has(identifier)) {
- datatype = program->builtin_variables[identifier];
- existing=true;
- break;
- }
- if (program->uniforms.has(identifier)) {
- datatype = program->uniforms[identifier].type;
- existing=true;
- break;
- }
+ DataType data_type;
+ IdentifierType ident_type;
+ if (!_find_identifier(p_block,p_builtin_types,identifier,&data_type,&ident_type)) {
+ _set_error("Unknown identifier in expression: "+String(identifier));
+ return NULL;
}
- node=node->parent;
- }
+ if (ident_type==IDENTIFIER_FUNCTION) {
+ _set_error("Can't use function as identifier: "+String(identifier));
+ return NULL;
+ }
- if (!existing) {
- parser.set_error("Nonexistent identifier in expression: "+identifier);
- return ERR_PARSE_ERROR;
+ VariableNode *varname = alloc_node<VariableNode>();
+ varname->name=identifier;
+ varname->datatype_cache=data_type;
+ expr=varname;
}
- VariableNode *varname = parser.create_node<VariableNode>(p_parent);
- varname->name=identifier;
- varname->datatype_cache=datatype;
- parser.advance();
- expr=varname;
-
- } else if (parser.get_token_type()==TK_OP_SUB || parser.get_token_type()==TK_OP_NOT) {
- //single prefix operators
- TokenType token_type=parser.get_token_type();
- parser.advance();
- //Node *subexpr=NULL;
- //Error err = parse_expression(parser,p_parent,&subexpr);
- //if (err)
- // return err;
+ } else if (tk.type==TK_OP_ADD) {
+ continue; //this one does nothing
+ } if (tk.type==TK_OP_SUB || tk.type==TK_OP_NOT || tk.type==TK_OP_BIT_INVERT || tk.type==TK_OP_INCREMENT || tk.type==TK_OP_DECREMENT) {
- //OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
Expression e;
e.is_op=true;
- switch(token_type) {
- case TK_OP_SUB: e.op=TK_OP_NEG; break;
- case TK_OP_NOT: e.op=TK_OP_NOT; break;
- //case TK_OP_PLUS_PLUS: op->op=OP_PLUS_PLUS; break;
- //case TK_OP_MINUS_MINUS: op->op=OP_MINUS_MINUS; break;
- default: ERR_FAIL_V(ERR_BUG);
+ switch(tk.type) {
+ case TK_OP_SUB: e.op=OP_NEGATE; break;
+ case TK_OP_NOT: e.op=OP_NOT; break;
+ case TK_OP_BIT_INVERT: e.op=OP_BIT_INVERT; break;
+ case TK_OP_INCREMENT: e.op=OP_INCREMENT; break;
+ case TK_OP_DECREMENT: e.op=OP_DECREMENT; break;
+ default: ERR_FAIL_V(NULL);
}
expression.push_back(e);
-
continue;
} else {
- print_line("found bug?");
- print_line("misplaced token: "+String(token_names[parser.get_token_type()]));
-
- parser.set_error("Error parsing expression, misplaced: "+String(token_names[parser.get_token_type()]));
- return ERR_PARSE_ERROR;
+ _set_error("Expected expression, found: "+get_token_text(tk));
+ return NULL;
//nothing
}
- ERR_FAIL_COND_V(!expr,ERR_BUG);
+ ERR_FAIL_COND_V(!expr,NULL);
/* OK now see what's NEXT to the operator.. */
/* OK now see what's NEXT to the operator.. */
/* OK now see what's NEXT to the operator.. */
+ while(true) {
+ int pos = char_idx;
+ tk=_get_token();
- if (parser.get_token_type()==TK_PERIOD) {
-
- if (parser.get_token_type(1)!=TK_INDENTIFIER) {
- parser.set_error("Expected identifier as member");
- return ERR_PARSE_ERROR;
- }
-
- DataType dt = compute_node_type(expr);
- String ident = parser.get_token(1).text;
-
- bool ok=true;
- DataType member_type;
- switch(dt) {
- case TYPE_VEC2: {
-
- int l = ident.length();
- if (l==1) {
- member_type=TYPE_FLOAT;
- } else if (l==2) {
- member_type=TYPE_VEC2;
- } else {
- ok=false;
- break;
- }
+ if (tk.type==TK_PERIOD) {
- const CharType *c=ident.ptr();
- for(int i=0;i<l;i++) {
+ tk=_get_token();
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected identifier as member");
+ return NULL;
+ }
- switch(c[i]) {
- case 'r':
- case 'g':
- case 'x':
- case 'y':
- break;
- default:
- ok=false;
- break;
+ DataType dt = expr->get_datatype();
+ String ident = tk.text;
+
+ bool ok=true;
+ DataType member_type;
+ switch(dt) {
+ case TYPE_BVEC2:
+ case TYPE_IVEC2:
+ case TYPE_UVEC2:
+ case TYPE_VEC2: {
+
+ int l = ident.length();
+ if (l==1) {
+ member_type=DataType(dt-1);
+ } else if (l==2) {
+ member_type=dt;
+ } else {
+ ok=false;
+ break;
}
- }
- } break;
- case TYPE_VEC3: {
-
- int l = ident.length();
- if (l==1) {
- member_type=TYPE_FLOAT;
- } else if (l==2) {
- member_type=TYPE_VEC2;
- } else if (l==3) {
- member_type=TYPE_VEC3;
- } else {
- ok=false;
- break;
- }
+ const CharType *c=ident.ptr();
+ for(int i=0;i<l;i++) {
+
+ switch(c[i]) {
+ case 'r':
+ case 'g':
+ case 'x':
+ case 'y':
+ break;
+ default:
+ ok=false;
+ break;
+ }
+ }
- const CharType *c=ident.ptr();
- for(int i=0;i<l;i++) {
+ } break;
+ case TYPE_BVEC3:
+ case TYPE_IVEC3:
+ case TYPE_UVEC3:
+ case TYPE_VEC3: {
+
+ int l = ident.length();
+ if (l==1) {
+ member_type=DataType(dt-2);
+ } else if (l==2) {
+ member_type=DataType(dt-1);
+ } else if (l==3) {
+ member_type=dt;
+ } else {
+ ok=false;
+ break;
+ }
- switch(c[i]) {
- case 'r':
- case 'g':
- case 'b':
- case 'x':
- case 'y':
- case 'z':
- break;
- default:
- ok=false;
- break;
+ const CharType *c=ident.ptr();
+ for(int i=0;i<l;i++) {
+
+ switch(c[i]) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'x':
+ case 'y':
+ case 'z':
+ break;
+ default:
+ ok=false;
+ break;
+ }
}
- }
- } break;
- case TYPE_VEC4: {
-
- int l = ident.length();
- if (l==1) {
- member_type=TYPE_FLOAT;
- } else if (l==2) {
- member_type=TYPE_VEC2;
- } else if (l==3) {
- member_type=TYPE_VEC3;
- } else if (l==4) {
- member_type=TYPE_VEC4;
- } else {
- ok=false;
- break;
- }
+ } break;
+ case TYPE_BVEC4:
+ case TYPE_IVEC4:
+ case TYPE_UVEC4:
+ case TYPE_VEC4: {
+
+ int l = ident.length();
+ if (l==1) {
+ member_type=DataType(dt-3);
+ } else if (l==2) {
+ member_type=DataType(dt-2);
+ } else if (l==3) {
+ member_type=DataType(dt-1);;
+ } else if (l==4) {
+ member_type=dt;
+ } else {
+ ok=false;
+ break;
+ }
- const CharType *c=ident.ptr();
- for(int i=0;i<l;i++) {
-
- switch(c[i]) {
- case 'r':
- case 'g':
- case 'b':
- case 'a':
- case 'x':
- case 'y':
- case 'z':
- case 'w':
- break;
- default:
- ok=false;
- break;
+ const CharType *c=ident.ptr();
+ for(int i=0;i<l;i++) {
+
+ switch(c[i]) {
+ case 'r':
+ case 'g':
+ case 'b':
+ case 'a':
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'w':
+ break;
+ default:
+ ok=false;
+ break;
+ }
}
- }
- } break;
- case TYPE_MAT2: ok=(ident=="x" || ident=="y"); member_type=TYPE_VEC2; break;
- case TYPE_MAT3: ok=(ident=="x" || ident=="y" || ident=="z" ); member_type=TYPE_VEC3; break;
- case TYPE_MAT4: ok=(ident=="x" || ident=="y" || ident=="z" || ident=="w"); member_type=TYPE_VEC4; break;
- default: {}
- }
+ } break;
+ case TYPE_MAT2: ok=(ident=="x" || ident=="y"); member_type=TYPE_VEC2; break;
+ case TYPE_MAT3: ok=(ident=="x" || ident=="y" || ident=="z" ); member_type=TYPE_VEC3; break;
+ case TYPE_MAT4: ok=(ident=="x" || ident=="y" || ident=="z" || ident=="w"); member_type=TYPE_VEC4; break;
+ default: {}
+ }
- if (!ok) {
+ if (!ok) {
- parser.set_error("Invalid member for expression: ."+ident);
- return ERR_PARSE_ERROR;
- }
+ _set_error("Invalid member for expression: ."+ident);
+ return NULL;
+ }
- MemberNode *mn = parser.create_node<MemberNode>(p_parent);
- mn->basetype=dt;
- mn->datatype=member_type;
- mn->name=ident;
- mn->owner=expr;
- expr=mn;
+ MemberNode *mn = alloc_node<MemberNode>();
+ mn->basetype=dt;
+ mn->datatype=member_type;
+ mn->name=ident;
+ mn->owner=expr;
+ expr=mn;
- parser.advance(2);
- //todo
- //member (period) has priority over any operator
- //creates a subindexing expression in place
+ //todo
+ //member (period) has priority over any operator
+ //creates a subindexing expression in place
- } else if (parser.get_token_type()==TK_BRACKET_OPEN) {
- //todo
- //subindexing has priority over any operator
- //creates a subindexing expression in place
+ /*} else if (tk.type==TK_BRACKET_OPEN) {
+ //todo
+ //subindexing has priority over any operator
+ //creates a subindexing expression in place
- } /*else if (parser.get_token_type()==TK_OP_PLUS_PLUS || parser.get_token_type()==TK_OP_MINUS_MINUS) {
- //todo
- //inc/dec operators have priority over any operator
- //creates a subindexing expression in place
- //return OK; //wtfs
+ */
+ } else if (tk.type==TK_OP_INCREMENT || tk.type==TK_OP_DECREMENT) {
- } */
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=tk.type==TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT;
+ op->arguments.push_back(expr);
+
+ if (!_validate_operator(op,&op->return_cache)) {
+ _set_error("Invalid base type for increment/decrement operator");
+ return NULL;
+ }
+ expr=op;
+ } else {
+ char_idx=pos; //rollback
+ break;
+ }
+ }
Expression e;
e.is_op=false;
e.node=expr;
expression.push_back(e);
+ pos = char_idx;
+ tk = _get_token();
- if (is_token_operator(parser.get_token_type())) {
+ if (is_token_operator(tk.type)) {
Expression o;
o.is_op=true;
- o.op=parser.get_token_type();
+
+ switch(tk.type) {
+
+ case TK_OP_EQUAL: o.op = OP_EQUAL; break;
+ case TK_OP_NOT_EQUAL: o.op = OP_NOT_EQUAL; break;
+ case TK_OP_LESS: o.op = OP_LESS; break;
+ case TK_OP_LESS_EQUAL: o.op = OP_LESS_EQUAL; break;
+ case TK_OP_GREATER: o.op = OP_GREATER; break;
+ case TK_OP_GREATER_EQUAL: o.op = OP_GREATER_EQUAL; break;
+ case TK_OP_AND: o.op = OP_AND; break;
+ case TK_OP_OR: o.op = OP_OR; break;
+ case TK_OP_ADD: o.op = OP_ADD; break;
+ case TK_OP_SUB: o.op = OP_SUB; break;
+ case TK_OP_MUL: o.op = OP_MUL; break;
+ case TK_OP_DIV: o.op = OP_DIV; break;
+ case TK_OP_MOD: o.op = OP_MOD; break;
+ case TK_OP_SHIFT_LEFT: o.op = OP_SHIFT_LEFT; break;
+ case TK_OP_SHIFT_RIGHT: o.op = OP_SHIFT_RIGHT; break;
+ case TK_OP_ASSIGN: o.op = OP_ASSIGN; break;
+ case TK_OP_ASSIGN_ADD: o.op = OP_ASSIGN_ADD; break;
+ case TK_OP_ASSIGN_SUB: o.op = OP_ASSIGN_SUB; break;
+ case TK_OP_ASSIGN_MUL: o.op = OP_ASSIGN_MUL; break;
+ case TK_OP_ASSIGN_DIV: o.op = OP_ASSIGN_DIV; break;
+ case TK_OP_ASSIGN_MOD: o.op = OP_ASSIGN_MOD; break;
+ case TK_OP_ASSIGN_SHIFT_LEFT: o.op = OP_ASSIGN_SHIFT_LEFT; break;
+ case TK_OP_ASSIGN_SHIFT_RIGHT: o.op = OP_ASSIGN_SHIFT_RIGHT; break;
+ case TK_OP_ASSIGN_BIT_AND: o.op = OP_ASSIGN_BIT_AND; break;
+ case TK_OP_ASSIGN_BIT_OR: o.op = OP_ASSIGN_BIT_OR; break;
+ case TK_OP_ASSIGN_BIT_XOR: o.op = OP_ASSIGN_BIT_XOR; break;
+ case TK_OP_BIT_AND: o.op = OP_BIT_AND; break;
+ case TK_OP_BIT_OR: o.op = OP_BIT_OR ; break;
+ case TK_OP_BIT_XOR: o.op = OP_BIT_XOR; break;
+ case TK_QUESTION: o.op = OP_SELECT_IF; break;
+ case TK_COLON: o.op = OP_SELECT_ELSE; break;
+ default: {
+ _set_error("Invalid token for operator: "+get_token_text(tk));
+ return NULL;
+ }
+ } break;
+
expression.push_back(o);
- parser.advance();
+
} else {
+ char_idx=pos; //something else, so rollback and end
break;
}
}
@@ -1948,6 +2316,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
int next_op=-1;
int min_priority=0xFFFFF;
bool is_unary=false;
+ bool is_ternary=false;
for(int i=0;i<expression.size();i++) {
@@ -1957,45 +2326,48 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
}
bool unary=false;
+ bool ternary=false;
int priority;
switch(expression[i].op) {
-
- case TK_OP_NOT: priority=0; unary=true; break;
- case TK_OP_NEG: priority=0; unary=true; break;
-
- case TK_OP_MUL: priority=1; break;
- case TK_OP_DIV: priority=1; break;
-
- case TK_OP_ADD: priority=2; break;
- case TK_OP_SUB: priority=2; break;
-
- // shift left/right =2
-
- case TK_OP_LESS: priority=4; break;
- case TK_OP_LESS_EQUAL: priority=4; break;
- case TK_OP_GREATER: priority=4; break;
- case TK_OP_GREATER_EQUAL: priority=4; break;
-
- case TK_OP_EQUAL: priority=5; break;
- case TK_OP_NOT_EQUAL: priority=5; break;
-
- //bit and =5
- //bit xor =6
- //bit or=7
-
- case TK_OP_AND: priority=8; break;
- case TK_OP_OR: priority=9; break;
-
- // ?: = 10
-
- case TK_OP_ASSIGN_ADD: priority=11; break;
- case TK_OP_ASSIGN_SUB: priority=11; break;
- case TK_OP_ASSIGN_MUL: priority=11; break;
- case TK_OP_ASSIGN_DIV: priority=11; break;
- case TK_OP_ASSIGN: priority=11; break;
-
- default: ERR_FAIL_V(ERR_BUG); //unexpected operator
+ case OP_EQUAL: priority=8; break;
+ case OP_NOT_EQUAL: priority=8; break;
+ case OP_LESS: priority=7; break;
+ case OP_LESS_EQUAL: priority=7; break;
+ case OP_GREATER: priority=7; break;
+ case OP_GREATER_EQUAL: priority=7; break;
+ case OP_AND: priority=12; break;
+ case OP_OR: priority=14; break;
+ case OP_NOT: priority=3; unary=true; break;
+ case OP_NEGATE: priority=3; unary=true; break;
+ case OP_ADD: priority=5; break;
+ case OP_SUB: priority=5; break;
+ case OP_MUL: priority=4; break;
+ case OP_DIV: priority=4; break;
+ case OP_MOD: priority=4; break;
+ case OP_SHIFT_LEFT: priority=6; break;
+ case OP_SHIFT_RIGHT: priority=6; break;
+ case OP_ASSIGN: priority=16; break;
+ case OP_ASSIGN_ADD: priority=16; break;
+ case OP_ASSIGN_SUB: priority=16; break;
+ case OP_ASSIGN_MUL: priority=16; break;
+ case OP_ASSIGN_DIV: priority=16; break;
+ case OP_ASSIGN_MOD: priority=16; break;
+ case OP_ASSIGN_SHIFT_LEFT: priority=16; break;
+ case OP_ASSIGN_SHIFT_RIGHT: priority=16; break;
+ case OP_ASSIGN_BIT_AND: priority=16; break;
+ case OP_ASSIGN_BIT_OR: priority=16; break;
+ case OP_ASSIGN_BIT_XOR: priority=16; break;
+ case OP_BIT_AND: priority=9; break;
+ case OP_BIT_OR: priority=11; break;
+ case OP_BIT_XOR: priority=10; break;
+ case OP_BIT_INVERT: priority=3; unary=true; break;
+ case OP_INCREMENT: priority=3; unary=true; break;
+ case OP_DECREMENT: priority=3; unary=true; break;
+ case OP_SELECT_IF: priority=15; ternary=true; break;
+ case OP_SELECT_ELSE: priority=15; ternary=true; break;
+
+ default: ERR_FAIL_V(NULL); //unexpected operator
}
@@ -2005,11 +2377,12 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
next_op=i;
min_priority=priority;
is_unary=unary;
+ is_ternary=ternary;
}
}
- ERR_FAIL_COND_V(next_op==-1,ERR_BUG);
+ ERR_FAIL_COND_V(next_op==-1,NULL);
// OK! create operator..
// OK! create operator..
@@ -2021,48 +2394,90 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
expr_pos++;
if (expr_pos==expression.size()) {
//can happen..
- parser.set_error("Unexpected end of expression..");
- return ERR_BUG;
+ _set_error("Unexpected end of expression..");
+ return NULL;
}
}
//consecutively do unary opeators
for(int i=expr_pos-1;i>=next_op;i--) {
- OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
- op->op=get_token_operator(expression[i].op);
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=expression[i].op;
op->arguments.push_back(expression[i+1].node);
expression[i].is_op=false;
- expression[i].node=validate_operator(parser,op);
- if (!expression[i].node) {
+ expression[i].node=op;
+
+
+ if (!_validate_operator(op,&op->return_cache)) {
String at;
for(int i=0;i<op->arguments.size();i++) {
if (i>0)
at+=" and ";
- at+=get_datatype_name(compute_node_type(op->arguments[i]));
+ at+=get_datatype_name(op->arguments[i]->get_datatype());
}
- parser.set_error("Invalid argument to unary operator "+String(token_names[op->op])+": "+at);
- return ERR_PARSE_ERROR;
+ _set_error("Invalid argument to unary operator: "+at);
+ return NULL;
}
expression.remove(i+1);
}
+
+ } else if (is_ternary) {
+
+ if (next_op <1 || next_op>=(expression.size()-1)) {
+ _set_error("Parser bug..");
+ ERR_FAIL_V(NULL);
+ }
+
+ if (next_op+2 >= expression.size() || !expression[next_op+2].is_op || expression[next_op+2].op!=OP_SELECT_ELSE) {
+ _set_error("Mising matching ':' for select operator");
+ return NULL;
+ }
+
+
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=expression[next_op].op;
+ op->arguments.push_back(expression[next_op-1].node);
+ op->arguments.push_back(expression[next_op+1].node);
+ op->arguments.push_back(expression[next_op+3].node);
+
+ expression[next_op-1].is_op=false;
+ expression[next_op-1].node=op;
+ if (!_validate_operator(op,&op->return_cache)) {
+
+ String at;
+ for(int i=0;i<op->arguments.size();i++) {
+ if (i>0)
+ at+=" and ";
+ at+=get_datatype_name(op->arguments[i]->get_datatype());
+
+ }
+ _set_error("Invalid argument to ternary ?: operator: "+at);
+ return NULL;
+ }
+
+ for(int i=0;i<4;i++) {
+ expression.remove(next_op);
+ }
+
} else {
if (next_op <1 || next_op>=(expression.size()-1)) {
- parser.set_error("Parser bug..");
- ERR_FAIL_V(ERR_BUG);
+ _set_error("Parser bug..");
+ ERR_FAIL_V(NULL);
}
- OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
- op->op=get_token_operator(expression[next_op].op);
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=expression[next_op].op;
if (expression[next_op-1].is_op) {
- parser.set_error("Parser bug..");
- ERR_FAIL_V(ERR_BUG);
+ _set_error("Parser bug..");
+ ERR_FAIL_V(NULL);
}
if (expression[next_op+1].is_op) {
@@ -2071,645 +2486,660 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
// can be followed by an unary op in a valid combination,
// due to how precedence works, unaries will always dissapear first
- parser.set_error("Parser bug..");
+ _set_error("Parser bug..");
}
op->arguments.push_back(expression[next_op-1].node); //expression goes as left
op->arguments.push_back(expression[next_op+1].node); //next expression goes as right
+ expression[next_op-1].node=op;
//replace all 3 nodes by this operator and make it an expression
- expression[next_op-1].node=validate_operator(parser,op);
- if (!expression[next_op-1].node) {
+
+ if (!_validate_operator(op,&op->return_cache)) {
String at;
for(int i=0;i<op->arguments.size();i++) {
if (i>0)
at+=" and ";
- at+=get_datatype_name(compute_node_type(op->arguments[i]));
+ at+=get_datatype_name(op->arguments[i]->get_datatype());
}
- static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"};
-
- parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at);
- return ERR_PARSE_ERROR;
+ _set_error("Invalid arguments to operator: "+at);
+ return NULL;
}
+
expression.remove(next_op);
expression.remove(next_op);
}
-#if 0
- OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
- op->op=get_token_operator(operators[next_op]);
+ }
- op->arguments.push_back(expressions[next_op]); //expression goes as left
- op->arguments.push_back(expressions[next_op+1]); //next expression goes as right
+ return expression[0].node;
+}
- expressions[next_op]=validate_operator(parser,op);
- if (!expressions[next_op]) {
- String at;
- for(int i=0;i<op->arguments.size();i++) {
- if (i>0)
- at+=" and ";
- at+=get_datatype_name(compute_node_type(op->arguments[i]));
+ShaderLanguage::Node* ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) {
- }
- parser.set_error("Invalid arguments to operator "+String(token_names[operators[next_op]])+": "+at);
- return ERR_PARSE_ERROR;
- }
+ if (p_node->type!=Node::TYPE_OPERATOR)
+ return p_node;
+ //for now only reduce simple constructors
+ OperatorNode *op=static_cast<OperatorNode*>(p_node);
- expressions.remove(next_op+1);
- operators.remove(next_op);
-#endif
+ if (op->op==OP_CONSTRUCT) {
- }
+ ERR_FAIL_COND_V(op->arguments[0]->type!=Node::TYPE_VARIABLE,p_node);
+ VariableNode *vn = static_cast<VariableNode*>(op->arguments[0]);
+ StringName name=vn->name;
- *r_expr=expression[0].node;
+ if (name=="vec2" || name=="vec3" || name=="vec4") {
+ Vector<Variant> values;
- return OK;
+ for(int i=1;i<op->arguments.size();i++) {
-/*
- TokenType token_type=parser.get_token_type();
- OperatorNode *op = parser.create_node<OperatorNode>(p_parent);
- op->op=get_token_operator(parser.get_token_type());
+ op->arguments[i]=_reduce_expression(p_block,op->arguments[i]);
+ if (op->arguments[i]->type==Node::TYPE_CONSTANT) {
+ ConstantNode *cn = static_cast<ConstantNode*>(op->arguments[i]);
+ values.push_back(cn->value);
- op->arguments.push_back(*r_expr); //expression goes as left
- parser.advance();
- Node *right_expr=NULL;
- Error err = parse_expression(parser,p_parent,&right_expr);
- if (err)
- return err;
- op->arguments.push_back(right_expr);
+ } else {
+ return p_node; //do not bother, not reducible
+ }
+ }
- if (!validate_operator(op)) {
+ ConstantNode *cn=alloc_node<ConstantNode>();
- parser.set_error("Invalid arguments to operator "+String(token_names[token_type]));
- return ERR_PARSE_ERROR;
+ if (name=="vec2") {
+ cn->datatype=TYPE_VEC2;
+ cn->value=Vector2(values[0],values[1]);
+ } else if (name=="vec3") {
+ cn->datatype=TYPE_VEC3;
+ cn->value=Vector3(values[0],values[1],values[2]);
+ } else if (name=="vec4") {
+ cn->datatype=TYPE_VEC4;
+ cn->value=Plane(values[0],values[1],values[2],values[3]);
+ } else {
+ ERR_FAIL_V(p_node);
}
-*/
+ return cn;
+ }
+ }
+
+
+ return p_node;
+
}
-Error ShaderLanguage::parse_variable_declaration(Parser& parser,BlockNode *p_block) {
- bool uniform = parser.get_token(-1).type==TK_UNIFORM;
+ShaderLanguage::Node* ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName,DataType> &p_builtin_types) {
- DataType type=get_token_datatype(parser.get_token_type(0));
- bool iscolor = parser.get_token_type(0)==TK_TYPE_COLOR;
- if (type==TYPE_VOID) {
+ ShaderLanguage::Node* expr = _parse_expression(p_block,p_builtin_types);
- parser.set_error("Cannot Declare a 'void' Variable");
- return ERR_PARSE_ERROR;
- }
+ expr = _reduce_expression(p_block,expr);
- if (type==TYPE_TEXTURE && !uniform) {
+ return expr;
+}
- parser.set_error("Cannot Declare a Non-Uniform Texture");
- return ERR_PARSE_ERROR;
- }
- if (type==TYPE_CUBEMAP && !uniform) {
- parser.set_error("Cannot Declare a Non-Uniform Cubemap");
- return ERR_PARSE_ERROR;
- }
- parser.advance();
- int found=0;
+Error ShaderLanguage::_parse_block(BlockNode* p_block,const Map<StringName,DataType> &p_builtin_types,bool p_just_one,bool p_can_break,bool p_can_continue) {
while(true) {
+ int pos = char_idx;
- if (found && parser.get_token_type()!=TK_COMMA) {
- break;
- }
+ Token tk = _get_token();
+ if (tk.type==TK_CURLY_BRACKET_CLOSE) { //end of block
+ if (p_just_one) {
+ _set_error("Unexpected '}'");
+ return ERR_PARSE_ERROR;
+ }
- if (parser.get_token_type()!=TK_INDENTIFIER) {
+ return OK;
- parser.set_error("Identifier Expected");
- return ERR_PARSE_ERROR;
+ } else if (is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) {
+ DataPrecision precision=PRECISION_DEFAULT;
+ if (is_token_precision(tk.type)) {
+ precision=get_token_precision(tk.type);
+ tk = _get_token();
+ if (!is_token_nonvoid_datatype(tk.type)) {
+ _set_error("Expected datatype after precission");
+ return ERR_PARSE_ERROR;
+ }
+ }
- }
+ DataType type = get_token_datatype(tk.type);
- StringName name = parser.get_token().text;
+ tk = _get_token();
- if (test_existing_identifier(p_block,name)) {
- parser.set_error("Duplicate Identifier (existing variable/function): "+name);
- return ERR_PARSE_ERROR;
- }
+ while(true) {
- found=true;
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected identifier after type");
+ return ERR_PARSE_ERROR;
+ }
- parser.advance();
- //see if declaration has an initializer
- if (parser.get_token_type()==TK_OP_ASSIGN) {
- parser.advance();
- OperatorNode * op = parser.create_node<OperatorNode>(p_block);
- VariableNode * var = parser.create_node<VariableNode>(op);
- var->name=name;
- var->datatype_cache=type;
- var->uniform=uniform;
- Node *expr;
- Error err = parse_expression(parser,p_block,&expr);
+ StringName name = tk.text;
+ if (_find_identifier(p_block,p_builtin_types,name)) {
+ _set_error("Redefinition of '"+String(name)+"'");
+ return ERR_PARSE_ERROR;
+ }
- if (err)
- return err;
+ BlockNode::Variable var;
+ var.type=type;
+ var.precision=precision;
+ p_block->variables[name]=var;
- if (var->uniform) {
+ tk = _get_token();
- if (expr->type!=Node::TYPE_CONSTANT) {
+ if (tk.type==TK_OP_ASSIGN) {
+ //variable creted with assignment! must parse an expression
+ Node* n = _parse_and_reduce_expression(p_block,p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
- parser.set_error("Uniform can only be initialized to a constant.");
- return ERR_PARSE_ERROR;
+ OperatorNode *assign = alloc_node<OperatorNode>();
+ VariableNode *vnode = alloc_node<VariableNode>();
+ vnode->name=name;
+ vnode->datatype_cache=type;
+ assign->arguments.push_back(vnode);
+ assign->arguments.push_back(n);
+ assign->op=OP_ASSIGN;
+ p_block->statements.push_back(assign);
+ tk = _get_token();
}
- Uniform u;
- u.order=parser.program->uniforms.size();
- u.type=type;
- u.default_value=static_cast<ConstantNode*>(expr)->value;
- if (iscolor && u.default_value.get_type()==Variant::PLANE) {
- Color c;
- Plane p = u.default_value;
- c=Color(p.normal.x,p.normal.y,p.normal.z,p.d);
- u.default_value=c;
- }
- parser.program->uniforms[var->name]=u;
- } else {
- op->op=OP_ASSIGN;
- op->arguments.push_back(var);
- op->arguments.push_back(expr);
- Node *n=validate_operator(parser,op);
- if (!n) {
- parser.set_error("Invalid initializer for variable: "+name);
+ if (tk.type==TK_COMMA) {
+ tk = _get_token();
+ //another variable
+ } else if (tk.type==TK_SEMICOLON) {
+ break;
+ } else {
+ _set_error("Expected ',' or ';' after variable");
return ERR_PARSE_ERROR;
}
- p_block->statements.push_back(n);
+ }
+ } else if (tk.type==TK_CURLY_BRACKET_OPEN) {
+ //a sub block, just because..
+ BlockNode* block = alloc_node<BlockNode>();
+ block->parent_block=p_block;
+ _parse_block(block,p_builtin_types,false,p_can_break,p_can_continue);
+ } else if (tk.type==TK_CF_IF) {
+ //if () {}
+ tk = _get_token();
+ if (tk.type!=TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after if");
+ return ERR_PARSE_ERROR;
}
- } else {
- //initialize it EMPTY
-
- OperatorNode * op = parser.create_node<OperatorNode>(p_block);
- VariableNode * var = parser.create_node<VariableNode>(op);
- ConstantNode * con = parser.create_node<ConstantNode>(op);
-
- var->name=name;
- var->datatype_cache=type;
- var->uniform=uniform;
- con->datatype=type;
-
- switch(type) {
- case TYPE_BOOL: con->value=false; break;
- case TYPE_FLOAT: con->value=0.0; break;
- case TYPE_VEC2: con->value=Vector2(); break;
- case TYPE_VEC3: con->value=Vector3(); break;
- case TYPE_VEC4: con->value=iscolor?Variant(Color()):Variant(Plane()); break;
- case TYPE_MAT2: con->value=Matrix32(); break;
- case TYPE_MAT3: con->value=Matrix3(); break;
- case TYPE_MAT4: con->value=Transform(); break;
- case TYPE_TEXTURE:
- case TYPE_CUBEMAP: con->value=RID(); break;
- default: {}
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op=FLOW_OP_IF;
+ Node* n = _parse_and_reduce_expression(p_block,p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ tk = _get_token();
+ if (tk.type!=TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected '(' after expression");
+ return ERR_PARSE_ERROR;
}
- if (uniform) {
- Uniform u;
- u.type=type;
- u.default_value=con->value;
- u.order=parser.program->uniforms.size();
- parser.program->uniforms[var->name]=u;
+ BlockNode* block = alloc_node<BlockNode>();
+ block->parent_block=p_block;
+ cf->blocks.push_back(block);
+
+
+ Error err=_parse_block(p_block,p_builtin_types,true,p_can_break,p_can_continue);
+
+ pos=char_idx;
+ tk = _get_token();
+ if (tk.type==TK_CF_ELSE) {
+
+ block = alloc_node<BlockNode>();
+ block->parent_block=p_block;
+ cf->blocks.push_back(block);
+ err=_parse_block(p_block,p_builtin_types,true,p_can_break,p_can_continue);
} else {
- op->op=OP_ASSIGN;
- op->arguments.push_back(var);
- op->arguments.push_back(con);
- p_block->statements.push_back(op);
+ char_idx=pos; //rollback
}
- }
+ } else {
- if (!uniform)
- p_block->variables[name]=type;
+ //nothng else, so expression
+ char_idx=pos; //rollback
+ _parse_and_reduce_expression(p_block,p_builtin_types);
+ tk = _get_token();
- }
+ if (tk.type!=TK_SEMICOLON) {
+ _set_error("Expected ';' after statement");
+ return ERR_PARSE_ERROR;
+ }
+ }
- if (parser.get_token_type()!=TK_SEMICOLON) {
- parser.set_error("Expected ';'");
- return ERR_PARSE_ERROR;
+ if (p_just_one)
+ break;
}
-
return OK;
-
}
-Error ShaderLanguage::parse_flow_if(Parser& parser,Node *p_parent,Node **r_statement) {
- ControlFlowNode *cf = parser.create_node<ControlFlowNode>(p_parent);
+Error ShaderLanguage::_parse_shader(const Map< StringName, Map<StringName,DataType> > &p_functions, const Set<String> &p_render_modes) {
- cf->flow_op=FLOW_OP_IF;
- parser.advance();
+ Token tk = _get_token();
- if (parser.get_token_type()!=TK_PARENTHESIS_OPEN) {
- parser.set_error("Expected '(' after 'if'");
- return ERR_PARSE_ERROR;
- }
- parser.advance();
+ while(tk.type!=TK_EOF) {
- Node *expression=NULL;
- Error err = parse_expression(parser,cf,&expression);
- if (err)
- return err;
+ switch(tk.type) {
+ case TK_RENDER_MODE: {
- if (compute_node_type(expression)!=TYPE_BOOL) {
+ while(true) {
+ tk = _get_token();
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected identifier for render mode");
+ return ERR_PARSE_ERROR;
+ }
- parser.set_error("Expression for 'if' is not boolean");
- return ERR_PARSE_ERROR;
- }
+ if (!p_render_modes.has(tk.text)) {
+ _set_error("Invalid render mode: '"+String(tk.text)+"'");
+ return ERR_PARSE_ERROR;
+ }
- cf->statements.push_back(expression);
+ if (shader->render_modes.has(tk.text)) {
+ _set_error("Duplicate render mode: '"+String(tk.text)+"'");
+ return ERR_PARSE_ERROR;
+ }
- if (parser.get_token_type()!=TK_PARENTHESIS_CLOSE) {
- parser.set_error("Expected ')' after expression");
- return ERR_PARSE_ERROR;
- }
+ shader->render_modes.insert(tk.text);
- parser.advance();
+ tk = _get_token();
+ if (tk.type==TK_COMMA) {
+ //all good, do nothing
+ } else if (tk.type==TK_SEMICOLON) {
+ break; //done
+ } else {
+ _set_error("Unexpected token: "+get_token_text(tk));
+ return ERR_PARSE_ERROR;
+ }
+ }
+ } break;
+ case TK_UNIFORM:
+ case TK_VARYING: {
+
+ bool uniform = tk.type==TK_UNIFORM;
+ DataPrecision precision = PRECISION_DEFAULT;
+ DataType type;
+ StringName name;
+
+ tk = _get_token();
+ if (is_token_precision(tk.type)) {
+ precision=get_token_precision(tk.type);
+ tk = _get_token();
+ }
- if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
- parser.set_error("Expected statement block after 'if()'");
- return ERR_PARSE_ERROR;
- }
+ if (!is_token_datatype(tk.type)) {
+ _set_error("Expected datatype. ");
+ return ERR_PARSE_ERROR;
+ }
- Node *substatement=NULL;
- err = parse_statement(parser,cf,&substatement);
- if (err)
- return err;
+ type = get_token_datatype(tk.type);
- cf->statements.push_back(substatement);
+ if (type==TYPE_VOID) {
+ _set_error("void datatype not allowed here");
+ return ERR_PARSE_ERROR;
+ }
+ if (!uniform && type<TYPE_FLOAT && type>TYPE_VEC4) {
+ _set_error("Invalid type for varying, only float,vec2,vec3,vec4 allowed.");
+ return ERR_PARSE_ERROR;
+ }
- if (parser.get_token_type()==TK_CF_ELSE) {
+ tk = _get_token();
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected identifier!");
+ return ERR_PARSE_ERROR;
+ }
- parser.advance();
+ name=tk.text;
- if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
- parser.set_error("Expected statement block after 'else'");
- return ERR_PARSE_ERROR;
- }
+ if (_find_identifier(NULL,Map<StringName,DataType>(),name)) {
+ _set_error("Redefinition of '"+String(name)+"'");
+ return ERR_PARSE_ERROR;
+ }
- substatement=NULL;
- err = parse_statement(parser,cf,&substatement);
- if (err)
- return err;
+ if (uniform) {
- cf->statements.push_back(substatement);
- }
+ ShaderNode::Uniform uniform;
+ uniform.order=shader->uniforms.size();
+ uniform.type=type;
+ uniform.precission=precision;
+ shader->uniforms[name]=uniform;
+ //todo parse default value
+ tk = _get_token();
+ if (tk.type==TK_OP_ASSIGN) {
- *r_statement=cf;
+ Node* expr = _parse_and_reduce_expression(NULL,Map<StringName,DataType>());
+ if (!expr)
+ return ERR_PARSE_ERROR;
+ if (expr->type!=Node::TYPE_CONSTANT) {
+ _set_error("Expected constant expression after '='");
+ return ERR_PARSE_ERROR;
+ }
- return OK;
-}
+ uniform.default_value=static_cast<ConstantNode*>(expr)->value;
+ tk = _get_token();
+ }
-Error ShaderLanguage::parse_flow_return(Parser& parser,Node *p_parent,Node **r_statement) {
+ if (tk.type==TK_COLON) {
+ //hint
+ tk = _get_token();
+ if (tk.type==TK_HINT_WHITE_TEXTURE) {
+ uniform.hint=ShaderNode::Uniform::HINT_WHITE_TEXTURE;
+ } else if (tk.type==TK_HINT_BLACK_TEXTURE) {
+ uniform.hint=ShaderNode::Uniform::HINT_BLACK_TEXTURE;
+ } else if (tk.type==TK_HINT_NORMAL_TEXTURE) {
+ uniform.hint=ShaderNode::Uniform::HINT_NORMAL_TEXTURE;
+ } else if (tk.type==TK_HINT_RANGE) {
+ uniform.hint=ShaderNode::Uniform::HINT_RANGE;
+ if (type!=TYPE_FLOAT && type!=TYPE_INT) {
+ _set_error("Range hint is for float and int only");
+ return ERR_PARSE_ERROR;
+ }
- FunctionNode *function=NULL;
+ tk = _get_token();
+ if (tk.type!=TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after hint_range");
+ return ERR_PARSE_ERROR;
+ }
- Node *parent=p_parent;
+ tk = _get_token();
- while(parent) {
+ if (tk.type!=TK_REAL_CONSTANT ||tk.type!=TK_INT_CONSTANT) {
+ _set_error("Expected integer constant");
+ return ERR_PARSE_ERROR;
+ }
- if (parent->type==Node::TYPE_FUNCTION) {
+ uniform.hint_range[0]=tk.constant;
- function=(FunctionNode*)parent;
- break;
- }
+ tk = _get_token();
- parent=parent->parent;
- }
+ if (tk.type!=TK_COMMA) {
+ _set_error("Expected ',' after integer constant");
+ return ERR_PARSE_ERROR;
+ }
- if (!function) {
+ tk = _get_token();
- parser.set_error("'return' must be inside a function");
- return ERR_PARSE_ERROR;
- }
+ if (tk.type!=TK_REAL_CONSTANT || tk.type!=TK_INT_CONSTANT) {
+ _set_error("Expected integer constant after ','");
+ return ERR_PARSE_ERROR;
+ }
- ControlFlowNode *cf = parser.create_node<ControlFlowNode>(p_parent);
+ uniform.hint_range[1]=tk.constant;
- cf->flow_op=FLOW_OP_RETURN;
+ tk = _get_token();
- parser.advance();
+ if (tk.type==TK_COMMA) {
+ tk = _get_token();
- if (function->return_type!=TYPE_VOID) {
- // should expect a return expression.
+ if (tk.type!=TK_REAL_CONSTANT || tk.type!=TK_INT_CONSTANT) {
+ _set_error("Expected integer constant after ','");
+ return ERR_PARSE_ERROR;
+ }
- Node *expr=NULL;
- Error err = parse_expression(parser,cf,&expr);
- if (err)
- return err;
+ uniform.hint_range[2]=tk.constant;
+ tk = _get_token();
+ } else {
+ if (type==TYPE_INT) {
+ uniform.hint_range[2]=1;
+ } else {
+ uniform.hint_range[2]=0.001;
+ }
+ }
- if (compute_node_type(expr)!=function->return_type) {
- parser.set_error("Invalid type for 'return' expression");
- return ERR_PARSE_ERROR;
- }
- cf->statements.push_back(expr);
- }
+ if (tk.type!=TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ','");
+ return ERR_PARSE_ERROR;
+ }
- *r_statement=cf;
+ }
- if (parser.get_token_type()!=TK_SEMICOLON) {
- parser.set_error("Expected ';'");
- return ERR_PARSE_ERROR;
- }
+ if (uniform.hint!=ShaderNode::Uniform::HINT_RANGE && uniform.hint!=ShaderNode::Uniform::HINT_NONE && type <=TYPE_MAT4) {
+ _set_error("This hint is only for sampler types");
+ return ERR_PARSE_ERROR;
- return OK;
-}
+ }
-Error ShaderLanguage::parse_statement(Parser& parser,Node *p_parent,Node **r_statement) {
- *r_statement=NULL;
+ }
- TokenType token_type = parser.get_token_type();
+ if (tk.type!=TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
- if (token_type==TK_CURLY_BRACKET_OPEN) {
- //sub-block
- parser.advance();
- BlockNode *block = parser.create_node<BlockNode>(p_parent);
+ ShaderNode::Varying varying;
+ varying.type=type;
+ varying.precission=precision;
+ shader->varyings[name]=varying;
- *r_statement=block;
- return parse_block(parser,block);
- } else if (token_type==TK_SEMICOLON) {
- // empty ;
- parser.advance();
- return OK;
- } else if (token_type==TK_CF_IF) {
- return parse_flow_if(parser,p_parent,r_statement);
+ tk = _get_token();
+ if (tk.type!=TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
- } else if (token_type==TK_CF_RETURN) {
- return parse_flow_return(parser,p_parent,r_statement);
- } else {
- Error err=parse_expression(parser,p_parent,r_statement);
+ }
- if (err)
- return err;
- if (parser.get_token_type()!=TK_SEMICOLON) {
- parser.set_error("Expected ';'");
- return ERR_PARSE_ERROR;
- }
- }
+ } break;
+ default: {
+ //function
- return OK;
-}
+ DataPrecision precision = PRECISION_DEFAULT;
+ DataType type;
+ StringName name;
-Error ShaderLanguage::parse_block(Parser& parser,BlockNode *p_block) {
+ if (is_token_precision(tk.type)) {
+ precision=get_token_precision(tk.type);
+ tk = _get_token();
+ }
- while(true) {
+ if (!is_token_datatype(tk.type)) {
+ _set_error("Expected funtion, uniform or varying ");
+ return ERR_PARSE_ERROR;
+ }
- if (parser.is_at_end()) {
- if (p_block->parent->type!=Node::TYPE_PROGRAM) {
- parser.set_error("Unexpected End of File");
- return ERR_PARSE_ERROR;
- }
- return OK; //bye
- }
+ type = get_token_datatype(tk.type);
- TokenType token_type = parser.get_token_type();
- if (token_type==TK_CURLY_BRACKET_CLOSE) {
- if (p_block->parent->type==Node::TYPE_PROGRAM) {
- parser.set_error("Unexpected '}'");
- return ERR_PARSE_ERROR;
- }
- parser.advance();
- return OK; // exit block
+ tk = _get_token();
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected function name after datatype");
+ return ERR_PARSE_ERROR;
- } else if (token_type==TK_UNIFORM) {
+ }
- if (p_block!=parser.program->body) {
+ name=tk.text;
- parser.set_error("Uniform only allowed in main program body.");
- return ERR_PARSE_ERROR;
- }
- parser.advance();
- Error err=parse_variable_declaration(parser,p_block);
- if (err)
- return err;
-
- } else if (is_token_datatype(token_type)) {
-
- Error err=OK;
- if (parser_is_at_function(parser))
- err = parse_function(parser,p_block);
- else {
- err = parse_variable_declaration(parser,p_block);
- }
+ if (_find_identifier(NULL,Map<StringName,DataType>(),name)) {
+ _set_error("Redefinition of '"+String(name)+"'");
+ return ERR_PARSE_ERROR;
+ }
- if (err)
- return err;
+ tk = _get_token();
+ if (tk.type!=TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after identifier");
+ return ERR_PARSE_ERROR;
- } else {
- // must be a statement
- Node *statement=NULL;
-
- Error err = parse_statement(parser,p_block,&statement);
- if (err)
- return err;
- if (statement) {
- p_block->statements.push_back(statement);
- }
+ }
- }
- }
- return OK;
-}
+ Map<StringName,DataType> builtin_types;
+ if (p_functions.has(name)) {
+ builtin_types=p_functions[name];
+ }
+ ShaderNode::Function function;
+ function.callable=!p_functions.has(name);
+ function.name=name;
-Error ShaderLanguage::parse(const Vector<Token>& p_tokens,ShaderType p_type,CompileFunc p_compile_func,void *p_userdata,String *r_error,int *r_err_line,int *r_err_column) {
+ FunctionNode* func_node=alloc_node<FunctionNode>();
+ function.function=func_node;
- Parser parser(p_tokens);
- parser.program = parser.create_node<ProgramNode>(NULL);
- parser.program->body = parser.create_node<BlockNode>(parser.program);
+ shader->functions.push_back(function);
+ func_node->name=name;
+ func_node->return_type=type;
+ func_node->return_precision=precision;
- //add builtins
- switch(p_type) {
- case SHADER_MATERIAL_VERTEX: {
- int idx=0;
- while (vertex_builtins_defs[idx].name) {
- parser.program->builtin_variables[vertex_builtins_defs[idx].name]=vertex_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_MATERIAL_FRAGMENT: {
- int idx=0;
- while (fragment_builtins_defs[idx].name) {
- parser.program->builtin_variables[fragment_builtins_defs[idx].name]=fragment_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_MATERIAL_LIGHT: {
- int idx=0;
- while (light_builtins_defs[idx].name) {
- parser.program->builtin_variables[light_builtins_defs[idx].name]=light_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_VERTEX: {
- int idx=0;
- while (ci_vertex_builtins_defs[idx].name) {
- parser.program->builtin_variables[ci_vertex_builtins_defs[idx].name]=ci_vertex_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_FRAGMENT: {
- int idx=0;
- while (ci_fragment_builtins_defs[idx].name) {
- parser.program->builtin_variables[ci_fragment_builtins_defs[idx].name]=ci_fragment_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_LIGHT: {
- int idx=0;
- while (ci_light_builtins_defs[idx].name) {
- parser.program->builtin_variables[ci_light_builtins_defs[idx].name]=ci_light_builtins_defs[idx].type;
- idx++;
- }
- } break;
- case SHADER_POST_PROCESS: {
- int idx=0;
- while (postprocess_fragment_builtins_defs[idx].name) {
- parser.program->builtin_variables[postprocess_fragment_builtins_defs[idx].name]=postprocess_fragment_builtins_defs[idx].type;
- idx++;
- }
- } break;
- }
+ func_node->body = alloc_node<BlockNode>();
+ func_node->body->parent_function=func_node;
- Error err = parse_block(parser,parser.program->body);
- if (err) {
- parser.get_error(r_error,r_err_line,r_err_column);
- return err;
- }
- if (p_compile_func) {
- err = p_compile_func(p_userdata,parser.program);
- }
+ tk = _get_token();
- //clean up nodes created
- while(parser.nodegc.size()) {
+ while(true) {
+ if (tk.type==TK_PARENTHESIS_CLOSE) {
+ break;
+ }
- memdelete( parser.nodegc.front()->get() );
- parser.nodegc.pop_front();
- }
- return err;
-}
+ DataType ptype;
+ StringName pname;
+ DataPrecision pprecision = PRECISION_DEFAULT;
-Error ShaderLanguage::compile(const String& p_code,ShaderType p_type,CompileFunc p_compile_func,void *p_userdata,String *r_error,int *r_err_line,int *r_err_column) {
+ if (is_token_precision(tk.type)) {
+ pprecision=get_token_precision(tk.type);
+ tk = _get_token();
+ }
- *r_error="";
- *r_err_line=0;
- *r_err_column=0;
- Vector<Token> tokens;
+ if (!is_token_datatype(tk.type)) {
+ _set_error("Expected a valid datatype for argument");
+ return ERR_PARSE_ERROR;
+ }
- Error err = tokenize(p_code,&tokens,r_error,r_err_line,r_err_column);
- if (err!=OK) {
- print_line("tokenizer error!");
- }
+ ptype=get_token_datatype(tk.type);
- if (err!=OK) {
- return err;
- }
- err = parse(tokens,p_type,p_compile_func,p_userdata,r_error,r_err_line,r_err_column);
- if (err!=OK) {
- return err;
+ if (ptype==TYPE_VOID) {
+ _set_error("void not allowed in argument");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type!=TK_IDENTIFIER) {
+ _set_error("Expected identifier for argument name");
+ return ERR_PARSE_ERROR;
+ }
+
+ pname = tk.text;
+
+ if (_find_identifier(func_node->body,builtin_types,pname)) {
+ _set_error("Redefinition of '"+String(pname)+"'");
+ return ERR_PARSE_ERROR;
+ }
+ FunctionNode::Argument arg;
+ arg.type=ptype;
+ arg.name=pname;
+ arg.precision=pprecision;
+
+ func_node->arguments.push_back(arg);
+
+ tk = _get_token();
+
+
+ if (tk.type==TK_COMMA) {
+ tk = _get_token();
+ //do none and go on
+ } else if (tk.type!=TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ',' or ')' after identifier");
+ return ERR_PARSE_ERROR;
+ }
+
+ }
+
+ if (p_functions.has(name)) {
+ //if one of the core functions, make sure they are of the correct form
+ if (func_node->arguments.size() > 0) {
+ _set_error("Function '"+String(name)+"' expects no arguments.");
+ return ERR_PARSE_ERROR;
+ }
+ if (func_node->return_type!=TYPE_VOID) {
+ _set_error("Function '"+String(name)+"' must be of void return type.");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+
+ //all good let's parse inside the fucntion!
+ tk = _get_token();
+ if (tk.type!=TK_CURLY_BRACKET_OPEN) {
+ _set_error("Expected '{' to begin function");
+ return ERR_PARSE_ERROR;
+ }
+
+ Error err = _parse_block(func_node->body,builtin_types);
+ if (err)
+ return err;
+ }
+ }
+
+ tk = _get_token();
}
+
return OK;
}
+Error ShaderLanguage::compile(const String& p_code, const Map< StringName, Map<StringName,DataType> > &p_functions, const Set<String> &p_render_modes) {
+
+ clear();
-void ShaderLanguage::get_keyword_list(ShaderType p_type, List<String> *p_keywords) {
+ code=p_code;
- int idx=0;
+ nodes=NULL;
- p_keywords->push_back("uniform");
- p_keywords->push_back("texture");
- p_keywords->push_back("cubemap");
- p_keywords->push_back("color");
- p_keywords->push_back("if");
- p_keywords->push_back("else");
- while(intrinsic_func_defs[idx].name) {
+ shader = alloc_node<ShaderNode>();
+ Error err = _parse_shader(p_functions,p_render_modes);
- p_keywords->push_back(intrinsic_func_defs[idx].name);
- idx++;
+ if (err!=OK) {
+ return err;
}
+ return OK;
+}
+String ShaderLanguage::get_error_text() {
+ return error_str;
+}
- switch(p_type) {
- case SHADER_MATERIAL_VERTEX: {
- idx=0;
- while (vertex_builtins_defs[idx].name) {
- p_keywords->push_back(vertex_builtins_defs[idx].name);
- idx++;
- }
- } break;
- case SHADER_MATERIAL_FRAGMENT: {
- idx=0;
- while (fragment_builtins_defs[idx].name) {
- p_keywords->push_back(fragment_builtins_defs[idx].name);
- idx++;
- }
- } break;
- case SHADER_MATERIAL_LIGHT: {
- idx=0;
- while (light_builtins_defs[idx].name) {
- p_keywords->push_back(light_builtins_defs[idx].name);
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_VERTEX: {
- idx=0;
- while (ci_vertex_builtins_defs[idx].name) {
- p_keywords->push_back(ci_vertex_builtins_defs[idx].name);
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_FRAGMENT: {
- idx=0;
- while (ci_fragment_builtins_defs[idx].name) {
- p_keywords->push_back(ci_fragment_builtins_defs[idx].name);
- idx++;
- }
- } break;
- case SHADER_CANVAS_ITEM_LIGHT: {
- idx=0;
- while (ci_light_builtins_defs[idx].name) {
- p_keywords->push_back(ci_light_builtins_defs[idx].name);
- idx++;
- }
- } break;
+int ShaderLanguage::get_error_line() {
- case SHADER_POST_PROCESS: {
- idx=0;
- while (postprocess_fragment_builtins_defs[idx].name) {
- p_keywords->push_back(postprocess_fragment_builtins_defs[idx].name);
- idx++;
- }
- } break;
+ return error_line;
+}
- }
+ShaderLanguage::ShaderLanguage() {
+ nodes=NULL;
}
+
+ShaderLanguage::~ShaderLanguage() {
+
+ clear();
+}
+
+
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index 31e9fcda5b..b37853c77e 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -46,12 +46,24 @@ public:
enum TokenType {
TK_EMPTY,
- TK_INDENTIFIER,
+ TK_IDENTIFIER,
TK_TRUE,
TK_FALSE,
TK_REAL_CONSTANT,
+ TK_INT_CONSTANT,
TK_TYPE_VOID,
TK_TYPE_BOOL,
+ TK_TYPE_BVEC2,
+ TK_TYPE_BVEC3,
+ TK_TYPE_BVEC4,
+ TK_TYPE_INT,
+ TK_TYPE_IVEC2,
+ TK_TYPE_IVEC3,
+ TK_TYPE_IVEC4,
+ TK_TYPE_UINT,
+ TK_TYPE_UVEC2,
+ TK_TYPE_UVEC3,
+ TK_TYPE_UVEC4,
TK_TYPE_FLOAT,
TK_TYPE_VEC2,
TK_TYPE_VEC3,
@@ -59,9 +71,13 @@ public:
TK_TYPE_MAT2,
TK_TYPE_MAT3,
TK_TYPE_MAT4,
- TK_TYPE_TEXTURE,
- TK_TYPE_CUBEMAP,
- TK_TYPE_COLOR,
+ TK_TYPE_SAMPLER2D,
+ TK_TYPE_ISAMPLER2D,
+ TK_TYPE_USAMPLER2D,
+ TK_TYPE_SAMPLERCUBE,
+ TK_PRECISION_LOW,
+ TK_PRECISION_MID,
+ TK_PRECISION_HIGH,
TK_OP_EQUAL,
TK_OP_NOT_EQUAL,
TK_OP_LESS,
@@ -75,14 +91,35 @@ public:
TK_OP_SUB,
TK_OP_MUL,
TK_OP_DIV,
- TK_OP_NEG,
+ TK_OP_MOD,
+ TK_OP_SHIFT_LEFT,
+ TK_OP_SHIFT_RIGHT,
TK_OP_ASSIGN,
TK_OP_ASSIGN_ADD,
TK_OP_ASSIGN_SUB,
TK_OP_ASSIGN_MUL,
TK_OP_ASSIGN_DIV,
+ TK_OP_ASSIGN_MOD,
+ TK_OP_ASSIGN_SHIFT_LEFT,
+ TK_OP_ASSIGN_SHIFT_RIGHT,
+ TK_OP_ASSIGN_BIT_AND,
+ TK_OP_ASSIGN_BIT_OR,
+ TK_OP_ASSIGN_BIT_XOR,
+ TK_OP_BIT_AND,
+ TK_OP_BIT_OR,
+ TK_OP_BIT_XOR,
+ TK_OP_BIT_INVERT,
+ TK_OP_INCREMENT,
+ TK_OP_DECREMENT,
TK_CF_IF,
TK_CF_ELSE,
+ TK_CF_FOR,
+ TK_CF_WHILE,
+ TK_CF_DO,
+ TK_CF_SWITCH,
+ TK_CF_CASE,
+ TK_CF_BREAK,
+ TK_CF_CONTINUE,
TK_CF_RETURN,
TK_BRACKET_OPEN,
TK_BRACKET_CLOSE,
@@ -90,31 +127,39 @@ public:
TK_CURLY_BRACKET_CLOSE,
TK_PARENTHESIS_OPEN,
TK_PARENTHESIS_CLOSE,
+ TK_QUESTION,
TK_COMMA,
+ TK_COLON,
TK_SEMICOLON,
TK_PERIOD,
TK_UNIFORM,
+ TK_VARYING,
+ TK_RENDER_MODE,
+ TK_HINT_WHITE_TEXTURE,
+ TK_HINT_BLACK_TEXTURE,
+ TK_HINT_NORMAL_TEXTURE,
+ TK_HINT_RANGE,
TK_ERROR,
+ TK_EOF,
TK_MAX
};
-
-
/* COMPILER */
- enum ShaderType {
- SHADER_MATERIAL_VERTEX,
- SHADER_MATERIAL_FRAGMENT,
- SHADER_MATERIAL_LIGHT,
- SHADER_CANVAS_ITEM_VERTEX,
- SHADER_CANVAS_ITEM_FRAGMENT,
- SHADER_CANVAS_ITEM_LIGHT,
- SHADER_POST_PROCESS,
- };
-
enum DataType {
TYPE_VOID,
TYPE_BOOL,
+ TYPE_BVEC2,
+ TYPE_BVEC3,
+ TYPE_BVEC4,
+ TYPE_INT,
+ TYPE_IVEC2,
+ TYPE_IVEC3,
+ TYPE_IVEC4,
+ TYPE_UINT,
+ TYPE_UVEC2,
+ TYPE_UVEC3,
+ TYPE_UVEC4,
TYPE_FLOAT,
TYPE_VEC2,
TYPE_VEC3,
@@ -122,30 +167,58 @@ public:
TYPE_MAT2,
TYPE_MAT3,
TYPE_MAT4,
- TYPE_TEXTURE,
- TYPE_CUBEMAP,
+ TYPE_SAMPLER2D,
+ TYPE_ISAMPLER2D,
+ TYPE_USAMPLER2D,
+ TYPE_SAMPLERCUBE,
+ };
+
+ enum DataPrecision {
+ PRECISION_LOWP,
+ PRECISION_MEDIUMP,
+ PRECISION_HIGHP,
+ PRECISION_DEFAULT,
};
enum Operator {
- OP_ASSIGN,
+ OP_EQUAL,
+ OP_NOT_EQUAL,
+ OP_LESS,
+ OP_LESS_EQUAL,
+ OP_GREATER,
+ OP_GREATER_EQUAL,
+ OP_AND,
+ OP_OR,
+ OP_NOT,
+ OP_NEGATE,
OP_ADD,
OP_SUB,
OP_MUL,
OP_DIV,
+ OP_MOD,
+ OP_SHIFT_LEFT,
+ OP_SHIFT_RIGHT,
+ OP_ASSIGN,
OP_ASSIGN_ADD,
OP_ASSIGN_SUB,
OP_ASSIGN_MUL,
OP_ASSIGN_DIV,
- OP_NEG,
- OP_NOT,
- OP_CMP_EQ,
- OP_CMP_NEQ,
- OP_CMP_LEQ,
- OP_CMP_GEQ,
- OP_CMP_LESS,
- OP_CMP_GREATER,
- OP_CMP_OR,
- OP_CMP_AND,
+ OP_ASSIGN_MOD,
+ OP_ASSIGN_SHIFT_LEFT,
+ OP_ASSIGN_SHIFT_RIGHT,
+ OP_ASSIGN_BIT_AND,
+ OP_ASSIGN_BIT_OR,
+ OP_ASSIGN_BIT_XOR,
+ OP_BIT_AND,
+ OP_BIT_OR,
+ OP_BIT_XOR,
+ OP_BIT_INVERT,
+ OP_INCREMENT,
+ OP_DECREMENT,
+ OP_SELECT_IF,
+ OP_SELECT_ELSE, //used only internally, then only IF appears with 3 arguments
+ OP_POST_INCREMENT,
+ OP_POST_DECREMENT,
OP_CALL,
OP_CONSTRUCT,
OP_MAX
@@ -154,18 +227,21 @@ public:
enum FlowOperation {
FLOW_OP_IF,
FLOW_OP_RETURN,
- //FLOW_OP_FOR,
- //FLOW_OP_WHILE,
- //FLOW_OP_DO,
- //FLOW_OP_BREAK,
- //FLOW_OP_CONTINUE,
+ FLOW_OP_FOR,
+ FLOW_OP_WHILE,
+ FLOW_OP_DO,
+ FLOW_OP_BREAK,
+ FLOW_OP_SWITCH,
+ FLOW_OP_CONTINUE
};
struct Node {
+ Node *next;
+
enum Type {
- TYPE_PROGRAM,
+ TYPE_SHADER,
TYPE_FUNCTION,
TYPE_BLOCK,
TYPE_VARIABLE,
@@ -175,7 +251,6 @@ public:
TYPE_MEMBER
};
- Node * parent;
Type type;
virtual DataType get_datatype() const { return TYPE_VOID; }
@@ -183,24 +258,34 @@ public:
virtual ~Node() {}
};
+ template<class T>
+ T* alloc_node() {
+ T* node = memnew(T);
+ node->next=nodes;
+ nodes=node;
+ return node;
+ }
+
+ Node *nodes;
+
struct OperatorNode : public Node {
DataType return_cache;
+ DataPrecision return_precision_cache;
Operator op;
Vector<Node*> arguments;
virtual DataType get_datatype() const { return return_cache; }
- OperatorNode() { type=TYPE_OPERATOR; return_cache=TYPE_VOID; }
+ OperatorNode() { type=TYPE_OPERATOR; return_cache=TYPE_VOID; return_precision_cache=PRECISION_DEFAULT; }
};
struct VariableNode : public Node {
- bool uniform;
DataType datatype_cache;
StringName name;
virtual DataType get_datatype() const { return datatype_cache; }
- VariableNode() { type=TYPE_VARIABLE; datatype_cache=TYPE_VOID; uniform=false; }
+ VariableNode() { type=TYPE_VARIABLE; datatype_cache=TYPE_VOID; }
};
struct ConstantNode : public Node {
@@ -212,17 +297,26 @@ public:
ConstantNode() { type=TYPE_CONSTANT; }
};
+ struct FunctionNode;
+
struct BlockNode : public Node {
+ FunctionNode *parent_function;
+ BlockNode *parent_block;
- Map<StringName,DataType> variables;
+ struct Variable {
+ DataType type;
+ DataPrecision precision;
+ };
+
+ Map<StringName,Variable> variables;
List<Node*> statements;
- BlockNode() { type=TYPE_BLOCK; }
+ BlockNode() { type=TYPE_BLOCK; parent_block=NULL; parent_function=NULL; }
};
struct ControlFlowNode : public Node {
FlowOperation flow_op;
- Vector<Node*> statements;
+ Vector<BlockNode*> blocks;
ControlFlowNode() { type=TYPE_CONTROL_FLOW; flow_op=FLOW_OP_IF;}
};
@@ -244,39 +338,60 @@ public:
StringName name;
DataType type;
+ DataPrecision precision;
};
StringName name;
DataType return_type;
+ DataPrecision return_precision;
Vector<Argument> arguments;
BlockNode *body;
- FunctionNode() { type=TYPE_FUNCTION; }
+ FunctionNode() { type=TYPE_FUNCTION; return_precision=PRECISION_DEFAULT; }
};
- struct Uniform {
-
- int order;
- DataType type;
- Variant default_value;
- };
- struct ProgramNode : public Node {
+ struct ShaderNode : public Node {
struct Function {
StringName name;
FunctionNode*function;
+ bool callable;
+ };
+
+ struct Varying {
+ DataType type;
+ DataPrecision precission;
+ };
+
+ struct Uniform {
+ enum Hint {
+ HINT_NONE,
+ HINT_WHITE_TEXTURE,
+ HINT_BLACK_TEXTURE,
+ HINT_NORMAL_TEXTURE,
+ HINT_RANGE,
+ };
+
+ int order;
+ DataType type;
+ DataPrecision precission;
+ Variant default_value;
+ Hint hint;
+ float hint_range[3];
+
+ Uniform() { hint=HINT_NONE; hint_range[0]=0; hint_range[1]=1; hint_range[2]=0.001;}
};
- Map<StringName,DataType> builtin_variables;
+ Map<StringName,Varying> varyings;
Map<StringName,Uniform> uniforms;
+ Set<StringName> render_modes;
Vector<Function> functions;
- BlockNode *body;
- ProgramNode() { type=TYPE_PROGRAM; }
+ ShaderNode() { type=TYPE_SHADER; }
};
@@ -284,12 +399,12 @@ public:
bool is_op;
union {
- TokenType op;
+ Operator op;
Node *node;
};
};
- typedef Error (*CompileFunc)(void*,ProgramNode*);
+
struct VarInfo {
@@ -297,59 +412,78 @@ public:
DataType type;
};
-private:
-
-
-
- static const char * token_names[TK_MAX];
+ enum CompletionType {
+ COMPLETION_NONE,
+ COMPLETION_BUILT_IN_TYPE_CONSTANT,
+ COMPLETION_FUNCTION,
+ COMPLETION_IDENTIFIER,
+ COMPLETION_PARENT_FUNCTION,
+ COMPLETION_METHOD,
+ COMPLETION_CALL_ARGUMENTS,
+ COMPLETION_INDEX,
+ COMPLETION_VIRTUAL_FUNC,
+ COMPLETION_YIELD,
+ };
struct Token {
TokenType type;
StringName text;
- uint16_t line,col;
-
- Token(TokenType p_type=TK_EMPTY,const String& p_text=String()) { type=p_type; text=p_text; line=0; col=0; }
+ double constant;
+ uint16_t line;
};
+ static String get_token_text(Token p_token);
+ static bool is_token_datatype(TokenType p_type);
+ static DataType get_token_datatype(TokenType p_type);
+ static bool is_token_precision(TokenType p_type);
+ static DataPrecision get_token_precision(TokenType p_type);
+ static String get_datatype_name(DataType p_type);
+ static bool is_token_nonvoid_datatype(TokenType p_type);
+ static bool is_token_operator(TokenType p_type);
+
+private:
+ bool error_set;
+ String error_str;
+ int error_line;
- static Token read_token(const CharType* p_text,int p_len,int &r_line,int &r_chars);
- static Error tokenize(const String& p_text,Vector<Token> *p_tokens,String *r_error,int *r_err_line,int *r_err_column);
+ String code;
+ int char_idx;
+ int tk_line;
+ void _set_error(const String& p_str) {
+ if (error_set)
+ return;
+ error_set=true;
+ error_str=p_str;
+ }
- class Parser {
+ static const char * token_names[TK_MAX];
- Vector<Token> tokens;
- int pos;
- String error;
- public:
- void set_error(const String& p_error) { error=p_error; }
- void get_error(String *r_error, int *r_line, int *r_column) {
- *r_error=error;
- *r_line=get_token(pos).line;
- *r_column=get_token(pos).col;
- }
+ Token _make_token(TokenType p_type, const StringName& p_text=StringName());
+ Token _get_token();
+ ShaderNode *shader;
+ enum IdentifierType {
+ IDENTIFIER_FUNCTION,
+ IDENTIFIER_UNIFORM,
+ IDENTIFIER_VARYING,
+ IDENTIFIER_FUNCTION_ARGUMENT,
+ IDENTIFIER_LOCAL_VAR,
+ IDENTIFIER_BUILTIN_VAR,
+ };
- Token get_token(int ofs=0) const { int idx=pos+ofs; if (idx<0 || idx>=tokens.size()) return Token(TK_ERROR); return tokens[idx]; }
- TokenType get_token_type(int ofs=0) const { int idx=pos+ofs; if (idx<0 || idx>=tokens.size()) return TK_ERROR; return tokens[idx].type; }
- void advance(int p_amount=1) { pos+=p_amount; }
- bool is_at_end() const { return pos>=tokens.size(); }
+ bool _find_identifier(const BlockNode* p_block,const Map<StringName, DataType> &p_builtin_types,const StringName& p_identifier, DataType *r_data_type=NULL, IdentifierType *r_type=NULL);
- ProgramNode *program;
- template<class T>
- T* create_node(Node *p_parent) { T*n=memnew( T ); nodegc.push_back(n); n->parent=p_parent; return n; }
- List<Node*> nodegc;
+ bool _validate_operator(OperatorNode *p_op,DataType *r_ret_type=NULL);
- Parser(const Vector<Token>& p_tokens) { tokens=p_tokens; pos=0;}
- };
struct IntrinsicFuncDef {
@@ -360,70 +494,35 @@ private:
};
- static const IntrinsicFuncDef intrinsic_func_defs[];
-
- struct OperatorDef {
-
- enum { MAX_ARGS=2 };
- Operator op;
- DataType rettype;
- const DataType args[MAX_ARGS];
- };
-
- static const OperatorDef operator_defs[];
-
- struct BuiltinsDef {
-
- const char* name;
- DataType type;
- };
-
- static const BuiltinsDef vertex_builtins_defs[];
- static const BuiltinsDef fragment_builtins_defs[];
- static const BuiltinsDef light_builtins_defs[];
-
- static const BuiltinsDef ci_vertex_builtins_defs[];
- static const BuiltinsDef ci_fragment_builtins_defs[];
- static const BuiltinsDef ci_light_builtins_defs[];
-
- static const BuiltinsDef postprocess_fragment_builtins_defs[];
-
- static DataType get_token_datatype(TokenType p_type);
- static String get_datatype_name(DataType p_type);
- static bool is_token_datatype(TokenType p_type);
- static bool is_token_nonvoid_datatype(TokenType p_type);
-
- static bool test_existing_identifier(Node *p_node,const StringName p_identifier,bool p_func=true,bool p_var=true,bool p_builtin=true);
+ static const IntrinsicFuncDef intrinsic_func_defs[];
+ bool _validate_function_call(BlockNode* p_block, OperatorNode *p_func,DataType *r_ret_type);
- static bool parser_is_at_function(Parser& parser);
- static DataType compute_node_type(Node *p_node);
+ bool _parse_function_arguments(BlockNode *p_block, const Map<StringName,DataType> &p_builtin_types, OperatorNode* p_func);
- static Node* validate_function_call(Parser&parser, OperatorNode *p_func);
- static Node* validate_operator(Parser& parser,OperatorNode *p_func);
- static bool is_token_operator(TokenType p_type);
- static Operator get_token_operator(TokenType p_type);
+ Node* _parse_expression(BlockNode *p_block, const Map<StringName,DataType> &p_builtin_types);
- static Error parse_expression(Parser& parser,Node *p_parent,Node **r_expr);
+ ShaderLanguage::Node* _reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
+ Node* _parse_and_reduce_expression(BlockNode *p_block,const Map<StringName,DataType> &p_builtin_types);
- static Error parse_variable_declaration(Parser& parser,BlockNode *p_block);
- static Error parse_function(Parser& parser,BlockNode *p_block);
- static Error parse_flow_if(Parser& parser,Node *p_parent,Node **r_statement);
- static Error parse_flow_return(Parser& parser,Node *p_parent,Node **r_statement);
- static Error parse_statement(Parser& parser,Node *p_parent,Node **r_statement);
- static Error parse_block(Parser& parser,BlockNode *p_block);
+ Error _parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one=false, bool p_can_break=false, bool p_can_continue=false);
+ Error _parse_shader(const Map< StringName, Map<StringName,DataType> > &p_functions, const Set<String> &p_render_modes);
- static Error parse(const Vector<Token> &p_tokens,ShaderType p_type,CompileFunc p_compile_func,void *p_userdata,String *r_error,int *r_err_line,int *r_err_column);
-;
public:
- static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
+// static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
+
+ void clear();
+ Error compile(const String& p_code,const Map< StringName, Map<StringName,DataType> > &p_functions,const Set<String>& p_render_modes);
+ String get_error_text();
+ int get_error_line();
- static Error compile(const String& p_code,ShaderType p_type, CompileFunc p_compile_func,void *p_userdata,String *r_error,int *r_err_line,int *r_err_column);
static String lex_debug(const String& p_code);
+ ShaderLanguage();
+ ~ShaderLanguage();
};
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
new file mode 100644
index 0000000000..f70ce46a3d
--- /dev/null
+++ b/servers/visual/visual_server_canvas.cpp
@@ -0,0 +1,1268 @@
+#include "visual_server_canvas.h"
+#include "visual_server_global.h"
+#include "visual_server_viewport.h"
+
+void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color& p_modulate, RasterizerCanvas::Light *p_lights) {
+
+
+ static const int z_range = VS::CANVAS_ITEM_Z_MAX-VS::CANVAS_ITEM_Z_MIN+1;
+ RasterizerCanvas::Item *z_list[z_range];
+ RasterizerCanvas::Item *z_last_list[z_range];
+
+ for(int i=0;i<z_range;i++) {
+ z_list[i]=NULL;
+ z_last_list[i]=NULL;
+ }
+
+
+ _render_canvas_item(p_canvas_item,p_transform,p_clip_rect,Color(1,1,1,1),0,z_list,z_last_list,NULL,NULL);
+
+ for(int i=0;i<z_range;i++) {
+ if (!z_list[i])
+ continue;
+ VSG::canvas_render->canvas_render_items(z_list[i],VS::CANVAS_ITEM_Z_MIN+i,p_modulate,p_lights);
+ }
+
+}
+
+void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, const Color &p_modulate,int p_z,RasterizerCanvas::Item **z_list,RasterizerCanvas::Item **z_last_list,Item *p_canvas_clip,Item *p_material_owner) {
+
+ Item *ci = p_canvas_item;
+
+ if (!ci->visible)
+ return;
+
+ Rect2 rect = ci->get_rect();
+ Matrix32 xform = p_transform * ci->xform;
+ Rect2 global_rect = xform.xform(rect);
+ global_rect.pos+=p_clip_rect.pos;
+
+
+ if (ci->use_parent_material && p_material_owner)
+ ci->material_owner=p_material_owner;
+ else {
+ p_material_owner=ci;
+ ci->material_owner=NULL;
+ }
+
+
+ Color modulate( ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g,ci->modulate.b * p_modulate.b,ci->modulate.a * p_modulate.a);
+
+ if (modulate.a<0.007)
+ return;
+
+
+ int child_item_count=ci->child_items.size();
+ Item **child_items=(Item**)alloca(child_item_count*sizeof(Item*));
+ copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(Item*));
+
+ if (ci->clip) {
+ if (p_canvas_clip != NULL) {
+ ci->final_clip_rect=p_canvas_clip->final_clip_rect.clip(global_rect);
+ } else {
+ ci->final_clip_rect=global_rect;
+ }
+ ci->final_clip_owner=ci;
+
+ } else {
+ ci->final_clip_owner=p_canvas_clip;
+ }
+
+ if (ci->sort_y) {
+
+ SortArray<Item*,ItemPtrSort> sorter;
+ sorter.sort(child_items,child_item_count);
+ }
+
+ if (ci->z_relative)
+ p_z=CLAMP(p_z+ci->z,VS::CANVAS_ITEM_Z_MIN,VS::CANVAS_ITEM_Z_MAX);
+ else
+ p_z=ci->z;
+
+ for(int i=0;i<child_item_count;i++) {
+
+ if (!child_items[i]->behind)
+ continue;
+ _render_canvas_item(child_items[i],xform,p_clip_rect,modulate,p_z,z_list,z_last_list,(Item*)ci->final_clip_owner,p_material_owner);
+ }
+
+ if (ci->copy_back_buffer) {
+
+ ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect);
+ }
+
+ if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) {
+ //something to draw?
+ ci->final_transform=xform;
+ ci->final_modulate=Color(modulate.r*ci->self_modulate.r, modulate.g*ci->self_modulate.g, modulate.b*ci->self_modulate.b, modulate.a*ci->self_modulate.a );
+ ci->global_rect_cache=global_rect;
+ ci->global_rect_cache.pos-=p_clip_rect.pos;
+ ci->light_masked=false;
+
+ int zidx = p_z-VS::CANVAS_ITEM_Z_MIN;
+
+ if (z_last_list[zidx]) {
+ z_last_list[zidx]->next=ci;
+ z_last_list[zidx]=ci;
+
+ } else {
+ z_list[zidx]=ci;
+ z_last_list[zidx]=ci;
+ }
+
+ ci->next=NULL;
+
+ }
+
+ for(int i=0;i<child_item_count;i++) {
+
+ if (child_items[i]->behind)
+ continue;
+ _render_canvas_item(child_items[i],xform,p_clip_rect,modulate,p_z,z_list,z_last_list,(Item*)ci->final_clip_owner,p_material_owner);
+ }
+
+}
+
+void VisualServerCanvas::_light_mask_canvas_items(int p_z,RasterizerCanvas::Item *p_canvas_item,RasterizerCanvas::Light *p_masked_lights) {
+
+ if (!p_masked_lights)
+ return;
+
+ RasterizerCanvas::Item *ci=p_canvas_item;
+
+ while(ci) {
+
+ RasterizerCanvas::Light *light=p_masked_lights;
+ while(light) {
+
+ 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)) {
+ ci->light_masked=true;
+ }
+
+ light=light->mask_next_ptr;
+ }
+
+ ci=ci->next;
+ }
+
+
+
+
+}
+
+void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) {
+
+ VSG::canvas_render->canvas_begin();
+
+ int l = p_canvas->child_items.size();
+ Canvas::ChildItem *ci=p_canvas->child_items.ptr();
+
+ bool has_mirror=false;
+ for(int i=0;i<l;i++) {
+ if (ci[i].mirror.x || ci[i].mirror.y) {
+ has_mirror=true;
+ break;
+ }
+ }
+
+
+ if (!has_mirror) {
+
+ static const int z_range = VS::CANVAS_ITEM_Z_MAX-VS::CANVAS_ITEM_Z_MIN+1;
+ RasterizerCanvas::Item *z_list[z_range];
+ RasterizerCanvas::Item *z_last_list[z_range];
+
+ for(int i=0;i<z_range;i++) {
+ z_list[i]=NULL;
+ z_last_list[i]=NULL;
+ }
+ for(int i=0;i<l;i++) {
+ _render_canvas_item(ci[i].item,p_transform,p_clip_rect,Color(1,1,1,1),0,z_list,z_last_list,NULL,NULL);
+ }
+
+ for(int i=0;i<z_range;i++) {
+ if (!z_list[i])
+ continue;
+
+ if (p_masked_lights) {
+ _light_mask_canvas_items(VS::CANVAS_ITEM_Z_MIN+i,z_list[i],p_masked_lights);
+ }
+
+ VSG::canvas_render->canvas_render_items(z_list[i],VS::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,p_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,p_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,p_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,p_clip_rect,p_canvas->modulate,p_lights);
+ }
+
+ }
+ }
+
+}
+
+
+RID VisualServerCanvas::canvas_create() {
+
+ Canvas * canvas = memnew( Canvas );
+ ERR_FAIL_COND_V(!canvas,RID());
+ RID rid = canvas_owner.make_rid( canvas );
+
+ return rid;
+}
+
+void VisualServerCanvas::canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring) {
+
+ Canvas * canvas = canvas_owner.getornull(p_canvas);
+ ERR_FAIL_COND(!canvas);
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ int idx = canvas->find_item(canvas_item);
+ ERR_FAIL_COND(idx==-1);
+ canvas->child_items[idx].mirror=p_mirroring;
+
+}
+void VisualServerCanvas::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 VisualServerCanvas::canvas_item_create() {
+
+ Item *canvas_item = memnew( Item );
+ ERR_FAIL_COND_V(!canvas_item,RID());
+
+ return canvas_item_owner.make_rid( canvas_item );
+}
+
+void VisualServerCanvas::canvas_item_set_parent(RID p_item,RID p_parent) {
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ if (canvas_item->parent.is_valid()) {
+
+ if (canvas_owner.owns(canvas_item->parent)) {
+
+ Canvas *canvas = canvas_owner.get(canvas_item->parent);
+ canvas->erase_item(canvas_item);
+ } else if (canvas_item_owner.owns(canvas_item->parent)) {
+
+ Item *item_owner = canvas_item_owner.get(canvas_item->parent);
+ item_owner->child_items.erase(canvas_item);
+ }
+
+ canvas_item->parent=RID();
+ }
+
+
+ if (p_parent.is_valid()) {
+ if (canvas_owner.owns(p_parent)) {
+
+ Canvas *canvas = canvas_owner.get(p_parent);
+ Canvas::ChildItem ci;
+ ci.item=canvas_item;
+ canvas->child_items.push_back(ci);
+ canvas->children_order_dirty=true;
+ } else if (canvas_item_owner.owns(p_parent)) {
+
+ Item *item_owner = canvas_item_owner.get(p_parent);
+ item_owner->child_items.push_back(canvas_item);
+ item_owner->children_order_dirty=true;
+
+ } else {
+
+ ERR_EXPLAIN("Invalid parent");
+ ERR_FAIL();
+ }
+
+
+ }
+
+ canvas_item->parent=p_parent;
+
+
+}
+void VisualServerCanvas::canvas_item_set_visible(RID p_item,bool p_visible){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->visible=p_visible;
+
+}
+void VisualServerCanvas::canvas_item_set_light_mask(RID p_item,int p_mask){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->light_mask=p_mask;
+
+}
+
+void VisualServerCanvas::canvas_item_set_transform(RID p_item, const Matrix32& p_transform){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->xform=p_transform;
+
+}
+void VisualServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->clip=p_clip;
+
+}
+void VisualServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->distance_field=p_enable;
+
+
+}
+void VisualServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->custom_rect=p_custom_rect;
+ canvas_item->rect=p_rect;
+
+}
+void VisualServerCanvas::canvas_item_set_modulate(RID p_item, const Color& p_color) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->modulate=p_color;
+
+}
+void VisualServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color& p_color){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->self_modulate=p_color;
+
+}
+
+void VisualServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->behind=p_enable;
+
+}
+
+
+void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandLine * line = memnew( Item::CommandLine );
+ ERR_FAIL_COND(!line);
+ line->color=p_color;
+ line->from=p_from;
+ line->to=p_to;
+ line->width=p_width;
+ line->antialiased=p_antialiased;
+ canvas_item->rect_dirty=true;
+
+
+ canvas_item->commands.push_back(line);
+}
+
+void VisualServerCanvas::canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandRect * rect = memnew( Item::CommandRect );
+ ERR_FAIL_COND(!rect);
+ rect->modulate=p_color;
+ rect->rect=p_rect;
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(rect);
+}
+
+void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color) {
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandCircle * circle = memnew( Item::CommandCircle );
+ ERR_FAIL_COND(!circle);
+ circle->color=p_color;
+ circle->pos=p_pos;
+ circle->radius=p_radius;
+
+ canvas_item->commands.push_back(circle);
+
+}
+
+void VisualServerCanvas::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) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandRect * rect = memnew( Item::CommandRect );
+ ERR_FAIL_COND(!rect);
+ rect->modulate=p_modulate;
+ rect->rect=p_rect;
+ rect->flags=0;
+ if (p_tile) {
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_TILE;
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_REGION;
+ rect->source=Rect2(0,0,p_rect.size.width,p_rect.size.height);
+ }
+
+ if (p_rect.size.x<0) {
+
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_FLIP_H;
+ rect->rect.size.x = -rect->rect.size.x;
+ }
+ if (p_rect.size.y<0) {
+
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_FLIP_V;
+ rect->rect.size.y = -rect->rect.size.y;
+ }
+ if (p_transpose) {
+ rect->flags|=RasterizerCanvas::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 VisualServerCanvas::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) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandRect * rect = memnew( Item::CommandRect );
+ ERR_FAIL_COND(!rect);
+ rect->modulate=p_modulate;
+ rect->rect=p_rect;
+ rect->texture=p_texture;
+ rect->source=p_src_rect;
+ rect->flags=RasterizerCanvas::CANVAS_RECT_REGION;
+
+ if (p_rect.size.x<0) {
+
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_FLIP_H;
+ rect->rect.size.x = -rect->rect.size.x;
+ }
+ if (p_rect.size.y<0) {
+
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_FLIP_V;
+ rect->rect.size.y = -rect->rect.size.y;
+ }
+ if (p_transpose) {
+ rect->flags|=RasterizerCanvas::CANVAS_RECT_TRANSPOSE;
+ SWAP(rect->rect.size.x, rect->rect.size.y);
+ }
+
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(rect);
+
+}
+
+void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright,VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode,bool p_draw_center,const Color& p_modulate) {
+
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandNinePatch * style = memnew( Item::CommandNinePatch );
+ ERR_FAIL_COND(!style);
+ style->texture=p_texture;
+ style->rect=p_rect;
+ style->source=p_source;
+ style->draw_center=p_draw_center;
+ style->color=p_modulate;
+ style->margin[MARGIN_LEFT]=p_topleft.x;
+ style->margin[MARGIN_TOP]=p_topleft.y;
+ style->margin[MARGIN_RIGHT]=p_bottomright.x;
+ style->margin[MARGIN_BOTTOM]=p_bottomright.y;
+ style->axis_x=p_x_axis_mode;
+ style->axis_y=p_y_axis_mode;
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(style);
+}
+void VisualServerCanvas::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) {
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandPrimitive * prim = memnew( Item::CommandPrimitive );
+ ERR_FAIL_COND(!prim);
+ prim->texture=p_texture;
+ prim->points=p_points;
+ prim->uvs=p_uvs;
+ prim->colors=p_colors;
+ prim->width=p_width;
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(prim);
+}
+
+void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture) {
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+#ifdef DEBUG_ENABLED
+ int pointcount = p_points.size();
+ ERR_FAIL_COND(pointcount<3);
+ int color_size=p_colors.size();
+ int uv_size=p_uvs.size();
+ ERR_FAIL_COND(color_size!=0 && color_size!=1 && color_size!=pointcount);
+ ERR_FAIL_COND(uv_size!=0 && (uv_size!=pointcount || !p_texture.is_valid()));
+#endif
+ Vector<int> indices = Geometry::triangulate_polygon(p_points);
+
+ if (indices.empty()) {
+
+ ERR_EXPLAIN("Bad Polygon!");
+ ERR_FAIL_V();
+ }
+
+ Item::CommandPolygon * polygon = memnew( Item::CommandPolygon );
+ ERR_FAIL_COND(!polygon);
+ polygon->texture=p_texture;
+ polygon->points=p_points;
+ polygon->uvs=p_uvs;
+ polygon->colors=p_colors;
+ polygon->indices=indices;
+ polygon->count=indices.size();
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(polygon);
+
+}
+
+
+void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture, int p_count) {
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ int ps = p_points.size();
+ ERR_FAIL_COND(!p_colors.empty() && p_colors.size()!=ps && p_colors.size()!=1);
+ ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size()!=ps);
+
+ Vector<int> indices = p_indices;
+
+ int count = p_count * 3;
+
+ if (indices.empty()) {
+
+ ERR_FAIL_COND( ps % 3 != 0 );
+ if (p_count == -1)
+ count = ps;
+ } else {
+
+ ERR_FAIL_COND( indices.size() % 3 != 0 );
+ if (p_count == -1)
+ count = indices.size();
+ }
+
+ Item::CommandPolygon * polygon = memnew( Item::CommandPolygon );
+ ERR_FAIL_COND(!polygon);
+ polygon->texture=p_texture;
+ polygon->points=p_points;
+ polygon->uvs=p_uvs;
+ polygon->colors=p_colors;
+ polygon->indices=indices;
+ polygon->count = count;
+ canvas_item->rect_dirty=true;
+
+ canvas_item->commands.push_back(polygon);
+}
+
+
+void VisualServerCanvas::canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform) {
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandTransform * tr = memnew( Item::CommandTransform );
+ ERR_FAIL_COND(!tr);
+ tr->xform=p_transform;
+
+ canvas_item->commands.push_back(tr);
+
+}
+
+void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID& p_mesh,RID p_skeleton){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandMesh * m = memnew( Item::CommandMesh );
+ ERR_FAIL_COND(!m);
+ m->mesh=p_mesh;
+ m->skeleton=p_skeleton;
+
+ canvas_item->commands.push_back(m);
+}
+void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh,RID p_skeleton){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandMultiMesh * mm = memnew( Item::CommandMultiMesh );
+ ERR_FAIL_COND(!mm);
+ mm->multimesh=p_mesh;
+ mm->skeleton=p_skeleton;
+
+ canvas_item->commands.push_back(mm);
+
+}
+
+void VisualServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore){
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandClipIgnore * ci = memnew( Item::CommandClipIgnore);
+ ERR_FAIL_COND(!ci);
+ ci->ignore=p_ignore;
+
+ canvas_item->commands.push_back(ci);
+}
+void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable){
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->sort_y=p_enable;
+}
+void VisualServerCanvas::canvas_item_set_z(RID p_item, int p_z){
+
+ ERR_FAIL_COND(p_z<VS::CANVAS_ITEM_Z_MIN || p_z>VS::CANVAS_ITEM_Z_MAX);
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->z=p_z;
+}
+void VisualServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->z_relative=p_enable;
+
+}
+void VisualServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect){
+
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+ if (bool(canvas_item->copy_back_buffer!=NULL) !=p_enable) {
+ if (p_enable) {
+ canvas_item->copy_back_buffer = memnew( RasterizerCanvas::Item::CopyBackBuffer );
+ } else {
+ memdelete(canvas_item->copy_back_buffer);
+ canvas_item->copy_back_buffer=NULL;
+ }
+ }
+
+ if (p_enable) {
+ canvas_item->copy_back_buffer->rect=p_rect;
+ canvas_item->copy_back_buffer->full=p_rect==Rect2();
+ }
+
+}
+
+void VisualServerCanvas::canvas_item_clear(RID p_item){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->clear();
+}
+void VisualServerCanvas::canvas_item_set_draw_index(RID p_item,int p_index){
+
+ Item *canvas_item = canvas_item_owner.getornull( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->index=p_index;
+
+ if (canvas_item_owner.owns( canvas_item->parent)) {
+ Item *canvas_item_parent = canvas_item_owner.getornull( canvas_item->parent );
+ canvas_item_parent->children_order_dirty=true;
+ return;
+ }
+
+ Canvas* canvas = canvas_owner.getornull( canvas_item->parent );
+ if (canvas) {
+ canvas->children_order_dirty=true;
+ return;
+ }
+
+}
+
+void VisualServerCanvas::canvas_item_set_material(RID p_item, RID p_material){
+
+ Item *canvas_item = canvas_item_owner.get( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->material=p_material;
+}
+
+void VisualServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable){
+
+ Item *canvas_item = canvas_item_owner.get( p_item );
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->use_parent_material=p_enable;
+
+}
+
+RID VisualServerCanvas::canvas_light_create(){
+
+ RasterizerCanvas::Light *clight = memnew( RasterizerCanvas::Light );
+ clight->light_internal = VSG::canvas_render->light_internal_create();
+ return canvas_light_owner.make_rid(clight);
+
+}
+void VisualServerCanvas::canvas_light_attach_to_canvas(RID p_light,RID p_canvas){
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ if (clight->canvas.is_valid()) {
+
+ Canvas *canvas = canvas_owner.getornull(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 VisualServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled){
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->enabled=p_enabled;
+
+}
+void VisualServerCanvas::canvas_light_set_scale(RID p_light, float p_scale){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->scale=p_scale;
+
+}
+void VisualServerCanvas::canvas_light_set_transform(RID p_light, const Matrix32& p_transform){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->xform=p_transform;
+
+}
+void VisualServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->texture=p_texture;
+
+}
+void VisualServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->texture_offset=p_offset;
+
+}
+void VisualServerCanvas::canvas_light_set_color(RID p_light, const Color& p_color){
+
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->color=p_color;
+}
+void VisualServerCanvas::canvas_light_set_height(RID p_light, float p_height){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->height=p_height;
+
+}
+void VisualServerCanvas::canvas_light_set_energy(RID p_light, float p_energy){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->energy=p_energy;
+
+}
+void VisualServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->z_min=p_min_z;
+ clight->z_max=p_max_z;
+
+}
+void VisualServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+
+ clight->layer_max=p_max_layer;
+ clight->layer_min=p_min_layer;
+
+
+}
+void VisualServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask){
+
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->item_mask=p_mask;
+
+}
+void VisualServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask){
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->item_shadow_mask=p_mask;
+
+}
+void VisualServerCanvas::canvas_light_set_mode(RID p_light, VS::CanvasLightMode p_mode){
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->mode=p_mode;
+
+}
+
+
+void VisualServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ if (clight->shadow_buffer.is_valid()==p_enabled)
+ return;
+ if (p_enabled) {
+ clight->shadow_buffer=VSG::storage->canvas_light_shadow_buffer_create(clight->shadow_buffer_size);
+ } else {
+ VSG::storage->free(clight->shadow_buffer);
+ clight->shadow_buffer=RID();
+ }
+
+}
+void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){
+
+ ERR_FAIL_COND(p_size<32 || p_size>16384);
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ int new_size = nearest_power_of_2(p_size);;
+ if (new_size==clight->shadow_buffer_size)
+ return;
+
+ clight->shadow_buffer_size=nearest_power_of_2(p_size);
+
+ if (clight->shadow_buffer.is_valid()) {
+ VSG::storage->free(clight->shadow_buffer);
+ clight->shadow_buffer=VSG::storage->canvas_light_shadow_buffer_create(clight->shadow_buffer_size);
+ }
+}
+
+void VisualServerCanvas::canvas_light_set_shadow_gradient_length(RID p_light, float p_length) {
+
+ ERR_FAIL_COND(p_length<0);
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->shadow_gradient_length=p_length;
+
+}
+void VisualServerCanvas::canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter) {
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->shadow_filter=p_filter;
+
+}
+void VisualServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color& p_color) {
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+
+ clight->shadow_color=p_color;
+}
+
+
+
+RID VisualServerCanvas::canvas_light_occluder_create() {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = memnew( RasterizerCanvas::LightOccluderInstance );
+
+ return canvas_light_occluder_owner.make_rid(occluder);
+}
+void VisualServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas){
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!occluder);
+
+ if (occluder->canvas.is_valid()) {
+
+ Canvas *canvas = canvas_owner.get(occluder->canvas);
+ canvas->occluders.erase(occluder);
+ }
+
+ if (!canvas_owner.owns(p_canvas))
+ p_canvas=RID();
+
+ occluder->canvas=p_canvas;
+
+ if (occluder->canvas.is_valid()) {
+
+ Canvas *canvas = canvas_owner.get(occluder->canvas);
+ canvas->occluders.insert(occluder);
+ }
+}
+void VisualServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled) {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!occluder);
+
+ occluder->enabled=p_enabled;
+}
+void VisualServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!occluder);
+
+ if (occluder->polygon.is_valid()) {
+ LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon);
+ if (occluder_poly) {
+ occluder_poly->owners.erase(occluder);
+ }
+ }
+
+ occluder->polygon=p_polygon;
+ occluder->polygon_buffer=RID();
+
+ if (occluder->polygon.is_valid()) {
+ LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon);
+ if (!occluder_poly)
+ occluder->polygon=RID();
+ ERR_FAIL_COND(!occluder_poly);
+ occluder_poly->owners.insert(occluder);
+ occluder->polygon_buffer=occluder_poly->occluder;
+ occluder->aabb_cache=occluder_poly->aabb;
+ occluder->cull_cache=occluder_poly->cull_mode;
+ }
+
+}
+void VisualServerCanvas::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!occluder);
+
+ occluder->xform=p_xform;
+}
+void VisualServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!occluder);
+
+ occluder->light_mask=p_mask;
+}
+
+RID VisualServerCanvas::canvas_occluder_polygon_create() {
+
+ LightOccluderPolygon * occluder_poly = memnew( LightOccluderPolygon );
+ occluder_poly->occluder=VSG::storage->canvas_light_occluder_create();
+ return canvas_light_occluder_polygon_owner.make_rid(occluder_poly);
+
+}
+void VisualServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed) {
+
+ if (p_shape.size()<3) {
+ canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape);
+ return;
+ }
+
+ DVector<Vector2> lines;
+ int lc = p_shape.size()*2;
+
+ lines.resize(lc-(p_closed?0:2));
+ {
+ DVector<Vector2>::Write w = lines.write();
+ DVector<Vector2>::Read r = p_shape.read();
+
+ int max=lc/2;
+ if (!p_closed) {
+ max--;
+ }
+ for(int i=0;i<max;i++) {
+
+ Vector2 a = r[i];
+ Vector2 b = r[(i+1)%(lc/2)];
+ w[i*2+0]=a;
+ w[i*2+1]=b;
+ }
+
+ }
+
+ canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,lines);
+}
+void VisualServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape) {
+
+ LightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon);
+ ERR_FAIL_COND(!occluder_poly);
+ ERR_FAIL_COND(p_shape.size()&1);
+
+ int lc = p_shape.size();
+ occluder_poly->aabb=Rect2();
+ {
+ DVector<Vector2>::Read r = p_shape.read();
+ for(int i=0;i<lc;i++) {
+ if (i==0)
+ occluder_poly->aabb.pos=r[i];
+ else
+ occluder_poly->aabb.expand_to(r[i]);
+ }
+ }
+
+ VSG::storage->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape);
+ for( Set<RasterizerCanvas::LightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) {
+ E->get()->aabb_cache=occluder_poly->aabb;
+ }
+}
+
+
+void VisualServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,VS::CanvasOccluderPolygonCullMode p_mode) {
+
+ LightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon);
+ ERR_FAIL_COND(!occluder_poly);
+ occluder_poly->cull_mode=p_mode;
+ for( Set<RasterizerCanvas::LightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) {
+ E->get()->cull_cache=p_mode;
+ }
+}
+
+
+
+bool VisualServerCanvas::free(RID p_rid) {
+
+ if (canvas_owner.owns(p_rid)) {
+
+ Canvas *canvas = canvas_owner.get(p_rid);
+ ERR_FAIL_COND_V(!canvas,false);
+
+ while(canvas->viewports.size()) {
+
+ VisualServerViewport::Viewport *vp = VSG::viewport->viewport_owner.get(canvas->viewports.front()->get());
+ ERR_FAIL_COND_V(!vp,true);
+
+ Map<RID,VisualServerViewport::Viewport::CanvasData>::Element *E=vp->canvas_map.find(p_rid);
+ ERR_FAIL_COND_V(!E,true);
+ vp->canvas_map.erase(p_rid);
+
+ canvas->viewports.erase( canvas->viewports.front() );
+ }
+
+ for (int i=0;i<canvas->child_items.size();i++) {
+
+ canvas->child_items[i].item->parent=RID();
+ }
+
+ for (Set<RasterizerCanvas::Light*>::Element *E=canvas->lights.front();E;E=E->next()) {
+
+ E->get()->canvas=RID();
+ }
+
+ for (Set<RasterizerCanvas::LightOccluderInstance*>::Element *E=canvas->occluders.front();E;E=E->next()) {
+
+ E->get()->canvas=RID();
+ }
+
+ canvas_owner.free( p_rid );
+
+ memdelete( canvas );
+
+ } else if (canvas_item_owner.owns(p_rid)) {
+
+ Item *canvas_item = canvas_item_owner.get(p_rid);
+ ERR_FAIL_COND_V(!canvas_item,true);
+
+ if (canvas_item->parent.is_valid()) {
+
+ if (canvas_owner.owns(canvas_item->parent)) {
+
+ Canvas *canvas = canvas_owner.get(canvas_item->parent);
+ canvas->erase_item(canvas_item);
+ } else if (canvas_item_owner.owns(canvas_item->parent)) {
+
+ Item *item_owner = canvas_item_owner.get(canvas_item->parent);
+ item_owner->child_items.erase(canvas_item);
+
+ }
+ }
+
+ for (int i=0;i<canvas_item->child_items.size();i++) {
+
+ canvas_item->child_items[i]->parent=RID();
+ }
+
+// if (canvas_item->material) {
+// canvas_item->material->owners.erase(canvas_item);
+// }
+
+ canvas_item_owner.free( p_rid );
+
+ memdelete( canvas_item );
+
+ } else if (canvas_light_owner.owns(p_rid)) {
+
+ RasterizerCanvas::Light *canvas_light = canvas_light_owner.get(p_rid);
+ ERR_FAIL_COND_V(!canvas_light,true);
+
+ if (canvas_light->canvas.is_valid()) {
+ Canvas* canvas = canvas_owner.get(canvas_light->canvas);
+ if (canvas)
+ canvas->lights.erase(canvas_light);
+ }
+
+ if (canvas_light->shadow_buffer.is_valid())
+ VSG::storage->free(canvas_light->shadow_buffer);
+
+ VSG::canvas_render->light_internal_free(canvas_light->light_internal);
+
+ canvas_light_owner.free( p_rid );
+ memdelete( canvas_light );
+
+ } else if (canvas_light_occluder_owner.owns(p_rid)) {
+
+ RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid);
+ ERR_FAIL_COND_V(!occluder,true);
+
+ if (occluder->polygon.is_valid()) {
+
+ LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon);
+ if (occluder_poly) {
+ occluder_poly->owners.erase(occluder);
+ }
+
+ }
+
+ if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) {
+
+ Canvas *canvas = canvas_owner.get(occluder->canvas);
+ canvas->occluders.erase(occluder);
+
+ }
+
+ canvas_light_occluder_owner.free( p_rid );
+ memdelete(occluder);
+
+ } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) {
+
+ LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid);
+ ERR_FAIL_COND_V(!occluder_poly,true);
+ VSG::storage->free(occluder_poly->occluder);
+
+ while(occluder_poly->owners.size()) {
+
+ occluder_poly->owners.front()->get()->polygon=RID();
+ occluder_poly->owners.erase( occluder_poly->owners.front() );
+ }
+
+ canvas_light_occluder_polygon_owner.free( p_rid );
+ memdelete(occluder_poly);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+
+
+VisualServerCanvas::VisualServerCanvas()
+{
+
+}
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
new file mode 100644
index 0000000000..b5412ed608
--- /dev/null
+++ b/servers/visual/visual_server_canvas.h
@@ -0,0 +1,214 @@
+#ifndef VISUALSERVERCANVAS_H
+#define VISUALSERVERCANVAS_H
+
+#include "rasterizer.h"
+#include "visual_server_viewport.h"
+
+class VisualServerCanvas {
+public:
+
+
+ struct Item : public RasterizerCanvas::Item {
+
+
+ RID parent; // canvas it belongs to
+ List<Item*>::Element *E;
+ int z;
+ bool z_relative;
+ bool sort_y;
+ Color modulate;
+ Color self_modulate;
+ bool use_parent_material;
+ int index;
+ bool children_order_dirty;
+
+
+ Vector<Item*> child_items;
+
+
+ Item() {
+ children_order_dirty=true;
+ E=NULL;
+ z=0;
+ modulate=Color(1,1,1,1);
+ self_modulate=Color(1,1,1,1);
+ sort_y=false;
+ use_parent_material=false;
+ z_relative=true;
+ index=0;
+ }
+ };
+
+
+ struct ItemPtrSort {
+
+ _FORCE_INLINE_ bool operator()(const Item* p_left,const Item* p_right) const {
+
+ return p_left->xform.elements[2].y < p_right->xform.elements[2].y;
+ }
+ };
+
+ struct LightOccluderPolygon : RID_Data {
+
+ bool active;
+ Rect2 aabb;
+ VS::CanvasOccluderPolygonCullMode cull_mode;
+ RID occluder;
+ Set<RasterizerCanvas::LightOccluderInstance*> owners;
+
+ LightOccluderPolygon() { active=false; cull_mode=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
+ };
+
+
+ RID_Owner<LightOccluderPolygon> canvas_light_occluder_polygon_owner;
+
+ RID_Owner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner;
+
+ struct Canvas : public VisualServerViewport::CanvasBase {
+
+ Set<RID> viewports;
+ struct ChildItem {
+
+ Point2 mirror;
+ Item *item;
+ bool operator<(const ChildItem& p_item) const {
+ return item->index < p_item.item->index;
+ }
+ };
+
+
+
+ Set<RasterizerCanvas::Light*> lights;
+
+ Set<RasterizerCanvas::LightOccluderInstance*> occluders;
+
+ bool children_order_dirty;
+ Vector<ChildItem> child_items;
+ Color modulate;
+
+ int find_item(Item *p_item) {
+ for(int i=0;i<child_items.size();i++) {
+ if (child_items[i].item==p_item)
+ return i;
+ }
+ return -1;
+ }
+ void erase_item(Item *p_item) {
+ int idx=find_item(p_item);
+ if (idx>=0)
+ child_items.remove(idx);
+ }
+
+
+ Canvas() { modulate=Color(1,1,1,1); children_order_dirty=true; }
+
+ };
+
+
+ RID_Owner<Canvas> canvas_owner;
+ RID_Owner<Item> canvas_item_owner;
+ RID_Owner<RasterizerCanvas::Light> canvas_light_owner;
+
+private:
+
+ void _render_canvas_item_tree(Item *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights);
+ void _render_canvas_item(Item *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
+ void _light_mask_canvas_items(int p_z,RasterizerCanvas::Item *p_canvas_item,RasterizerCanvas::Light *p_masked_lights);
+public:
+
+ void render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights,const Rect2& p_clip_rect);
+
+ RID canvas_create();
+ void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring);
+ void canvas_set_modulate(RID p_canvas,const Color& p_color);
+
+
+ RID canvas_item_create();
+ void canvas_item_set_parent(RID p_item,RID p_parent);
+
+ void canvas_item_set_visible(RID p_item,bool p_visible);
+ void canvas_item_set_light_mask(RID p_item,int p_mask);
+
+ void canvas_item_set_transform(RID p_item, const Matrix32& p_transform);
+ void canvas_item_set_clip(RID p_item, bool p_clip);
+ void canvas_item_set_distance_field_mode(RID p_item, bool p_enable);
+ void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2());
+ void canvas_item_set_modulate(RID p_item, const Color& p_color);
+ void canvas_item_set_self_modulate(RID p_item, const Color& p_color);
+
+ void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable);
+
+
+ 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,bool p_antialiased=false);
+ void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color);
+ void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color);
+ 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);
+ 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);
+ void canvas_item_add_nine_patch(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright,VS::NinePatchAxisMode p_x_axis_mode=VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode=VS::NINE_PATCH_STRETCH,bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
+ 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);
+ 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());
+ void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1);
+ void canvas_item_add_mesh(RID p_item, const RID& p_mesh,RID p_skeleton=RID());
+ void canvas_item_add_multimesh(RID p_item, RID p_mesh,RID p_skeleton=RID());
+ void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform);
+ void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
+ void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
+ void canvas_item_set_z(RID p_item, int p_z);
+ void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
+ void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect);
+
+ void canvas_item_clear(RID p_item);
+ void canvas_item_set_draw_index(RID p_item, int p_index);
+
+ void canvas_item_set_material(RID p_item, RID p_material);
+
+ void canvas_item_set_use_parent_material(RID p_item, bool p_enable);
+
+ RID canvas_light_create();
+ void canvas_light_attach_to_canvas(RID p_light,RID p_canvas);
+ void canvas_light_set_enabled(RID p_light, bool p_enabled);
+ void canvas_light_set_scale(RID p_light, float p_scale);
+ void canvas_light_set_transform(RID p_light, const Matrix32& p_transform);
+ void canvas_light_set_texture(RID p_light, RID p_texture);
+ void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset);
+ void canvas_light_set_color(RID p_light, const Color& p_color);
+ void canvas_light_set_height(RID p_light, float p_height);
+ void canvas_light_set_energy(RID p_light, float p_energy);
+ void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z);
+ void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer);
+ void canvas_light_set_item_cull_mask(RID p_light, int p_mask);
+ void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask);
+
+ void canvas_light_set_mode(RID p_light, VS::CanvasLightMode p_mode);
+
+
+ void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
+ void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
+ void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
+ void canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter);
+ void canvas_light_set_shadow_color(RID p_light, const Color& p_color);
+
+
+
+ RID canvas_light_occluder_create();
+ void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas);
+ void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled);
+ void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon);
+ void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform);
+ void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask);
+
+ RID canvas_occluder_polygon_create();
+ void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed);
+ void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape);
+
+
+ void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,VS::CanvasOccluderPolygonCullMode p_mode);
+
+
+ bool free(RID p_rid);
+ VisualServerCanvas();
+
+
+};
+
+#endif // VISUALSERVERCANVAS_H
diff --git a/servers/visual/visual_server_global.cpp b/servers/visual/visual_server_global.cpp
new file mode 100644
index 0000000000..32b9710f42
--- /dev/null
+++ b/servers/visual/visual_server_global.cpp
@@ -0,0 +1,10 @@
+#include "visual_server_global.h"
+
+RasterizerStorage *VisualServerGlobals::storage=NULL;
+RasterizerCanvas *VisualServerGlobals::canvas_render=NULL;
+RasterizerScene *VisualServerGlobals::scene_render=NULL;
+Rasterizer *VisualServerGlobals::rasterizer=NULL;
+
+VisualServerCanvas *VisualServerGlobals::canvas=NULL;
+VisualServerViewport *VisualServerGlobals::viewport=NULL;
+VisualServerScene *VisualServerGlobals::scene=NULL;
diff --git a/servers/visual/visual_server_global.h b/servers/visual/visual_server_global.h
new file mode 100644
index 0000000000..d413334ac4
--- /dev/null
+++ b/servers/visual/visual_server_global.h
@@ -0,0 +1,26 @@
+#ifndef VISUALSERVERGLOBAL_H
+#define VISUALSERVERGLOBAL_H
+
+#include "rasterizer.h"
+
+class VisualServerCanvas;
+class VisualServerViewport;
+class VisualServerScene;
+
+class VisualServerGlobals
+{
+public:
+
+ static RasterizerStorage *storage;
+ static RasterizerCanvas *canvas_render;
+ static RasterizerScene *scene_render;
+ static Rasterizer *rasterizer;
+
+ static VisualServerCanvas *canvas;
+ static VisualServerViewport *viewport;
+ static VisualServerScene *scene;
+};
+
+#define VSG VisualServerGlobals
+
+#endif // VISUALSERVERGLOBAL_H
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 8d228ad859..168afac77f 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -32,8 +32,1280 @@
#include "default_mouse_cursor.xpm"
#include "sort.h"
#include "io/marshalls.h"
+#include "visual_server_canvas.h"
+#include "visual_server_global.h"
+
// careful, these may run in different threads than the visual server
+RID VisualServerRaster::texture_create(){
+
+ return VSG::storage->texture_create();
+}
+void VisualServerRaster::texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags){
+
+ VSG::storage->texture_allocate(p_texture,p_width,p_height,p_format,p_flags);
+}
+void VisualServerRaster::texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side){
+
+ VSG::storage->texture_set_data(p_texture,p_image,p_cube_side);
+}
+Image VisualServerRaster::texture_get_data(RID p_texture,CubeMapSide p_cube_side) const{
+
+ return VSG::storage->texture_get_data(p_texture,p_cube_side);
+}
+void VisualServerRaster::texture_set_flags(RID p_texture,uint32_t p_flags) {
+
+ VSG::storage->texture_set_flags(p_texture,p_flags);
+}
+uint32_t VisualServerRaster::texture_get_flags(RID p_texture) const{
+
+ return VSG::storage->texture_get_flags(p_texture);
+}
+Image::Format VisualServerRaster::texture_get_format(RID p_texture) const{
+
+ return VSG::storage->texture_get_format(p_texture);
+}
+uint32_t VisualServerRaster::texture_get_width(RID p_texture) const{
+
+ return VSG::storage->texture_get_width(p_texture);
+}
+uint32_t VisualServerRaster::texture_get_height(RID p_texture) const{
+
+ return VSG::storage->texture_get_height(p_texture);
+}
+void VisualServerRaster::texture_set_size_override(RID p_texture,int p_width, int p_height){
+ VSG::storage->texture_set_size_override(p_texture,p_width,p_height);
+
+}
+
+void VisualServerRaster::texture_set_path(RID p_texture,const String& p_path){
+
+ VSG::storage->texture_set_path(p_texture,p_path);
+}
+
+String VisualServerRaster::texture_get_path(RID p_texture) const{
+
+ return VSG::storage->texture_get_path(p_texture);
+}
+
+void VisualServerRaster::texture_set_shrink_all_x2_on_set_data(bool p_enable){
+
+ VSG::storage->texture_set_shrink_all_x2_on_set_data(p_enable);
+}
+
+void VisualServerRaster::texture_debug_usage(List<TextureInfo> *r_info){
+
+ VSG::storage->texture_debug_usage(r_info);
+}
+
+
+/* SHADER API */
+
+
+RID VisualServerRaster::shader_create(ShaderMode p_mode){
+
+ return VSG::storage->shader_create(p_mode);
+}
+
+void VisualServerRaster::shader_set_mode(RID p_shader,ShaderMode p_mode){
+
+ VSG::storage->shader_set_mode(p_shader,p_mode);
+}
+VisualServerRaster::ShaderMode VisualServerRaster::shader_get_mode(RID p_shader) const{
+
+ return VSG::storage->shader_get_mode(p_shader);
+}
+
+void VisualServerRaster::shader_set_code(RID p_shader, const String& p_code){
+
+ VSG::storage->shader_set_code(p_shader,p_code);
+}
+String VisualServerRaster::shader_get_code(RID p_shader) const{
+
+ return VSG::storage->shader_get_code(p_shader);
+}
+void VisualServerRaster::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const{
+
+ VSG::storage->shader_get_param_list(p_shader,p_param_list);
+}
+
+void VisualServerRaster::shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture){
+
+ VSG::storage->shader_set_default_texture_param(p_shader,p_name,p_texture);
+}
+RID VisualServerRaster::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
+
+ return VSG::storage->shader_get_default_texture_param(p_shader,p_name);
+}
+
+
+/* COMMON MATERIAL API */
+
+RID VisualServerRaster::material_create(){
+
+ return VSG::storage->material_create();
+}
+
+void VisualServerRaster::material_set_shader(RID p_shader_material, RID p_shader){
+
+ VSG::storage->material_set_shader(p_shader_material,p_shader);
+}
+RID VisualServerRaster::material_get_shader(RID p_shader_material) const{
+
+ return VSG::storage->material_get_shader(p_shader_material);
+}
+
+void VisualServerRaster::material_set_param(RID p_material, const StringName& p_param, const Variant& p_value){
+
+ VSG::storage->material_set_param(p_material,p_param,p_value);
+}
+Variant VisualServerRaster::material_get_param(RID p_material, const StringName& p_param) const{
+
+ return VSG::storage->material_get_param(p_material,p_param);
+}
+
+/* MESH API */
+
+RID VisualServerRaster::mesh_create(){
+
+ return VSG::storage->mesh_create();
+}
+
+void VisualServerRaster::mesh_add_surface(RID p_mesh,uint32_t p_format,PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const Vector<DVector<uint8_t> >& p_blend_shapes){
+
+ VSG::storage->mesh_add_surface(p_mesh,p_format,p_primitive,p_array,p_vertex_count,p_index_array,p_index_count,p_blend_shapes);
+}
+
+void VisualServerRaster::mesh_set_morph_target_count(RID p_mesh,int p_amount){
+
+ VSG::storage->mesh_set_morph_target_count(p_mesh,p_amount);
+}
+int VisualServerRaster::mesh_get_morph_target_count(RID p_mesh) const{
+
+ return VSG::storage->mesh_get_morph_target_count(p_mesh);
+}
+
+
+void VisualServerRaster::mesh_set_morph_target_mode(RID p_mesh,MorphTargetMode p_mode){
+
+ VSG::storage->mesh_set_morph_target_mode(p_mesh,p_mode);
+}
+VisualServerRaster::MorphTargetMode VisualServerRaster::mesh_get_morph_target_mode(RID p_mesh) const{
+
+ return VSG::storage->mesh_get_morph_target_mode(p_mesh);
+}
+
+void VisualServerRaster::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material){
+
+ VSG::storage->mesh_surface_set_material(p_mesh,p_surface,p_material);
+}
+RID VisualServerRaster::mesh_surface_get_material(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_material(p_mesh,p_surface);
+}
+
+int VisualServerRaster::mesh_surface_get_array_len(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_array_len(p_mesh,p_surface);
+}
+int VisualServerRaster::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_array_index_len(p_mesh,p_surface);
+}
+
+DVector<uint8_t> VisualServerRaster::mesh_surface_get_array(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_array(p_mesh,p_surface);
+}
+DVector<uint8_t> VisualServerRaster::mesh_surface_get_index_array(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_index_array(p_mesh,p_surface);
+}
+
+
+uint32_t VisualServerRaster::mesh_surface_get_format(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_format(p_mesh,p_surface);
+}
+VisualServerRaster::PrimitiveType VisualServerRaster::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const{
+
+ return VSG::storage->mesh_surface_get_primitive_type(p_mesh,p_surface);
+}
+
+void VisualServerRaster::mesh_remove_surface(RID p_mesh,int p_index){
+
+ VSG::storage->mesh_remove_surface(p_mesh,p_index);
+}
+int VisualServerRaster::mesh_get_surface_count(RID p_mesh) const{
+
+ return VSG::storage->mesh_get_surface_count(p_mesh);
+}
+
+void VisualServerRaster::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb){
+
+ VSG::storage->mesh_set_custom_aabb(p_mesh,p_aabb);
+}
+AABB VisualServerRaster::mesh_get_custom_aabb(RID p_mesh) const{
+
+ return VSG::storage->mesh_get_custom_aabb(p_mesh);
+}
+
+void VisualServerRaster::mesh_clear(RID p_mesh){
+
+ VSG::storage->mesh_clear(p_mesh);
+}
+
+/* MULTIMESH API */
+
+
+RID VisualServerRaster::multimesh_create() {
+
+ return VSG::storage->multimesh_create();
+}
+
+void VisualServerRaster::multimesh_allocate(RID p_multimesh,int p_instances,MultimeshTransformFormat p_transform_format,MultimeshColorFormat p_color_format,bool p_gen_aabb){
+
+ VSG::storage->multimesh_allocate(p_multimesh,p_instances,p_transform_format,p_color_format,p_gen_aabb);
+}
+int VisualServerRaster::multimesh_get_instance_count(RID p_multimesh) const{
+
+ return VSG::storage->multimesh_get_instance_count(p_multimesh);
+}
+
+void VisualServerRaster::multimesh_set_mesh(RID p_multimesh,RID p_mesh){
+
+ VSG::storage->multimesh_set_mesh(p_multimesh,p_mesh);
+}
+void VisualServerRaster::multimesh_set_custom_aabb(RID p_multimesh,const AABB& p_aabb){
+
+ VSG::storage->multimesh_set_custom_aabb(p_multimesh,p_aabb);
+}
+void VisualServerRaster::multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform& p_transform){
+
+ VSG::storage->multimesh_instance_set_transform(p_multimesh,p_index,p_transform);
+}
+void VisualServerRaster::multimesh_instance_set_transform_2d(RID p_multimesh,int p_index,const Matrix32& p_transform){
+
+ VSG::storage->multimesh_instance_set_transform_2d(p_multimesh,p_index,p_transform);
+}
+void VisualServerRaster::multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color){
+
+ VSG::storage->multimesh_instance_set_color(p_multimesh,p_index,p_color);
+}
+
+RID VisualServerRaster::multimesh_get_mesh(RID p_multimesh) const{
+
+ return VSG::storage->multimesh_get_mesh(p_multimesh);
+}
+AABB VisualServerRaster::multimesh_get_custom_aabb(RID p_multimesh,const AABB& p_aabb) const{
+
+ return VSG::storage->multimesh_get_custom_aabb(p_multimesh,p_aabb);
+}
+
+Transform VisualServerRaster::multimesh_instance_get_transform(RID p_multimesh,int p_index) const{
+
+ return VSG::storage->multimesh_instance_get_transform(p_multimesh,p_index);
+}
+Matrix32 VisualServerRaster::multimesh_instance_get_transform_2d(RID p_multimesh,int p_index) const{
+
+ return VSG::storage->multimesh_instance_get_transform_2d(p_multimesh,p_index);
+}
+Color VisualServerRaster::multimesh_instance_get_color(RID p_multimesh,int p_index) const{
+
+ return VSG::storage->multimesh_instance_get_color(p_multimesh,p_index);
+}
+
+void VisualServerRaster::multimesh_set_visible_instances(RID p_multimesh,int p_visible){
+
+ VSG::storage->multimesh_set_visible_instances(p_multimesh,p_visible);
+}
+int VisualServerRaster::multimesh_get_visible_instances(RID p_multimesh) const{
+
+ return VSG::storage->multimesh_get_visible_instances(p_multimesh);
+}
+
+
+/* IMMEDIATE API */
+
+RID VisualServerRaster::immediate_create(){
+
+ return VSG::storage->immediate_create();
+}
+void VisualServerRaster::immediate_begin(RID p_immediate,PrimitiveType p_rimitive,RID p_texture){
+
+ VSG::storage->immediate_begin(p_immediate,p_rimitive,p_texture);
+}
+void VisualServerRaster::immediate_vertex(RID p_immediate,const Vector3& p_vertex){
+
+ VSG::storage->immediate_vertex(p_immediate,p_vertex);
+}
+void VisualServerRaster::immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex){
+
+ VSG::storage->immediate_vertex_2d(p_immediate,p_vertex);
+
+}
+void VisualServerRaster::immediate_normal(RID p_immediate,const Vector3& p_normal){
+
+ VSG::storage->immediate_normal(p_immediate,p_normal);
+
+}
+void VisualServerRaster::immediate_tangent(RID p_immediate,const Plane& p_tangent){
+
+ VSG::storage->immediate_tangent(p_immediate,p_tangent);
+}
+void VisualServerRaster::immediate_color(RID p_immediate,const Color& p_color){
+
+ VSG::storage->immediate_color(p_immediate,p_color);
+
+}
+void VisualServerRaster::immediate_uv(RID p_immediate,const Vector2& tex_uv){
+
+ VSG::storage->immediate_uv(p_immediate,tex_uv);
+
+}
+void VisualServerRaster::immediate_uv2(RID p_immediate,const Vector2& tex_uv){
+
+ VSG::storage->immediate_uv2(p_immediate,tex_uv);
+
+}
+void VisualServerRaster::immediate_end(RID p_immediate){
+
+ VSG::storage->immediate_end(p_immediate);
+
+}
+void VisualServerRaster::immediate_clear(RID p_immediate){
+
+ VSG::storage->immediate_clear(p_immediate);
+
+}
+void VisualServerRaster::immediate_set_material(RID p_immediate,RID p_material){
+
+ VSG::storage->immediate_set_material(p_immediate,p_material);
+
+}
+RID VisualServerRaster::immediate_get_material(RID p_immediate) const{
+
+ return VSG::storage->immediate_get_material(p_immediate);
+}
+
+/* SKELETON API */
+
+RID VisualServerRaster::skeleton_create(){
+
+ return VSG::storage->skeleton_create();
+}
+void VisualServerRaster::skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton){
+
+ VSG::storage->skeleton_allocate(p_skeleton,p_bones,p_2d_skeleton);
+}
+int VisualServerRaster::skeleton_get_bone_count(RID p_skeleton) const{
+
+ return VSG::storage->skeleton_get_bone_count(p_skeleton);
+}
+void VisualServerRaster::skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform){
+
+ VSG::storage->skeleton_bone_set_transform(p_skeleton,p_bone,p_transform);
+}
+Transform VisualServerRaster::skeleton_bone_get_transform(RID p_skeleton,int p_bone){
+
+ return VSG::storage->skeleton_bone_get_transform(p_skeleton,p_bone);
+}
+void VisualServerRaster::skeleton_bone_set_transform_2d(RID p_skeleton,int p_bone, const Matrix32& p_transform){
+
+ VSG::storage->skeleton_bone_set_transform_2d(p_skeleton,p_bone,p_transform);
+}
+Matrix32 VisualServerRaster::skeleton_bone_get_transform_2d(RID p_skeleton,int p_bone){
+
+ return VSG::storage->skeleton_bone_get_transform_2d(p_skeleton,p_bone);
+}
+
+/* Light API */
+
+RID VisualServerRaster::light_create(LightType p_type){
+
+ return VSG::storage->light_create(p_type);
+}
+
+void VisualServerRaster::light_set_color(RID p_light,const Color& p_color){
+
+ VSG::storage->light_set_color(p_light,p_color);
+}
+void VisualServerRaster::light_set_param(RID p_light,LightParam p_param,float p_value){
+
+ VSG::storage->light_set_param(p_light,p_param,p_value);
+}
+void VisualServerRaster::light_set_shadow(RID p_light,bool p_enabled){
+
+ VSG::storage->light_set_shadow(p_light,p_enabled);
+}
+void VisualServerRaster::light_set_projector(RID p_light,RID p_texture){
+
+ VSG::storage->light_set_projector(p_light,p_texture);
+}
+void VisualServerRaster::light_set_attenuation_texure(RID p_light,RID p_texture){
+
+ VSG::storage->light_set_attenuation_texure(p_light,p_texture);
+}
+void VisualServerRaster::light_set_negative(RID p_light,bool p_enable){
+
+ VSG::storage->light_set_negative(p_light,p_enable);
+}
+void VisualServerRaster::light_set_cull_mask(RID p_light,uint32_t p_mask){
+
+ VSG::storage->light_set_cull_mask(p_light,p_mask);
+}
+void VisualServerRaster::light_set_shader(RID p_light,RID p_shader){
+
+ VSG::storage->light_set_shader(p_light,p_shader);
+}
+
+
+void VisualServerRaster::light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode){
+
+ VSG::storage->light_directional_set_shadow_mode(p_light,p_mode);
+}
+
+/* PROBE API */
+
+RID VisualServerRaster::reflection_probe_create(){
+
+ return VSG::storage->reflection_probe_create();
+}
+
+void VisualServerRaster::reflection_probe_set_intensity(RID p_probe, float p_intensity){
+
+ VSG::storage->reflection_probe_set_intensity(p_probe,p_intensity);
+}
+void VisualServerRaster::reflection_probe_set_clip(RID p_probe, float p_near, float p_far){
+
+ VSG::storage->reflection_probe_set_clip(p_probe,p_near,p_far);
+}
+void VisualServerRaster::reflection_probe_set_min_blend_distance(RID p_probe, float p_distance){
+
+ VSG::storage->reflection_probe_set_min_blend_distance(p_probe,p_distance);
+}
+void VisualServerRaster::reflection_probe_set_extents(RID p_probe, const Vector3& p_extents){
+
+ VSG::storage->reflection_probe_set_extents(p_probe,p_extents);
+}
+void VisualServerRaster::reflection_probe_set_origin_offset(RID p_probe, const Vector3& p_offset){
+
+ VSG::storage->reflection_probe_set_origin_offset(p_probe,p_offset);
+}
+void VisualServerRaster::reflection_probe_set_enable_parallax_correction(RID p_probe, bool p_enable){
+
+ VSG::storage->reflection_probe_set_enable_parallax_correction(p_probe,p_enable);
+}
+void VisualServerRaster::reflection_probe_set_resolution(RID p_probe, int p_resolution){
+
+ VSG::storage->reflection_probe_set_resolution(p_probe,p_resolution);
+}
+void VisualServerRaster::reflection_probe_set_hide_skybox(RID p_probe, bool p_hide){
+
+ VSG::storage->reflection_probe_set_hide_skybox(p_probe,p_hide);
+}
+void VisualServerRaster::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers){
+
+ VSG::storage->reflection_probe_set_cull_mask(p_probe,p_layers);
+}
+
+
+/* ROOM API */
+
+RID VisualServerRaster::room_create(){
+
+ return VSG::storage->room_create();
+}
+void VisualServerRaster::room_add_bounds(RID p_room, const DVector<Vector2>& p_convex_polygon,float p_height,const Transform& p_transform){
+
+ VSG::storage->room_add_bounds(p_room,p_convex_polygon,p_height,p_transform);
+}
+void VisualServerRaster::room_clear_bounds(){
+
+ VSG::storage->room_clear_bounds();
+}
+
+/* PORTAL API */
+
+// portals are only (x/y) points, forming a convex shape, which its clockwise
+// order points outside. (z is 0);
+
+RID VisualServerRaster::portal_create(){
+
+ return VSG::storage->portal_create();
+}
+void VisualServerRaster::portal_set_shape(RID p_portal, const Vector<Point2>& p_shape){
+
+ VSG::storage->portal_set_shape(p_portal,p_shape);
+}
+void VisualServerRaster::portal_set_enabled(RID p_portal, bool p_enabled) {
+
+ VSG::storage->portal_set_enabled(p_portal,p_enabled);
+}
+void VisualServerRaster::portal_set_disable_distance(RID p_portal, float p_distance){
+
+ VSG::storage->portal_set_disable_distance(p_portal,p_distance);
+}
+void VisualServerRaster::portal_set_disabled_color(RID p_portal, const Color& p_color){
+
+ VSG::storage->portal_set_disabled_color(p_portal,p_color);
+}
+
+/* CAMERA API */
+
+RID VisualServerRaster::camera_create() {
+
+ return RID();
+}
+void VisualServerRaster::camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far) {
+
+}
+void VisualServerRaster::camera_set_orthogonal(RID p_camera,float p_size, float p_z_near, float p_z_far){
+
+}
+void VisualServerRaster::camera_set_transform(RID p_camera,const Transform& p_transform) {
+
+}
+void VisualServerRaster::camera_set_cull_mask(RID p_camera,uint32_t p_layers){
+
+}
+void VisualServerRaster::camera_set_environment(RID p_camera,RID p_env){
+
+}
+void VisualServerRaster::camera_set_use_vertical_aspect(RID p_camera,bool p_enable){
+
+}
+
+
+/* VIEWPORT TARGET API */
+
+RID VisualServerRaster::viewport_create(){
+
+ return VSG::viewport->viewport_create();
+}
+
+void VisualServerRaster::viewport_set_size(RID p_viewport,int p_width,int p_height){
+
+ VSG::viewport->viewport_set_size(p_viewport,p_width,p_height);
+}
+
+void VisualServerRaster::viewport_set_active(RID p_viewport,bool p_active) {
+
+ VSG::viewport->viewport_set_active(p_viewport,p_active);
+}
+
+void VisualServerRaster::viewport_set_clear_mode(RID p_viewport,ViewportClearMode p_clear_mode) {
+
+ VSG::viewport->viewport_set_clear_mode(p_viewport,p_clear_mode);
+}
+
+void VisualServerRaster::viewport_attach_to_screen(RID p_viewport,const Rect2& p_rect,int p_screen){
+
+ VSG::viewport->viewport_attach_to_screen(p_viewport,p_rect,p_screen);
+
+}
+void VisualServerRaster::viewport_detach(RID p_viewport){
+
+ VSG::viewport->viewport_detach(p_viewport);
+
+}
+
+void VisualServerRaster::viewport_set_update_mode(RID p_viewport,ViewportUpdateMode p_mode){
+
+ VSG::viewport->viewport_set_update_mode(p_viewport,p_mode);
+
+}
+void VisualServerRaster::viewport_set_vflip(RID p_viewport,bool p_enable){
+
+ VSG::viewport->viewport_set_vflip(p_viewport,p_enable);
+
+}
+
+RID VisualServerRaster::viewport_get_texture(RID p_viewport) const{
+
+ return VSG::viewport->viewport_get_texture(p_viewport);
+
+}
+Image VisualServerRaster::viewport_capture(RID p_viewport) const{
+
+ return VSG::viewport->viewport_capture(p_viewport);
+}
+
+void VisualServerRaster::viewport_set_hide_scenario(RID p_viewport,bool p_hide){
+
+ return VSG::viewport->viewport_set_hide_scenario(p_viewport,p_hide);
+}
+void VisualServerRaster::viewport_set_hide_canvas(RID p_viewport,bool p_hide){
+
+ return VSG::viewport->viewport_set_hide_canvas(p_viewport,p_hide);
+
+}
+void VisualServerRaster::viewport_set_disable_environment(RID p_viewport,bool p_disable){
+
+ return VSG::viewport->viewport_set_disable_environment(p_viewport,p_disable);
+
+}
+
+void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera){
+
+ return VSG::viewport->viewport_attach_camera(p_viewport,p_camera);
+
+}
+void VisualServerRaster::viewport_set_scenario(RID p_viewport,RID p_scenario){
+
+ return VSG::viewport->viewport_set_scenario(p_viewport,p_scenario);
+
+}
+void VisualServerRaster::viewport_attach_canvas(RID p_viewport,RID p_canvas){
+
+ return VSG::viewport->viewport_attach_canvas(p_viewport,p_canvas);
+
+}
+void VisualServerRaster::viewport_remove_canvas(RID p_viewport,RID p_canvas){
+
+ return VSG::viewport->viewport_remove_canvas(p_viewport,p_canvas);
+
+}
+void VisualServerRaster::viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset){
+
+ return VSG::viewport->viewport_set_canvas_transform(p_viewport,p_canvas,p_offset);
+
+}
+void VisualServerRaster::viewport_set_transparent_background(RID p_viewport,bool p_enabled){
+
+ return VSG::viewport->viewport_set_transparent_background(p_viewport,p_enabled);
+
+}
+
+void VisualServerRaster::viewport_set_global_canvas_transform(RID p_viewport,const Matrix32& p_transform){
+
+ return VSG::viewport->viewport_set_global_canvas_transform(p_viewport,p_transform);
+
+}
+void VisualServerRaster::viewport_set_canvas_layer(RID p_viewport,RID p_canvas,int p_layer){
+
+ return VSG::viewport->viewport_set_canvas_layer(p_viewport,p_canvas,p_layer);
+
+}
+
+
+/* ENVIRONMENT API */
+
+RID VisualServerRaster::environment_create(){
+
+ return RID();
+}
+
+void VisualServerRaster::environment_set_background(RID p_env,EnvironmentBG p_bg){
+
+}
+void VisualServerRaster::environment_set_skybox(RID p_env,RID p_skybox,float p_energy){
+
+}
+void VisualServerRaster::environment_set_bg_color(RID p_env,const Color& p_color){
+
+}
+void VisualServerRaster::environment_set_canvas_max_layer(RID p_env,int p_max_layer){
+
+}
+void VisualServerRaster::environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy){
+
+}
+
+void VisualServerRaster::environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,EnvironmentGlowBlendMode p_blend_mode){
+
+}
+void VisualServerRaster::environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture){
+
+}
+
+void VisualServerRaster::environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,EnvironmentToneMapper p_tone_mapper){
+
+}
+void VisualServerRaster::environment_set_brightness(RID p_env,bool p_enable,float p_brightness){
+
+}
+void VisualServerRaster::environment_set_contrast(RID p_env,bool p_enable,float p_contrast){
+
+}
+void VisualServerRaster::environment_set_saturation(RID p_env,bool p_enable,float p_saturation){
+
+}
+void VisualServerRaster::environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp){
+
+}
+
+
+/* SCENARIO API */
+
+
+RID VisualServerRaster::scenario_create() {
+
+ return RID();
+}
+
+void VisualServerRaster::scenario_set_debug(RID p_scenario,ScenarioDebugMode p_debug_mode){
+
+}
+void VisualServerRaster::scenario_set_environment(RID p_scenario, RID p_environment){
+
+}
+RID VisualServerRaster::scenario_get_environment(RID p_scenario, RID p_environment) const{
+
+ return RID();
+}
+void VisualServerRaster::scenario_set_fallback_environment(RID p_scenario, RID p_environment){
+
+}
+
+
+/* INSTANCING API */
+// from can be mesh, light, area and portal so far.
+RID VisualServerRaster::instance_create(){
+
+ return RID();
+}
+
+void VisualServerRaster::instance_set_base(RID p_instance, RID p_base){
+
+}
+void VisualServerRaster::instance_set_scenario(RID p_instance, RID p_scenario){
+
+}
+void VisualServerRaster::instance_set_layer_mask(RID p_instance, uint32_t p_mask){
+
+}
+void VisualServerRaster::instance_set_transform(RID p_instance, const Transform& p_transform){
+
+}
+void VisualServerRaster::instance_attach_object_instance_ID(RID p_instance,ObjectID p_ID){
+
+}
+void VisualServerRaster::instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight){
+
+}
+void VisualServerRaster::instance_set_surface_material(RID p_instance,int p_surface, RID p_material){
+
+}
+
+void VisualServerRaster::instance_attach_skeleton(RID p_instance,RID p_skeleton){
+
+}
+void VisualServerRaster::instance_set_exterior( RID p_instance, bool p_enabled ){
+
+}
+void VisualServerRaster::instance_set_room( RID p_instance, RID p_room ){
+
+}
+
+void VisualServerRaster::instance_set_extra_visibility_margin( RID p_instance, real_t p_margin ){
+
+}
+
+// don't use these in a game!
+Vector<ObjectID> VisualServerRaster::instances_cull_aabb(const AABB& p_aabb, RID p_scenario) const{
+
+ return Vector<ObjectID>();
+}
+
+Vector<ObjectID> VisualServerRaster::instances_cull_ray(const Vector3& p_from, const Vector3& p_to, RID p_scenario) const{
+
+ return Vector<ObjectID>();
+}
+Vector<ObjectID> VisualServerRaster::instances_cull_convex(const Vector<Plane>& p_convex, RID p_scenario) const {
+
+ return Vector<ObjectID>();
+}
+
+
+void VisualServerRaster::instance_geometry_set_flag(RID p_instance,InstanceFlags p_flags,bool p_enabled){
+
+}
+void VisualServerRaster::instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting) {
+
+}
+void VisualServerRaster::instance_geometry_set_material_override(RID p_instance, RID p_material){
+
+}
+
+
+void VisualServerRaster::instance_geometry_set_draw_range(RID p_instance,float p_min,float p_max,float p_min_margin,float p_max_margin){
+
+}
+void VisualServerRaster::instance_geometry_set_as_instance_lod(RID p_instance,RID p_as_lod_of_instance){
+
+}
+
+/* CANVAS (2D) */
+
+RID VisualServerRaster::canvas_create(){
+
+ return VSG::canvas->canvas_create();
+
+}
+void VisualServerRaster::canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring){
+
+ VSG::canvas->canvas_set_item_mirroring(p_canvas,p_item,p_mirroring);
+}
+void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color){
+
+ VSG::canvas->canvas_set_modulate(p_canvas,p_color);
+}
+
+
+RID VisualServerRaster::canvas_item_create(){
+
+ return VSG::canvas->canvas_item_create();
+}
+void VisualServerRaster::canvas_item_set_parent(RID p_item,RID p_parent){
+
+ VSG::canvas->canvas_item_set_parent(p_item,p_parent);
+
+}
+
+void VisualServerRaster::canvas_item_set_visible(RID p_item,bool p_visible){
+
+ VSG::canvas->canvas_item_set_visible(p_item,p_visible);
+
+}
+void VisualServerRaster::canvas_item_set_light_mask(RID p_item,int p_mask){
+
+ VSG::canvas->canvas_item_set_light_mask(p_item,p_mask);
+
+}
+
+void VisualServerRaster::canvas_item_set_transform(RID p_item, const Matrix32& p_transform){
+
+ VSG::canvas->canvas_item_set_transform(p_item,p_transform);
+
+}
+void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip){
+
+ VSG::canvas->canvas_item_set_clip(p_item,p_clip);
+
+}
+void VisualServerRaster::canvas_item_set_distance_field_mode(RID p_item, bool p_enable){
+
+ VSG::canvas->canvas_item_set_distance_field_mode(p_item,p_enable);
+
+}
+void VisualServerRaster::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect){
+
+ VSG::canvas->canvas_item_set_custom_rect(p_item,p_custom_rect,p_rect);
+
+}
+void VisualServerRaster::canvas_item_set_modulate(RID p_item, const Color& p_color){
+
+ VSG::canvas->canvas_item_set_modulate(p_item,p_color);
+
+}
+void VisualServerRaster::canvas_item_set_self_modulate(RID p_item, const Color& p_color){
+
+ VSG::canvas->canvas_item_set_self_modulate(p_item,p_color);
+
+}
+
+void VisualServerRaster::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable){
+
+ VSG::canvas->canvas_item_set_draw_behind_parent(p_item,p_enable);
+
+}
+
+
+void VisualServerRaster::canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased){
+
+ VSG::canvas->canvas_item_add_line(p_item,p_from,p_to,p_color,p_width,p_antialiased);
+
+}
+void VisualServerRaster::canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color){
+
+ VSG::canvas->canvas_item_add_rect(p_item,p_rect,p_color);
+
+}
+void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color){
+
+ VSG::canvas->canvas_item_add_circle(p_item,p_pos,p_radius,p_color);
+
+}
+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){
+
+ VSG::canvas->canvas_item_add_texture_rect(p_item,p_rect,p_texture,p_tile,p_modulate,p_transpose);
+
+}
+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){
+
+ VSG::canvas->canvas_item_add_texture_rect_region(p_item,p_rect,p_texture,p_src_rect,p_modulate,p_transpose);
+
+}
+void VisualServerRaster::canvas_item_add_nine_patch(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright,NinePatchAxisMode p_x_axis_mode, NinePatchAxisMode p_y_axis_mode,bool p_draw_center,const Color& p_modulate){
+
+ VSG::canvas->canvas_item_add_nine_patch(p_item,p_rect,p_source,p_texture,p_topleft,p_bottomright,p_x_axis_mode,p_y_axis_mode,p_draw_center,p_modulate);
+
+}
+void VisualServerRaster::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){
+
+ VSG::canvas->canvas_item_add_primitive(p_item,p_points,p_colors,p_uvs,p_texture,p_width);
+
+}
+void VisualServerRaster::canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture){
+
+ VSG::canvas->canvas_item_add_polygon(p_item,p_points,p_colors,p_uvs,p_texture);
+
+}
+void VisualServerRaster::canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture, int p_count){
+
+ VSG::canvas->canvas_item_add_triangle_array(p_item,p_indices,p_points,p_colors,p_uvs,p_texture,p_count);
+
+}
+void VisualServerRaster::canvas_item_add_mesh(RID p_item, const RID& p_mesh,RID p_skeleton){
+
+ VSG::canvas->canvas_item_add_mesh(p_item,p_mesh,p_skeleton);
+
+}
+void VisualServerRaster::canvas_item_add_multimesh(RID p_item, RID p_mesh,RID p_skeleton){
+
+ VSG::canvas->canvas_item_add_multimesh(p_item,p_mesh,p_skeleton);
+
+}
+void VisualServerRaster::canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform){
+
+ VSG::canvas->canvas_item_add_set_transform(p_item,p_transform);
+
+}
+void VisualServerRaster::canvas_item_add_clip_ignore(RID p_item, bool p_ignore){
+
+ VSG::canvas->canvas_item_add_clip_ignore(p_item,p_ignore);
+
+}
+void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable){
+
+ VSG::canvas->canvas_item_set_sort_children_by_y(p_item,p_enable);
+
+}
+void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z){
+
+ VSG::canvas->canvas_item_set_z(p_item,p_z);
+
+}
+void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable){
+
+ VSG::canvas->canvas_item_set_z_as_relative_to_parent(p_item,p_enable);
+
+}
+void VisualServerRaster::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect){
+
+ VSG::canvas->canvas_item_set_copy_to_backbuffer(p_item,p_enable,p_rect);
+
+}
+
+void VisualServerRaster::canvas_item_clear(RID p_item){
+
+ VSG::canvas->canvas_item_clear(p_item);
+
+}
+void VisualServerRaster::canvas_item_set_draw_index(RID p_item,int p_index){
+
+ VSG::canvas->canvas_item_set_draw_index(p_item,p_index);
+
+}
+
+void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material){
+
+ VSG::canvas->canvas_item_set_material(p_item,p_material);
+
+}
+
+void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
+
+ VSG::canvas->canvas_item_set_use_parent_material(p_item,p_enable);
+}
+
+RID VisualServerRaster::canvas_light_create(){
+
+ return VSG::canvas->canvas_light_create();
+}
+
+void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas){
+
+ VSG::canvas->canvas_light_attach_to_canvas(p_light,p_canvas);
+
+}
+void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){
+
+ VSG::canvas->canvas_light_set_enabled(p_light,p_enabled);
+
+}
+void VisualServerRaster::canvas_light_set_scale(RID p_light, float p_scale){
+
+ VSG::canvas->canvas_light_set_scale(p_light,p_scale);
+
+}
+void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& p_transform){
+
+ VSG::canvas->canvas_light_set_transform(p_light,p_transform);
+
+}
+void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){
+
+ VSG::canvas->canvas_light_set_texture(p_light,p_texture);
+
+}
+void VisualServerRaster::canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset){
+
+ VSG::canvas->canvas_light_set_texture_offset(p_light,p_offset);
+
+}
+void VisualServerRaster::canvas_light_set_color(RID p_light, const Color& p_color){
+
+ VSG::canvas->canvas_light_set_color(p_light,p_color);
+
+}
+void VisualServerRaster::canvas_light_set_height(RID p_light, float p_height){
+
+ VSG::canvas->canvas_light_set_height(p_light,p_height);
+
+}
+void VisualServerRaster::canvas_light_set_energy(RID p_light, float p_energy){
+
+ VSG::canvas->canvas_light_set_energy(p_light,p_energy);
+
+}
+void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){
+
+ VSG::canvas->canvas_light_set_z_range(p_light,p_min_z,p_max_z);
+
+}
+void VisualServerRaster::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer){
+
+ VSG::canvas->canvas_light_set_layer_range(p_light,p_min_layer,p_max_layer);
+
+}
+void VisualServerRaster::canvas_light_set_item_cull_mask(RID p_light, int p_mask){
+
+ VSG::canvas->canvas_light_set_item_cull_mask(p_light,p_mask);
+
+}
+void VisualServerRaster::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask){
+
+ VSG::canvas->canvas_light_set_item_shadow_cull_mask(p_light,p_mask);
+
+}
+
+void VisualServerRaster::canvas_light_set_mode(RID p_light, CanvasLightMode p_mode){
+
+ VSG::canvas->canvas_light_set_mode(p_light,p_mode);
+
+}
+
+
+void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) {
+
+ VSG::canvas->canvas_light_set_shadow_enabled(p_light,p_enabled);
+
+}
+void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size) {
+
+ VSG::canvas->canvas_light_set_shadow_buffer_size(p_light,p_size);
+
+}
+void VisualServerRaster::canvas_light_set_shadow_gradient_length(RID p_light, float p_length) {
+
+ VSG::canvas->canvas_light_set_shadow_gradient_length(p_light,p_length);
+
+}
+void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter){
+
+ VSG::canvas->canvas_light_set_shadow_filter(p_light,p_filter);
+
+}
+void VisualServerRaster::canvas_light_set_shadow_color(RID p_light, const Color& p_color){
+
+ VSG::canvas->canvas_light_set_shadow_color(p_light,p_color);
+
+}
+
+
+
+RID VisualServerRaster::canvas_light_occluder_create() {
+
+ return VSG::canvas->canvas_light_occluder_create();
+}
+
+void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas){
+
+ VSG::canvas->canvas_light_occluder_attach_to_canvas(p_occluder,p_canvas);
+
+}
+void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled) {
+
+ VSG::canvas->canvas_light_occluder_set_enabled(p_occluder,p_enabled);
+
+}
+void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon){
+
+ VSG::canvas->canvas_light_occluder_set_polygon(p_occluder,p_polygon);
+
+}
+void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform){
+
+ VSG::canvas->canvas_light_occluder_set_transform(p_occluder,p_xform);
+
+}
+void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask){
+
+ VSG::canvas->canvas_light_occluder_set_light_mask(p_occluder,p_mask);
+
+}
+
+RID VisualServerRaster::canvas_occluder_polygon_create() {
+
+ return VSG::canvas->canvas_occluder_polygon_create();
+}
+void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed){
+
+ VSG::canvas->canvas_occluder_polygon_set_shape(p_occluder_polygon,p_shape,p_closed);
+}
+void VisualServerRaster::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape){
+
+ VSG::canvas->canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape);
+
+}
+
+
+void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode){
+
+ VSG::canvas->canvas_occluder_polygon_set_cull_mode(p_occluder_polygon,p_mode);
+
+}
+
+
+/* CURSOR */
+void VisualServerRaster::cursor_set_rotation(float p_rotation, int p_cursor ){
+
+}
+void VisualServerRaster::cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor, const Rect2 &p_region){
+
+}
+void VisualServerRaster::cursor_set_visible(bool p_visible, int p_cursor ){
+
+}
+void VisualServerRaster::cursor_set_pos(const Point2& p_pos, int p_cursor ){
+
+}
+
+/* BLACK BARS */
+
+
+void VisualServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom){
+
+}
+void VisualServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom){
+
+}
+
+
+/* FREE */
+
+void VisualServerRaster::free( RID p_rid ){
+
+ if (VSG::storage->free(p_rid))
+ return;
+ if (VSG::canvas->free(p_rid))
+ return;
+ if (VSG::viewport->free(p_rid))
+ return;
+
+}
+
+/* EVENT QUEUING */
+
+void VisualServerRaster::draw(){
+
+ //if (changes)
+ // print_line("changes: "+itos(changes));
+
+// changes=0;
+ VSG::rasterizer->begin_frame();
+ VSG::viewport->draw_viewports();
+ //_draw_cursors_and_margins();
+ VSG::rasterizer->end_frame();
+ //draw_extra_frame=VS:rasterizer->needs_to_draw_next_frame();
+}
+void VisualServerRaster::sync(){
+
+}
+bool VisualServerRaster::has_changed() const{
+
+ return false;
+}
+void VisualServerRaster::init(){
+
+ VSG::rasterizer->initialize();
+
+}
+void VisualServerRaster::finish(){
+
+ if (test_cube.is_valid()) {
+ free(test_cube);
+ }
+
+ VSG::rasterizer->finalize();
+}
+
+/* STATUS INFORMATION */
+
+
+int VisualServerRaster::get_render_info(RenderInfo p_info){
+
+ return 0;
+}
+
+
+
+/* TESTING */
+
+
+
+void VisualServerRaster::set_boot_image(const Image& p_image, const Color& p_color,bool p_scale){
+
+}
+void VisualServerRaster::set_default_clear_color(const Color& p_color){
+
+}
+
+bool VisualServerRaster::has_feature(Features p_feature) const {
+
+ return false;
+}
+
+RID VisualServerRaster::get_test_cube() {
+ if (!test_cube.is_valid()) {
+ test_cube=_make_test_cube();
+ }
+ return test_cube;
+}
+
+VisualServerRaster::VisualServerRaster() {
+
+ VSG::canvas = memnew( VisualServerCanvas);
+ VSG::viewport = memnew( VisualServerViewport);
+ VSG::rasterizer = Rasterizer::create();
+ VSG::storage=VSG::rasterizer->get_storage();
+ VSG::canvas_render=VSG::rasterizer->get_canvas();
+ VSG::scene_render=VSG::rasterizer->get_scene();
+
+}
+
+VisualServerRaster::~VisualServerRaster() {
+
+ memdelete(VSG::canvas);
+ memdelete(VSG::viewport);
+ memdelete(VSG::rasterizer);
+}
+
+
+#if 0
+
BalloonAllocator<> *VisualServerRaster::OctreeAllocator::allocator=NULL;
#define VS_CHANGED\
@@ -1146,7 +2418,7 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
if (p_octree.size()==0) {
if (baked_light->data.octree_texture.is_valid())
rasterizer->free(baked_light->data.octree_texture);
- baked_light->data.octree_texture=RID();
+ baked_light->data.octree_texture;
baked_light->octree_aabb=AABB();
baked_light->octree_tex_size=Size2();
} else {
@@ -1203,7 +2475,7 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
if (tex_w!=baked_light->octree_tex_size.x || tex_h!=baked_light->octree_tex_size.y) {
rasterizer->free(baked_light->data.octree_texture);
- baked_light->data.octree_texture=RID();
+ baked_light->data.octree_texture;
baked_light->octree_tex_size.x=0;
baked_light->octree_tex_size.y=0;
}
@@ -1212,7 +2484,7 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
if (baked_light->data.light_texture.is_valid()) {
if (!has_light_tex || light_tex_w!=baked_light->light_tex_size.x || light_tex_h!=baked_light->light_tex_size.y) {
rasterizer->free(baked_light->data.light_texture);
- baked_light->data.light_texture=RID();
+ baked_light->data.light_texture;
baked_light->light_tex_size.x=0;
baked_light->light_tex_size.y=0;
}
@@ -1220,20 +2492,20 @@ void VisualServerRaster::baked_light_set_octree(RID p_baked_light,const DVector<
if (!baked_light->data.octree_texture.is_valid()) {
baked_light->data.octree_texture=rasterizer->texture_create();
- rasterizer->texture_allocate(baked_light->data.octree_texture,tex_w,tex_h,Image::FORMAT_RGBA,TEXTURE_FLAG_FILTER);
+ rasterizer->texture_allocate(baked_light->data.octree_texture,tex_w,tex_h,Image::FORMAT_RGBA8,TEXTURE_FLAG_FILTER);
baked_light->octree_tex_size.x=tex_w;
baked_light->octree_tex_size.y=tex_h;
}
if (!baked_light->data.light_texture.is_valid() && has_light_tex) {
baked_light->data.light_texture=rasterizer->texture_create();
- rasterizer->texture_allocate(baked_light->data.light_texture,light_tex_w,light_tex_h,Image::FORMAT_RGBA,TEXTURE_FLAG_FILTER);
+ rasterizer->texture_allocate(baked_light->data.light_texture,light_tex_w,light_tex_h,Image::FORMAT_RGBA8,TEXTURE_FLAG_FILTER);
baked_light->light_tex_size.x=light_tex_w;
baked_light->light_tex_size.y=light_tex_h;
}
- Image img(tex_w,tex_h,0,Image::FORMAT_RGBA,p_octree);
+ Image img(tex_w,tex_h,0,Image::FORMAT_RGBA8,p_octree);
rasterizer->texture_set_data(baked_light->data.octree_texture,img);
}
@@ -1276,7 +2548,7 @@ void VisualServerRaster::baked_light_set_light(RID p_baked_light,const DVector<u
print_line("w: "+itos(tex_w)+" h: "+itos(tex_h)+" lightsize: "+itos(p_light.size()));
- Image img(tex_w,tex_h,0,Image::FORMAT_RGBA,p_light);
+ Image img(tex_w,tex_h,0,Image::FORMAT_RGBA8,p_light);
rasterizer->texture_set_data(baked_light->data.light_texture,img);
@@ -1611,8 +2883,8 @@ void VisualServerRaster::viewport_set_as_render_target(RID p_viewport,bool p_ena
if (!p_enable) {
rasterizer->free(viewport->render_target);
- viewport->render_target=RID();
- viewport->render_target_texture=RID();
+ viewport->render_target;
+ viewport->render_target_texture;
if (viewport->update_list.in_list())
viewport_update_list.remove(&viewport->update_list);
@@ -1811,7 +3083,7 @@ void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera) {
// a camera
viewport->camera=p_camera;
} else {
- viewport->camera=RID();
+ viewport->camera;
}
}
@@ -1830,7 +3102,7 @@ void VisualServerRaster::viewport_set_scenario(RID p_viewport,RID p_scenario) {
// a camera
viewport->scenario=p_scenario;
} else {
- viewport->scenario=RID();
+ viewport->scenario;
}
}
@@ -2284,7 +3556,7 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) {
instance->base_type=INSTANCE_NONE;
- instance->base_rid=RID();
+ instance->base_rid;
if (p_base.is_valid()) {
@@ -3003,7 +4275,7 @@ void VisualServerRaster::instance_geometry_set_baked_light_sampler(RID p_instanc
if (instance->sampled_light) {
instance->sampled_light->baked_light_sampler_info->owned_instances.erase(instance);
- instance->data.sampled_light=RID();
+ instance->data.sampled_light;
}
if(p_baked_light_sampler.is_valid()) {
@@ -3016,7 +4288,7 @@ void VisualServerRaster::instance_geometry_set_baked_light_sampler(RID p_instanc
instance->sampled_light=NULL;
}
- instance->data.sampled_light=RID();
+ instance->data.sampled_light;
}
@@ -3432,7 +4704,7 @@ void VisualServerRaster::canvas_item_set_parent(RID p_item,RID p_parent) {
item_owner->child_items.erase(canvas_item);
}
- canvas_item->parent=RID();
+ canvas_item->parent;
}
@@ -4057,7 +5329,7 @@ void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas)
}
if (!canvas_owner.owns(p_canvas))
- p_canvas=RID();
+ p_canvas;
clight->canvas=p_canvas;
if (clight->canvas.is_valid()) {
@@ -4184,7 +5456,7 @@ void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_ena
clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size);
} else {
rasterizer->free(clight->shadow_buffer);
- clight->shadow_buffer=RID();
+ clight->shadow_buffer;
}
@@ -4246,7 +5518,7 @@ void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,R
}
if (!canvas_owner.owns(p_canvas))
- p_canvas=RID();
+ p_canvas;
occluder->canvas=p_canvas;
@@ -4279,12 +5551,12 @@ void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_
}
occluder->polygon=p_polygon;
- occluder->polygon_buffer=RID();
+ occluder->polygon_buffer;
if (occluder->polygon.is_valid()) {
CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon);
if (!occluder_poly)
- occluder->polygon=RID();
+ occluder->polygon;
ERR_FAIL_COND(!occluder_poly);
occluder_poly->owners.insert(occluder);
occluder->polygon_buffer=occluder_poly->occluder;
@@ -4558,7 +5830,7 @@ void VisualServerRaster::free( RID p_rid ) {
//detach skeletons
for (Set<Instance*>::Element *F=E->get().front();F;F=F->next()) {
- F->get()->data.skeleton=RID();
+ F->get()->data.skeleton;
}
skeleton_dependency_map.erase(E);
}
@@ -4688,17 +5960,17 @@ void VisualServerRaster::free( RID p_rid ) {
for (int i=0;i<canvas->child_items.size();i++) {
- canvas->child_items[i].item->parent=RID();
+ canvas->child_items[i].item->parent;
}
for (Set<Rasterizer::CanvasLight*>::Element *E=canvas->lights.front();E;E=E->next()) {
- E->get()->canvas=RID();
+ E->get()->canvas;
}
for (Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=canvas->occluders.front();E;E=E->next()) {
- E->get()->canvas=RID();
+ E->get()->canvas;
}
canvas_owner.free( p_rid );
@@ -4726,7 +5998,7 @@ void VisualServerRaster::free( RID p_rid ) {
for (int i=0;i<canvas_item->child_items.size();i++) {
- canvas_item->child_items[i]->parent=RID();
+ canvas_item->child_items[i]->parent;
}
if (canvas_item->material) {
@@ -4798,7 +6070,7 @@ void VisualServerRaster::free( RID p_rid ) {
while(occluder_poly->owners.size()) {
- occluder_poly->owners.front()->get()->polygon=RID();
+ occluder_poly->owners.front()->get()->polygon;
occluder_poly->owners.erase( occluder_poly->owners.front() );
}
@@ -6417,7 +7689,7 @@ void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instan
for(Set<Instance*>::Element *F=p_sampled_light->baked_light_sampler_info->owned_instances.front();F;F=F->next()) {
- F->get()->data.sampled_light=RID(); //do not use because nothing close
+ F->get()->data.sampled_light; //do not use because nothing close
}
}
@@ -7679,7 +8951,7 @@ void VisualServerRaster::init() {
Image img;
img.create(default_mouse_cursor_xpm);
- //img.convert(Image::FORMAT_RGB);
+ //img.convert(Image::FORMAT_RGB8);
default_cursor_texture = texture_create_from_image(img, 0);
aabb_random_points.resize( GLOBAL_DEF("render/aabb_random_points",16) );
@@ -7766,3 +9038,4 @@ VisualServerRaster::VisualServerRaster(Rasterizer *p_rasterizer) {
VisualServerRaster::~VisualServerRaster()
{
}
+#endif
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 496820f4a8..4cad03928b 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -40,6 +40,8 @@
*/
+
+
class VisualServerRaster : public VisualServer {
@@ -57,6 +59,12 @@ class VisualServerRaster : public VisualServer {
};
+ int changes;
+ bool draw_extra_frame;
+ RID test_cube;
+
+
+ #if 0
struct Room {
bool occlude_exterior;
@@ -374,97 +382,6 @@ class VisualServerRaster : public VisualServer {
mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner;
- struct CanvasItem : public Rasterizer::CanvasItem {
-
-
- RID parent; // canvas it belongs to
- List<CanvasItem*>::Element *E;
- RID viewport;
- int z;
- bool z_relative;
- bool sort_y;
- float opacity;
- float self_opacity;
- bool use_parent_material;
-
-
- Vector<CanvasItem*> child_items;
-
-
- CanvasItem() {
- E=NULL;
- z=0;
- opacity=1;
- self_opacity=1;
- sort_y=false;
- use_parent_material=false;
- z_relative=true;
- }
- };
-
-
- struct CanvasItemPtrSort {
-
- _FORCE_INLINE_ bool operator()(const CanvasItem* p_left,const CanvasItem* p_right) const {
-
- return p_left->xform.elements[2].y < p_right->xform.elements[2].y;
- }
- };
-
- struct CanvasLightOccluder;
-
- struct CanvasLightOccluderPolygon {
-
- bool active;
- Rect2 aabb;
- CanvasOccluderPolygonCullMode cull_mode;
- RID occluder;
- Set<Rasterizer::CanvasLightOccluderInstance*> owners;
-
- CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
- };
-
-
- RID_Owner<CanvasLightOccluderPolygon> canvas_light_occluder_polygon_owner;
-
- RID_Owner<Rasterizer::CanvasLightOccluderInstance> canvas_light_occluder_owner;
-
- struct CanvasLight;
-
- struct Canvas {
-
- Set<RID> viewports;
- struct ChildItem {
-
- Point2 mirror;
- CanvasItem *item;
- };
-
- Set<Rasterizer::CanvasLight*> lights;
- Set<Rasterizer::CanvasLightOccluderInstance*> occluders;
-
- Vector<ChildItem> child_items;
- Color modulate;
-
- int find_item(CanvasItem *p_item) {
- for(int i=0;i<child_items.size();i++) {
- if (child_items[i].item==p_item)
- return i;
- }
- return -1;
- }
- void erase_item(CanvasItem *p_item) {
- int idx=find_item(p_item);
- if (idx>=0)
- child_items.remove(idx);
- }
-
- Canvas() { modulate=Color(1,1,1,1); }
-
- };
-
-
- RID_Owner<Rasterizer::CanvasLight> canvas_light_owner;
struct Viewport {
@@ -658,8 +575,14 @@ class VisualServerRaster : public VisualServer {
Rasterizer *rasterizer;
+
+#endif
+
public:
+
+ /* TEXTURE API */
+
virtual RID texture_create();
virtual void texture_allocate(RID p_texture,int p_width, int p_height,Image::Format p_format,uint32_t p_flags=TEXTURE_FLAGS_DEFAULT);
virtual void texture_set_data(RID p_texture,const Image& p_image,CubeMapSide p_cube_side=CUBEMAP_LEFT);
@@ -670,29 +593,27 @@ public:
virtual uint32_t texture_get_width(RID p_texture) const;
virtual uint32_t texture_get_height(RID p_texture) const;
virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
- virtual bool texture_can_stream(RID p_texture) const;
- virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
+
+
virtual void texture_set_path(RID p_texture,const String& p_path);
virtual String texture_get_path(RID p_texture) const;
- virtual void texture_debug_usage(List<TextureInfo> *r_info);
-
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
+ virtual void texture_debug_usage(List<TextureInfo> *r_info);
+
/* SHADER API */
- virtual RID shader_create(ShaderMode p_mode=SHADER_MATERIAL);
+
+ virtual RID shader_create(ShaderMode p_mode=SHADER_SPATIAL);
virtual void shader_set_mode(RID p_shader,ShaderMode p_mode);
virtual ShaderMode shader_get_mode(RID p_shader) const;
- virtual void shader_set_code(RID p_shader, const String& p_vertex, const String& p_fragment,const String& p_light,int p_vertex_ofs=0,int p_fragment_ofs=0,int p_light_ofs=0);
- virtual String shader_get_vertex_code(RID p_shader) const;
- virtual String shader_get_fragment_code(RID p_shader) const;
- virtual String shader_get_light_code(RID p_shader) const;
-
+ virtual void shader_set_code(RID p_shader, const String& p_code);
+ virtual String shader_get_code(RID p_shader) const;
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
@@ -709,65 +630,29 @@ public:
virtual void material_set_param(RID p_material, const StringName& p_param, const Variant& p_value);
virtual Variant material_get_param(RID p_material, const StringName& p_param) const;
- virtual void material_set_flag(RID p_material, MaterialFlag p_flag,bool p_enabled);
- virtual bool material_get_flag(RID p_material,MaterialFlag p_flag) const;
-
- virtual void material_set_depth_draw_mode(RID p_material, MaterialDepthDrawMode p_mode);
- virtual MaterialDepthDrawMode material_get_depth_draw_mode(RID p_material) const;
-
- virtual void material_set_blend_mode(RID p_material,MaterialBlendMode p_mode);
- virtual MaterialBlendMode material_get_blend_mode(RID p_material) const;
-
- virtual void material_set_line_width(RID p_material,float p_line_width);
- virtual float material_get_line_width(RID p_material) const;
-
- /* FIXED MATERIAL */
-
-
- virtual RID fixed_material_create();
-
- virtual void fixed_material_set_flag(RID p_material, FixedMaterialFlags p_flag, bool p_enabled);
- virtual bool fixed_material_get_flag(RID p_material, FixedMaterialFlags p_flag) const;
+ /* MESH API */
- virtual void fixed_material_set_param(RID p_material, FixedMaterialParam p_parameter, const Variant& p_value);
- virtual Variant fixed_material_get_param(RID p_material,FixedMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_texture(RID p_material,FixedMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material,FixedMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_texcoord_mode(RID p_material,FixedMaterialParam p_parameter, FixedMaterialTexCoordMode p_mode);
- virtual FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,FixedMaterialParam p_parameter) const;
-
-
- virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
- virtual Transform fixed_material_get_uv_transform(RID p_material) const;
-
- virtual void fixed_material_set_light_shader(RID p_material,FixedMaterialLightShader p_shader);
- virtual FixedMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
-
- virtual void fixed_material_set_point_size(RID p_material,float p_size);
- virtual float fixed_material_get_point_size(RID p_material) const;
-
- /* SURFACE API */
virtual RID mesh_create();
+ virtual void mesh_add_surface(RID p_mesh,uint32_t p_format,PrimitiveType p_primitive,const DVector<uint8_t>& p_array,int p_vertex_count,const DVector<uint8_t>& p_index_array,int p_index_count,const Vector<DVector<uint8_t> >& p_blend_shapes=Vector<DVector<uint8_t> >());
+
virtual void mesh_set_morph_target_count(RID p_mesh,int p_amount);
virtual int mesh_get_morph_target_count(RID p_mesh) const;
+
virtual void mesh_set_morph_target_mode(RID p_mesh,MorphTargetMode p_mode);
virtual MorphTargetMode mesh_get_morph_target_mode(RID p_mesh) const;
- virtual void mesh_add_custom_surface(RID p_mesh,const Variant& p_dat); //this is used by each platform in a different way
-
- virtual void mesh_add_surface(RID p_mesh,PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes=Array(),bool p_alpha_sort=false);
- virtual Array mesh_get_surface_arrays(RID p_mesh,int p_surface) const;
- virtual Array mesh_get_surface_morph_arrays(RID p_mesh,int p_surface) const;
-
- virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material,bool p_owned=false);
+ virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material);
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const;
virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const;
+
+ virtual DVector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const;
+ virtual DVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const;
+
+
virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
virtual PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
@@ -781,199 +666,102 @@ public:
/* MULTIMESH API */
+
virtual RID multimesh_create();
- virtual void multimesh_set_instance_count(RID p_multimesh,int p_count);
+
+ virtual void multimesh_allocate(RID p_multimesh,int p_instances,MultimeshTransformFormat p_transform_format,MultimeshColorFormat p_color_format,bool p_gen_aabb=true);
virtual int multimesh_get_instance_count(RID p_multimesh) const;
virtual void multimesh_set_mesh(RID p_multimesh,RID p_mesh);
- virtual void multimesh_set_aabb(RID p_multimesh,const AABB& p_aabb);
+ virtual void multimesh_set_custom_aabb(RID p_multimesh,const AABB& p_aabb);
virtual void multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform& p_transform);
+ virtual void multimesh_instance_set_transform_2d(RID p_multimesh,int p_index,const Matrix32& p_transform);
virtual void multimesh_instance_set_color(RID p_multimesh,int p_index,const Color& p_color);
virtual RID multimesh_get_mesh(RID p_multimesh) const;
- virtual AABB multimesh_get_aabb(RID p_multimesh,const AABB& p_aabb) const;
+ virtual AABB multimesh_get_custom_aabb(RID p_multimesh,const AABB& p_aabb) const;
+
virtual Transform multimesh_instance_get_transform(RID p_multimesh,int p_index) const;
+ virtual Matrix32 multimesh_instance_get_transform_2d(RID p_multimesh,int p_index) const;
virtual Color multimesh_instance_get_color(RID p_multimesh,int p_index) const;
virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible);
virtual int multimesh_get_visible_instances(RID p_multimesh) const;
+
/* IMMEDIATE API */
virtual RID immediate_create();
virtual void immediate_begin(RID p_immediate,PrimitiveType p_rimitive,RID p_texture=RID());
virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex);
+ virtual void immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex);
virtual void immediate_normal(RID p_immediate,const Vector3& p_normal);
virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent);
virtual void immediate_color(RID p_immediate,const Color& p_color);
- virtual void immediate_uv(RID p_immediate, const Vector2& p_uv);
+ virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv);
virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv);
virtual void immediate_end(RID p_immediate);
virtual void immediate_clear(RID p_immediate);
virtual void immediate_set_material(RID p_immediate,RID p_material);
virtual RID immediate_get_material(RID p_immediate) const;
+ /* SKELETON API */
- /* PARTICLES API */
-
- virtual RID particles_create();
-
- virtual void particles_set_amount(RID p_particles, int p_amount);
- virtual int particles_get_amount(RID p_particles) const;
-
- virtual void particles_set_emitting(RID p_particles, bool p_emitting);
- virtual bool particles_is_emitting(RID p_particles) const;
-
- virtual void particles_set_visibility_aabb(RID p_particles, const AABB& p_visibility);
- virtual AABB particles_get_visibility_aabb(RID p_particles) const;
-
- virtual void particles_set_emission_half_extents(RID p_particles, const Vector3& p_half_extents);
- virtual Vector3 particles_get_emission_half_extents(RID p_particles) const;
-
- virtual void particles_set_emission_base_velocity(RID p_particles, const Vector3& p_base_velocity);
- virtual Vector3 particles_get_emission_base_velocity(RID p_particles) const;
-
- virtual void particles_set_emission_points(RID p_particles, const DVector<Vector3>& p_points);
- virtual DVector<Vector3> particles_get_emission_points(RID p_particles) const;
-
- virtual void particles_set_gravity_normal(RID p_particles, const Vector3& p_normal);
- virtual Vector3 particles_get_gravity_normal(RID p_particles) const;
-
- virtual void particles_set_variable(RID p_particles, ParticleVariable p_variable,float p_value);
- virtual float particles_get_variable(RID p_particles, ParticleVariable p_variable) const;
-
- virtual void particles_set_randomness(RID p_particles, ParticleVariable p_variable,float p_randomness);
- virtual float particles_get_randomness(RID p_particles, ParticleVariable p_variable) const;
-
- virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos);
- virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const;
-
- virtual void particles_set_color_phases(RID p_particles, int p_phases);
- virtual int particles_get_color_phases(RID p_particles) const;
-
- virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color& p_color);
- virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const;
-
- virtual void particles_set_attractors(RID p_particles, int p_attractors);
- virtual int particles_get_attractors(RID p_particles) const;
-
- virtual void particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3& p_pos);
- virtual Vector3 particles_get_attractor_pos(RID p_particles,int p_attractor) const;
-
- virtual void particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force);
- virtual float particles_get_attractor_strength(RID p_particles,int p_attractor) const;
-
- virtual void particles_set_material(RID p_particles, RID p_material,bool p_owned=false);
- virtual RID particles_get_material(RID p_particles) const;
-
- virtual void particles_set_height_from_velocity(RID p_particles, bool p_enable);
- virtual bool particles_has_height_from_velocity(RID p_particles) const;
-
- virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable);
- virtual bool particles_is_using_local_coordinates(RID p_particles) const;
-
+ virtual RID skeleton_create();
+ virtual void skeleton_allocate(RID p_skeleton,int p_bones,bool p_2d_skeleton=false);
+ virtual int skeleton_get_bone_count(RID p_skeleton) const;
+ virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform);
+ virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone);
+ virtual void skeleton_bone_set_transform_2d(RID p_skeleton,int p_bone, const Matrix32& p_transform);
+ virtual Matrix32 skeleton_bone_get_transform_2d(RID p_skeleton,int p_bone);
/* Light API */
virtual RID light_create(LightType p_type);
- virtual LightType light_get_type(RID p_light) const;
-
- virtual void light_set_color(RID p_light,LightColor p_type, const Color& p_color);
- virtual Color light_get_color(RID p_light,LightColor p_type) const;
-
+ virtual void light_set_color(RID p_light,const Color& p_color);
+ virtual void light_set_param(RID p_light,LightParam p_param,float p_value);
virtual void light_set_shadow(RID p_light,bool p_enabled);
- virtual bool light_has_shadow(RID p_light) const;
-
- virtual void light_set_volumetric(RID p_light,bool p_enabled);
- virtual bool light_is_volumetric(RID p_light) const;
-
virtual void light_set_projector(RID p_light,RID p_texture);
- virtual RID light_get_projector(RID p_light) const;
-
- virtual void light_set_param(RID p_light, LightParam p_var, float p_value);
- virtual float light_get_param(RID p_light, LightParam p_var) const;
+ virtual void light_set_attenuation_texure(RID p_light,RID p_texture);
+ virtual void light_set_negative(RID p_light,bool p_enable);
+ virtual void light_set_cull_mask(RID p_light,uint32_t p_mask);
+ virtual void light_set_shader(RID p_light,RID p_shader);
- virtual void light_set_operator(RID p_light,LightOp p_op);
- virtual LightOp light_get_operator(RID p_light) const;
-
- virtual void light_omni_set_shadow_mode(RID p_light,LightOmniShadowMode p_mode);
- virtual LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) const;
virtual void light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode);
- virtual LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) const;
- virtual void light_directional_set_shadow_param(RID p_light,LightDirectionalShadowParam p_param, float p_value);
- virtual float light_directional_get_shadow_param(RID p_light,LightDirectionalShadowParam p_param) const;
+ /* PROBE API */
- /* SKELETON API */
+ virtual RID reflection_probe_create();
+
+ virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity);
+ virtual void reflection_probe_set_clip(RID p_probe, float p_near, float p_far);
+ virtual void reflection_probe_set_min_blend_distance(RID p_probe, float p_distance);
+ virtual void reflection_probe_set_extents(RID p_probe, const Vector3& p_extents);
+ virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3& p_offset);
+ virtual void reflection_probe_set_enable_parallax_correction(RID p_probe, bool p_enable);
+ virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution);
+ virtual void reflection_probe_set_hide_skybox(RID p_probe, bool p_hide);
+ virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers);
- virtual RID skeleton_create();
- virtual void skeleton_resize(RID p_skeleton,int p_bones);
- virtual int skeleton_get_bone_count(RID p_skeleton) const;
- virtual void skeleton_bone_set_transform(RID p_skeleton,int p_bone, const Transform& p_transform);
- virtual Transform skeleton_bone_get_transform(RID p_skeleton,int p_bone);
/* ROOM API */
virtual RID room_create();
- virtual void room_set_bounds(RID p_room, const BSP_Tree& p_bounds);
- virtual BSP_Tree room_get_bounds(RID p_room) const;
+ virtual void room_add_bounds(RID p_room, const DVector<Vector2>& p_convex_polygon,float p_height,const Transform& p_transform);
+ virtual void room_clear_bounds();
/* PORTAL API */
+ // portals are only (x/y) points, forming a convex shape, which its clockwise
+ // order points outside. (z is 0);
+
virtual RID portal_create();
virtual void portal_set_shape(RID p_portal, const Vector<Point2>& p_shape);
- virtual Vector<Point2> portal_get_shape(RID p_portal) const;
virtual void portal_set_enabled(RID p_portal, bool p_enabled);
- virtual bool portal_is_enabled(RID p_portal) const;
virtual void portal_set_disable_distance(RID p_portal, float p_distance);
- virtual float portal_get_disable_distance(RID p_portal) const;
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color);
- virtual Color portal_get_disabled_color(RID p_portal) const;
- virtual void portal_set_connect_range(RID p_portal, float p_range);
- virtual float portal_get_connect_range(RID p_portal) const;
-
- /* BAKED LIGHT */
-
- virtual RID baked_light_create();
-
- virtual void baked_light_set_mode(RID p_baked_light,BakedLightMode p_mode);
- virtual BakedLightMode baked_light_get_mode(RID p_baked_light) const;
-
- virtual void baked_light_set_octree(RID p_baked_light,const DVector<uint8_t> p_octree);
- virtual DVector<uint8_t> baked_light_get_octree(RID p_baked_light) const;
-
- virtual void baked_light_set_light(RID p_baked_light,const DVector<uint8_t> p_light);
- virtual DVector<uint8_t> baked_light_get_light(RID p_baked_light) const;
-
- virtual void baked_light_set_sampler_octree(RID p_baked_light,const DVector<int> &p_sampler);
- virtual DVector<int> baked_light_get_sampler_octree(RID p_baked_light) const;
-
- virtual void baked_light_set_lightmap_multiplier(RID p_baked_light,float p_multiplier);
- virtual float baked_light_get_lightmap_multiplier(RID p_baked_light) const;
-
- virtual void baked_light_add_lightmap(RID p_baked_light,const RID p_texture,int p_id);
- virtual void baked_light_clear_lightmaps(RID p_baked_light);
-
- virtual void baked_light_set_realtime_color_enabled(RID p_baked_light, const bool p_enabled);
- virtual bool baked_light_get_realtime_color_enabled(RID p_baked_light) const;
-
- virtual void baked_light_set_realtime_color(RID p_baked_light, const Color& p_color);
- virtual Color baked_light_get_realtime_color(RID p_baked_light) const;
-
- virtual void baked_light_set_realtime_energy(RID p_baked_light, const float p_energy);
- virtual float baked_light_get_realtime_energy(RID p_baked_light) const;
-
- /* BAKED LIGHT SAMPLER */
-
- virtual RID baked_light_sampler_create();
-
- virtual void baked_light_sampler_set_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param,float p_value);
- virtual float baked_light_sampler_get_param(RID p_baked_light_sampler,BakedLightSamplerParam p_param) const;
-
- virtual void baked_light_sampler_set_resolution(RID p_baked_light_sampler,int p_resolution);
- virtual int baked_light_sampler_get_resolution(RID p_baked_light_sampler) const;
/* CAMERA API */
@@ -981,58 +769,44 @@ public:
virtual void camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far);
virtual void camera_set_orthogonal(RID p_camera,float p_size, float p_z_near, float p_z_far);
virtual void camera_set_transform(RID p_camera,const Transform& p_transform);
-
- virtual void camera_set_visible_layers(RID p_camera,uint32_t p_layers);
- virtual uint32_t camera_get_visible_layers(RID p_camera) const;
-
+ virtual void camera_set_cull_mask(RID p_camera,uint32_t p_layers);
virtual void camera_set_environment(RID p_camera,RID p_env);
- virtual RID camera_get_environment(RID p_camera) const;
-
virtual void camera_set_use_vertical_aspect(RID p_camera,bool p_enable);
- virtual bool camera_is_using_vertical_aspect(RID p_camera,bool p_enable) const;
- /* VIEWPORT API */
+
+ /* VIEWPORT TARGET API */
virtual RID viewport_create();
- virtual void viewport_attach_to_screen(RID p_viewport,int p_screen=0);
- virtual void viewport_detach(RID p_viewport);
+ virtual void viewport_set_size(RID p_viewport,int p_width,int p_height);
+
+ virtual void viewport_set_active(RID p_viewport,bool p_active);
- virtual void viewport_set_as_render_target(RID p_viewport,bool p_enable);
- virtual void viewport_set_render_target_update_mode(RID p_viewport,RenderTargetUpdateMode p_mode);
- virtual RenderTargetUpdateMode viewport_get_render_target_update_mode(RID p_viewport) const;
- 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_set_clear_mode(RID p_viewport,ViewportClearMode p_clear_mode);
+ virtual void viewport_attach_to_screen(RID p_viewport,const Rect2& p_rect=Rect2(),int p_screen=0);
+ virtual void viewport_detach(RID p_viewport);
+
+ virtual void viewport_set_update_mode(RID p_viewport,ViewportUpdateMode p_mode);
+ virtual void viewport_set_vflip(RID p_viewport,bool p_enable);
- virtual void viewport_queue_screen_capture(RID p_viewport);
- virtual Image viewport_get_screen_capture(RID p_viewport) const;
- virtual void viewport_set_rect(RID p_viewport,const ViewportRect& p_rect);
- virtual ViewportRect viewport_get_rect(RID p_viewport) const;
+ virtual RID viewport_get_texture(RID p_viewport) const;
+ virtual Image viewport_capture(RID p_viewport) const;
virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide);
virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide);
virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable);
+
virtual void viewport_attach_camera(RID p_viewport,RID p_camera);
virtual void viewport_set_scenario(RID p_viewport,RID p_scenario);
-
- virtual RID viewport_get_attached_camera(RID p_viewport) const;
- virtual RID viewport_get_scenario(RID p_viewport) const;
virtual void viewport_attach_canvas(RID p_viewport,RID p_canvas);
virtual void viewport_remove_canvas(RID p_viewport,RID p_canvas);
virtual void viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset);
- virtual Matrix32 viewport_get_canvas_transform(RID p_viewport,RID p_canvas) const;
+ virtual void viewport_set_transparent_background(RID p_viewport,bool p_enabled);
+
virtual void viewport_set_global_canvas_transform(RID p_viewport,const Matrix32& p_transform);
- virtual Matrix32 viewport_get_global_canvas_transform(RID p_viewport) const;
virtual void viewport_set_canvas_layer(RID p_viewport,RID p_canvas,int p_layer);
- virtual void viewport_set_transparent_background(RID p_viewport,bool p_enabled);
- virtual bool viewport_has_transparent_background(RID p_viewport) const;
/* ENVIRONMENT API */
@@ -1040,21 +814,24 @@ public:
virtual RID environment_create();
virtual void environment_set_background(RID p_env,EnvironmentBG p_bg);
- virtual EnvironmentBG environment_get_background(RID p_env) const;
+ virtual void environment_set_skybox(RID p_env,RID p_skybox,float p_energy=1.0);
+ virtual void environment_set_bg_color(RID p_env,const Color& p_color);
+ virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer);
+ virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0);
- virtual void environment_set_background_param(RID p_env,EnvironmentBGParam p_param, const Variant& p_value);
- virtual Variant environment_get_background_param(RID p_env,EnvironmentBGParam p_param) const;
+ virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,EnvironmentGlowBlendMode p_blend_mode);
+ virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture);
- virtual void environment_set_enable_fx(RID p_env,EnvironmentFx p_effect,bool p_enabled);
- virtual bool environment_is_fx_enabled(RID p_env,EnvironmentFx p_effect) const;
-
-
- virtual void environment_fx_set_param(RID p_env,EnvironmentFxParam p_effect,const Variant& p_param);
- virtual Variant environment_fx_get_param(RID p_env,EnvironmentFxParam p_effect) const;
+ virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,EnvironmentToneMapper p_tone_mapper);
+ virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness);
+ virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast);
+ virtual void environment_set_saturation(RID p_env,bool p_enable,float p_saturation);
+ virtual void environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp);
/* SCENARIO API */
+
virtual RID scenario_create();
virtual void scenario_set_debug(RID p_scenario,ScenarioDebugMode p_debug_mode);
@@ -1063,137 +840,91 @@ public:
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
-
/* INSTANCING API */
+ // from can be mesh, light, area and portal so far.
+ virtual RID instance_create(); // from can be mesh, light, poly, area and portal so far.
- virtual RID instance_create();
-
- virtual void instance_set_base(RID p_instance, RID p_base);
- virtual RID instance_get_base(RID p_instance) const;
-
- virtual void instance_set_scenario(RID p_instance, RID p_scenario);
- virtual RID instance_get_scenario(RID p_instance) const;
-
+ virtual void instance_set_base(RID p_instance, RID p_base); // from can be mesh, light, poly, area and portal so far.
+ virtual void instance_set_scenario(RID p_instance, RID p_scenario); // from can be mesh, light, poly, area and portal so far.
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask);
- virtual uint32_t instance_get_layer_mask(RID p_instance) const;
-
- virtual AABB instance_get_base_aabb(RID p_instance) const;
-
- virtual void instance_attach_object_instance_ID(RID p_instance,uint32_t p_ID);
- virtual uint32_t instance_get_object_instance_ID(RID p_instance) const;
-
- virtual void instance_attach_skeleton(RID p_instance,RID p_skeleton);
- virtual RID instance_get_skeleton(RID p_instance) const;
-
+ virtual void instance_set_transform(RID p_instance, const Transform& p_transform);
+ virtual void instance_attach_object_instance_ID(RID p_instance,ObjectID p_ID);
virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight);
- virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const;
-
virtual void instance_set_surface_material(RID p_instance,int p_surface, RID p_material);
-
- virtual void instance_set_transform(RID p_instance, const Transform& p_transform);
- virtual Transform instance_get_transform(RID p_instance) const;
-
+ virtual void instance_attach_skeleton(RID p_instance,RID p_skeleton);
virtual void instance_set_exterior( RID p_instance, bool p_enabled );
- virtual bool instance_is_exterior( RID p_instance) const;
-
virtual void instance_set_room( RID p_instance, RID p_room );
- virtual RID instance_get_room( RID p_instance ) const ;
virtual void instance_set_extra_visibility_margin( RID p_instance, real_t p_margin );
- virtual real_t instance_get_extra_visibility_margin( RID p_instance ) const;
- virtual Vector<RID> instances_cull_aabb(const AABB& p_aabb, RID p_scenario=RID()) const;
- virtual Vector<RID> instances_cull_ray(const Vector3& p_from, const Vector3& p_to, RID p_scenario=RID()) const;
- virtual Vector<RID> instances_cull_convex(const Vector<Plane>& p_convex, RID p_scenario=RID()) const;
+ // don't use these in a game!
+ virtual Vector<ObjectID> instances_cull_aabb(const AABB& p_aabb, RID p_scenario=RID()) const;
+ virtual Vector<ObjectID> instances_cull_ray(const Vector3& p_from, const Vector3& p_to, RID p_scenario=RID()) const;
+ virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane>& p_convex, RID p_scenario=RID()) const;
- virtual void instance_geometry_set_flag(RID p_instance,InstanceFlags p_flags,bool p_enabled);
- virtual bool instance_geometry_get_flag(RID p_instance,InstanceFlags p_flags) const;
-
- virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting);
- virtual VS::ShadowCastingSetting instance_geometry_get_cast_shadows_setting(RID p_instance) const;
+ virtual void instance_geometry_set_flag(RID p_instance,InstanceFlags p_flags,bool p_enabled);
+ virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting);
virtual void instance_geometry_set_material_override(RID p_instance, RID p_material);
- virtual RID instance_geometry_get_material_override(RID p_instance) const;
-
- virtual void instance_geometry_set_draw_range(RID p_instance,float p_min,float p_max);
- virtual float instance_geometry_get_draw_range_max(RID p_instance) const;
- virtual float instance_geometry_get_draw_range_min(RID p_instance) const;
- virtual void instance_geometry_set_baked_light(RID p_instance,RID p_baked_light);
- virtual RID instance_geometry_get_baked_light(RID p_instance) const;
- virtual void instance_geometry_set_baked_light_sampler(RID p_instance,RID p_baked_light_sampler);
- virtual RID instance_geometry_get_baked_light_sampler(RID p_instance) const;
-
- virtual void instance_geometry_set_baked_light_texture_index(RID p_instance,int p_tex_id);
- virtual int instance_geometry_get_baked_light_texture_index(RID p_instance) const;
-
- virtual void instance_light_set_enabled(RID p_instance,bool p_enabled);
- virtual bool instance_light_is_enabled(RID p_instance) const;
+ virtual void instance_geometry_set_draw_range(RID p_instance,float p_min,float p_max,float p_min_margin,float p_max_margin);
+ virtual void instance_geometry_set_as_instance_lod(RID p_instance,RID p_as_lod_of_instance);
/* CANVAS (2D) */
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();
-
- virtual void canvas_item_set_parent(RID p_item,RID p_parent_item);
- virtual RID canvas_item_get_parent(RID p_canvas_item) const;
+ virtual void canvas_item_set_parent(RID p_item,RID p_parent);
virtual void canvas_item_set_visible(RID p_item,bool p_visible);
- virtual bool canvas_item_is_visible(RID p_item) const;
+ virtual void canvas_item_set_light_mask(RID p_item,int p_mask);
- 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);
virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform);
virtual void canvas_item_set_clip(RID p_item, bool p_clip);
virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable);
virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2());
- virtual void canvas_item_set_opacity(RID p_item, float p_opacity);
- virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const;
- virtual void canvas_item_set_on_top(RID p_item, bool p_on_top);
- virtual bool canvas_item_is_on_top(RID p_item) const;
+ virtual void canvas_item_set_modulate(RID p_item, const Color& p_color);
+ virtual void canvas_item_set_self_modulate(RID p_item, const Color& p_color);
- virtual void canvas_item_set_self_opacity(RID p_item, float p_self_opacity);
- virtual float canvas_item_get_self_opacity(RID p_item, float p_self_opacity) const;
+ virtual void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable);
- virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport);
- 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, bool p_antialiased=false);
+ 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,bool p_antialiased=false);
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),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, const Rect2& p_source, 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_nine_patch(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright,NinePatchAxisMode p_x_axis_mode=NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode=NINE_PATCH_STRETCH,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());
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1);
- virtual void canvas_item_add_triangle_array_ptr(RID p_item, int p_count, const int* p_indices, const Point2* p_points, const Color* p_colors,const Point2* p_uvs=NULL, RID p_texture=RID());
+ virtual void canvas_item_add_mesh(RID p_item, const RID& p_mesh,RID p_skeleton=RID());
+ virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh,RID p_skeleton=RID());
virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform);
- 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_set_z_as_relative_to_parent(RID p_item, bool p_enable);
virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect);
+ virtual void canvas_item_clear(RID p_item);
+ virtual void canvas_item_set_draw_index(RID p_item,int p_index);
+
virtual void canvas_item_set_material(RID p_item, RID p_material);
+
virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable);
virtual RID canvas_light_create();
virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas);
virtual void canvas_light_set_enabled(RID p_light, bool p_enabled);
- virtual void canvas_light_set_transform(RID p_light, const Matrix32& p_transform);
virtual void canvas_light_set_scale(RID p_light, float p_scale);
+ virtual void canvas_light_set_transform(RID p_light, const Matrix32& p_transform);
virtual void canvas_light_set_texture(RID p_light, RID p_texture);
virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset);
virtual void canvas_light_set_color(RID p_light, const Color& p_color);
@@ -1201,13 +932,16 @@ public:
virtual void canvas_light_set_energy(RID p_light, float p_energy);
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);
- virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask);
+ virtual void canvas_light_set_item_cull_mask(RID p_light, int p_mask);
+ virtual void canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask);
virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode);
+
+
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_esm_multiplier(RID p_light, float p_multiplier);
+ virtual void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
+ virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter);
virtual void canvas_light_set_shadow_color(RID p_light, const Color& p_color);
@@ -1219,72 +953,56 @@ public:
virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform);
virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask);
-
virtual RID canvas_occluder_polygon_create();
- virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_close);
+ virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed);
virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape);
- virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode);
-
- virtual void canvas_item_clear(RID p_item);
- virtual void canvas_item_raise(RID p_item);
-
- /* CANVAS ITEM MATERIAL */
-
- virtual RID canvas_item_material_create();
- virtual void canvas_item_material_set_shader(RID p_material, RID p_shader);
- virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value);
- virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;
- virtual void canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode);
-
+ virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode);
/* CURSOR */
virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians
- virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0, const Rect2 &p_region=Rect2());
+ virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor=0, const Rect2 &p_region=Rect2());
virtual void cursor_set_visible(bool p_visible, int p_cursor = 0);
virtual void cursor_set_pos(const Point2& p_pos, int p_cursor = 0);
/* BLACK BARS */
+
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom);
virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom);
- /* FREE */
-
- virtual void free( RID p_rid );
- /* CUSTOM SHADE MODEL */
+ /* FREE */
- virtual void custom_shade_model_set_shader(int p_model, RID p_shader);
- virtual RID custom_shade_model_get_shader(int p_model) const;
- virtual void custom_shade_model_set_name(int p_model, const String& p_name);
- virtual String custom_shade_model_get_name(int p_model) const;
- virtual void custom_shade_model_set_param_info(int p_model, const List<PropertyInfo>& p_info);
- virtual void custom_shade_model_get_param_info(int p_model, List<PropertyInfo>* p_info) const;
+ virtual void free( RID p_rid ); ///< free RIDs associated with the visual server
/* EVENT QUEUING */
virtual void draw();
virtual void sync();
-
+ virtual bool has_changed() const;
virtual void init();
virtual void finish();
- virtual bool has_changed() const;
+ /* STATUS INFORMATION */
- /* RENDER INFO */
virtual int get_render_info(RenderInfo p_info);
- virtual bool has_feature(Features p_feature) const;
- RID get_test_cube();
+ virtual RID get_test_cube();
+
+
+ /* TESTING */
- virtual void set_boot_image(const Image& p_image, const Color& p_color, bool p_scale);
+ virtual void set_boot_image(const Image& p_image, const Color& p_color,bool p_scale);
virtual void set_default_clear_color(const Color& p_color);
- VisualServerRaster(Rasterizer *p_rasterizer);
+ virtual bool has_feature(Features p_feature) const;
+
+
+ VisualServerRaster();
~VisualServerRaster();
};
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
new file mode 100644
index 0000000000..b30a57a5b8
--- /dev/null
+++ b/servers/visual/visual_server_viewport.cpp
@@ -0,0 +1,489 @@
+#include "visual_server_viewport.h"
+#include "visual_server_global.h"
+#include "visual_server_canvas.h"
+
+void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
+
+ /* Camera should always be BEFORE any other 3D */
+#if 0
+ bool scenario_draw_canvas_bg=false;
+ int scenario_canvas_max_layer=0;
+
+ if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) {
+
+ Scenario *scenario=scenario_owner.get(p_viewport->scenario);
+ if (scenario->environment.is_valid()) {
+ if (rasterizer->is_environment(scenario->environment)) {
+ scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS;
+ scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER);
+ }
+ }
+ }
+
+ bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario);
+
+
+ if (scenario_draw_canvas_bg) {
+
+ rasterizer->begin_canvas_bg();
+ }
+
+ if (!scenario_draw_canvas_bg && can_draw_3d) {
+
+ _draw_viewport_camera(p_viewport,false);
+
+ } else if (true /*|| !p_viewport->canvas_list.empty()*/){
+
+ //clear the viewport black because of no camera? i seriously should..
+ if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) {
+ if (p_viewport->transparent_bg) {
+ rasterizer->clear_viewport(Color(0,0,0,0));
+ }
+ else {
+ Color cc=clear_color;
+ if (scenario_draw_canvas_bg)
+ cc.a=0;
+ rasterizer->clear_viewport(cc);
+ }
+ p_viewport->render_target_clear=false;
+ }
+ }
+#endif
+
+ VSG::rasterizer->clear_render_target(Color(0.5,0.5,0.5,1.0));
+
+ if (!p_viewport->hide_canvas) {
+ int i=0;
+
+ Map<Viewport::CanvasKey,Viewport::CanvasData*> canvas_map;
+
+ Rect2 clip_rect(0,0,p_viewport->size.x,p_viewport->size.y);
+ RasterizerCanvas::Light *lights=NULL;
+ RasterizerCanvas::Light *lights_with_shadow=NULL;
+ RasterizerCanvas::Light *lights_with_mask=NULL;
+ Rect2 shadow_rect;
+
+ int light_count=0;
+
+ 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;
+
+ VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas*>(E->get().canvas);
+
+ //find lights in canvas
+
+
+ for(Set<RasterizerCanvas::Light*>::Element *F=canvas->lights.front();F;F=F->next()) {
+
+
+ RasterizerCanvas::Light* cl=F->get();
+ if (cl->enabled && cl->texture.is_valid()) {
+ //not super efficient..
+ Size2 tsize(VSG::storage->texture_get_width(cl->texture),VSG::storage->texture_get_height(cl->texture));
+ tsize*=cl->scale;
+
+ 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];
+ if (cl->shadow_buffer.is_valid()) {
+
+ cl->shadows_next_ptr=lights_with_shadow;
+ if (lights_with_shadow==NULL) {
+ shadow_rect = cl->xform_cache.xform(cl->rect_cache);
+ } else {
+ shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) );
+ }
+ lights_with_shadow=cl;
+ cl->radius_cache=cl->rect_cache.size.length();
+
+ }
+ if (cl->mode==VS::CANVAS_LIGHT_MODE_MASK) {
+ cl->mask_next_ptr=lights_with_mask;
+ lights_with_mask=cl;
+ }
+
+ light_count++;
+ }
+
+ VSG::canvas_render->light_internal_update(cl->light_internal,cl);
+
+ }
+ }
+
+ //print_line("lights: "+itos(light_count));
+ canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get();
+
+ }
+
+ if (lights_with_shadow) {
+ //update shadows if any
+
+ RasterizerCanvas::LightOccluderInstance * occluders=NULL;
+
+ //make list of occluders
+ for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) {
+
+ VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas*>(E->get().canvas);
+ Matrix32 xf = p_viewport->global_transform * E->get().transform;
+
+
+ for(Set<RasterizerCanvas::LightOccluderInstance*>::Element *F=canvas->occluders.front();F;F=F->next()) {
+
+ if (!F->get()->enabled)
+ continue;
+ F->get()->xform_cache = xf * F->get()->xform;
+ if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) {
+
+ F->get()->next=occluders;
+ occluders=F->get();
+
+ }
+ }
+ }
+ //update the light shadowmaps with them
+ RasterizerCanvas::Light *light=lights_with_shadow;
+ while(light) {
+
+ VSG::canvas_render->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache);
+ light=light->shadows_next_ptr;
+ }
+
+ VSG::rasterizer->restore_render_target();
+ // VSG::canvas_render->reset_canvas();
+ }
+
+
+
+#if 0
+ if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) {
+
+ _draw_viewport_camera(p_viewport,!can_draw_3d);
+ scenario_draw_canvas_bg=false;
+
+ }
+#endif
+ for (Map<Viewport::CanvasKey,Viewport::CanvasData*>::Element *E=canvas_map.front();E;E=E->next()) {
+
+ VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas*>(E->get()->canvas);
+
+ // 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;
+
+ RasterizerCanvas::Light *canvas_lights=NULL;
+
+ RasterizerCanvas::Light *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;
+ }
+
+ VSG::canvas->render_canvas( canvas,xform,canvas_lights,lights_with_mask,clip_rect );
+ i++;
+#if 0
+ if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) {
+ _draw_viewport_camera(p_viewport,!can_draw_3d);
+ scenario_draw_canvas_bg=false;
+ }
+#endif
+
+
+ }
+#if 0
+ if (scenario_draw_canvas_bg) {
+ _draw_viewport_camera(p_viewport,!can_draw_3d);
+ scenario_draw_canvas_bg=false;
+ }
+#endif
+
+ //VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
+ }
+
+
+
+}
+
+void VisualServerViewport::draw_viewports() {
+
+ //sort viewports
+
+
+ //draw viewports
+
+
+ for(int i=0;i<active_viewports.size();i++) {
+
+ Viewport *vp = active_viewports[i];
+
+ if (vp->update_mode==VS::VIEWPORT_UPDATE_DISABLED)
+ continue;
+
+ ERR_CONTINUE( !vp->render_target.is_valid() );
+
+ VSG::rasterizer->set_current_render_target(vp->render_target);
+ _draw_viewport(vp);
+
+ if (vp->viewport_to_screen_rect!=Rect2()) {
+ //copy to screen if set as such
+ VSG::rasterizer->set_current_render_target(RID());
+ VSG::rasterizer->blit_render_target_to_screen(vp->render_target,vp->viewport_to_screen_rect,vp->viewport_to_screen);
+ }
+
+ if (vp->update_mode==VS::VIEWPORT_UPDATE_ONCE) {
+ vp->update_mode=VS::VIEWPORT_UPDATE_DISABLED;
+ }
+ }
+}
+
+
+RID VisualServerViewport::viewport_create() {
+
+ Viewport * viewport = memnew( Viewport );
+
+ RID rid = viewport_owner.make_rid(viewport);
+
+ viewport->self=rid;
+ viewport->hide_scenario=false;
+ viewport->hide_canvas=false;
+ viewport->render_target=VSG::storage->render_target_create();
+
+ return rid;
+
+}
+
+void VisualServerViewport::viewport_set_size(RID p_viewport,int p_width,int p_height){
+
+ ERR_FAIL_COND(p_width<0 && p_height<0);
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+
+
+ viewport->size=Size2(p_width,p_height);
+ VSG::storage->render_target_set_size(viewport->render_target,p_width,p_height);
+
+
+}
+
+void VisualServerViewport::viewport_set_active(RID p_viewport,bool p_active) {
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ if (p_active) {
+ ERR_FAIL_COND(active_viewports.find(viewport)!=-1);//already active
+ active_viewports.push_back(viewport);
+ } else {
+ active_viewports.erase(viewport);
+ }
+
+
+}
+
+void VisualServerViewport::viewport_set_clear_mode(RID p_viewport,VS::ViewportClearMode p_clear_mode) {
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->clear_mode=p_clear_mode;
+
+}
+
+
+void VisualServerViewport::viewport_attach_to_screen(RID p_viewport,const Rect2& p_rect,int p_screen){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->viewport_to_screen_rect=p_rect;
+ viewport->viewport_to_screen=p_screen;
+}
+void VisualServerViewport::viewport_detach(RID p_viewport){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->viewport_to_screen_rect=Rect2();
+ viewport->viewport_to_screen=0;
+
+}
+
+void VisualServerViewport::viewport_set_update_mode(RID p_viewport,VS::ViewportUpdateMode p_mode){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->update_mode=p_mode;
+
+}
+void VisualServerViewport::viewport_set_vflip(RID p_viewport,bool p_enable){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VSG::storage->render_target_set_flag(viewport->render_target,RasterizerStorage::RENDER_TARGET_VFLIP,p_enable);
+
+}
+
+RID VisualServerViewport::viewport_get_texture(RID p_viewport) const{
+
+ const Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND_V(!viewport,RID());
+
+ return VSG::storage->render_target_get_texture(viewport->render_target);
+
+}
+Image VisualServerViewport::viewport_capture(RID p_viewport) const{
+
+ const Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND_V(!viewport,Image());
+ return VSG::storage->render_target_get_image(viewport->render_target);
+
+}
+
+void VisualServerViewport::viewport_set_hide_scenario(RID p_viewport,bool p_hide){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->hide_scenario=p_hide;
+}
+void VisualServerViewport::viewport_set_hide_canvas(RID p_viewport,bool p_hide){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->hide_canvas=p_hide;
+}
+void VisualServerViewport::viewport_set_disable_environment(RID p_viewport,bool p_disable){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+
+ viewport->disable_environment=p_disable;
+}
+
+void VisualServerViewport::viewport_attach_camera(RID p_viewport,RID p_camera){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->camera=p_camera;
+}
+void VisualServerViewport::viewport_set_scenario(RID p_viewport,RID p_scenario){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->scenario=p_scenario;
+}
+void VisualServerViewport::viewport_attach_canvas(RID p_viewport,RID p_canvas){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ ERR_FAIL_COND(viewport->canvas_map.has(p_canvas));
+ VisualServerCanvas::Canvas *canvas = VSG::canvas->canvas_owner.getornull(p_canvas);
+ ERR_FAIL_COND(!canvas);
+
+ canvas->viewports.insert(p_viewport);
+ viewport->canvas_map[p_canvas]=Viewport::CanvasData();
+ viewport->canvas_map[p_canvas].layer=0;
+ viewport->canvas_map[p_canvas].canvas=canvas;
+
+}
+
+void VisualServerViewport::viewport_remove_canvas(RID p_viewport,RID p_canvas){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VisualServerCanvas::Canvas *canvas = VSG::canvas->canvas_owner.getornull(p_canvas);
+ ERR_FAIL_COND(!canvas);
+
+ viewport->canvas_map.erase(p_canvas);
+ canvas->viewports.erase(p_viewport);
+
+}
+void VisualServerViewport::viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
+ viewport->canvas_map[p_canvas].transform=p_offset;
+
+}
+void VisualServerViewport::viewport_set_transparent_background(RID p_viewport,bool p_enabled){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ VSG::storage->render_target_set_flag(viewport->render_target,RasterizerStorage::RENDER_TARGET_TRANSPARENT,p_enabled);
+
+}
+
+void VisualServerViewport::viewport_set_global_canvas_transform(RID p_viewport,const Matrix32& p_transform){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->global_transform=p_transform;
+
+}
+void VisualServerViewport::viewport_set_canvas_layer(RID p_viewport,RID p_canvas,int p_layer){
+
+ Viewport * viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
+ viewport->canvas_map[p_canvas].layer=p_layer;
+
+}
+
+bool VisualServerViewport::free(RID p_rid) {
+
+ Viewport * viewport = viewport_owner.getornull(p_rid);
+ if (!viewport)
+ return false;
+
+
+ VSG::storage->free( viewport->render_target );
+
+ while(viewport->canvas_map.front()) {
+ viewport_remove_canvas(p_rid,viewport->canvas_map.front()->key());
+ }
+
+ viewport_set_scenario(p_rid,RID());
+ active_viewports.erase(viewport);
+
+ viewport_owner.free(p_rid);
+ memdelete(viewport);
+
+
+ return true;
+
+}
+
+VisualServerViewport::VisualServerViewport()
+{
+
+}
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
new file mode 100644
index 0000000000..e5c888fbcb
--- /dev/null
+++ b/servers/visual/visual_server_viewport.h
@@ -0,0 +1,118 @@
+#ifndef VISUALSERVERVIEWPORT_H
+#define VISUALSERVERVIEWPORT_H
+
+#include "servers/visual_server.h"
+#include "rasterizer.h"
+#include "self_list.h"
+
+class VisualServerViewport {
+public:
+
+ struct CanvasBase : public RID_Data {
+
+
+ };
+
+ struct Viewport : public RID_Data {
+
+ RID self;
+ RID parent;
+
+ Size2i size;
+ RID camera;
+ RID scenario;
+
+ VS::ViewportUpdateMode update_mode;
+ RID render_target;
+ RID render_target_texture;
+
+ int viewport_to_screen;
+ Rect2 viewport_to_screen_rect;
+
+ bool hide_scenario;
+ bool hide_canvas;
+ bool disable_environment;
+
+ Image capture;
+
+ VS::ViewportClearMode clear_mode;
+
+ bool rendered_in_prev_frame;
+
+ struct CanvasKey {
+
+ int layer;
+ RID canvas;
+ bool operator<(const CanvasKey& p_canvas) const { if (layer==p_canvas.layer) return canvas < p_canvas.canvas; return layer<p_canvas.layer; }
+ CanvasKey() { layer=0; }
+ CanvasKey(const RID& p_canvas, int p_layer) { canvas=p_canvas; layer=p_layer; }
+ };
+
+ struct CanvasData {
+
+ CanvasBase *canvas;
+ Matrix32 transform;
+ int layer;
+ };
+
+ Matrix32 global_transform;
+
+ Map<RID,CanvasData> canvas_map;
+
+ Viewport() {
+ update_mode=VS::VIEWPORT_UPDATE_WHEN_VISIBLE;
+ clear_mode=VS::VIEWPORT_CLEAR_ALWAYS;
+ rendered_in_prev_frame=false;
+ disable_environment=false;
+ viewport_to_screen=0;
+
+ }
+ };
+
+ mutable RID_Owner<Viewport> viewport_owner;
+ Vector<Viewport*> active_viewports;
+private:
+ void _draw_viewport(Viewport *p_viewport);
+public:
+
+
+ RID viewport_create();
+
+ void viewport_set_size(RID p_viewport,int p_width,int p_height);
+
+ void viewport_attach_to_screen(RID p_viewport,const Rect2& p_rect=Rect2(),int p_screen=0);
+ void viewport_detach(RID p_viewport);
+
+ void viewport_set_active(RID p_viewport,bool p_active);
+
+ void viewport_set_update_mode(RID p_viewport,VS::ViewportUpdateMode p_mode);
+ void viewport_set_vflip(RID p_viewport,bool p_enable);
+
+
+ void viewport_set_clear_mode(RID p_viewport,VS::ViewportClearMode p_clear_mode);
+
+ RID viewport_get_texture(RID p_viewport) const;
+ Image viewport_capture(RID p_viewport) const;
+
+ void viewport_set_hide_scenario(RID p_viewport,bool p_hide);
+ void viewport_set_hide_canvas(RID p_viewport,bool p_hide);
+ void viewport_set_disable_environment(RID p_viewport,bool p_disable);
+
+ void viewport_attach_camera(RID p_viewport,RID p_camera);
+ void viewport_set_scenario(RID p_viewport,RID p_scenario);
+ void viewport_attach_canvas(RID p_viewport,RID p_canvas);
+ void viewport_remove_canvas(RID p_viewport,RID p_canvas);
+ void viewport_set_canvas_transform(RID p_viewport,RID p_canvas,const Matrix32& p_offset);
+ void viewport_set_transparent_background(RID p_viewport,bool p_enabled);
+
+ void viewport_set_global_canvas_transform(RID p_viewport,const Matrix32& p_transform);
+ void viewport_set_canvas_layer(RID p_viewport,RID p_canvas,int p_layer);
+
+ void draw_viewports();
+
+ bool free(RID p_rid);
+
+ VisualServerViewport();
+};
+
+#endif // VISUALSERVERVIEWPORT_H
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
deleted file mode 100644
index 5ea4145342..0000000000
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*************************************************************************/
-/* visual_server_wrap_mt.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "visual_server_wrap_mt.h"
-#include "os/os.h"
-#include "globals.h"
-void VisualServerWrapMT::thread_exit() {
-
- exit=true;
-}
-
-void VisualServerWrapMT::thread_draw() {
-
-
- draw_mutex->lock();
-
- draw_pending--;
- bool draw=(draw_pending==0);// only draw when no more flushes are pending
-
- draw_mutex->unlock();
-
- if (draw) {
-
- visual_server->draw();
- }
-
-}
-
-void VisualServerWrapMT::thread_flush() {
-
-
- draw_mutex->lock();
-
- draw_pending--;
-
- draw_mutex->unlock();
-
-}
-
-
-
-void VisualServerWrapMT::_thread_callback(void *_instance) {
-
- VisualServerWrapMT *vsmt = reinterpret_cast<VisualServerWrapMT*>(_instance);
-
-
- vsmt->thread_loop();
-}
-
-void VisualServerWrapMT::thread_loop() {
-
- server_thread=Thread::get_caller_ID();
-
- OS::get_singleton()->make_rendering_thread();
-
- visual_server->init();
-
- exit=false;
- draw_thread_up=true;
- while(!exit) {
- // flush commands one by one, until exit is requested
- command_queue.wait_and_flush_one();
- }
-
- command_queue.flush_all(); // flush all
-
- visual_server->finish();
-
-}
-
-
-/* EVENT QUEUING */
-
-void VisualServerWrapMT::sync() {
-
- if (create_thread) {
-
- /* TODO: sync with the thread */
-
- /*
- ERR_FAIL_COND(!draw_mutex);
- draw_mutex->lock();
- draw_pending++; //cambiar por un saferefcount
- draw_mutex->unlock();
- */
- //command_queue.push( this, &VisualServerWrapMT::thread_flush);
- } else {
-
- command_queue.flush_all(); //flush all pending from other threads
- }
-
-}
-
-void VisualServerWrapMT::draw() {
-
-
- if (create_thread) {
-
- /* TODO: Make it draw
- ERR_FAIL_COND(!draw_mutex);
- draw_mutex->lock();
- draw_pending++; //cambiar por un saferefcount
- draw_mutex->unlock();
-
- command_queue.push( this, &VisualServerWrapMT::thread_draw);
- */
- } else {
-
- visual_server->draw();
- }
-}
-
-
-void VisualServerWrapMT::init() {
-
- if (create_thread) {
-
- draw_mutex = Mutex::create();
- print_line("CREATING RENDER THREAD");
- OS::get_singleton()->release_rendering_thread();
- if (create_thread) {
- thread = Thread::create( _thread_callback, this );
- print_line("STARTING RENDER THREAD");
- }
- while(!draw_thread_up) {
- OS::get_singleton()->delay_usec(1000);
- }
- print_line("DONE RENDER THREAD");
- } else {
-
- visual_server->init();
- }
-
-}
-
-void VisualServerWrapMT::finish() {
-
-
- if (thread) {
-
- command_queue.push( this, &VisualServerWrapMT::thread_exit);
- Thread::wait_to_finish( thread );
- memdelete(thread);
-
-
- texture_free_cached_ids();
- mesh_free_cached_ids();
-
- thread=NULL;
- } else {
- visual_server->finish();
- }
-
- if (draw_mutex)
- memdelete(draw_mutex);
-
-}
-
-
-VisualServerWrapMT::VisualServerWrapMT(VisualServer* p_contained,bool p_create_thread) : command_queue(p_create_thread) {
-
- visual_server=p_contained;
- create_thread=p_create_thread;
- thread=NULL;
- draw_mutex=NULL;
- draw_pending=0;
- draw_thread_up=false;
- alloc_mutex=Mutex::create();
- texture_pool_max_size=GLOBAL_DEF("render/thread_textures_prealloc",5);
- mesh_pool_max_size=GLOBAL_DEF("core/rid_pool_prealloc",20);
- if (!p_create_thread) {
- server_thread=Thread::get_caller_ID();
- } else {
- server_thread=0;
- }
-}
-
-
-VisualServerWrapMT::~VisualServerWrapMT() {
-
- memdelete(visual_server);
- memdelete(alloc_mutex);
- //finish();
-
-}
-
-
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
deleted file mode 100644
index b4e374dd6f..0000000000
--- a/servers/visual/visual_server_wrap_mt.h
+++ /dev/null
@@ -1,739 +0,0 @@
-/*************************************************************************/
-/* visual_server_wrap_mt.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifndef VISUAL_SERVER_WRAP_MT_H
-#define VISUAL_SERVER_WRAP_MT_H
-
-
-#include "servers/visual_server.h"
-#include "command_queue_mt.h"
-#include "os/thread.h"
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class VisualServerWrapMT : public VisualServer {
-
- // the real visual server
- mutable VisualServer *visual_server;
-
- mutable CommandQueueMT command_queue;
-
- static void _thread_callback(void *_instance);
- void thread_loop();
-
- Thread::ID server_thread;
- volatile bool exit;
- Thread *thread;
- volatile bool draw_thread_up;
- bool create_thread;
-
- Mutex *draw_mutex;
- int draw_pending;
- void thread_draw();
- void thread_flush();
-
- void thread_exit();
-
- Mutex*alloc_mutex;
-
-
- int texture_pool_max_size;
- List<RID> texture_id_pool;
-
- int mesh_pool_max_size;
- List<RID> mesh_id_pool;
-
-//#define DEBUG_SYNC
-
-#ifdef DEBUG_SYNC
-#define SYNC_DEBUG print_line("sync on: "+String(__FUNCTION__));
-#else
-#define SYNC_DEBUG
-#endif
-
-public:
-
-#define ServerName VisualServer
-#define ServerNameWrapMT VisualServerWrapMT
-#define server_name visual_server
-#include "servers/server_wrap_mt_common.h"
-
- //FUNC0R(RID,texture_create);
- FUNCRID(texture);
- FUNC5(texture_allocate,RID,int,int,Image::Format,uint32_t);
- FUNC3(texture_set_data,RID,const Image&,CubeMapSide);
- FUNC2RC(Image,texture_get_data,RID,CubeMapSide);
- FUNC2(texture_set_flags,RID,uint32_t);
- FUNC1RC(Image::Format,texture_get_format,RID);
- FUNC1RC(uint32_t,texture_get_flags,RID);
- FUNC1RC(uint32_t,texture_get_width,RID);
- FUNC1RC(uint32_t,texture_get_height,RID);
- FUNC3(texture_set_size_override,RID,int,int);
- FUNC1RC(bool,texture_can_stream,RID);
- FUNC3C(texture_set_reload_hook,RID,ObjectID,const StringName&);
-
- FUNC2(texture_set_path,RID,const String&);
- FUNC1RC(String,texture_get_path,RID);
-
- FUNC1(texture_set_shrink_all_x2_on_set_data,bool);
-
- virtual void texture_debug_usage(List<TextureInfo> *r_info) {
- //pass directly, should lock the server anyway
- visual_server->texture_debug_usage(r_info);
- }
-
-
- /* SHADER API */
-
- FUNC1R(RID,shader_create,ShaderMode);
- FUNC2(shader_set_mode,RID,ShaderMode);
- FUNC1RC(ShaderMode,shader_get_mode,RID);
- FUNC7(shader_set_code,RID,const String&,const String&,const String&,int,int,int);
- FUNC1RC(String,shader_get_vertex_code,RID);
- FUNC1RC(String,shader_get_fragment_code,RID);
- FUNC1RC(String,shader_get_light_code,RID);
- FUNC2SC(shader_get_param_list,RID,List<PropertyInfo>*);
-
- FUNC3(shader_set_default_texture_param,RID,const StringName&,RID);
- FUNC2RC(RID,shader_get_default_texture_param,RID,const StringName&);
-
-
- /*virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) {
- if (Thread::get_caller_ID()!=server_thread) {
- command_queue.push_and_sync( visual_server, &VisualServer::shader_get_param_list,p_shader,p_param_list);
- } else {
- visual_server->m_type(p1, p2, p3, p4, p5);
- }
- }*/
-
-// virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list);
-
-
- /* COMMON MATERIAL API */
-
- FUNC0R(RID,material_create);
- FUNC2(material_set_shader,RID,RID);
- FUNC1RC(RID,material_get_shader,RID);
-
- FUNC3(material_set_param,RID,const StringName&,const Variant&);
- FUNC2RC(Variant,material_get_param,RID,const StringName&);
-
- FUNC3(material_set_flag,RID,MaterialFlag,bool);
- FUNC2RC(bool,material_get_flag,RID,MaterialFlag);
-
- FUNC2(material_set_depth_draw_mode,RID,MaterialDepthDrawMode);
- FUNC1RC(MaterialDepthDrawMode,material_get_depth_draw_mode,RID);
-
- FUNC2(material_set_blend_mode,RID,MaterialBlendMode);
- FUNC1RC(MaterialBlendMode,material_get_blend_mode,RID);
-
- FUNC2(material_set_line_width,RID,float);
- FUNC1RC(float,material_get_line_width,RID);
-
- /* FIXED MATERIAL */
-
-
- FUNC0R(RID,fixed_material_create);
-
- FUNC3(fixed_material_set_flag,RID, FixedMaterialFlags , bool );
- FUNC2RC(bool, fixed_material_get_flag,RID, FixedMaterialFlags);
-
- FUNC3(fixed_material_set_param,RID, FixedMaterialParam, const Variant& );
- FUNC2RC(Variant, fixed_material_get_param,RID ,FixedMaterialParam);
-
- FUNC3(fixed_material_set_texture,RID ,FixedMaterialParam, RID );
- FUNC2RC(RID, fixed_material_get_texture,RID,FixedMaterialParam);
-
-
-
- FUNC3(fixed_material_set_texcoord_mode,RID,FixedMaterialParam, FixedMaterialTexCoordMode );
- FUNC2RC(FixedMaterialTexCoordMode, fixed_material_get_texcoord_mode,RID,FixedMaterialParam);
-
- FUNC2(fixed_material_set_light_shader,RID,FixedMaterialLightShader);
- FUNC1RC(FixedMaterialLightShader, fixed_material_get_light_shader,RID);
-
- FUNC2(fixed_material_set_uv_transform,RID,const Transform&);
- FUNC1RC(Transform, fixed_material_get_uv_transform,RID);
-
- FUNC2(fixed_material_set_point_size,RID ,float);
- FUNC1RC(float,fixed_material_get_point_size,RID);
-
- /* SURFACE API */
- FUNCRID(mesh);
-
- FUNC2(mesh_set_morph_target_count,RID,int);
- FUNC1RC(int,mesh_get_morph_target_count,RID);
-
-
- FUNC2(mesh_set_morph_target_mode,RID,MorphTargetMode);
- FUNC1RC(MorphTargetMode,mesh_get_morph_target_mode,RID);
-
- FUNC2(mesh_add_custom_surface,RID,const Variant&); //this is used by each platform in a different way
-
- FUNC5(mesh_add_surface,RID,PrimitiveType,const Array&,const Array&,bool);
- FUNC2RC(Array,mesh_get_surface_arrays,RID,int);
- FUNC2RC(Array,mesh_get_surface_morph_arrays,RID,int);
-
- FUNC4(mesh_surface_set_material,RID, int, RID,bool);
- FUNC2RC(RID,mesh_surface_get_material,RID, int);
-
- FUNC2RC(int,mesh_surface_get_array_len,RID, int);
- FUNC2RC(int,mesh_surface_get_array_index_len,RID, int);
- FUNC2RC(uint32_t,mesh_surface_get_format,RID, int);
- FUNC2RC(PrimitiveType,mesh_surface_get_primitive_type,RID, int);
-
- FUNC2(mesh_remove_surface,RID,int);
- FUNC1RC(int,mesh_get_surface_count,RID);
- FUNC1(mesh_clear,RID);
-
-
- FUNC2(mesh_set_custom_aabb,RID,const AABB&);
- FUNC1RC(AABB,mesh_get_custom_aabb,RID);
-
-
- /* MULTIMESH API */
-
- FUNC0R(RID,multimesh_create);
- FUNC2(multimesh_set_instance_count,RID,int);
- FUNC1RC(int,multimesh_get_instance_count,RID);
-
- FUNC2(multimesh_set_mesh,RID,RID);
- FUNC2(multimesh_set_aabb,RID,const AABB&);
- FUNC3(multimesh_instance_set_transform,RID,int,const Transform&);
- FUNC3(multimesh_instance_set_color,RID,int,const Color&);
-
- FUNC1RC(RID,multimesh_get_mesh,RID);
- FUNC2RC(AABB,multimesh_get_aabb,RID,const AABB&);
- FUNC2RC(Transform,multimesh_instance_get_transform,RID,int);
- FUNC2RC(Color,multimesh_instance_get_color,RID,int);
-
- FUNC2(multimesh_set_visible_instances,RID,int);
- FUNC1RC(int,multimesh_get_visible_instances,RID);
-
- /* IMMEDIATE API */
-
-
- FUNC0R(RID,immediate_create);
- FUNC3(immediate_begin,RID,PrimitiveType,RID);
- FUNC2(immediate_vertex,RID,const Vector3&);
- FUNC2(immediate_normal,RID,const Vector3&);
- FUNC2(immediate_tangent,RID,const Plane&);
- FUNC2(immediate_color,RID,const Color&);
- FUNC2(immediate_uv,RID,const Vector2&);
- FUNC2(immediate_uv2,RID,const Vector2&);
- FUNC1(immediate_end,RID);
- FUNC1(immediate_clear,RID);
- FUNC2(immediate_set_material,RID,RID);
- FUNC1RC(RID,immediate_get_material,RID);
-
-
- /* PARTICLES API */
-
- FUNC0R(RID,particles_create);
-
- FUNC2(particles_set_amount,RID, int );
- FUNC1RC(int,particles_get_amount,RID);
-
- FUNC2(particles_set_emitting,RID, bool );
- FUNC1RC(bool,particles_is_emitting,RID);
-
- FUNC2(particles_set_visibility_aabb,RID, const AABB&);
- FUNC1RC(AABB,particles_get_visibility_aabb,RID);
-
- FUNC2(particles_set_emission_half_extents,RID, const Vector3&);
- FUNC1RC(Vector3,particles_get_emission_half_extents,RID);
-
- FUNC2(particles_set_emission_base_velocity,RID, const Vector3&);
- FUNC1RC(Vector3,particles_get_emission_base_velocity,RID);
-
- FUNC2(particles_set_emission_points,RID, const DVector<Vector3>& );
- FUNC1RC(DVector<Vector3>,particles_get_emission_points,RID);
-
- FUNC2(particles_set_gravity_normal,RID, const Vector3& );
- FUNC1RC(Vector3,particles_get_gravity_normal,RID);
-
- FUNC3(particles_set_variable,RID, ParticleVariable ,float);
- FUNC2RC(float,particles_get_variable,RID, ParticleVariable );
-
- FUNC3(particles_set_randomness,RID, ParticleVariable ,float);
- FUNC2RC(float,particles_get_randomness,RID, ParticleVariable );
-
- FUNC3(particles_set_color_phase_pos,RID, int , float);
- FUNC2RC(float,particles_get_color_phase_pos,RID, int );
-
- FUNC2(particles_set_color_phases,RID, int );
- FUNC1RC(int,particles_get_color_phases,RID);
-
- FUNC3(particles_set_color_phase_color,RID, int , const Color& );
- FUNC2RC(Color,particles_get_color_phase_color,RID, int );
-
- FUNC2(particles_set_attractors,RID, int);
- FUNC1RC(int,particles_get_attractors,RID);
-
- FUNC3(particles_set_attractor_pos,RID, int, const Vector3&);
- FUNC2RC(Vector3,particles_get_attractor_pos,RID,int);
-
- FUNC3(particles_set_attractor_strength,RID, int, float);
- FUNC2RC(float,particles_get_attractor_strength,RID,int);
-
- FUNC3(particles_set_material,RID, RID,bool);
- FUNC1RC(RID,particles_get_material,RID);
-
- FUNC2(particles_set_height_from_velocity,RID, bool);
- FUNC1RC(bool,particles_has_height_from_velocity,RID);
-
- FUNC2(particles_set_use_local_coordinates,RID, bool);
- FUNC1RC(bool,particles_is_using_local_coordinates,RID);
-
-
- /* Light API */
-
- FUNC1R(RID,light_create,LightType);
- FUNC1RC(LightType,light_get_type,RID);
-
- FUNC3(light_set_color,RID,LightColor , const Color& );
- FUNC2RC(Color,light_get_color,RID,LightColor );
-
-
- FUNC2(light_set_shadow,RID,bool );
- FUNC1RC(bool,light_has_shadow,RID);
-
- FUNC2(light_set_volumetric,RID,bool );
- FUNC1RC(bool,light_is_volumetric,RID);
-
- FUNC2(light_set_projector,RID,RID );
- FUNC1RC(RID,light_get_projector,RID);
-
- FUNC3(light_set_param,RID, LightParam , float );
- FUNC2RC(float,light_get_param,RID, LightParam );
-
- FUNC2(light_set_operator,RID,LightOp);
- FUNC1RC(LightOp,light_get_operator,RID);
-
- FUNC2(light_omni_set_shadow_mode,RID,LightOmniShadowMode);
- FUNC1RC(LightOmniShadowMode,light_omni_get_shadow_mode,RID);
-
- FUNC2(light_directional_set_shadow_mode,RID,LightDirectionalShadowMode);
- FUNC1RC(LightDirectionalShadowMode,light_directional_get_shadow_mode,RID);
- FUNC3(light_directional_set_shadow_param,RID,LightDirectionalShadowParam, float );
- FUNC2RC(float,light_directional_get_shadow_param,RID,LightDirectionalShadowParam );
-
-
- /* SKELETON API */
-
- FUNC0R(RID,skeleton_create);
- FUNC2(skeleton_resize,RID,int );
- FUNC1RC(int,skeleton_get_bone_count,RID) ;
- FUNC3(skeleton_bone_set_transform,RID,int, const Transform&);
- FUNC2R(Transform,skeleton_bone_get_transform,RID,int );
-
- /* ROOM API */
-
- FUNC0R(RID,room_create);
- FUNC2(room_set_bounds,RID, const BSP_Tree&);
- FUNC1RC(BSP_Tree,room_get_bounds,RID);
-
- /* PORTAL API */
-
- FUNC0R(RID,portal_create);
- FUNC2(portal_set_shape,RID,const Vector<Point2>&);
- FUNC1RC(Vector<Point2>,portal_get_shape,RID);
- FUNC2(portal_set_enabled,RID, bool);
- FUNC1RC(bool,portal_is_enabled,RID);
- FUNC2(portal_set_disable_distance,RID, float);
- FUNC1RC(float,portal_get_disable_distance,RID);
- FUNC2(portal_set_disabled_color,RID, const Color&);
- FUNC1RC(Color,portal_get_disabled_color,RID);
- FUNC2(portal_set_connect_range,RID, float);
- FUNC1RC(float,portal_get_connect_range,RID);
-
-
- FUNC0R(RID,baked_light_create);
- FUNC2(baked_light_set_mode,RID,BakedLightMode);
- FUNC1RC(BakedLightMode,baked_light_get_mode,RID);
-
- FUNC2(baked_light_set_octree,RID,DVector<uint8_t>);
- FUNC1RC(DVector<uint8_t>,baked_light_get_octree,RID);
-
- FUNC2(baked_light_set_light,RID,DVector<uint8_t>);
- FUNC1RC(DVector<uint8_t>,baked_light_get_light,RID);
-
- FUNC2(baked_light_set_sampler_octree,RID,const DVector<int>&);
- FUNC1RC(DVector<int>,baked_light_get_sampler_octree,RID);
-
- FUNC2(baked_light_set_lightmap_multiplier,RID,float);
- FUNC1RC(float,baked_light_get_lightmap_multiplier,RID);
-
- FUNC3(baked_light_add_lightmap,RID,RID,int);
- FUNC1(baked_light_clear_lightmaps,RID);
-
- FUNC2(baked_light_set_realtime_color_enabled, RID, const bool);
- FUNC1RC(bool, baked_light_get_realtime_color_enabled, RID);
-
- FUNC2(baked_light_set_realtime_color, RID, const Color&);
- FUNC1RC(Color, baked_light_get_realtime_color, RID);
-
- FUNC2(baked_light_set_realtime_energy, RID, const float);
- FUNC1RC(float, baked_light_get_realtime_energy, RID);
-
- FUNC0R(RID,baked_light_sampler_create);
-
- FUNC3(baked_light_sampler_set_param,RID, BakedLightSamplerParam , float );
- FUNC2RC(float,baked_light_sampler_get_param,RID, BakedLightSamplerParam );
-
- FUNC2(baked_light_sampler_set_resolution,RID,int);
- FUNC1RC(int,baked_light_sampler_get_resolution,RID);
-
- /* CAMERA API */
-
- FUNC0R(RID,camera_create);
- FUNC4(camera_set_perspective,RID,float , float , float );
- FUNC4(camera_set_orthogonal,RID,float, float , float );
- FUNC2(camera_set_transform,RID,const Transform& );
-
- FUNC2(camera_set_visible_layers,RID,uint32_t);
- FUNC1RC(uint32_t,camera_get_visible_layers,RID);
-
- FUNC2(camera_set_environment,RID,RID);
- FUNC1RC(RID,camera_get_environment,RID);
-
-
- FUNC2(camera_set_use_vertical_aspect,RID,bool);
- FUNC2RC(bool,camera_is_using_vertical_aspect,RID,bool);
-
-
- /* VIEWPORT API */
-
- FUNC0R(RID,viewport_create);
-
- FUNC2(viewport_attach_to_screen,RID,int );
- FUNC1(viewport_detach,RID);
-
- FUNC2(viewport_set_as_render_target,RID,bool);
- FUNC2(viewport_set_render_target_update_mode,RID,RenderTargetUpdateMode);
- FUNC1RC(RenderTargetUpdateMode,viewport_get_render_target_update_mode,RID);
- FUNC1RC(RID,viewport_get_render_target_texture,RID);
-
- 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);
-
- FUNC2(viewport_set_rect,RID,const ViewportRect&);
- FUNC1RC(ViewportRect,viewport_get_rect,RID);
-
- FUNC2(viewport_set_hide_scenario,RID,bool );
- FUNC2(viewport_set_hide_canvas,RID,bool );
- FUNC2(viewport_attach_camera,RID,RID );
- FUNC2(viewport_set_scenario,RID,RID );
- FUNC2(viewport_set_disable_environment,RID,bool );
-
- FUNC1RC(RID,viewport_get_attached_camera,RID);
- FUNC1RC(RID,viewport_get_scenario,RID );
- FUNC2(viewport_attach_canvas,RID,RID);
- FUNC2(viewport_remove_canvas,RID,RID);
- FUNC3(viewport_set_canvas_transform,RID,RID,const Matrix32&);
- FUNC2RC(Matrix32,viewport_get_canvas_transform,RID,RID);
- FUNC2(viewport_set_global_canvas_transform,RID,const Matrix32&);
- FUNC1RC(Matrix32,viewport_get_global_canvas_transform,RID);
- FUNC3(viewport_set_canvas_layer,RID,RID ,int);
- FUNC2(viewport_set_transparent_background,RID,bool);
- FUNC1RC(bool,viewport_has_transparent_background,RID);
-
-
- /* ENVIRONMENT API */
-
- FUNC0R(RID,environment_create);
-
- FUNC2(environment_set_background,RID,EnvironmentBG);
- FUNC1RC(EnvironmentBG,environment_get_background,RID);
-
- FUNC3(environment_set_background_param,RID,EnvironmentBGParam, const Variant&);
- FUNC2RC(Variant,environment_get_background_param,RID,EnvironmentBGParam );
-
- FUNC3(environment_set_enable_fx,RID,EnvironmentFx,bool);
- FUNC2RC(bool,environment_is_fx_enabled,RID,EnvironmentFx);
-
-
- FUNC3(environment_fx_set_param,RID,EnvironmentFxParam,const Variant&);
- FUNC2RC(Variant,environment_fx_get_param,RID,EnvironmentFxParam);
-
-
- /* SCENARIO API */
-
- FUNC0R(RID,scenario_create);
-
- FUNC2(scenario_set_debug,RID,ScenarioDebugMode);
- FUNC2(scenario_set_environment,RID, RID);
- FUNC2RC(RID,scenario_get_environment,RID, RID);
- FUNC2(scenario_set_fallback_environment,RID, RID);
-
-
- /* INSTANCING API */
-
- FUNC0R(RID,instance_create);
-
- FUNC2(instance_set_base,RID, RID);
- FUNC1RC(RID,instance_get_base,RID);
-
- FUNC2(instance_set_scenario,RID, RID);
- FUNC1RC(RID,instance_get_scenario,RID);
-
- FUNC2(instance_set_layer_mask,RID, uint32_t);
- FUNC1RC(uint32_t,instance_get_layer_mask,RID);
-
- FUNC1RC(AABB,instance_get_base_aabb,RID);
-
- FUNC2(instance_attach_object_instance_ID,RID,uint32_t);
- FUNC1RC(uint32_t,instance_get_object_instance_ID,RID);
-
- FUNC2(instance_attach_skeleton,RID,RID);
- FUNC1RC(RID,instance_get_skeleton,RID);
-
- FUNC3(instance_set_morph_target_weight,RID,int, float);
- FUNC2RC(float,instance_get_morph_target_weight,RID,int);
-
- FUNC3(instance_set_surface_material,RID,int, RID);
-
- FUNC2(instance_set_transform,RID, const Transform&);
- FUNC1RC(Transform,instance_get_transform,RID);
-
- FUNC2(instance_set_exterior,RID, bool );
- FUNC1RC(bool,instance_is_exterior,RID);
-
- FUNC2(instance_set_room,RID, RID );
- FUNC1RC(RID,instance_get_room,RID ) ;
-
- FUNC2(instance_set_extra_visibility_margin,RID, real_t );
- FUNC1RC(real_t,instance_get_extra_visibility_margin,RID );
-
- FUNC2RC(Vector<RID>,instances_cull_aabb,const AABB& , RID );
- FUNC3RC(Vector<RID>,instances_cull_ray,const Vector3& ,const Vector3&, RID );
- FUNC2RC(Vector<RID>,instances_cull_convex,const Vector<Plane>& , RID );
-
- FUNC3(instance_geometry_set_flag,RID,InstanceFlags ,bool );
- FUNC2RC(bool,instance_geometry_get_flag,RID,InstanceFlags );
-
- FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting);
- FUNC1RC(ShadowCastingSetting, instance_geometry_get_cast_shadows_setting, RID);
-
- FUNC2(instance_geometry_set_material_override,RID, RID );
- FUNC1RC(RID,instance_geometry_get_material_override,RID);
-
- FUNC3(instance_geometry_set_draw_range,RID,float ,float);
- FUNC1RC(float,instance_geometry_get_draw_range_max,RID);
- FUNC1RC(float,instance_geometry_get_draw_range_min,RID);
-
- FUNC2(instance_geometry_set_baked_light,RID, RID );
- FUNC1RC(RID,instance_geometry_get_baked_light,RID);
-
- FUNC2(instance_geometry_set_baked_light_sampler,RID, RID );
- FUNC1RC(RID,instance_geometry_get_baked_light_sampler,RID);
-
- FUNC2(instance_geometry_set_baked_light_texture_index,RID, int);
- FUNC1RC(int,instance_geometry_get_baked_light_texture_index,RID);
-
- FUNC2(instance_light_set_enabled,RID,bool);
- FUNC1RC(bool,instance_light_is_enabled,RID);
-
- /* CANVAS (2D) */
-
- 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);
-
- FUNC2(canvas_item_set_parent,RID,RID );
- FUNC1RC(RID,canvas_item_get_parent,RID);
-
- FUNC2(canvas_item_set_visible,RID,bool );
- 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& );
- FUNC2(canvas_item_set_clip,RID, bool );
- FUNC2(canvas_item_set_distance_field_mode,RID, bool );
- FUNC3(canvas_item_set_custom_rect,RID, bool ,const Rect2&);
- FUNC2(canvas_item_set_opacity,RID, float );
- FUNC2RC(float,canvas_item_get_opacity,RID, float );
- FUNC2(canvas_item_set_on_top,RID, bool );
- FUNC1RC(bool,canvas_item_is_on_top,RID);
-
- FUNC2(canvas_item_set_self_opacity,RID, float );
- FUNC2RC(float,canvas_item_get_self_opacity,RID, float );
-
- FUNC2(canvas_item_attach_viewport,RID, RID );
-
- FUNC6(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float,bool);
- FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& );
- FUNC4(canvas_item_add_circle,RID, const Point2& , float ,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 );
- FUNC8(canvas_item_add_style_box,RID, const Rect2& , 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 );
- FUNC7(canvas_item_add_triangle_array,RID, const Vector<int>& , const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID , int );
- FUNC7(canvas_item_add_triangle_array_ptr,RID, int , const int* , const Point2* , const Color* ,const Point2* , RID );
-
-
- FUNC2(canvas_item_add_set_transform,RID,const Matrix32& );
- FUNC2(canvas_item_add_set_blend_mode,RID, MaterialBlendMode );
- 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);
- FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool);
- FUNC3(canvas_item_set_copy_to_backbuffer,RID,bool,const Rect2&);
-
-
- FUNC2(canvas_item_set_material,RID, RID );
-
- FUNC2(canvas_item_set_use_parent_material,RID, bool );
-
- FUNC1(canvas_item_clear,RID);
- FUNC1(canvas_item_raise,RID);
-
- /* CANVAS LIGHT */
- FUNC0R(RID,canvas_light_create);
- FUNC2(canvas_light_attach_to_canvas,RID,RID);
- FUNC2(canvas_light_set_enabled,RID,bool);
- FUNC2(canvas_light_set_transform,RID,const Matrix32&);
- FUNC2(canvas_light_set_scale,RID,float);
- FUNC2(canvas_light_set_texture,RID,RID);
- FUNC2(canvas_light_set_texture_offset,RID,const Vector2&);
- FUNC2(canvas_light_set_color,RID,const Color&);
- FUNC2(canvas_light_set_height,RID,float);
- FUNC2(canvas_light_set_energy,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_item_shadow_mask,RID,int);
-
- FUNC2(canvas_light_set_mode,RID,CanvasLightMode);
- FUNC2(canvas_light_set_shadow_enabled,RID,bool);
- FUNC2(canvas_light_set_shadow_buffer_size,RID,int);
- FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float);
- FUNC2(canvas_light_set_shadow_color,RID,const Color&);
-
-
-
- /* CANVAS OCCLUDER */
-
- FUNC0R(RID,canvas_light_occluder_create);
- FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID);
- FUNC2(canvas_light_occluder_set_enabled,RID,bool);
- FUNC2(canvas_light_occluder_set_polygon,RID,RID);
- FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&);
- FUNC2(canvas_light_occluder_set_light_mask,RID,int);
-
-
- FUNC0R(RID,canvas_occluder_polygon_create);
- FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector<Vector2>&,bool);
- FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector<Vector2>&);
- FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode);
-
- /* CANVAS MATERIAL */
-
- FUNC0R(RID,canvas_item_material_create);
- FUNC2(canvas_item_material_set_shader,RID,RID);
- FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&);
- FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);
- FUNC2(canvas_item_material_set_shading_mode,RID,CanvasItemShadingMode);
-
- /* CURSOR */
- FUNC2(cursor_set_rotation,float , int ); // radians
- FUNC4(cursor_set_texture,RID , const Point2 &, int, const Rect2 &);
- FUNC2(cursor_set_visible,bool , int );
- FUNC2(cursor_set_pos,const Point2& , int );
-
- /* BLACK BARS */
-
- FUNC4(black_bars_set_margins,int , int , int , int );
- FUNC4(black_bars_set_images,RID , RID , RID , RID );
-
- /* FREE */
-
- FUNC1(free,RID);
-
- /* CUSTOM SHADE MODEL */
-
- FUNC2(custom_shade_model_set_shader,int , RID );
- FUNC1RC(RID,custom_shade_model_get_shader,int );
- FUNC2(custom_shade_model_set_name,int , const String& );
- FUNC1RC(String,custom_shade_model_get_name,int );
- FUNC2(custom_shade_model_set_param_info,int , const List<PropertyInfo>& );
- FUNC2SC(custom_shade_model_get_param_info,int , List<PropertyInfo>* );
-
- /* EVENT QUEUING */
-
-
- virtual void init();
- virtual void finish();
- virtual void draw();
- virtual void sync();
- FUNC0RC(bool,has_changed);
-
- /* RENDER INFO */
-
- FUNC1R(int,get_render_info,RenderInfo );
- virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); }
-
- FUNC3(set_boot_image,const Image& , const Color&,bool );
- FUNC1(set_default_clear_color,const Color& );
-
- FUNC0R(RID,get_test_cube );
-
-
- VisualServerWrapMT(VisualServer* p_contained,bool p_create_thread);
- ~VisualServerWrapMT();
-
-#undef ServerName
-#undef ServerNameWrapMT
-#undef server_name
-
-};
-
-#ifdef DEBUG_SYNC
-#undef DEBUG_SYNC
-#endif
-#undef SYNC_DEBUG
-
-#endif