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
This commit is contained in:
Juan Linietsky 2016-10-03 16:33:42 -03:00
parent 78d97b060a
commit 22d83bc9f6
211 changed files with 15188 additions and 14195 deletions

View File

@ -386,6 +386,9 @@ if selected_platform in platform_list:
if (env['etc1']=='yes'):
env.Append(CPPFLAGS=['-DETC1_ENABLED'])
if (True): # detect GLES3
env.Append( BUILDERS = { 'GLES3_GLSL' : env.Builder(action = methods.build_gles3_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
Export('env')
#build subdirs, the build order is dependent on link order.

View File

@ -1,217 +0,0 @@
/*************************************************************************/
/* test_detailer.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 "test_detailer.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
#include "geometry.h"
#include "quick_hull.h"
namespace TestMultiMesh {
class TestMainLoop : public MainLoop {
RID instance;
RID camera;
RID viewport;
RID light;
RID mesh;
RID scenario;
#define MULTIMESH_COUNT 1500
float ofs_x,ofs_y;
bool quit;
public:
virtual void _update_qh() {
VisualServer *vs=VisualServer::get_singleton();
Vector<Vector3> vts;
/*
static const int s = 20;
for(int i=0;i<s;i++) {
Matrix3 rot(Vector3(0,1,0),i*Math_PI/s);
for(int j=0;j<s;j++) {
Vector3 v;
v.x=Math::sin(j*Math_PI*2/s);
v.y=Math::cos(j*Math_PI*2/s);
vts.push_back( rot.xform(v*2 ) );
}
}*/
/*
Math::seed(0);
for(int i=0;i<50;i++) {
vts.push_back( Vector3(Math::randf()*2-1.0,Math::randf()*2-1.0,Math::randf()*2-1.0).normalized()*2);
}*/
/*
vts.push_back(Vector3(0,0,1));
vts.push_back(Vector3(0,0,-1));
vts.push_back(Vector3(0,1,0));
vts.push_back(Vector3(0,-1,0));
vts.push_back(Vector3(1,0,0));
vts.push_back(Vector3(-1,0,0));*/
/*
vts.push_back(Vector3(1,1,1));
vts.push_back(Vector3(1,-1,1));
vts.push_back(Vector3(-1,1,1));
vts.push_back(Vector3(-1,-1,1));
vts.push_back(Vector3(1,1,-1));
vts.push_back(Vector3(1,-1,-1));
vts.push_back(Vector3(-1,1,-1));
vts.push_back(Vector3(-1,-1,-1));
*/
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,4,Vector3::AXIS_Z);
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
vts=convex_data.vertices;
Geometry::MeshData md;
Error err = QuickHull::build(vts,md);
print_line("ERR: "+itos(err));
vs->mesh_remove_surface(mesh,0);
vs->mesh_add_surface_from_mesh_data(mesh,md);
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
/*
RID sm = vs->shader_create();
//vs->shader_set_fragment_code(sm,"OUT_ALPHA=mod(TIME,1);");
//vs->shader_set_vertex_code(sm,"OUT_VERTEX=IN_VERTEX*mod(TIME,1);");
vs->shader_set_fragment_code(sm,"OUT_DIFFUSE=vec3(1,0,1);OUT_GLOW=abs(sin(TIME));");
RID tcmat = vs->mesh_surface_get_material(test_cube,0);
vs->material_set_shader(tcmat,sm);
*/
}
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_x+=p_event.mouse_motion.relative_y/200.0;
ofs_y+=p_event.mouse_motion.relative_x/200.0;
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
QuickHull::debug_stop_after++;
_update_qh();
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==2) {
if (QuickHull::debug_stop_after>0)
QuickHull::debug_stop_after--;
_update_qh();
}
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
mesh = vs->mesh_create();
scenario = vs->scenario_create();
QuickHull::debug_stop_after=0;
_update_qh();
instance = vs->instance_create2(mesh,scenario);
camera = vs->camera_create();
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
vs->viewport_attach_to_screen(viewport);
vs->viewport_set_scenario( viewport, scenario );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,2 ) ) );
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
light = vs->instance_create2( lightaux,scenario );
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
ofs_x=0;
ofs_y=0;
quit=false;
}
virtual bool idle(float p_time) {
return false;
}
virtual bool iteration(float p_time) {
VisualServer *vs=VisualServer::get_singleton();
Transform tr_camera;
tr_camera.rotate( Vector3(0,1,0), ofs_y );
tr_camera.rotate( Vector3(1,0,0),ofs_x );
tr_camera.translate(0,0,10);
vs->camera_set_transform( camera, tr_camera );
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew(TestMainLoop);
}
}

View File

@ -1,44 +0,0 @@
/*************************************************************************/
/* test_detailer.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 TEST_MULTIMESH_H
#define TEST_MULTIMESH_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestMultiMesh {
MainLoop* test();
}
#endif

View File

@ -370,7 +370,7 @@ public:
tabc->set_size( Point2( 180,250 ) );
Ref<ImageTexture> text = memnew( ImageTexture );
/*Ref<ImageTexture> text = memnew( ImageTexture );
text->load("test_data/concave.png");
Sprite* sprite = memnew(Sprite);
@ -383,7 +383,7 @@ public:
sprite->set_texture(text);
sprite->add_child(sprite2);
sprite2->set_pos(Point2(50, 50));
sprite2->show();
sprite2->show();*/
}

View File

@ -37,13 +37,10 @@
#include "test_gui.h"
#include "test_render.h"
#include "test_sound.h"
#include "test_misc.h"
#include "test_physics.h"
#include "test_physics_2d.h"
#include "test_python.h"
#include "test_io.h"
#include "test_particles.h"
#include "test_detailer.h"
#include "test_shader_lang.h"
#include "test_gdscript.h"
#include "test_image.h"
@ -56,7 +53,6 @@ const char ** tests_get_names() {
"containers",
"math",
"render",
"particles",
"multimesh",
"gui",
"io",
@ -96,11 +92,6 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
return TestPhysics2D::test();
}
if (p_test=="misc") {
return TestMisc::test();
}
if (p_test=="render") {
return TestRender::test();
@ -123,16 +114,6 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
return TestIO::test();
}
if (p_test=="particles") {
return TestParticles::test();
}
if (p_test=="multimesh") {
return TestMultiMesh::test();
}
if (p_test=="shaderlang") {
return TestShaderLang::test();
@ -163,19 +144,6 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
return TestImage::test();
}
if (p_test=="detailer") {
return TestMultiMesh::test();
}
#ifdef PYTHON_ENABLED
if (p_test=="python") {
return TestPython::test();
}
#endif
return NULL;
}

View File

@ -1,499 +0,0 @@
/*************************************************************************/
/* test_misc.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 "test_misc.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
namespace TestMisc {
struct ConvexTestResult
{
Vector3 edgeA[2];
Vector3 edgeB[2];
bool valid;
Vector3 contactA;
Vector3 contactB;
Vector3 contactNormal;
float depth;
/*
Vector3 contactA;
Vector3 contactB;
Vector3 contactNormal;
Vector3 contactX;
Vector3 contactY;
Vector3 edgeA[2];
Vector3 edgeB[2];
float depth;
bool valid;
bool isEdgeEdge;
bool needTransform;
neBool ComputerEdgeContactPoint(ConvexTestResult & res);
neBool ComputerEdgeContactPoint2(float & au, float & bu);
void Reverse()
{
neSwap(contactA, contactB);
contactNormal *= -1.0f;
}*/
bool ComputerEdgeContactPoint2(float & au, float & bu);
};
bool ConvexTestResult::ComputerEdgeContactPoint2(float & au, float & bu)
{
float d1343, d4321, d1321, d4343, d2121;
float numer, denom;
Vector3 p13;
Vector3 p43;
Vector3 p21;
Vector3 diff;
p13 = (edgeA[0]) - (edgeB[0]);
p43 = (edgeB[1]) - (edgeB[0]);
if ( p43.length_squared() < CMP_EPSILON2 )
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
p21 = (edgeA[1]) - (edgeA[0]);
if ( p21.length_squared()<CMP_EPSILON2 )
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
d1343 = p13.dot(p43);
d4321 = p43.dot(p21);
d1321 = p13.dot(p21);
d4343 = p43.dot(p43);
d2121 = p21.dot(p21);
denom = d2121 * d4343 - d4321 * d4321;
if (ABS(denom) < CMP_EPSILON)
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
numer = d1343 * d4321 - d1321 * d4343;
au = numer / denom;
bu = (d1343 + d4321 * (au)) / d4343;
if (au < 0.0f || au >= 1.0f)
{
valid = false;
}
else if (bu < 0.0f || bu >= 1.0f)
{
valid = false;
}
else
{
valid = true;
}
{
Vector3 tmpv;
tmpv = p21 * au;
contactA = (edgeA[0]) + tmpv;
tmpv = p43 * bu;
contactB = (edgeB[0]) + tmpv;
}
diff = contactA - contactB;
depth = Math::sqrt(diff.dot(diff));
return true;
ComputerEdgeContactPoint2_Exit:
return false;
}
struct neCollisionResult {
float depth;
bool penetrate;
Matrix3 collisionFrame;
Vector3 contactA;
Vector3 contactB;
};
struct TConvex {
float radius;
float half_height;
float CylinderRadius() const { return radius; }
float CylinderHalfHeight() const { return half_height; }
};
float GetDistanceFromLine2(Vector3 v, Vector3 & project, const Vector3 & pointA, const Vector3 & pointB)
{
Vector3 ba = pointB - pointA;
float len = ba.length();
if (len<CMP_EPSILON)
ba=Vector3();
else
ba *= 1.0f / len;
Vector3 pa = v - pointA;
float k = pa.dot(ba);
project = pointA + ba * k;
Vector3 diff = v - project;
return diff.length();
}
void TestCylinderVertEdge(neCollisionResult & result, Vector3 & edgeA1, Vector3 & edgeA2, Vector3 & vertB,
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB, bool flip)
{
Vector3 project;
float dist = GetDistanceFromLine2(vertB,project, edgeA1, edgeA2);
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
if (depth <= 0.0f)
return;
if (depth <= result.depth)
return;
result.penetrate = true;
result.depth = depth;
if (!flip)
{
result.collisionFrame.set_axis(2,(project - vertB).normalized());
result.contactA = project - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
}
else
{
result.collisionFrame.set_axis(2,(vertB - project).normalized());
result.contactA = vertB - result.collisionFrame.get_axis(2) * cB.CylinderRadius();
result.contactB = project + result.collisionFrame.get_axis(2) * cA.CylinderRadius();
}
}
void TestCylinderVertVert(neCollisionResult & result, Vector3 & vertA, Vector3 & vertB,
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB)
{
Vector3 diff = vertA - vertB;
float dist = diff.length();
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
if (depth <= 0.0f)
return;
if (depth <= result.depth)
return;
result.penetrate = true;
result.depth = depth;
result.collisionFrame.set_axis(2, diff * (1.0f / dist));
result.contactA = vertA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
}
void Cylinder2CylinderTest(neCollisionResult & result, TConvex & cA, Transform & transA, TConvex & cB, Transform & transB)
{
result.penetrate = false;
Vector3 dir = transA.basis.get_axis(1).cross(transB.basis.get_axis(1));
float len = dir.length();
// bool isParallel = len<CMP_EPSILON;
// int doVertCheck = 0;
ConvexTestResult cr;
cr.edgeA[0] = transA.origin + transA.basis.get_axis(1) * cA.CylinderHalfHeight();
cr.edgeA[1] = transA.origin - transA.basis.get_axis(1) * cA.CylinderHalfHeight();
cr.edgeB[0] = transB.origin + transB.basis.get_axis(1) * cB.CylinderHalfHeight();
cr.edgeB[1] = transB.origin - transB.basis.get_axis(1) * cB.CylinderHalfHeight();
// float dot = transA.basis.get_axis(1).dot(transB.basis.get_axis(1));
if (len>CMP_EPSILON)
{
float au, bu;
cr.ComputerEdgeContactPoint2(au, bu);
if (cr.valid)
{
float depth = cA.CylinderRadius() + cB.CylinderRadius() - cr.depth;
if (depth <= 0.0f)
return;
result.depth = depth;
result.penetrate = true;
result.collisionFrame.set_axis(2, (cr.contactA - cr.contactB)*(1.0f / cr.depth));
result.contactA = cr.contactA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = cr.contactB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
return;
}
}
result.depth = -1.0e6f;
int i;
for (i = 0; i < 2; i++)
{
//project onto edge b
Vector3 diff = cr.edgeA[i] - cr.edgeB[1];
float dot = diff.dot(transB.basis.get_axis(1));
if (dot < 0.0f)
{
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[1], cA, cB, transA, transB);
}
else if (dot > (2.0f * cB.CylinderHalfHeight()))
{
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[0], cA, cB, transA, transB);
}
else
{
TestCylinderVertEdge(result, cr.edgeB[0], cr.edgeB[1], cr.edgeA[i], cB, cA, transB, transA, true);
}
}
for (i = 0; i < 2; i++)
{
//project onto edge b
Vector3 diff = cr.edgeB[i] - cr.edgeA[1];
float dot = diff.dot(transA.basis.get_axis(1));
if (dot < 0.0f)
{
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[1], cA, cB, transA, transB);
}
else if (dot > (2.0f * cB.CylinderHalfHeight()))
{
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[0], cA, cB, transA, transB);
}
else
{
TestCylinderVertEdge(result, cr.edgeA[0], cr.edgeA[1], cr.edgeB[i], cA, cB, transA, transB, false);
}
}
}
class TestMainLoop : public MainLoop {
RID meshA;
RID meshB;
RID poly;
RID instance;
RID camera;
RID viewport;
RID boxA;
RID boxB;
RID scenario;
Transform rot_a;
Transform rot_b;
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
rot_b.origin.y+=-p_event.mouse_motion.relative_y/100.0;
rot_b.origin.x+=p_event.mouse_motion.relative_x/100.0;
}
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_MIDDLE) {
//rot_b.origin.x+=-p_event.mouse_motion.relative_y/100.0;
rot_b.origin.z+=p_event.mouse_motion.relative_x/100.0;
}
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_RIGHT) {
float rot_x=-p_event.mouse_motion.relative_y/100.0;
float rot_y=p_event.mouse_motion.relative_x/100.0;
rot_b.basis = rot_b.basis * Matrix3(Vector3(1,0,0),rot_x) * Matrix3(Vector3(0,1,0),rot_y);
}
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
camera = vs->camera_create();
viewport = vs->viewport_create();
vs->viewport_attach_to_screen(viewport);
vs->viewport_attach_camera( viewport, camera );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,3 ) ) );
/* CONVEX SHAPE */
DVector<Plane> cylinder_planes = Geometry::build_cylinder_planes(0.5,2,9,Vector3::AXIS_Y);
RID cylinder_material = vs->fixed_material_create();
vs->fixed_material_set_param( cylinder_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_ONTOP,true);
//vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_WIREFRAME,true);
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_DOUBLE_SIDED,true);
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_UNSHADED,true);
RID cylinder_mesh = vs->mesh_create();
Geometry::MeshData cylinder_data = Geometry::build_convex_mesh(cylinder_planes);
vs->mesh_add_surface_from_mesh_data(cylinder_mesh,cylinder_data);
vs->mesh_surface_set_material( cylinder_mesh, 0, cylinder_material );
meshA=vs->instance_create2(cylinder_mesh,scenario);
meshB=vs->instance_create2(cylinder_mesh,scenario);
boxA=vs->instance_create2(vs->get_test_cube(),scenario);
boxB=vs->instance_create2(vs->get_test_cube(),scenario);
/*
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
light = vs->instance_create2( lightaux );
*/
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
//vs->light_set_shadow( lightaux, true );
vs->instance_create2( lightaux,scenario );
//rot_a=Transform(Matrix3(Vector3(1,0,0),Math_PI/2.0),Vector3());
rot_b=Transform(Matrix3(),Vector3(2,0,0));
//rot_x=0;
//rot_y=0;
quit=false;
}
virtual bool idle(float p_time) {
VisualServer *vs=VisualServer::get_singleton();
vs->instance_set_transform(meshA,rot_a);
vs->instance_set_transform(meshB,rot_b);
neCollisionResult res;
TConvex a;
a.radius=0.5;
a.half_height=1;
Cylinder2CylinderTest(res,a,rot_a,a,rot_b);
if (res.penetrate) {
Matrix3 scale;
scale.scale(Vector3(0.1,0.1,0.1));
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
print_line("depth: "+rtos(res.depth));
} else {
Matrix3 scale;
scale.scale(Vector3());
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
}
print_line("collided: "+itos(res.penetrate));
return false;
}
virtual bool iteration(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

View File

@ -1,40 +0,0 @@
/*************************************************************************/
/* test_misc.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 TEST_MISC_H
#define TEST_MISC_H
#include "os/main_loop.h"
namespace TestMisc {
MainLoop* test();
}
#endif

View File

@ -1,121 +0,0 @@
/*************************************************************************/
/* test_particles.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 "test_particles.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
namespace TestParticles {
class TestMainLoop : public MainLoop {
RID particles;
RID instance;
RID camera;
RID viewport;
RID light;
RID scenario;
struct InstanceInfo {
RID instance;
Transform base;
Vector3 rot_axis;
};
List<InstanceInfo> instances;
float ofs;
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
particles = vs->particles_create();
vs->particles_set_amount(particles,1000);
instance = vs->instance_create2(particles,scenario);
camera = vs->camera_create();
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,20 ) ) );
/*
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
light = vs->instance_create2( lightaux );
*/
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
light = vs->instance_create2( lightaux, scenario );
ofs=0;
quit=false;
}
virtual bool idle(float p_time) {
return false;
}
virtual bool iteration(float p_time) {
// VisualServer *vs=VisualServer::get_singleton();
ofs+=p_time;
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

View File

@ -1,43 +0,0 @@
/*************************************************************************/
/* test_particles.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 TEST_PARTICLES_H
#define TEST_PARTICLES_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestParticles {
MainLoop* test();
}
#endif

View File

@ -138,10 +138,6 @@ protected:
/* SPHERE SHAPE */
RID sphere_mesh = vs->make_sphere_mesh(10,20,0.5);
RID sphere_material = vs->fixed_material_create();
//vs->material_set_flag( sphere_material, VisualServer::MATERIAL_FLAG_WIREFRAME, true );
vs->fixed_material_set_param( sphere_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.7,0.8,3.0) );
vs->mesh_surface_set_material( sphere_mesh, 0, sphere_material );
type_mesh_map[PhysicsServer::SHAPE_SPHERE]=sphere_mesh;
RID sphere_shape=ps->shape_create(PhysicsServer::SHAPE_SPHERE);
@ -151,12 +147,9 @@ protected:
/* BOX SHAPE */
DVector<Plane> box_planes = Geometry::build_box_planes(Vector3(0.5,0.5,0.5));
RID box_material = vs->fixed_material_create();
vs->fixed_material_set_param( box_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.2,0.2) );
RID box_mesh = vs->mesh_create();
Geometry::MeshData box_data = Geometry::build_convex_mesh(box_planes);
vs->mesh_add_surface_from_mesh_data(box_mesh,box_data);
vs->mesh_surface_set_material( box_mesh, 0, box_material );
type_mesh_map[PhysicsServer::SHAPE_BOX]=box_mesh;
RID box_shape=ps->shape_create(PhysicsServer::SHAPE_BOX);
@ -167,13 +160,11 @@ protected:
/* CAPSULE SHAPE */
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,0.7,12,Vector3::AXIS_Z);
RID capsule_material = vs->fixed_material_create();
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.3,0.4,1.0) );
RID capsule_mesh = vs->mesh_create();
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);
@ -186,14 +177,12 @@ protected:
/* CONVEX SHAPE */
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,5,Vector3::AXIS_Z);
RID convex_material = vs->fixed_material_create();
vs->fixed_material_set_param( convex_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
RID convex_mesh = vs->mesh_create();
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
QuickHull::build(convex_data.vertices,convex_data);
vs->mesh_add_surface_from_mesh_data(convex_mesh,convex_data);
vs->mesh_surface_set_material( convex_mesh, 0, convex_material );
type_mesh_map[PhysicsServer::SHAPE_CONVEX_POLYGON]=convex_mesh;
RID convex_shape=ps->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON);
@ -223,11 +212,9 @@ protected:
d.resize(VS::ARRAY_MAX);
d[VS::ARRAY_VERTEX]=p_faces;
d[VS::ARRAY_NORMAL]=normals;
vs->mesh_add_surface(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, d );
RID trimesh_mat = vs->fixed_material_create();
vs->fixed_material_set_param( trimesh_mat, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.5,0.8));
vs->mesh_add_surface_from_arrays(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, d );
//vs->material_set_flag( trimesh_mat, VisualServer::MATERIAL_FLAG_UNSHADED,true);
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
RID triins = vs->instance_create2(trimesh_mesh,scenario);
@ -464,7 +451,7 @@ public:
}
virtual bool iteration(float p_time) {
if (mover) {
if (mover.is_valid()) {
static float joy_speed = 10;
PhysicsServer * ps = PhysicsServer::get_singleton();
Transform t = ps->body_get_state(mover,PhysicsServer::BODY_STATE_TRANSFORM);
@ -548,15 +535,10 @@ public:
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,1,12,5,Vector3::AXIS_Y);
RID capsule_material = vs->fixed_material_create();
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1,1,1) );
RID capsule_mesh = vs->mesh_create();
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);

View File

@ -85,7 +85,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
Image image(32,2,0,Image::FORMAT_GRAYSCALE_ALPHA,pixels);
Image image(32,2,0,Image::FORMAT_LA8,pixels);
body_shape_data[Physics2DServer::SHAPE_SEGMENT].image=vs->texture_create_from_image(image);
@ -113,7 +113,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
Image image(32,32,0,Image::FORMAT_GRAYSCALE_ALPHA,pixels);
Image image(32,32,0,Image::FORMAT_LA8,pixels);
body_shape_data[Physics2DServer::SHAPE_CIRCLE].image=vs->texture_create_from_image(image);
@ -141,7 +141,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
Image image(32,32,0,Image::FORMAT_GRAYSCALE_ALPHA,pixels);
Image image(32,32,0,Image::FORMAT_LA8,pixels);
body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image=vs->texture_create_from_image(image);
@ -173,7 +173,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
Image image(32,64,0,Image::FORMAT_GRAYSCALE_ALPHA,pixels);
Image image(32,64,0,Image::FORMAT_LA8,pixels);
body_shape_data[Physics2DServer::SHAPE_CAPSULE].image=vs->texture_create_from_image(image);
@ -381,7 +381,7 @@ public:
RID vp = vs->viewport_create();
canvas = vs->canvas_create();
vs->viewport_attach_canvas(vp,canvas);
vs->viewport_attach_to_screen(vp);
vs->viewport_attach_to_screen(vp,Rect2(Vector2(),OS::get_singleton()->get_window_size()));
Matrix32 smaller;
//smaller.scale(Vector2(0.6,0.6));
//smaller.elements[2]=Vector2(100,0);

View File

@ -1,56 +0,0 @@
/*************************************************************************/
/* test_python.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 "test_python.h"
#ifdef PYTHON_ENABLED
#include "Python.h"
#include "print_string.h"
namespace TestPython {
void test() {
print_line("testing python");
PyRun_SimpleString("import engine\n");
PyRun_SimpleString("def test(self):\n\tprint(\"noway\")\n");
PyRun_SimpleString("a=engine.ObjectPtr()\n");
PyRun_SimpleString("a.noway(22,'hello')\n");
PyRun_SimpleString("a.normalize()\n");
PyRun_SimpleString("class Moch(engine.ObjectPtr):\n\tdef mooch(self):\n\t\tprint('muchi')\n");
PyRun_SimpleString("b=Moch();\n");
PyRun_SimpleString("b.mooch();\n");
PyRun_SimpleString("b.meis();\n");
}
}
#endif

View File

@ -1,43 +0,0 @@
/*************************************************************************/
/* test_python.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 TEST_PYTHON_H
#define TEST_PYTHON_H
#ifdef PYTHON_ENABLED
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
namespace TestPython {
void test();
}
#endif
#endif

View File

@ -173,7 +173,7 @@ public:
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_to_screen(viewport);
vs->viewport_attach_to_screen(viewport,Rect2(Vector2(),OS::get_singleton()->get_window_size()));
vs->viewport_attach_camera( viewport, camera );
vs->viewport_set_scenario( viewport, scenario );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,3,30 ) ) );
@ -192,7 +192,7 @@ public:
//*
lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,1.0) );
vs->light_set_color( lightaux, Color(1.0,1.0,1.0) );
//vs->light_set_shadow( lightaux, true );
light = vs->instance_create2( lightaux, scenario );
Transform lla;
@ -205,8 +205,8 @@ public:
//*
lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,1.0) );
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,0.0) );
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_RADIUS, 4 );
vs->light_set_color( lightaux, Color(1.0,1.0,0.0) );
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_RANGE, 4 );
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_ENERGY, 8 );
//vs->light_set_shadow( lightaux, true );
//light = vs->instance_create( lightaux );

View File

@ -37,9 +37,9 @@
#include "scene/gui/text_edit.h"
#include "print_string.h"
#include "servers/visual/shader_language.h"
#include "drivers/gles2/shader_compiler_gles2.h"
//#include "drivers/gles2/shader_compiler_gles2.h"
#if 0
typedef ShaderLanguage SL;
namespace TestShaderLang {
@ -323,7 +323,7 @@ MainLoop* test() {
if (!err) {
print_line(rcode);
}
#if 0
ShaderCompilerGLES2 comp;
String codeline,globalsline;
SL::VarInfo vi;
@ -333,6 +333,18 @@ MainLoop* test() {
ShaderCompilerGLES2::Flags fl;
comp.compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,codeline,globalsline,fl);
#endif
return NULL;
}
}
#endif
typedef ShaderLanguage SL;
namespace TestShaderLang {
MainLoop* test() {
return NULL;
}

View File

@ -657,37 +657,37 @@ static Variant _decode_variant(const String& p_string) {
String format=params[0].strip_edges();
Image::Format imgformat;
/*
if (format=="grayscale") {
imgformat=Image::FORMAT_GRAYSCALE;
imgformat=Image::FORMAT_L8;
} else if (format=="intensity") {
imgformat=Image::FORMAT_INTENSITY;
} else if (format=="grayscale_alpha") {
imgformat=Image::FORMAT_GRAYSCALE_ALPHA;
imgformat=Image::FORMAT_LA8;
} else if (format=="rgb") {
imgformat=Image::FORMAT_RGB;
imgformat=Image::FORMAT_RGB8;
} else if (format=="rgba") {
imgformat=Image::FORMAT_RGBA;
imgformat=Image::FORMAT_RGBA8;
} else if (format=="indexed") {
imgformat=Image::FORMAT_INDEXED;
} else if (format=="indexed_alpha") {
imgformat=Image::FORMAT_INDEXED_ALPHA;
} else if (format=="bc1") {
imgformat=Image::FORMAT_BC1;
imgformat=Image::FORMAT_DXT1;
} else if (format=="bc2") {
imgformat=Image::FORMAT_BC2;
imgformat=Image::FORMAT_DXT3;
} else if (format=="bc3") {
imgformat=Image::FORMAT_BC3;
imgformat=Image::FORMAT_DXT5;
} else if (format=="bc4") {
imgformat=Image::FORMAT_BC4;
imgformat=Image::FORMAT_ATI1;
} else if (format=="bc5") {
imgformat=Image::FORMAT_BC5;
imgformat=Image::FORMAT_ATI2;
} else if (format=="custom") {
imgformat=Image::FORMAT_CUSTOM;
} else {
ERR_FAIL_V( Image() );
}
}*/
int mipmaps=params[1].to_int();
int w=params[2].to_int();
@ -974,26 +974,30 @@ static String _encode_variant(const Variant& p_variant) {
if (!img.empty()) {
String format;
/*
switch(img.get_format()) {
case Image::FORMAT_GRAYSCALE: format="grayscale"; break;
case Image::FORMAT_L8: format="grayscale"; break;
case Image::FORMAT_INTENSITY: format="intensity"; break;
case Image::FORMAT_GRAYSCALE_ALPHA: format="grayscale_alpha"; break;
case Image::FORMAT_RGB: format="rgb"; break;
case Image::FORMAT_RGBA: format="rgba"; break;
case Image::FORMAT_LA8: format="grayscale_alpha"; break;
case Image::FORMAT_RGB8: format="rgb"; break;
case Image::FORMAT_RGBA8: format="rgba"; break;
case Image::FORMAT_INDEXED : format="indexed"; break;
case Image::FORMAT_INDEXED_ALPHA: format="indexed_alpha"; break;
case Image::FORMAT_BC1: format="bc1"; break;
case Image::FORMAT_BC2: format="bc2"; break;
case Image::FORMAT_BC3: format="bc3"; break;
case Image::FORMAT_BC4: format="bc4"; break;
case Image::FORMAT_BC5: format="bc5"; break;
case Image::FORMAT_DXT1: format="bc1"; break;
case Image::FORMAT_DXT3: format="bc2"; break;
case Image::FORMAT_DXT5: format="bc3"; break;
case Image::FORMAT_ATI1: format="bc4"; break;
case Image::FORMAT_ATI2: format="bc5"; break;
case Image::FORMAT_CUSTOM: format="custom custom_size="+itos(img.get_data().size())+""; break;
default: {}
}
*/
str+=format+", ";
str+=itos(img.get_mipmaps())+", ";
str+=itos(img.has_mipmaps())+", ";
str+=itos(img.get_width())+", ";
str+=itos(img.get_height())+", ";
DVector<uint8_t> data = img.get_data();
@ -1399,6 +1403,7 @@ void Globals::set_custom_property_info(const String& p_prop,const PropertyInfo&
ERR_FAIL_COND(!props.has(p_prop));
custom_prop_info[p_prop]=p_info;
custom_prop_info[p_prop].name=p_prop;
}

File diff suppressed because it is too large Load Diff

View File

@ -55,35 +55,44 @@ public:
static SavePNGFunc save_png_func;
enum Format {
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
FORMAT_INTENSITY, ///< one byte per pixel, 0-255
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
FORMAT_RGB, ///< one byte R, one byte G, one byte B
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
FORMAT_YUV_422,
FORMAT_YUV_444,
FORMAT_BC1, // DXT1
FORMAT_BC2, // DXT3
FORMAT_BC3, // DXT5
FORMAT_BC4, // ATI1
FORMAT_BC5, // ATI2
FORMAT_PVRTC2,
FORMAT_PVRTC2_ALPHA,
FORMAT_PVRTC4,
FORMAT_PVRTC4_ALPHA,
FORMAT_ETC, // regular ETC, no transparency
FORMAT_ATC,
FORMAT_ATC_ALPHA_EXPLICIT,
FORMAT_ATC_ALPHA_INTERPOLATED,
/*FORMAT_ETC2_R, for the future..
FORMAT_ETC2_RG,
FORMAT_ETC2_RGB,
FORMAT_ETC2_RGBA1,
FORMAT_ETC2_RGBA,*/
FORMAT_CUSTOM,
FORMAT_L8, //luminance
FORMAT_LA8, //luminance-alpha
FORMAT_R8,
FORMAT_RG8,
FORMAT_RGB8,
FORMAT_RGBA8,
FORMAT_RGB565, //16 bit
FORMAT_RGBA4444,
FORMAT_RGBA5551,
FORMAT_RF, //float
FORMAT_RGF,
FORMAT_RGBF,
FORMAT_RGBAF,
FORMAT_RH, //half float
FORMAT_RGH,
FORMAT_RGBH,
FORMAT_RGBAH,
FORMAT_DXT1, //s3tc bc1
FORMAT_DXT3, //bc2
FORMAT_DXT5, //bc3
FORMAT_ATI1, //bc4
FORMAT_ATI2, //bc5
FORMAT_BPTC_RGBA, //btpc bc6h
FORMAT_BPTC_RGBF, //float /
FORMAT_BPTC_RGBFU, //unsigned float
FORMAT_PVRTC2, //pvrtc
FORMAT_PVRTC2A,
FORMAT_PVRTC4,
FORMAT_PVRTC4A,
FORMAT_ETC, //etc1
FORMAT_ETC2_R11, //etc2
FORMAT_ETC2_R11S, //signed, NOT srgb.
FORMAT_ETC2_RG11,
FORMAT_ETC2_RG11S,
FORMAT_ETC2_RGB8,
FORMAT_ETC2_RGBA8,
FORMAT_ETC2_RGB8A1,
FORMAT_MAX
};
@ -96,15 +105,21 @@ public:
/* INTERPOLATE GAUSS */
};
//some functions provided by something else
static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
static Image (*_jpg_mem_loader_func)(const uint8_t* p_png,int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
static void (*_image_compress_etc_func)(Image *);
static void (*_image_compress_etc2_func)(Image *);
static void (*_image_decompress_pvrtc)(Image *);
static void (*_image_decompress_bc)(Image *);
static void (*_image_decompress_etc)(Image *);
static void (*_image_decompress_etc2)(Image *);
Error _decompress_bc();
@ -114,92 +129,19 @@ public:
static Image (*lossless_unpacker)(const DVector<uint8_t>& p_buffer);
private:
//internal byte based color
struct BColor {
union {
uint8_t col[4];
struct {
uint8_t r,g,b,a;
};
};
bool operator==(const BColor& p_color) const { for(int i=0;i<4;i++) {if (col[i]!=p_color.col[i]) return false; } return true; }
_FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0])+uint16_t(col[1])+uint16_t(col[2]))/3; }
_FORCE_INLINE_ BColor() {}
BColor(uint8_t p_r,uint8_t p_g,uint8_t p_b,uint8_t p_a=255) { col[0]=p_r; col[1]=p_g; col[2]=p_b; col[3]=p_a; }
};
//median cut classes
struct BColorPos {
uint32_t index;
BColor color;
struct SortR {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.r < cb.color.r; }
};
struct SortG {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.g < cb.color.g; }
};
struct SortB {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.b < cb.color.b; }
};
struct SortA {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.a < cb.color.a; }
};
};
struct SPTree {
bool leaf;
uint8_t split_plane;
uint8_t split_value;
union {
int left;
int color;
};
int right;
SPTree() { leaf=true; left=-1; right=-1;}
};
struct MCBlock {
BColorPos min_color,max_color;
BColorPos *colors;
int sp_idx;
int color_count;
int get_longest_axis_index() const;
int get_longest_axis_length() const;
bool operator<(const MCBlock& p_block) const;
void shrink();
MCBlock();
MCBlock(BColorPos *p_colors,int p_color_count);
};
Format format;
DVector<uint8_t> data;
int width,height,mipmaps;
int width,height;
bool mipmaps;
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ void _put_pixelw(int p_x,int p_y, int p_width, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap,int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
_FORCE_INLINE_ static void _get_format_min_data_size(Format p_format,int &r_w, int &r_h);
static int _get_dst_image_size(int p_width, int p_height, Format p_format,int &r_mipmaps,int p_mipmaps=-1);
bool _can_modify(Format p_format) const;
_FORCE_INLINE_ void _put_pixelb(int p_x,int p_y, uint32_t p_pixelsize,uint8_t *p_dst,const uint8_t *p_src);
_FORCE_INLINE_ void _get_pixelb(int p_x,int p_y, uint32_t p_pixelsize,const uint8_t *p_src,uint8_t *p_dst);
public:
@ -207,20 +149,11 @@ public:
int get_width() const; ///< Get image width
int get_height() const; ///< Get image height
int get_mipmaps() const;
bool has_mipmaps() const;
int get_mipmap_count() const;
/**
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
* value.
*/
Color get_pixel(int p_x,int p_y,int p_mipmap=0) const;
/**
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
*/
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
/**
* Convert the image to another format, as close as it can be done.
* Convert the image to another format, conversion only to raw byte format
*/
void convert( Format p_new_format );
@ -259,25 +192,21 @@ public:
void flip_x();
void flip_y();
/**
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
Error generate_mipmaps(bool p_keep_existing=false);
void clear_mipmaps();
/**
* Generate a normal map from a grayscale image
*/
void make_normalmap(float p_height_scale=1.0);
/**
* Create a new image of a given size and format. Current image will be lost
*/
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
void create( const char ** p_xpm );
/**
@ -301,7 +230,7 @@ public:
/**
* import an image of a specific size and format from a pointer
*/
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
enum AlphaMode {
ALPHA_NONE,
@ -312,32 +241,27 @@ public:
AlphaMode detect_alpha() const;
bool is_invisible() const;
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap=0);
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
void set_pallete(const DVector<uint8_t>& p_data);
static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format);
static int get_format_pallete_size(Format p_format);
static void get_format_min_pixel_size(Format p_format,int &r_w, int &r_h);
static int get_image_data_size(int p_width, int p_height, Format p_format,int p_mipmaps=0);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
bool operator==(const Image& p_image) const;
void quantize();
enum CompressMode {
COMPRESS_BC,
COMPRESS_16BIT,
COMPRESS_S3TC,
COMPRESS_PVRTC2,
COMPRESS_PVRTC4,
COMPRESS_ETC
COMPRESS_ETC,
COMPRESS_ETC2
};
Error compress(CompressMode p_mode=COMPRESS_BC);
Error compress(CompressMode p_mode=COMPRESS_S3TC);
Image compressed(int p_mode); /* from the Image::CompressMode enum */
Error decompress();
Image decompressed() const;
@ -349,8 +273,6 @@ public:
void normalmap_to_xy();
void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest);
void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest);
Image brushed(const Image& p_src, const Image& p_brush, const Point2& p_dest) const;
Rect2 get_used_rect() const;
Image get_rect(const Rect2& p_area) const;

View File

@ -1,365 +0,0 @@
/*************************************************************************/
/* image_quantize.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 "image.h"
#include <stdio.h>
#include "print_string.h"
#ifdef TOOLS_ENABLED
#include "set.h"
#include "sort.h"
#include "os/os.h"
//#define QUANTIZE_SPEED_OVER_QUALITY
Image::MCBlock::MCBlock() {
}
Image::MCBlock::MCBlock(BColorPos *p_colors,int p_color_count) {
colors=p_colors;
color_count=p_color_count;
min_color.color=BColor(255,255,255,255);
max_color.color=BColor(0,0,0,0);
shrink();
}
int Image::MCBlock::get_longest_axis_index() const {
int max_dist=-1;
int max_index=0;
for(int i=0;i<4;i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_index=i;
max_dist=d;
}
}
return max_index;
}
int Image::MCBlock::get_longest_axis_length() const {
int max_dist=-1;
for(int i=0;i<4;i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_dist=d;
}
}
return max_dist;
}
bool Image::MCBlock::operator<(const MCBlock& p_block) const {
int alen = get_longest_axis_length();
int blen = p_block.get_longest_axis_length();
if (alen==blen) {
return colors < p_block.colors;
} else
return alen < blen;
}
void Image::MCBlock::shrink() {
min_color=colors[0];
max_color=colors[0];
for(int i=1;i<color_count;i++) {
for(int j=0;j<4;j++) {
min_color.color.col[j]=MIN(min_color.color.col[j],colors[i].color.col[j]);
max_color.color.col[j]=MAX(max_color.color.col[j],colors[i].color.col[j]);
}
}
}
void Image::quantize() {
bool has_alpha = detect_alpha()!=ALPHA_NONE;
bool quantize_fast=OS::get_singleton()->has_environment("QUANTIZE_FAST");
convert(FORMAT_RGBA);
ERR_FAIL_COND( format!=FORMAT_RGBA );
DVector<uint8_t> indexed_data;
{
int color_count = data.size()/4;
ERR_FAIL_COND(color_count==0);
Set<MCBlock> block_queue;
DVector<BColorPos> data_colors;
data_colors.resize(color_count);
DVector<BColorPos>::Write dcw=data_colors.write();
DVector<uint8_t>::Read dr = data.read();
const BColor * drptr=(const BColor*)&dr[0];
BColorPos *bcptr=&dcw[0];
{
for(int i=0;i<color_count;i++) {
//uint32_t data_ofs=i<<2;
bcptr[i].color=drptr[i];//BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
bcptr[i].index=i;
}
}
//printf("color count: %i\n",color_count);
/*
for(int i=0;i<color_count;i++) {
BColor bc = ((BColor*)&wb[0])[i];
printf("%i - %i,%i,%i,%i\n",i,bc.r,bc.g,bc.b,bc.a);
}*/
MCBlock initial_block((BColorPos*)&dcw[0],color_count);
block_queue.insert(initial_block);
while( block_queue.size() < 256 && block_queue.back()->get().color_count > 1 ) {
MCBlock longest = block_queue.back()->get();
//printf("longest: %i (%i)\n",longest.get_longest_axis_index(),longest.get_longest_axis_length());
block_queue.erase(block_queue.back());
BColorPos *first = longest.colors;
BColorPos *median = longest.colors + (longest.color_count+1)/2;
BColorPos *end = longest.colors + longest.color_count;
#if 0
int lai =longest.get_longest_axis_index();
switch(lai) {
#if 0
case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.sort(first,end-first); } break;
case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.sort(first,end-first); } break;
case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.sort(first,end-first); } break;
case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.sort(first,end-first); } break;
#else
case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break;
#endif
}
//avoid same color from being split in 2
//search forward and flip
BColorPos *median_end=median;
BColorPos *p=median_end+1;
while(p!=end) {
if (median_end->color==p->color) {
SWAP(*(median_end+1),*p);
median_end++;
}
p++;
}
//search backward and flip
BColorPos *median_begin=median;
p=median_begin-1;
while(p!=(first-1)) {
if (median_begin->color==p->color) {
SWAP(*(median_begin-1),*p);
median_begin--;
}
p--;
}
if (first < median_begin) {
median=median_begin;
} else if (median_end < end-1) {
median=median_end+1;
} else {
break; //shouldn't have arrived here, since it means all pixels are equal, but wathever
}
MCBlock left(first,median-first);
MCBlock right(median,end-median);
block_queue.insert(left);
block_queue.insert(right);
#else
switch(longest.get_longest_axis_index()) {
case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break;
}
MCBlock left(first,median-first);
MCBlock right(median,end-median);
block_queue.insert(left);
block_queue.insert(right);
#endif
}
while(block_queue.size() > 256) {
block_queue.erase(block_queue.front());// erase least significant
}
int res_colors=0;
int comp_size = (has_alpha?4:3);
indexed_data.resize(color_count + 256*comp_size);
DVector<uint8_t>::Write iw = indexed_data.write();
uint8_t *iwptr=&iw[0];
BColor pallete[256];
// print_line("applying quantization - res colors "+itos(block_queue.size()));
while(block_queue.size()) {
const MCBlock &b = block_queue.back()->get();
uint64_t sum[4]={0,0,0,0};
for(int i=0;i<b.color_count;i++) {
sum[0]+=b.colors[i].color.col[0];
sum[1]+=b.colors[i].color.col[1];
sum[2]+=b.colors[i].color.col[2];
sum[3]+=b.colors[i].color.col[3];
}
BColor c( sum[0]/b.color_count, sum[1]/b.color_count, sum[2]/b.color_count, sum[3]/b.color_count );
//printf(" %i: %i,%i,%i,%i out of %i\n",res_colors,c.r,c.g,c.b,c.a,b.color_count);
for(int i=0;i<comp_size;i++) {
iwptr[ color_count + res_colors * comp_size + i ] = c.col[i];
}
if (quantize_fast) {
for(int i=0;i<b.color_count;i++) {
iwptr[b.colors[i].index]=res_colors;
}
} else {
pallete[res_colors]=c;
}
res_colors++;
block_queue.erase(block_queue.back());
}
if (!quantize_fast) {
for(int i=0;i<color_count;i++) {
const BColor &c=drptr[i];
uint8_t best_dist_idx=0;
uint32_t dist=0xFFFFFFFF;
for(int j=0;j<res_colors;j++) {
const BColor &pc=pallete[j];
uint32_t d = 0;
{ int16_t v = (int16_t)c.r-(int16_t)pc.r; d+=v*v; }
{ int16_t v = (int16_t)c.g-(int16_t)pc.g; d+=v*v; }
{ int16_t v = (int16_t)c.b-(int16_t)pc.b; d+=v*v; }
{ int16_t v = (int16_t)c.a-(int16_t)pc.a; d+=v*v; }
if (d<=dist) {
best_dist_idx=j;
dist=d;
}
}
iwptr[ i ] = best_dist_idx;
}
}
//iw = DVector<uint8_t>::Write();
//dr = DVector<uint8_t>::Read();
//wb = DVector<uint8_t>::Write();
}
print_line(itos(indexed_data.size()));
data=indexed_data;
format=has_alpha?FORMAT_INDEXED_ALPHA:FORMAT_INDEXED;
} //do none
#else
void Image::quantize() {} //do none
#endif

View File

@ -1060,7 +1060,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
if (buf) {
encode_uint32(image.get_format(),&buf[0]);
encode_uint32(image.get_mipmaps(),&buf[4]);
encode_uint32(image.has_mipmaps(),&buf[4]);
encode_uint32(image.get_width(),&buf[8]);
encode_uint32(image.get_height(),&buf[12]);
int ds=data.size();

View File

@ -74,29 +74,6 @@ enum {
IMAGE_ENCODING_LOSSLESS=2,
IMAGE_ENCODING_LOSSY=3,
IMAGE_FORMAT_GRAYSCALE=0,
IMAGE_FORMAT_INTENSITY=1,
IMAGE_FORMAT_GRAYSCALE_ALPHA=2,
IMAGE_FORMAT_RGB=3,
IMAGE_FORMAT_RGBA=4,
IMAGE_FORMAT_INDEXED=5,
IMAGE_FORMAT_INDEXED_ALPHA=6,
IMAGE_FORMAT_BC1=7,
IMAGE_FORMAT_BC2=8,
IMAGE_FORMAT_BC3=9,
IMAGE_FORMAT_BC4=10,
IMAGE_FORMAT_BC5=11,
IMAGE_FORMAT_PVRTC2=12,
IMAGE_FORMAT_PVRTC2_ALPHA=13,
IMAGE_FORMAT_PVRTC4=14,
IMAGE_FORMAT_PVRTC4_ALPHA=15,
IMAGE_FORMAT_ETC=16,
IMAGE_FORMAT_ATC=17,
IMAGE_FORMAT_ATC_ALPHA_EXPLICIT=18,
IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED=19,
IMAGE_FORMAT_CUSTOM=30,
OBJECT_EMPTY=0,
OBJECT_EXTERNAL_RESOURCE=1,
OBJECT_INTERNAL_RESOURCE=2,
@ -269,38 +246,22 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
uint32_t height = f->get_32();
uint32_t mipmaps = f->get_32();
uint32_t format = f->get_32();
Image::Format fmt;
switch(format) {
const uint32_t format_version_shift=24;
const uint32_t format_version_mask=format_version_shift-1;
case IMAGE_FORMAT_GRAYSCALE: { fmt=Image::FORMAT_GRAYSCALE; } break;
case IMAGE_FORMAT_INTENSITY: { fmt=Image::FORMAT_INTENSITY; } break;
case IMAGE_FORMAT_GRAYSCALE_ALPHA: { fmt=Image::FORMAT_GRAYSCALE_ALPHA; } break;
case IMAGE_FORMAT_RGB: { fmt=Image::FORMAT_RGB; } break;
case IMAGE_FORMAT_RGBA: { fmt=Image::FORMAT_RGBA; } break;
case IMAGE_FORMAT_INDEXED: { fmt=Image::FORMAT_INDEXED; } break;
case IMAGE_FORMAT_INDEXED_ALPHA: { fmt=Image::FORMAT_INDEXED_ALPHA; } break;
case IMAGE_FORMAT_BC1: { fmt=Image::FORMAT_BC1; } break;
case IMAGE_FORMAT_BC2: { fmt=Image::FORMAT_BC2; } break;
case IMAGE_FORMAT_BC3: { fmt=Image::FORMAT_BC3; } break;
case IMAGE_FORMAT_BC4: { fmt=Image::FORMAT_BC4; } break;
case IMAGE_FORMAT_BC5: { fmt=Image::FORMAT_BC5; } break;
case IMAGE_FORMAT_PVRTC2: { fmt=Image::FORMAT_PVRTC2; } break;
case IMAGE_FORMAT_PVRTC2_ALPHA: { fmt=Image::FORMAT_PVRTC2_ALPHA; } break;
case IMAGE_FORMAT_PVRTC4: { fmt=Image::FORMAT_PVRTC4; } break;
case IMAGE_FORMAT_PVRTC4_ALPHA: { fmt=Image::FORMAT_PVRTC4_ALPHA; } break;
case IMAGE_FORMAT_ETC: { fmt=Image::FORMAT_ETC; } break;
case IMAGE_FORMAT_ATC: { fmt=Image::FORMAT_ATC; } break;
case IMAGE_FORMAT_ATC_ALPHA_EXPLICIT: { fmt=Image::FORMAT_ATC_ALPHA_EXPLICIT; } break;
case IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED: { fmt=Image::FORMAT_ATC_ALPHA_INTERPOLATED; } break;
case IMAGE_FORMAT_CUSTOM: { fmt=Image::FORMAT_CUSTOM; } break;
default: {
uint32_t format_version = format>>format_version_shift;
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
const uint32_t current_version = 0;
if (format_version>current_version) {
ERR_PRINT("Format version for encoded binary image is too new");
return ERR_PARSE_ERROR;
}
Image::Format fmt=Image::Format(format&format_version_mask); //if format changes, we can add a compatibility bit on top
uint32_t datalen = f->get_32();
DVector<uint8_t> imgdata;
@ -1599,7 +1560,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
int encoding=IMAGE_ENCODING_RAW;
float quality=0.7;
if (val.get_format() <= Image::FORMAT_INDEXED_ALPHA) {
if (!val.is_compressed()) {
//can only compress uncompressed stuff
if (p_hint.hint==PROPERTY_HINT_IMAGE_COMPRESS_LOSSY && Image::lossy_packer) {
@ -1621,33 +1582,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
f->store_32(val.get_width());
f->store_32(val.get_height());
f->store_32(val.get_mipmaps());
switch(val.get_format()) {
case Image::FORMAT_GRAYSCALE: f->store_32(IMAGE_FORMAT_GRAYSCALE ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
case Image::FORMAT_INTENSITY: f->store_32(IMAGE_FORMAT_INTENSITY ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
case Image::FORMAT_GRAYSCALE_ALPHA: f->store_32(IMAGE_FORMAT_GRAYSCALE_ALPHA ); break; ///< two bytes per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255. alpha 0-255
case Image::FORMAT_RGB: f->store_32(IMAGE_FORMAT_RGB ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B
case Image::FORMAT_RGBA: f->store_32(IMAGE_FORMAT_RGBA ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B: f->store_32(IMAGE_FORMAT_ ); break; one byte A
case Image::FORMAT_INDEXED: f->store_32(IMAGE_FORMAT_INDEXED ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*3 bytes of palette
case Image::FORMAT_INDEXED_ALPHA: f->store_32(IMAGE_FORMAT_INDEXED_ALPHA ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*4 bytes of palette (alpha)
case Image::FORMAT_BC1: f->store_32(IMAGE_FORMAT_BC1 ); break; // DXT1
case Image::FORMAT_BC2: f->store_32(IMAGE_FORMAT_BC2 ); break; // DXT3
case Image::FORMAT_BC3: f->store_32(IMAGE_FORMAT_BC3 ); break; // DXT5
case Image::FORMAT_BC4: f->store_32(IMAGE_FORMAT_BC4 ); break; // ATI1
case Image::FORMAT_BC5: f->store_32(IMAGE_FORMAT_BC5 ); break; // ATI2
case Image::FORMAT_PVRTC2: f->store_32(IMAGE_FORMAT_PVRTC2 ); break;
case Image::FORMAT_PVRTC2_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC2_ALPHA ); break;
case Image::FORMAT_PVRTC4: f->store_32(IMAGE_FORMAT_PVRTC4 ); break;
case Image::FORMAT_PVRTC4_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC4_ALPHA ); break;
case Image::FORMAT_ETC: f->store_32(IMAGE_FORMAT_ETC); break;
case Image::FORMAT_ATC: f->store_32(IMAGE_FORMAT_ATC); break;
case Image::FORMAT_ATC_ALPHA_EXPLICIT: f->store_32(IMAGE_FORMAT_ATC_ALPHA_EXPLICIT); break;
case Image::FORMAT_ATC_ALPHA_INTERPOLATED: f->store_32(IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED); break;
case Image::FORMAT_CUSTOM: f->store_32(IMAGE_FORMAT_CUSTOM ); break;
default: {}
}
f->store_32(val.has_mipmaps());
f->store_32(val.get_format()); //if format changes we can add a compatibility version bit
int dlen = val.get_data().size();
f->store_32(dlen);

View File

@ -553,39 +553,39 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
Image::Format imgformat;
/*
if (format=="grayscale") {
imgformat=Image::FORMAT_GRAYSCALE;
imgformat=Image::FORMAT_L8;
} else if (format=="intensity") {
imgformat=Image::FORMAT_INTENSITY;
} else if (format=="grayscale_alpha") {
imgformat=Image::FORMAT_GRAYSCALE_ALPHA;
imgformat=Image::FORMAT_LA8;
} else if (format=="rgb") {
imgformat=Image::FORMAT_RGB;
imgformat=Image::FORMAT_RGB8;
} else if (format=="rgba") {
imgformat=Image::FORMAT_RGBA;
imgformat=Image::FORMAT_RGBA8;
} else if (format=="indexed") {
imgformat=Image::FORMAT_INDEXED;
} else if (format=="indexed_alpha") {
imgformat=Image::FORMAT_INDEXED_ALPHA;
} else if (format=="bc1") {
imgformat=Image::FORMAT_BC1;
imgformat=Image::FORMAT_DXT1;
} else if (format=="bc2") {
imgformat=Image::FORMAT_BC2;
imgformat=Image::FORMAT_DXT3;
} else if (format=="bc3") {
imgformat=Image::FORMAT_BC3;
imgformat=Image::FORMAT_DXT5;
} else if (format=="bc4") {
imgformat=Image::FORMAT_BC4;
imgformat=Image::FORMAT_ATI1;
} else if (format=="bc5") {
imgformat=Image::FORMAT_BC5;
imgformat=Image::FORMAT_ATI2;
} else if (format=="pvrtc2") {
imgformat=Image::FORMAT_PVRTC2;
} else if (format=="pvrtc2a") {
imgformat=Image::FORMAT_PVRTC2_ALPHA;
imgformat=Image::FORMAT_PVRTC2A;
} else if (format=="pvrtc4") {
imgformat=Image::FORMAT_PVRTC4;
} else if (format=="pvrtc4a") {
imgformat=Image::FORMAT_PVRTC4_ALPHA;
imgformat=Image::FORMAT_PVRTC4A;
} else if (format=="etc") {
imgformat=Image::FORMAT_ETC;
} else if (format=="atc") {
@ -599,7 +599,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
} else {
ERR_FAIL_V( ERR_FILE_CORRUPT );
}
}*/
int datasize;
@ -614,13 +614,6 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
return OK;
};
if (imgformat==Image::FORMAT_CUSTOM) {
datasize=custom_size;
} else {
datasize = Image::get_image_data_size(h,w,imgformat,mipmaps);
}
if (datasize==0) {
//r_v = Image(w, h, imgformat);
@ -2186,33 +2179,33 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
params+="encoding=\"raw\"";
params+=" width=\""+itos(img.get_width())+"\"";
params+=" height=\""+itos(img.get_height())+"\"";
params+=" mipmaps=\""+itos(img.get_mipmaps())+"\"";
params+=" mipmaps=\""+itos(img.has_mipmaps())+"\"";
/*
switch(img.get_format()) {
case Image::FORMAT_GRAYSCALE: params+=" format=\"grayscale\""; break;
case Image::FORMAT_L8: params+=" format=\"grayscale\""; break;
case Image::FORMAT_INTENSITY: params+=" format=\"intensity\""; break;
case Image::FORMAT_GRAYSCALE_ALPHA: params+=" format=\"grayscale_alpha\""; break;
case Image::FORMAT_RGB: params+=" format=\"rgb\""; break;
case Image::FORMAT_RGBA: params+=" format=\"rgba\""; break;
case Image::FORMAT_LA8: params+=" format=\"grayscale_alpha\""; break;
case Image::FORMAT_RGB8: params+=" format=\"rgb\""; break;
case Image::FORMAT_RGBA8: params+=" format=\"rgba\""; break;
case Image::FORMAT_INDEXED : params+=" format=\"indexed\""; break;
case Image::FORMAT_INDEXED_ALPHA: params+=" format=\"indexed_alpha\""; break;
case Image::FORMAT_BC1: params+=" format=\"bc1\""; break;
case Image::FORMAT_BC2: params+=" format=\"bc2\""; break;
case Image::FORMAT_BC3: params+=" format=\"bc3\""; break;
case Image::FORMAT_BC4: params+=" format=\"bc4\""; break;
case Image::FORMAT_BC5: params+=" format=\"bc5\""; break;
case Image::FORMAT_DXT1: params+=" format=\"bc1\""; break;
case Image::FORMAT_DXT3: params+=" format=\"bc2\""; break;
case Image::FORMAT_DXT5: params+=" format=\"bc3\""; break;
case Image::FORMAT_ATI1: params+=" format=\"bc4\""; break;
case Image::FORMAT_ATI2: params+=" format=\"bc5\""; break;
case Image::FORMAT_PVRTC2: params+=" format=\"pvrtc2\""; break;
case Image::FORMAT_PVRTC2_ALPHA: params+=" format=\"pvrtc2a\""; break;
case Image::FORMAT_PVRTC2A: params+=" format=\"pvrtc2a\""; break;
case Image::FORMAT_PVRTC4: params+=" format=\"pvrtc4\""; break;
case Image::FORMAT_PVRTC4_ALPHA: params+=" format=\"pvrtc4a\""; break;
case Image::FORMAT_PVRTC4A: params+=" format=\"pvrtc4a\""; break;
case Image::FORMAT_ETC: params+=" format=\"etc\""; break;
case Image::FORMAT_ATC: params+=" format=\"atc\""; break;
case Image::FORMAT_ATC_ALPHA_EXPLICIT: params+=" format=\"atcae\""; break;
case Image::FORMAT_ATC_ALPHA_INTERPOLATED: params+=" format=\"atcai\""; break;
case Image::FORMAT_CUSTOM: params+=" format=\"custom\" custom_size=\""+itos(img.get_data().size())+"\""; break;
default: {}
}
}*/
} break;
case Variant::NODE_PATH: type="node_path"; break;
case Variant::OBJECT: {

View File

@ -28,18 +28,16 @@
/*************************************************************************/
#include "rid.h"
static SafeRefCount current_id;
RID_Data::~RID_Data() {
}
SafeRefCount RID_OwnerBase::refcount;
void RID_OwnerBase::init_rid() {
current_id.init(1);
refcount.init();
}
ID RID_OwnerBase::new_ID() {
ID id = current_id.refval();
return id;
}

View File

@ -33,183 +33,189 @@
#include "safe_refcount.h"
#include "typedefs.h"
#include "os/memory.h"
#include "hash_map.h"
#include "set.h"
#include "list.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class RID_OwnerBase;
typedef uint32_t ID;
class RID_Data {
friend class RID_OwnerBase;
#ifndef DEBUG_ENABLED
RID_OwnerBase *_owner;
#endif
uint32_t _id;
public:
_FORCE_INLINE_ uint32_t get_id() const { return _id; }
virtual ~RID_Data();
};
class RID {
friend class RID_OwnerBase;
ID _id;
RID_OwnerBase *owner;
mutable RID_Data *_data;
public:
_FORCE_INLINE_ ID get_id() const { return _id; }
bool operator==(const RID& p_rid) const {
_FORCE_INLINE_ RID_Data *get_data() const { return _data; }
return _id==p_rid._id;
_FORCE_INLINE_ bool operator==(const RID& p_rid) const {
return _data==p_rid._data;
}
_FORCE_INLINE_ bool operator<(const RID& p_rid) const {
return _id < p_rid._id;
return _data < p_rid._data;
}
_FORCE_INLINE_ bool operator<=(const RID& p_rid) const {
return _id <= p_rid._id;
return _data <= p_rid._data;
}
_FORCE_INLINE_ bool operator>(const RID& p_rid) const {
return _id > p_rid._id;
return _data > p_rid._data;
}
bool operator!=(const RID& p_rid) const {
_FORCE_INLINE_ bool operator!=(const RID& p_rid) const {
return _id!=p_rid._id;
return _data!=p_rid._data;
}
_FORCE_INLINE_ bool is_valid() const { return _id>0; }
_FORCE_INLINE_ bool is_valid() const { return _data!=NULL; }
operator const void*() const {
return is_valid() ? this : 0;
};
_FORCE_INLINE_ uint32_t get_id() const { return _data?_data->get_id():0; }
_FORCE_INLINE_ RID() {
_id = 0;
owner=0;
_data=NULL;
}
};
class RID_OwnerBase {
protected:
friend class RID;
void set_id(RID& p_rid, ID p_id) const { p_rid._id=p_id; }
void set_ownage(RID& p_rid) const { p_rid.owner=const_cast<RID_OwnerBase*>(this); }
ID new_ID();
static SafeRefCount refcount;
_FORCE_INLINE_ void _set_data(RID& p_rid, RID_Data* p_data) {
p_rid._data=p_data;
refcount.ref();
p_data->_id=refcount.get();
#ifndef DEBUG_ENABLED
p_data->_owner=this;
#endif
}
#ifndef DEBUG_ENABLED
_FORCE_INLINE_ bool _is_owner(RID& p_rid) const {
return this==p_rid._owner;
}
_FORCE_INLINE_ void _remove_owner(RID& p_rid) {
return p_rid._owner=NULL;
}
#
#endif
public:
virtual bool owns(const RID& p_rid) const=0;
virtual void get_owned_list(List<RID> *p_owned) const=0;
virtual void get_owned_list(List<RID> *p_owned)=0;
static void init_rid();
virtual ~RID_OwnerBase() {}
};
template<class T,bool thread_safe=false>
template<class T>
class RID_Owner : public RID_OwnerBase {
public:
typedef void (*ReleaseNotifyFunc)(void*user,T *p_data);
private:
Mutex *mutex;
mutable HashMap<ID,T*> id_map;
#ifdef DEBUG_ENABLED
mutable Set<RID_Data*> id_map;
#endif
public:
RID make_rid(T * p_data) {
_FORCE_INLINE_ RID make_rid(T * p_data) {
if (thread_safe) {
mutex->lock();
}
ID id = new_ID();
id_map[id]=p_data;
RID rid;
set_id(rid,id);
set_ownage(rid);
_set_data(rid,p_data);
if (thread_safe) {
mutex->unlock();
}
#ifdef DEBUG_ENABLED
id_map.insert(p_data) ;
#endif
return rid;
}
_FORCE_INLINE_ T * get(const RID& p_rid) {
if (thread_safe) {
mutex->lock();
}
#ifdef DEBUG_ENABLED
T**elem = id_map.getptr(p_rid.get_id());
if (thread_safe) {
mutex->unlock();
}
ERR_FAIL_COND_V(!elem,NULL);
return *elem;
ERR_FAIL_COND_V(!p_rid.is_valid(),NULL);
ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()),NULL);
#endif
return static_cast<T*>(p_rid.get_data());
}
virtual bool owns(const RID& p_rid) const {
_FORCE_INLINE_ T * getornull(const RID& p_rid) {
if (thread_safe) {
mutex->lock();
}
T**elem = id_map.getptr(p_rid.get_id());
if (thread_safe) {
mutex->lock();
}
return elem!=NULL;
}
virtual void free(RID p_rid) {
if (thread_safe) {
mutex->lock();
}
ERR_FAIL_COND(!owns(p_rid));
id_map.erase(p_rid.get_id());
}
virtual void get_owned_list(List<RID> *p_owned) const {
if (thread_safe) {
mutex->lock();
}
const ID*id=NULL;
while((id=id_map.next(id))) {
RID rid;
set_id(rid,*id);
set_ownage(rid);
p_owned->push_back(rid);
}
if (thread_safe) {
mutex->lock();
}
}
RID_Owner() {
if (thread_safe) {
mutex = Mutex::create();
#ifdef DEBUG_ENABLED
if (p_rid.get_data()) {
ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()),NULL);
}
#endif
return static_cast<T*>(p_rid.get_data());
}
_FORCE_INLINE_ bool owns(const RID& p_rid) const {
~RID_Owner() {
if (thread_safe) {
memdelete(mutex);
}
if (p_rid.get_data()==NULL)
return false;
#ifdef DEBUG_ENABLED
return id_map.has(p_rid.get_data());
#else
return _is_owner(p_rid);
#endif
}
void free(RID p_rid) {
#ifdef DEBUG_ENABLED
id_map.erase(p_rid.get_data());
#else
_remove_owner(p_rid);
#endif
}
void get_owned_list(List<RID> *p_owned) {
#ifdef DEBUG_ENABLED
for (typename Set<RID_Data*>::Element *E=id_map.front();E;E=E->next()) {
RID r;
_set_data(r,static_cast<T*>(E->get()));
p_owned->push_back(r);
}
#endif
}
};

View File

@ -617,13 +617,9 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_PTR0R(Image,get_width);
VCALL_PTR0R(Image,get_height);
VCALL_PTR0R(Image,empty);
VCALL_PTR3R(Image,get_pixel);
VCALL_PTR4(Image, put_pixel);
VCALL_PTR0R(Image,get_used_rect);
VCALL_PTR3R(Image,brushed);
VCALL_PTR1R(Image,load);
VCALL_PTR1R(Image,save_png);
VCALL_PTR3(Image,brush_transfer);
VCALL_PTR1R(Image,get_rect);
VCALL_PTR1R(Image,compressed);
VCALL_PTR0R(Image,decompressed);
@ -1526,12 +1522,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC0(IMAGE, INT, Image, get_width, varray());
ADDFUNC0(IMAGE, INT, Image, get_height, varray());
ADDFUNC0(IMAGE, BOOL, Image, empty, varray());
ADDFUNC3(IMAGE, COLOR, Image, get_pixel, INT, "x", INT, "y", INT, "mipmap_level", varray(0));
ADDFUNC4(IMAGE, NIL, Image, put_pixel, INT, "x", INT, "y", COLOR, "color", INT, "mipmap_level", varray(0));
ADDFUNC3(IMAGE, IMAGE, Image, brushed, IMAGE, "src", IMAGE, "brush", VECTOR2, "pos", varray(0));
ADDFUNC1(IMAGE, INT, Image, load, STRING, "path", varray(0));
ADDFUNC1(IMAGE, INT, Image, save_png, STRING, "path", varray(0));
ADDFUNC3(IMAGE, NIL, Image, brush_transfer, IMAGE, "src", IMAGE, "brush", VECTOR2, "pos", varray(0));
ADDFUNC0(IMAGE, RECT2, Image, get_used_rect, varray(0));
ADDFUNC1(IMAGE, IMAGE, Image, get_rect, RECT2, "area", varray(0));
ADDFUNC1(IMAGE, IMAGE, Image, compressed, INT, "format", varray(0));
@ -1788,34 +1780,53 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
_VariantCall::add_constant(Variant::INPUT_EVENT,"ACTION",InputEvent::ACTION);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_BC",Image::COMPRESS_BC);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_16BIT",Image::COMPRESS_16BIT);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_S3TC",Image::COMPRESS_S3TC);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_PVRTC2",Image::COMPRESS_PVRTC2);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_PVRTC4",Image::COMPRESS_PVRTC4);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_ETC",Image::COMPRESS_ETC);
_VariantCall::add_constant(Variant::IMAGE,"COMPRESS_ETC2",Image::COMPRESS_ETC2);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_GRAYSCALE",Image::FORMAT_GRAYSCALE);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_INTENSITY",Image::FORMAT_INTENSITY);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_GRAYSCALE_ALPHA",Image::FORMAT_GRAYSCALE_ALPHA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB",Image::FORMAT_RGB);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA",Image::FORMAT_RGBA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_INDEXED",Image::FORMAT_INDEXED);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_INDEXED_ALPHA",Image::FORMAT_INDEXED_ALPHA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_YUV_422",Image::FORMAT_YUV_422);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_YUV_444",Image::FORMAT_YUV_444);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC1",Image::FORMAT_BC1);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC2",Image::FORMAT_BC2);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC3",Image::FORMAT_BC3);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC4",Image::FORMAT_BC4);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC5",Image::FORMAT_BC5);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_L8",Image::FORMAT_L8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_LA8",Image::FORMAT_LA8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_R8",Image::FORMAT_R8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RG8",Image::FORMAT_RG8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB8",Image::FORMAT_RGB8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA8",Image::FORMAT_RGBA8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB565",Image::FORMAT_RGB565);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA4444",Image::FORMAT_RGBA4444);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA5551",Image::FORMAT_DXT1);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RF",Image::FORMAT_RF);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGF",Image::FORMAT_RGF);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBF",Image::FORMAT_RGBF);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBAF",Image::FORMAT_RGBAF);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RH",Image::FORMAT_RH);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGH",Image::FORMAT_RGH);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBH",Image::FORMAT_RGBH);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBAH",Image::FORMAT_RGBAH);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT1",Image::FORMAT_DXT1);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT3",Image::FORMAT_DXT3);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT5",Image::FORMAT_DXT5);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATI1",Image::FORMAT_ATI1);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATI2",Image::FORMAT_ATI2);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBA",Image::FORMAT_BPTC_RGBA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBF",Image::FORMAT_BPTC_RGBF);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBFU",Image::FORMAT_BPTC_RGBFU);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2",Image::FORMAT_PVRTC2);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2_ALPHA",Image::FORMAT_PVRTC2_ALPHA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2A",Image::FORMAT_PVRTC2A);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4",Image::FORMAT_PVRTC4);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4_ALPHA",Image::FORMAT_PVRTC4_ALPHA);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4A",Image::FORMAT_PVRTC4A);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC",Image::FORMAT_ETC);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC",Image::FORMAT_ATC);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC_ALPHA_EXPLICIT",Image::FORMAT_ATC_ALPHA_EXPLICIT);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC_ALPHA_INTERPOLATED",Image::FORMAT_ATC_ALPHA_INTERPOLATED);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_CUSTOM",Image::FORMAT_CUSTOM);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_R11",Image::FORMAT_ETC2_R11);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_R11S",Image::FORMAT_ETC2_R11S);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RG11",Image::FORMAT_ETC2_RG11);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RG11S",Image::FORMAT_ETC2_RG11S);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGB8",Image::FORMAT_ETC2_RGB8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGBA8",Image::FORMAT_ETC2_RGBA8);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGB8A1",Image::FORMAT_ETC2_RGB8A1);
_VariantCall::add_constant(Variant::IMAGE,"FORMAT_MAX",Image::FORMAT_MAX);
_VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_NEAREST",Image::INTERPOLATE_NEAREST);
_VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_BILINEAR",Image::INTERPOLATE_BILINEAR);

View File

@ -755,8 +755,17 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
}
get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_NUMBER) {
r_err_str="Expected number (mipmaps)";
bool has_mipmaps=false;
if (token.type==TK_NUMBER) {
has_mipmaps=bool(token.value);
} else if (token.type==TK_IDENTIFIER && String(token.value)=="true") {
has_mipmaps=true;
} else if (token.type==TK_IDENTIFIER && String(token.value)=="false") {
has_mipmaps=false;
} else {
r_err_str="Expected number/true/false (mipmaps)";
return ERR_PARSE_ERROR;
}
@ -778,32 +787,18 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
String sformat=token.value;
Image::Format format;
Image::Format format=Image::FORMAT_MAX;
if (sformat=="GRAYSCALE") format=Image::FORMAT_GRAYSCALE;
else if (sformat=="INTENSITY") format=Image::FORMAT_INTENSITY;
else if (sformat=="GRAYSCALE_ALPHA") format=Image::FORMAT_GRAYSCALE_ALPHA;
else if (sformat=="RGB") format=Image::FORMAT_RGB;
else if (sformat=="RGBA") format=Image::FORMAT_RGBA;
else if (sformat=="INDEXED") format=Image::FORMAT_INDEXED;
else if (sformat=="INDEXED_ALPHA") format=Image::FORMAT_INDEXED_ALPHA;
else if (sformat=="BC1") format=Image::FORMAT_BC1;
else if (sformat=="BC2") format=Image::FORMAT_BC2;
else if (sformat=="BC3") format=Image::FORMAT_BC3;
else if (sformat=="BC4") format=Image::FORMAT_BC4;
else if (sformat=="BC5") format=Image::FORMAT_BC5;
else if (sformat=="PVRTC2") format=Image::FORMAT_PVRTC2;
else if (sformat=="PVRTC2_ALPHA") format=Image::FORMAT_PVRTC2_ALPHA;
else if (sformat=="PVRTC4") format=Image::FORMAT_PVRTC4;
else if (sformat=="PVRTC4_ALPHA") format=Image::FORMAT_PVRTC4_ALPHA;
else if (sformat=="ATC") format=Image::FORMAT_ATC;
else if (sformat=="ATC_ALPHA_EXPLICIT") format=Image::FORMAT_ATC_ALPHA_EXPLICIT;
else if (sformat=="ATC_ALPHA_INTERPOLATED") format=Image::FORMAT_ATC_ALPHA_INTERPOLATED;
else if (sformat=="CUSTOM") format=Image::FORMAT_CUSTOM;
else {
r_err_str="Invalid image format: '"+sformat+"'";
for(int i=0;i<Image::FORMAT_MAX;i++) {
if (Image::get_format_name(format)==sformat) {
format=Image::Format(i);
}
}
if (format==Image::FORMAT_MAX) {
r_err_str="Unknown image format: "+String(sformat);
return ERR_PARSE_ERROR;
};
}
int len = Image::get_image_data_size(width,height,format,mipmaps);
@ -1986,35 +1981,8 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str
String imgstr="Image( ";
imgstr+=itos(img.get_width());
imgstr+=", "+itos(img.get_height());
imgstr+=", "+itos(img.get_mipmaps());
imgstr+=", ";
switch(img.get_format()) {
case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break;
case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break;
case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break;
case Image::FORMAT_RGB: imgstr+="RGB"; break;
case Image::FORMAT_RGBA: imgstr+="RGBA"; break;
case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break;
case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break;
case Image::FORMAT_BC1: imgstr+="BC1"; break;
case Image::FORMAT_BC2: imgstr+="BC2"; break;
case Image::FORMAT_BC3: imgstr+="BC3"; break;
case Image::FORMAT_BC4: imgstr+="BC4"; break;
case Image::FORMAT_BC5: imgstr+="BC5"; break;
case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break;
case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break;
case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break;
case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break;
case Image::FORMAT_ETC: imgstr+="ETC"; break;
case Image::FORMAT_ATC: imgstr+="ATC"; break;
case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break;
case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break;
case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break;
default: {}
}
imgstr+=", "+String(img.has_mipmaps()?"true":"false");
imgstr+=", "+Image::get_format_name(img.get_format());
String s;

View File

@ -16324,15 +16324,15 @@
</constant>
<constant name="COMPRESS_ETC" value="3">
</constant>
<constant name="FORMAT_GRAYSCALE" value="0">
<constant name="FORMAT_L8" value="0">
</constant>
<constant name="FORMAT_INTENSITY" value="1">
</constant>
<constant name="FORMAT_GRAYSCALE_ALPHA" value="2">
<constant name="FORMAT_LA8" value="2">
</constant>
<constant name="FORMAT_RGB" value="3">
<constant name="FORMAT_RGB8" value="3">
</constant>
<constant name="FORMAT_RGBA" value="4">
<constant name="FORMAT_RGBA8" value="4">
</constant>
<constant name="FORMAT_INDEXED" value="5">
</constant>
@ -16342,23 +16342,23 @@
</constant>
<constant name="FORMAT_YUV_444" value="8">
</constant>
<constant name="FORMAT_BC1" value="9">
<constant name="FORMAT_DXT1" value="9">
</constant>
<constant name="FORMAT_BC2" value="10">
<constant name="FORMAT_DXT3" value="10">
</constant>
<constant name="FORMAT_BC3" value="11">
<constant name="FORMAT_DXT5" value="11">
</constant>
<constant name="FORMAT_BC4" value="12">
<constant name="FORMAT_ATI1" value="12">
</constant>
<constant name="FORMAT_BC5" value="13">
<constant name="FORMAT_ATI2" value="13">
</constant>
<constant name="FORMAT_PVRTC2" value="14">
</constant>
<constant name="FORMAT_PVRTC2_ALPHA" value="15">
<constant name="FORMAT_PVRTC2A" value="15">
</constant>
<constant name="FORMAT_PVRTC4" value="16">
</constant>
<constant name="FORMAT_PVRTC4_ALPHA" value="17">
<constant name="FORMAT_PVRTC4A" value="17">
</constant>
<constant name="FORMAT_ETC" value="18">
</constant>

2
drivers/SCsub vendored
View File

@ -12,7 +12,7 @@ SConscript('unix/SCsub');
SConscript('alsa/SCsub');
SConscript('pulseaudio/SCsub');
SConscript('windows/SCsub');
SConscript('gles2/SCsub');
SConscript('gles3/SCsub');
SConscript('gl_context/SCsub');
SConscript('pnm/SCsub');

View File

@ -74,21 +74,20 @@ struct DDSFormatInfo {
static const DDSFormatInfo dds_format_info[DDS_MAX]={
{"DXT1",true,false,4,8,Image::FORMAT_BC1},
{"DXT3",true,false,4,16,Image::FORMAT_BC2},
{"DXT5",true,false,4,16,Image::FORMAT_BC3},
{"ATI1",true,false,4,8,Image::FORMAT_BC4},
{"ATI2",true,false,4,16,Image::FORMAT_BC5},
{"BGRA8",false,false,1,4,Image::FORMAT_RGBA},
{"BGR8",false,false,1,3,Image::FORMAT_RGB},
{"RGBA8",false,false,1,4,Image::FORMAT_RGBA},
{"RGB8",false,false,1,3,Image::FORMAT_RGB},
{"BGR5A1",false,false,1,2,Image::FORMAT_RGBA},
{"BGR565",false,false,1,2,Image::FORMAT_RGB},
{"BGR10A2",false,false,1,4,Image::FORMAT_RGBA},
{"INDEXED",false,true,1,1,Image::FORMAT_INDEXED},
{"GRAYSCALE",false,false,1,1,Image::FORMAT_GRAYSCALE},
{"GRAYSCALE_ALPHA",false,false,1,2,Image::FORMAT_GRAYSCALE_ALPHA}
{"DXT1",true,false,4,8,Image::FORMAT_DXT1},
{"DXT3",true,false,4,16,Image::FORMAT_DXT3},
{"DXT5",true,false,4,16,Image::FORMAT_DXT5},
{"ATI1",true,false,4,8,Image::FORMAT_ATI1},
{"ATI2",true,false,4,16,Image::FORMAT_ATI2},
{"BGRA8",false,false,1,4,Image::FORMAT_RGBA8},
{"BGR8",false,false,1,3,Image::FORMAT_RGB8},
{"RGBA8",false,false,1,4,Image::FORMAT_RGBA8},
{"RGB8",false,false,1,3,Image::FORMAT_RGB8},
{"BGR5A1",false,false,1,2,Image::FORMAT_RGBA8},
{"BGR565",false,false,1,2,Image::FORMAT_RGB8},
{"BGR10A2",false,false,1,4,Image::FORMAT_RGBA8},
{"GRAYSCALE",false,false,1,1,Image::FORMAT_L8},
{"GRAYSCALE_ALPHA",false,false,1,2,Image::FORMAT_LA8}
};

View File

@ -42,7 +42,7 @@ static void _decompress_etc(Image *p_img) {
DVector<uint8_t>::Read r = src.read();
int mmc=p_img->get_mipmaps();
int mmc=p_img->get_mipmap_count();
for(int i=0;i<=mmc;i++) {
@ -93,9 +93,9 @@ static void _decompress_etc(Image *p_img) {
r=DVector<uint8_t>::Read();
//print_line("Re Creating ETC into regular image: w "+itos(p_img->get_width())+" h "+itos(p_img->get_height())+" mm "+itos(p_img->get_mipmaps()));
*p_img=Image(p_img->get_width(),p_img->get_height(),p_img->get_mipmaps(),Image::FORMAT_RGB,dst);
if (p_img->get_mipmaps())
p_img->generate_mipmaps(-1,true);
*p_img=Image(p_img->get_width(),p_img->get_height(),p_img->has_mipmaps(),Image::FORMAT_RGB8,dst);
if (p_img->has_mipmaps())
p_img->generate_mipmaps(true);
}
@ -108,11 +108,11 @@ static void _compress_etc(Image *p_img) {
ERR_FAIL_COND( nearest_power_of_2(imgw)!=imgw || nearest_power_of_2(imgh)!=imgh );
if (img.get_format()!=Image::FORMAT_RGB)
img.convert(Image::FORMAT_RGB);
if (img.get_format()!=Image::FORMAT_RGB8)
img.convert(Image::FORMAT_RGB8);
int mmc=img.get_mipmaps();
int mmc=img.get_mipmap_count();
if (mmc==0)
img.generate_mipmaps(); // force mipmaps, so it works on most hardware
@ -186,7 +186,7 @@ static void _compress_etc(Image *p_img) {
}
*p_img=Image(p_img->get_width(),p_img->get_height(),mc-1,Image::FORMAT_ETC,dst_data);
*p_img=Image(p_img->get_width(),p_img->get_height(),(mc-1)?true:false,Image::FORMAT_ETC,dst_data);
}

View File

@ -376,7 +376,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
switch(p_format) {
case Image::FORMAT_GRAYSCALE: {
case Image::FORMAT_L8: {
r_gl_components=1;
r_gl_format=GL_LUMINANCE;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_NV:GL_LUMINANCE;
@ -385,15 +385,15 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
case Image::FORMAT_INTENSITY: {
if (!image.empty())
image.convert(Image::FORMAT_RGBA);
image.convert(Image::FORMAT_RGBA8);
r_gl_components=4;
r_gl_format=GL_RGBA;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
r_has_alpha_cache=true;
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
case Image::FORMAT_LA8: {
//image.convert(Image::FORMAT_RGBA);
//image.convert(Image::FORMAT_RGBA8);
r_gl_components=2;
r_gl_format=GL_LUMINANCE_ALPHA;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_ALPHA_NV:GL_LUMINANCE_ALPHA;
@ -403,7 +403,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
case Image::FORMAT_INDEXED: {
if (!image.empty())
image.convert(Image::FORMAT_RGB);
image.convert(Image::FORMAT_RGB8);
r_gl_components=3;
r_gl_format=GL_RGB;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB;
@ -413,7 +413,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
case Image::FORMAT_INDEXED_ALPHA: {
if (!image.empty())
image.convert(Image::FORMAT_RGBA);
image.convert(Image::FORMAT_RGBA8);
r_gl_components=4;
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
@ -432,7 +432,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
r_has_alpha_cache=true;
} break;
case Image::FORMAT_RGB: {
case Image::FORMAT_RGB8: {
r_gl_components=3;
@ -450,7 +450,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
r_gl_internal_format=GL_RGB;
}
} break;
case Image::FORMAT_RGBA: {
case Image::FORMAT_RGBA8: {
r_gl_components=4;
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
@ -470,7 +470,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
r_has_alpha_cache=true;
} break;
case Image::FORMAT_BC1: {
case Image::FORMAT_DXT1: {
if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
@ -501,7 +501,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
};
} break;
case Image::FORMAT_BC2: {
case Image::FORMAT_DXT3: {
if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
@ -533,7 +533,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
};
} break;
case Image::FORMAT_BC3: {
case Image::FORMAT_DXT5: {
if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
@ -564,7 +564,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
};
} break;
case Image::FORMAT_BC4: {
case Image::FORMAT_ATI1: {
if (!latc_supported) {
@ -595,7 +595,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
};
} break;
case Image::FORMAT_BC5: {
case Image::FORMAT_ATI2: {
if (!latc_supported ) {
@ -657,7 +657,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
}
} break;
case Image::FORMAT_PVRTC2_ALPHA: {
case Image::FORMAT_PVRTC2A: {
if (!pvr_supported || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
@ -719,7 +719,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
}
} break;
case Image::FORMAT_PVRTC4_ALPHA: {
case Image::FORMAT_PVRTC4A: {
if (!pvr_supported || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
@ -841,7 +841,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
case Image::FORMAT_YUV_444: {
if (!image.empty())
image.convert(Image::FORMAT_RGB);
image.convert(Image::FORMAT_RGB8);
r_gl_internal_format=GL_RGB;
r_gl_components=3;
@ -1145,7 +1145,7 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
switch(texture->format) {
case Image::FORMAT_GRAYSCALE: {
case Image::FORMAT_L8: {
format=GL_LUMINANCE;
type=GL_UNSIGNED_BYTE;
@ -1156,19 +1156,19 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
case Image::FORMAT_INTENSITY: {
return Image();
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
case Image::FORMAT_LA8: {
format=GL_LUMINANCE_ALPHA;
type=GL_UNSIGNED_BYTE;
pixelsize=2;
} break;
case Image::FORMAT_RGB: {
case Image::FORMAT_RGB8: {
format=GL_RGB;
type=GL_UNSIGNED_BYTE;
pixelsize=3;
} break;
case Image::FORMAT_RGBA: {
case Image::FORMAT_RGBA8: {
format=GL_RGBA;
type=GL_UNSIGNED_BYTE;
@ -1178,18 +1178,18 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
format=GL_RGB;
type=GL_UNSIGNED_BYTE;
fmt=Image::FORMAT_RGB;
fmt=Image::FORMAT_RGB8;
pixelsize=3;
} break;
case Image::FORMAT_INDEXED_ALPHA: {
format=GL_RGBA;
type=GL_UNSIGNED_BYTE;
fmt=Image::FORMAT_RGBA;
fmt=Image::FORMAT_RGBA8;
pixelsize=4;
} break;
case Image::FORMAT_BC1: {
case Image::FORMAT_DXT1: {
pixelsize=1; //doesn't matter much
format=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
@ -1198,14 +1198,14 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
minw=minh=4;
} break;
case Image::FORMAT_BC2: {
case Image::FORMAT_DXT3: {
pixelsize=1; //doesn't matter much
format=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
compressed=true;
minw=minh=4;
} break;
case Image::FORMAT_BC3: {
case Image::FORMAT_DXT5: {
pixelsize=1; //doesn't matter much
format=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
@ -1213,7 +1213,7 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
minw=minh=4;
} break;
case Image::FORMAT_BC4: {
case Image::FORMAT_ATI1: {
format=GL_COMPRESSED_RED_RGTC1;
pixelsize=1; //doesn't matter much
@ -1222,7 +1222,7 @@ Image RasterizerGLES2::texture_get_data(RID p_texture,VS::CubeMapSide p_cube_sid
minw=minh=4;
} break;
case Image::FORMAT_BC5: {
case Image::FORMAT_ATI2: {
format=GL_COMPRESSED_RG_RGTC2;
pixelsize=1; //doesn't matter much
@ -1359,7 +1359,7 @@ Image::Format RasterizerGLES2::texture_get_format(RID p_texture) const {
Texture * texture = texture_owner.get(p_texture);
ERR_FAIL_COND_V(!texture,Image::FORMAT_GRAYSCALE);
ERR_FAIL_COND_V(!texture,Image::FORMAT_L8);
return texture->format;
}
@ -4320,7 +4320,7 @@ void RasterizerGLES2::capture_viewport(Image* r_capture) {
w=DVector<uint8_t>::Write();
r_capture->create(viewport.width,viewport.height,0,Image::FORMAT_RGB,pixels);
r_capture->create(viewport.width,viewport.height,0,Image::FORMAT_RGB8,pixels);
#else
@ -4360,7 +4360,7 @@ void RasterizerGLES2::capture_viewport(Image* r_capture) {
}
w=DVector<uint8_t>::Write();
r_capture->create(viewport.width,viewport.height,0,Image::FORMAT_RGBA,pixels);
r_capture->create(viewport.width,viewport.height,0,Image::FORMAT_RGBA8,pixels);
//r_capture->flip_y();

View File

@ -154,7 +154,7 @@ class RasterizerGLES2 : public Rasterizer {
flags=width=height=0;
tex_id=0;
data_size=0;
format=Image::FORMAT_GRAYSCALE;
format=Image::FORMAT_L8;
gl_components_cache=0;
format_has_alpha=false;
has_alpha=false;

View File

@ -105,8 +105,8 @@ precision mediump float;
precision mediump int;
#endif
// texunit:0
uniform sampler2D texture;
uniform sampler2D texture; // texunit:0
varying vec2 uv_interp;
varying vec4 color_interp;
@ -319,7 +319,7 @@ LIGHT_SHADER_CODE
#ifdef USE_DEPTH_SHADOWS
#define SHADOW_DEPTH(m_tex,m_uv) (texture2D((m_tex),(m_uv)).z)
#define SHADOW_DEPTH(m_tex,m_uv) (texture2D((m_tex),(m_uv)).r)
#else

5
drivers/gles3/SCsub Normal file
View File

@ -0,0 +1,5 @@
Import('env')
env.add_source_files(env.drivers_sources,"*.cpp")
SConscript("shaders/SCsub")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
#ifndef RASTERIZERCANVASGLES3_H
#define RASTERIZERCANVASGLES3_H
#include "servers/visual/rasterizer.h"
#include "rasterizer_storage_gles3.h"
#include "shaders/canvas_shadow.glsl.h"
class RasterizerCanvasGLES3 : public RasterizerCanvas {
public:
struct CanvasItemUBO {
float projection_matrix[16];
};
struct Data {
GLuint canvas_quad_vertices;
GLuint canvas_quad_array;
} data;
struct State {
CanvasItemUBO canvas_item_ubo_data;
GLuint canvas_item_ubo;
bool canvas_texscreen_used;
CanvasShaderGLES3 canvas_shader;
CanvasShadowShaderGLES3 canvas_shadow_shader;
bool using_texture_rect;
RID current_tex;
RasterizerStorageGLES3::Texture *current_tex_ptr;
Transform vp;
Color canvas_item_modulate;
Matrix32 extra_matrix;
Matrix32 final_transform;
} state;
RasterizerStorageGLES3 *storage;
struct LightInternal : public RID_Data {
struct UBOData {
float light_matrix[16];
float local_matrix[16];
float shadow_matrix[16];
float color[4];
float shadow_color[4];
float light_pos[2];
float shadowpixel_size;
float shadow_gradient;
float light_height;
float light_outside_alpha;
float shadow_distance_mult;
} ubo_data;
GLuint ubo;
};
RID_Owner<LightInternal> light_internal_owner;
virtual RID light_internal_create();
virtual void light_internal_update(RID p_rid, Light* p_light);
virtual void light_internal_free(RID p_rid);
virtual void canvas_begin();
virtual void canvas_end();
_FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable);
_FORCE_INLINE_ RasterizerStorageGLES3::Texture* _bind_canvas_texture(const RID& p_texture);
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs);
_FORCE_INLINE_ void _draw_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);
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item,Item *current_clip,bool &reclip);
virtual void canvas_render_items(Item *p_item_list,int p_z,const Color& p_modulate,Light *p_light);
virtual void canvas_debug_viewport_shadows(Light* p_lights_with_shadow);
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);
virtual void reset_canvas();
void draw_generic_textured_rect(const Rect2& p_rect, const Rect2& p_src);
void initialize();
void finalize();
RasterizerCanvasGLES3();
};
#endif // RASTERIZERCANVASGLES3_H

View File

@ -0,0 +1,266 @@
#include "rasterizer_gles3.h"
#include "os/os.h"
#include "globals.h"
#include "gl_context/context_gl.h"
#include <string.h>
RasterizerStorage *RasterizerGLES3::get_storage() {
return storage;
}
RasterizerCanvas *RasterizerGLES3::get_canvas() {
return canvas;
}
RasterizerScene *RasterizerGLES3::get_scene() {
return NULL;
}
static void _gl_debug_print(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const GLvoid *userParam)
{
if (type==GL_DEBUG_TYPE_OTHER_ARB)
return;
print_line("mesege");
char debSource[256], debType[256], debSev[256];
if(source == GL_DEBUG_SOURCE_API_ARB)
strcpy(debSource, "OpenGL");
else if(source == GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
strcpy(debSource, "Windows");
else if(source == GL_DEBUG_SOURCE_SHADER_COMPILER_ARB)
strcpy(debSource, "Shader Compiler");
else if(source == GL_DEBUG_SOURCE_THIRD_PARTY_ARB)
strcpy(debSource, "Third Party");
else if(source == GL_DEBUG_SOURCE_APPLICATION_ARB)
strcpy(debSource, "Application");
else if(source == GL_DEBUG_SOURCE_OTHER_ARB)
strcpy(debSource, "Other");
if(type == GL_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error");
else if(type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
strcpy(debType, "Deprecated behavior");
else if(type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
strcpy(debType, "Undefined behavior");
else if(type == GL_DEBUG_TYPE_PORTABILITY_ARB)
strcpy(debType, "Portability");
else if(type == GL_DEBUG_TYPE_PERFORMANCE_ARB)
strcpy(debType, "Performance");
else if(type == GL_DEBUG_TYPE_OTHER_ARB)
strcpy(debType, "Other");
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB)
strcpy(debSev, "High");
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
strcpy(debSev, "Medium");
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
strcpy(debSev, "Low");
String output = String()+ "GL ERROR: Source: " + debSource + "\tType: " + debType + "\tID: " + itos(id) + "\tSeverity: " + debSev + "\tMessage: " + message;
ERR_PRINTS(output);
}
void RasterizerGLES3::initialize() {
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("Using GLES3 video driver");
}
#ifdef GLEW_ENABLED
GLuint res = glewInit();
ERR_FAIL_COND(res!=GLEW_OK);
if (OS::get_singleton()->is_stdout_verbose()) {
print_line(String("GLES2: Using GLEW ") + (const char*) glewGetString(GLEW_VERSION));
}
// Check for GL 2.1 compatibility, if not bail out
if (!glewIsSupported("GL_VERSION_3_0")) {
ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n"
"Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n"
"Godot Engine will self-destruct as soon as you acknowledge this error message.",
"Fatal error: Insufficient OpenGL / GLES drivers");
// TODO: If it's even possible, we should stop the execution without segfault and memory leaks :)
}
#endif
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(_gl_debug_print, NULL);
glEnable(GL_DEBUG_OUTPUT);
/* glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE);
glDebugMessageInsertARB(
GL_DEBUG_SOURCE_API_ARB,
GL_DEBUG_TYPE_OTHER_ARB, 1,
GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello");
*/
storage->initialize();
canvas->initialize();
}
void RasterizerGLES3::begin_frame(){
}
void RasterizerGLES3::set_current_render_target(RID p_render_target){
if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
//handle pending clear request, if the framebuffer was not cleared
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
glClearColor(
storage->frame.clear_request_color.r,
storage->frame.clear_request_color.g,
storage->frame.clear_request_color.b,
storage->frame.clear_request_color.a );
glClear(GL_COLOR_BUFFER_BIT);
}
if (p_render_target.is_valid()) {
RasterizerStorageGLES3::RenderTarget * rt = storage->render_target_owner.getornull(p_render_target);
if (!rt) {
storage->frame.current_rt=NULL;
}
ERR_FAIL_COND(!rt);
storage->frame.current_rt=rt;
storage->frame.clear_request=false;
glViewport(0,0,rt->width,rt->height);
} else {
storage->frame.current_rt=NULL;
storage->frame.clear_request=false;
glViewport(0,0,OS::get_singleton()->get_window_size().width,OS::get_singleton()->get_window_size().height);
glBindFramebuffer(GL_FRAMEBUFFER,storage->config.system_fbo);
}
}
void RasterizerGLES3::restore_render_target() {
ERR_FAIL_COND(storage->frame.current_rt==NULL);
RasterizerStorageGLES3::RenderTarget * rt = storage->frame.current_rt;
glViewport(0,0,rt->width,rt->height);
}
void RasterizerGLES3::clear_render_target(const Color& p_color) {
ERR_FAIL_COND(!storage->frame.current_rt);
storage->frame.clear_request=true;
storage->frame.clear_request_color=p_color;
}
void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target,const Rect2& p_screen_rect,int p_screen){
ERR_FAIL_COND( storage->frame.current_rt );
RasterizerStorageGLES3::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
canvas->canvas_begin();
glBindFramebuffer(GL_FRAMEBUFFER,storage->config.system_fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,rt->front.color);
canvas->draw_generic_textured_rect(p_screen_rect,Rect2(0,0,1,-1));
glBindTexture(GL_TEXTURE_2D,0);
canvas->canvas_end();
}
void RasterizerGLES3::end_frame(){
#if 0
canvas->canvas_begin();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
float vtx[8]={0,0,
0,1,
1,1,
1,0
};
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
glVertexAttribPointer( VS::ARRAY_VERTEX, 2 ,GL_FLOAT, false, 0, vtx );
// glBindBuffer(GL_ARRAY_BUFFER,canvas->data.canvas_quad_vertices);
// glEnableVertexAttribArray(VS::ARRAY_VERTEX);
// glVertexAttribPointer( VS::ARRAY_VERTEX, 2 ,GL_FLOAT, false, 0, 0 );
glBindVertexArray(canvas->data.canvas_quad_array);
canvas->draw_generic_textured_rect(Rect2(0,0,15,15),Rect2(0,0,1,1));
#endif
if (ContextGL::get_singleton())
ContextGL::get_singleton()->swap_buffers();
}
void RasterizerGLES3::finalize(){
storage->finalize();
canvas->finalize();
}
Rasterizer *RasterizerGLES3::_create_current() {
return memnew( RasterizerGLES3 );
}
void RasterizerGLES3::make_current() {
_create_func=_create_current;
}
void RasterizerGLES3::register_config() {
GLOBAL_DEF("rendering/gles3/framebuffer_format",RasterizerStorageGLES3::FBO_FORMAT_FLOAT);
Globals::get_singleton()->set_custom_property_info("rendering/gles3/framebuffer_format",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"16 Bits,32 Bits,Half Float"));
GLOBAL_DEF("rendering/gles3/lighting_technique",1);
Globals::get_singleton()->set_custom_property_info("rendering/gles3/lighting_technique",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Forward,Deferred"));
GLOBAL_DEF("rendering/gles3/use_nearest_mipmap_filter",false);
GLOBAL_DEF("rendering/gles3/anisotropic_filter_level",4.0);
}
RasterizerGLES3::RasterizerGLES3()
{
storage = memnew( RasterizerStorageGLES3 );
canvas = memnew( RasterizerCanvasGLES3 );
canvas->storage=storage;
}
RasterizerGLES3::~RasterizerGLES3() {
memdelete(storage);
memdelete(canvas);
}

View File

@ -0,0 +1,38 @@
#ifndef RASTERIZERGLES3_H
#define RASTERIZERGLES3_H
#include "servers/visual/rasterizer.h"
#include "rasterizer_storage_gles3.h"
#include "rasterizer_canvas_gles3.h"
class RasterizerGLES3 : public Rasterizer {
static Rasterizer *_create_current();
RasterizerStorageGLES3 *storage;
RasterizerCanvasGLES3 *canvas;
public:
virtual RasterizerStorage *get_storage();
virtual RasterizerCanvas *get_canvas();
virtual RasterizerScene *get_scene();
virtual void initialize();
virtual void begin_frame();
virtual void set_current_render_target(RID p_render_target);
virtual void restore_render_target();
virtual void clear_render_target(const Color& p_color);
virtual void blit_render_target_to_screen(RID p_render_target,const Rect2& p_screen_rect,int p_screen=0);
virtual void end_frame();
virtual void finalize();
static void make_current();
static void register_config();
RasterizerGLES3();
~RasterizerGLES3();
};
#endif // RASTERIZERGLES3_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,445 @@
#ifndef RASTERIZERSTORAGEGLES3_H
#define RASTERIZERSTORAGEGLES3_H
#include "servers/visual/rasterizer.h"
#include "shader_gles3.h"
#include "shaders/copy.glsl.h"
#include "shaders/canvas.glsl.h"
class RasterizerStorageGLES3 : public RasterizerStorage {
public:
enum FBOFormat {
FBO_FORMAT_16_BITS,
FBO_FORMAT_32_BITS,
FBO_FORMAT_FLOAT,
};
struct Config {
FBOFormat fbo_format;
bool fbo_deferred;
GLuint system_fbo; //on some devices, such as apple, screen is rendered to yet another fbo.
bool shrink_textures_x2;
bool use_fast_texture_filter;
bool use_anisotropic_filter;
bool s3tc_supported;
bool latc_supported;
bool bptc_supported;
bool etc_supported;
bool etc2_supported;
bool pvrtc_supported;
bool srgb_decode_supported;
bool use_rgba_2d_shadows;
float anisotropic_level;
int max_texture_image_units;
int max_texture_size;
Set<String> extensions;
} config;
struct Shaders {
CopyShaderGLES3 copy;
} shaders;
struct Resources {
GLuint white_tex;
GLuint black_tex;
GLuint normal_tex;
} resources;
struct Info {
uint64_t texture_mem;
} info;
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////DATA///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////API////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/* TEXTURE API */
struct RenderTarget;
struct Texture : public RID_Data {
String path;
uint32_t flags;
int width,height;
int alloc_width, alloc_height;
Image::Format format;
GLenum target;
GLenum gl_format_cache;
GLenum gl_internal_format_cache;
GLenum gl_type_cache;
int data_size; //original data size, useful for retrieving back
bool compressed;
bool srgb;
int total_data_size;
bool ignore_mipmaps;
int mipmaps;
bool active;
GLuint tex_id;
RenderTarget *render_target;
Texture() {
ignore_mipmaps=false;
render_target=NULL;
flags=width=height=0;
tex_id=0;
data_size=0;
format=Image::FORMAT_L8;
active=false;
compressed=false;
total_data_size=0;
target=GL_TEXTURE_2D;
mipmaps=0;
}
~Texture() {
if (tex_id!=0) {
glDeleteTextures(1,&tex_id);
}
}
};
mutable RID_Owner<Texture> texture_owner;
Image _get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags, GLenum& r_gl_format, GLenum& r_gl_internal_format, GLenum &r_type, bool &r_compressed, bool &srgb);
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 void texture_set_size_override(RID p_texture,int p_width, int p_height);
virtual void texture_set_path(RID p_texture,const String& p_path);
virtual String texture_get_path(RID p_texture) const;
virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable);
virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
/* SHADER API */
struct Shader : public RID_Data {
};
virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_SPATIAL);
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_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);
virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
/* 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;
/* MESH API */
virtual RID mesh_create();
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> >());
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);
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 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 void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
virtual AABB mesh_get_aabb(RID p_mesh) const;
virtual void mesh_clear(RID p_mesh);
/* MULTIMESH API */
virtual RID multimesh_create();
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);
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_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_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;
virtual AABB multimesh_get_aabb(RID p_mesh) 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_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& 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 */
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(VS::LightType p_type);
virtual void light_set_color(RID p_light,const Color& p_color);
virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value);
virtual void light_set_shadow(RID p_light,bool p_enabled);
virtual void light_set_projector(RID p_light,RID p_texture);
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_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode);
/* PROBE 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);
/* ROOM API */
virtual RID room_create();
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 void portal_set_enabled(RID p_portal, bool p_enabled);
virtual void portal_set_disable_distance(RID p_portal, float p_distance);
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color);
/* RENDER TARGET */
struct RenderTarget : public RID_Data {
struct Color {
GLuint fbo;
GLuint color;
} front,back;
GLuint depth;
struct Deferred {
GLuint fbo;
GLuint fbo_color;
GLuint albedo_ao;
GLuint metal_rough_motion;
GLuint normal_special;
} deferred;
int width,height;
bool flags[RENDER_TARGET_FLAG_MAX];
bool used_in_frame;
RenderTarget() {
width=0;
height=0;
depth=0;
front.fbo=0;
back.fbo=0;
deferred.fbo=0;
deferred.fbo_color=0;
used_in_frame=false;
flags[RENDER_TARGET_VFLIP]=false;
flags[RENDER_TARGET_TRANSPARENT]=false;
flags[RENDER_TARGET_NO_3D]=false;
flags[RENDER_TARGET_NO_SAMPLING]=false;
}
};
mutable RID_Owner<RenderTarget> render_target_owner;
void _render_target_clear(RenderTarget *rt);
void _render_target_allocate(RenderTarget *rt);
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 Image render_target_get_image(RID p_render_target) const;
virtual void render_target_set_flag(RID p_render_target,RenderTargetFlags p_flag,bool p_value);
virtual bool render_target_renedered_in_frame(RID p_render_target);
/* CANVAS SHADOW */
struct CanvasLightShadow : public RID_Data {
int size;
int height;
GLuint fbo;
GLuint depth;
GLuint distance; //for older devices
};
RID_Owner<CanvasLightShadow> canvas_light_shadow_owner;
virtual RID canvas_light_shadow_buffer_create(int p_width);
/* LIGHT SHADOW MAPPING */
struct CanvasOccluder : public RID_Data {
GLuint vertex_id; // 0 means, unconfigured
GLuint index_id; // 0 means, unconfigured
DVector<Vector2> lines;
int len;
};
RID_Owner<CanvasOccluder> canvas_occluder_owner;
virtual RID canvas_light_occluder_create();
virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines);
virtual bool free(RID p_rid);
struct Frame {
RenderTarget *current_rt;
bool clear_request;
Color clear_request_color;
int canvas_draw_commands;
} frame;
void initialize();
void finalize();
RasterizerStorageGLES3();
};
#endif // RASTERIZERSTORAGEGLES3_H

View File

@ -0,0 +1,754 @@
/*************************************************************************/
/* shader_gles2.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 "shader_gles3.h"
#include "print_string.h"
//#define DEBUG_OPENGL
#ifdef DEBUG_OPENGL
#define DEBUG_TEST_ERROR(m_section)\
{\
uint32_t err = glGetError();\
if (err) {\
print_line("OpenGL Error #"+itos(err)+" at: "+m_section);\
}\
}
#else
#define DEBUG_TEST_ERROR(m_section)
#endif
ShaderGLES3 *ShaderGLES3::active=NULL;
//#define DEBUG_SHADER
#ifdef DEBUG_SHADER
#define DEBUG_PRINT(m_text) print_line(m_text);
#else
#define DEBUG_PRINT(m_text)
#endif
void ShaderGLES3::bind_uniforms() {
if (!uniforms_dirty) {
return;
};
// upload default uniforms
const Map<uint32_t,Variant>::Element *E =uniform_defaults.front();
while(E) {
int idx=E->key();
int location=version->uniform_location[idx];
if (location<0) {
E=E->next();
continue;
}
const Variant &v=E->value();
_set_uniform_variant(location, v);
//print_line("uniform "+itos(location)+" value "+v+ " type "+Variant::get_type_name(v.get_type()));
E=E->next();
};
const Map<uint32_t,CameraMatrix>::Element* C = uniform_cameras.front();
while (C) {
int location = version->uniform_location[C->key()];
if (location<0) {
C=C->next();
continue;
}
glUniformMatrix4fv(location,1,false,&(C->get().matrix[0][0]));
C = C->next();
};
uniforms_dirty = false;
};
GLint ShaderGLES3::get_uniform_location(int p_idx) const {
ERR_FAIL_COND_V(!version, -1);
return version->uniform_location[p_idx];
};
bool ShaderGLES3::bind() {
if (active!=this || !version || new_conditional_version.key!=conditional_version.key) {
conditional_version=new_conditional_version;
version = get_current_version();
} else {
return false;
}
ERR_FAIL_COND_V(!version,false);
glUseProgram( version->id );
DEBUG_TEST_ERROR("Use Program");
active=this;
uniforms_dirty = true;
/*
* why on earth is this code here?
for (int i=0;i<texunit_pair_count;i++) {
glUniform1i(texunit_pairs[i].location, texunit_pairs[i].index);
DEBUG_TEST_ERROR("Uniform 1 i");
}
*/
return true;
}
void ShaderGLES3::unbind() {
version=NULL;
glUseProgram(0);
uniforms_dirty = true;
active=NULL;
}
static void _display_error_with_code(const String& p_error,const Vector<const char*>& p_code) {
int line=1;
String total_code;
for(int i=0;i<p_code.size();i++) {
total_code+=String(p_code[i]);
}
Vector<String> lines = String(total_code).split("\n");
for(int j=0;j<lines.size();j++) {
print_line(itos(line)+": "+lines[j]);
line++;
}
ERR_PRINTS(p_error);
}
ShaderGLES3::Version* ShaderGLES3::get_current_version() {
Version *_v=version_map.getptr(conditional_version);
if (_v) {
if (conditional_version.code_version!=0) {
CustomCode *cc=custom_code_map.getptr(conditional_version.code_version);
ERR_FAIL_COND_V(!cc,_v);
if (cc->version==_v->code_version)
return _v;
} else {
return _v;
}
}
if (!_v)
version_map[conditional_version]=Version();
Version &v = version_map[conditional_version];
if (!_v) {
v.uniform_location = memnew_arr( GLint, uniform_count );
} else {
if (v.ok) {
//bye bye shaders
glDeleteShader( v.vert_id );
glDeleteShader( v.frag_id );
glDeleteProgram( v.id );
v.id=0;
}
}
v.ok=false;
/* SETUP CONDITIONALS */
Vector<const char*> strings;
#ifdef GLEW_ENABLED
//strings.push_back("#version 330\n");
strings.push_back("#version 300 es\n");
#else
strings.push_back("#version 300 es\n"); //ATI requieres this before anything
#endif
int define_line_ofs=1;
for(int j=0;j<conditional_count;j++) {
bool enable=((1<<j)&conditional_version.version);
strings.push_back(enable?conditional_defines[j]:"");
if (enable)
define_line_ofs++;
if (enable) {
DEBUG_PRINT(conditional_defines[j]);
}
}
//keep them around during the function
CharString code_string;
CharString code_string2;
CharString code_globals;
//print_line("code version? "+itos(conditional_version.code_version));
CustomCode *cc=NULL;
if ( conditional_version.code_version>0 ) {
//do custom code related stuff
ERR_FAIL_COND_V( !custom_code_map.has( conditional_version.code_version ), NULL );
cc=&custom_code_map[conditional_version.code_version];
v.code_version=cc->version;
define_line_ofs+=2;
}
/* CREATE PROGRAM */
v.id = glCreateProgram();
ERR_FAIL_COND_V(v.id==0, NULL);
/* VERTEX SHADER */
if (cc) {
for(int i=0;i<cc->custom_defines.size();i++) {
strings.push_back(cc->custom_defines[i]);
DEBUG_PRINT("CD #"+itos(i)+": "+String(cc->custom_defines[i]));
}
}
int strings_base_size=strings.size();
//vertex precision is high
strings.push_back("precision highp float;\n");
strings.push_back("precision highp int;\n");
#if 0
if (cc) {
String _code_string = "#define VERTEX_SHADER_CODE "+cc->vertex+"\n";
String _code_globals = "#define VERTEX_SHADER_GLOBALS "+cc->vertex_globals+"\n";
code_string=_code_string.ascii();
code_globals=_code_globals.ascii();
DEBUG_PRINT( code_globals.get_data() );
DEBUG_PRINT( code_string.get_data() );
strings.push_back(code_globals);
strings.push_back(code_string);
}
#endif
strings.push_back(vertex_code0.get_data());
if (cc) {
code_globals=cc->vertex_globals.ascii();
strings.push_back(code_globals.get_data());
}
strings.push_back(vertex_code1.get_data());
if (cc) {
code_string=cc->vertex.ascii();
strings.push_back(code_string.get_data());
}
strings.push_back(vertex_code2.get_data());
#ifdef DEBUG_SHADER
DEBUG_PRINT("\nVertex Code:\n\n"+String(code_string.get_data()));
for(int i=0;i<strings.size();i++) {
//print_line("vert strings "+itos(i)+":"+String(strings[i]));
}
#endif
v.vert_id = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(v.vert_id,strings.size(),&strings[0],NULL);
glCompileShader(v.vert_id);
GLint status;
glGetShaderiv(v.vert_id,GL_COMPILE_STATUS,&status);
if (status==GL_FALSE) {
// error compiling
GLsizei iloglen;
glGetShaderiv(v.vert_id,GL_INFO_LOG_LENGTH,&iloglen);
if (iloglen<0) {
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
ERR_PRINT("NO LOG, WTF");
} else {
if (iloglen==0) {
iloglen = 4096; //buggy driver (Adreno 220+....)
}
char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
ilogmem[iloglen]=0;
glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem);
String err_string=get_shader_name()+": Vertex Program Compilation Failed:\n";
err_string+=ilogmem;
_display_error_with_code(err_string,strings);
Memory::free_static(ilogmem);
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
}
ERR_FAIL_V(NULL);
}
/* FRAGMENT SHADER */
strings.resize(strings_base_size);
//fragment precision is medium
strings.push_back("precision mediump float;\n");
strings.push_back("precision mediump int;\n");
#if 0
if (cc) {
String _code_string = "#define FRAGMENT_SHADER_CODE "+cc->fragment+"\n";
String _code_globals = "#define FRAGMENT_SHADER_GLOBALS "+cc->fragment_globals+"\n";
code_string=_code_string.ascii();
code_globals=_code_globals.ascii();
DEBUG_PRINT( code_globals.get_data() );
DEBUG_PRINT( code_string.get_data() );
strings.push_back(code_globals);
strings.push_back(code_string);
}
#endif
strings.push_back(fragment_code0.get_data());
if (cc) {
code_globals=cc->fragment_globals.ascii();
strings.push_back(code_globals.get_data());
}
strings.push_back(fragment_code1.get_data());
if (cc) {
code_string=cc->fragment.ascii();
strings.push_back(code_string.get_data());
}
strings.push_back(fragment_code2.get_data());
if (cc) {
code_string2=cc->light.ascii();
strings.push_back(code_string2.get_data());
}
strings.push_back(fragment_code3.get_data());
#ifdef DEBUG_SHADER
DEBUG_PRINT("\nFragment Code:\n\n"+String(code_string.get_data()));
for(int i=0;i<strings.size();i++) {
//print_line("frag strings "+itos(i)+":"+String(strings[i]));
}
#endif
v.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(v.frag_id,strings.size(),&strings[0],NULL);
glCompileShader(v.frag_id);
glGetShaderiv(v.frag_id,GL_COMPILE_STATUS,&status);
if (status==GL_FALSE) {
// error compiling
GLsizei iloglen;
glGetShaderiv(v.frag_id,GL_INFO_LOG_LENGTH,&iloglen);
if (iloglen<0) {
glDeleteShader(v.frag_id);
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
ERR_PRINT("NO LOG, WTF");
} else {
if (iloglen==0) {
iloglen = 4096; //buggy driver (Adreno 220+....)
}
char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
ilogmem[iloglen]=0;
glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem);
String err_string=get_shader_name()+": Fragment Program Compilation Failed:\n";
err_string+=ilogmem;
_display_error_with_code(err_string,strings);
ERR_PRINT(err_string.ascii().get_data());
Memory::free_static(ilogmem);
glDeleteShader(v.frag_id);
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
}
ERR_FAIL_V( NULL );
}
glAttachShader(v.id,v.frag_id);
glAttachShader(v.id,v.vert_id);
// bind attributes before linking
for (int i=0;i<attribute_pair_count;i++) {
glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name );
}
glLinkProgram(v.id);
glGetProgramiv(v.id, GL_LINK_STATUS, &status);
if (status==GL_FALSE) {
// error linking
GLsizei iloglen;
glGetProgramiv(v.id,GL_INFO_LOG_LENGTH,&iloglen);
if (iloglen<0) {
glDeleteShader(v.frag_id);
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
ERR_FAIL_COND_V(iloglen<=0, NULL);
}
if (iloglen==0) {
iloglen = 4096; //buggy driver (Adreno 220+....)
}
char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
ilogmem[iloglen]=0;
glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem);
String err_string=get_shader_name()+": Program LINK FAILED:\n";
err_string+=ilogmem;
_display_error_with_code(err_string,strings);
ERR_PRINT(err_string.ascii().get_data());
Memory::free_static(ilogmem);
glDeleteShader(v.frag_id);
glDeleteShader(v.vert_id);
glDeleteProgram( v.id );
v.id=0;
ERR_FAIL_V(NULL);
}
/* UNIFORMS */
glUseProgram(v.id);
//print_line("uniforms: ");
for(int j=0;j<uniform_count;j++) {
v.uniform_location[j]=glGetUniformLocation(v.id,uniform_names[j]);
// print_line("uniform "+String(uniform_names[j])+" location "+itos(v.uniform_location[j]));
}
// set texture uniforms
for (int i=0;i<texunit_pair_count;i++) {
GLint loc = glGetUniformLocation(v.id,texunit_pairs[i].name);
if (loc>=0) {
if (texunit_pairs[i].index<0) {
glUniform1i(loc,max_image_units+texunit_pairs[i].index); //negative, goes down
} else {
glUniform1i(loc,texunit_pairs[i].index);
}
}
}
// assign uniform block bind points
for (int i=0;i<ubo_count;i++) {
GLint loc = glGetUniformBlockIndex(v.id,ubo_pairs[i].name);
if (loc>=0)
glUniformBlockBinding(v.id,loc,ubo_pairs[i].index);
}
if ( cc ) {
v.custom_uniform_locations.resize(cc->custom_uniforms.size());
for(int i=0;i<cc->custom_uniforms.size();i++) {
v.custom_uniform_locations[i]=glGetUniformLocation(v.id,String(cc->custom_uniforms[i]).ascii().get_data());
}
}
glUseProgram(0);
v.ok=true;
return &v;
}
GLint ShaderGLES3::get_uniform_location(const String& p_name) const {
ERR_FAIL_COND_V(!version,-1);
return glGetUniformLocation(version->id,p_name.ascii().get_data());
}
void ShaderGLES3::setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start) {
ERR_FAIL_COND(version);
conditional_version.key=0;
new_conditional_version.key=0;
uniform_count=p_uniform_count;
conditional_count=p_conditional_count;
conditional_defines=p_conditional_defines;
uniform_names=p_uniform_names;
vertex_code=p_vertex_code;
fragment_code=p_fragment_code;
texunit_pairs=p_texunit_pairs;
texunit_pair_count=p_texunit_pair_count;
vertex_code_start=p_vertex_code_start;
fragment_code_start=p_fragment_code_start;
attribute_pairs=p_attribute_pairs;
attribute_pair_count=p_attribute_count;
ubo_pairs=p_ubo_pairs;
ubo_count=p_ubo_pair_count;
//split vertex and shader code (thank you, retarded shader compiler programmers from you know what company).
{
String globals_tag="\nVERTEX_SHADER_GLOBALS";
String code_tag="\nVERTEX_SHADER_CODE";
String code = vertex_code;
int cpos = code.find(globals_tag);
if (cpos==-1) {
vertex_code0=code.ascii();
} else {
vertex_code0=code.substr(0,cpos).ascii();
code = code.substr(cpos+globals_tag.length(),code.length());
cpos = code.find(code_tag);
if (cpos==-1) {
vertex_code1=code.ascii();
} else {
vertex_code1=code.substr(0,cpos).ascii();
vertex_code2=code.substr(cpos+code_tag.length(),code.length()).ascii();
}
}
}
{
String globals_tag="\nFRAGMENT_SHADER_GLOBALS";
String code_tag="\nFRAGMENT_SHADER_CODE";
String light_code_tag="\nLIGHT_SHADER_CODE";
String code = fragment_code;
int cpos = code.find(globals_tag);
if (cpos==-1) {
fragment_code0=code.ascii();
} else {
fragment_code0=code.substr(0,cpos).ascii();
code = code.substr(cpos+globals_tag.length(),code.length());
cpos = code.find(code_tag);
if (cpos==-1) {
fragment_code1=code.ascii();
} else {
fragment_code1=code.substr(0,cpos).ascii();
String code2 = code.substr(cpos+code_tag.length(),code.length());
cpos = code2.find(light_code_tag);
if (cpos==-1) {
fragment_code2=code2.ascii();
} else {
fragment_code2=code2.substr(0,cpos).ascii();
fragment_code3 = code2.substr(cpos+light_code_tag.length(),code2.length()).ascii();
}
}
}
}
}
void ShaderGLES3::finish() {
const VersionKey *V=NULL;
while((V=version_map.next(V))) {
Version &v=version_map[*V];
glDeleteShader( v.vert_id );
glDeleteShader( v.frag_id );
glDeleteProgram( v.id );
memdelete_arr( v.uniform_location );
}
}
void ShaderGLES3::clear_caches() {
const VersionKey *V=NULL;
while((V=version_map.next(V))) {
Version &v=version_map[*V];
glDeleteShader( v.vert_id );
glDeleteShader( v.frag_id );
glDeleteProgram( v.id );
memdelete_arr( v.uniform_location );
}
version_map.clear();
custom_code_map.clear();
version=NULL;
last_custom_code=1;
uniforms_dirty = true;
}
uint32_t ShaderGLES3::create_custom_shader() {
custom_code_map[last_custom_code]=CustomCode();
custom_code_map[last_custom_code].version=1;
return last_custom_code++;
}
void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id, const String& p_vertex, const String& p_vertex_globals,const String& p_fragment,const String& p_light, const String& p_fragment_globals,const Vector<StringName>& p_uniforms,const Vector<const char*> &p_custom_defines) {
ERR_FAIL_COND(!custom_code_map.has(p_code_id));
CustomCode *cc=&custom_code_map[p_code_id];
cc->vertex=p_vertex;
cc->vertex_globals=p_vertex_globals;
cc->fragment=p_fragment;
cc->fragment_globals=p_fragment_globals;
cc->light=p_light;
cc->custom_uniforms=p_uniforms;
cc->custom_defines=p_custom_defines;
cc->version++;
}
void ShaderGLES3::set_custom_shader(uint32_t p_code_id) {
new_conditional_version.code_version=p_code_id;
}
void ShaderGLES3::free_custom_shader(uint32_t p_code_id) {
/* if (! custom_code_map.has( p_code_id )) {
print_line("no code id "+itos(p_code_id));
} else {
print_line("freed code id "+itos(p_code_id));
}*/
ERR_FAIL_COND(! custom_code_map.has( p_code_id ));
if (conditional_version.code_version==p_code_id)
conditional_version.code_version=0; //bye
custom_code_map.erase(p_code_id);
}
ShaderGLES3::ShaderGLES3() {
version=NULL;
last_custom_code=1;
uniforms_dirty = true;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&max_image_units);
}
ShaderGLES3::~ShaderGLES3() {
finish();
}

View File

@ -0,0 +1,377 @@
/*************************************************************************/
/* shader_gles2.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 SHADER_GLES3_H
#define SHADER_GLES3_H
#include "platform_config.h"
#ifndef GLES3_INCLUDE_H
#include <GLES3/gl3.h>
#else
#include GLES3_INCLUDE_H
#endif
#include "hash_map.h"
#include "map.h"
#include "variant.h"
#include "camera_matrix.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class ShaderGLES3 {
protected:
struct Enum {
uint64_t mask;
uint64_t shift;
const char *defines[16];
};
struct EnumValue {
uint64_t set_mask;
uint64_t clear_mask;
};
struct AttributePair {
const char *name;
int index;
};
struct UniformPair {
const char* name;
Variant::Type type_hint;
};
struct TexUnitPair {
const char *name;
int index;
};
struct UBOPair {
const char *name;
int index;
};
bool uniforms_dirty;
private:
//@TODO Optimize to a fixed set of shader pools and use a LRU
int uniform_count;
int texunit_pair_count;
int conditional_count;
int ubo_count;
int vertex_code_start;
int fragment_code_start;
int attribute_pair_count;
struct CustomCode {
String vertex;
String vertex_globals;
String fragment;
String fragment_globals;
String light;
uint32_t version;
Vector<StringName> custom_uniforms;
Vector<const char*> custom_defines;
};
struct Version {
GLuint id;
GLuint vert_id;
GLuint frag_id;
GLint *uniform_location;
Vector<GLint> custom_uniform_locations;
uint32_t code_version;
bool ok;
Version() { code_version=0; ok=false; uniform_location=NULL; }
};
Version *version;
union VersionKey {
struct {
uint32_t version;
uint32_t code_version;
};
uint64_t key;
bool operator==(const VersionKey& p_key) const { return key==p_key.key; }
bool operator<(const VersionKey& p_key) const { return key<p_key.key; }
};
struct VersionKeyHash {
static _FORCE_INLINE_ uint32_t hash( const VersionKey& p_key) { return HashMapHahserDefault::hash(p_key.key); };
};
//this should use a way more cachefriendly version..
HashMap<VersionKey,Version,VersionKeyHash> version_map;
HashMap<uint32_t,CustomCode> custom_code_map;
uint32_t last_custom_code;
VersionKey conditional_version;
VersionKey new_conditional_version;
virtual String get_shader_name() const=0;
const char** conditional_defines;
const char** uniform_names;
const AttributePair *attribute_pairs;
const TexUnitPair *texunit_pairs;
const UBOPair *ubo_pairs;
const char* vertex_code;
const char* fragment_code;
CharString fragment_code0;
CharString fragment_code1;
CharString fragment_code2;
CharString fragment_code3;
CharString vertex_code0;
CharString vertex_code1;
CharString vertex_code2;
Version * get_current_version();
static ShaderGLES3 *active;
int max_image_units;
_FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform,const Variant& p_value) {
if (p_uniform<0)
return; // do none
switch(p_value.get_type()) {
case Variant::BOOL:
case Variant::INT: {
int val=p_value;
glUniform1i( p_uniform, val );
} break;
case Variant::REAL: {
real_t val=p_value;
glUniform1f( p_uniform, val );
} break;
case Variant::COLOR: {
Color val=p_value;
glUniform4f( p_uniform, val.r, val.g,val.b,val.a );
} break;
case Variant::VECTOR2: {
Vector2 val=p_value;
glUniform2f( p_uniform, val.x,val.y );
} break;
case Variant::VECTOR3: {
Vector3 val=p_value;
glUniform3f( p_uniform, val.x,val.y,val.z );
} break;
case Variant::PLANE: {
Plane val=p_value;
glUniform4f( p_uniform, val.normal.x,val.normal.y,val.normal.z,val.d );
} break;
case Variant::QUAT: {
Quat val=p_value;
glUniform4f( p_uniform, val.x,val.y,val.z,val.w );
} break;
case Variant::MATRIX32: {
Matrix32 tr=p_value;
GLfloat matrix[16]={ /* build a 16x16 matrix */
tr.elements[0][0],
tr.elements[0][1],
0,
0,
tr.elements[1][0],
tr.elements[1][1],
0,
0,
0,
0,
1,
0,
tr.elements[2][0],
tr.elements[2][1],
0,
1
};
glUniformMatrix4fv(p_uniform,1,false,matrix);
} break;
case Variant::MATRIX3:
case Variant::TRANSFORM: {
Transform tr=p_value;
GLfloat matrix[16]={ /* build a 16x16 matrix */
tr.basis.elements[0][0],
tr.basis.elements[1][0],
tr.basis.elements[2][0],
0,
tr.basis.elements[0][1],
tr.basis.elements[1][1],
tr.basis.elements[2][1],
0,
tr.basis.elements[0][2],
tr.basis.elements[1][2],
tr.basis.elements[2][2],
0,
tr.origin.x,
tr.origin.y,
tr.origin.z,
1
};
glUniformMatrix4fv(p_uniform,1,false,matrix);
} break;
default: { ERR_FAIL(); } // do nothing
}
}
Map<uint32_t,Variant> uniform_defaults;
Map<uint32_t,CameraMatrix> uniform_cameras;
protected:
_FORCE_INLINE_ int _get_uniform(int p_which) const;
_FORCE_INLINE_ void _set_conditional(int p_which, bool p_value);
void setup(const char** p_conditional_defines, int p_conditional_count,const char** p_uniform_names,int p_uniform_count, const AttributePair* p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count,const char*p_vertex_code, const char *p_fragment_code,int p_vertex_code_start,int p_fragment_code_start);
ShaderGLES3();
public:
enum {
CUSTOM_SHADER_DISABLED=0
};
GLint get_uniform_location(const String& p_name) const;
GLint get_uniform_location(int p_uniform) const;
static _FORCE_INLINE_ ShaderGLES3 *get_active() { return active; };
bool bind();
void unbind();
void bind_uniforms();
inline GLuint get_program() const { return version?version->id:0; }
void clear_caches();
uint32_t create_custom_shader();
void set_custom_shader_code(uint32_t p_id,const String& p_vertex, const String& p_vertex_globals,const String& p_fragment,const String& p_p_light,const String& p_fragment_globals,const Vector<StringName>& p_uniforms,const Vector<const char*> &p_custom_defines);
void set_custom_shader(uint32_t p_id);
void free_custom_shader(uint32_t p_id);
void set_uniform_default(int p_idx, const Variant& p_value) {
if (p_value.get_type()==Variant::NIL) {
uniform_defaults.erase(p_idx);
} else {
uniform_defaults[p_idx]=p_value;
}
uniforms_dirty = true;
}
uint32_t get_version() const { return new_conditional_version.version; }
void set_uniform_camera(int p_idx, const CameraMatrix& p_mat) {
uniform_cameras[p_idx] = p_mat;
uniforms_dirty = true;
};
_FORCE_INLINE_ void set_custom_uniform(int p_idx, const Variant& p_value) {
ERR_FAIL_COND(!version);
ERR_FAIL_INDEX(p_idx,version->custom_uniform_locations.size());
_set_uniform_variant( version->custom_uniform_locations[p_idx], p_value );
}
_FORCE_INLINE_ GLint get_custom_uniform_location(int p_idx) {
ERR_FAIL_COND_V(!version,-1);
ERR_FAIL_INDEX_V(p_idx,version->custom_uniform_locations.size(),-1);
return version->custom_uniform_locations[p_idx];
}
virtual void init()=0;
void finish();
virtual ~ShaderGLES3();
};
// called a lot, made inline
int ShaderGLES3::_get_uniform(int p_which) const {
ERR_FAIL_INDEX_V( p_which, uniform_count,-1 );
ERR_FAIL_COND_V( !version, -1 );
return version->uniform_location[p_which];
}
void ShaderGLES3::_set_conditional(int p_which, bool p_value) {
ERR_FAIL_INDEX(p_which,conditional_count);
if (p_value)
new_conditional_version.version|=(1<<p_which);
else
new_conditional_version.version&=~(1<<p_which);
}
#endif

View File

@ -0,0 +1,7 @@
Import('env')
if env['BUILDERS'].has_key('GLES3_GLSL'):
env.GLES3_GLSL('copy.glsl');
env.GLES3_GLSL('canvas.glsl');
env.GLES3_GLSL('canvas_shadow.glsl');

View File

@ -0,0 +1,428 @@
[vertex]
layout(location=0) in highp vec3 vertex;
layout(location=3) in vec4 color_attrib;
#ifdef USE_TEXTURE_RECT
layout(location=1) in highp vec4 dst_rect;
layout(location=2) in highp vec4 src_rect;
#else
layout(location=4) in highp vec2 uv_attrib;
//skeletn
#endif
layout(std140) uniform CanvasItemData { //ubo:0
highp mat4 projection_matrix;
};
uniform highp mat4 modelview_matrix;
uniform highp mat4 extra_matrix;
out mediump vec2 uv_interp;
out mediump vec4 color_interp;
#if defined(USE_TIME)
uniform float time;
#endif
#ifdef USE_LIGHTING
layout(std140) uniform LightData { //ubo:1
//light matrices
highp mat4 light_matrix;
highp mat4 light_local_matrix;
highp mat4 shadow_matrix;
highp vec4 light_color;
highp vec4 light_shadow_color;
highp vec2 light_pos;
highp float shadowpixel_size;
highp float shadow_gradient;
highp float light_height;
highp float light_outside_alpha;
highp float shadow_distance_mult;
};
out vec4 light_uv_interp;
#if defined(NORMAL_USED)
out vec4 local_rot;
#endif
#ifdef USE_SHADOWS
out highp vec2 pos;
#endif
#endif
VERTEX_SHADER_GLOBALS
void main() {
color_interp = color_attrib;
#ifdef USE_TEXTURE_RECT
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.xy;
highp vec4 outvec = vec4(dst_rect.xy + dst_rect.zw * mix(vertex.xy,vec2(1.0,1.0)-vertex.xy,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0);
#else
uv_interp = uv_attrib;
highp vec4 outvec = vec4(vertex, 1.0);
#endif
{
vec2 src_vtx=outvec.xy;
VERTEX_SHADER_CODE
}
#if !defined(USE_WORLD_VEC)
outvec = extra_matrix * outvec;
outvec = modelview_matrix * outvec;
#endif
#ifdef USE_PIXEL_SNAP
outvec.xy=floor(outvec.xy+0.5);
#endif
gl_Position = projection_matrix * outvec;
#ifdef USE_LIGHTING
light_uv_interp.xy = (light_matrix * outvec).xy;
light_uv_interp.zw =(light_local_matrix * outvec).xy;
#ifdef USE_SHADOWS
pos=outvec.xy;
#endif
#if defined(NORMAL_USED)
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy );
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy );
#ifdef USE_TEXTURE_RECT
local_rot.xy*=sign(src_rect.z);
local_rot.zw*=sign(src_rect.w);
#endif
#endif
#endif
}
[fragment]
uniform mediump sampler2D color_texture; // texunit:0
in mediump vec2 uv_interp;
in mediump vec4 color_interp;
#if defined(ENABLE_TEXSCREEN)
uniform sampler2D texscreen_tex; // texunit:-3
#endif
#if defined(USE_TIME)
uniform float time;
#endif
#ifdef USE_LIGHTING
layout(std140) uniform LightData {
highp mat4 light_matrix;
highp mat4 light_local_matrix;
highp mat4 shadow_matrix;
highp vec4 light_color;
highp vec4 light_shadow_color;
highp vec2 light_pos;
highp float shadowpixel_size;
highp float shadow_gradient;
highp float light_height;
highp float light_outside_alpha;
highp float shadow_distance_mult;
};
uniform lowp sampler2D light_texture; // texunit:-1
in vec4 light_uv_interp;
#if defined(NORMAL_USED)
in vec4 local_rot;
#endif
#ifdef USE_SHADOWS
uniform highp sampler2D shadow_texture; // texunit:-2
in highp vec2 pos;
#endif
#endif
uniform mediump vec4 final_modulate;
FRAGMENT_SHADER_GLOBALS
layout(location=0) out mediump vec4 frag_color;
void main() {
vec4 color = color_interp;
#if defined(NORMAL_USED)
vec3 normal = vec3(0.0,0.0,1.0);
#endif
#ifdef USE_DISTANCE_FIELD
const float smoothing = 1.0/32.0;
float distance = texture(color_texture, uv_interp).a;
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a;
#else
color *= texture( color_texture, uv_interp );
#endif
#if defined(ENABLE_SCREEN_UV)
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
#endif
{
#if defined(USE_NORMALMAP)
vec3 normal_map=vec3(0.0,0.0,1.0);
float normal_depth=1.0;
#endif
FRAGMENT_SHADER_CODE
#if defined(USE_NORMALMAP)
normal = mix(vec3(0.0,0.0,1.0), normal_map * vec3(2.0,-2.0,1.0) - vec3( 1.0, -1.0, 0.0 ), normal_depth );
#endif
}
#ifdef DEBUG_ENCODED_32
highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) );
color = vec4(vec3(enc32),1.0);
#endif
color*=final_modulate;
#ifdef USE_LIGHTING
vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping
#if defined(NORMAL_USED)
normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
#endif
float att=1.0;
vec2 light_uv = light_uv_interp.xy;
vec4 light = texture(light_texture,light_uv) * light_color;
#if defined(USE_OUTPUT_SHADOW_COLOR)
vec4 shadow_color=vec4(0.0,0.0,0.0,0.0);
#endif
if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) {
color.a*=light_outside_alpha; //invisible
} else {
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
{
vec4 light_out=light*color;
LIGHT_SHADER_CODE
color=light_out;
}
#else
#if defined(NORMAL_USED)
vec3 light_normal = normalize(vec3(light_vec,-light_height));
light*=max(dot(-light_normal,normal),0.0);
#endif
color*=light;
/*
#ifdef USE_NORMAL
color.xy=local_rot.xy;//normal.xy;
color.zw=vec2(0.0,1.0);
#endif
*/
//light shader code
#endif
#ifdef USE_SHADOWS
float angle_to_light = -atan(light_vec.x,light_vec.y);
float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/
float su,sz;
float abs_angle = abs(angle_to_light);
vec2 point;
float sh;
if (abs_angle<45.0*PI/180.0) {
point = light_vec;
sh=0.0+(1.0/8.0);
} else if (abs_angle>135.0*PI/180.0) {
point = -light_vec;
sh = 0.5+(1.0/8.0);
} else if (angle_to_light>0.0) {
point = vec2(light_vec.y,-light_vec.x);
sh = 0.25+(1.0/8.0);
} else {
point = vec2(-light_vec.y,light_vec.x);
sh = 0.75+(1.0/8.0);
}
highp vec4 s = shadow_matrix * vec4(point,0.0,1.0);
s.xyz/=s.w;
su=s.x*0.5+0.5;
sz=s.z*0.5+0.5;
//sz=lightlength(light_vec);
highp float shadow_attenuation=0.0;
#ifdef USE_RGBA_SHADOWS
#define SHADOW_DEPTH(m_tex,m_uv) dot(texture2D((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) )
#else
#define SHADOW_DEPTH(m_tex,m_uv) (texture2D((m_tex),(m_uv)).r)
#endif
#ifdef SHADOW_USE_GRADIENT
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=1.0-smoothstep(sd,sd+shadow_gradient,sz); }
#else
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=step(sz,sd); }
#endif
#ifdef SHADOW_FILTER_NEAREST
SHADOW_TEST(su+shadowpixel_size);
#endif
#ifdef SHADOW_FILTER_PCF3
SHADOW_TEST(su+shadowpixel_size);
SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size);
shadow_attenuation/=3.0;
#endif
#ifdef SHADOW_FILTER_PCF5
SHADOW_TEST(su+shadowpixel_size*3.0);
SHADOW_TEST(su+shadowpixel_size*2.0);
SHADOW_TEST(su+shadowpixel_size);
SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0);
SHADOW_TEST(su-shadowpixel_size*3.0);
shadow_attenuation/=5.0;
#endif
#ifdef SHADOW_FILTER_PCF9
SHADOW_TEST(su+shadowpixel_size*4.0);
SHADOW_TEST(su+shadowpixel_size*3.0);
SHADOW_TEST(su+shadowpixel_size*2.0);
SHADOW_TEST(su+shadowpixel_size);
SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0);
SHADOW_TEST(su-shadowpixel_size*3.0);
SHADOW_TEST(su-shadowpixel_size*4.0);
shadow_attenuation/=9.0;
#endif
#ifdef SHADOW_FILTER_PCF13
SHADOW_TEST(su+shadowpixel_size*6.0);
SHADOW_TEST(su+shadowpixel_size*5.0);
SHADOW_TEST(su+shadowpixel_size*4.0);
SHADOW_TEST(su+shadowpixel_size*3.0);
SHADOW_TEST(su+shadowpixel_size*2.0);
SHADOW_TEST(su+shadowpixel_size);
SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0);
SHADOW_TEST(su-shadowpixel_size*3.0);
SHADOW_TEST(su-shadowpixel_size*4.0);
SHADOW_TEST(su-shadowpixel_size*5.0);
SHADOW_TEST(su-shadowpixel_size*6.0);
shadow_attenuation/=13.0;
#endif
#if defined(USE_OUTPUT_SHADOW_COLOR)
color=mix(shadow_color,color,shadow_attenuation);
#else
//color*=shadow_attenuation;
color=mix(light_shadow_color,color,shadow_attenuation);
#endif
//use shadows
#endif
}
//use lighting
#endif
// color.rgb*=color.a;
frag_color = color;
}

View File

@ -0,0 +1,49 @@
[vertex]
uniform highp mat4 projection_matrix;
uniform highp mat4 light_matrix;
uniform highp mat4 world_matrix;
uniform highp float distance_norm;
layout(location=0) in highp vec3 vertex;
out highp vec4 position_interp;
void main() {
gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex,1.0)));
position_interp=gl_Position;
}
[fragment]
in highp vec4 position_interp;
#ifdef USE_RGBA_SHADOWS
layout(location=0) out lowp vec4 distance_buf;
#else
layout(location=0) out highp float distance_buf;
#endif
void main() {
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0;//bias;
#ifdef USE_RGBA_SHADOWS
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
distance_buf=comp;
#else
distance_buf=depth;
#endif
}

View File

@ -0,0 +1,52 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
#ifdef USE_CUBEMAP
layout(location=4) in vec3 cube_in;
#else
layout(location=4) in vec2 uv_in; // attrib:4
#endif
layout(location=5) in vec2 uv2_in; // attrib:5
#ifdef USE_CUBEMAP
out vec3 cube_interp;
#else
out vec2 uv_interp;
#endif
out vec2 uv2_interp;
void main() {
#ifdef USE_CUBEMAP
cube_interp = cube_in;
#else
uv_interp = uv_in;
#endif
uv2_interp = uv2_in;
gl_Position = vertex_attrib;
}
[fragment]
#ifdef USE_CUBEMAP
in vec3 cube_interp;
uniform samplerCube source_cube;
#else
in vec2 uv_interp;
uniform sampler2D source;
#endif
in vec2 uv2_interp;
layout(location = 0) vec4 frag_color; //color:0
void main() {
//vec4 color = color_interp;
frag_color = color;
}

View File

@ -83,9 +83,9 @@ Error jpeg_load_image_from_buffer(Image *p_image,const uint8_t* p_buffer, int p_
Image::Format fmt;
if (comps==1)
fmt=Image::FORMAT_GRAYSCALE;
fmt=Image::FORMAT_L8;
else
fmt=Image::FORMAT_RGBA;
fmt=Image::FORMAT_RGBA8;
dw = DVector<uint8_t>::Write();
p_image->create(image_width,image_height,0,fmt,data);

View File

@ -113,25 +113,36 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
printf("Color type:%i\n", color);
*/
bool update_info=false;
if (depth<8) { //only bit dept 8 per channel is handled
png_set_packing(png);
update_info=true;
};
if (png_get_color_type(png,info)==PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png);
update_info=true;
}
if (depth > 8) {
png_set_strip_16(png);
png_read_update_info(png, info);
update_info=true;
}
if (png_get_valid(png,info,PNG_INFO_tRNS)) {
// png_set_expand_gray_1_2_4_to_8(png);
png_set_tRNS_to_alpha(png);
update_info=true;
}
if (update_info) {
png_read_update_info(png, info);
png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
}
int palette_colors = 0;
int palette_components = 0;
int components = 0;
Image::Format fmt;
@ -140,38 +151,24 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
case PNG_COLOR_TYPE_GRAY: {
fmt=Image::FORMAT_GRAYSCALE;
fmt=Image::FORMAT_L8;
components=1;
} break;
case PNG_COLOR_TYPE_GRAY_ALPHA: {
fmt=Image::FORMAT_GRAYSCALE_ALPHA;
fmt=Image::FORMAT_LA8;
components=2;
} break;
case PNG_COLOR_TYPE_RGB: {
fmt=Image::FORMAT_RGB;
fmt=Image::FORMAT_RGB8;
components=3;
} break;
case PNG_COLOR_TYPE_RGB_ALPHA: {
fmt=Image::FORMAT_RGBA;
fmt=Image::FORMAT_RGBA8;
components=4;
} break;
case PNG_COLOR_TYPE_PALETTE: {
int ntrans = 0;
png_get_tRNS(png, info, NULL, &ntrans, NULL);
//printf("transparent colors %i\n", ntrans);
fmt = ntrans > 0 ? Image::FORMAT_INDEXED_ALPHA : Image::FORMAT_INDEXED;
palette_components = ntrans > 0 ? 4 : 3;
components = 1;
png_colorp colors;
png_get_PLTE(png, info, &colors, &palette_colors);
} break;
default: {
ERR_PRINT("INVALID PNG TYPE");
@ -185,7 +182,7 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
DVector<uint8_t> dstbuff;
dstbuff.resize( rowsize * height + palette_components * 256 ); // alloc the entire palette? - yes always
dstbuff.resize( rowsize * height );
DVector<uint8_t>::Write dstbuff_write = dstbuff.write();
@ -199,38 +196,6 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
png_read_image(png, (png_bytep*)row_p);
if (palette_colors) {
uint8_t *r_pal = &data[components*width*height]; // end of the array
png_colorp colors;
int num;
png_get_PLTE(png, info, &colors, &num);
int ofs = 0;
for (int i=0; i < palette_colors; i++) {
r_pal[ofs + 0] = colors[i].red;
r_pal[ofs + 1] = colors[i].green;
r_pal[ofs + 2] = colors[i].blue;
if (palette_components == 4) {
r_pal[ofs + 3] = 255;
};
ofs += palette_components;
};
if (fmt == Image::FORMAT_INDEXED_ALPHA) {
png_color_16p alphas;
png_bytep alpha_idx;
int count;
png_get_tRNS(png, info, &alpha_idx, &count, &alphas);
for (int i=0; i<count; i++) {
//printf("%i: loading alpha fron transparent color %i, values %i, %i, %i, %i, %i\n", i, (int)alpha_idx[i], (int)alphas[i].index, (int)alphas[i].red, (int)alphas[i].green, (int)alphas[i].blue, (int)alphas[i].gray);
//r_pal[alpha_idx[i]] = alphas[i].gray >> 8;
r_pal[i*4+3] = alpha_idx[i];
};
};
};
memdelete_arr( row_p );
@ -324,11 +289,11 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
Image img = p_image;
if (img.get_format() > Image::FORMAT_INDEXED_ALPHA)
if (img.is_compressed())
img.decompress();
ERR_FAIL_COND_V(img.get_format() > Image::FORMAT_INDEXED_ALPHA, DVector<uint8_t>());
ERR_FAIL_COND_V(img.is_compressed(), DVector<uint8_t>());
png_structp png_ptr;
png_infop info_ptr;
@ -365,22 +330,22 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
switch(img.get_format()) {
case Image::FORMAT_GRAYSCALE: {
case Image::FORMAT_L8: {
pngf=PNG_COLOR_TYPE_GRAY;
cs=1;
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
case Image::FORMAT_LA8: {
pngf=PNG_COLOR_TYPE_GRAY_ALPHA;
cs=2;
} break;
case Image::FORMAT_RGB: {
case Image::FORMAT_RGB8: {
pngf=PNG_COLOR_TYPE_RGB;
cs=3;
} break;
case Image::FORMAT_RGBA: {
case Image::FORMAT_RGBA8: {
pngf=PNG_COLOR_TYPE_RGB_ALPHA;
cs=4;
@ -389,12 +354,12 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
if (img.detect_alpha()) {
img.convert(Image::FORMAT_RGBA);
img.convert(Image::FORMAT_RGBA8);
pngf=PNG_COLOR_TYPE_RGB_ALPHA;
cs=4;
} else {
img.convert(Image::FORMAT_RGB);
img.convert(Image::FORMAT_RGB8);
pngf=PNG_COLOR_TYPE_RGB;
cs=3;
}

View File

@ -96,10 +96,10 @@ Error ResourceSaverPNG::save(const String &p_path,const RES& p_resource,uint32_t
Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
if (p_img.get_format() > Image::FORMAT_INDEXED_ALPHA)
if (p_img.is_compressed())
p_img.decompress();
ERR_FAIL_COND_V(p_img.get_format() > Image::FORMAT_INDEXED_ALPHA, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_img.is_compressed(), ERR_INVALID_PARAMETER);
png_structp png_ptr;
png_infop info_ptr;
@ -138,22 +138,22 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
switch(p_img.get_format()) {
case Image::FORMAT_GRAYSCALE: {
case Image::FORMAT_L8: {
pngf=PNG_COLOR_TYPE_GRAY;
cs=1;
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
case Image::FORMAT_LA8: {
pngf=PNG_COLOR_TYPE_GRAY_ALPHA;
cs=2;
} break;
case Image::FORMAT_RGB: {
case Image::FORMAT_RGB8: {
pngf=PNG_COLOR_TYPE_RGB;
cs=3;
} break;
case Image::FORMAT_RGBA: {
case Image::FORMAT_RGBA8: {
pngf=PNG_COLOR_TYPE_RGB_ALPHA;
cs=4;
@ -162,12 +162,12 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
if (p_img.detect_alpha()) {
p_img.convert(Image::FORMAT_RGBA);
p_img.convert(Image::FORMAT_RGBA8);
pngf=PNG_COLOR_TYPE_RGB_ALPHA;
cs=4;
} else {
p_img.convert(Image::FORMAT_RGB);
p_img.convert(Image::FORMAT_RGB8);
pngf=PNG_COLOR_TYPE_RGB;
cs=3;
}

View File

@ -116,33 +116,33 @@ RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path,E
switch(flags&0xFF) {
case 0x18:
case 0xC: format=(flags&PVR_HAS_ALPHA)?Image::FORMAT_PVRTC2_ALPHA:Image::FORMAT_PVRTC2; break;
case 0xC: format=(flags&PVR_HAS_ALPHA)?Image::FORMAT_PVRTC2A:Image::FORMAT_PVRTC2; break;
case 0x19:
case 0xD: format=(flags&PVR_HAS_ALPHA)?Image::FORMAT_PVRTC4_ALPHA:Image::FORMAT_PVRTC4; break;
case 0xD: format=(flags&PVR_HAS_ALPHA)?Image::FORMAT_PVRTC4A:Image::FORMAT_PVRTC4; break;
case 0x16:
format=Image::FORMAT_GRAYSCALE; break;
format=Image::FORMAT_L8; break;
case 0x17:
format=Image::FORMAT_GRAYSCALE_ALPHA; break;
format=Image::FORMAT_LA8; break;
case 0x20:
case 0x80:
case 0x81:
format=Image::FORMAT_BC1; break;
format=Image::FORMAT_DXT1; break;
case 0x21:
case 0x22:
case 0x82:
case 0x83:
format=Image::FORMAT_BC2; break;
format=Image::FORMAT_DXT3; break;
case 0x23:
case 0x24:
case 0x84:
case 0x85:
format=Image::FORMAT_BC3; break;
format=Image::FORMAT_DXT5; break;
case 0x4:
case 0x15:
format=Image::FORMAT_RGB; break;
format=Image::FORMAT_RGB8; break;
case 0x5:
case 0x12:
format=Image::FORMAT_RGBA; break;
format=Image::FORMAT_RGBA8; break;
case 0x36:
format=Image::FORMAT_ETC; break;
default:
@ -198,24 +198,24 @@ static void _compress_pvrtc4(Image * p_img) {
bool make_mipmaps=false;
if (img.get_width()%8 || img.get_height()%8) {
make_mipmaps=img.get_mipmaps()>0;
make_mipmaps=img.has_mipmaps();
img.resize(img.get_width()+(8-(img.get_width()%8)),img.get_height()+(8-(img.get_height()%8)));
}
img.convert(Image::FORMAT_RGBA);
if (img.get_mipmaps()==0 && make_mipmaps)
img.convert(Image::FORMAT_RGBA8);
if (!img.has_mipmaps() && make_mipmaps)
img.generate_mipmaps();
bool use_alpha=img.detect_alpha();
Image new_img;
new_img.create(img.get_width(),img.get_height(),true,use_alpha?Image::FORMAT_PVRTC4_ALPHA:Image::FORMAT_PVRTC4);
new_img.create(img.get_width(),img.get_height(),true,use_alpha?Image::FORMAT_PVRTC4A:Image::FORMAT_PVRTC4);
DVector<uint8_t> data=new_img.get_data();
{
DVector<uint8_t>::Write wr=data.write();
DVector<uint8_t>::Read r=img.get_data().read();
for(int i=0;i<=new_img.get_mipmaps();i++) {
for(int i=0;i<=new_img.get_mipmap_count();i++) {
int ofs,size,w,h;
img.get_mipmap_offset_size_and_dimensions(i,ofs,size,w,h);
@ -234,7 +234,7 @@ static void _compress_pvrtc4(Image * p_img) {
}
*p_img = Image(new_img.get_width(),new_img.get_height(),new_img.get_mipmaps(),new_img.get_format(),data);
*p_img = Image(new_img.get_width(),new_img.get_height(),new_img.has_mipmaps(),new_img.get_format(),data);
}
@ -673,9 +673,9 @@ static void _pvrtc_decompress(Image* p_img) {
// decompress_pvrtc((PVRTCBlock*)p_comp_img,p_2bit,p_width,p_height,1,p_dst);
// }
ERR_FAIL_COND( p_img->get_format()!=Image::FORMAT_PVRTC2 && p_img->get_format()!=Image::FORMAT_PVRTC2_ALPHA && p_img->get_format()!=Image::FORMAT_PVRTC4 && p_img->get_format()!=Image::FORMAT_PVRTC4_ALPHA);
ERR_FAIL_COND( p_img->get_format()!=Image::FORMAT_PVRTC2 && p_img->get_format()!=Image::FORMAT_PVRTC2A && p_img->get_format()!=Image::FORMAT_PVRTC4 && p_img->get_format()!=Image::FORMAT_PVRTC4A);
bool _2bit = (p_img->get_format()==Image::FORMAT_PVRTC2 || p_img->get_format()==Image::FORMAT_PVRTC2_ALPHA );
bool _2bit = (p_img->get_format()==Image::FORMAT_PVRTC2 || p_img->get_format()==Image::FORMAT_PVRTC2A );
DVector<uint8_t> data = p_img->get_data();
DVector<uint8_t>::Read r = data.read();
@ -694,8 +694,8 @@ static void _pvrtc_decompress(Image* p_img) {
w=DVector<uint8_t>::Write();
r=DVector<uint8_t>::Read();
bool make_mipmaps=p_img->get_mipmaps()>0;
Image newimg(p_img->get_width(),p_img->get_height(),0,Image::FORMAT_RGBA,newdata);
bool make_mipmaps=p_img->has_mipmaps();
Image newimg(p_img->get_width(),p_img->get_height(),false,Image::FORMAT_RGBA8,newdata);
if (make_mipmaps)
newimg.generate_mipmaps();
*p_img=newimg;

View File

@ -35,7 +35,7 @@ void image_compress_squish(Image *p_image) {
int w=p_image->get_width();
int h=p_image->get_height();
if (p_image->get_mipmaps() == 0) {
if (!p_image->has_mipmaps() ) {
ERR_FAIL_COND( !w || w % 4 != 0);
ERR_FAIL_COND( !h || h % 4 != 0);
} else {
@ -43,26 +43,26 @@ void image_compress_squish(Image *p_image) {
ERR_FAIL_COND( !h || h !=nearest_power_of_2(h) );
};
if (p_image->get_format()>=Image::FORMAT_BC1)
if (p_image->get_format()>=Image::FORMAT_DXT1)
return; //do not compress, already compressed
int shift=0;
int squish_comp=squish::kColourRangeFit;
Image::Format target_format;
if (p_image->get_format()==Image::FORMAT_GRAYSCALE_ALPHA) {
if (p_image->get_format()==Image::FORMAT_LA8) {
//compressed normalmap
target_format = Image::FORMAT_BC3; squish_comp|=squish::kDxt5;;
target_format = Image::FORMAT_DXT5; squish_comp|=squish::kDxt5;;
} else if (p_image->detect_alpha()!=Image::ALPHA_NONE) {
target_format = Image::FORMAT_BC2; squish_comp|=squish::kDxt3;;
target_format = Image::FORMAT_DXT3; squish_comp|=squish::kDxt3;;
} else {
target_format = Image::FORMAT_BC1; shift=1; squish_comp|=squish::kDxt1;;
target_format = Image::FORMAT_DXT1; shift=1; squish_comp|=squish::kDxt1;;
}
p_image->convert(Image::FORMAT_RGBA); //always expects rgba
p_image->convert(Image::FORMAT_RGBA8); //always expects rgba
int mm_count = p_image->get_mipmaps();
int mm_count = p_image->get_mipmap_count();
DVector<uint8_t> data;
int target_size = Image::get_image_data_size(w,h,target_format,mm_count);
@ -85,7 +85,7 @@ void image_compress_squish(Image *p_image) {
rb = DVector<uint8_t>::Read();
wb = DVector<uint8_t>::Write();
p_image->create(p_image->get_width(),p_image->get_height(),p_image->get_mipmaps(),target_format,data);
p_image->create(p_image->get_width(),p_image->get_height(),p_image->has_mipmaps(),target_format,data);
}

View File

@ -105,7 +105,7 @@ void VideoStreamPlaybackTheora::video_write(void){
dst[p++] = 255;
};
}
format = Image::FORMAT_RGBA;
format = Image::FORMAT_RGBA8;
}
// */
@ -132,10 +132,10 @@ void VideoStreamPlaybackTheora::video_write(void){
yuv420_2_rgb8888((uint8_t*)dst, (uint8_t*)yuv[0].data, (uint8_t*)yuv[2].data, (uint8_t*)yuv[1].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x<<2, 0);
};
format = Image::FORMAT_RGBA;
format = Image::FORMAT_RGBA8;
}
Image img(size.x,size.y,0,Image::FORMAT_RGBA,frame_data); //zero copy image creation
Image img(size.x,size.y,0,Image::FORMAT_RGBA8,frame_data); //zero copy image creation
texture->set_data(img); //zero copy send to visual server
@ -204,7 +204,7 @@ void VideoStreamPlaybackTheora::video_write(void){
}
}
format = Image::FORMAT_RGBA;
format = Image::FORMAT_RGBA8;
} else {
@ -472,7 +472,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
size.x = w;
size.y = h;
texture->create(w,h,Image::FORMAT_RGBA,Texture::FLAG_FILTER|Texture::FLAG_VIDEO_SURFACE);
texture->create(w,h,Image::FORMAT_RGBA8,Texture::FLAG_FILTER|Texture::FLAG_VIDEO_SURFACE);
}else{
/* tear down the partial theora setup */

View File

@ -41,9 +41,9 @@ static DVector<uint8_t> _webp_lossy_pack(const Image& p_image,float p_quality) {
Image img=p_image;
if (img.detect_alpha())
img.convert(Image::FORMAT_RGBA);
img.convert(Image::FORMAT_RGBA8);
else
img.convert(Image::FORMAT_RGB);
img.convert(Image::FORMAT_RGB8);
Size2 s(img.get_width(),img.get_height());
DVector<uint8_t> data = img.get_data();
@ -51,7 +51,7 @@ static DVector<uint8_t> _webp_lossy_pack(const Image& p_image,float p_quality) {
uint8_t *dst_buff=NULL;
size_t dst_size=0;
if (img.get_format()==Image::FORMAT_RGB) {
if (img.get_format()==Image::FORMAT_RGB8) {
dst_size = WebPEncodeRGB(r.ptr(),s.width,s.height,3*s.width,CLAMP(p_quality*100.0,0,100.0),&dst_buff);
} else {
@ -108,7 +108,7 @@ static Image _webp_lossy_unpack(const DVector<uint8_t>& p_buffer) {
dst_w = DVector<uint8_t>::Write();
return Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB,dst_image);
return Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8,dst_image);
}
@ -160,7 +160,7 @@ Error ImageLoaderWEBP::load_image(Image *p_image,FileAccess *f) {
src_r = DVector<uint8_t>::Read();
dst_w = DVector<uint8_t>::Write();
*p_image = Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB,dst_image);
*p_image = Image(features.width,features.height,0,features.has_alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8,dst_image);
return OK;

View File

@ -123,7 +123,7 @@ def build_glsl_header( filename ):
uline=line[:line.lower().find("//")]
uline = uline[uline.find("uniform")+len("uniform"):];
uline = uline.replace(";","");
uline = uline.replace("{","");
uline = uline.replace("{","").strip();
lines = uline.split(",")
for x in lines:
@ -767,9 +767,31 @@ def include_file_in_legacygl_header( filename, header_data, depth ):
header_data.texunits+=[(x,texunit)]
header_data.texunit_names+=[x]
elif (line.find("uniform")!=-1 and line.lower().find("ubo:")!=-1):
#uniform buffer object
ubostr = line[line.find(":")+1:].strip()
ubo = str(int(ubostr ))
uline=line[:line.lower().find("//")]
uline = uline[uline.find("uniform")+len("uniform"):];
uline = uline.replace("highp","");
uline = uline.replace(";","");
uline = uline.replace("{","").strip();
lines = uline.split(",")
for x in lines:
x = x.strip()
x = x[ x.rfind(" ")+1: ]
if (x.find("[")!=-1):
#unfiorm array
x = x[ :x.find("[") ]
if (not x in header_data.ubo_names):
header_data.ubos+=[(x,ubo)]
header_data.ubo_names+=[x]
elif (line.find("uniform")!=-1):
elif (line.find("uniform")!=-1 and line.find("{")==-1 and line.find(";")!=-1):
uline = line.replace("uniform","");
uline = uline.replace(";","");
lines = uline.split(",")
@ -785,7 +807,7 @@ def include_file_in_legacygl_header( filename, header_data, depth ):
header_data.uniforms+=[x]
if ((line.strip().find("in ")==0 or line.strip().find("attribute ")==0) and line.find("attrib:")!=-1):
if ( line.strip().find("attribute ")==0 and line.find("attrib:")!=-1):
uline = line.replace("in ","");
uline = uline.replace("attribute ","");
uline = uline.replace("highp ","");
@ -1036,6 +1058,7 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
else:
fd.write("\t\tstatic const char **_uniform_strings=NULL;\n")
if output_attribs:
if (len(header_data.attributes)):
@ -1055,6 +1078,14 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
else:
fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n")
if (len(header_data.ubos)):
fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n")
for x in header_data.ubos:
fd.write("\t\t\t{\""+x[0]+"\","+x[1]+"},\n");
fd.write("\t\t};\n\n");
else:
fd.write("\t\tstatic UBOPair *_ubo_pairs=NULL;\n")
fd.write("\t\tstatic const char _vertex_code[]={\n")
for x in header_data.vertex_lines:
for i in range(len(x)):
@ -1077,9 +1108,9 @@ def build_legacygl_header( filename, include, class_suffix, output_attribs ):
fd.write("\t\tstatic const int _fragment_code_start="+str(header_data.fragment_offset)+";\n")
if output_attribs:
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_attribute_pairs,"+str(len(header_data.attributes))+", _texunit_pairs,"+str(len(header_data.texunits))+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_attribute_pairs,"+str(len(header_data.attributes))+", _texunit_pairs,"+str(len(header_data.texunits))+",_ubo_pairs,"+str(len(header_data.ubos))+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
else:
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_texunit_pairs,"+str(len(header_data.texunits))+",_enums,"+str(len(header_data.enums))+",_enum_values,"+str(enum_value_count)+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
fd.write("\t\tsetup(_conditional_strings,"+str(len(header_data.conditionals))+",_uniform_strings,"+str(len(header_data.uniforms))+",_texunit_pairs,"+str(len(header_data.texunits))+",_enums,"+str(len(header_data.enums))+",_enum_values,"+str(enum_value_count)+",_ubo_pairs,"+str(len(header_data.ubos))+",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
fd.write("\t};\n\n")
@ -1112,6 +1143,11 @@ def build_gles2_headers( target, source, env ):
for x in source:
build_legacygl_header(str(x), include="drivers/gles2/shader_gles2.h", class_suffix = "GLES2", output_attribs = True)
def build_gles3_headers( target, source, env ):
for x in source:
build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix = "GLES3", output_attribs = True)
def update_version():
rev = "custom_build"

View File

@ -1,7 +1,7 @@
def can_build(platform):
return True
return False
def configure(env):

View File

@ -134,21 +134,21 @@ static Image _get_gl_image_and_format(const Image& p_image, Image::Format p_form
switch(p_format) {
case Image::FORMAT_GRAYSCALE: {
case Image::FORMAT_L8: {
r_gl_components=1;
r_gl_format=GL_LUMINANCE;
} break;
case Image::FORMAT_INTENSITY: {
image.convert(Image::FORMAT_RGBA);
image.convert(Image::FORMAT_RGBA8);
r_gl_components=4;
r_gl_format=GL_RGBA;
r_has_alpha_cache=true;
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
case Image::FORMAT_LA8: {
image.convert(Image::FORMAT_RGBA);
image.convert(Image::FORMAT_RGBA8);
r_gl_components=4;
r_gl_format=GL_RGBA;
r_has_alpha_cache=true;
@ -156,7 +156,7 @@ static Image _get_gl_image_and_format(const Image& p_image, Image::Format p_form
case Image::FORMAT_INDEXED: {
image.convert(Image::FORMAT_RGB);
image.convert(Image::FORMAT_RGB8);
r_gl_components=3;
r_gl_format=GL_RGB;
@ -164,17 +164,17 @@ static Image _get_gl_image_and_format(const Image& p_image, Image::Format p_form
case Image::FORMAT_INDEXED_ALPHA: {
image.convert(Image::FORMAT_RGBA);
image.convert(Image::FORMAT_RGBA8);
r_gl_components=4;
r_gl_format=GL_RGB;
r_has_alpha_cache=true;
} break;
case Image::FORMAT_RGB: {
case Image::FORMAT_RGB8: {
r_gl_components=3; r_gl_format=GL_RGB;
} break;
case Image::FORMAT_RGBA: {
case Image::FORMAT_RGBA8: {
r_gl_components=4;
r_gl_format=GL_RGBA;
@ -344,7 +344,7 @@ Image::Format RasterizerIPhone::texture_get_format(RID p_texture) const {
Texture * texture = texture_owner.get(p_texture);
ERR_FAIL_COND_V(!texture,Image::FORMAT_GRAYSCALE);
ERR_FAIL_COND_V(!texture,Image::FORMAT_L8);
return texture->format;
}

View File

@ -74,7 +74,7 @@ class RasterizerIPhone : public Rasterizer {
flags=width=height=0;
tex_id=0;
format=Image::FORMAT_GRAYSCALE;
format=Image::FORMAT_L8;
gl_components_cache=0;
format_has_alpha=false;
has_alpha=false;

View File

@ -207,7 +207,7 @@ void EditorExportPlatformOSX::_make_icon(const Image& p_icon,Vector<uint8_t>& ic
while(size>=16) {
Image copy = p_icon;
copy.convert(Image::FORMAT_RGBA);
copy.convert(Image::FORMAT_RGBA8);
copy.resize(size,size);
it->create_from_image(copy);
String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/icon.png";

View File

@ -1313,7 +1313,7 @@ void OS_OSX::set_window_title(const String& p_title) {
void OS_OSX::set_icon(const Image& p_icon) {
Image img=p_icon;
img.convert(Image::FORMAT_RGBA);
img.convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep= [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
pixelsWide: p_icon.get_width()
pixelsHigh: p_icon.get_height()

View File

@ -27,5 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include <alloca.h>
#define GLES2_INCLUDE_H "gl_context/GL/glew.h"
#define GLES3_INCLUDE_H "gl_context/GL/glew.h"
#define PTHREAD_RENAME_SELF

View File

@ -26,8 +26,8 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/rasterizer_dummy.h"
//#include "servers/visual/visual_server_raster.h"
//#include "servers/visual/rasterizer_dummy.h"
#include "os_server.h"
#include <stdio.h>
#include <stdlib.h>
@ -57,9 +57,9 @@ void OS_Server::initialize(const VideoMode& p_desired,int p_video_driver,int p_a
current_videomode=p_desired;
main_loop=NULL;
rasterizer = memnew( RasterizerDummy );
//rasterizer = memnew( RasterizerDummy );
visual_server = memnew( VisualServerRaster(rasterizer) );
//visual_server = memnew( VisualServerRaster(rasterizer) );
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
@ -114,7 +114,7 @@ void OS_Server::finalize() {
visual_server->finish();
memdelete(visual_server);
memdelete(rasterizer);
//memdelete(rasterizer);
physics_server->finish();
memdelete(physics_server);

View File

@ -51,7 +51,7 @@
class OS_Server : public OS_Unix {
Rasterizer *rasterizer;
// Rasterizer *rasterizer;
VisualServer *visual_server;
VideoMode current_videomode;
List<String> args;

View File

@ -2081,8 +2081,8 @@ void OS_Windows::set_icon(const Image& p_icon) {
Image icon=p_icon;
if (icon.get_format()!=Image::FORMAT_RGBA)
icon.convert(Image::FORMAT_RGBA);
if (icon.get_format()!=Image::FORMAT_RGBA8)
icon.convert(Image::FORMAT_RGBA8);
int w = icon.get_width();
int h = icon.get_height();

View File

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

View File

@ -140,6 +140,7 @@ Error ContextGL_X11::initialize() {
static int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None
};

View File

@ -198,9 +198,9 @@ def configure(env):
import methods
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
#env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
#env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
#env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
#env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
if (env["use_static_cpp"]=="yes"):

View File

@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "servers/visual/visual_server_raster.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
#include "os_x11.h"
#include "key_mapping_x11.h"
#include <stdio.h>
@ -74,7 +74,7 @@ int OS_X11::get_video_driver_count() const {
}
const char * OS_X11::get_video_driver_name(int p_driver) const {
return "GLES2";
return "GLES3";
}
OS::VideoMode OS_X11::get_default_video_mode() const {
@ -203,19 +203,22 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
//print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height));
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) );
context_gl->initialize();
rasterizer = memnew( RasterizerGLES2 );
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
#endif
visual_server = memnew( VisualServerRaster(rasterizer) );
visual_server = memnew( VisualServerRaster );
#if 0
if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
}
#endif
// borderless fullscreen window mode
if (current_videomode.fullscreen) {
// needed for lxde/openbox, possibly others
@ -487,7 +490,7 @@ void OS_X11::finalize() {
visual_server->finish();
memdelete(visual_server);
memdelete(rasterizer);
//memdelete(rasterizer);
physics_server->finish();
memdelete(physics_server);
@ -1878,7 +1881,7 @@ void OS_X11::set_icon(const Image& p_icon) {
if (!p_icon.empty()) {
Image img=p_icon;
img.convert(Image::FORMAT_RGBA);
img.convert(Image::FORMAT_RGBA8);
int w = img.get_width();
int h = img.get_height();

View File

@ -34,7 +34,7 @@
#include "drivers/unix/os_unix.h"
#include "context_gl_x11.h"
#include "servers/visual_server.h"
#include "servers/visual/visual_server_wrap_mt.h"
//#include "servers/visual/visual_server_wrap_mt.h"
#include "servers/visual/rasterizer.h"
#include "servers/physics_server.h"
#include "servers/audio/audio_server_sw.h"
@ -99,7 +99,7 @@ class OS_X11 : public OS_Unix {
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
ContextGL_X11 *context_gl;
#endif
Rasterizer *rasterizer;
//Rasterizer *rasterizer;
VisualServer *visual_server;
VideoMode current_videomode;
List<String> args;

View File

@ -35,5 +35,6 @@
#endif
#define GLES2_INCLUDE_H "gl_context/GL/glew.h"
#define GLES3_INCLUDE_H "gl_context/GL/glew.h"

View File

@ -42,9 +42,6 @@ bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value)
if (p_name==SceneStringNames::get_singleton()->shader_shader) {
set_shader(p_value);
return true;
} else if (p_name==SceneStringNames::get_singleton()->shading_mode) {
set_shading_mode(ShadingMode(p_value.operator int()));
return true;
} else {
if (shader.is_valid()) {
@ -58,7 +55,7 @@ bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value)
}
}
if (pr) {
VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value);
VisualServer::get_singleton()->material_set_param(material,pr,p_value);
return true;
}
}
@ -74,18 +71,14 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const {
r_ret=get_shader();
return true;
} else if (p_name==SceneStringNames::get_singleton()->shading_mode) {
r_ret=shading_mode;
return true;
} else {
if (shader.is_valid()) {
StringName pr = shader->remap_param(p_name);
if (pr) {
r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr);
r_ret=VisualServer::get_singleton()->material_get_param(material,pr);
return true;
}
}
@ -100,7 +93,6 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const {
void CanvasItemMaterial::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) );
p_list->push_back( PropertyInfo( Variant::INT, "shader/shading_mode",PROPERTY_HINT_ENUM,"Normal,Unshaded,Light Only") );
if (!shader.is_null()) {
@ -119,7 +111,7 @@ void CanvasItemMaterial::set_shader(const Ref<Shader>& p_shader) {
if (shader.is_valid())
rid=shader->get_rid();
VS::get_singleton()->canvas_item_material_set_shader(material,rid);
VS::get_singleton()->material_set_shader(material,rid);
_change_notify(); //properties for shader exposed
emit_changed();
}
@ -131,12 +123,12 @@ Ref<Shader> CanvasItemMaterial::get_shader() const{
void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){
VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value);
VS::get_singleton()->material_set_param(material,p_param,p_value);
}
Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{
return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param);
return VS::get_singleton()->material_get_param(material,p_param);
}
RID CanvasItemMaterial::get_rid() const {
@ -144,16 +136,6 @@ RID CanvasItemMaterial::get_rid() const {
return material;
}
void CanvasItemMaterial::set_shading_mode(ShadingMode p_mode) {
shading_mode=p_mode;
VS::get_singleton()->canvas_item_material_set_shading_mode(material,VS::CanvasItemShadingMode(p_mode));
}
CanvasItemMaterial::ShadingMode CanvasItemMaterial::get_shading_mode() const {
return shading_mode;
}
void CanvasItemMaterial::_bind_methods() {
@ -161,12 +143,7 @@ void CanvasItemMaterial::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader);
ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param);
ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param);
ObjectTypeDB::bind_method(_MD("set_shading_mode","mode"),&CanvasItemMaterial::set_shading_mode);
ObjectTypeDB::bind_method(_MD("get_shading_mode"),&CanvasItemMaterial::get_shading_mode);
BIND_CONSTANT( SHADING_NORMAL );
BIND_CONSTANT( SHADING_UNSHADED );
BIND_CONSTANT( SHADING_ONLY_LIGHT );
}
@ -189,13 +166,13 @@ void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p
CanvasItemMaterial::CanvasItemMaterial() {
material=VS::get_singleton()->canvas_item_material_create();
shading_mode=SHADING_NORMAL;
}
CanvasItemMaterial::~CanvasItemMaterial(){
VS::get_singleton()->free(material);
}
@ -374,6 +351,8 @@ Matrix32 CanvasItem::get_global_transform_with_canvas() const {
return last_valid->canvas_layer->get_transform() * xform;
else if (is_inside_tree())
return get_viewport()->get_canvas_transform() * xform;
return xform;
}
Matrix32 CanvasItem::get_global_transform() const {
@ -394,42 +373,17 @@ Matrix32 CanvasItem::get_global_transform() const {
}
void CanvasItem::_queue_sort_children() {
if (pending_children_sort)
return;
pending_children_sort=true;
MessageQueue::get_singleton()->push_call(this,"_sort_children");
}
void CanvasItem::_sort_children() {
pending_children_sort=false;
void CanvasItem::_toplevel_raise_self() {
if (!is_inside_tree())
return;
for(int i=0;i<get_child_count();i++) {
if (canvas_layer)
VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,canvas_layer->get_sort_index());
else
VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_viewport()->gui_get_canvas_sort_index());
Node *n = get_child(i);
CanvasItem *ci=n->cast_to<CanvasItem>();
if (ci) {
if (ci->toplevel || ci->group!="")
continue;
VisualServer::get_singleton()->canvas_item_raise(n->cast_to<CanvasItem>()->canvas_item);
}
}
}
void CanvasItem::_raise_self() {
if (!is_inside_tree())
return;
VisualServer::get_singleton()->canvas_item_raise(canvas_item);
}
@ -461,14 +415,19 @@ void CanvasItem::_enter_canvas() {
group = "root_canvas"+itos(canvas.get_id());
add_to_group(group);
get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self");
if (canvas_layer)
canvas_layer->reset_sort_index();
else
get_viewport()->gui_reset_canvas_sort_index();
get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_toplevel_raise_self");
} else {
CanvasItem *parent = get_parent_item();
canvas_layer=parent->canvas_layer;
VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item());
parent->_queue_sort_children();
VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_index());
}
pending_update=false;
@ -495,7 +454,6 @@ void CanvasItem::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
first_draw=true;
pending_children_sort=false;
if (get_parent()) {
CanvasItem *ci = get_parent()->cast_to<CanvasItem>();
if (ci)
@ -508,13 +466,15 @@ void CanvasItem::_notification(int p_what) {
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
if (!is_inside_tree())
break;
if (group!="") {
get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self");
get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_toplevel_raise_self");
} else {
CanvasItem *p = get_parent_item();
ERR_FAIL_COND(!p);
p->_queue_sort_children();
VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item,get_index());
}
@ -569,15 +529,15 @@ void CanvasItem::update() {
MessageQueue::get_singleton()->push_call(this,"_update_callback");
}
void CanvasItem::set_opacity(float p_opacity) {
void CanvasItem::set_modulate(const Color& p_modulate) {
opacity=p_opacity;
VisualServer::get_singleton()->canvas_item_set_opacity(canvas_item,opacity);
modulate=p_modulate;
VisualServer::get_singleton()->canvas_item_set_modulate(canvas_item,modulate);
}
float CanvasItem::get_opacity() const {
Color CanvasItem::get_modulate() const {
return opacity;
return modulate;
}
@ -614,29 +574,17 @@ CanvasItem *CanvasItem::get_parent_item() const {
}
void CanvasItem::set_self_opacity(float p_self_opacity) {
void CanvasItem::set_self_modulate(const Color& p_self_modulate) {
self_opacity=p_self_opacity;
VisualServer::get_singleton()->canvas_item_set_self_opacity(canvas_item,self_opacity);
self_modulate=p_self_modulate;
VisualServer::get_singleton()->canvas_item_set_self_modulate(canvas_item,self_modulate);
}
float CanvasItem::get_self_opacity() const {
Color CanvasItem::get_self_modulate() const {
return self_opacity;
return self_modulate;
}
void CanvasItem::set_blend_mode(BlendMode p_blend_mode) {
ERR_FAIL_INDEX(p_blend_mode,5);
blend_mode=p_blend_mode;
VisualServer::get_singleton()->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(blend_mode));
}
CanvasItem::BlendMode CanvasItem::get_blend_mode() const {
return blend_mode;
}
void CanvasItem::set_light_mask(int p_light_mask) {
@ -913,7 +861,7 @@ void CanvasItem::set_draw_behind_parent(bool p_enable) {
if (behind==p_enable)
return;
behind=p_enable;
VisualServer::get_singleton()->canvas_item_set_on_top(canvas_item,!behind);
VisualServer::get_singleton()->canvas_item_set_draw_behind_parent(canvas_item,behind);
}
@ -983,8 +931,7 @@ Vector2 CanvasItem::get_local_mouse_pos() const{
void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_sort_children"),&CanvasItem::_sort_children);
ObjectTypeDB::bind_method(_MD("_raise_self"),&CanvasItem::_raise_self);
ObjectTypeDB::bind_method(_MD("_toplevel_raise_self"),&CanvasItem::_toplevel_raise_self);
ObjectTypeDB::bind_method(_MD("_update_callback"),&CanvasItem::_update_callback);
ObjectTypeDB::bind_method(_MD("_set_visible_"),&CanvasItem::_set_visible_);
ObjectTypeDB::bind_method(_MD("_is_visible_"),&CanvasItem::_is_visible_);
@ -1011,16 +958,13 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_as_toplevel","enable"),&CanvasItem::set_as_toplevel);
ObjectTypeDB::bind_method(_MD("is_set_as_toplevel"),&CanvasItem::is_set_as_toplevel);
ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode);
ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode);
ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask);
ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask);
ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity);
ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity);
ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity);
ObjectTypeDB::bind_method(_MD("get_self_opacity"),&CanvasItem::get_self_opacity);
ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&CanvasItem::set_modulate);
ObjectTypeDB::bind_method(_MD("get_modulate"),&CanvasItem::get_modulate);
ObjectTypeDB::bind_method(_MD("set_self_modulate","self_modulate"),&CanvasItem::set_self_modulate);
ObjectTypeDB::bind_method(_MD("get_self_modulate"),&CanvasItem::get_self_modulate);
ObjectTypeDB::bind_method(_MD("set_draw_behind_parent","enable"),&CanvasItem::set_draw_behind_parent);
ObjectTypeDB::bind_method(_MD("is_draw_behind_parent_enabled"),&CanvasItem::is_draw_behind_parent_enabled);
@ -1069,12 +1013,11 @@ void CanvasItem::_bind_methods() {
BIND_VMETHOD(MethodInfo("_draw"));
ADD_PROPERTYNO( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity") );
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/self_opacity",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_opacity"),_SCS("get_self_opacity") );
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/modulate",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_modulate"),_SCS("get_modulate") );
ADD_PROPERTYNO( PropertyInfo(Variant::REAL,"visibility/self_modulate",PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_self_modulate"),_SCS("get_self_modulate") );
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
ADD_PROPERTYNO( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") );
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") );
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") );
@ -1176,12 +1119,10 @@ CanvasItem::CanvasItem() : xform_change(this) {
canvas_item=VisualServer::get_singleton()->canvas_item_create();
hidden=false;
pending_update=false;
opacity=1;
self_opacity=1;
modulate=Color(1,1,1,1);
self_modulate=Color(1,1,1,1);
toplevel=false;
pending_children_sort=false;
first_draw=false;
blend_mode=BLEND_MODE_MIX;
drawing=false;
behind=false;
block_transform_notify=false;

View File

@ -33,6 +33,7 @@
#include "scene/resources/texture.h"
#include "scene/main/scene_main_loop.h"
#include "scene/resources/shader.h"
#include "scene/resources/material.h"
class CanvasLayer;
class Viewport;
@ -40,22 +41,19 @@ class Font;
class StyleBox;
class CanvasItemMaterial : public Resource{
class CanvasItemMaterial : public Material{
OBJ_TYPE(CanvasItemMaterial,Resource);
OBJ_TYPE(CanvasItemMaterial,Material);
RID material;
Ref<Shader> shader;
public:
enum ShadingMode {
/*enum ShadingMode {
SHADING_NORMAL,
SHADING_UNSHADED,
SHADING_ONLY_LIGHT,
};
};*/
protected:
ShadingMode shading_mode;
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
@ -72,15 +70,12 @@ public:
void set_shader_param(const StringName& p_param,const Variant& p_value);
Variant get_shader_param(const StringName& p_param) const;
void set_shading_mode(ShadingMode p_mode);
ShadingMode get_shading_mode() const;
virtual RID get_rid() const;
CanvasItemMaterial();
~CanvasItemMaterial();
};
VARIANT_ENUM_CAST( CanvasItemMaterial::ShadingMode );
class CanvasItem : public Node {
@ -107,8 +102,8 @@ private:
CanvasLayer *canvas_layer;
float opacity;
float self_opacity;
Color modulate;
Color self_modulate;
List<CanvasItem*> children_items;
List<CanvasItem*>::Element *C;
@ -120,7 +115,6 @@ private:
bool hidden;
bool pending_update;
bool toplevel;
bool pending_children_sort;
bool drawing;
bool block_transform_notify;
bool behind;
@ -133,7 +127,7 @@ private:
mutable bool global_invalid;
void _raise_self();
void _toplevel_raise_self();
void _propagate_visibility_changed(bool p_visible);
@ -145,9 +139,6 @@ private:
void _enter_canvas();
void _exit_canvas();
void _queue_sort_children();
void _sort_children();
void _notify_transform(CanvasItem *p_node);
void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
@ -193,17 +184,14 @@ public:
void update();
void set_blend_mode(BlendMode p_blend_mode);
BlendMode get_blend_mode() const;
virtual void set_light_mask(int p_light_mask);
int get_light_mask() const;
void set_opacity(float p_opacity);
float get_opacity() const;
void set_modulate(const Color& p_modulate);
Color get_modulate() const;
void set_self_opacity(float p_self_opacity);
float get_self_opacity() const;
void set_self_modulate(const Color& p_self_modulate);
Color get_self_modulate() const;
/* DRAWING API */

View File

@ -208,26 +208,26 @@ int Light2D::get_layer_range_max() const {
return layer_max;
}
void Light2D::set_item_mask( int p_mask) {
void Light2D::set_item_cull_mask( int p_mask) {
item_mask=p_mask;
VS::get_singleton()->canvas_light_set_item_mask(canvas_light,item_mask);
VS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light,item_mask);
}
int Light2D::get_item_mask() const {
int Light2D::get_item_cull_mask() const {
return item_mask;
}
void Light2D::set_item_shadow_mask( int p_mask) {
void Light2D::set_item_shadow_cull_mask( int p_mask) {
item_shadow_mask=p_mask;
VS::get_singleton()->canvas_light_set_item_shadow_mask(canvas_light,item_shadow_mask);
VS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light,item_shadow_mask);
}
int Light2D::get_item_shadow_mask() const {
int Light2D::get_item_shadow_cull_mask() const {
return item_shadow_mask;
}
@ -265,17 +265,30 @@ int Light2D::get_shadow_buffer_size() const {
return shadow_buffer_size;
}
void Light2D::set_shadow_esm_multiplier( float p_multiplier) {
void Light2D::set_shadow_gradient_length( float p_multiplier) {
shadow_esm_multiplier=p_multiplier;
VS::get_singleton()->canvas_light_set_shadow_esm_multiplier(canvas_light,p_multiplier);
shadow_gradient_length=p_multiplier;
VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light,p_multiplier);
}
float Light2D::get_shadow_esm_multiplier() const{
float Light2D::get_shadow_gradient_length() const{
return shadow_esm_multiplier;
return shadow_gradient_length;
}
void Light2D::set_shadow_filter( ShadowFilter p_filter) {
shadow_filter=p_filter;
VS::get_singleton()->canvas_light_set_shadow_filter(canvas_light,VS::CanvasLightShadowFilter(p_filter ));
}
Light2D::ShadowFilter Light2D::get_shadow_filter() const {
return shadow_filter;
}
void Light2D::set_shadow_color( const Color& p_shadow_color) {
shadow_color=p_shadow_color;
VS::get_singleton()->canvas_light_set_shadow_color(canvas_light,shadow_color);
@ -360,11 +373,11 @@ void Light2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_layer_range_max"),&Light2D::get_layer_range_max);
ObjectTypeDB::bind_method(_MD("set_item_mask","item_mask"),&Light2D::set_item_mask);
ObjectTypeDB::bind_method(_MD("get_item_mask"),&Light2D::get_item_mask);
ObjectTypeDB::bind_method(_MD("set_item_cull_mask","item_cull_mask"),&Light2D::set_item_cull_mask);
ObjectTypeDB::bind_method(_MD("get_item_cull_mask"),&Light2D::get_item_cull_mask);
ObjectTypeDB::bind_method(_MD("set_item_shadow_mask","item_shadow_mask"),&Light2D::set_item_shadow_mask);
ObjectTypeDB::bind_method(_MD("get_item_shadow_mask"),&Light2D::get_item_shadow_mask);
ObjectTypeDB::bind_method(_MD("set_item_shadow_cull_mask","item_shadow_cull_mask"),&Light2D::set_item_shadow_cull_mask);
ObjectTypeDB::bind_method(_MD("get_item_shadow_cull_mask"),&Light2D::get_item_shadow_cull_mask);
ObjectTypeDB::bind_method(_MD("set_mode","mode"),&Light2D::set_mode);
ObjectTypeDB::bind_method(_MD("get_mode"),&Light2D::get_mode);
@ -375,8 +388,11 @@ void Light2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_shadow_buffer_size","size"),&Light2D::set_shadow_buffer_size);
ObjectTypeDB::bind_method(_MD("get_shadow_buffer_size"),&Light2D::get_shadow_buffer_size);
ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier);
ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier);
ObjectTypeDB::bind_method(_MD("set_shadow_gradient_length","multiplier"),&Light2D::set_shadow_gradient_length);
ObjectTypeDB::bind_method(_MD("get_shadow_gradient_length"),&Light2D::get_shadow_gradient_length);
ObjectTypeDB::bind_method(_MD("set_shadow_filter","filter"),&Light2D::set_shadow_filter);
ObjectTypeDB::bind_method(_MD("get_shadow_filter"),&Light2D::get_shadow_filter);
ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"),&Light2D::set_shadow_color);
ObjectTypeDB::bind_method(_MD("get_shadow_color"),&Light2D::get_shadow_color);
@ -394,12 +410,13 @@ void Light2D::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_cull_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_cull_mask"),_SCS("get_item_cull_mask"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::COLOR,"shadow/color"),_SCS("set_shadow_color"),_SCS("get_shadow_color"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_mask"),_SCS("get_item_shadow_mask"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/gradient_length",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_gradient_length"),_SCS("get_shadow_gradient_length"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/filter",PROPERTY_HINT_ENUM,"None,PCF3,PCF5,PCF9,PCF13"),_SCS("set_shadow_filter"),_SCS("get_shadow_filter"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_cull_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_cull_mask"),_SCS("get_item_shadow_cull_mask"));
BIND_CONSTANT( MODE_ADD );
BIND_CONSTANT( MODE_SUB );
@ -425,9 +442,10 @@ Light2D::Light2D() {
item_shadow_mask=1;
mode=MODE_ADD;
shadow_buffer_size=2048;
shadow_esm_multiplier=80;
shadow_gradient_length=0;
energy=1.0;
shadow_color=Color(0,0,0,0);
shadow_filter=SHADOW_FILTER_NONE;
}

View File

@ -42,6 +42,14 @@ public:
MODE_MASK,
};
enum ShadowFilter {
SHADOW_FILTER_NONE,
SHADOW_FILTER_PCF3,
SHADOW_FILTER_PCF5,
SHADOW_FILTER_PCF9,
SHADOW_FILTER_PCF13,
};
private:
RID canvas_light;
bool enabled;
@ -58,10 +66,12 @@ private:
int item_mask;
int item_shadow_mask;
int shadow_buffer_size;
float shadow_esm_multiplier;
float shadow_gradient_length;
Mode mode;
Ref<Texture> texture;
Vector2 texture_offset;
ShadowFilter shadow_filter;
void _update_light_visibility();
protected:
@ -108,11 +118,11 @@ public:
void set_layer_range_max( int p_max_layer);
int get_layer_range_max() const;
void set_item_mask( int p_mask);
int get_item_mask() const;
void set_item_cull_mask( int p_mask);
int get_item_cull_mask() const;
void set_item_shadow_mask( int p_mask);
int get_item_shadow_mask() const;
void set_item_shadow_cull_mask( int p_mask);
int get_item_shadow_cull_mask() const;
void set_mode( Mode p_mode );
Mode get_mode() const;
@ -123,8 +133,11 @@ public:
void set_shadow_buffer_size( int p_size );
int get_shadow_buffer_size() const;
void set_shadow_esm_multiplier( float p_multiplier);
float get_shadow_esm_multiplier() const;
void set_shadow_gradient_length( float p_multiplier);
float get_shadow_gradient_length() const;
void set_shadow_filter( ShadowFilter p_filter);
ShadowFilter get_shadow_filter() const;
void set_shadow_color( const Color& p_shadow_color);
Color get_shadow_color() const;
@ -139,5 +152,7 @@ public:
};
VARIANT_ENUM_CAST(Light2D::Mode);
VARIANT_ENUM_CAST(Light2D::ShadowFilter);
#endif // LIGHT_2D_H

View File

@ -376,7 +376,7 @@ Sprite::Sprite() {
///
///
#if 0
void ViewportSprite::edit_set_pivot(const Point2& p_pivot) {
set_offset(p_pivot);
@ -588,3 +588,4 @@ ViewportSprite::ViewportSprite() {
centered=true;
modulate=Color(1,1,1,1);
}
#endif

View File

@ -107,6 +107,7 @@ public:
Sprite();
};
#if 0
class ViewportSprite : public Node2D {
OBJ_TYPE( ViewportSprite, Node2D );
@ -149,4 +150,5 @@ public:
ViewportSprite();
};
#endif
#endif // SPRITE_H

View File

@ -477,7 +477,7 @@ void TileMap::_update_dirty_quadrants() {
_fix_cell_transform(xform,c,shape_ofs+center_ofs,s);
if (debug_canvas_item) {
if (debug_canvas_item.is_valid()) {
vs->canvas_item_add_set_transform(debug_canvas_item,xform);
shape->draw(debug_canvas_item,debug_collision_color);
@ -488,7 +488,7 @@ void TileMap::_update_dirty_quadrants() {
}
}
if (debug_canvas_item) {
if (debug_canvas_item.is_valid()) {
vs->canvas_item_add_set_transform(debug_canvas_item,Matrix32());
}
@ -541,26 +541,19 @@ void TileMap::_update_dirty_quadrants() {
if (quadrant_order_dirty) {
int index=-0x80000000; //always must be drawn below children
for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
Quadrant &q=E->get();
for (List<RID>::Element *E=q.canvas_items.front();E;E=E->next()) {
VS::get_singleton()->canvas_item_raise(E->get());
VS::get_singleton()->canvas_item_set_draw_index(E->get(),index++);
}
}
quadrant_order_dirty=false;
}
for(int i=0;i<get_child_count();i++) {
CanvasItem *c=get_child(i)->cast_to<CanvasItem>();
if (c)
VS::get_singleton()->canvas_item_raise(c->get_canvas_item());
}
_recompute_rect_cache();
}

View File

@ -29,6 +29,7 @@
#include "baked_light_instance.h"
#include "scene/scene_string_names.h"
#if 0
RID BakedLightInstance::get_baked_light_instance() const {
@ -179,3 +180,4 @@ BakedLightSampler::~BakedLightSampler(){
VS::get_singleton()->free(base);
}
#endif

View File

@ -32,6 +32,7 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/baked_light.h"
#if 0
class BakedLightBaker;
@ -101,5 +102,5 @@ public:
VARIANT_ENUM_CAST( BakedLightSampler::Param );
#endif
#endif // BAKED_LIGHT_H

View File

@ -96,8 +96,8 @@ bool Camera::_set(const StringName& p_name, const Variant& p_value) {
} else {
clear_current();
}
} else if (p_name=="visible_layers") {
set_visible_layers(p_value);
} else if (p_name=="cull_mask") {
set_cull_mask(p_value);
} else if (p_name=="environment") {
set_environment(p_value);
} else
@ -130,8 +130,8 @@ bool Camera::_get(const StringName& p_name,Variant &r_ret) const {
} else {
r_ret=is_current();
}
} else if (p_name=="visible_layers") {
r_ret=get_visible_layers();
} else if (p_name=="cull_mask") {
r_ret=get_cull_mask();
} else if (p_name=="h_offset") {
r_ret=get_h_offset();
} else if (p_name=="v_offset") {
@ -176,7 +176,7 @@ void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::REAL, "far" , PROPERTY_HINT_EXP_RANGE, "0.01,4096.0,0.01") );
p_list->push_back( PropertyInfo( Variant::INT, "keep_aspect",PROPERTY_HINT_ENUM,"Keep Width,Keep Height") );
p_list->push_back( PropertyInfo( Variant::BOOL, "current" ) );
p_list->push_back( PropertyInfo( Variant::INT, "visible_layers",PROPERTY_HINT_ALL_FLAGS ) );
p_list->push_back( PropertyInfo( Variant::INT, "cull_mask",PROPERTY_HINT_ALL_FLAGS ) );
p_list->push_back( PropertyInfo( Variant::OBJECT, "environment",PROPERTY_HINT_RESOURCE_TYPE,"Environment" ) );
p_list->push_back( PropertyInfo( Variant::REAL, "h_offset" ) );
p_list->push_back( PropertyInfo( Variant::REAL, "v_offset" ) );
@ -342,91 +342,6 @@ bool Camera::_can_gizmo_scale() const {
}
RES Camera::_get_gizmo_geometry() const {
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.5) );
mat->set_line_width(4);
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
mat->set_flag(Material::FLAG_UNSHADED,true);
//mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
surface_tool->begin(Mesh::PRIMITIVE_LINES);
surface_tool->set_material(mat);
switch(mode) {
case PROJECTION_PERSPECTIVE: {
Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) );
Vector3 nside=side;
nside.x=-nside.x;
Vector3 up=Vector3(0,side.x,0);
#define ADD_TRIANGLE( m_a, m_b, m_c)\
{\
surface_tool->add_vertex(m_a);\
surface_tool->add_vertex(m_b);\
surface_tool->add_vertex(m_b);\
surface_tool->add_vertex(m_c);\
surface_tool->add_vertex(m_c);\
surface_tool->add_vertex(m_a);\
}
ADD_TRIANGLE( Vector3(), side+up, side-up );
ADD_TRIANGLE( Vector3(), nside+up, nside-up );
ADD_TRIANGLE( Vector3(), side+up, nside+up );
ADD_TRIANGLE( Vector3(), side-up, nside-up );
side.x*=0.25;
nside.x*=0.25;
Vector3 tup( 0, up.y*3/2,side.z);
ADD_TRIANGLE( tup, side+up, nside+up );
} break;
case PROJECTION_ORTHOGONAL: {
#define ADD_QUAD( m_a, m_b, m_c, m_d)\
{\
surface_tool->add_vertex(m_a);\
surface_tool->add_vertex(m_b);\
surface_tool->add_vertex(m_b);\
surface_tool->add_vertex(m_c);\
surface_tool->add_vertex(m_c);\
surface_tool->add_vertex(m_d);\
surface_tool->add_vertex(m_d);\
surface_tool->add_vertex(m_a);\
}
float hsize=size*0.5;
Vector3 right(hsize,0,0);
Vector3 up(0,hsize,0);
Vector3 back(0,0,-1.0);
Vector3 front(0,0,0);
ADD_QUAD( -up-right,-up+right,up+right,up-right);
ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back);
ADD_QUAD( up+right,up+right+back,up-right+back,up-right);
ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right);
right.x*=0.25;
Vector3 tup( 0, up.y*3/2,back.z );
ADD_TRIANGLE( tup, right+up+back, -right+up+back );
} break;
}
return surface_tool->commit();
}
Vector3 Camera::project_ray_normal(const Point2& p_pos) const {
@ -648,8 +563,8 @@ void Camera::_bind_methods() {
ObjectTypeDB::bind_method( _MD("get_zfar"),&Camera::get_zfar );
ObjectTypeDB::bind_method( _MD("get_znear"),&Camera::get_znear );
ObjectTypeDB::bind_method( _MD("get_projection"),&Camera::get_projection );
ObjectTypeDB::bind_method( _MD("set_visible_layers","mask"),&Camera::set_visible_layers );
ObjectTypeDB::bind_method( _MD("get_visible_layers"),&Camera::get_visible_layers );
ObjectTypeDB::bind_method( _MD("set_cull_mask","mask"),&Camera::set_cull_mask );
ObjectTypeDB::bind_method( _MD("get_cull_mask"),&Camera::get_cull_mask );
ObjectTypeDB::bind_method(_MD("set_environment","env:Environment"),&Camera::set_environment);
ObjectTypeDB::bind_method(_MD("get_environment:Environment"),&Camera::get_environment);
ObjectTypeDB::bind_method(_MD("set_keep_aspect_mode","mode"),&Camera::set_keep_aspect_mode);
@ -690,13 +605,13 @@ Camera::Projection Camera::get_projection() const {
return mode;
}
void Camera::set_visible_layers(uint32_t p_layers) {
void Camera::set_cull_mask(uint32_t p_layers) {
layers=p_layers;
VisualServer::get_singleton()->camera_set_visible_layers(camera,layers);
VisualServer::get_singleton()->camera_set_cull_mask(camera,layers);
}
uint32_t Camera::get_visible_layers() const{
uint32_t Camera::get_cull_mask() const{
return layers;
}
@ -757,7 +672,7 @@ Camera::Camera() {
layers=0xfffff;
v_offset=0;
h_offset=0;
VisualServer::get_singleton()->camera_set_visible_layers(camera,layers);
VisualServer::get_singleton()->camera_set_cull_mask(camera,layers);
//active=false;
}

View File

@ -75,7 +75,7 @@ private:
Ref<Environment> environment;
virtual bool _can_gizmo_scale() const;
virtual RES _get_gizmo_geometry() const;
//void _camera_make_current(Node *p_camera);
@ -126,8 +126,8 @@ public:
bool is_position_behind(const Vector3& p_pos) const;
Vector3 project_position(const Point2& p_point) const;
void set_visible_layers(uint32_t p_layers);
uint32_t get_visible_layers() const;
void set_cull_mask(uint32_t p_layers);
uint32_t get_cull_mask() const;
Vector<Plane> get_frustum() const;

View File

@ -32,75 +32,6 @@
#include "scene/resources/surface_tool.h"
static const char* _light_param_names[VS::LIGHT_PARAM_MAX]={
"params/spot_attenuation",
"params/spot_angle",
"params/radius",
"params/energy",
"params/attenuation",
"shadow/darkening",
"shadow/z_offset",
"shadow/z_slope_scale",
"shadow/esm_multiplier",
"shadow/blur_passes"
};
void Light::set_parameter(Parameter p_param, float p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
vars[p_param]=p_value;
VisualServer::get_singleton()->light_set_param(light,(VisualServer::LightParam)p_param,p_value);
if (p_param==PARAM_RADIUS || p_param==PARAM_SPOT_ANGLE)
update_gizmo();
_change_notify(_light_param_names[p_param]);
// _change_notify(_param_names[p_param]);
}
float Light::get_parameter(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return vars[p_param];
}
void Light::set_color(LightColor p_color, const Color& p_value) {
ERR_FAIL_INDEX(p_color, 3);
colors[p_color]=p_value;
VisualServer::get_singleton()->light_set_color(light,(VisualServer::LightColor)p_color,p_value);
//_change_notify(_color_names[p_color]);
}
Color Light::get_color(LightColor p_color) const {
ERR_FAIL_INDEX_V(p_color, 3, Color());
return colors[p_color];
}
void Light::set_project_shadows(bool p_enabled) {
shadows=p_enabled;
VisualServer::get_singleton()->light_set_shadow(light, p_enabled);
_change_notify("shadow");
}
bool Light::has_project_shadows() const {
return shadows;
}
void Light::set_projector(const Ref<Texture>& p_projector) {
projector=p_projector;
VisualServer::get_singleton()->light_set_projector(light, projector.is_null()?RID():projector->get_rid());
}
Ref<Texture> Light::get_projector() const {
return projector;
}
bool Light::_can_gizmo_scale() const {
@ -108,220 +39,9 @@ bool Light::_can_gizmo_scale() const {
}
static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceTool> p_tool) {
p_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
for(int i = 1; i <= p_lats; i++) {
double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats);
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
double lat1 = Math_PI * (-0.5 + (double) i / p_lats);
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for(int j = p_lons; j >= 1; j--) {
double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
double lng1 = 2 * Math_PI * (double) (j) / p_lons;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
Vector3 v[4]={
Vector3(x1 * zr0, z0, y1 *zr0),
Vector3(x1 * zr1, z1, y1 *zr1),
Vector3(x0 * zr1, z1, y0 *zr1),
Vector3(x0 * zr0, z0, y0 *zr0)
};
#define ADD_POINT(m_idx) \
p_tool->add_normal(v[m_idx]);\
p_tool->add_vertex(v[m_idx]*p_radius);
ADD_POINT(0);
ADD_POINT(1);
ADD_POINT(2);
ADD_POINT(2);
ADD_POINT(3);
ADD_POINT(0);
}
}
}
RES Light::_get_gizmo_geometry() const {
Ref<FixedMaterial> mat_area( memnew( FixedMaterial ));
mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.7,0.6,0.0,0.05) );
mat_area->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.7,0.7,0.7) );
mat_area->set_blend_mode( Material::BLEND_MODE_ADD );
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,true);
// mat_area->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
Ref<FixedMaterial> mat_light( memnew( FixedMaterial ));
mat_light->set_parameter( FixedMaterial::PARAM_DIFFUSE, Color(1.0,1.0,0.8,0.9) );
mat_light->set_flag(Material::FLAG_UNSHADED,true);
Ref< Mesh > mesh;
Ref<SurfaceTool> surftool( memnew( SurfaceTool ));
switch(type) {
case VisualServer::LIGHT_DIRECTIONAL: {
mat_area->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.9,0.8,0.1,0.8) );
mat_area->set_blend_mode( Material::BLEND_MODE_MIX);
mat_area->set_flag(Material::FLAG_DOUBLE_SIDED,false);
mat_area->set_flag(Material::FLAG_UNSHADED,true);
_make_sphere( 5,5,0.6, surftool );
surftool->set_material(mat_light);
mesh=surftool->commit(mesh);
// float radius=1;
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
const int arrow_points=5;
Vector3 arrow[arrow_points]={
Vector3(0,0,2),
Vector3(1,1,2),
Vector3(1,1,-1),
Vector3(2,2,-1),
Vector3(0,0,-3)
};
int arrow_sides=4;
for(int i = 0; i < arrow_sides ; i++) {
Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/arrow_sides);
Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/arrow_sides);
for(int j=0;j<arrow_points-1;j++) {
Vector3 points[4]={
ma.xform(arrow[j]),
mb.xform(arrow[j]),
mb.xform(arrow[j+1]),
ma.xform(arrow[j+1]),
};
Vector3 n = Plane(points[0],points[1],points[2]).normal;
surftool->add_normal(n);
surftool->add_vertex(points[0]);
surftool->add_normal(n);
surftool->add_vertex(points[1]);
surftool->add_normal(n);
surftool->add_vertex(points[2]);
surftool->add_normal(n);
surftool->add_vertex(points[0]);
surftool->add_normal(n);
surftool->add_vertex(points[2]);
surftool->add_normal(n);
surftool->add_vertex(points[3]);
}
}
surftool->set_material(mat_area);
mesh=surftool->commit(mesh);
} break;
case VisualServer::LIGHT_OMNI: {
_make_sphere( 20,20,vars[PARAM_RADIUS], surftool );
surftool->set_material(mat_area);
mesh=surftool->commit(mesh);
_make_sphere(5,5, 0.1, surftool );
surftool->set_material(mat_light);
mesh=surftool->commit(mesh);
} break;
case VisualServer::LIGHT_SPOT: {
_make_sphere( 5,5,0.1, surftool );
surftool->set_material(mat_light);
mesh=surftool->commit(mesh);
// make cone
int points=24;
float len=vars[PARAM_RADIUS];
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
for(int i = 0; i < points; i++) {
float x0=Math::sin(i * Math_PI * 2 / points);
float y0=Math::cos(i * Math_PI * 2 / points);
float x1=Math::sin((i+1) * Math_PI * 2 / points);
float y1=Math::cos((i+1) * Math_PI * 2 / points);
Vector3 v1=Vector3(x0*size,y0*size,-len).normalized()*len;
Vector3 v2=Vector3(x1*size,y1*size,-len).normalized()*len;
Vector3 v3=Vector3(0,0,0);
Vector3 v4=Vector3(0,0,v1.z);
Vector3 n = Plane(v1,v2,v3).normal;
surftool->add_normal(n);
surftool->add_vertex(v1);
surftool->add_normal(n);
surftool->add_vertex(v2);
surftool->add_normal(n);
surftool->add_vertex(v3);
n=Vector3(0,0,-1);
surftool->add_normal(n);
surftool->add_vertex(v1);
surftool->add_normal(n);
surftool->add_vertex(v2);
surftool->add_normal(n);
surftool->add_vertex(v4);
}
surftool->set_material(mat_area);
mesh=surftool->commit(mesh);
} break;
}
return mesh;
}
AABB Light::get_aabb() const {
#if 0
if (type==VisualServer::LIGHT_DIRECTIONAL) {
return AABB( Vector3(-1,-1,-1), Vector3(2, 2, 2 ) );
@ -336,7 +56,7 @@ AABB Light::get_aabb() const {
float size=Math::tan(Math::deg2rad(vars[PARAM_SPOT_ANGLE]))*len;
return AABB( Vector3( -size,-size,-len ), Vector3( size*2, size*2, len ) );
}
#endif
return AABB();
}
@ -346,89 +66,6 @@ DVector<Face3> Light::get_faces(uint32_t p_usage_flags) const {
}
void Light::set_operator(Operator p_op) {
ERR_FAIL_INDEX(p_op,2);
op=p_op;
VisualServer::get_singleton()->light_set_operator(light,VS::LightOp(op));
}
void Light::set_bake_mode(BakeMode p_bake_mode) {
bake_mode=p_bake_mode;
}
Light::BakeMode Light::get_bake_mode() const {
return bake_mode;
}
Light::Operator Light::get_operator() const {
return op;
}
void Light::approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic,float p_radius_treshold) {
//this is horrible and must never be used
float a = p_quadratic * p_radius_treshold;
float b = p_linear * p_radius_treshold;
float c = p_constant * p_radius_treshold -1;
float radius=10000;
if(a == 0) { // solve linear
float d = Math::abs(-c/b);
if(d<radius)
radius=d;
} else { // solve quadratic
// now ad^2 + bd + c = 0, solve quadratic equation:
float denominator = 2*a;
if(denominator != 0) {
float root = b*b - 4*a*c;
if(root >=0) {
root = sqrt(root);
float solution1 = fabs( (-b + root) / denominator);
float solution2 = fabs( (-b - root) / denominator);
if(solution1 > radius)
solution1 = radius;
if(solution2 > radius)
solution2 = radius;
radius = (solution1 > solution2 ? solution1 : solution2);
}
}
}
float energy=1.0;
/*if (p_constant>0)
energy=1.0/p_constant; //energy is this
else
energy=8.0; // some high number..
*/
if (radius==10000)
radius=100; //bug?
set_parameter(PARAM_RADIUS,radius);
set_parameter(PARAM_ENERGY,energy);
}
void Light::_update_visibility() {
@ -436,7 +73,7 @@ void Light::_update_visibility() {
return;
bool editor_ok=true;
bool editor_ok=true;
#ifdef TOOLS_ENABLED
if (editor_only) {
@ -448,7 +85,7 @@ bool editor_ok=true;
}
#endif
VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && enabled && editor_ok);
//VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible() && editor_ok);
_change_notify("geometry/visible");
}
@ -461,16 +98,6 @@ void Light::_notification(int p_what) {
}
}
void Light::set_enabled(bool p_enabled) {
enabled=p_enabled;
_update_visibility();
}
bool Light::is_enabled() const{
return enabled;
}
void Light::set_editor_only(bool p_editor_only) {
@ -486,69 +113,16 @@ bool Light::is_editor_only() const{
void Light::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_parameter","variable","value"), &Light::set_parameter );
ObjectTypeDB::bind_method(_MD("get_parameter","variable"), &Light::get_parameter );
ObjectTypeDB::bind_method(_MD("set_color","color","value"), &Light::set_color );
ObjectTypeDB::bind_method(_MD("get_color","color"), &Light::get_color );
ObjectTypeDB::bind_method(_MD("set_project_shadows","enable"), &Light::set_project_shadows );
ObjectTypeDB::bind_method(_MD("has_project_shadows"), &Light::has_project_shadows );
ObjectTypeDB::bind_method(_MD("set_projector","projector:Texture"), &Light::set_projector );
ObjectTypeDB::bind_method(_MD("get_projector:Texture"), &Light::get_projector );
ObjectTypeDB::bind_method(_MD("set_operator","operator"), &Light::set_operator );
ObjectTypeDB::bind_method(_MD("get_operator"), &Light::get_operator );
ObjectTypeDB::bind_method(_MD("set_bake_mode","bake_mode"), &Light::set_bake_mode );
ObjectTypeDB::bind_method(_MD("get_bake_mode"), &Light::get_bake_mode );
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"), &Light::set_enabled );
ObjectTypeDB::bind_method(_MD("is_enabled"), &Light::is_enabled );
ObjectTypeDB::bind_method(_MD("set_editor_only","editor_only"), &Light::set_editor_only );
ObjectTypeDB::bind_method(_MD("is_editor_only"), &Light::is_editor_only );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/enabled"), _SCS("set_enabled"), _SCS("is_enabled"));
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "params/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "params/bake_mode",PROPERTY_HINT_ENUM,"Disabled,Indirect,Indirect+Shadows,Full"), _SCS("set_bake_mode"), _SCS("get_bake_mode"));
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/energy", PROPERTY_HINT_EXP_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ENERGY );
/*
if (type == VisualServer::LIGHT_OMNI || type == VisualServer::LIGHT_SPOT) {
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"));
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_RANGE, "0,8,0.01"));
}
if (type == VisualServer::LIGHT_SPOT) {
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,90.0,0.01"));
ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_RANGE, "0,8,0.01"));
}*/
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/diffuse"), _SCS("set_color"), _SCS("get_color"),COLOR_DIFFUSE);
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "colors/specular"), _SCS("set_color"), _SCS("get_color"),COLOR_SPECULAR);
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/shadow"), _SCS("set_project_shadows"), _SCS("has_project_shadows"));
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkening", PROPERTY_HINT_RANGE, "0,1,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_DARKENING );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_offset", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_OFFSET);
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_slope_scale", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_SLOPE_SCALE);
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/esm_multiplier", PROPERTY_HINT_RANGE, "1.0,512.0,0.1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_ESM_MULTIPLIER);
ADD_PROPERTYI( PropertyInfo( Variant::INT, "shadow/blur_passes", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_BLUR_PASSES);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "projector",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_projector"), _SCS("get_projector"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "operator",PROPERTY_HINT_ENUM,"Add,Sub"), _SCS("set_operator"), _SCS("get_operator"));
BIND_CONSTANT( PARAM_RADIUS );
BIND_CONSTANT( PARAM_ENERGY );
BIND_CONSTANT( PARAM_ATTENUATION );
BIND_CONSTANT( PARAM_SPOT_ANGLE );
BIND_CONSTANT( PARAM_SPOT_ATTENUATION );
BIND_CONSTANT( PARAM_SHADOW_DARKENING );
BIND_CONSTANT( PARAM_SHADOW_Z_OFFSET );
BIND_CONSTANT( COLOR_DIFFUSE );
BIND_CONSTANT( COLOR_SPECULAR );
BIND_CONSTANT( BAKE_MODE_DISABLED );
BIND_CONSTANT( BAKE_MODE_INDIRECT );
BIND_CONSTANT( BAKE_MODE_INDIRECT_AND_SHADOWS );
BIND_CONSTANT( BAKE_MODE_FULL );
}
@ -558,27 +132,8 @@ Light::Light(VisualServer::LightType p_type) {
type=p_type;
light=VisualServer::get_singleton()->light_create(p_type);
set_parameter(PARAM_SPOT_ATTENUATION,1.0);
set_parameter(PARAM_SPOT_ANGLE,30.0);
set_parameter(PARAM_RADIUS,2.0);
set_parameter(PARAM_ENERGY,1.0);
set_parameter(PARAM_ATTENUATION,1.0);
set_parameter(PARAM_SHADOW_DARKENING,0.0);
set_parameter(PARAM_SHADOW_Z_OFFSET,0.05);
set_parameter(PARAM_SHADOW_Z_SLOPE_SCALE,0);
set_parameter(PARAM_SHADOW_ESM_MULTIPLIER,60);
set_parameter(PARAM_SHADOW_BLUR_PASSES,1);
set_color( COLOR_DIFFUSE, Color(1,1,1));
set_color( COLOR_SPECULAR, Color(1,1,1));
op=OPERATOR_ADD;
set_project_shadows( false );
set_base(light);
enabled=true;
editor_only=false;
bake_mode=BAKE_MODE_DISABLED;
}
@ -598,59 +153,15 @@ Light::~Light() {
/////////////////////////////////////////
void DirectionalLight::set_shadow_mode(ShadowMode p_mode) {
shadow_mode=p_mode;
VS::get_singleton()->light_directional_set_shadow_mode(light,(VS::LightDirectionalShadowMode)p_mode);
}
DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const{
return shadow_mode;
}
void DirectionalLight::set_shadow_param(ShadowParam p_param, float p_value) {
ERR_FAIL_INDEX(p_param,3);
shadow_param[p_param]=p_value;
VS::get_singleton()->light_directional_set_shadow_param(light,VS::LightDirectionalShadowParam(p_param),p_value);
}
float DirectionalLight::get_shadow_param(ShadowParam p_param) const {
ERR_FAIL_INDEX_V(p_param,3,0);
return shadow_param[p_param];
}
void DirectionalLight::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_shadow_mode","mode"),&DirectionalLight::set_shadow_mode);
ObjectTypeDB::bind_method(_MD("get_shadow_mode"),&DirectionalLight::get_shadow_mode);
ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param);
ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param);
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
BIND_CONSTANT( SHADOW_ORTHOGONAL );
BIND_CONSTANT( SHADOW_PERSPECTIVE );
BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
BIND_CONSTANT( SHADOW_PARALLEL_4_SPLITS );
BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE );
BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT );
BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE );
}
DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL ) {
shadow_mode=SHADOW_ORTHOGONAL;
shadow_param[SHADOW_PARAM_MAX_DISTANCE]=0;
shadow_param[SHADOW_PARAM_PSSM_SPLIT_WEIGHT]=0.5;
shadow_param[SHADOW_PARAM_PSSM_ZOFFSET_SCALE]=2.0;
}
@ -658,19 +169,11 @@ DirectionalLight::DirectionalLight() : Light( VisualServer::LIGHT_DIRECTIONAL )
void OmniLight::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
}
void SpotLight::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/radius", PROPERTY_HINT_EXP_RANGE, "0.2,4096,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_RADIUS );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "spot_attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION );
}

View File

@ -44,57 +44,12 @@ class Light : public VisualInstance {
public:
enum Parameter {
PARAM_RADIUS=VisualServer::LIGHT_PARAM_RADIUS,
PARAM_ENERGY=VisualServer::LIGHT_PARAM_ENERGY,
PARAM_ATTENUATION=VisualServer::LIGHT_PARAM_ATTENUATION,
PARAM_SPOT_ANGLE=VisualServer::LIGHT_PARAM_SPOT_ANGLE,
PARAM_SPOT_ATTENUATION=VisualServer::LIGHT_PARAM_SPOT_ATTENUATION,
PARAM_SHADOW_DARKENING=VisualServer::LIGHT_PARAM_SHADOW_DARKENING,
PARAM_SHADOW_Z_OFFSET=VisualServer::LIGHT_PARAM_SHADOW_Z_OFFSET,
PARAM_SHADOW_Z_SLOPE_SCALE=VisualServer::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE,
PARAM_SHADOW_ESM_MULTIPLIER=VisualServer::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER,
PARAM_SHADOW_BLUR_PASSES=VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES,
PARAM_MAX=VisualServer::LIGHT_PARAM_MAX
};
enum LightColor {
COLOR_DIFFUSE=VisualServer::LIGHT_COLOR_DIFFUSE,
COLOR_SPECULAR=VisualServer::LIGHT_COLOR_SPECULAR
};
enum BakeMode {
BAKE_MODE_DISABLED,
BAKE_MODE_INDIRECT,
BAKE_MODE_INDIRECT_AND_SHADOWS,
BAKE_MODE_FULL
};
enum Operator {
OPERATOR_ADD,
OPERATOR_SUB
};
private:
Ref<Texture> projector;
float vars[PARAM_MAX];
Color colors[3];
BakeMode bake_mode;
VisualServer::LightType type;
bool shadows;
bool enabled;
VS::LightType type;
bool editor_only;
Operator op;
void _update_visibility();
// bind helpers
@ -103,7 +58,6 @@ protected:
RID light;
virtual bool _can_gizmo_scale() const;
virtual RES _get_gizmo_geometry() const;
static void _bind_methods();
void _notification(int p_what);
@ -114,44 +68,17 @@ public:
VS::LightType get_light_type() const { return type; }
void set_parameter(Parameter p_var, float p_value);
float get_parameter(Parameter p_var) const;
void set_color(LightColor p_color,const Color& p_value);
Color get_color(LightColor p_color) const;
void set_project_shadows(bool p_enabled);
bool has_project_shadows() const;
void set_projector(const Ref<Texture>& p_projector);
Ref<Texture> get_projector() const;
void set_operator(Operator p_op);
Operator get_operator() const;
void set_bake_mode(BakeMode p_bake_mode);
BakeMode get_bake_mode() const;
void set_enabled(bool p_enabled);
bool is_enabled() const;
void set_editor_only(bool p_editor_only);
bool is_editor_only() const;
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
void approximate_opengl_attenuation(float p_constant, float p_linear, float p_quadratic, float p_radius_treshold=0.5);
Light();
~Light();
};
VARIANT_ENUM_CAST( Light::Parameter );
VARIANT_ENUM_CAST( Light::LightColor );
VARIANT_ENUM_CAST( Light::Operator );
VARIANT_ENUM_CAST( Light::BakeMode);
class DirectionalLight : public Light {
@ -160,39 +87,18 @@ class DirectionalLight : public Light {
public:
enum ShadowMode {
SHADOW_ORTHOGONAL,
SHADOW_PERSPECTIVE,
SHADOW_PARALLEL_2_SPLITS,
SHADOW_PARALLEL_4_SPLITS
};
enum ShadowParam {
SHADOW_PARAM_MAX_DISTANCE,
SHADOW_PARAM_PSSM_SPLIT_WEIGHT,
SHADOW_PARAM_PSSM_ZOFFSET_SCALE
};
private:
ShadowMode shadow_mode;
float shadow_param[3];
protected:
static void _bind_methods();
public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
void set_shadow_max_distance(float p_distance);
float get_shadow_max_distance() const;
void set_shadow_param(ShadowParam p_param, float p_value);
float get_shadow_param(ShadowParam p_param) const;
DirectionalLight();
};
VARIANT_ENUM_CAST( DirectionalLight::ShadowMode );
VARIANT_ENUM_CAST( DirectionalLight::ShadowParam );
class OmniLight : public Light {
@ -203,7 +109,7 @@ protected:
public:
OmniLight() : Light( VisualServer::LIGHT_OMNI ) { set_parameter(PARAM_SHADOW_Z_OFFSET,0.001);}
OmniLight() : Light( VisualServer::LIGHT_OMNI ) { }
};
class SpotLight : public Light {

View File

@ -30,6 +30,7 @@
#include "servers/visual_server.h"
#include "scene/resources/surface_tool.h"
#if 0
/*
static const char* _var_names[Particles::VAR_MAX]={
"vars/lifetime",
@ -557,3 +558,4 @@ Particles::~Particles() {
VisualServer::get_singleton()->free(particles);
}
#endif

View File

@ -37,7 +37,7 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#if 0
class Particles : public GeometryInstance {
public:
@ -163,3 +163,4 @@ public:
VARIANT_ENUM_CAST( Particles::Variable );
#endif
#endif

View File

@ -96,45 +96,6 @@ void Portal::_get_property_list( List<PropertyInfo> *p_list) const {
}
RES Portal::_get_gizmo_geometry() const {
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.8,0.8,0.7) );
mat->set_line_width(4);
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
mat->set_flag(Material::FLAG_UNSHADED,true);
// mat->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER,true);
surface_tool->begin(Mesh::PRIMITIVE_LINES);
surface_tool->set_material(mat);
Vector<Point2> shape = get_shape();
Vector2 center;
for (int i=0;i<shape.size();i++) {
int n=(i+1)%shape.size();
Vector<Vector3> points;
surface_tool->add_vertex( Vector3( shape[i].x, shape[i].y,0 ));
surface_tool->add_vertex( Vector3( shape[n].x, shape[n].y,0 ));
center+=shape[i];
}
if (shape.size()>0) {
center/=shape.size();
Vector<Vector3> points;
surface_tool->add_vertex( Vector3( center.x, center.y,0 ));
surface_tool->add_vertex( Vector3( center.x, center.y,1.0 ));
}
return surface_tool->commit();
}
AABB Portal::get_aabb() const {
@ -178,18 +139,19 @@ void Portal::set_shape(const Vector<Point2>& p_shape) {
VisualServer::get_singleton()->portal_set_shape(portal, p_shape);
shape=p_shape;
update_gizmo();
}
Vector<Point2> Portal::get_shape() const {
return VisualServer::get_singleton()->portal_get_shape(portal);
return shape;
}
void Portal::set_connect_range(float p_range) {
connect_range=p_range;
VisualServer::get_singleton()->portal_set_connect_range(portal,p_range);
//VisualServer::get_singleton()->portal_set_connect_range(portal,p_range);
}
float Portal::get_connect_range() const {

View File

@ -47,6 +47,7 @@ class Portal : public VisualInstance {
OBJ_TYPE(Portal, VisualInstance);
RID portal;
Vector<Point2> shape;
bool enabled;
float disable_distance;
@ -55,7 +56,6 @@ class Portal : public VisualInstance {
AABB aabb;
virtual RES _get_gizmo_geometry() const;
protected:

View File

@ -29,37 +29,6 @@
#include "position_3d.h"
#include "scene/resources/mesh.h"
RES Position3D::_get_gizmo_geometry() const {
Ref<Mesh> mesh = memnew( Mesh );
DVector<Vector3> cursor_points;
DVector<Color> cursor_colors;
float cs = 0.25;
cursor_points.push_back(Vector3(+cs,0,0));
cursor_points.push_back(Vector3(-cs,0,0));
cursor_points.push_back(Vector3(0,+cs,0));
cursor_points.push_back(Vector3(0,-cs,0));
cursor_points.push_back(Vector3(0,0,+cs));
cursor_points.push_back(Vector3(0,0,-cs));
cursor_colors.push_back(Color(1,0.5,0.5,1));
cursor_colors.push_back(Color(1,0.5,0.5,1));
cursor_colors.push_back(Color(0.5,1,0.5,1));
cursor_colors.push_back(Color(0.5,1,0.5,1));
cursor_colors.push_back(Color(0.5,0.5,1,1));
cursor_colors.push_back(Color(0.5,0.5,1,1));
Ref<FixedMaterial> mat = memnew( FixedMaterial );
mat->set_flag(Material::FLAG_UNSHADED,true);
mat->set_line_width(3);
Array d;
d[Mesh::ARRAY_VERTEX]=cursor_points;
d[Mesh::ARRAY_COLOR]=cursor_colors;
mesh->add_surface(Mesh::PRIMITIVE_LINES,d);
mesh->surface_set_material(0,mat);
return mesh;
}
Position3D::Position3D()
{

View File

@ -35,7 +35,6 @@ class Position3D : public Spatial {
OBJ_TYPE(Position3D,Spatial);
virtual RES _get_gizmo_geometry() const;
public:

View File

@ -120,7 +120,7 @@ void Quad::_update() {
} else {
configured=true;
}
VS::get_singleton()->mesh_add_surface(mesh,VS::PRIMITIVE_TRIANGLES,arr);
VS::get_singleton()->mesh_add_surface_from_arrays(mesh,VS::PRIMITIVE_TRIANGLES,arr);
pending_update=false;
}

View File

@ -75,50 +75,6 @@ void Room::_notification(int p_what) {
}
RES Room::_get_gizmo_geometry() const {
DVector<Face3> faces;
if (!room.is_null())
faces=room->get_geometry_hint();
int count=faces.size();
if (count==0)
return RES();
DVector<Face3>::Read facesr=faces.read();
const Face3* facesptr=facesr.ptr();
DVector<Vector3> points;
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.2,0.8,0.9,0.3) );
mat->set_line_width(4);
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
mat->set_flag(Material::FLAG_UNSHADED,true);
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
surface_tool->begin(Mesh::PRIMITIVE_LINES);
surface_tool->set_material(mat);
for (int i=0;i<count;i++) {
surface_tool->add_vertex(facesptr[i].vertex[0]);
surface_tool->add_vertex(facesptr[i].vertex[1]);
surface_tool->add_vertex(facesptr[i].vertex[1]);
surface_tool->add_vertex(facesptr[i].vertex[2]);
surface_tool->add_vertex(facesptr[i].vertex[2]);
surface_tool->add_vertex(facesptr[i].vertex[0]);
}
return surface_tool->commit();
}
@ -127,8 +83,9 @@ AABB Room::get_aabb() const {
if (room.is_null())
return AABB();
return room->get_bounds().get_aabb();
return AABB();
}
DVector<Face3> Room::get_faces(uint32_t p_usage_flags) const {
return DVector<Face3>();
@ -154,9 +111,6 @@ void Room::set_room( const Ref<RoomBounds>& p_room ) {
propagate_notification(NOTIFICATION_AREA_CHANGED);
update_gizmo();
if (room.is_valid())
SpatialSoundServer::get_singleton()->room_set_bounds(sound_room,room->get_bounds());
}
@ -202,32 +156,6 @@ void Room::_parse_node_faces(DVector<Face3> &all_faces,const Node *p_node) const
}
void Room::compute_room_from_subtree() {
DVector<Face3> all_faces;
_parse_node_faces(all_faces,this);
if (all_faces.size()==0)
return;
float error;
DVector<Face3> wrapped_faces = Geometry::wrap_geometry(all_faces,&error);
if (wrapped_faces.size()==0)
return;
BSP_Tree tree(wrapped_faces,error);
Ref<RoomBounds> room( memnew( RoomBounds ) );
room->set_bounds(tree);
room->set_geometry_hint(wrapped_faces);
set_room(room);
}
void Room::set_simulate_acoustics(bool p_enable) {
@ -268,7 +196,6 @@ void Room::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_room","room:Room"),&Room::set_room );
ObjectTypeDB::bind_method(_MD("get_room:Room"),&Room::get_room );
ObjectTypeDB::bind_method(_MD("compute_room_from_subtree"),&Room::compute_room_from_subtree);

View File

@ -45,6 +45,8 @@
*/
class Room : public VisualInstance {
OBJ_TYPE( Room, VisualInstance );
@ -65,7 +67,7 @@ private:
void _bounds_changed();
virtual RES _get_gizmo_geometry() const;
protected:
@ -89,7 +91,6 @@ public:
void set_simulate_acoustics(bool p_enable);
bool is_simulating_acoustics() const;
void compute_room_from_subtree();
RID get_sound_room() const;

View File

@ -163,7 +163,7 @@ void Skeleton::_notification(int p_what) {
Bone *bonesptr=&bones[0];
int len=bones.size();
vs->skeleton_resize( skeleton, len ); // if same size, nothin really happens
vs->skeleton_allocate( skeleton, len ); // if same size, nothin really happens
// pose changed, rebuild cache of inverses
if (rest_global_inverse_dirty) {
@ -513,51 +513,6 @@ void Skeleton::_make_dirty() {
}
RES Skeleton::_get_gizmo_geometry() const {
if (!GLOBAL_DEF("debug/draw_skeleton", true))
return RES();
if (bones.size()==0)
return RES();
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.6,1.0,0.3,0.1) );
mat->set_line_width(4);
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
mat->set_flag(Material::FLAG_UNSHADED,true);
mat->set_flag(Material::FLAG_ONTOP,true);
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
surface_tool->begin(Mesh::PRIMITIVE_LINES);
surface_tool->set_material(mat);
const Bone *bonesptr=&bones[0];
int len=bones.size();
for (int i=0;i<len;i++) {
const Bone &b=bonesptr[i];
Transform t;
if (b.parent<0)
continue;
Vector3 v1=(bonesptr[b.parent].pose_global * bonesptr[b.parent].rest_global_inverse).xform(bonesptr[b.parent].rest_global_inverse.affine_inverse().origin);
Vector3 v2=(b.pose_global * b.rest_global_inverse).xform(b.rest_global_inverse.affine_inverse().origin);
surface_tool->add_vertex(v1);
surface_tool->add_vertex(v2);
}
return surface_tool->commit();
}
void Skeleton::localize_rests() {

View File

@ -84,7 +84,6 @@ class Skeleton : public Spatial {
return bound;
}
virtual RES _get_gizmo_geometry() const;
protected:

View File

@ -88,146 +88,6 @@ bool SpatialPlayer::_can_gizmo_scale() const {
return false;
}
RES SpatialPlayer::_get_gizmo_geometry() const {
Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));
Ref<FixedMaterial> mat( memnew( FixedMaterial ));
mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.0,0.6,0.7,0.05) );
mat->set_parameter( FixedMaterial::PARAM_EMISSION,Color(0.5,0.7,0.8) );
mat->set_blend_mode( Material::BLEND_MODE_ADD );
mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
// mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
surface_tool->set_material(mat);
int sides=16;
int sections=24;
// float len=1;
float deg=Math::deg2rad(params[PARAM_EMISSION_CONE_DEGREES]);
if (deg==180)
deg=179.5;
Vector3 to=Vector3(0,0,-1);
for(int j=0;j<sections;j++) {
Vector3 p1=Matrix3(Vector3(1,0,0),deg*j/sections).xform(to);
Vector3 p2=Matrix3(Vector3(1,0,0),deg*(j+1)/sections).xform(to);
for(int i=0;i<sides;i++) {
Vector3 p1r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p1);
Vector3 p1s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p1);
Vector3 p2s = Matrix3(Vector3(0,0,1),Math_PI*2*float(i+1)/sides).xform(p2);
Vector3 p2r = Matrix3(Vector3(0,0,1),Math_PI*2*float(i)/sides).xform(p2);
surface_tool->add_normal(p1r.normalized());
surface_tool->add_vertex(p1r);
surface_tool->add_normal(p1s.normalized());
surface_tool->add_vertex(p1s);
surface_tool->add_normal(p2s.normalized());
surface_tool->add_vertex(p2s);
surface_tool->add_normal(p1r.normalized());
surface_tool->add_vertex(p1r);
surface_tool->add_normal(p2s.normalized());
surface_tool->add_vertex(p2s);
surface_tool->add_normal(p2r.normalized());
surface_tool->add_vertex(p2r);
if (j==sections-1) {
surface_tool->add_normal(p2r.normalized());
surface_tool->add_vertex(p2r);
surface_tool->add_normal(p2s.normalized());
surface_tool->add_vertex(p2s);
surface_tool->add_normal(Vector3(0,0,1));
surface_tool->add_vertex(Vector3());
}
}
}
Ref<Mesh> mesh = surface_tool->commit();
Ref<FixedMaterial> mat_speaker( memnew( FixedMaterial ));
mat_speaker->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.3,0.3,0.6) );
mat_speaker->set_parameter( FixedMaterial::PARAM_SPECULAR,Color(0.5,0.5,0.6) );
//mat_speaker->set_blend_mode( Material::BLEND_MODE_MIX);
//mat_speaker->set_flag(Material::FLAG_DOUBLE_SIDED,false);
//mat_speaker->set_flag(Material::FLAG_UNSHADED,true);
surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
surface_tool->set_material(mat_speaker);
// float radius=1;
const int speaker_points=8;
Vector3 speaker[speaker_points]={
Vector3(0,0,1)*0.15,
Vector3(1,1,1)*0.15,
Vector3(1,1,0)*0.15,
Vector3(2,2,-1)*0.15,
Vector3(1,1,-1)*0.15,
Vector3(0.8,0.8,-1.2)*0.15,
Vector3(0.5,0.5,-1.4)*0.15,
Vector3(0.0,0.0,-1.6)*0.15
};
int speaker_sides=10;
for(int i = 0; i < speaker_sides ; i++) {
Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/speaker_sides);
Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/speaker_sides);
for(int j=0;j<speaker_points-1;j++) {
Vector3 points[4]={
ma.xform(speaker[j]),
mb.xform(speaker[j]),
mb.xform(speaker[j+1]),
ma.xform(speaker[j+1]),
};
Vector3 n = -Plane(points[0],points[1],points[2]).normal;
surface_tool->add_normal(n);
surface_tool->add_vertex(points[0]);
surface_tool->add_normal(n);
surface_tool->add_vertex(points[2]);
surface_tool->add_normal(n);
surface_tool->add_vertex(points[1]);
surface_tool->add_normal(n);
surface_tool->add_vertex(points[0]);
surface_tool->add_normal(n);
surface_tool->add_vertex(points[3]);
surface_tool->add_normal(n);
surface_tool->add_vertex(points[2]);
}
}
return surface_tool->commit(mesh);
}
void SpatialPlayer::_bind_methods() {

View File

@ -60,7 +60,7 @@ private:
RID source_rid;
virtual bool _can_gizmo_scale() const;
virtual RES _get_gizmo_geometry() const;
protected:

View File

@ -52,7 +52,7 @@ void VisualInstance::_notification(int p_what) {
Room *room=NULL;
bool is_geom = cast_to<GeometryInstance>();
while(parent) {
/* while(parent) {
room = parent->cast_to<Room>();
if (room)
@ -64,7 +64,7 @@ void VisualInstance::_notification(int p_what) {
}
parent=parent->get_parent_spatial();
}
}*/
@ -92,7 +92,7 @@ void VisualInstance::_notification(int p_what) {
VisualServer::get_singleton()->instance_set_scenario( instance, RID() );
VisualServer::get_singleton()->instance_set_room(instance,RID());
VisualServer::get_singleton()->instance_attach_skeleton( instance, RID() );
VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
// VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
} break;
@ -172,30 +172,55 @@ Ref<Material> GeometryInstance::get_material_override() const{
void GeometryInstance::set_draw_range_begin(float p_dist){
void GeometryInstance::set_lod_min_distance(float p_dist){
draw_begin=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end);
lod_min_distance=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis);
}
float GeometryInstance::get_draw_range_begin() const{
float GeometryInstance::get_lod_min_distance() const{
return draw_begin;
return lod_min_distance;
}
void GeometryInstance::set_draw_range_end(float p_dist) {
void GeometryInstance::set_lod_max_distance(float p_dist) {
draw_end=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),draw_begin,draw_end);
lod_max_distance=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis);
}
float GeometryInstance::get_draw_range_end() const {
float GeometryInstance::get_lod_max_distance() const {
return draw_end;
return lod_max_distance;
}
void GeometryInstance::set_lod_min_hysteresis(float p_dist){
lod_min_hysteresis=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis);
}
float GeometryInstance::get_lod_min_hysteresis() const{
return lod_min_hysteresis;
}
void GeometryInstance::set_lod_max_hysteresis(float p_dist) {
lod_max_hysteresis=p_dist;
VS::get_singleton()->instance_geometry_set_draw_range(get_instance(),lod_min_distance,lod_max_distance,lod_min_hysteresis,lod_max_hysteresis);
}
float GeometryInstance::get_lod_max_hysteresis() const {
return lod_max_hysteresis;
}
void GeometryInstance::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_WORLD) {
@ -212,8 +237,8 @@ void GeometryInstance::_notification(int p_what) {
if (flags[FLAG_USE_BAKED_LIGHT]) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
// baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
// baked_light_instance=NULL;
}
_baked_light_changed();
@ -229,15 +254,15 @@ void GeometryInstance::_notification(int p_what) {
void GeometryInstance::_baked_light_changed() {
if (!baked_light_instance)
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
else
VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
//if (!baked_light_instance)
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
// else
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
}
void GeometryInstance::_find_baked_light() {
/*
Node *n=get_parent();
while(n) {
@ -255,6 +280,7 @@ void GeometryInstance::_find_baked_light() {
}
_baked_light_changed();
*/
}
void GeometryInstance::_update_visibility() {
@ -288,7 +314,7 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
}
if (p_flag==FLAG_USE_BAKED_LIGHT) {
if (is_inside_world()) {
/* if (is_inside_world()) {
if (!p_value) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
@ -298,7 +324,7 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
} else {
_find_baked_light();
}
}
}*/
}
}
@ -333,8 +359,8 @@ GeometryInstance::ShadowCastingSetting GeometryInstance::get_cast_shadows_settin
void GeometryInstance::set_baked_light_texture_id(int p_id) {
baked_light_texture_id=p_id;
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),baked_light_texture_id);
// baked_light_texture_id=p_id;
// VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),baked_light_texture_id);
}
@ -366,11 +392,18 @@ void GeometryInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance::set_cast_shadows_setting);
ObjectTypeDB::bind_method(_MD("get_cast_shadows_setting"), &GeometryInstance::get_cast_shadows_setting);
ObjectTypeDB::bind_method(_MD("set_draw_range_begin","mode"), &GeometryInstance::set_draw_range_begin);
ObjectTypeDB::bind_method(_MD("get_draw_range_begin"), &GeometryInstance::get_draw_range_begin);
ObjectTypeDB::bind_method(_MD("set_lod_max_hysteresis","mode"), &GeometryInstance::set_lod_max_hysteresis);
ObjectTypeDB::bind_method(_MD("get_lod_max_hysteresis"), &GeometryInstance::get_lod_max_hysteresis);
ObjectTypeDB::bind_method(_MD("set_lod_max_distance","mode"), &GeometryInstance::set_lod_max_distance);
ObjectTypeDB::bind_method(_MD("get_lod_max_distance"), &GeometryInstance::get_lod_max_distance);
ObjectTypeDB::bind_method(_MD("set_lod_min_hysteresis","mode"), &GeometryInstance::set_lod_min_hysteresis);
ObjectTypeDB::bind_method(_MD("get_lod_min_hysteresis"), &GeometryInstance::get_lod_min_hysteresis);
ObjectTypeDB::bind_method(_MD("set_lod_min_distance","mode"), &GeometryInstance::set_lod_min_distance);
ObjectTypeDB::bind_method(_MD("get_lod_min_distance"), &GeometryInstance::get_lod_min_distance);
ObjectTypeDB::bind_method(_MD("set_draw_range_end","mode"), &GeometryInstance::set_draw_range_end);
ObjectTypeDB::bind_method(_MD("get_draw_range_end"), &GeometryInstance::get_draw_range_end);
ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id);
ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id);
@ -385,9 +418,6 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override"));
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), _SCS("set_cast_shadows_setting"), _SCS("get_cast_shadows_setting"));
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS);
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end"));
ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin"));
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y);
@ -395,12 +425,15 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE_IN_ALL_ROOMS);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"),FLAG_USE_BAKED_LIGHT);
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/baked_light_tex_id"), _SCS("set_baked_light_texture_id"), _SCS("get_baked_light_texture_id"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_distance"), _SCS("get_lod_min_distance"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_hysteresis",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_hysteresis"), _SCS("get_lod_min_hysteresis"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/max_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_max_distance"), _SCS("get_lod_max_distance"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/max_hysteresis",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_max_hysteresis"), _SCS("get_lod_max_hysteresis"));
// ADD_SIGNAL( MethodInfo("visibility_changed"));
BIND_CONSTANT(FLAG_VISIBLE );
BIND_CONSTANT(FLAG_CAST_SHADOW );
BIND_CONSTANT(FLAG_RECEIVE_SHADOWS );
BIND_CONSTANT(FLAG_BILLBOARD );
BIND_CONSTANT(FLAG_BILLBOARD_FIX_Y );
BIND_CONSTANT(FLAG_DEPH_SCALE );
@ -415,20 +448,23 @@ void GeometryInstance::_bind_methods() {
}
GeometryInstance::GeometryInstance() {
draw_begin=0;
draw_end=0;
lod_min_distance=0;
lod_max_distance=0;
lod_min_hysteresis=0;
lod_max_hysteresis=0;
for(int i=0;i<FLAG_MAX;i++) {
flags[i]=false;
}
flags[FLAG_VISIBLE]=true;
flags[FLAG_CAST_SHADOW]=true;
flags[FLAG_RECEIVE_SHADOWS]=true;
shadow_casting_setting=SHADOW_CASTING_SETTING_ON;
baked_light_instance=NULL;
baked_light_texture_id=0;
extra_cull_margin=0;
VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
// VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
}

View File

@ -89,7 +89,6 @@ public:
enum Flags {
FLAG_VISIBLE=VS::INSTANCE_FLAG_VISIBLE,
FLAG_CAST_SHADOW=VS::INSTANCE_FLAG_CAST_SHADOW,
FLAG_RECEIVE_SHADOWS=VS::INSTANCE_FLAG_RECEIVE_SHADOWS,
FLAG_BILLBOARD=VS::INSTANCE_FLAG_BILLBOARD,
FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y,
FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE,
@ -110,8 +109,10 @@ private:
bool flags[FLAG_MAX];
ShadowCastingSetting shadow_casting_setting;
Ref<Material> material_override;
float draw_begin;
float draw_end;
float lod_min_distance;
float lod_max_distance;
float lod_min_hysteresis;
float lod_max_hysteresis;
void _find_baked_light();
BakedLightInstance *baked_light_instance;
int baked_light_texture_id;
@ -131,11 +132,17 @@ public:
void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);
ShadowCastingSetting get_cast_shadows_setting() const;
void set_draw_range_begin(float p_dist);
float get_draw_range_begin() const;
void set_lod_min_distance(float p_dist);
float get_lod_min_distance() const;
void set_draw_range_end(float p_dist);
float get_draw_range_end() const;
void set_lod_max_distance(float p_dist);
float get_lod_max_distance() const;
void set_lod_min_hysteresis(float p_dist);
float get_lod_min_hysteresis() const;
void set_lod_max_hysteresis(float p_dist);
float get_lod_max_hysteresis() const;
void set_material_override(const Ref<Material>& p_material);
Ref<Material> get_material_override() const;

View File

@ -59,6 +59,10 @@ void ColorPicker::_notification(int p_what) {
w_material->set_shader(get_shader("w_editor"));
update_material(uv_material,color,h,s,v);
update_material(w_material,color,h,s,v);
uv_edit->set_texture(get_icon("color_main"));
w_edit->set_texture(get_icon("color_hue"));
sample->set_texture(get_icon("color_sample"));
_update_controls();
} break;
@ -192,10 +196,24 @@ void ColorPicker::_update_presets()
{
Size2 size=bt_add_preset->get_size();
preset->set_custom_minimum_size(Size2(size.width*presets.size(),size.height));
Image i(size.x*presets.size(),size.y, false, Image::FORMAT_RGB);
for (int y=0;y<size.y;y++)
for (int x=0;x<size.x*presets.size();x++)
i.put_pixel(x,y,presets[(int)x/size.x]);
DVector<uint8_t> img;
img.resize(size.x*presets.size()*size.y*3);
{
DVector<uint8_t>::Write w=img.write();
for (int y=0;y<size.y;y++) {
for (int x=0;x<size.x*presets.size();x++) {
int ofs = (y*(size.x*presets.size())+x)*3;
w[ofs+0]=uint8_t(CLAMP(presets[(int)x/size.x].r*255.0,0,255));
w[ofs+1]=uint8_t(CLAMP(presets[(int)x/size.x].g*255.0,0,255));
w[ofs+2]=uint8_t(CLAMP(presets[(int)x/size.x].b*255.0,0,255));
}
}
}
Image i(size.x*presets.size(),size.y, false, Image::FORMAT_RGB8,img);
Ref<ImageTexture> t;
t.instance();
t->create_from_image(i);
@ -394,15 +412,23 @@ void ColorPicker::_screen_input(const InputEvent &ev)
} else if (ev.type==InputEvent::MOUSE_MOTION) {
const InputEventMouse &mev = ev.mouse_motion;
Viewport *r=get_tree()->get_root();
if (!r->get_rect().has_point(Point2(mev.global_x,mev.global_y)))
if (!r->get_visible_rect().has_point(Point2(mev.global_x,mev.global_y)))
return;
Image img =r->get_screen_capture();
if (!img.empty()) {
last_capture=img;
r->queue_screen_capture();
}
if (!last_capture.empty())
set_color(last_capture.get_pixel(mev.global_x,mev.global_y));
if (!last_capture.empty()) {
int pw = last_capture.get_format()==Image::FORMAT_RGBA8?4:3;
int ofs = (mev.global_y*last_capture.get_width()+mev.global_x)*pw;
DVector<uint8_t>::Read r = last_capture.get_data().read();
Color c( r[ofs+0]/255.0, r[ofs+1]/255.0, r[ofs+2]/255.0 );
set_color(c);
}
}
}
@ -474,16 +500,10 @@ ColorPicker::ColorPicker() :
HBoxContainer *hb_edit = memnew( HBoxContainer );
uv_edit= memnew ( TextureFrame );
Image i(256, 256, false, Image::FORMAT_RGB);
for (int y=0;y<256;y++)
for (int x=0;x<256;x++)
i.put_pixel(x,y,Color());
Ref<ImageTexture> t;
t.instance();
t->create_from_image(i);
uv_edit->set_texture(t);
uv_edit->set_ignore_mouse(false);
uv_edit->set_custom_minimum_size(Size2(256,256));
uv_edit->connect("input_event", this, "_uv_input");
Control *c= memnew( Control );
uv_edit->add_child(c);
@ -497,16 +517,9 @@ ColorPicker::ColorPicker() :
add_child(hb_edit);
w_edit= memnew( TextureFrame );
i = Image(15, 256, false, Image::FORMAT_RGB);
for (int y=0;y<256;y++)
for (int x=0;x<15;x++)
i.put_pixel(x,y,Color());
Ref<ImageTexture> tw;
tw.instance();
tw->create_from_image(i);
w_edit->set_texture(tw);
w_edit->set_ignore_mouse(false);
w_edit->set_custom_minimum_size(Size2(15,256));
w_edit->connect("input_event", this, "_w_input");
c= memnew( Control );
w_edit->add_child(c);
@ -594,17 +607,6 @@ ColorPicker::ColorPicker() :
set_color(Color(1,1,1));
i.create(256,20,false,Image::FORMAT_RGB);
for (int y=0;y<20;y++)
for(int x=0;x<256;x++)
if ((x/4+y/4)%2)
i.put_pixel(x,y,Color(1,1,1));
else
i.put_pixel(x,y,Color(0.6,0.6,0.6));
Ref<ImageTexture> t_smpl;
t_smpl.instance();
t_smpl->create_from_image(i);
sample->set_texture(t_smpl);
HBoxContainer *bbc = memnew( HBoxContainer );
add_child(bbc);

View File

@ -39,7 +39,7 @@ void Patch9Frame::_notification(int p_what) {
Size2 s=get_size();
RID ci = get_canvas_item();
VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate);
VS::get_singleton()->canvas_item_add_nine_patch(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),VS::NINE_PATCH_STRETCH,VS::NINE_PATCH_STRETCH,draw_center,modulate);
// draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
/*

View File

@ -246,6 +246,15 @@ Node* CanvasLayer::get_custom_viewport() const {
return custom_viewport;
}
void CanvasLayer::reset_sort_index() {
sort_index=0;
}
int CanvasLayer::get_sort_index() {
return sort_index++;
}
void CanvasLayer::_bind_methods() {
@ -296,4 +305,5 @@ CanvasLayer::CanvasLayer() {
canvas = Ref<World2D>( memnew(World2D) );
custom_viewport=NULL;
custom_viewport_id=0;
sort_index=0;
}

Some files were not shown because too many files have changed in this diff Show More