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:
commit
3f3f5a5359
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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();*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
1255
core/image.cpp
1255
core/image.cpp
File diff suppressed because it is too large
Load Diff
200
core/image.h
200
core/image.h
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
18
core/rid.cpp
18
core/rid.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
230
core/rid.h
230
core/rid.h
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
|
@ -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")
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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();
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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');
|
||||
|
||||
|
|
@ -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() {
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
|
||||
def can_build(platform):
|
||||
return True
|
||||
# FIXME: Disabled temporary for gles3 implementation
|
||||
return False
|
||||
|
||||
|
||||
def configure(env):
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
class OS_Server : public OS_Unix {
|
||||
|
||||
Rasterizer *rasterizer;
|
||||
// Rasterizer *rasterizer;
|
||||
VisualServer *visual_server;
|
||||
VideoMode current_videomode;
|
||||
List<String> args;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue