Merge remote-tracking branch 'origin/gles3' into gles3-on-master

Various merge conflicts have been fixed manually and some mistakes
might have been made - time will tell :)
This commit is contained in:
Rémi Verschelde 2017-01-02 21:38:20 +01:00
commit 3f3f5a5359
287 changed files with 59481 additions and 17904 deletions

1
.gitignore vendored
View file

@ -8,6 +8,7 @@ platform/osx/logo.h
platform/windows/logo.h
platform/x11/logo.h
drivers/gles2/shaders/*.h
drivers/gles3/shaders/*.h
modules/register_module_types.cpp
core/version.h
core/method_bind.inc

View file

@ -348,6 +348,9 @@ if selected_platform in platform_list:
if (env['verbose'] == 'no'):
methods.no_verbose(sys, env)
if (True): # FIXME: detect GLES3
env.Append( BUILDERS = { 'GLES3_GLSL' : env.Builder(action = methods.build_gles3_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
Export('env')

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,10 @@ public:
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_to_screen(viewport);
Size2i screen_size = OS::get_singleton()->get_window_size();
vs->viewport_set_size(viewport,screen_size.x,screen_size.y);
vs->viewport_attach_to_screen(viewport,Rect2(Vector2(),screen_size));
vs->viewport_set_active(viewport,true);
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 +195,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 +208,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,7 +37,7 @@
#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"
typedef ShaderLanguage SL;
@ -57,50 +57,54 @@ static String _mktab(int p_level) {
static String _typestr(SL::DataType p_type) {
switch(p_type) {
case SL::TYPE_VOID: return "void";
case SL::TYPE_BOOL: return "bool";
case SL::TYPE_FLOAT: return "float";
case SL::TYPE_VEC2: return "vec2";
case SL::TYPE_VEC3: return "vec3";
case SL::TYPE_VEC4: return "vec4";
case SL::TYPE_MAT3: return "mat3";
case SL::TYPE_MAT4: return "mat4";
case SL::TYPE_TEXTURE: return "texture";
case SL::TYPE_CUBEMAP: return "cubemap";
default: {}
}
return ShaderLanguage::get_datatype_name(p_type);
return "";
}
static String _prestr(SL::DataPrecision p_pres) {
switch(p_pres) {
case SL::PRECISION_LOWP: return "lowp ";
case SL::PRECISION_MEDIUMP: return "mediump ";
case SL::PRECISION_HIGHP: return "highp ";
case SL::PRECISION_DEFAULT: return "";
}
return "";
}
static String _opstr(SL::Operator p_op) {
switch(p_op) {
case SL::OP_ASSIGN: return "=";
case SL::OP_ADD: return "+";
case SL::OP_SUB: return "-";
case SL::OP_MUL: return "*";
case SL::OP_DIV: return "/";
case SL::OP_ASSIGN_ADD: return "+=";
case SL::OP_ASSIGN_SUB: return "-=";
case SL::OP_ASSIGN_MUL: return "*=";
case SL::OP_ASSIGN_DIV: return "/=";
case SL::OP_NEG: return "-";
case SL::OP_NOT: return "!";
case SL::OP_CMP_EQ: return "==";
case SL::OP_CMP_NEQ: return "!=";
case SL::OP_CMP_LEQ: return "<=";
case SL::OP_CMP_GEQ: return ">=";
case SL::OP_CMP_LESS: return "<";
case SL::OP_CMP_GREATER: return ">";
case SL::OP_CMP_OR: return "||";
case SL::OP_CMP_AND: return "&&";
default: return "";
}
return ShaderLanguage::get_operator_text(p_op);
return "";
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value>& p_values) {
switch(p_type) {
case SL::TYPE_BOOL: return p_values[0].boolean?"true":"false";
case SL::TYPE_BVEC2: return String()+"bvec2("+(p_values[0].boolean?"true":"false")+(p_values[1].boolean?"true":"false")+")";
case SL::TYPE_BVEC3: return String()+"bvec3("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+")";
case SL::TYPE_BVEC4: return String()+"bvec4("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+","+(p_values[3].boolean?"true":"false")+")";
case SL::TYPE_INT: return rtos(p_values[0].sint);
case SL::TYPE_IVEC2: return String()+"ivec2("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+")";
case SL::TYPE_IVEC3: return String()+"ivec3("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+")";
case SL::TYPE_IVEC4: return String()+"ivec4("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+","+rtos(p_values[3].sint)+")";
case SL::TYPE_UINT: return rtos(p_values[0].real);
case SL::TYPE_UVEC2: return String()+"uvec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")";
case SL::TYPE_UVEC3: return String()+"uvec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")";
case SL::TYPE_UVEC4: return String()+"uvec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")";
case SL::TYPE_FLOAT: return rtos(p_values[0].real);
case SL::TYPE_VEC2: return String()+"vec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")";
case SL::TYPE_VEC3: return String()+"vec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")";
case SL::TYPE_VEC4: return String()+"vec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")";
default: ERR_FAIL_V(String());
}
}
static String dump_node_code(SL::Node *p_node,int p_level) {
@ -109,18 +113,48 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
switch(p_node->type) {
case SL::Node::TYPE_PROGRAM: {
case SL::Node::TYPE_SHADER: {
SL::ProgramNode *pnode=(SL::ProgramNode*)p_node;
SL::ShaderNode *pnode=(SL::ShaderNode*)p_node;
for(Map<StringName,SL::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
String ucode="uniform ";
ucode+=_typestr(E->get().type)+"="+String(E->get().default_value)+"\n";
code+=ucode;
ucode+=_prestr(E->get().precission);
ucode+=_typestr(E->get().type);
ucode+=" "+String(E->key());
if (E->get().default_value.size()) {
ucode+=" = "+get_constant_text(E->get().type,E->get().default_value);
}
static const char*hint_name[SL::ShaderNode::Uniform::HINT_MAX]={
"",
"color",
"range",
"albedo",
"normal",
"black",
"white"
};
if (E->get().hint)
ucode+=" : "+String(hint_name[E->get().hint]);
code+=ucode+"\n";
}
for(Map<StringName,SL::ShaderNode::Varying>::Element *E=pnode->varyings.front();E;E=E->next()) {
String vcode="varying ";
vcode+=_prestr(E->get().precission);
vcode+=_typestr(E->get().type);
vcode+=" "+String(E->key());
code+=vcode+"\n";
}
for(int i=0;i<pnode->functions.size();i++) {
SL::FunctionNode *fnode=pnode->functions[i].function;
@ -131,16 +165,15 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
if (i>0)
header+=", ";
header+=_typestr(fnode->arguments[i].type)+" "+fnode->arguments[i].name;
header+=_prestr(fnode->arguments[i].precision)+_typestr(fnode->arguments[i].type)+" "+fnode->arguments[i].name;
}
header+=") {\n";
header+=")\n";
code+=header;
code+=dump_node_code(fnode->body,p_level+1);
code+="}\n";
}
code+=dump_node_code(pnode->body,p_level);
//code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_FUNCTION: {
@ -149,15 +182,23 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
SL::BlockNode *bnode=(SL::BlockNode*)p_node;
//variables
for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {
code+=_mktab(p_level-1)+"{\n";
for(Map<StringName,SL::BlockNode::Variable>::Element *E=bnode->variables.front();E;E=E->next()) {
code+=_mktab(p_level)+_typestr(E->value())+" "+E->key()+";\n";
code+=_mktab(p_level)+_prestr(E->get().precision)+_typestr(E->get().type)+" "+E->key()+";\n";
}
for(int i=0;i<bnode->statements.size();i++) {
code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";\n";
String scode = dump_node_code(bnode->statements[i],p_level);
if (bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW) {
code+=scode; //use directly
} else {
code+=_mktab(p_level)+scode+";\n";
}
}
code+=_mktab(p_level-1)+"}\n";
} break;
@ -168,18 +209,7 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
} break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
switch(cnode->datatype) {
case SL::TYPE_BOOL: code=cnode->value.operator bool()?"true":"false"; break;
case SL::TYPE_FLOAT: code=cnode->value; break;
case SL::TYPE_VEC2: { Vector2 v = cnode->value; code="vec2("+rtos(v.x)+", "+rtos(v.y)+")"; } break;
case SL::TYPE_VEC3: { Vector3 v = cnode->value; code="vec3("+rtos(v.x)+", "+rtos(v.y)+", "+rtos(v.z)+")"; } break;
case SL::TYPE_VEC4: { Plane v = cnode->value; code="vec4("+rtos(v.normal.x)+", "+rtos(v.normal.y)+", "+rtos(v.normal.z)+", "+rtos(v.d)+")"; } break;
case SL::TYPE_MAT3: { Matrix3 x = cnode->value; code="mat3( vec3("+rtos(x.get_axis(0).x)+", "+rtos(x.get_axis(0).y)+", "+rtos(x.get_axis(0).z)+"), vec3("+rtos(x.get_axis(1).x)+", "+rtos(x.get_axis(1).y)+", "+rtos(x.get_axis(1).z)+"), vec3("+rtos(x.get_axis(2).x)+", "+rtos(x.get_axis(2).y)+", "+rtos(x.get_axis(2).z)+"))"; } break;
case SL::TYPE_MAT4: { Transform x = cnode->value; code="mat4( vec3("+rtos(x.basis.get_axis(0).x)+", "+rtos(x.basis.get_axis(0).y)+", "+rtos(x.basis.get_axis(0).z)+"), vec3("+rtos(x.basis.get_axis(1).x)+", "+rtos(x.basis.get_axis(1).y)+", "+rtos(x.basis.get_axis(1).z)+"), vec3("+rtos(x.basis.get_axis(2).x)+", "+rtos(x.basis.get_axis(2).y)+", "+rtos(x.basis.get_axis(2).z)+"), vec3("+rtos(x.origin.x)+", "+rtos(x.origin.y)+", "+rtos(x.origin.z)+"))"; } break;
default: code="<error: "+Variant::get_type_name(cnode->value.get_type())+" ("+itos(cnode->datatype)+">";
}
return get_constant_text(cnode->datatype,cnode->values);
} break;
case SL::Node::TYPE_OPERATOR: {
@ -193,28 +223,25 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
case SL::OP_ASSIGN_SUB:
case SL::OP_ASSIGN_MUL:
case SL::OP_ASSIGN_DIV:
case SL::OP_ASSIGN_SHIFT_LEFT:
case SL::OP_ASSIGN_SHIFT_RIGHT:
case SL::OP_ASSIGN_MOD:
case SL::OP_ASSIGN_BIT_AND:
case SL::OP_ASSIGN_BIT_OR:
case SL::OP_ASSIGN_BIT_XOR:
code=dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level);
break;
case SL::OP_ADD:
case SL::OP_SUB:
case SL::OP_MUL:
case SL::OP_DIV:
case SL::OP_CMP_EQ:
case SL::OP_CMP_NEQ:
case SL::OP_CMP_LEQ:
case SL::OP_CMP_GEQ:
case SL::OP_CMP_LESS:
case SL::OP_CMP_GREATER:
case SL::OP_CMP_OR:
case SL::OP_CMP_AND:
code="("+dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
break;
case SL::OP_NEG:
case SL::OP_BIT_INVERT:
case SL::OP_NEGATE:
case SL::OP_NOT:
case SL::OP_DECREMENT:
case SL::OP_INCREMENT:
code=_opstr(onode->op)+dump_node_code(onode->arguments[0],p_level);
break;
case SL::OP_POST_DECREMENT:
case SL::OP_POST_INCREMENT:
code=dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op);
break;
case SL::OP_CALL:
case SL::OP_CONSTRUCT:
code=dump_node_code(onode->arguments[0],p_level)+"(";
@ -225,7 +252,12 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
}
code+=")";
break;
default: {}
default: {
code="("+dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
break;
}
}
} break;
@ -233,20 +265,19 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
if (cfnode->flow_op==SL::FLOW_OP_IF) {
code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {\n";
code+=dump_node_code(cfnode->statements[1],p_level+1);
if (cfnode->statements.size()==3) {
code+=_mktab(p_level)+"if ("+dump_node_code(cfnode->expressions[0],p_level)+")\n";
code+=dump_node_code(cfnode->blocks[0],p_level+1);
if (cfnode->blocks.size()==2) {
code+="} else {\n";
code+=dump_node_code(cfnode->statements[2],p_level+1);
code+=_mktab(p_level)+"else\n";
code+=dump_node_code(cfnode->blocks[1],p_level+1);
}
code+="}\n";
} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
if (cfnode->statements.size()) {
code="return "+dump_node_code(cfnode->statements[0],p_level);
if (cfnode->blocks.size()) {
code="return "+dump_node_code(cfnode->blocks[0],p_level);
} else {
code="return";
}
@ -264,16 +295,14 @@ static String dump_node_code(SL::Node *p_node,int p_level) {
}
static Error recreate_code(void *p_str,SL::ProgramNode *p_program) {
static Error recreate_code(void *p_str,SL::ShaderNode *p_program) {
print_line("recr");
String *str=(String*)p_str;
*str=dump_node_code(p_program,0);
return OK;
}
@ -283,6 +312,7 @@ MainLoop* test() {
if (cmdlargs.empty()) {
//try editor!
print_line("usage: godot -test shader_lang <shader>");
return NULL;
}
@ -303,38 +333,29 @@ MainLoop* test() {
code+=c;
}
int errline;
int errcol;
String error;
print_line(SL::lex_debug(code));
Error err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,NULL,NULL,&error,&errline,&errcol);
SL sl;
print_line("tokens:\n\n"+sl.token_debug(code));
Map<StringName,Map<StringName,SL::DataType> > dt;
dt["fragment"]["ALBEDO"]=SL::TYPE_VEC3;
Set<String> rm;
rm.insert("popo");
Error err = sl.compile(code,dt,rm);
if (err) {
print_line("Error: "+itos(errline)+":"+itos(errcol)+" "+error);
print_line("Error at line: "+rtos(sl.get_error_line())+": "+sl.get_error_text());
return NULL;
} else {
String code;
recreate_code(&code,sl.get_shader());
print_line("code:\n\n"+code);
}
print_line("Compile OK! - pretty printing");
String rcode;
err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,recreate_code,&rcode,&error,&errline,&errcol);
if (!err) {
print_line(rcode);
}
ShaderCompilerGLES2 comp;
String codeline,globalsline;
SL::VarInfo vi;
vi.name="mongs";
vi.type=SL::TYPE_VEC3;
ShaderCompilerGLES2::Flags fl;
comp.compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,codeline,globalsline,fl);
return NULL;
}
}

View file

@ -49,7 +49,8 @@
enum ErrorHandlerType {
ERR_HANDLER_ERROR,
ERR_HANDLER_WARNING,
ERR_HANDLER_SCRIPT
ERR_HANDLER_SCRIPT,
ERR_HANDLER_SHADER,
};
typedef void (*ErrorHandlerFunc)(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);

View file

@ -658,37 +658,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();
@ -975,26 +975,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();
@ -1400,6 +1404,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-2017 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

@ -54,7 +54,7 @@ void CameraMatrix::set_zero() {
}
Plane CameraMatrix::xform4(const Plane& p_vec4) {
Plane CameraMatrix::xform4(const Plane& p_vec4) const {
Plane ret;
@ -495,6 +495,28 @@ void CameraMatrix::set_light_bias() {
}
void CameraMatrix::set_light_atlas_rect(const Rect2& p_rect) {
float *m=&matrix[0][0];
m[0]=p_rect.size.width,
m[1]=0.0,
m[2]=0.0,
m[3]=0.0,
m[4]=0.0,
m[5]=p_rect.size.height,
m[6]=0.0,
m[7]=0.0,
m[8]=0.0,
m[9]=0.0,
m[10]=1.0,
m[11]=0.0,
m[12]=p_rect.pos.x,
m[13]=p_rect.pos.y,
m[14]=0.0,
m[15]=1.0;
}
CameraMatrix::operator String() const {
String str;
@ -512,6 +534,15 @@ float CameraMatrix::get_aspect() const {
return w/h;
}
int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const {
Vector3 result = xform(Vector3(1,0,-1));
return int((result.x * 0.5 + 0.5) * p_for_pixel_width);
}
float CameraMatrix::get_fov() const {
const float * matrix = (const float*)this->matrix;

View file

@ -30,6 +30,7 @@
#define CAMERA_MATRIX_H
#include "transform.h"
#include "math_2d.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@ -53,6 +54,7 @@ struct CameraMatrix {
void set_identity();
void set_zero();
void set_light_bias();
void set_light_atlas_rect(const Rect2& p_rect);
void set_perspective(float p_fovy_degrees, float p_aspect, float p_z_near, float p_z_far,bool p_flip_fov=false);
void set_orthogonal(float p_left, float p_right, float p_bottom, float p_top, float p_znear, float p_zfar);
void set_orthogonal(float p_size, float p_aspect, float p_znear, float p_zfar,bool p_flip_fov=false);
@ -78,13 +80,14 @@ struct CameraMatrix {
CameraMatrix operator*(const CameraMatrix& p_matrix) const;
Plane xform4(const Plane& p_vec4);
Plane xform4(const Plane& p_vec4) const;
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
operator String() const;
void scale_translate_to_fit(const AABB& p_aabb);
void make_scale(const Vector3 &p_scale);
int get_pixels_per_meter(int p_for_pixel_width) const;
operator Transform() const;
CameraMatrix();

View file

@ -175,6 +175,108 @@ public:
static double log(double x);
static double exp(double x);
static _FORCE_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h)
{
uint16_t h_exp, h_sig;
uint32_t f_sgn, f_exp, f_sig;
h_exp = (h&0x7c00u);
f_sgn = ((uint32_t)h&0x8000u) << 16;
switch (h_exp) {
case 0x0000u: /* 0 or subnormal */
h_sig = (h&0x03ffu);
/* Signed zero */
if (h_sig == 0) {
return f_sgn;
}
/* Subnormal */
h_sig <<= 1;
while ((h_sig&0x0400u) == 0) {
h_sig <<= 1;
h_exp++;
}
f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23;
f_sig = ((uint32_t)(h_sig&0x03ffu)) << 13;
return f_sgn + f_exp + f_sig;
case 0x7c00u: /* inf or NaN */
/* All-ones exponent and a copy of the significand */
return f_sgn + 0x7f800000u + (((uint32_t)(h&0x03ffu)) << 13);
default: /* normalized */
/* Just need to adjust the exponent and shift */
return f_sgn + (((uint32_t)(h&0x7fffu) + 0x1c000u) << 13);
}
}
static _FORCE_INLINE_ float halfptr_to_float(const uint16_t *h) {
union {
uint32_t u32;
float f32;
} u;
u.u32=halfbits_to_floatbits(*h);
return u.f32;
}
static _FORCE_INLINE_ uint16_t make_half_float(float f) {
union {
float fv;
uint32_t ui;
} ci;
ci.fv=f;
uint32_t x = ci.ui;
uint32_t sign = (unsigned short)(x >> 31);
uint32_t mantissa;
uint32_t exp;
uint16_t hf;
// get mantissa
mantissa = x & ((1 << 23) - 1);
// get exponent bits
exp = x & (0xFF << 23);
if (exp >= 0x47800000)
{
// check if the original single precision float number is a NaN
if (mantissa && (exp == (0xFF << 23)))
{
// we have a single precision NaN
mantissa = (1 << 23) - 1;
}
else
{
// 16-bit half-float representation stores number as Inf
mantissa = 0;
}
hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) |
(uint16_t)(mantissa >> 13);
}
// check if exponent is <= -15
else if (exp <= 0x38000000)
{
/*// store a denorm half-float value or zero
exp = (0x38000000 - exp) >> 23;
mantissa >>= (14 + exp);
hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa);
*/
hf=0; //denormals do not work for 3D, convert to zero
}
else
{
hf = (((uint16_t)sign) << 15) |
(uint16_t)((exp - 0x38000000) >> 13) |
(uint16_t)(mantissa >> 13);
}
return hf;
}
};

View file

@ -68,6 +68,7 @@ void OS::print_error(const char* p_function,const char* p_file,int p_line,const
case ERR_ERROR: err_type="**ERROR**"; break;
case ERR_WARNING: err_type="**WARNING**"; break;
case ERR_SCRIPT: err_type="**SCRIPT ERROR**"; break;
case ERR_SHADER: err_type="**SHADER ERROR**"; break;
}
if (p_rationale && *p_rationale)

View file

@ -120,7 +120,8 @@ public:
enum ErrorType {
ERR_ERROR,
ERR_WARNING,
ERR_SCRIPT
ERR_SCRIPT,
ERR_SHADER
};
virtual void print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type=ERR_ERROR);

View file

@ -34,6 +34,9 @@ struct Pair {
F first;
S second;
Pair() {}
Pair( F p_first, S p_second) { first=p_first; second=p_second; }
};
#endif // PAIR_H

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,197 @@
#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());
}
~RID_Owner() {
_FORCE_INLINE_ T * getptr(const RID& p_rid) {
if (thread_safe) {
return static_cast<T*>(p_rid.get_data());
memdelete(mutex);
}
}
_FORCE_INLINE_ bool owns(const RID& p_rid) const {
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

@ -612,6 +612,8 @@ String String::get_slicec(CharType p_splitter, int p_slice) const {
if (p_slice==count) {
return substr(prev,i-prev);
} else if (c[i]==0) {
return String();
} else {
count++;
prev=i+1;

View file

@ -619,13 +619,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);
@ -1528,12 +1524,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));
@ -1792,34 +1784,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

@ -13448,12 +13448,12 @@
</theme_item>
</theme_items>
</class>
<class name="FixedMaterial" inherits="Material" category="Core">
<class name="FixedSpatialMaterial" inherits="Material" category="Core">
<brief_description>
Simple Material with a fixed parameter set.
</brief_description>
<description>
FixedMaterial is a simple type of material [Resource], which contains a fixed amount of parameters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
FixedSpatialMaterial is a simple type of material [Resource], which contains a fixed amount of parameters. It is the only type of material supported in fixed-pipeline devices and APIs. It is also an often a better alternative to [ShaderMaterial] for most simple use cases.
</description>
<methods>
<method name="get_fixed_flag" qualifiers="const">
@ -16342,15 +16342,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>
@ -16360,23 +16360,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

@ -20,7 +20,7 @@ if (env["xaudio2"] == "yes"):
SConscript("xaudio2/SCsub")
# Graphics drivers
SConscript('gles2/SCsub')
SConscript('gles3/SCsub')
SConscript('gl_context/SCsub')
# Core dependencies

View file

@ -0,0 +1,285 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are 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 Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by sending them to the public Khronos Bugzilla
* (http://khronos.org/bugzilla) by filing a bug against product
* "Khronos (general)" component "Registry".
*
* A predefined template which fills in some of the bug fields can be
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
* must create a Bugzilla login first.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# include <sys/cdefs.h>
# define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

View file

@ -3,8 +3,11 @@
Import('env')
if (env["platform"] in ["haiku", "osx", "windows", "x11"]):
# FIXME: Dead code, now using GLAD
"""
# Thirdparty source files
if (env['builtin_glew'] != 'no'): # builtin
thirdparty_dir = "#thirdparty/glew/"
thirdparty_sources = [
"glew.c",
@ -16,6 +19,12 @@ if (env["platform"] in ["haiku", "osx", "windows", "x11"]):
env.Append(CPPPATH=[thirdparty_dir])
env.Append(CPPFLAGS=['-DGLEW_ENABLED'])
"""
env.add_source_files(env.drivers_sources,"glad.c")
env.Append(CPPFLAGS = ['-DGLAD_ENABLED'])
env.Append(CPPFLAGS = ['-DGLES_OVER_GL'])
env.Append(CPPPATH = ['.'])
# Godot source files
env.add_source_files(env.drivers_sources, "*.cpp")

1818
drivers/gl_context/glad.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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
@ -395,5 +395,6 @@ LIGHT_SHADER_CODE
// color.rgb*=color.a;
gl_FragColor = color;
}

View file

@ -71,6 +71,11 @@ uniform sampler2D source;
#endif
varying vec2 uv2_interp;
#ifdef USE_DEPTH
uniform highp sampler2D source_depth; //texunit:1
#endif
#ifdef USE_GLOW
uniform sampler2D glow_source;
@ -547,5 +552,10 @@ void main() {
gl_FragColor = color;
#ifdef USE_DEPTH
gl_FragDepth = texture(source_depth,uv_interp).r;
#endif
}

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,107 @@
#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];
float time[4];
};
struct Data {
GLuint canvas_quad_vertices;
GLuint canvas_quad_array;
GLuint primitive_quad_buffer;
GLuint primitive_quad_buffer_arrays[4];
} 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,362 @@
#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 scene;
}
#define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
#define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
#define _EXT_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
#define _EXT_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
#define _EXT_DEBUG_SOURCE_API_ARB 0x8246
#define _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
#define _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
#define _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
#define _EXT_DEBUG_SOURCE_APPLICATION_ARB 0x824A
#define _EXT_DEBUG_SOURCE_OTHER_ARB 0x824B
#define _EXT_DEBUG_TYPE_ERROR_ARB 0x824C
#define _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
#define _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
#define _EXT_DEBUG_TYPE_PORTABILITY_ARB 0x824F
#define _EXT_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
#define _EXT_DEBUG_TYPE_OTHER_ARB 0x8251
#define _EXT_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
#define _EXT_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
#define _EXT_DEBUG_LOGGED_MESSAGES_ARB 0x9145
#define _EXT_DEBUG_SEVERITY_HIGH_ARB 0x9146
#define _EXT_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148
#define _EXT_DEBUG_OUTPUT 0x92E0
#ifdef WINDOWS_ENABLED
#define GLAPIENTRY APIENTRY
#else
#define GLAPIENTRY
#endif
static void GLAPIENTRY _gl_debug_print(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const GLvoid *userParam)
{
if (type==_EXT_DEBUG_TYPE_OTHER_ARB)
return;
print_line("mesege");
char debSource[256], debType[256], debSev[256];
if(source == _EXT_DEBUG_SOURCE_API_ARB)
strcpy(debSource, "OpenGL");
else if(source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
strcpy(debSource, "Windows");
else if(source == _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB)
strcpy(debSource, "Shader Compiler");
else if(source == _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB)
strcpy(debSource, "Third Party");
else if(source == _EXT_DEBUG_SOURCE_APPLICATION_ARB)
strcpy(debSource, "Application");
else if(source == _EXT_DEBUG_SOURCE_OTHER_ARB)
strcpy(debSource, "Other");
if(type == _EXT_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error");
else if(type == _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
strcpy(debType, "Deprecated behavior");
else if(type == _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
strcpy(debType, "Undefined behavior");
else if(type == _EXT_DEBUG_TYPE_PORTABILITY_ARB)
strcpy(debType, "Portability");
else if(type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
strcpy(debType, "Performance");
else if(type == _EXT_DEBUG_TYPE_OTHER_ARB)
strcpy(debType, "Other");
if(severity == _EXT_DEBUG_SEVERITY_HIGH_ARB)
strcpy(debSev, "High");
else if(severity == _EXT_DEBUG_SEVERITY_MEDIUM_ARB)
strcpy(debSev, "Medium");
else if(severity == _EXT_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);
}
typedef void (*DEBUGPROCARB)(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const char* message,
const void* userParam);
typedef void (* DebugMessageCallbackARB) (DEBUGPROCARB callback, const void *userParam);
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
#ifdef GLAD_ENABLED
if(!gladLoadGL()) {
ERR_PRINT("Error initializing GLAD");
}
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(_gl_debug_print, NULL);
glEnable(_EXT_DEBUG_OUTPUT);
#endif
/* 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();
scene->initialize();
}
void RasterizerGLES3::begin_frame(){
uint64_t tick = OS::get_singleton()->get_ticks_usec();
double time_total = double(tick)/1000000.0;
storage->frame.time[0]=time_total;
storage->frame.time[1]=Math::fmod(time_total,3600);
storage->frame.time[2]=Math::fmod(time_total,900);
storage->frame.time[3]=Math::fmod(time_total,60);
storage->frame.count++;
storage->frame.delta = double(tick-storage->frame.prev_tick)/1000000.0;
if (storage->frame.prev_tick==0) {
//to avoid hiccups
storage->frame.delta=0.001;
}
storage->frame.prev_tick=tick;
storage->update_dirty_multimeshes();
storage->update_dirty_skeletons();
storage->update_dirty_shaders();
storage->update_dirty_materials();
storage->update_particles();
storage->info.render_object_count=0;
storage->info.render_material_switch_count=0;
storage->info.render_surface_switch_count=0;
storage->info.render_shader_rebind_count=0;
storage->info.render_vertices_count=0;
scene->iteration();
}
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->fbo);
print_line("unbind clear of: "+storage->frame.clear_request_color);
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;
glBindFramebuffer(GL_FRAMEBUFFER,rt->fbo);
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();
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER,storage->config.system_fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,rt->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
OS::get_singleton()->swap_buffers();
/* print_line("objects: "+itos(storage->info.render_object_count));
print_line("material chages: "+itos(storage->info.render_material_switch_count));
print_line("surface changes: "+itos(storage->info.render_surface_switch_count));
print_line("shader changes: "+itos(storage->info.render_shader_rebind_count));
print_line("vertices: "+itos(storage->info.render_vertices_count));
*/
}
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/render_architecture",0);
Globals::get_singleton()->set_custom_property_info("rendering/gles3/render_architecture",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Desktop,Mobile"));
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 );
scene = memnew( RasterizerSceneGLES3 );
canvas->storage=storage;
storage->canvas=canvas;
scene->storage=storage;
storage->scene=scene;
}
RasterizerGLES3::~RasterizerGLES3() {
memdelete(storage);
memdelete(canvas);
}

View file

@ -0,0 +1,41 @@
#ifndef RASTERIZERGLES3_H
#define RASTERIZERGLES3_H
#include "servers/visual/rasterizer.h"
#include "rasterizer_storage_gles3.h"
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
class RasterizerGLES3 : public Rasterizer {
static Rasterizer *_create_current();
RasterizerStorageGLES3 *storage;
RasterizerCanvasGLES3 *canvas;
RasterizerSceneGLES3 *scene;
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,733 @@
#ifndef RASTERIZERSCENEGLES3_H
#define RASTERIZERSCENEGLES3_H
#include "rasterizer_storage_gles3.h"
#include "drivers/gles3/shaders/scene.glsl.h"
#include "drivers/gles3/shaders/cube_to_dp.glsl.h"
#include "drivers/gles3/shaders/resolve.glsl.h"
#include "drivers/gles3/shaders/screen_space_reflection.glsl.h"
#include "drivers/gles3/shaders/effect_blur.glsl.h"
#include "drivers/gles3/shaders/subsurf_scattering.glsl.h"
#include "drivers/gles3/shaders/ssao_minify.glsl.h"
#include "drivers/gles3/shaders/ssao.glsl.h"
#include "drivers/gles3/shaders/ssao_blur.glsl.h"
#include "drivers/gles3/shaders/exposure.glsl.h"
#include "drivers/gles3/shaders/tonemap.glsl.h"
class RasterizerSceneGLES3 : public RasterizerScene {
public:
enum ShadowFilterMode {
SHADOW_FILTER_NEAREST,
SHADOW_FILTER_PCF5,
SHADOW_FILTER_PCF13,
};
ShadowFilterMode shadow_filter_mode;
uint64_t shadow_atlas_realloc_tolerance_msec;
enum SubSurfaceScatterQuality {
SSS_QUALITY_LOW,
SSS_QUALITY_MEDIUM,
SSS_QUALITY_HIGH,
};
SubSurfaceScatterQuality subsurface_scatter_quality;
float subsurface_scatter_size;
bool subsurface_scatter_follow_surface;
uint64_t render_pass;
uint64_t scene_pass;
uint32_t current_material_index;
uint32_t current_geometry_index;
RID default_material;
RID default_material_twosided;
RID default_shader;
RID default_shader_twosided;
RasterizerStorageGLES3 *storage;
Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink;
int exposure_shrink_size;
struct State {
bool texscreen_copied;
int current_blend_mode;
float current_line_width;
int current_depth_draw;
GLuint current_main_tex;
SceneShaderGLES3 scene_shader;
CubeToDpShaderGLES3 cube_to_dp_shader;
ResolveShaderGLES3 resolve_shader;
ScreenSpaceReflectionShaderGLES3 ssr_shader;
EffectBlurShaderGLES3 effect_blur_shader;
SubsurfScatteringShaderGLES3 sss_shader;
SsaoMinifyShaderGLES3 ssao_minify_shader;
SsaoShaderGLES3 ssao_shader;
SsaoBlurShaderGLES3 ssao_blur_shader;
ExposureShaderGLES3 exposure_shader;
TonemapShaderGLES3 tonemap_shader;
struct SceneDataUBO {
float projection_matrix[16];
float camera_inverse_matrix[16];
float camera_matrix[16];
float time[4];
float ambient_light_color[4];
float bg_color[4];
float ambient_energy;
float bg_energy;
float shadow_z_offset;
float shadow_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
} ubo_data;
GLuint scene_ubo;
struct EnvironmentRadianceUBO {
float transform[16];
float box_min[4]; //unused for now
float box_max[4];
float ambient_contribution;
} env_radiance_data;
GLuint env_radiance_ubo;
GLuint brdf_texture;
GLuint skybox_verts;
GLuint skybox_array;
GLuint directional_ubo;
GLuint spot_array_ubo;
GLuint omni_array_ubo;
GLuint reflection_array_ubo;
GLuint immediate_buffer;
GLuint immediate_array;
uint32_t ubo_light_size;
uint8_t *spot_array_tmp;
uint8_t *omni_array_tmp;
uint8_t *reflection_array_tmp;
int max_ubo_lights;
int max_forward_lights_per_object;
int max_ubo_reflections;
int max_skeleton_bones;
int spot_light_count;
int omni_light_count;
int directional_light_count;
int reflection_probe_count;
bool cull_front;
bool used_sss;
} state;
/* SHADOW ATLAS API */
struct ShadowAtlas : public RID_Data {
enum {
QUADRANT_SHIFT=27,
SHADOW_INDEX_MASK=(1<<QUADRANT_SHIFT)-1,
SHADOW_INVALID=0xFFFFFFFF
};
struct Quadrant {
uint32_t subdivision;
struct Shadow {
RID owner;
uint64_t version;
uint64_t alloc_tick;
Shadow() {
version=0;
alloc_tick=0;
}
};
Vector<Shadow> shadows;
Quadrant() {
subdivision=0; //not in use
}
} quadrants[4];
int size_order[4];
uint32_t smallest_subdiv;
int size;
GLuint fbo;
GLuint depth;
Map<RID,uint32_t> shadow_owners;
};
struct ShadowCubeMap {
GLuint fbo_id[6];
GLuint cubemap;
int size;
};
Vector<ShadowCubeMap> shadow_cubemaps;
RID_Owner<ShadowAtlas> shadow_atlas_owner;
RID shadow_atlas_create();
void shadow_atlas_set_size(RID p_atlas,int p_size);
void shadow_atlas_set_quadrant_subdivision(RID p_atlas,int p_quadrant,int p_subdivision);
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
bool shadow_atlas_update_light(RID p_atlas,RID p_light_intance,float p_coverage,uint64_t p_light_version);
struct DirectionalShadow {
GLuint fbo;
GLuint depth;
int light_count;
int size;
int current_light;
} directional_shadow;
virtual int get_directional_light_shadow_size(RID p_light_intance);
virtual void set_directional_shadow_count(int p_count);
/* REFLECTION PROBE ATLAS API */
struct ReflectionAtlas : public RID_Data {
int subdiv;
int size;
struct Reflection {
RID owner;
uint64_t last_frame;
};
GLuint fbo[6];
GLuint color;
Vector<Reflection> reflections;
};
mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner;
virtual RID reflection_atlas_create();
virtual void reflection_atlas_set_size(RID p_ref_atlas,int p_size);
virtual void reflection_atlas_set_subdivision(RID p_ref_atlas,int p_subdiv);
/* REFLECTION CUBEMAPS */
struct ReflectionCubeMap {
GLuint fbo_id[6];
GLuint cubemap;
GLuint depth;
int size;
};
Vector<ReflectionCubeMap> reflection_cubemaps;
/* REFLECTION PROBE INSTANCE */
struct ReflectionProbeInstance : public RID_Data {
RasterizerStorageGLES3::ReflectionProbe *probe_ptr;
RID probe;
RID self;
RID atlas;
int reflection_atlas_index;
int render_step;
uint64_t last_pass;
int reflection_index;
Transform transform;
};
struct ReflectionProbeDataUBO {
float box_extents[4];
float box_ofs[4];
float params[4]; // intensity, 0, 0, boxproject
float ambient[4]; //color, probe contrib
float atlas_clamp[4];
float local_matrix[16]; //up to here for spot and omni, rest is for directional
//notes: for ambientblend, use distance to edge to blend between already existing global environment
};
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
virtual RID reflection_probe_instance_create(RID p_probe);
virtual void reflection_probe_instance_set_transform(RID p_instance,const Transform& p_transform);
virtual void reflection_probe_release_atlas_index(RID p_instance);
virtual bool reflection_probe_instance_needs_redraw(RID p_instance);
virtual bool reflection_probe_instance_has_reflection(RID p_instance);
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas);
virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
/* ENVIRONMENT API */
struct Environment : public RID_Data {
VS::EnvironmentBG bg_mode;
RID skybox;
float skybox_scale;
Color bg_color;
float bg_energy;
float skybox_ambient;
Color ambient_color;
float ambient_energy;
float ambient_skybox_contribution;
int canvas_max_layer;
bool ssr_enabled;
int ssr_max_steps;
float ssr_accel;
float ssr_fade;
float ssr_depth_tolerance;
bool ssr_smooth;
bool ssr_roughness;
bool ssao_enabled;
float ssao_intensity;
float ssao_radius;
float ssao_intensity2;
float ssao_radius2;
float ssao_bias;
float ssao_light_affect;
Color ssao_color;
bool ssao_filter;
bool glow_enabled;
int glow_levels;
float glow_intensity;
float glow_strength;
float glow_bloom;
VS::EnvironmentGlowBlendMode glow_blend_mode;
float glow_hdr_bleed_treshold;
float glow_hdr_bleed_scale;
bool glow_bicubic_upscale;
VS::EnvironmentToneMapper tone_mapper;
float tone_mapper_exposure;
float tone_mapper_exposure_white;
bool auto_exposure;
float auto_exposure_speed;
float auto_exposure_min;
float auto_exposure_max;
float auto_exposure_grey;
bool dof_blur_far_enabled;
float dof_blur_far_distance;
float dof_blur_far_transition;
float dof_blur_far_amount;
VS::EnvironmentDOFBlurQuality dof_blur_far_quality;
bool dof_blur_near_enabled;
float dof_blur_near_distance;
float dof_blur_near_transition;
float dof_blur_near_amount;
VS::EnvironmentDOFBlurQuality dof_blur_near_quality;
Environment() {
bg_mode=VS::ENV_BG_CLEAR_COLOR;
skybox_scale=1.0;
bg_energy=1.0;
skybox_ambient=0;
ambient_energy=1.0;
ambient_skybox_contribution=0.0;
canvas_max_layer=0;
ssr_enabled=false;
ssr_max_steps=64;
ssr_accel=0.04;
ssr_fade=2.0;
ssr_depth_tolerance=0.2;
ssr_smooth=true;
ssr_roughness=true;
ssao_enabled=false;
ssao_intensity=1.0;
ssao_radius=1.0;
ssao_intensity2=1.0;
ssao_radius2=0.0;
ssao_bias=0.01;
ssao_light_affect=0;
ssao_filter=true;
tone_mapper=VS::ENV_TONE_MAPPER_LINEAR;
tone_mapper_exposure=1.0;
tone_mapper_exposure_white=1.0;
auto_exposure=false;
auto_exposure_speed=0.5;
auto_exposure_min=0.05;
auto_exposure_max=8;
auto_exposure_grey=0.4;
glow_enabled=false;
glow_levels=(1<<2)|(1<<4);
glow_intensity=0.8;
glow_strength=1.0;
glow_bloom=0.0;
glow_blend_mode=VS::GLOW_BLEND_MODE_SOFTLIGHT;
glow_hdr_bleed_treshold=1.0;
glow_hdr_bleed_scale=2.0;
glow_bicubic_upscale=false;
dof_blur_far_enabled=false;
dof_blur_far_distance=10;
dof_blur_far_transition=5;
dof_blur_far_amount=0.1;
dof_blur_far_quality=VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
dof_blur_near_enabled=false;
dof_blur_near_distance=2;
dof_blur_near_transition=1;
dof_blur_near_amount=0.1;
dof_blur_near_quality=VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
}
};
RID_Owner<Environment> environment_owner;
virtual RID environment_create();
virtual void environment_set_background(RID p_env,VS::EnvironmentBG p_bg);
virtual void environment_set_skybox(RID p_env,RID p_skybox);
virtual void environment_set_skybox_scale(RID p_env,float p_scale);
virtual void environment_set_bg_color(RID p_env,const Color& p_color);
virtual void environment_set_bg_energy(RID p_env,float p_energy);
virtual void environment_set_canvas_max_layer(RID p_env,int p_max_layer);
virtual void environment_set_ambient_light(RID p_env,const Color& p_color,float p_energy=1.0,float p_skybox_contribution=0.0);
virtual void environment_set_dof_blur_near(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_amount,VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_dof_blur_far(RID p_env,bool p_enable,float p_distance,float p_transition,float p_far_amount,VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_glow(RID p_env,bool p_enable,int p_level_flags,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode,float p_hdr_bleed_treshold,float p_hdr_bleed_scale,bool p_bicubic_upscale);
virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture);
virtual void environment_set_ssr(RID p_env,bool p_enable, int p_max_steps,float p_accel,float p_fade,float p_depth_tolerance,bool p_smooth,bool p_roughness);
virtual void environment_set_ssao(RID p_env,bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect,const Color &p_color,bool p_blur);
virtual void environment_set_tonemap(RID p_env,VS::EnvironmentToneMapper p_tone_mapper,float p_exposure,float p_white,bool p_auto_exposure,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale);
virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp);
/* LIGHT INSTANCE */
struct LightDataUBO {
float light_pos_inv_radius[4];
float light_direction_attenuation[4];
float light_color_energy[4];
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
float light_clamp[4];
float light_shadow_color[4];
float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
float shadow_matrix2[16];
float shadow_matrix3[16];
float shadow_matrix4[16];
float shadow_split_offsets[4];
};
struct LightInstance : public RID_Data {
struct ShadowTransform {
CameraMatrix camera;
Transform transform;
float farplane;
float split;
};
ShadowTransform shadow_transform[4];
RID self;
RID light;
RasterizerStorageGLES3::Light *light_ptr;
Transform transform;
Vector3 light_vector;
Vector3 spot_vector;
float linear_att;
uint64_t shadow_pass;
uint64_t last_scene_pass;
uint64_t last_scene_shadow_pass;
uint64_t last_pass;
uint16_t light_index;
uint16_t light_directional_index;
uint32_t current_shadow_atlas_key;
Vector2 dp;
Rect2 directional_rect;
Set<RID> shadow_atlases; //shadow atlases where this light is registered
LightInstance() { }
};
mutable RID_Owner<LightInstance> light_instance_owner;
virtual RID light_instance_create(RID p_light);
virtual void light_instance_set_transform(RID p_light_instance,const Transform& p_transform);
virtual void light_instance_set_shadow_transform(RID p_light_instance,const CameraMatrix& p_projection,const Transform& p_transform,float p_far,float p_split,int p_pass);
virtual void light_instance_mark_visible(RID p_light_instance);
/* REFLECTION INSTANCE */
struct GIProbeInstance : public RID_Data {
RID data;
RasterizerStorageGLES3::GIProbe *probe;
GLuint tex_cache;
Vector3 cell_size_cache;
Vector3 bounds;
Transform transform_to_data;
GIProbeInstance() { probe=NULL; tex_cache=0; }
};
mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
virtual RID gi_probe_instance_create();
virtual void gi_probe_instance_set_light_data(RID p_probe,RID p_base,RID p_data);
virtual void gi_probe_instance_set_transform_to_data(RID p_probe,const Transform& p_xform);
virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds);
/* RENDER LIST */
struct RenderList {
enum {
DEFAULT_MAX_ELEMENTS=65536,
SORT_FLAG_SKELETON=1,
SORT_FLAG_INSTANCING=2,
MAX_DIRECTIONAL_LIGHTS=16,
MAX_LIGHTS=4096,
MAX_REFLECTIONS=1024,
SORT_KEY_DEPTH_LAYER_SHIFT=60,
SORT_KEY_UNSHADED_FLAG=uint64_t(1)<<59,
SORT_KEY_NO_DIRECTIONAL_FLAG=uint64_t(1)<<58,
SORT_KEY_GI_PROBES_FLAG=uint64_t(1)<<57,
SORT_KEY_SHADING_SHIFT=57,
SORT_KEY_SHADING_MASK=7,
SORT_KEY_MATERIAL_INDEX_SHIFT=40,
SORT_KEY_GEOMETRY_INDEX_SHIFT=20,
SORT_KEY_GEOMETRY_TYPE_SHIFT=15,
SORT_KEY_SKELETON_FLAG=2,
SORT_KEY_MIRROR_FLAG=1
};
int max_elements;
struct Element {
RasterizerScene::InstanceBase *instance;
RasterizerStorageGLES3::Geometry *geometry;
RasterizerStorageGLES3::Material *material;
RasterizerStorageGLES3::GeometryOwner *owner;
uint64_t sort_key;
};
Element *_elements;
Element **elements;
int element_count;
int alpha_element_count;
void clear() {
element_count=0;
alpha_element_count=0;
}
//should eventually be replaced by radix
struct SortByKey {
_FORCE_INLINE_ bool operator()(const Element* A, const Element* B ) const {
return A->sort_key < B->sort_key;
}
};
void sort_by_key(bool p_alpha) {
SortArray<Element*,SortByKey> sorter;
if (p_alpha) {
sorter.sort(&elements[max_elements-alpha_element_count],alpha_element_count);
} else {
sorter.sort(elements,element_count);
}
}
struct SortByDepth {
_FORCE_INLINE_ bool operator()(const Element* A, const Element* B ) const {
return A->instance->depth > B->instance->depth;
}
};
void sort_by_depth(bool p_alpha) {
SortArray<Element*,SortByDepth> sorter;
if (p_alpha) {
sorter.sort(&elements[max_elements-alpha_element_count],alpha_element_count);
} else {
sorter.sort(elements,element_count);
}
}
_FORCE_INLINE_ Element* add_element() {
if (element_count+alpha_element_count>=max_elements)
return NULL;
elements[element_count]=&_elements[element_count];
return elements[element_count++];
}
_FORCE_INLINE_ Element* add_alpha_element() {
if (element_count+alpha_element_count>=max_elements)
return NULL;
int idx = max_elements-alpha_element_count-1;
elements[idx]=&_elements[idx];
alpha_element_count++;
return elements[idx];
}
void init() {
element_count = 0;
alpha_element_count =0;
elements=memnew_arr(Element*,max_elements);
_elements=memnew_arr(Element,max_elements);
for (int i=0;i<max_elements;i++)
elements[i]=&_elements[i]; // assign elements
}
RenderList() {
max_elements=DEFAULT_MAX_ELEMENTS;
}
~RenderList() {
memdelete_arr(elements);
memdelete_arr(_elements);
}
};
LightInstance *directional_light;
LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
RenderList render_list;
_FORCE_INLINE_ void _set_cull(bool p_front,bool p_reverse_cull);
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material* p_material,bool p_alpha_pass);
_FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection);
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e,const Transform& p_view_transform);
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
_FORCE_INLINE_ void _add_geometry( RasterizerStorageGLES3::Geometry* p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner,int p_material,bool p_shadow);
void _draw_skybox(RasterizerStorageGLES3::SkyBox *p_skybox, const CameraMatrix& p_projection, const Transform& p_transform, bool p_vflip, float p_scale);
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform& p_cam_transform);
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transformm, bool p_use_shadows);
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix& p_camera_projection, RID p_shadow_atlas);
void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform& p_camera_inverse_transform, const CameraMatrix& p_camera_projection, RID p_reflection_atlas, Environment *p_env);
void _copy_screen();
void _copy_to_front_buffer(Environment *env);
void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug
void _fill_render_list(InstanceBase** p_cull_result,int p_cull_count,bool p_shadow);
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
void _post_process(Environment *env, const CameraMatrix &p_cam_projection);
virtual void render_scene(const Transform& p_cam_transform,const CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_reflection_probe_cull_result,int p_reflection_probe_cull_count,RID p_environment,RID p_shadow_atlas,RID p_reflection_atlas,RID p_reflection_probe,int p_reflection_probe_pass);
virtual void render_shadow(RID p_light,RID p_shadow_atlas,int p_pass,InstanceBase** p_cull_result,int p_cull_count);
virtual bool free(RID p_rid);
void _generate_brdf();
virtual void set_scene_pass(uint64_t p_pass);
void iteration();
void initialize();
void finalize();
RasterizerSceneGLES3();
};
#endif // RASTERIZERSCENEGLES3_H

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,738 @@
#include "shader_compiler_gles3.h"
#include "os/os.h"
#define SL ShaderLanguage
static String _mktab(int p_level) {
String tb;
for(int i=0;i<p_level;i++) {
tb+="\t";
}
return tb;
}
static String _typestr(SL::DataType p_type) {
return ShaderLanguage::get_datatype_name(p_type);
}
static int _get_datatype_size(SL::DataType p_type) {
switch(p_type) {
case SL::TYPE_VOID: return 0;
case SL::TYPE_BOOL: return 4;
case SL::TYPE_BVEC2: return 8;
case SL::TYPE_BVEC3: return 16;
case SL::TYPE_BVEC4: return 16;
case SL::TYPE_INT: return 4;
case SL::TYPE_IVEC2: return 8;
case SL::TYPE_IVEC3: return 16;
case SL::TYPE_IVEC4: return 16;
case SL::TYPE_UINT: return 4;
case SL::TYPE_UVEC2: return 8;
case SL::TYPE_UVEC3: return 16;
case SL::TYPE_UVEC4: return 16;
case SL::TYPE_FLOAT: return 4;
case SL::TYPE_VEC2: return 8;
case SL::TYPE_VEC3: return 16;
case SL::TYPE_VEC4: return 16;
case SL::TYPE_MAT2: return 16;
case SL::TYPE_MAT3: return 48;
case SL::TYPE_MAT4: return 64;
case SL::TYPE_SAMPLER2D: return 16;
case SL::TYPE_ISAMPLER2D: return 16;
case SL::TYPE_USAMPLER2D: return 16;
case SL::TYPE_SAMPLERCUBE: return 16;
}
ERR_FAIL_V(0);
}
static String _prestr(SL::DataPrecision p_pres) {
switch(p_pres) {
case SL::PRECISION_LOWP: return "lowp ";
case SL::PRECISION_MEDIUMP: return "mediump ";
case SL::PRECISION_HIGHP: return "highp ";
case SL::PRECISION_DEFAULT: return "";
}
return "";
}
static String _opstr(SL::Operator p_op) {
return SL::get_operator_text(p_op);
}
static String _mkid(const String& p_id) {
return "m_"+p_id;
}
static String f2sp0(float p_float) {
if (int(p_float)==p_float)
return itos(p_float)+".0";
else
return rtoss(p_float);
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value>& p_values) {
switch(p_type) {
case SL::TYPE_BOOL: return p_values[0].boolean?"true":"false";
case SL::TYPE_BVEC2:
case SL::TYPE_BVEC3:
case SL::TYPE_BVEC4: {
String text="bvec"+itos(p_type-SL::TYPE_BOOL+1)+"(";
for(int i=0;i<p_values.size();i++) {
if (i>0)
text+=",";
text+=p_values[i].boolean?"true":"false";
}
text+=")";
return text;
}
case SL::TYPE_INT: return itos(p_values[0].sint);
case SL::TYPE_IVEC2:
case SL::TYPE_IVEC3:
case SL::TYPE_IVEC4: {
String text="ivec"+itos(p_type-SL::TYPE_INT+1)+"(";
for(int i=0;i<p_values.size();i++) {
if (i>0)
text+=",";
text+=itos(p_values[i].sint);
}
text+=")";
return text;
} break;
case SL::TYPE_UINT: return itos(p_values[0].uint)+"u";
case SL::TYPE_UVEC2:
case SL::TYPE_UVEC3:
case SL::TYPE_UVEC4: {
String text="uvec"+itos(p_type-SL::TYPE_UINT+1)+"(";
for(int i=0;i<p_values.size();i++) {
if (i>0)
text+=",";
text+=itos(p_values[i].uint)+"u";
}
text+=")";
return text;
} break;
case SL::TYPE_FLOAT: return f2sp0(p_values[0].real)+"f";
case SL::TYPE_VEC2:
case SL::TYPE_VEC3:
case SL::TYPE_VEC4: {
String text="vec"+itos(p_type-SL::TYPE_FLOAT+1)+"(";
for(int i=0;i<p_values.size();i++) {
if (i>0)
text+=",";
text+=f2sp0(p_values[i].real);
}
text+=")";
return text;
} break;
default: ERR_FAIL_V(String());
}
}
void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode* p_node, const StringName& p_for_func, const Map<StringName,String>& p_func_code, String& r_to_add, Set<StringName> &added) {
int fidx=-1;
for(int i=0;i<p_node->functions.size();i++) {
if (p_node->functions[i].name==p_for_func) {
fidx=i;
break;
}
}
ERR_FAIL_COND(fidx==-1);
for (Set<StringName>::Element *E=p_node->functions[fidx].uses_function.front();E;E=E->next()) {
if (added.has(E->get())) {
continue; //was added already
}
_dump_function_deps(p_node,E->get(),p_func_code,r_to_add,added);
SL::FunctionNode *fnode=NULL;
for(int i=0;i<p_node->functions.size();i++) {
if (p_node->functions[i].name==E->get()) {
fnode=p_node->functions[i].function;
break;
}
}
ERR_FAIL_COND(!fnode);
r_to_add+="\n";
String header;
header=_typestr(fnode->return_type)+" "+_mkid(fnode->name)+"(";
for(int i=0;i<fnode->arguments.size();i++) {
if (i>0)
header+=", ";
header+=_prestr(fnode->arguments[i].precision)+_typestr(fnode->arguments[i].type)+" "+_mkid(fnode->arguments[i].name);
}
header+=")\n";
r_to_add+=header;
r_to_add+=p_func_code[E->get()];
added.insert(E->get());
}
}
String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode& r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions) {
String code;
switch(p_node->type) {
case SL::Node::TYPE_SHADER: {
SL::ShaderNode *pnode=(SL::ShaderNode*)p_node;
for(int i=0;i<pnode->render_modes.size();i++) {
if (p_default_actions.render_mode_defines.has(pnode->render_modes[i]) && !used_rmode_defines.has(pnode->render_modes[i])) {
r_gen_code.defines.push_back(p_default_actions.render_mode_defines[pnode->render_modes[i]].utf8());
used_rmode_defines.insert(pnode->render_modes[i]);
}
if (p_actions.render_mode_flags.has(pnode->render_modes[i])) {
*p_actions.render_mode_flags[pnode->render_modes[i]]=true;
}
if (p_actions.render_mode_values.has(pnode->render_modes[i])) {
Pair<int*,int> &p = p_actions.render_mode_values[pnode->render_modes[i]];
*p.first=p.second;
}
}
int max_texture_uniforms=0;
int max_uniforms=0;
for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
if (SL::is_sampler_type(E->get().type))
max_texture_uniforms++;
else
max_uniforms++;
}
r_gen_code.texture_uniforms.resize(max_texture_uniforms);
r_gen_code.texture_hints.resize(max_texture_uniforms);
Vector<int> uniform_sizes;
Vector<int> uniform_alignments;
Vector<StringName> uniform_defines;
uniform_sizes.resize(max_uniforms);
uniform_alignments.resize(max_uniforms);
uniform_defines.resize(max_uniforms);
for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
String ucode;
if (SL::is_sampler_type(E->get().type)) {
ucode="uniform ";
}
ucode+=_prestr(E->get().precission);
ucode+=_typestr(E->get().type);
ucode+=" "+_mkid(E->key());
ucode+=";\n";
if (SL::is_sampler_type(E->get().type)) {
r_gen_code.vertex_global+=ucode;
r_gen_code.fragment_global+=ucode;
r_gen_code.texture_uniforms[E->get().texture_order]=_mkid(E->key());
r_gen_code.texture_hints[E->get().texture_order]=E->get().hint;
} else {
if (r_gen_code.uniforms.empty()) {
r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii());
}
uniform_defines[E->get().order]=ucode;
uniform_sizes[E->get().order]=_get_datatype_size(E->get().type);
uniform_alignments[E->get().order]=MIN(16,_get_datatype_size(E->get().type));
}
p_actions.uniforms->insert(E->key(),E->get());
}
for(int i=0;i<max_uniforms;i++) {
r_gen_code.uniforms+=uniform_defines[i];
}
// add up
for(int i=0;i<uniform_sizes.size();i++) {
if (i>0) {
int align = uniform_sizes[i-1] % uniform_alignments[i];
if (align!=0) {
uniform_sizes[i-1]+=uniform_alignments[i]-align;
}
uniform_sizes[i]=uniform_sizes[i]+uniform_sizes[i-1];
}
}
//offset
r_gen_code.uniform_offsets.resize(uniform_sizes.size());
for(int i=0;i<uniform_sizes.size();i++) {
if (i>0)
r_gen_code.uniform_offsets[i]=uniform_sizes[i-1];
else
r_gen_code.uniform_offsets[i]=0;
}
/*
for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
if (SL::is_sampler_type(E->get().type)) {
continue;
}
print_line("u - "+String(E->key())+" offset: "+itos(r_gen_code.uniform_offsets[E->get().order]));
}
*/
if (uniform_sizes.size()) {
r_gen_code.uniform_total_size=uniform_sizes[ uniform_sizes.size() -1 ];
} else {
r_gen_code.uniform_total_size=0;
}
for(Map<StringName,SL::ShaderNode::Varying>::Element *E=pnode->varyings.front();E;E=E->next()) {
String vcode;
vcode+=_prestr(E->get().precission);
vcode+=_typestr(E->get().type);
vcode+=" "+String(E->key());
vcode+=";\n";
r_gen_code.vertex_global+="out "+vcode;
r_gen_code.fragment_global+="in "+vcode;
}
Map<StringName,String> function_code;
//code for functions
for(int i=0;i<pnode->functions.size();i++) {
SL::FunctionNode *fnode=pnode->functions[i].function;
function_code[fnode->name]=_dump_node_code(fnode->body,p_level+1,r_gen_code,p_actions,p_default_actions);
}
//place functions in actual code
Set<StringName> added_vtx;
Set<StringName> added_fragment; //share for light
for(int i=0;i<pnode->functions.size();i++) {
SL::FunctionNode *fnode=pnode->functions[i].function;
current_func_name=fnode->name;
if (fnode->name=="vertex") {
_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.vertex_global,added_vtx);
r_gen_code.vertex=function_code["vertex"];
}
if (fnode->name=="fragment") {
_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.fragment_global,added_fragment);
r_gen_code.fragment=function_code["fragment"];
}
if (fnode->name=="light") {
_dump_function_deps(pnode,fnode->name,function_code,r_gen_code.fragment_global,added_fragment);
r_gen_code.light=function_code["light"];
}
}
//code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_FUNCTION: {
} break;
case SL::Node::TYPE_BLOCK: {
SL::BlockNode *bnode=(SL::BlockNode*)p_node;
//variables
code+=_mktab(p_level-1)+"{\n";
for(Map<StringName,SL::BlockNode::Variable>::Element *E=bnode->variables.front();E;E=E->next()) {
code+=_mktab(p_level)+_prestr(E->get().precision)+_typestr(E->get().type)+" "+_mkid(E->key())+";\n";
}
for(int i=0;i<bnode->statements.size();i++) {
String scode = _dump_node_code(bnode->statements[i],p_level,r_gen_code,p_actions,p_default_actions);
if (bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type==SL::Node::TYPE_CONTROL_FLOW) {
code+=scode; //use directly
} else {
code+=_mktab(p_level)+scode+";\n";
}
}
code+=_mktab(p_level-1)+"}\n";
} break;
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode=(SL::VariableNode*)p_node;
if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
String define = p_default_actions.usage_defines[vnode->name];
if (define.begins_with("@")) {
define = p_default_actions.usage_defines[define.substr(1,define.length())];
}
r_gen_code.defines.push_back(define.utf8());
used_name_defines.insert(vnode->name);
}
if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) {
*p_actions.usage_flag_pointers[vnode->name]=true;
used_flag_pointers.insert(vnode->name);
}
if (p_default_actions.renames.has(vnode->name))
code=p_default_actions.renames[vnode->name];
else
code=_mkid(vnode->name);
if (vnode->name==time_name) {
if (current_func_name==vertex_name) {
r_gen_code.uses_vertex_time=true;
}
if (current_func_name==fragment_name) {
r_gen_code.uses_fragment_time=true;
}
}
} break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
return get_constant_text(cnode->datatype,cnode->values);
} break;
case SL::Node::TYPE_OPERATOR: {
SL::OperatorNode *onode=(SL::OperatorNode*)p_node;
switch(onode->op) {
case SL::OP_ASSIGN:
case SL::OP_ASSIGN_ADD:
case SL::OP_ASSIGN_SUB:
case SL::OP_ASSIGN_MUL:
case SL::OP_ASSIGN_DIV:
case SL::OP_ASSIGN_SHIFT_LEFT:
case SL::OP_ASSIGN_SHIFT_RIGHT:
case SL::OP_ASSIGN_MOD:
case SL::OP_ASSIGN_BIT_AND:
case SL::OP_ASSIGN_BIT_OR:
case SL::OP_ASSIGN_BIT_XOR:
code=_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op)+_dump_node_code(onode->arguments[1],p_level,r_gen_code,p_actions,p_default_actions);
break;
case SL::OP_BIT_INVERT:
case SL::OP_NEGATE:
case SL::OP_NOT:
case SL::OP_DECREMENT:
case SL::OP_INCREMENT:
code=_opstr(onode->op)+_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions);
break;
case SL::OP_POST_DECREMENT:
case SL::OP_POST_INCREMENT:
code=_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op);
break;
case SL::OP_CALL:
case SL::OP_CONSTRUCT: {
ERR_FAIL_COND_V(onode->arguments[0]->type!=SL::Node::TYPE_VARIABLE,String());
SL::VariableNode *vnode=(SL::VariableNode*)onode->arguments[0];
if (onode->op==SL::OP_CONSTRUCT) {
code+=String(vnode->name);
} else {
if (internal_functions.has(vnode->name)) {
code+=vnode->name;
} else if (p_default_actions.renames.has(vnode->name)) {
code+=p_default_actions.renames[vnode->name];
} else {
code+=_mkid(vnode->name);
}
}
code+="(";
for(int i=1;i<onode->arguments.size();i++) {
if (i>1)
code+=", ";
code+=_dump_node_code(onode->arguments[i],p_level,r_gen_code,p_actions,p_default_actions);
}
code+=")";
} break;
default: {
code="("+_dump_node_code(onode->arguments[0],p_level,r_gen_code,p_actions,p_default_actions)+_opstr(onode->op)+_dump_node_code(onode->arguments[1],p_level,r_gen_code,p_actions,p_default_actions)+")";
break;
}
}
} break;
case SL::Node::TYPE_CONTROL_FLOW: {
SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
if (cfnode->flow_op==SL::FLOW_OP_IF) {
code+=_mktab(p_level)+"if ("+_dump_node_code(cfnode->expressions[0],p_level,r_gen_code,p_actions,p_default_actions)+")\n";
code+=_dump_node_code(cfnode->blocks[0],p_level+1,r_gen_code,p_actions,p_default_actions);
if (cfnode->blocks.size()==2) {
code+=_mktab(p_level)+"else\n";
code+=_dump_node_code(cfnode->blocks[1],p_level+1,r_gen_code,p_actions,p_default_actions);
}
} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
if (cfnode->blocks.size()) {
code="return "+_dump_node_code(cfnode->blocks[0],p_level,r_gen_code,p_actions,p_default_actions);
} else {
code="return";
}
}
} break;
case SL::Node::TYPE_MEMBER: {
SL::MemberNode *mnode=(SL::MemberNode*)p_node;
code=_dump_node_code(mnode->owner,p_level,r_gen_code,p_actions,p_default_actions)+"."+mnode->name;
} break;
}
return code;
}
Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String& p_code, IdentifierActions* p_actions, const String &p_path,GeneratedCode& r_gen_code) {
Error err = parser.compile(p_code,ShaderTypes::get_singleton()->get_functions(p_mode),ShaderTypes::get_singleton()->get_modes(p_mode));
if (err!=OK) {
#if 1
Vector<String> shader = p_code.split("\n");
for(int i=0;i<shader.size();i++) {
print_line(itos(i)+" "+shader[i]);
}
#endif
_err_print_error(NULL,p_path.utf8().get_data(),parser.get_error_line(),parser.get_error_text().utf8().get_data(),ERR_HANDLER_SHADER);
return err;
}
r_gen_code.defines.clear();
r_gen_code.vertex=String();
r_gen_code.vertex_global=String();
r_gen_code.fragment=String();
r_gen_code.fragment_global=String();
r_gen_code.light=String();
r_gen_code.uses_fragment_time=false;
r_gen_code.uses_vertex_time=false;
used_name_defines.clear();
used_rmode_defines.clear();
_dump_node_code(parser.get_shader(),1,r_gen_code,*p_actions,actions[p_mode]);
return OK;
}
ShaderCompilerGLES3::ShaderCompilerGLES3() {
/** CANVAS ITEM SHADER **/
actions[VS::SHADER_CANVAS_ITEM].renames["SRC_VERTEX"]="vertex";
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"]="outvec.xy";
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX_COLOR"]="vertex_color";
actions[VS::SHADER_CANVAS_ITEM].renames["UV"]="uv_interp";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"]="gl_PointSize";
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"]="modelview_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"]="projection_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"]=="extra_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["TIME"]="time";
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"]="color";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"]="normal";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"]="normal_map";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"]="normal_depth";
actions[VS::SHADER_CANVAS_ITEM].renames["UV"]="uv_interp";
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"]="color";
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"]="color_texture";
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"]="color_texpixel_size";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"]="screen_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"]="screen_texture";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_COORD"]="gl_PointCoord";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_VEC"]="light_vec";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_HEIGHT"]="light_height";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_COLOR"]="light_color";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"]="light_uv";
//actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_SHADOW_COLOR"]="light_shadow_color";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"]="light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"]="shadow_color";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"]="#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"]="#define SCREEN_TEXTURE_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_UV"]="#define SCREEN_UV_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"]="#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"]="#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"]="#define SHADOW_COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"]="world_transform";
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"]="camera_inverse_matrix";
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"]="projection_matrix";
actions[VS::SHADER_SPATIAL].renames["VERTEX"]="vertex.xyz";
actions[VS::SHADER_SPATIAL].renames["NORMAL"]="normal";
actions[VS::SHADER_SPATIAL].renames["TANGENT"]="tangent";
actions[VS::SHADER_SPATIAL].renames["BINORMAL"]="binormal";
actions[VS::SHADER_SPATIAL].renames["UV"]="uv_interp";
actions[VS::SHADER_SPATIAL].renames["UV2"]="uv2_interp";
actions[VS::SHADER_SPATIAL].renames["COLOR"]="color_interp";
actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"]="gl_PointSize";
//actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"]=ShaderLanguage::TYPE_INT;
//builtins
actions[VS::SHADER_SPATIAL].renames["TIME"]="time";
//actions[VS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["FRAGCOORD"]="gl_FragCoord";
actions[VS::SHADER_SPATIAL].renames["FRONT_FACING"]="gl_FrotFacing";
actions[VS::SHADER_SPATIAL].renames["NORMALMAP"]="normalmap";
actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"]="normaldepth";
actions[VS::SHADER_SPATIAL].renames["ALBEDO"]="albedo";
actions[VS::SHADER_SPATIAL].renames["ALPHA"]="alpha";
actions[VS::SHADER_SPATIAL].renames["SPECULAR"]="specular";
actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"]="roughness";
actions[VS::SHADER_SPATIAL].renames["RIM"]="rim";
actions[VS::SHADER_SPATIAL].renames["RIM_TINT"]="rim_tint";
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT"]="clearcoat";
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"]="clearcoat_gloss";
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"]="anisotropy";
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"]="anisotropy_flow";
actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"]="sss_spread";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"]="sss_strength";
actions[VS::SHADER_SPATIAL].renames["AO"]="ao";
actions[VS::SHADER_SPATIAL].renames["EMISSION"]="emission";
actions[VS::SHADER_SPATIAL].renames["DISCARD"]="_discard";
// actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"]="gl_PointCoord";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"]="#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"]="@TANGENT";
actions[VS::SHADER_SPATIAL].usage_defines["RIM"]="#define LIGHT_USE_RIM\n";
actions[VS::SHADER_SPATIAL].usage_defines["RIM_TINT"]="@RIM";
actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT"]="#define LIGHT_USE_CLEARCOAT\n";
actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"]="@CLEARCOAT";
actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY"]="#define LIGHT_USE_ANISOTROPY\n";
actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"]="@ANISOTROPY";
actions[VS::SHADER_SPATIAL].usage_defines["AO"]="#define ENABLE_AO\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV"]="#define ENABLE_UV_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV2"]="#define ENABLE_UV2_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"]="#define ENABLE_NORMALMAP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"]="@NORMALMAP";
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"]="#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"]="#define ENABLE_SSS_MOTION\n";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"]="sss_strength";
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
/* PARTICLES SHADER */
actions[VS::SHADER_PARTICLES].renames["COLOR"]="color";
actions[VS::SHADER_PARTICLES].renames["VELOCITY"]="out_velocity_active.xyz";
actions[VS::SHADER_PARTICLES].renames["MASS"]="mass";
actions[VS::SHADER_PARTICLES].renames["ACTIVE"]="active";
actions[VS::SHADER_PARTICLES].renames["RESTART"]="restart";
actions[VS::SHADER_PARTICLES].renames["CUSTOM"]="out_custom";
actions[VS::SHADER_PARTICLES].renames["TRANSFORM"]="xform";
actions[VS::SHADER_PARTICLES].renames["TIME"]="time";
actions[VS::SHADER_PARTICLES].renames["LIFETIME"]="lifetime";
actions[VS::SHADER_PARTICLES].renames["DELTA"]="delta";
actions[VS::SHADER_PARTICLES].renames["SEED"]="seed";
actions[VS::SHADER_PARTICLES].renames["ORIGIN"]="origin";
actions[VS::SHADER_PARTICLES].renames["INDEX"]="index";
actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"]="#define DISABLE_FORCE\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"]="#define DISABLE_VELOCITY\n";
vertex_name="vertex";
fragment_name="fragment";
time_name="TIME";
List<String> func_list;
ShaderLanguage::get_builtin_funcs(&func_list);
for (List<String>::Element *E=func_list.front();E;E=E->next()) {
internal_functions.insert(E->get());
}
}

View file

@ -0,0 +1,77 @@
#ifndef SHADERCOMPILERGLES3_H
#define SHADERCOMPILERGLES3_H
#include "servers/visual/shader_language.h"
#include "servers/visual/shader_types.h"
#include "servers/visual_server.h"
#include "pair.h"
class ShaderCompilerGLES3 {
public:
struct IdentifierActions {
Map<StringName,Pair<int*,int> > render_mode_values;
Map<StringName,bool*> render_mode_flags;
Map<StringName,bool*> usage_flag_pointers;
Map<StringName,ShaderLanguage::ShaderNode::Uniform> *uniforms;
};
struct GeneratedCode {
Vector<CharString> defines;
Vector<StringName> texture_uniforms;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
Vector<uint32_t> uniform_offsets;
uint32_t uniform_total_size;
String uniforms;
String vertex_global;
String vertex;
String fragment_global;
String fragment;
String light;
bool uses_fragment_time;
bool uses_vertex_time;
};
private:
ShaderLanguage parser;
struct DefaultIdentifierActions {
Map<StringName,String> renames;
Map<StringName,String> render_mode_defines;
Map<StringName,String> usage_defines;
};
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName& p_for_func, const Map<StringName, String> &p_func_code, String& r_to_add,Set<StringName> &added);
String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions& p_actions, const DefaultIdentifierActions& p_default_actions);
StringName current_func_name;
StringName vertex_name;
StringName fragment_name;
StringName time_name;
Set<StringName> used_name_defines;
Set<StringName> used_flag_pointers;
Set<StringName> used_rmode_defines;
Set<StringName> internal_functions;
DefaultIdentifierActions actions[VS::SHADER_MAX];
public:
Error compile(VS::ShaderMode p_mode, const String& p_code, IdentifierActions* p_actions, const String& p_path, GeneratedCode& r_gen_code);
ShaderCompilerGLES3();
};
#endif // SHADERCOMPILERGLES3_H

View file

@ -0,0 +1,839 @@
/*************************************************************************/
/* 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 GLES_OVER_GL
strings.push_back("#version 330\n");
#else
strings.push_back("#version 300 es\n");
#endif
int define_line_ofs=1;
for(int i=0;i<custom_defines.size();i++) {
strings.push_back(custom_defines[i].get_data());
define_line_ofs++;
}
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;
CharString material_string;
//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].get_data());
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) {
material_string=cc->uniforms.ascii();
strings.push_back(material_string.get_data());
}
strings.push_back(vertex_code2.get_data());
if (cc) {
code_string=cc->vertex.ascii();
strings.push_back(code_string.get_data());
}
strings.push_back(vertex_code3.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 highp float;\n");
strings.push_back("precision highp 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) {
material_string=cc->uniforms.ascii();
strings.push_back(material_string.get_data());
}
strings.push_back(fragment_code2.get_data());
if (cc) {
code_string=cc->fragment.ascii();
strings.push_back(code_string.get_data());
}
strings.push_back(fragment_code3.get_data());
if (cc) {
code_string2=cc->light.ascii();
strings.push_back(code_string2.get_data());
}
strings.push_back(fragment_code4.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 );
}
//if feedback exists, set it up
if (feedback_count) {
Vector<const char*> feedback;
for(int i=0;i<feedback_count;i++) {
if (feedbacks[i].conditional==-1 || (1<<feedbacks[i].conditional)&conditional_version.version) {
//conditional for this feedback is enabled
print_line("tf varying: "+itos(feedback.size())+" "+String(feedbacks[i].name));
feedback.push_back(feedbacks[i].name);
}
}
if (feedback.size()) {
glTransformFeedbackVaryings(v.id,feedback.size(),feedback.ptr(),GL_INTERLEAVED_ATTRIBS );
}
}
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.texture_uniform_locations.resize(cc->texture_uniforms.size());
for(int i=0;i<cc->texture_uniforms.size();i++) {
v.texture_uniform_locations[i]=glGetUniformLocation(v.id,String(cc->texture_uniforms[i]).ascii().get_data());
glUniform1i(v.texture_uniform_locations[i],i+base_material_tex_index);
}
}
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 Feedback* p_feedback, int p_feedback_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;
feedbacks=p_feedback;
feedback_count=p_feedback_count;
//split vertex and shader code (thank you, retarded shader compiler programmers from you know what company).
{
String globals_tag="\nVERTEX_SHADER_GLOBALS";
String material_tag="\nMATERIAL_UNIFORMS";
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(material_tag);
if (cpos==-1) {
vertex_code1=code.ascii();
} else {
vertex_code1=code.substr(0,cpos).ascii();
String code2 = code.substr(cpos+material_tag.length(),code.length());
cpos = code2.find(code_tag);
if (cpos==-1) {
vertex_code2=code2.ascii();
} else {
vertex_code2=code2.substr(0,cpos).ascii();
vertex_code3 = code2.substr(cpos+code_tag.length(),code2.length()).ascii();
}
}
}
}
{
String globals_tag="\nFRAGMENT_SHADER_GLOBALS";
String material_tag="\nMATERIAL_UNIFORMS";
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();
//print_line("CODE0:\n"+String(fragment_code0.get_data()));
code = code.substr(cpos+globals_tag.length(),code.length());
cpos = code.find(material_tag);
if (cpos==-1) {
fragment_code1=code.ascii();
} else {
fragment_code1=code.substr(0,cpos).ascii();
//print_line("CODE1:\n"+String(fragment_code1.get_data()));
String code2 = code.substr(cpos+material_tag.length(),code.length());
cpos = code2.find(code_tag);
if (cpos==-1) {
fragment_code2=code2.ascii();
} else {
fragment_code2=code2.substr(0,cpos).ascii();
//print_line("CODE2:\n"+String(fragment_code2.get_data()));
String code3 = code2.substr(cpos+code_tag.length(),code2.length());
cpos = code3.find(light_code_tag);
if (cpos==-1) {
fragment_code3=code3.ascii();
} else {
fragment_code3=code3.substr(0,cpos).ascii();
// print_line("CODE3:\n"+String(fragment_code3.get_data()));
fragment_code4 = code3.substr(cpos+light_code_tag.length(),code3.length()).ascii();
//print_line("CODE4:\n"+String(fragment_code4.get_data()));
}
}
}
}
}
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&max_image_units);
}
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 String &p_uniforms, const Vector<StringName> &p_texture_uniforms, const Vector<CharString> &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->texture_uniforms=p_texture_uniforms;
cc->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);
}
void ShaderGLES3::set_base_material_tex_index(int p_idx) {
base_material_tex_index=p_idx;
}
ShaderGLES3::ShaderGLES3() {
version=NULL;
last_custom_code=1;
uniforms_dirty = true;
base_material_tex_index=0;
}
ShaderGLES3::~ShaderGLES3() {
finish();
}

View file

@ -0,0 +1,399 @@
/*************************************************************************/
/* 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 <stdio.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;
};
struct Feedback {
const char *name;
int conditional;
};
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 feedback_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;
String uniforms;
uint32_t version;
Vector<StringName> texture_uniforms;
Vector<CharString> custom_defines;
};
struct Version {
GLuint id;
GLuint vert_id;
GLuint frag_id;
GLint *uniform_location;
Vector<GLint> texture_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 Feedback *feedbacks;
const char* vertex_code;
const char* fragment_code;
CharString fragment_code0;
CharString fragment_code1;
CharString fragment_code2;
CharString fragment_code3;
CharString fragment_code4;
CharString vertex_code0;
CharString vertex_code1;
CharString vertex_code2;
CharString vertex_code3;
Vector<CharString> custom_defines;
int base_material_tex_index;
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 Feedback* p_feedback, int p_feedback_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 String& p_uniforms,const Vector<StringName>& p_texture_uniforms,const Vector<CharString> &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_texture_uniform(int p_idx, const Variant& p_value) {
ERR_FAIL_COND(!version);
ERR_FAIL_INDEX(p_idx,version->texture_uniform_locations.size());
_set_uniform_variant( version->texture_uniform_locations[p_idx], p_value );
}
_FORCE_INLINE_ GLint get_texture_uniform_location(int p_idx) {
ERR_FAIL_COND_V(!version,-1);
ERR_FAIL_INDEX_V(p_idx,version->texture_uniform_locations.size(),-1);
return version->texture_uniform_locations[p_idx];
}
virtual void init()=0;
void finish();
void set_base_material_tex_index(int p_idx);
void add_custom_define(const String& p_define) {
custom_defines.push_back(p_define.utf8());
}
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,22 @@
Import('env')
if env['BUILDERS'].has_key('GLES3_GLSL'):
env.GLES3_GLSL('copy.glsl');
env.GLES3_GLSL('resolve.glsl');
env.GLES3_GLSL('canvas.glsl');
env.GLES3_GLSL('canvas_shadow.glsl');
env.GLES3_GLSL('scene.glsl');
env.GLES3_GLSL('cubemap_filter.glsl');
env.GLES3_GLSL('cube_to_dp.glsl');
env.GLES3_GLSL('blend_shape.glsl');
env.GLES3_GLSL('screen_space_reflection.glsl');
env.GLES3_GLSL('effect_blur.glsl');
env.GLES3_GLSL('subsurf_scattering.glsl');
env.GLES3_GLSL('ssao.glsl');
env.GLES3_GLSL('ssao_minify.glsl');
env.GLES3_GLSL('ssao_blur.glsl');
env.GLES3_GLSL('exposure.glsl');
env.GLES3_GLSL('tonemap.glsl');
env.GLES3_GLSL('particles.glsl');

View file

@ -0,0 +1,197 @@
[vertex]
/*
from VisualServer:
ARRAY_VERTEX=0,
ARRAY_NORMAL=1,
ARRAY_TANGENT=2,
ARRAY_COLOR=3,
ARRAY_TEX_UV=4,
ARRAY_TEX_UV2=5,
ARRAY_BONES=6,
ARRAY_WEIGHTS=7,
ARRAY_INDEX=8,
*/
#ifdef USE_2D_VERTEX
#define VFORMAT vec2
#else
#define VFORMAT vec3
#endif
/* INPUT ATTRIBS */
layout(location=0) in highp VFORMAT vertex_attrib;
layout(location=1) in vec3 normal_attrib;
#ifdef ENABLE_TANGENT
layout(location=2) in vec4 tangent_attrib;
#endif
#ifdef ENABLE_COLOR
layout(location=3) in vec4 color_attrib;
#endif
#ifdef ENABLE_UV
layout(location=4) in vec2 uv_attrib;
#endif
#ifdef ENABLE_UV2
layout(location=5) in vec2 uv2_attrib;
#endif
#ifdef ENABLE_SKELETON
layout(location=6) in ivec4 bone_attrib;
layout(location=7) in vec4 weight_attrib;
#endif
/* BLEND ATTRIBS */
#ifdef ENABLE_BLEND
layout(location=8) in highp VFORMAT vertex_attrib_blend;
layout(location=9) in vec3 normal_attrib_blend;
#ifdef ENABLE_TANGENT
layout(location=10) in vec4 tangent_attrib_blend;
#endif
#ifdef ENABLE_COLOR
layout(location=11) in vec4 color_attrib_blend;
#endif
#ifdef ENABLE_UV
layout(location=12) in vec2 uv_attrib_blend;
#endif
#ifdef ENABLE_UV2
layout(location=13) in vec2 uv2_attrib_blend;
#endif
#ifdef ENABLE_SKELETON
layout(location=14) in ivec4 bone_attrib_blend;
layout(location=15) in vec4 weight_attrib_blend;
#endif
#endif
/* OUTPUTS */
out VFORMAT vertex_out; //tfb:
#ifdef ENABLE_NORMAL
out vec3 normal_out; //tfb:ENABLE_NORMAL
#endif
#ifdef ENABLE_TANGENT
out vec4 tangent_out; //tfb:ENABLE_TANGENT
#endif
#ifdef ENABLE_COLOR
out vec4 color_out; //tfb:ENABLE_COLOR
#endif
#ifdef ENABLE_UV
out vec2 uv_out; //tfb:ENABLE_UV
#endif
#ifdef ENABLE_UV2
out vec2 uv2_out; //tfb:ENABLE_UV2
#endif
#ifdef ENABLE_SKELETON
out ivec4 bone_out; //tfb:ENABLE_SKELETON
out vec4 weight_out; //tfb:ENABLE_SKELETON
#endif
uniform float blend_amount;
void main() {
#ifdef ENABLE_BLEND
vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
#ifdef ENABLE_NORMAL
normal_out = normal_attrib_blend + normal_attrib * blend_amount;
#endif
#ifdef ENABLE_TANGENT
tangent_out.xyz = tangent_attrib_blend.xyz + tangent_attrib.xyz * blend_amount;
tangent_out.w = tangent_attrib_blend.w; //just copy, no point in blending his
#endif
#ifdef ENABLE_COLOR
color_out = color_attrib_blend + color_attrib * blend_amount;
#endif
#ifdef ENABLE_UV
uv_out = uv_attrib_blend + uv_attrib * blend_amount;
#endif
#ifdef ENABLE_UV2
uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount;
#endif
#ifdef ENABLE_SKELETON
bone_out = bone_attrib_blend;
weight_out = weight_attrib_blend + weight_attrib * blend_amount;
#endif
#else //ENABLE_BLEND
vertex_out = vertex_attrib * blend_amount;
#ifdef ENABLE_NORMAL
normal_out = normal_attrib * blend_amount;
#endif
#ifdef ENABLE_TANGENT
tangent_out.xyz = tangent_attrib.xyz * blend_amount;
tangent_out.w = tangent_attrib.w; //just copy, no point in blending his
#endif
#ifdef ENABLE_COLOR
color_out = color_attrib * blend_amount;
#endif
#ifdef ENABLE_UV
uv_out = uv_attrib * blend_amount;
#endif
#ifdef ENABLE_UV2
uv2_out = uv2_attrib * blend_amount;
#endif
#ifdef ENABLE_SKELETON
bone_out = bone_attrib;
weight_out = weight_attrib * blend_amount;
#endif
#endif
gl_Position = vec4(0.0);
}
[fragment]
void main() {
}

View file

@ -0,0 +1,456 @@
[vertex]
layout(location=0) in highp vec2 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;
highp vec4 time;
};
uniform highp mat4 modelview_matrix;
uniform highp mat4 extra_matrix;
out mediump vec2 uv_interp;
out mediump vec4 color_interp;
#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
#if defined(USE_MATERIAL)
layout(std140) uniform UniformData { //ubo:2
MATERIAL_UNIFORMS
};
#endif
void main() {
vec4 vertex_color = color_attrib;
#ifdef USE_TEXTURE_RECT
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
highp vec4 outvec = vec4(dst_rect.xy + dst_rect.zw * mix(vertex,vec2(1.0,1.0)-vertex,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0);
#else
uv_interp = uv_attrib;
highp vec4 outvec = vec4(vertex,0.0,1.0);
#endif
{
vec2 src_vtx=outvec.xy;
VERTEX_SHADER_CODE
}
#if !defined(SKIP_TRANSFORM_USED)
outvec = extra_matrix * outvec;
outvec = modelview_matrix * outvec;
#endif
color_interp = vertex_color;
#ifdef USE_PIXEL_SNAP
outvec.xy=floor(outvec+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
uniform highp vec2 color_texpixel_size;
in mediump vec2 uv_interp;
in mediump vec4 color_interp;
#if defined(SCREEN_TEXTURE_USED)
uniform sampler2D screen_texture; // texunit:-3
#endif
layout(std140) uniform CanvasItemData {
highp mat4 projection_matrix;
highp vec4 time;
};
#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;
#if defined(USE_MATERIAL)
layout(std140) uniform UniformData {
MATERIAL_UNIFORMS
};
#endif
void main() {
vec4 color = color_interp;
#if defined(NORMAL_USED)
vec3 normal = vec3(0.0,0.0,1.0);
#endif
#if !defined(COLOR_USED)
//default behavior, texture by color
#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
#endif
#if defined(ENABLE_SCREEN_UV)
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
#endif
{
float normal_depth=1.0;
#if defined(NORMALMAP_USED)
vec3 normal_map=vec3(0.0,0.0,1.0);
#endif
FRAGMENT_SHADER_CODE
#if defined(NORMALMAP_USED)
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(SHADOW_COLOR_USED)
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(SHADOW_COLOR_USED)
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,105 @@
[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;
#endif
layout(location=5) in vec2 uv2_in;
#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; //texunit:0
#else
in vec2 uv_interp;
uniform sampler2D source; //texunit:0
#endif
float sRGB_gamma_correct(float c){
float a = 0.055;
if(c < 0.0031308)
return 12.92*c;
else
return (1.0+a)*pow(c, 1.0/2.4) - a;
}
uniform float stuff;
uniform vec2 pixel_size;
in vec2 uv2_interp;
layout(location = 0) out vec4 frag_color;
void main() {
//vec4 color = color_interp;
#ifdef USE_CUBEMAP
vec4 color = texture( source_cube, normalize(cube_interp) );
#else
vec4 color = texture( source, uv_interp );
#endif
#ifdef LINEAR_TO_SRGB
//regular Linear -> SRGB conversion
vec3 a = vec3(0.055);
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
#endif
#ifdef DEBUG_GRADIENT
color.rg=uv_interp;
color.b=0.0;
#endif
#ifdef DISABLE_ALPHA
color.a=1.0;
#endif
#ifdef GAUSSIAN_HORIZONTAL
color*=0.38774;
color+=texture( source, uv_interp+vec2( 1.0, 0.0)*pixel_size )*0.24477;
color+=texture( source, uv_interp+vec2( 2.0, 0.0)*pixel_size )*0.06136;
color+=texture( source, uv_interp+vec2(-1.0, 0.0)*pixel_size )*0.24477;
color+=texture( source, uv_interp+vec2(-2.0, 0.0)*pixel_size )*0.06136;
#endif
#ifdef GAUSSIAN_VERTICAL
color*=0.38774;
color+=texture( source, uv_interp+vec2( 0.0, 1.0)*pixel_size )*0.24477;
color+=texture( source, uv_interp+vec2( 0.0, 2.0)*pixel_size )*0.06136;
color+=texture( source, uv_interp+vec2( 0.0,-1.0)*pixel_size )*0.24477;
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136;
#endif
frag_color = color;
}

View file

@ -0,0 +1,79 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
[fragment]
uniform highp samplerCube source_cube; //texunit:0
in vec2 uv_interp;
uniform bool z_flip;
uniform highp float z_far;
uniform highp float z_near;
uniform highp float bias;
void main() {
highp vec3 normal = vec3( uv_interp * 2.0 - 1.0, 0.0 );
/*
if(z_flip) {
normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y));
} else {
normal.z = -0.5 + 0.5*((normal.x * normal.x) + (normal.y * normal.y));
}
*/
//normal.z = sqrt(1.0-dot(normal.xy,normal.xy));
//normal.xy*=1.0+normal.z;
normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y));
normal = normalize(normal);
/*
normal.z=0.5;
normal=normalize(normal);
*/
if (!z_flip) {
normal.z=-normal.z;
}
//normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 ));
float depth = texture(source_cube,normal).r;
// absolute values for direction cosines, bigger value equals closer to basis axis
vec3 unorm = abs(normal);
if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) {
// x code
unorm = normal.x > 0.0 ? vec3( 1.0, 0.0, 0.0 ) : vec3( -1.0, 0.0, 0.0 ) ;
} else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) {
// y code
unorm = normal.y > 0.0 ? vec3( 0.0, 1.0, 0.0 ) : vec3( 0.0, -1.0, 0.0 ) ;
} else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) {
// z code
unorm = normal.z > 0.0 ? vec3( 0.0, 0.0, 1.0 ) : vec3( 0.0, 0.0, -1.0 ) ;
} else {
// oh-no we messed up code
// has to be
unorm = vec3( 1.0, 0.0, 0.0 );
}
float depth_fix = 1.0 / dot(normal,unorm);
depth = 2.0 * depth - 1.0;
float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near));
gl_FragDepth = (linear_depth*depth_fix+bias) / z_far;
}

View file

@ -0,0 +1,218 @@
[vertex]
layout(location=0) in highp vec2 vertex;
layout(location=4) in highp vec2 uv;
out highp vec2 uv_interp;
void main() {
uv_interp=uv;
gl_Position=vec4(vertex,0,1);
}
[fragment]
precision highp float;
precision highp int;
uniform samplerCube source_cube; //texunit:0
uniform int face_id;
uniform float roughness;
in highp vec2 uv_interp;
layout(location = 0) out vec4 frag_color;
#define M_PI 3.14159265359
vec3 texelCoordToVec(vec2 uv, int faceID)
{
mat3 faceUvVectors[6];
/*
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x
faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face
// -y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face
// +y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face
// -z
faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face
// +z
faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face
*/
// -x
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
// -y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
// +y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
// -z
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
// +z
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
return normalize(result);
}
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
{
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
// Compute distribution direction
float Phi = 2.0 * M_PI * Xi.x;
float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
// Convert to spherical direction
vec3 H;
H.x = SinTheta * cos(Phi);
H.y = SinTheta * sin(Phi);
H.z = CosTheta;
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
vec3 TangentX = normalize(cross(UpVector, N));
vec3 TangentY = cross(N, TangentX);
// Tangent to world space
return TangentX * H.x + TangentY * H.y + N * H.z;
}
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float GGX(float NdotV, float a)
{
float k = a / 2.0;
return NdotV / (NdotV * (1.0 - k) + k);
}
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float G_Smith(float a, float nDotV, float nDotL)
{
return GGX(nDotL, a * a) * GGX(nDotV, a * a);
}
float radicalInverse_VdC(uint bits) {
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
vec2 Hammersley(uint i, uint N) {
return vec2(float(i)/float(N), radicalInverse_VdC(i));
}
#ifdef LOW_QUALITY
#define SAMPLE_COUNT 64u
#else
#define SAMPLE_COUNT 512u
#endif
uniform bool z_flip;
void main() {
#ifdef USE_DUAL_PARABOLOID
vec3 N = vec3( uv_interp * 2.0 - 1.0, 0.0 );
N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y));
N = normalize(N);
if (!z_flip) {
N.y=-N.y; //y is flipped to improve blending between both sides
} else {
N.z=-N.z;
}
#else
vec2 uv = (uv_interp * 2.0) - 1.0;
vec3 N = texelCoordToVec(uv, face_id);
#endif
//vec4 color = color_interp;
#ifdef USE_DIRECT_WRITE
frag_color=vec4(texture(N,source_cube).rgb,1.0);
#else
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) {
vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX( xi, roughness, N );
vec3 V = N;
vec3 L = normalize(2.0 * dot( V, H ) * H - V);
float ndotl = clamp(dot(N, L),0.0,1.0);
if (ndotl>0.0) {
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
sum.a += ndotl;
}
}
sum /= sum.a;
frag_color = vec4(sum.rgb, 1.0);
#endif
}

View file

@ -0,0 +1,278 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
[fragment]
in vec2 uv_interp;
uniform sampler2D source_color; //texunit:0
#ifdef SSAO_MERGE
uniform sampler2D source_ssao; //texunit:1
#endif
uniform float lod;
uniform vec2 pixel_size;
layout(location = 0) out vec4 frag_color;
#ifdef SSAO_MERGE
uniform vec4 ssao_color;
#endif
#if defined (GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL)
uniform float glow_strength;
#endif
#if defined(DOF_FAR_BLUR) || defined (DOF_NEAR_BLUR)
#ifdef DOF_QUALITY_LOW
const int dof_kernel_size=5;
const int dof_kernel_from=2;
const float dof_kernel[5] = float[] (0.153388,0.221461,0.250301,0.221461,0.153388);
#endif
#ifdef DOF_QUALITY_MEDIUM
const int dof_kernel_size=11;
const int dof_kernel_from=5;
const float dof_kernel[11] = float[] (0.055037,0.072806,0.090506,0.105726,0.116061,0.119726,0.116061,0.105726,0.090506,0.072806,0.055037);
#endif
#ifdef DOF_QUALITY_HIGH
const int dof_kernel_size=21;
const int dof_kernel_from=10;
const float dof_kernel[21] = float[] (0.028174,0.032676,0.037311,0.041944,0.046421,0.050582,0.054261,0.057307,0.059587,0.060998,0.061476,0.060998,0.059587,0.057307,0.054261,0.050582,0.046421,0.041944,0.037311,0.032676,0.028174);
#endif
uniform sampler2D dof_source_depth; //texunit:1
uniform float dof_begin;
uniform float dof_end;
uniform vec2 dof_dir;
uniform float dof_radius;
#ifdef DOF_NEAR_BLUR_MERGE
uniform sampler2D source_dof_original; //texunit:2
#endif
#endif
#ifdef GLOW_FIRST_PASS
uniform float exposure;
uniform float white;
#ifdef GLOW_USE_AUTO_EXPOSURE
uniform highp sampler2D source_auto_exposure; //texunit:1
uniform highp float auto_exposure_grey;
#endif
uniform float glow_bloom;
uniform float glow_hdr_treshold;
uniform float glow_hdr_scale;
#endif
uniform float camera_z_far;
uniform float camera_z_near;
void main() {
#ifdef GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size;
pix_size*=0.5; //reading from larger buffer, so use more samples
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.214607;
color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.189879;
color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.157305;
color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.071303;
color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.189879;
color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.157305;
color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.071303;
frag_color = color;
#endif
#ifdef GAUSSIAN_VERTICAL
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.38774;
color+=textureLod( source_color, uv_interp+vec2( 0.0, 1.0)*pixel_size,lod )*0.24477;
color+=textureLod( source_color, uv_interp+vec2( 0.0, 2.0)*pixel_size,lod )*0.06136;
color+=textureLod( source_color, uv_interp+vec2( 0.0,-1.0)*pixel_size,lod )*0.24477;
color+=textureLod( source_color, uv_interp+vec2( 0.0,-2.0)*pixel_size,lod )*0.06136;
frag_color = color;
#endif
//glow uses larger sigma for a more rounded blur effect
#ifdef GLOW_GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size;
pix_size*=0.5; //reading from larger buffer, so use more samples
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.174938;
color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.165569;
color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.140367;
color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.106595;
color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.165569;
color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.140367;
color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.106595;
color*=glow_strength;
frag_color = color;
#endif
#ifdef GLOW_GAUSSIAN_VERTICAL
vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.288713;
color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.233062;
color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.122581;
color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.233062;
color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.122581;
color*=glow_strength;
frag_color = color;
#endif
#ifdef DOF_FAR_BLUR
vec4 color_accum = vec4(0.0);
float depth = textureLod( dof_source_depth, uv_interp, 0.0).r;
depth = depth * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float amount = smoothstep(dof_begin,dof_end,depth);
float k_accum=0.0;
for(int i=0;i<dof_kernel_size;i++) {
int int_ofs = i-dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius;
float tap_k = dof_kernel[i];
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
tap_depth = tap_depth * 2.0 - 1.0;
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0);
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
vec4 tap_color = textureLod( source_color, tap_uv, 0.0) * tap_k;
k_accum+=tap_k*tap_amount;
color_accum+=tap_color*tap_amount;
}
if (k_accum>0.0) {
color_accum/=k_accum;
}
frag_color = color_accum;///k_accum;
#endif
#ifdef DOF_NEAR_BLUR
vec4 color_accum = vec4(0.0);
float max_accum=0;
for(int i=0;i<dof_kernel_size;i++) {
int int_ofs = i-dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius;
float ofs_influence = max(0.0,1.0-float(abs(int_ofs))/float(dof_kernel_from));
float tap_k = dof_kernel[i];
vec4 tap_color = textureLod( source_color, tap_uv, 0.0);
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r;
tap_depth = tap_depth * 2.0 - 1.0;
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth);
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect
#ifdef DOF_NEAR_FIRST_TAP
tap_color.a= 1.0-smoothstep(dof_end,dof_begin,tap_depth);
#endif
max_accum=max(max_accum,tap_amount*ofs_influence);
color_accum+=tap_color*tap_k;
}
color_accum.a=max(color_accum.a,sqrt(max_accum));
#ifdef DOF_NEAR_BLUR_MERGE
vec4 original = textureLod( source_dof_original, uv_interp, 0.0);
color_accum = mix(original,color_accum,color_accum.a);
#endif
#ifndef DOF_NEAR_FIRST_TAP
//color_accum=vec4(vec3(color_accum.a),1.0);
#endif
frag_color = color_accum;
#endif
#ifdef GLOW_FIRST_PASS
#ifdef GLOW_USE_AUTO_EXPOSURE
frag_color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey;
#endif
frag_color*=exposure;
float luminance = max(frag_color.r,max(frag_color.g,frag_color.b));
float feedback = max( smoothstep(glow_hdr_treshold,glow_hdr_treshold+glow_hdr_scale,luminance), glow_bloom );
frag_color *= feedback;
#endif
#ifdef SIMPLE_COPY
vec4 color =textureLod( source_color, uv_interp,0.0);
frag_color = color;
#endif
#ifdef SSAO_MERGE
vec4 color =textureLod( source_color, uv_interp,0.0);
float ssao =textureLod( source_ssao, uv_interp,0.0).r;
frag_color = vec4( mix(color.rgb,color.rgb*mix(ssao_color.rgb,vec3(1.0),ssao),color.a), 1.0 );
#endif
}

View file

@ -0,0 +1,98 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
void main() {
gl_Position = vertex_attrib;
}
[fragment]
uniform highp sampler2D source_exposure; //texunit:0
#ifdef EXPOSURE_BEGIN
uniform highp ivec2 source_render_size;
uniform highp ivec2 target_size;
#endif
#ifdef EXPOSURE_END
uniform highp sampler2D prev_exposure; //texunit:1
uniform highp float exposure_adjust;
uniform highp float min_luminance;
uniform highp float max_luminance;
#endif
layout(location = 0) out highp float exposure;
void main() {
#ifdef EXPOSURE_BEGIN
ivec2 src_pos = ivec2(gl_FragCoord.xy)*source_render_size/target_size;
#if 1
//more precise and expensive, but less jittery
ivec2 next_pos = ivec2(gl_FragCoord.xy+ivec2(1))*source_render_size/target_size;
next_pos = max(next_pos,src_pos+ivec2(1)); //so it at least reads one pixel
highp vec3 source_color=vec3(0.0);
for(int i=src_pos.x;i<next_pos.x;i++) {
for(int j=src_pos.y;j<next_pos.y;j++) {
source_color += texelFetch(source_exposure,ivec2(i,j),0).rgb;
}
}
source_color/=float( (next_pos.x-src_pos.x)*(next_pos.y-src_pos.y) );
#else
highp vec3 source_color = texelFetch(source_exposure,src_pos,0).rgb;
#endif
exposure = max(source_color.r,max(source_color.g,source_color.b));
#else
ivec2 coord = ivec2(gl_FragCoord.xy);
exposure = texelFetch(source_exposure,coord*3+ivec2(0,0),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,0),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,0),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(0,1),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,1),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,1),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(0,2),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,2),0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,2),0).r;
exposure *= (1.0/9.0);
#ifdef EXPOSURE_END
#ifdef EXPOSURE_FORCE_SET
//will stay as is
#else
highp float prev_lum = texelFetch(prev_exposure,ivec2(0,0),0).r; //1 pixel previous exposure
exposure = clamp( prev_lum + (exposure-prev_lum)*exposure_adjust,min_luminance,max_luminance);
#endif //EXPOSURE_FORCE_SET
#endif //EXPOSURE_END
#endif //EXPOSURE_BEGIN
}

View file

@ -0,0 +1,167 @@
[vertex]
layout(location=0) in highp vec4 color;
layout(location=1) in highp vec4 velocity_active;
layout(location=2) in highp vec4 custom;
layout(location=3) in highp vec4 xform_1;
layout(location=4) in highp vec4 xform_2;
layout(location=5) in highp vec4 xform_3;
struct Attractor {
vec3 pos;
vec3 dir;
float radius;
float eat_radius;
float strength;
float attenuation;
};
#define MAX_ATTRACTORS 64
uniform mat4 origin;
uniform float system_phase;
uniform float prev_system_phase;
uniform float total_particles;
uniform float explosiveness;
uniform vec4 time;
uniform float delta;
uniform vec3 gravity;
uniform int attractor_count;
uniform Attractor attractors[MAX_ATTRACTORS];
out highp vec4 out_color; //tfb:
out highp vec4 out_velocity_active; //tfb:
out highp vec4 out_custom; //tfb:
out highp vec4 out_xform_1; //tfb:
out highp vec4 out_xform_2; //tfb:
out highp vec4 out_xform_3; //tfb:
VERTEX_SHADER_GLOBALS
#if defined(USE_MATERIAL)
layout(std140) uniform UniformData { //ubo:0
MATERIAL_UNIFORMS
};
#endif
void main() {
bool apply_forces=true;
bool apply_velocity=true;
float mass = 1.0;
float restart_phase = float(gl_InstanceID)/total_particles;
restart_phase*= explosiveness;
bool restart=false;
bool active = out_velocity_active.a > 0.5;
if (system_phase > prev_system_phase) {
restart = prev_system_phase < restart_phase && system_phase >= restart_phase;
} else {
restart = prev_system_phase < restart_phase || system_phase >= restart_phase;
}
if (restart) {
active=true;
}
out_color=color;
out_velocity_active=velocity_active;
out_custom=custom;
mat4 xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0)));
out_rot_active=rot_active;
if (active) {
//execute shader
{
VERTEX_SHADER_CODE
}
#if !defined(DISABLE_FORCE)
{
vec3 force = gravity;
for(int i=0;i<attractor_count;i++) {
vec3 rel_vec = out_pos_lifetime.xyz - attractors[i].pos;
float dist = rel_vec.length();
if (attractors[i].radius < dist)
continue;
if (attractors[i].eat_radius>0 && attractors[i].eat_radius > dist) {
out_velocity_active.a=0.0;
}
rel_vec = normalize(rel_vec);
float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation);
if (attractors[i].dir==vec3(0.0)) {
//towards center
force+=attractors[i].strength * rel_vec * attenuation * mass;
} else {
force+=attractors[i].strength * attractors[i].dir * attenuation *mass;
}
}
out_velocity_seed.xyz += force * delta;
}
#endif
#if !defined(DISABLE_VELOCITY)
{
out_pos_lifetime.xyz += out_velocity_seed.xyz * delta;
}
#endif
}
xform = transpose(xform);
out_velocity_active.a = mix(0.0,1.0,active);
out_xform_1 = xform[0];
out_xform_2 = xform[1];
out_xform_3 = xform[2];
}
[fragment]
//any code here is never executed, stuff is filled just so it works
FRAGMENT_SHADER_GLOBALS
#if defined(USE_MATERIAL)
layout(std140) uniform UniformData {
MATERIAL_UNIFORMS
};
#endif
void main() {
{
FRAGMENT_SHADER_CODE
}
}

View file

@ -0,0 +1,41 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
[fragment]
in vec2 uv_interp;
uniform sampler2D source_specular; //texunit:0
uniform sampler2D source_ssr; //texunit:1
uniform float stuff;
in vec2 uv2_interp;
layout(location = 0) out vec4 frag_color;
void main() {
vec4 specular = texture( source_specular, uv_interp );
#ifdef USE_SSR
vec4 ssr = textureLod(source_ssr,uv_interp,0.0);
specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a);
#endif
frag_color = vec4(specular.rgb,1.0);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,345 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
out vec2 pos_interp;
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
pos_interp.xy=gl_Position.xy;
}
[fragment]
in vec2 uv_interp;
in vec2 pos_interp;
uniform sampler2D source_diffuse; //texunit:0
uniform sampler2D source_normal_roughness; //texunit:1
uniform sampler2D source_depth; //texunit:2
uniform float camera_z_near;
uniform float camera_z_far;
uniform vec2 viewport_size;
uniform vec2 pixel_size;
uniform float filter_mipmap_levels;
uniform mat4 inverse_projection;
uniform mat4 projection;
uniform int num_steps;
uniform float depth_tolerance;
uniform float distance_fade;
uniform float acceleration;
layout(location = 0) out vec4 frag_color;
vec2 view_to_screen(vec3 view_pos,out float w) {
vec4 projected = projection * vec4(view_pos, 1.0);
projected.xyz /= projected.w;
projected.xy = projected.xy * 0.5 + 0.5;
w=projected.w;
return projected.xy;
}
#define M_PI 3.14159265359
void main() {
////
vec4 diffuse = texture( source_diffuse, uv_interp );
vec4 normal_roughness = texture( source_normal_roughness, uv_interp);
vec3 normal;
normal = normal_roughness.xyz*2.0-1.0;
float roughness = normal_roughness.w;
float depth_tex = texture(source_depth,uv_interp).r;
vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 );
vec3 vertex = world_pos.xyz/world_pos.w;
vec3 view_dir = normalize(vertex);
vec3 ray_dir = normalize(reflect(view_dir, normal));
if (dot(ray_dir,normal)<0.001) {
frag_color=vec4(0.0);
return;
}
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
//ray_dir = normalize(vec3(1,1,-1));
////////////////
//make ray length and clip it against the near plane (don't want to trace beyond visible)
float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far;
vec3 ray_end = vertex + ray_dir*ray_len;
float w_begin;
vec2 vp_line_begin = view_to_screen(vertex,w_begin);
float w_end;
vec2 vp_line_end = view_to_screen( ray_end, w_end);
vec2 vp_line_dir = vp_line_end-vp_line_begin;
//we need to interpolate w along the ray, to generate perspective correct reflections
w_begin = 1.0/w_begin;
w_end = 1.0/w_end;
float z_begin = vertex.z*w_begin;
float z_end = ray_end.z*w_end;
vec2 line_begin = vp_line_begin/pixel_size;
vec2 line_dir = vp_line_dir/pixel_size;
float z_dir = z_end - z_begin;
float w_dir = w_end - w_begin;
// clip the line to the viewport edges
float scale_max_x = min(1, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
float scale_max_y = min(1, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y));
float scale_min_x = min(1, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x));
float scale_min_y = min(1, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y));
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
line_dir *= line_clip;
z_dir *= line_clip;
w_dir *=line_clip;
//clip z and w advance to line advance
vec2 line_advance = normalize(line_dir); //down to pixel
float step_size = length(line_advance)/length(line_dir);
float z_advance = z_dir*step_size; // adapt z advance to line advance
float w_advance = w_dir*step_size; // adapt w advance to line advance
//make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y));
line_advance*=advance_angle_adj; // adapt z advance to line advance
z_advance*=advance_angle_adj;
w_advance*=advance_angle_adj;
vec2 pos = line_begin;
float z = z_begin;
float w = w_begin;
float z_from=z/w;
float z_to=z_from;
float depth;
vec2 prev_pos=pos;
bool found=false;
//if acceleration > 0, distance between pixels gets larger each step. This allows covering a larger area
float accel=1.0+acceleration;
float steps_taken=0;
for(float i=0;i<num_steps;i++) {
pos+=line_advance;
z+=z_advance;
w+=w_advance;
//convert to linear depth
depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
depth=-depth;
z_from = z_to;
z_to = z/w;
if (depth>z_to) {
//if depth was surpassed
if (depth<=max(z_to,z_from)+depth_tolerance) {
//check the depth tolerance
found=true;
}
break;
}
steps_taken+=1.0;
prev_pos=pos;
z_advance*=accel;
w_advance*=accel;
line_advance*=accel;
}
if (found) {
float margin_blend=1.0;
vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin
if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) {
//clip outside screen + margin
frag_color=vec4(0.0);
return;
}
{
//blend fading out towards external margin
vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0)));
margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y));
//margin_blend=1.0;
}
vec2 final_pos;
float grad;
#ifdef SMOOTH_ACCEL
//if the distance between point and prev point is >1, then take some samples in the middle for smoothing out the image
vec2 blend_dir = pos - prev_pos;
float steps = min(8.0,length(blend_dir));
if (steps>2.0) {
vec2 blend_step = blend_dir/steps;
float blend_z = (z_to-z_from)/steps;
vec2 new_pos;
float subgrad=0.0;
for(float i=0.0;i<steps;i++) {
new_pos = (prev_pos+blend_step*i);
float z = z_from+blend_z*i;
depth = texture(source_depth, new_pos*pixel_size).r * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
depth=-depth;
subgrad=i/steps;
if (depth>z)
break;
}
final_pos = new_pos;
grad=(steps_taken+subgrad)/num_steps;
} else {
#endif
grad=steps_taken/num_steps;
final_pos=pos;
#ifdef SMOOTH_ACCEL
}
#endif
#ifdef REFLECT_ROUGHNESS
vec4 final_color;
//if roughness is enabled, do screen space cone tracing
if (roughness > 0.001) {
///////////////////////////////////////////////////////////////////////////////////////
//use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
float gloss = 1.0-roughness;
float cone_angle = roughness * M_PI * 0.5;
vec2 cone_dir = final_pos - line_begin;
float cone_len = length(cone_dir);
cone_dir = normalize(cone_dir); //will be used normalized from now on
float max_mipmap = filter_mipmap_levels -1;
float gloss_mult=gloss;
float rem_alpha=1.0;
final_color = vec4(0.0);
for(int i=0;i<7;i++) {
float op_len = 2.0 * tan(cone_angle) * cone_len; //oposite side of iso triangle
float radius;
{
//fit to sphere inside cone (sphere ends at end of cone), something like this:
// ___
// \O/
// V
//
// as it avoids bleeding from beyond the reflection as much as possible. As a plus
// it also makes the rough reflection more elongated.
float a = op_len;
float h = cone_len;
float a2 = a * a;
float fh2 = 4.0f * h * h;
radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
}
//find the place where screen must be sampled
vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size;
//radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
float mipmap = clamp( log2( radius ), 0.0, max_mipmap );
//mipmap = max(mipmap-1.0,0.0);
//do sampling
vec4 sample_color;
{
sample_color = textureLod(source_diffuse,sample_pos,mipmap);
}
//multiply by gloss
sample_color.rgb*=gloss_mult;
sample_color.a=gloss_mult;
rem_alpha -= sample_color.a;
if(rem_alpha < 0.0) {
sample_color.rgb *= (1.0 - abs(rem_alpha));
}
final_color+=sample_color;
if (final_color.a>=0.95) {
// This code of accumulating gloss and aborting on near one
// makes sense when you think of cone tracing.
// Think of it as if roughness was 0, then we could abort on the first
// iteration. For lesser roughness values, we need more iterations, but
// each needs to have less influence given the sphere is smaller
break;
}
cone_len-=radius*2.0; //go to next (smaller) circle.
gloss_mult*=gloss;
}
} else {
final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0);
}
frag_color = vec4(final_color.rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
#else
frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
#endif
} else {
frag_color = vec4(0.0,0.0,0.0,0.0);
}
}

View file

@ -0,0 +1,247 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
void main() {
gl_Position = vertex_attrib;
gl_Position.z=1.0;
}
[fragment]
#define NUM_SAMPLES (11)
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
// miplevel to maintain reasonable spatial locality in the cache
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
#define LOG_MAX_OFFSET (3)
// This must be less than or equal to the MAX_MIP_LEVEL defined in SSAO.cpp
#define MAX_MIP_LEVEL (4)
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
#define NUM_SPIRAL_TURNS (7)
uniform sampler2D source_depth; //texunit:0
uniform usampler2D source_depth_mipmaps; //texunit:1
uniform sampler2D source_normal; //texunit:2
uniform ivec2 screen_size;
uniform float camera_z_far;
uniform float camera_z_near;
uniform float intensity_div_r6;
uniform float radius;
#ifdef ENABLE_RADIUS2
uniform float intensity_div_r62;
uniform float radius2;
#endif
uniform float bias;
uniform float proj_scale;
layout(location = 0) out float visibility;
uniform vec4 proj_info;
vec3 reconstructCSPosition(vec2 S, float z) {
return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z);
}
vec3 getPosition(ivec2 ssP) {
vec3 P;
P.z = texelFetch(source_depth, ssP, 0).r;
P.z = P.z * 2.0 - 1.0;
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
P.z = -P.z;
// Offset to pixel center
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
return P;
}
/** Reconstructs screen-space unit normal from screen-space position */
vec3 reconstructCSFaceNormal(vec3 C) {
return normalize(cross(dFdy(C), dFdx(C)));
}
/** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */
vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR){
// Radius relative to ssR
float alpha = float(sampleNumber + 0.5) * (1.0 / NUM_SAMPLES);
float angle = alpha * (NUM_SPIRAL_TURNS * 6.28) + spinAngle;
ssR = alpha;
return vec2(cos(angle), sin(angle));
}
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) {
// Derivation:
// mipLevel = floor(log(ssR / MAX_OFFSET));
int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
ivec2 ssP = ivec2(ssR * unitOffset) + ssC;
vec3 P;
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
// Manually clamp to the texture size because texelFetch bypasses the texture unit
ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1));
if (mipLevel < 1) {
//read from depth buffer
P.z = texelFetch(source_depth, mipP, 0).r;
P.z = P.z * 2.0 - 1.0;
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
P.z = -P.z;
} else {
//read from mipmaps
uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel-1).r;
P.z = -(float(d)/65535.0)*camera_z_far;
}
// Offset to pixel center
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
return P;
}
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius
Note that units of H() in the HPG12 paper are meters, not
unitless. The whole falloff/sampling function is therefore
unitless. In this implementation, we factor out (9 / radius).
Four versions of the falloff function are implemented below
*/
float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius,in float p_radius, in int tapIndex, in float randomPatternRotationAngle) {
// Offset on the unit disk, spun for this pixel
float ssR;
vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR);
ssR *= ssDiskRadius;
// The occluding point in camera space
vec3 Q = getOffsetPosition(ssC, unitOffset, ssR);
vec3 v = Q - C;
float vv = dot(v, v);
float vn = dot(v, n_C);
const float epsilon = 0.01;
float radius2 = p_radius*p_radius;
// A: From the HPG12 paper
// Note large epsilon to avoid overdarkening within cracks
//return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
float f=max(radius2 - vv, 0.0);
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
// C: Medium contrast (which looks better at high radii), no division. Note that the
// contribution still falls off with radius^2, but we've adjusted the rate in a way that is
// more computationally efficient and happens to be aesthetically pleasing.
// return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0);
// D: Low contrast, no division operation
// return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0);
}
void main() {
// Pixel being shaded
ivec2 ssC = ivec2(gl_FragCoord.xy);
// World space point being shaded
vec3 C = getPosition(ssC);
/* if (C.z <= -camera_z_far*0.999) {
// We're on the skybox
visibility=1.0;
return;
}*/
//visibility=-C.z/camera_z_far;
//return;
//vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
vec3 n_C = reconstructCSFaceNormal(C);
n_C = -n_C;
// Hash function used in the HPG12 AlchemyAO paper
float randomPatternRotationAngle = (3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10;
// Reconstruct normals from positions. These will lead to 1-pixel black lines
// at depth discontinuities, however the blur will wipe those out so they are not visible
// in the final image.
// Choose the screen-space sample radius
// proportional to the projected area of the sphere
float ssDiskRadius = -proj_scale * radius / C.z;
float sum = 0.0;
for (int i = 0; i < NUM_SAMPLES; ++i) {
sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle);
}
float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / NUM_SAMPLES));
#ifdef ENABLE_RADIUS2
//go again for radius2
randomPatternRotationAngle = (5 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 11;
// Reconstruct normals from positions. These will lead to 1-pixel black lines
// at depth discontinuities, however the blur will wipe those out so they are not visible
// in the final image.
// Choose the screen-space sample radius
// proportional to the projected area of the sphere
ssDiskRadius = -proj_scale * radius2 / C.z;
sum = 0.0;
for (int i = 0; i < NUM_SAMPLES; ++i) {
sum += sampleAO(ssC, C, n_C, ssDiskRadius,radius2, i, randomPatternRotationAngle);
}
A= min(A,max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / NUM_SAMPLES)));
#endif
// Bilateral box-filter over a quad for free, respecting depth edges
// (the difference that this makes is subtle)
if (abs(dFdx(C.z)) < 0.02) {
A -= dFdx(A) * ((ssC.x & 1) - 0.5);
}
if (abs(dFdy(C.z)) < 0.02) {
A -= dFdy(A) * ((ssC.y & 1) - 0.5);
}
visibility = A;
}

View file

@ -0,0 +1,113 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
void main() {
gl_Position = vertex_attrib;
gl_Position.z=1.0;
}
[fragment]
uniform sampler2D source_ssao; //texunit:0
uniform sampler2D source_depth; //texunit:1
layout(location = 0) out float visibility;
//////////////////////////////////////////////////////////////////////////////////////////////
// Tunable Parameters:
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
#define EDGE_SHARPNESS (1.0)
/** Step in 2-pixel intervals since we already blurred against neighbors in the
first AO pass. This constant can be increased while R decreases to improve
performance at the expense of some dithering artifacts.
Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was
unobjectionable after shading was applied but eliminated most temporal incoherence
from using small numbers of sample taps.
*/
#define SCALE (3)
/** Filter radius in pixels. This will be multiplied by SCALE. */
#define R (4)
//////////////////////////////////////////////////////////////////////////////////////////////
// Gaussian coefficients
const float gaussian[R + 1] =
// float[](0.356642, 0.239400, 0.072410, 0.009869);
// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
/** (1, 0) or (0, 1)*/
uniform ivec2 axis;
uniform float camera_z_far;
uniform float camera_z_near;
void main() {
ivec2 ssC = ivec2(gl_FragCoord.xy);
float depth = texelFetch(source_depth, ssC, 0).r;
depth = depth * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float depth_divide = 1.0 / camera_z_far;
depth*=depth_divide;
//if (depth > camera_z_far*0.999) {
// discard;//skybox
//}
float sum = texelFetch(source_ssao, ssC, 0).r;
// Base weight for depth falloff. Increase this for more blurriness,
// decrease it for better edge discrimination
float BASE = gaussian[0];
float totalWeight = BASE;
sum *= totalWeight;
for (int r = -R; r <= R; ++r) {
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
// so the IF statement has no runtime cost
if (r != 0) {
ivec2 ppos = ssC + axis * (r * SCALE);
float value = texelFetch(source_ssao, ppos, 0).r;
float temp_depth = texelFetch(source_depth, ssC, 0).r;
temp_depth = temp_depth * 2.0 - 1.0;
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
temp_depth *= depth_divide;
// spatial domain: offset gaussian tap
float weight = 0.3 + gaussian[abs(r)];
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
weight *= max(0.0, 1.0
- (EDGE_SHARPNESS * 2000.0) * abs(temp_depth - depth)
);
sum += value * weight;
totalWeight += weight;
}
}
const float epsilon = 0.0001;
visibility = sum / (totalWeight + epsilon);
}

View file

@ -0,0 +1,55 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
void main() {
gl_Position = vertex_attrib;
}
[fragment]
#ifdef MINIFY_START
#define SDEPTH_TYPE highp sampler2D
uniform float camera_z_far;
uniform float camera_z_near;
#else
#define SDEPTH_TYPE mediump usampler2D
#endif
uniform SDEPTH_TYPE source_depth; //texunit:0
uniform ivec2 from_size;
uniform int source_mipmap;
layout(location = 0) out mediump uint depth;
void main() {
ivec2 ssP = ivec2(gl_FragCoord.xy);
// Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling.
// On DX9, the bit-and can be implemented with floating-point modulo
#ifdef MINIFY_START
float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
fdepth = fdepth * 2.0 - 1.0;
fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near));
fdepth /= camera_z_far;
depth = uint(clamp(fdepth*65535,0.0,65535.0));
#else
depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
#endif
}

View file

@ -0,0 +1,172 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
[fragment]
//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this
#define QUALIFIER const
#ifdef USE_25_SAMPLES
const int kernel_size=25;
QUALIFIER vec4 kernel[25] = vec4[] (
vec4(0.530605, 0.613514, 0.739601, 0.0),
vec4(0.000973794, 1.11862e-005, 9.43437e-007, -3.0),
vec4(0.00333804, 7.85443e-005, 1.2945e-005, -2.52083),
vec4(0.00500364, 0.00020094, 5.28848e-005, -2.08333),
vec4(0.00700976, 0.00049366, 0.000151938, -1.6875),
vec4(0.0094389, 0.00139119, 0.000416598, -1.33333),
vec4(0.0128496, 0.00356329, 0.00132016, -1.02083),
vec4(0.017924, 0.00711691, 0.00347194, -0.75),
vec4(0.0263642, 0.0119715, 0.00684598, -0.520833),
vec4(0.0410172, 0.0199899, 0.0118481, -0.333333),
vec4(0.0493588, 0.0367726, 0.0219485, -0.1875),
vec4(0.0402784, 0.0657244, 0.04631, -0.0833333),
vec4(0.0211412, 0.0459286, 0.0378196, -0.0208333),
vec4(0.0211412, 0.0459286, 0.0378196, 0.0208333),
vec4(0.0402784, 0.0657244, 0.04631, 0.0833333),
vec4(0.0493588, 0.0367726, 0.0219485, 0.1875),
vec4(0.0410172, 0.0199899, 0.0118481, 0.333333),
vec4(0.0263642, 0.0119715, 0.00684598, 0.520833),
vec4(0.017924, 0.00711691, 0.00347194, 0.75),
vec4(0.0128496, 0.00356329, 0.00132016, 1.02083),
vec4(0.0094389, 0.00139119, 0.000416598, 1.33333),
vec4(0.00700976, 0.00049366, 0.000151938, 1.6875),
vec4(0.00500364, 0.00020094, 5.28848e-005, 2.08333),
vec4(0.00333804, 7.85443e-005, 1.2945e-005, 2.52083),
vec4(0.000973794, 1.11862e-005, 9.43437e-007, 3.0)
);
#endif //USE_25_SAMPLES
#ifdef USE_17_SAMPLES
const int kernel_size=17;
QUALIFIER vec4 kernel[17] = vec4[](
vec4(0.536343, 0.624624, 0.748867, 0.0),
vec4(0.00317394, 0.000134823, 3.77269e-005, -2.0),
vec4(0.0100386, 0.000914679, 0.000275702, -1.53125),
vec4(0.0144609, 0.00317269, 0.00106399, -1.125),
vec4(0.0216301, 0.00794618, 0.00376991, -0.78125),
vec4(0.0347317, 0.0151085, 0.00871983, -0.5),
vec4(0.0571056, 0.0287432, 0.0172844, -0.28125),
vec4(0.0582416, 0.0659959, 0.0411329, -0.125),
vec4(0.0324462, 0.0656718, 0.0532821, -0.03125),
vec4(0.0324462, 0.0656718, 0.0532821, 0.03125),
vec4(0.0582416, 0.0659959, 0.0411329, 0.125),
vec4(0.0571056, 0.0287432, 0.0172844, 0.28125),
vec4(0.0347317, 0.0151085, 0.00871983, 0.5),
vec4(0.0216301, 0.00794618, 0.00376991, 0.78125),
vec4(0.0144609, 0.00317269, 0.00106399, 1.125),
vec4(0.0100386, 0.000914679, 0.000275702, 1.53125),
vec4(0.00317394, 0.000134823, 3.77269e-005, 2.0)
);
#endif //USE_17_SAMPLES
#ifdef USE_11_SAMPLES
const int kernel_size=11;
QUALIFIER vec4 kernel[11] = vec4[](
vec4(0.560479, 0.669086, 0.784728, 0.0),
vec4(0.00471691, 0.000184771, 5.07566e-005, -2.0),
vec4(0.0192831, 0.00282018, 0.00084214, -1.28),
vec4(0.03639, 0.0130999, 0.00643685, -0.72),
vec4(0.0821904, 0.0358608, 0.0209261, -0.32),
vec4(0.0771802, 0.113491, 0.0793803, -0.08),
vec4(0.0771802, 0.113491, 0.0793803, 0.08),
vec4(0.0821904, 0.0358608, 0.0209261, 0.32),
vec4(0.03639, 0.0130999, 0.00643685, 0.72),
vec4(0.0192831, 0.00282018, 0.00084214, 1.28),
vec4(0.00471691, 0.000184771, 5.07565e-005, 2.0)
);
#endif //USE_11_SAMPLES
uniform float max_radius;
uniform float fovy;
uniform float camera_z_far;
uniform float camera_z_near;
uniform vec2 dir;
in vec2 uv_interp;
uniform sampler2D source_diffuse; //texunit:0
uniform sampler2D source_motion_ss; //texunit:1
uniform sampler2D source_depth; //texunit:2
layout(location = 0) out vec4 frag_color;
void main() {
float strength = texture(source_motion_ss,uv_interp).a;
strength*=strength; //stored as sqrt
// Fetch color of current pixel:
vec4 base_color = texture(source_diffuse, uv_interp);
if (strength>0.0) {
// Fetch linear depth of current pixel:
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
depth=-depth;
// Calculate the radius scale (1.0 for a unit plane sitting on the
// projection window):
float distance = 1.0 / tan(0.5 * fovy);
float scale = distance / -depth; //remember depth is negative by default in OpenGL
// Calculate the final step to fetch the surrounding pixels:
vec2 step = max_radius * scale * dir;
step *= strength; // Modulate it using the alpha channel.
step *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
// Accumulate the center sample:
vec3 color_accum = base_color.rgb;
color_accum *= kernel[0].rgb;
// Accumulate the other samples:
for (int i = 1; i < kernel_size; i++) {
// Fetch color and depth for current sample:
vec2 offset = uv_interp + kernel[i].a * step;
vec3 color = texture(source_diffuse, offset).rgb;
#ifdef ENABLE_FOLLOW_SURFACE
// If the difference in depth is huge, we lerp color back to "colorM":
float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0;
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
depth_cmp=-depth_cmp;
float s = clamp(300.0f * distance *
max_radius * abs(depth - depth_cmp),0.0,1.0);
color = mix(color, base_color.rgb, s);
#endif
// Accumulate:
color_accum += kernel[i].rgb * color;
}
frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO)
} else {
frag_color = base_color;
}
}

View file

@ -0,0 +1,263 @@
[vertex]
layout(location=0) in highp vec4 vertex_attrib;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
gl_Position = vertex_attrib;
uv_interp = uv_in;
}
[fragment]
in vec2 uv_interp;
uniform highp sampler2D source; //texunit:0
uniform float exposure;
uniform float white;
#ifdef USE_AUTO_EXPOSURE
uniform highp sampler2D source_auto_exposure; //texunit:1
uniform highp float auto_exposure_grey;
#endif
#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
uniform highp sampler2D source_glow; //texunit:2
uniform highp float glow_intensity;
#endif
layout(location = 0) out vec4 frag_color;
#ifdef USE_GLOW_FILTER_BICUBIC
// w0, w1, w2, and w3 are the four cubic B-spline basis functions
float w0(float a)
{
return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0);
}
float w1(float a)
{
return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0);
}
float w2(float a)
{
return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0);
}
float w3(float a)
{
return (1.0/6.0)*(a*a*a);
}
// g0 and g1 are the two amplitude functions
float g0(float a)
{
return w0(a) + w1(a);
}
float g1(float a)
{
return w2(a) + w3(a);
}
// h0 and h1 are the two offset functions
float h0(float a)
{
return -1.0 + w1(a) / (w0(a) + w1(a));
}
float h1(float a)
{
return 1.0 + w3(a) / (w2(a) + w3(a));
}
uniform ivec2 glow_texture_size;
vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod)
{
float lod=float(p_lod);
vec2 tex_size = vec2(glow_texture_size >> p_lod);
vec2 pixel_size =1.0/tex_size;
uv = uv*tex_size + 0.5;
vec2 iuv = floor( uv );
vec2 fuv = fract( uv );
float g0x = g0(fuv.x);
float g1x = g1(fuv.x);
float h0x = h0(fuv.x);
float h1x = h1(fuv.x);
float h0y = h0(fuv.y);
float h1y = h1(fuv.y);
vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size;
vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size;
vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size;
vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size;
return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) +
g1x * textureLod(tex, p1,lod)) +
g1(fuv.y) * (g0x * textureLod(tex, p2,lod) +
g1x * textureLod(tex, p3,lod));
}
#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod)
#else
#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod))
#endif
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
vec3 color = texelFetch(source,coord,0).rgb;
#ifdef USE_AUTO_EXPOSURE
color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey;
#endif
color*=exposure;
#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
vec3 glow = vec3(0.0);
#ifdef USE_GLOW_LEVEL1
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb;
#endif
#ifdef USE_GLOW_LEVEL2
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb;
#endif
#ifdef USE_GLOW_LEVEL3
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb;
#endif
#ifdef USE_GLOW_LEVEL4
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb;
#endif
#ifdef USE_GLOW_LEVEL5
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb;
#endif
#ifdef USE_GLOW_LEVEL6
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb;
#endif
#ifdef USE_GLOW_LEVEL7
glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb;
#endif
glow *= glow_intensity;
#ifdef USE_GLOW_REPLACE
color.rgb = glow;
#endif
#ifdef USE_GLOW_SCREEN
color.rgb = clamp((color.rgb + glow) - (color.rgb * glow), 0.0, 1.0);
#endif
#ifdef USE_GLOW_SOFTLIGHT
{
glow = (glow * 0.5) + 0.5;
color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
}
#endif
#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE)
color.rgb+=glow;
#endif
#endif
#ifdef USE_REINDHART_TONEMAPPER
{
color.rgb = ( color.rgb * ( 1.0 + ( color.rgb / ( white) ) ) ) / ( 1.0 + color.rgb );
}
#endif
#ifdef USE_FILMIC_TONEMAPPER
{
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
vec3 coltn = ((color.rgb*(A*color.rgb+C*B)+D*E)/(color.rgb*(A*color.rgb+B)+D*F))-E/F;
float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F;
color.rgb=coltn/whitetn;
}
#endif
#ifdef USE_ACES_TONEMAPPER
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
color.rgb = clamp((color.rgb*(a*color.rgb+b))/(color.rgb*(c*color.rgb+d)+e),vec3(0.0),vec3(1.0));
}
#endif
//regular Linear -> SRGB conversion
vec3 a = vec3(0.055);
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
frag_color=vec4(color.rgb,1.0);
}

View file

@ -114,25 +114,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;
@ -141,38 +152,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;
} break;
default: {
ERR_PRINT("INVALID PNG TYPE");
@ -186,7 +183,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();
@ -200,38 +197,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 );
@ -325,11 +290,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;
@ -366,22 +331,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;
@ -390,12 +355,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

@ -98,10 +98,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;
@ -140,22 +140,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;
@ -164,12 +164,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

@ -88,6 +88,10 @@ void OS_Unix::print_error(const char* p_function,const char* p_file,int p_line,c
print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n",p_function,err_details);
print("\E[0;35m At: %s:%i.\E[0m\n",p_file,p_line);
break;
case ERR_SHADER:
print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n",p_function,err_details);
print("\E[0;36m At: %s:%i.\E[0m\n",p_file,p_line);
break;
}
}

View file

@ -1295,6 +1295,17 @@ bool Main::start() {
appname = TranslationServer::get_singleton()->translate(appname);
OS::get_singleton()->set_window_title(appname);
int shadow_atlas_size = GLOBAL_DEF("rendering/shadow_atlas/size",2048);
int shadow_atlas_q0_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_0_subdiv",2);
int shadow_atlas_q1_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_1_subdiv",2);
int shadow_atlas_q2_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_2_subdiv",3);
int shadow_atlas_q3_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_3_subdiv",4);
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0,Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q0_subdiv));
sml->get_root()->set_shadow_atlas_quadrant_subdiv(1,Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q1_subdiv));
sml->get_root()->set_shadow_atlas_quadrant_subdiv(2,Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q2_subdiv));
sml->get_root()->set_shadow_atlas_quadrant_subdiv(3,Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q3_subdiv));
} else {
GLOBAL_DEF("display/stretch_mode","disabled");
@ -1303,7 +1314,17 @@ bool Main::start() {
Globals::get_singleton()->set_custom_property_info("display/stretch_aspect",PropertyInfo(Variant::STRING,"display/stretch_aspect",PROPERTY_HINT_ENUM,"ignore,keep,keep_width,keep_height"));
sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit",true));
GLOBAL_DEF("rendering/shadow_atlas/size",2048);
Globals::get_singleton()->set_custom_property_info("rendering/shadow_atlas/size",PropertyInfo(Variant::INT,"rendering/shadow_atlas/size",PROPERTY_HINT_RANGE,"256,16384"));
GLOBAL_DEF("rendering/shadow_atlas/quadrant_0_subdiv",2);
GLOBAL_DEF("rendering/shadow_atlas/quadrant_1_subdiv",2);
GLOBAL_DEF("rendering/shadow_atlas/quadrant_2_subdiv",3);
GLOBAL_DEF("rendering/shadow_atlas/quadrant_3_subdiv",4);
Globals::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_0_subdiv",PropertyInfo(Variant::INT,"rendering/shadow_atlas/quadrant_0_subdiv",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
Globals::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_1_subdiv",PropertyInfo(Variant::INT,"rendering/shadow_atlas/quadrant_1_subdiv",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
Globals::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_2_subdiv",PropertyInfo(Variant::INT,"rendering/shadow_atlas/quadrant_2_subdiv",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
Globals::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_3_subdiv",PropertyInfo(Variant::INT,"rendering/shadow_atlas/quadrant_3_subdiv",PROPERTY_HINT_ENUM,"Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
}

82
methods.py Executable file → Normal file
View file

@ -122,7 +122,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:
@ -228,6 +228,7 @@ def build_glsl_header(filename):
fd.write("\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n")
fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; ERR_FAIL_COND( get_active()!=this );\n\n ")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, bool p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value?1:0); }\n\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n")
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n")
@ -655,6 +656,7 @@ class LegacyGLHeaderStruct:
self.fragment_lines = []
self.uniforms = []
self.attributes = []
self.feedbacks = []
self.fbos = []
self.conditionals = []
self.enums = {}
@ -753,7 +755,29 @@ 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):
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 and line.find("{") == -1 and line.find(";") != -1):
uline = line.replace("uniform", "")
uline = uline.replace(";", "")
lines = uline.split(",")
@ -768,7 +792,7 @@ def include_file_in_legacygl_header(filename, header_data, depth):
if (not x in header_data.uniforms):
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 ", "")
@ -782,6 +806,19 @@ def include_file_in_legacygl_header(filename, header_data, depth):
bind = bind.replace("attrib:", "").strip()
header_data.attributes += [(name, bind)]
if (line.strip().find("out ") == 0 and line.find("tfb:") != -1):
uline = line.replace("out ", "")
uline = uline.replace("highp ", "")
uline = uline.replace(";", "")
uline = uline[uline.find(" "):].strip()
if (uline.find("//") != -1):
name, bind = uline.split("//")
if (bind.find("tfb:") != -1):
name = name.strip()
bind = bind.replace("tfb:", "").strip()
header_data.feedbacks += [(name, bind)]
line = line.replace("\r", "")
line = line.replace("\n", "")
# line=line.replace("\\","\\\\")
@ -991,12 +1028,14 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write("\t\tstatic const Enum *_enums=NULL;\n")
fd.write("\t\tstatic const EnumValue *_enum_values=NULL;\n")
conditionals_found = []
if (len(header_data.conditionals)):
fd.write("\t\tstatic const char* _conditional_strings[]={\n")
if (len(header_data.conditionals)):
for x in header_data.conditionals:
fd.write("\t\t\t\"#define " + x + "\\n\",\n")
conditionals_found.append(x)
fd.write("\t\t};\n\n")
else:
fd.write("\t\tstatic const char **_conditional_strings=NULL;\n")
@ -1021,6 +1060,25 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
else:
fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n")
feedback_count = 0
if (len(header_data.feedbacks)):
fd.write("\t\tstatic const Feedback _feedbacks[]={\n")
for x in header_data.feedbacks:
name = x[0]
cond = x[1]
if (cond in conditionals_found):
fd.write("\t\t\t{\"" + name + "\"," + str(conditionals_found.index(cond)) + "},\n")
else:
fd.write("\t\t\t{\"" + name + "\",-1},\n")
feedback_count += 1
fd.write("\t\t};\n\n")
else:
fd.write("\t\tstatic const Feedback* _feedbacks=NULL;\n")
if (len(header_data.texunits)):
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
for x in header_data.texunits:
@ -1029,6 +1087,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)):
@ -1050,9 +1116,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)) + ",_feedbacks," + str(feedback_count) + ",_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)) + ",_feedbacks," + str(feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n")
fd.write("\t};\n\n")
@ -1084,6 +1150,12 @@ def build_gles2_headers(target, source, env):
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

@ -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

@ -1,7 +1,8 @@
def can_build(platform):
return True
# FIXME: Disabled temporary for gles3 implementation
return False
def configure(env):

View file

@ -960,9 +960,9 @@ void GridMap::_octant_bake(const OctantKey &p_key, const Ref<TriangleMesh>& p_tm
st->add_to_format(VS::ARRAY_FORMAT_COLOR);
if (m.is_valid()) {
Ref<FixedMaterial> fm = m;
Ref<FixedSpatialMaterial> fm = m;
if (fm.is_valid())
fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true);
}
}
}

View file

@ -84,9 +84,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

@ -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

@ -37,7 +37,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 {
@ -45,26 +45,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);
@ -87,6 +87,6 @@ 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

@ -103,7 +103,7 @@ void VideoStreamPlaybackTheora::video_write(void){
dst[p++] = 255;
};
}
format = Image::FORMAT_RGBA;
format = Image::FORMAT_RGBA8;
}
// */
@ -130,10 +130,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
@ -202,7 +202,7 @@ void VideoStreamPlaybackTheora::video_write(void){
}
}
format = Image::FORMAT_RGBA;
format = Image::FORMAT_RGBA8;
} else {
@ -470,7 +470,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

@ -127,7 +127,7 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) {
}
frame_data.resize((webm->getWidth() * webm->getHeight()) << 2);
texture->create(webm->getWidth(), webm->getHeight(), Image::FORMAT_RGBA, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE);
texture->create(webm->getWidth(), webm->getHeight(), Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE);
return true;
}
@ -318,7 +318,7 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
}
if (converted)
texture->set_data(Image(image.w, image.h, 0, Image::FORMAT_RGBA, frame_data)); //Zero copy send to visual server
texture->set_data(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); //Zero copy send to visual server
}
break;

View file

@ -42,9 +42,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();
@ -52,7 +52,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 {
@ -109,7 +109,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);
}
@ -161,7 +161,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

@ -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;
}
@ -486,7 +486,7 @@ RID RasterizerIPhone::material_create() {
return material_owner.make_rid( memnew( Material ) );
}
void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value) {
void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value) {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND(!m);
@ -494,7 +494,7 @@ void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedMat
m->parameters[p_parameter] = p_value;
}
Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const {
Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND_V(!m, Variant());
@ -503,7 +503,7 @@ Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material,VS::FixedM
return m->parameters[p_parameter];
}
void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture) {
void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture) {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND(!m);
@ -511,7 +511,7 @@ void RasterizerIPhone::fixed_material_set_texture(RID p_material,VS::FixedMateri
m->textures[p_parameter] = p_texture;
}
RID RasterizerIPhone::fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const {
RID RasterizerIPhone::fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND_V(!m, RID());
@ -535,7 +535,7 @@ VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID
return m->detail_blend_mode;
}
void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) {
void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND(!m);
@ -543,7 +543,7 @@ void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material,VS::Fixed
m->texcoord_mode[p_parameter] = p_mode;
}
VS::FixedMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const {
VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
@ -552,7 +552,7 @@ VS::FixedMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode
return m->texcoord_mode[p_parameter]; // for now
}
void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedMaterialTexGenMode p_mode) {
void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedSpatialMaterialTexGenMode p_mode) {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND(!m);
@ -560,7 +560,7 @@ void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material,VS::FixedMa
m->texgen_mode = p_mode;
};
VS::FixedMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
VS::FixedSpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
Material *m=material_owner.get( p_material );
ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);

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;
@ -100,11 +100,11 @@ class RasterizerIPhone : public Rasterizer {
RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX];
Transform uv_transform;
VS::FixedMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
VS::FixedSpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
VS::MaterialBlendMode detail_blend_mode;
VS::FixedMaterialTexGenMode texgen_mode;
VS::FixedSpatialMaterialTexGenMode texgen_mode;
Material() {
@ -624,20 +624,20 @@ public:
virtual RID material_create();
virtual void fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant& p_value);
virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const;
virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value);
virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter, RID p_texture);
virtual RID fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const;
virtual void fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
virtual RID fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode);
virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const;
virtual void fixed_material_set_texgen_mode(RID p_material,VS::FixedMaterialTexGenMode p_mode);
virtual VS::FixedMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
virtual void fixed_material_set_texgen_mode(RID p_material,VS::FixedSpatialMaterialTexGenMode p_mode);
virtual VS::FixedSpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode);
virtual VS::FixedMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const;
virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
virtual Transform fixed_material_get_uv_transform(RID p_material) const;

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/glew.h"
#define GLES3_INCLUDE_H "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

@ -110,6 +110,7 @@ bool ContextGL_Win::is_using_vsync() const {
return use_vsync;
}
#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
Error ContextGL_Win::initialize() {
@ -162,10 +163,10 @@ Error ContextGL_Win::initialize() {
if (opengl_3_context) {
int attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.1 context
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.3 context
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
//and it shall be forward compatible so that we can only use up to date functionality
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|_WGL_CONTEXT_DEBUG_BIT_ARB,
0}; //zero indicates the end of the array
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; //pointer to the method
@ -182,7 +183,7 @@ Error ContextGL_Win::initialize() {
if (!(new_hRC=wglCreateContextAttribsARB(hDC,0, attribs)))
{
wglDeleteContext(hRC);
MessageBox(NULL,"Can't Create An OpenGL 3.1 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
MessageBox(NULL,"Can't Create An OpenGL 3.3 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return false
}
wglMakeCurrent(hDC,NULL);
@ -191,11 +192,11 @@ Error ContextGL_Win::initialize() {
if (!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
MessageBox(NULL,"Can't Activate The GL 3.1 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
MessageBox(NULL,"Can't Activate The GL 3.3 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
printf("Activated GL 3.1 context");
printf("Activated GL 3.3 context");
}
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress ("wglSwapIntervalEXT");

View file

@ -246,7 +246,7 @@ def configure(env):
env.Append(CCFLAGS=['/DWIN32'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
env.Append(CCFLAGS=['/DGLES2_ENABLED'])
env.Append(CCFLAGS=['/DOPENGL_ENABLED'])
LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', 'shell32', 'advapi32', 'dinput8', 'dxguid']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
@ -370,7 +370,7 @@ def configure(env):
env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows'])
env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DGLES2_ENABLED'])
env.Append(CCFLAGS=['-DOPENGL_ENABLED'])
env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid'])
# if (env["bits"]=="32"):

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