WIP New GLES3 Shader Compiler
Uses versions and specializations (more similar to RenderingDevice version)
This commit is contained in:
parent
96a20e477b
commit
98ac002c34
|
@ -118,9 +118,9 @@ void RasterizerCanvasBaseGLES3::canvas_begin() {
|
||||||
state.using_large_vertex = false;
|
state.using_large_vertex = false;
|
||||||
state.using_modulate = false;
|
state.using_modulate = false;
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_MODULATE, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_LARGE_VERTEX, false);
|
||||||
state.canvas_shader.bind();
|
state.canvas_shader.bind();
|
||||||
|
|
||||||
int viewport_x, viewport_y, viewport_width, viewport_height;
|
int viewport_x, viewport_y, viewport_width, viewport_height;
|
||||||
|
@ -248,29 +248,29 @@ void RasterizerCanvasBaseGLES3::canvas_end() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasBaseGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
|
void RasterizerCanvasBaseGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
|
||||||
_bind_quad_buffer();
|
_bind_quad_buffer();
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasBaseGLES3::_set_texture_rect_mode(bool p_texture_rect, bool p_light_angle, bool p_modulate, bool p_large_vertex) {
|
void RasterizerCanvasBaseGLES3::_set_texture_rect_mode(bool p_texture_rect, bool p_light_angle, bool p_modulate, bool p_large_vertex) {
|
||||||
// always set this directly (this could be state checked)
|
// always set this directly (this could be state checked)
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_TEXTURE_RECT, p_texture_rect);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_TEXTURE_RECT, p_texture_rect);
|
||||||
|
|
||||||
if (state.using_light_angle != p_light_angle) {
|
if (state.using_light_angle != p_light_angle) {
|
||||||
state.using_light_angle = p_light_angle;
|
state.using_light_angle = p_light_angle;
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, p_light_angle);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, p_light_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.using_modulate != p_modulate) {
|
if (state.using_modulate != p_modulate) {
|
||||||
state.using_modulate = p_modulate;
|
state.using_modulate = p_modulate;
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, p_modulate);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_MODULATE, p_modulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.using_large_vertex != p_large_vertex) {
|
if (state.using_large_vertex != p_large_vertex) {
|
||||||
state.using_large_vertex = p_large_vertex;
|
state.using_large_vertex = p_large_vertex;
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, p_large_vertex);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_ATTRIB_LARGE_VERTEX, p_large_vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasBaseGLES3::_bind_canvas_texture
|
||||||
|
|
||||||
if (p_normal_map == state.current_normal) {
|
if (p_normal_map == state.current_normal) {
|
||||||
//do none
|
//do none
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
|
||||||
|
|
||||||
} else if (p_normal_map.is_valid()) {
|
} else if (p_normal_map.is_valid()) {
|
||||||
RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(p_normal_map);
|
RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(p_normal_map);
|
||||||
|
@ -329,7 +329,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasBaseGLES3::_bind_canvas_texture
|
||||||
state.current_normal = RID();
|
state.current_normal = RID();
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
||||||
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
|
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::USE_DEFAULT_NORMAL, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
|
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
|
||||||
|
@ -341,14 +341,14 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasBaseGLES3::_bind_canvas_texture
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
||||||
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
|
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
|
||||||
state.current_normal = p_normal_map;
|
state.current_normal = p_normal_map;
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, true);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::USE_DEFAULT_NORMAL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
state.current_normal = RID();
|
state.current_normal = RID();
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
||||||
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
|
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::USE_DEFAULT_NORMAL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tex_return;
|
return tex_return;
|
||||||
|
@ -432,44 +432,44 @@ void RasterizerCanvasBaseGLES3::_bind_quad_buffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasBaseGLES3::_set_uniforms() {
|
void RasterizerCanvasBaseGLES3::_set_uniforms() {
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::PROJECTION_MATRIX, state.uniforms.projection_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::PROJECTION_MATRIX, state.uniforms.projection_matrix);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.uniforms.final_modulate);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::FINAL_MODULATE, state.uniforms.final_modulate);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::TIME, storage->frame.time[0]);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::TIME, storage->frame.time[0]);
|
||||||
|
|
||||||
if (storage->frame.current_rt) {
|
if (storage->frame.current_rt) {
|
||||||
Vector2 screen_pixel_size;
|
Vector2 screen_pixel_size;
|
||||||
screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
|
screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
|
||||||
screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
|
screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.using_skeleton) {
|
if (state.using_skeleton) {
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.using_light) {
|
if (state.using_light) {
|
||||||
Light *light = state.using_light;
|
Light *light = state.using_light;
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX, light->light_shader_xform);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_MATRIX, light->light_shader_xform);
|
||||||
Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
|
Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
|
||||||
basis_inverse.elements[2] = Vector2();
|
basis_inverse.elements[2] = Vector2();
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX_INVERSE, basis_inverse);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_MATRIX_INVERSE, basis_inverse);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_COLOR, light->color * light->energy);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_COLOR, light->color * light->energy);
|
||||||
// state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_pos);
|
// state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_pos);
|
||||||
// FTODO
|
// FTODO
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_xform.elements[2]);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_POS, light->light_shader_xform.elements[2]);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_HEIGHT, light->height);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_HEIGHT, light->height);
|
||||||
|
|
||||||
// FTODO
|
// FTODO
|
||||||
//state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, light->mode == RS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
|
//state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, light->mode == RS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, 0.0f);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::LIGHT_OUTSIDE_ALPHA, 0.0f);
|
||||||
|
|
||||||
if (state.using_shadow) {
|
if (state.using_shadow) {
|
||||||
// FTODO
|
// FTODO
|
||||||
|
@ -749,7 +749,7 @@ void RasterizerCanvasBaseGLES3::_legacy_draw_poly_triangles(Item::CommandPolygon
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
|
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_polygon(pd.indices.ptr(), pd.indices.size(), pd.points.size(), pd.points.ptr(), pd.uvs.ptr(), pd.colors.ptr(), pd.colors.size() == 1, nullptr, nullptr);
|
_draw_polygon(pd.indices.ptr(), pd.indices.size(), pd.points.size(), pd.points.ptr(), pd.uvs.ptr(), pd.colors.ptr(), pd.colors.size() == 1, nullptr, nullptr);
|
||||||
|
@ -788,7 +788,7 @@ void RasterizerCanvasBaseGLES3::_legacy_draw_primitive(Item::CommandPrimitive *p
|
||||||
glDisableVertexAttribArray(RS::ARRAY_COLOR);
|
glDisableVertexAttribArray(RS::ARRAY_COLOR);
|
||||||
glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
|
glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
||||||
|
|
||||||
_draw_gui_primitive(p_pr->point_count, p_pr->points, NULL, NULL);
|
_draw_gui_primitive(p_pr->point_count, p_pr->points, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -806,7 +806,7 @@ void RasterizerCanvasBaseGLES3::_legacy_draw_line(Item::CommandPrimitive *p_pr,
|
||||||
glDisableVertexAttribArray(RS::ARRAY_COLOR);
|
glDisableVertexAttribArray(RS::ARRAY_COLOR);
|
||||||
glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
|
glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
||||||
|
|
||||||
#ifdef GLES_OVER_GL
|
#ifdef GLES_OVER_GL
|
||||||
// if (line->antialiased)
|
// if (line->antialiased)
|
||||||
|
@ -1312,13 +1312,13 @@ void RasterizerCanvasBaseGLES3::initialize() {
|
||||||
state.canvas_shadow_shader.init();
|
state.canvas_shadow_shader.init();
|
||||||
state.canvas_shader.init();
|
state.canvas_shader.init();
|
||||||
_set_texture_rect_mode(true);
|
_set_texture_rect_mode(true);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
|
||||||
|
|
||||||
state.canvas_shader.bind();
|
state.canvas_shader.bind();
|
||||||
|
|
||||||
state.lens_shader.init();
|
state.lens_shader.init();
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
|
||||||
|
|
||||||
state.using_light = NULL;
|
state.using_light = NULL;
|
||||||
state.using_transparent_rt = false;
|
state.using_transparent_rt = false;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "servers/rendering/renderer_canvas_render.h"
|
#include "servers/rendering/renderer_canvas_render.h"
|
||||||
#include "servers/rendering/renderer_compositor.h"
|
#include "servers/rendering/renderer_compositor.h"
|
||||||
|
|
||||||
#include "shaders/canvas.glsl.gen.h"
|
#include "shaders/canvas_old.glsl.gen.h"
|
||||||
#include "shaders/canvas_shadow.glsl.gen.h"
|
#include "shaders/canvas_shadow.glsl.gen.h"
|
||||||
#include "shaders/lens_distorted.glsl.gen.h"
|
#include "shaders/lens_distorted.glsl.gen.h"
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ public:
|
||||||
CanvasItemUBO canvas_item_ubo_data;
|
CanvasItemUBO canvas_item_ubo_data;
|
||||||
GLuint canvas_item_ubo;
|
GLuint canvas_item_ubo;
|
||||||
bool canvas_texscreen_used;
|
bool canvas_texscreen_used;
|
||||||
CanvasShaderGLES3 canvas_shader;
|
CanvasOldShaderGLES3 canvas_shader;
|
||||||
CanvasShadowShaderGLES3 canvas_shadow_shader;
|
CanvasShadowShaderGLES3 canvas_shadow_shader;
|
||||||
LensDistortedShaderGLES3 lens_shader;
|
LensDistortedShaderGLES3 lens_shader;
|
||||||
|
|
||||||
|
|
|
@ -430,7 +430,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
texture = texture->get_ptr();
|
texture = texture->get_ptr();
|
||||||
|
|
||||||
if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
|
if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, true);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_FORCE_REPEAT, true);
|
||||||
can_tile = false;
|
can_tile = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
flip_v = !flip_v;
|
flip_v = !flip_v;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
|
|
||||||
bool untile = false;
|
bool untile = false;
|
||||||
|
|
||||||
|
@ -558,7 +558,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
Vector2(1.0, 0.0),
|
Vector2(1.0, 0.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2());
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2());
|
||||||
_draw_gui_primitive(4, points, NULL, uvs);
|
_draw_gui_primitive(4, points, NULL, uvs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,8 +589,8 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
dst_rect.size.height *= -1;
|
dst_rect.size.height *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SRC_RECT, Color(0, 0, 1, 1));
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
storage->info.render._2d_draw_call_count++;
|
storage->info.render._2d_draw_call_count++;
|
||||||
|
@ -628,10 +628,10 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
|
dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y));
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y));
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
storage->info.render._2d_draw_call_count++;
|
storage->info.render._2d_draw_call_count++;
|
||||||
|
@ -645,7 +645,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_FORCE_REPEAT, false);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Item::Command::TYPE_NINEPATCH: {
|
case Item::Command::TYPE_NINEPATCH: {
|
||||||
|
@ -678,7 +678,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height);
|
Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height);
|
||||||
|
|
||||||
// state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
// state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
|
|
||||||
Rect2 source = np->source;
|
Rect2 source = np->source;
|
||||||
if (source.size.x == 0 && source.size.y == 0) {
|
if (source.size.x == 0 && source.size.y == 0) {
|
||||||
|
@ -1151,7 +1151,7 @@ void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Ite
|
||||||
case Item::Command::TYPE_TRANSFORM: {
|
case Item::Command::TYPE_TRANSFORM: {
|
||||||
Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(command);
|
Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(command);
|
||||||
state.uniforms.extra_matrix = transform->xform;
|
state.uniforms.extra_matrix = transform->xform;
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
state.canvas_shader.set_uniform(CanvasOldShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Item::Command::TYPE_PARTICLES: {
|
case Item::Command::TYPE_PARTICLES: {
|
||||||
|
@ -1250,7 +1250,7 @@ void RasterizerCanvasGLES3::canvas_render_items_implementation(Item *p_item_list
|
||||||
ris.item_group_light = p_light;
|
ris.item_group_light = p_light;
|
||||||
ris.item_group_base_transform = p_base_transform;
|
ris.item_group_base_transform = p_base_transform;
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_SKELETON, false);
|
||||||
|
|
||||||
state.current_tex = RID();
|
state.current_tex = RID();
|
||||||
state.current_tex_ptr = NULL;
|
state.current_tex_ptr = NULL;
|
||||||
|
@ -1270,7 +1270,7 @@ void RasterizerCanvasGLES3::canvas_render_items_implementation(Item *p_item_list
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_SKELETON, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy non-batched implementation for regression testing.
|
// Legacy non-batched implementation for regression testing.
|
||||||
|
@ -1555,7 +1555,7 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!light_used) {
|
if (!light_used) {
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, true);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_LIGHTING, true);
|
||||||
light_used = true;
|
light_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,20 +1563,20 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
|
||||||
//bool has_shadow = light->shadow_buffer.is_valid() && p_ci->light_mask & light->item_shadow_mask;
|
//bool has_shadow = light->shadow_buffer.is_valid() && p_ci->light_mask & light->item_shadow_mask;
|
||||||
bool has_shadow = light->use_shadow && p_ci->light_mask & light->item_shadow_mask;
|
bool has_shadow = light->use_shadow && p_ci->light_mask & light->item_shadow_mask;
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, has_shadow);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_SHADOWS, has_shadow);
|
||||||
if (has_shadow) {
|
if (has_shadow) {
|
||||||
// FTODO
|
// FTODO
|
||||||
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0);
|
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_USE_GRADIENT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_NONE);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_NEAREST, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_NONE);
|
||||||
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF3);
|
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF3);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF3, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF5);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF5, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF5);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF7, false);
|
||||||
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF7);
|
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF7);
|
||||||
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF9);
|
//state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF9);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF9, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF13);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF13, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF13);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.canvas_shader.bind();
|
state.canvas_shader.bind();
|
||||||
|
@ -1607,14 +1607,14 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
|
||||||
}
|
}
|
||||||
|
|
||||||
if (light_used) {
|
if (light_used) {
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_LIGHTING, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_SHADOWS, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_NEAREST, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF3, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF5, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF7, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF9, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false);
|
state.canvas_shader.set_conditional(CanvasOldShaderGLES3::SHADOW_FILTER_PCF13, false);
|
||||||
|
|
||||||
state.canvas_shader.bind();
|
state.canvas_shader.bind();
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "rasterizer_gles3.h"
|
#include "rasterizer_gles3.h"
|
||||||
|
|
||||||
#ifdef GLES3_BACKEND_ENABLED
|
#ifdef GLES3_BACKEND_ENABLED
|
||||||
#include "shader_gles3.h"
|
#include "shader_old_gles3.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
|
|
@ -1559,8 +1559,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
|
||||||
return; //just invalid, but no error
|
return; //just invalid, but no error
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderCompilerGLES3::GeneratedCode gen_code;
|
ShaderCompilerOLDGLES3::GeneratedCode gen_code;
|
||||||
ShaderCompilerGLES3::IdentifierActions *actions = NULL;
|
ShaderCompilerOLDGLES3::IdentifierActions *actions = NULL;
|
||||||
|
|
||||||
switch (p_shader->mode) {
|
switch (p_shader->mode) {
|
||||||
case RS::SHADER_CANVAS_ITEM: {
|
case RS::SHADER_CANVAS_ITEM: {
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
#include "servers/rendering/renderer_compositor.h"
|
#include "servers/rendering/renderer_compositor.h"
|
||||||
#include "servers/rendering/renderer_storage.h"
|
#include "servers/rendering/renderer_storage.h"
|
||||||
#include "servers/rendering/shader_language.h"
|
#include "servers/rendering/shader_language.h"
|
||||||
#include "shader_compiler_gles3.h"
|
#include "shader_compiler_old_gles3.h"
|
||||||
#include "shader_gles3.h"
|
#include "shader_old_gles3.h"
|
||||||
|
|
||||||
#include "shaders/copy.glsl.gen.h"
|
#include "shaders/copy.glsl.gen.h"
|
||||||
#include "shaders/cubemap_filter.glsl.gen.h"
|
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||||
|
@ -134,14 +134,14 @@ public:
|
||||||
} resources;
|
} resources;
|
||||||
|
|
||||||
mutable struct Shaders {
|
mutable struct Shaders {
|
||||||
ShaderCompilerGLES3 compiler;
|
ShaderCompilerOLDGLES3 compiler;
|
||||||
|
|
||||||
CopyShaderGLES3 copy;
|
CopyShaderGLES3 copy;
|
||||||
CubemapFilterShaderGLES3 cubemap_filter;
|
CubemapFilterShaderGLES3 cubemap_filter;
|
||||||
|
|
||||||
ShaderCompilerGLES3::IdentifierActions actions_canvas;
|
ShaderCompilerOLDGLES3::IdentifierActions actions_canvas;
|
||||||
ShaderCompilerGLES3::IdentifierActions actions_scene;
|
ShaderCompilerOLDGLES3::IdentifierActions actions_scene;
|
||||||
ShaderCompilerGLES3::IdentifierActions actions_particles;
|
ShaderCompilerOLDGLES3::IdentifierActions actions_particles;
|
||||||
|
|
||||||
} shaders;
|
} shaders;
|
||||||
|
|
||||||
|
@ -567,7 +567,7 @@ public:
|
||||||
RID self;
|
RID self;
|
||||||
|
|
||||||
RS::ShaderMode mode;
|
RS::ShaderMode mode;
|
||||||
ShaderGLES3 *shader;
|
ShaderOLDGLES3 *shader;
|
||||||
String code;
|
String code;
|
||||||
SelfList<Material>::List materials;
|
SelfList<Material>::List materials;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "shader_compiler_gles3.h"
|
#include "shader_compiler_old_gles3.h"
|
||||||
#ifdef GLES3_BACKEND_ENABLED
|
#ifdef GLES3_BACKEND_ENABLED
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
|
@ -213,7 +213,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) {
|
void ShaderCompilerOLDGLES3::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) {
|
||||||
int fidx = -1;
|
int fidx = -1;
|
||||||
|
|
||||||
for (int i = 0; i < p_node->functions.size(); i++) {
|
for (int i = 0; i < p_node->functions.size(); i++) {
|
||||||
|
@ -272,7 +272,7 @@ void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const Stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
|
String ShaderCompilerOLDGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
|
||||||
StringBuilder code;
|
StringBuilder code;
|
||||||
|
|
||||||
switch (p_node->type) {
|
switch (p_node->type) {
|
||||||
|
@ -852,13 +852,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
return code.as_string();
|
return code.as_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderLanguage::DataType ShaderCompilerGLES3::_get_variable_type(const StringName &p_type) {
|
ShaderLanguage::DataType ShaderCompilerOLDGLES3::_get_variable_type(const StringName &p_type) {
|
||||||
// RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
|
// RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
|
||||||
RS::GlobalVariableType gvt = RS::GLOBAL_VAR_TYPE_MAX;
|
RS::GlobalVariableType gvt = RS::GLOBAL_VAR_TYPE_MAX;
|
||||||
return RS::global_variable_type_get_shader_datatype(gvt);
|
return RS::global_variable_type_get_shader_datatype(gvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error ShaderCompilerGLES3::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
|
Error ShaderCompilerOLDGLES3::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
|
||||||
ShaderLanguage::VaryingFunctionNames var_names;
|
ShaderLanguage::VaryingFunctionNames var_names;
|
||||||
|
|
||||||
ShaderLanguage::ShaderCompileInfo info;
|
ShaderLanguage::ShaderCompileInfo info;
|
||||||
|
@ -901,7 +901,7 @@ Error ShaderCompilerGLES3::compile(RS::ShaderMode p_mode, const String &p_code,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
ShaderCompilerOLDGLES3::ShaderCompilerOLDGLES3() {
|
||||||
/** CANVAS ITEM SHADER **/
|
/** CANVAS ITEM SHADER **/
|
||||||
|
|
||||||
actions[RS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
|
actions[RS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
|
|
@ -28,8 +28,8 @@
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#ifndef SHADER_COMPILER_OPENGL_H
|
#ifndef SHADER_COMPILER_OLD_OPENGL_H
|
||||||
#define SHADER_COMPILER_OPENGL_H
|
#define SHADER_COMPILER_OLD_OPENGL_H
|
||||||
|
|
||||||
#include "drivers/gles3/rasterizer_platforms.h"
|
#include "drivers/gles3/rasterizer_platforms.h"
|
||||||
#ifdef GLES3_BACKEND_ENABLED
|
#ifdef GLES3_BACKEND_ENABLED
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
#include "servers/rendering/shader_types.h"
|
#include "servers/rendering/shader_types.h"
|
||||||
#include "servers/rendering_server.h"
|
#include "servers/rendering_server.h"
|
||||||
|
|
||||||
class ShaderCompilerGLES3 {
|
class ShaderCompilerOLDGLES3 {
|
||||||
public:
|
public:
|
||||||
struct IdentifierActions {
|
struct IdentifierActions {
|
||||||
Map<StringName, Pair<int *, int>> render_mode_values;
|
Map<StringName, Pair<int *, int>> render_mode_values;
|
||||||
|
@ -98,7 +98,7 @@ private:
|
||||||
public:
|
public:
|
||||||
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
|
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
|
||||||
|
|
||||||
ShaderCompilerGLES3();
|
ShaderCompilerOLDGLES3();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLES3_BACKEND_ENABLED
|
#endif // GLES3_BACKEND_ENABLED
|
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,15 @@
|
||||||
#ifndef SHADER_OPENGL_H
|
#ifndef SHADER_OPENGL_H
|
||||||
#define SHADER_OPENGL_H
|
#define SHADER_OPENGL_H
|
||||||
|
|
||||||
|
#include "core/os/mutex.h"
|
||||||
|
#include "core/string/string_builder.h"
|
||||||
|
#include "core/templates/hash_map.h"
|
||||||
|
#include "core/templates/local_vector.h"
|
||||||
|
#include "core/templates/map.h"
|
||||||
|
#include "core/templates/rid_owner.h"
|
||||||
|
#include "core/variant/variant.h"
|
||||||
|
#include "servers/rendering_server.h"
|
||||||
|
|
||||||
#include "drivers/gles3/rasterizer_platforms.h"
|
#include "drivers/gles3/rasterizer_platforms.h"
|
||||||
#ifdef GLES3_BACKEND_ENABLED
|
#ifdef GLES3_BACKEND_ENABLED
|
||||||
|
|
||||||
|
@ -42,236 +51,187 @@
|
||||||
#include OPENGL_INCLUDE_H
|
#include OPENGL_INCLUDE_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "core/math/camera_matrix.h"
|
|
||||||
#include "core/templates/hash_map.h"
|
|
||||||
#include "core/templates/map.h"
|
|
||||||
#include "core/templates/pair.h"
|
|
||||||
#include "core/variant/variant.h"
|
|
||||||
#include "servers/rendering/shader_language.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
/**
|
||||||
class RasterizerStorageGLES3;
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
class ShaderGLES3 {
|
class ShaderGLES3 {
|
||||||
protected:
|
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 {
|
struct TexUnitPair {
|
||||||
const char *name;
|
const char *name;
|
||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool uniforms_dirty;
|
struct UBOPair {
|
||||||
|
const char *name;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Specialization {
|
||||||
|
const char *name;
|
||||||
|
bool defalut_value = false;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool valid = false;
|
//versions
|
||||||
|
CharString general_defines;
|
||||||
//@TODO Optimize to a fixed set of shader pools and use a LRU
|
|
||||||
int uniform_count;
|
|
||||||
int texunit_pair_count;
|
|
||||||
int conditional_count;
|
|
||||||
int vertex_code_start;
|
|
||||||
int fragment_code_start;
|
|
||||||
int attribute_pair_count;
|
|
||||||
|
|
||||||
struct CustomCode {
|
|
||||||
String vertex;
|
|
||||||
String vertex_globals;
|
|
||||||
String fragment;
|
|
||||||
String fragment_globals;
|
|
||||||
String light;
|
|
||||||
uint32_t version;
|
|
||||||
Vector<StringName> texture_uniforms;
|
|
||||||
Vector<StringName> custom_uniforms;
|
|
||||||
Vector<CharString> custom_defines;
|
|
||||||
Set<uint32_t> versions;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Version {
|
struct Version {
|
||||||
GLuint id;
|
Vector<StringName> texture_uniforms;
|
||||||
GLuint vert_id;
|
CharString uniforms;
|
||||||
GLuint frag_id;
|
CharString vertex_globals;
|
||||||
GLint *uniform_location;
|
CharString fragment_globals;
|
||||||
Vector<GLint> texture_uniform_locations;
|
Map<StringName, CharString> code_sections;
|
||||||
Map<StringName, GLint> custom_uniform_locations;
|
Vector<CharString> custom_defines;
|
||||||
uint32_t code_version;
|
|
||||||
bool ok;
|
|
||||||
Version() {
|
|
||||||
id = 0;
|
|
||||||
vert_id = 0;
|
|
||||||
frag_id = 0;
|
|
||||||
uniform_location = NULL;
|
|
||||||
code_version = 0;
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Version *version;
|
struct Specialization {
|
||||||
|
GLuint id;
|
||||||
union VersionKey {
|
GLuint vert_id;
|
||||||
struct {
|
GLuint frag_id;
|
||||||
uint32_t version;
|
LocalVector<GLint> uniform_location;
|
||||||
uint32_t code_version;
|
LocalVector<GLint> texture_uniform_locations;
|
||||||
|
Map<StringName, GLint> custom_uniform_locations;
|
||||||
|
bool build_queued = false;
|
||||||
|
bool ok = false;
|
||||||
|
Specialization() {
|
||||||
|
id = 0;
|
||||||
|
vert_id = 0;
|
||||||
|
frag_id = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
uint64_t key;
|
|
||||||
bool operator==(const VersionKey &p_key) const { return key == p_key.key; }
|
LocalVector<OAHashMap<uint64_t, Specialization>> variants;
|
||||||
bool operator<(const VersionKey &p_key) const { return key < p_key.key; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VersionKeyHash {
|
Mutex variant_set_mutex;
|
||||||
static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); }
|
|
||||||
|
void _compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization);
|
||||||
|
|
||||||
|
void _clear_version(Version *p_version);
|
||||||
|
void _initialize_version(Version *p_version);
|
||||||
|
|
||||||
|
RID_Owner<Version> version_owner;
|
||||||
|
|
||||||
|
struct StageTemplate {
|
||||||
|
struct Chunk {
|
||||||
|
enum Type {
|
||||||
|
TYPE_MATERIAL_UNIFORMS,
|
||||||
|
TYPE_VERTEX_GLOBALS,
|
||||||
|
TYPE_FRAGMENT_GLOBALS,
|
||||||
|
TYPE_CODE,
|
||||||
|
TYPE_TEXT
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
StringName code;
|
||||||
|
CharString text;
|
||||||
|
};
|
||||||
|
LocalVector<Chunk> chunks;
|
||||||
};
|
};
|
||||||
|
|
||||||
//this should use a way more cachefriendly version..
|
String name;
|
||||||
HashMap<VersionKey, Version, VersionKeyHash> version_map;
|
|
||||||
|
|
||||||
HashMap<uint32_t, CustomCode> custom_code_map;
|
String base_sha256;
|
||||||
uint32_t last_custom_code;
|
|
||||||
|
|
||||||
VersionKey conditional_version;
|
static String shader_cache_dir;
|
||||||
VersionKey new_conditional_version;
|
static bool shader_cache_cleanup_on_start;
|
||||||
|
static bool shader_cache_save_compressed;
|
||||||
|
static bool shader_cache_save_compressed_zstd;
|
||||||
|
static bool shader_cache_save_debug;
|
||||||
|
bool shader_cache_dir_valid = false;
|
||||||
|
|
||||||
virtual String get_shader_name() const = 0;
|
GLint max_image_units;
|
||||||
|
|
||||||
const char **conditional_defines;
|
enum StageType {
|
||||||
const char **uniform_names;
|
STAGE_TYPE_VERTEX,
|
||||||
const AttributePair *attribute_pairs;
|
STAGE_TYPE_FRAGMENT,
|
||||||
const TexUnitPair *texunit_pairs;
|
STAGE_TYPE_MAX,
|
||||||
const char *vertex_code;
|
};
|
||||||
const char *fragment_code;
|
|
||||||
CharString fragment_code0;
|
|
||||||
CharString fragment_code1;
|
|
||||||
CharString fragment_code2;
|
|
||||||
CharString fragment_code3;
|
|
||||||
|
|
||||||
CharString vertex_code0;
|
StageTemplate stage_templates[STAGE_TYPE_MAX];
|
||||||
CharString vertex_code1;
|
|
||||||
CharString vertex_code2;
|
|
||||||
|
|
||||||
Vector<CharString> custom_defines;
|
void _build_variant_code(StringBuilder &p_builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization);
|
||||||
|
|
||||||
Version *get_current_version();
|
void _add_stage(const char *p_code, StageType p_stage_type);
|
||||||
|
|
||||||
static ShaderGLES3 *active;
|
String _version_get_sha1(Version *p_version) const;
|
||||||
|
bool _load_from_cache(Version *p_version);
|
||||||
|
void _save_to_cache(Version *p_version);
|
||||||
|
|
||||||
int max_image_units;
|
const char **uniform_names = nullptr;
|
||||||
|
int uniform_count = 0;
|
||||||
|
const UBOPair *ubo_pairs = nullptr;
|
||||||
|
int ubo_count = 0;
|
||||||
|
const TexUnitPair *texunit_pairs = nullptr;
|
||||||
|
int texunit_pair_count = 0;
|
||||||
|
int specialization_count = 0;
|
||||||
|
const Specialization *specializations = nullptr;
|
||||||
|
uint64_t specialization_default_mask = 0;
|
||||||
|
const char **variant_defines = nullptr;
|
||||||
|
int variant_count = 0;
|
||||||
|
|
||||||
Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values;
|
int base_texture_index = 0;
|
||||||
|
|
||||||
protected:
|
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 char *p_vertex_code,
|
|
||||||
const char *p_fragment_code,
|
|
||||||
int p_vertex_code_start,
|
|
||||||
int p_fragment_code_start);
|
|
||||||
|
|
||||||
ShaderGLES3();
|
ShaderGLES3();
|
||||||
|
void _setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants);
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void _version_bind_shader(RID p_version, int p_variant, uint64_t p_specialization) {
|
||||||
|
ERR_FAIL_INDEX(p_variant, variant_count);
|
||||||
|
|
||||||
|
Version *version = version_owner.get_or_null(p_version);
|
||||||
|
ERR_FAIL_COND(!version);
|
||||||
|
|
||||||
|
if (version->variants.size() == 0) {
|
||||||
|
_initialize_version(version); //may lack initialization
|
||||||
|
}
|
||||||
|
|
||||||
|
Version::Specialization *spec = version->variants[p_variant].lookup_ptr(p_specialization);
|
||||||
|
if (!spec) {
|
||||||
|
if (false) {
|
||||||
|
// Queue load this specialization and use defaults in the meantime (TODO)
|
||||||
|
|
||||||
|
spec = version->variants[p_variant].lookup_ptr(specialization_default_mask);
|
||||||
|
} else {
|
||||||
|
// Compile on the spot
|
||||||
|
Version::Specialization s;
|
||||||
|
_compile_specialization(s, p_variant, version, p_specialization);
|
||||||
|
version->variants[p_variant].insert(p_specialization, s);
|
||||||
|
spec = version->variants[p_variant].lookup_ptr(p_specialization);
|
||||||
|
}
|
||||||
|
} else if (spec->build_queued) {
|
||||||
|
// Still queued, wait
|
||||||
|
spec = version->variants[p_variant].lookup_ptr(specialization_default_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!spec); // Should never happen
|
||||||
|
ERR_FAIL_COND(!spec->ok); // Should never happen
|
||||||
|
|
||||||
|
glUseProgram(spec->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void _init() = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
RID version_create();
|
||||||
CUSTOM_SHADER_DISABLED = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
GLint get_uniform_location(const String &p_name) const;
|
void version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize = false);
|
||||||
GLint get_uniform_location(int p_index) const;
|
|
||||||
|
|
||||||
static _FORCE_INLINE_ ShaderGLES3 *get_active() { return active; }
|
bool version_is_valid(RID p_version);
|
||||||
bool bind();
|
|
||||||
void unbind();
|
|
||||||
|
|
||||||
inline GLuint get_program() const { return version ? version->id : 0; }
|
bool version_free(RID p_version);
|
||||||
|
|
||||||
void clear_caches();
|
static void set_shader_cache_dir(const String &p_dir);
|
||||||
|
static void set_shader_cache_save_compressed(bool p_enable);
|
||||||
|
static void set_shader_cache_save_compressed_zstd(bool p_enable);
|
||||||
|
static void set_shader_cache_save_debug(bool p_enable);
|
||||||
|
|
||||||
uint32_t create_custom_shader();
|
RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version);
|
||||||
void set_custom_shader_code(uint32_t p_code_id,
|
|
||||||
const String &p_vertex,
|
|
||||||
const String &p_vertex_globals,
|
|
||||||
const String &p_fragment,
|
|
||||||
const String &p_light,
|
|
||||||
const String &p_fragment_globals,
|
|
||||||
const Vector<StringName> &p_uniforms,
|
|
||||||
const Vector<StringName> &p_texture_uniforms,
|
|
||||||
const Vector<CharString> &p_custom_defines);
|
|
||||||
|
|
||||||
void set_custom_shader(uint32_t p_code_id);
|
|
||||||
void free_custom_shader(uint32_t p_code_id);
|
|
||||||
|
|
||||||
uint32_t get_version_key() const { return conditional_version.version; }
|
|
||||||
|
|
||||||
// this void* is actually a RasterizerStorageGLES3::Material, but C++ doesn't
|
|
||||||
// like forward declared nested classes.
|
|
||||||
void use_material(void *p_material);
|
|
||||||
|
|
||||||
_FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
|
|
||||||
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
|
|
||||||
|
|
||||||
virtual void init() = 0;
|
|
||||||
void finish();
|
|
||||||
|
|
||||||
void add_custom_define(const String &p_define) {
|
|
||||||
custom_defines.push_back(p_define.utf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_custom_defines(Vector<String> *p_defines) {
|
|
||||||
for (int i = 0; i < custom_defines.size(); i++) {
|
|
||||||
p_defines->push_back(custom_defines[i].get_data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_custom_define(const String &p_define) {
|
|
||||||
custom_defines.erase(p_define.utf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void initialize(const String &p_general_defines = "", int p_base_texture_index = 0);
|
||||||
virtual ~ShaderGLES3();
|
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 // GLES3_BACKEND_ENABLED
|
|
||||||
|
|
||||||
#endif // SHADER_OPENGL_H
|
#endif // SHADER_OPENGL_H
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,277 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* shader_gles3.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||||
|
/* */
|
||||||
|
/* 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_OLD_OPENGL_H
|
||||||
|
#define SHADER_OLD_OPENGL_H
|
||||||
|
|
||||||
|
#include "drivers/gles3/rasterizer_platforms.h"
|
||||||
|
#ifdef GLES3_BACKEND_ENABLED
|
||||||
|
|
||||||
|
// This must come first to avoid windows.h mess
|
||||||
|
#include "platform_config.h"
|
||||||
|
#ifndef OPENGL_INCLUDE_H
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#else
|
||||||
|
#include OPENGL_INCLUDE_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "core/math/camera_matrix.h"
|
||||||
|
#include "core/templates/hash_map.h"
|
||||||
|
#include "core/templates/map.h"
|
||||||
|
#include "core/templates/pair.h"
|
||||||
|
#include "core/variant/variant.h"
|
||||||
|
#include "servers/rendering/shader_language.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class RasterizerStorageGLES3;
|
||||||
|
|
||||||
|
class ShaderOLDGLES3 {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool uniforms_dirty;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
//@TODO Optimize to a fixed set of shader pools and use a LRU
|
||||||
|
int uniform_count;
|
||||||
|
int texunit_pair_count;
|
||||||
|
int conditional_count;
|
||||||
|
int vertex_code_start;
|
||||||
|
int fragment_code_start;
|
||||||
|
int attribute_pair_count;
|
||||||
|
|
||||||
|
struct CustomCode {
|
||||||
|
String vertex;
|
||||||
|
String vertex_globals;
|
||||||
|
String fragment;
|
||||||
|
String fragment_globals;
|
||||||
|
String light;
|
||||||
|
uint32_t version;
|
||||||
|
Vector<StringName> texture_uniforms;
|
||||||
|
Vector<StringName> custom_uniforms;
|
||||||
|
Vector<CharString> custom_defines;
|
||||||
|
Set<uint32_t> versions;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Version {
|
||||||
|
GLuint id;
|
||||||
|
GLuint vert_id;
|
||||||
|
GLuint frag_id;
|
||||||
|
GLint *uniform_location;
|
||||||
|
Vector<GLint> texture_uniform_locations;
|
||||||
|
Map<StringName, GLint> custom_uniform_locations;
|
||||||
|
uint32_t code_version;
|
||||||
|
bool ok;
|
||||||
|
Version() {
|
||||||
|
id = 0;
|
||||||
|
vert_id = 0;
|
||||||
|
frag_id = 0;
|
||||||
|
uniform_location = NULL;
|
||||||
|
code_version = 0;
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 HashMapHasherDefault::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 char *vertex_code;
|
||||||
|
const char *fragment_code;
|
||||||
|
CharString fragment_code0;
|
||||||
|
CharString fragment_code1;
|
||||||
|
CharString fragment_code2;
|
||||||
|
CharString fragment_code3;
|
||||||
|
|
||||||
|
CharString vertex_code0;
|
||||||
|
CharString vertex_code1;
|
||||||
|
CharString vertex_code2;
|
||||||
|
|
||||||
|
Vector<CharString> custom_defines;
|
||||||
|
|
||||||
|
Version *get_current_version();
|
||||||
|
|
||||||
|
static ShaderOLDGLES3 *active;
|
||||||
|
|
||||||
|
int max_image_units;
|
||||||
|
|
||||||
|
Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values;
|
||||||
|
|
||||||
|
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 char *p_vertex_code,
|
||||||
|
const char *p_fragment_code,
|
||||||
|
int p_vertex_code_start,
|
||||||
|
int p_fragment_code_start);
|
||||||
|
|
||||||
|
ShaderOLDGLES3();
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
CUSTOM_SHADER_DISABLED = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
GLint get_uniform_location(const String &p_name) const;
|
||||||
|
GLint get_uniform_location(int p_index) const;
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ ShaderOLDGLES3 *get_active() { return active; }
|
||||||
|
bool bind();
|
||||||
|
void unbind();
|
||||||
|
|
||||||
|
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_code_id,
|
||||||
|
const String &p_vertex,
|
||||||
|
const String &p_vertex_globals,
|
||||||
|
const String &p_fragment,
|
||||||
|
const String &p_light,
|
||||||
|
const String &p_fragment_globals,
|
||||||
|
const Vector<StringName> &p_uniforms,
|
||||||
|
const Vector<StringName> &p_texture_uniforms,
|
||||||
|
const Vector<CharString> &p_custom_defines);
|
||||||
|
|
||||||
|
void set_custom_shader(uint32_t p_code_id);
|
||||||
|
void free_custom_shader(uint32_t p_code_id);
|
||||||
|
|
||||||
|
uint32_t get_version_key() const { return conditional_version.version; }
|
||||||
|
|
||||||
|
// this void* is actually a RasterizerStorageGLES3::Material, but C++ doesn't
|
||||||
|
// like forward declared nested classes.
|
||||||
|
void use_material(void *p_material);
|
||||||
|
|
||||||
|
_FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
|
||||||
|
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
|
||||||
|
|
||||||
|
virtual void init() = 0;
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
void add_custom_define(const String &p_define) {
|
||||||
|
custom_defines.push_back(p_define.utf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_custom_defines(Vector<String> *p_defines) {
|
||||||
|
for (int i = 0; i < custom_defines.size(); i++) {
|
||||||
|
p_defines->push_back(custom_defines[i].get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_custom_define(const String &p_define) {
|
||||||
|
custom_defines.erase(p_define.utf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ShaderOLDGLES3();
|
||||||
|
};
|
||||||
|
|
||||||
|
// called a lot, made inline
|
||||||
|
|
||||||
|
int ShaderOLDGLES3::_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 ShaderOLDGLES3::_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 // GLES3_BACKEND_ENABLED
|
||||||
|
|
||||||
|
#endif // SHADER_OPENGL_H
|
|
@ -3,12 +3,15 @@
|
||||||
Import("env")
|
Import("env")
|
||||||
|
|
||||||
if "GLES3_GLSL" in env["BUILDERS"]:
|
if "GLES3_GLSL" in env["BUILDERS"]:
|
||||||
env.GLES3_GLSL("copy.glsl")
|
|
||||||
env.GLES3_GLSL("canvas.glsl")
|
env.GLES3_GLSL("canvas.glsl")
|
||||||
env.GLES3_GLSL("canvas_shadow.glsl")
|
|
||||||
env.GLES3_GLSL("scene.glsl")
|
if "GLES3_OLD_GLSL" in env["BUILDERS"]:
|
||||||
env.GLES3_GLSL("cubemap_filter.glsl")
|
env.GLES3_OLD_GLSL("copy.glsl")
|
||||||
env.GLES3_GLSL("cube_to_dp.glsl")
|
env.GLES3_OLD_GLSL("canvas_old.glsl")
|
||||||
env.GLES3_GLSL("effect_blur.glsl")
|
env.GLES3_OLD_GLSL("canvas_shadow.glsl")
|
||||||
env.GLES3_GLSL("tonemap.glsl")
|
env.GLES3_OLD_GLSL("scene.glsl")
|
||||||
env.GLES3_GLSL("lens_distorted.glsl")
|
env.GLES3_OLD_GLSL("cubemap_filter.glsl")
|
||||||
|
env.GLES3_OLD_GLSL("cube_to_dp.glsl")
|
||||||
|
env.GLES3_OLD_GLSL("effect_blur.glsl")
|
||||||
|
env.GLES3_OLD_GLSL("tonemap.glsl")
|
||||||
|
env.GLES3_OLD_GLSL("lens_distorted.glsl")
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,665 @@
|
||||||
|
/* clang-format off */
|
||||||
|
[vertex]
|
||||||
|
|
||||||
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
#define lowp
|
||||||
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
precision highp float;
|
||||||
|
precision highp int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform highp mat4 projection_matrix;
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
uniform highp mat4 modelview_matrix;
|
||||||
|
uniform highp mat4 extra_matrix;
|
||||||
|
layout(location = 0) in highp vec2 vertex;
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_LIGHT_ANGLE
|
||||||
|
// shared with tangent, not used in canvas shader
|
||||||
|
layout(location = 2) in highp float light_angle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layout(location = 3) in vec4 color_attrib;
|
||||||
|
layout(location = 4) in vec2 uv_attrib;
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_MODULATE
|
||||||
|
layout(location = 5) in highp vec4 modulate_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_LARGE_VERTEX
|
||||||
|
// shared with skeleton attributes, not used in batched shader
|
||||||
|
layout(location = 6) in highp vec2 translate_attrib;
|
||||||
|
layout(location = 7) in highp vec4 basis_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SKELETON
|
||||||
|
layout(location = 6) in highp vec4 bone_indices;
|
||||||
|
layout(location = 7) in highp vec4 bone_weights;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_INSTANCING
|
||||||
|
|
||||||
|
layout(location = 8) in highp vec4 instance_xform0;
|
||||||
|
layout(location = 9) in highp vec4 instance_xform1;
|
||||||
|
layout(location = 10) in highp vec4 instance_xform2;
|
||||||
|
layout(location = 11) in highp vec4 instance_color;
|
||||||
|
|
||||||
|
#ifdef USE_INSTANCE_CUSTOM
|
||||||
|
layout(location = 12) in highp vec4 instance_custom_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SKELETON
|
||||||
|
uniform highp sampler2D skeleton_texture; // texunit:-3
|
||||||
|
uniform highp ivec2 skeleton_texture_size;
|
||||||
|
uniform highp mat4 skeleton_transform;
|
||||||
|
uniform highp mat4 skeleton_transform_inverse;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out vec2 uv_interp;
|
||||||
|
out vec4 color_interp;
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_MODULATE
|
||||||
|
// modulate doesn't need interpolating but we need to send it to the fragment shader
|
||||||
|
flat out vec4 modulate_interp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODULATE_USED
|
||||||
|
uniform vec4 final_modulate;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform highp vec2 color_texpixel_size;
|
||||||
|
|
||||||
|
#ifdef USE_TEXTURE_RECT
|
||||||
|
|
||||||
|
uniform vec4 dst_rect;
|
||||||
|
uniform vec4 src_rect;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform highp float time;
|
||||||
|
|
||||||
|
#ifdef USE_LIGHTING
|
||||||
|
|
||||||
|
// light matrices
|
||||||
|
uniform highp mat4 light_matrix;
|
||||||
|
uniform highp mat4 light_matrix_inverse;
|
||||||
|
uniform highp mat4 light_local_matrix;
|
||||||
|
uniform highp mat4 shadow_matrix;
|
||||||
|
uniform highp vec4 light_color;
|
||||||
|
uniform highp vec4 light_shadow_color;
|
||||||
|
uniform highp vec2 light_pos;
|
||||||
|
uniform highp float shadowpixel_size;
|
||||||
|
uniform highp float shadow_gradient;
|
||||||
|
uniform highp float light_height;
|
||||||
|
uniform highp float light_outside_alpha;
|
||||||
|
uniform highp float shadow_distance_mult;
|
||||||
|
|
||||||
|
out vec4 light_uv_interp;
|
||||||
|
out vec2 transformed_light_uv;
|
||||||
|
out vec4 local_rot;
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
out highp vec2 pos;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const bool at_light_pass = true;
|
||||||
|
#else
|
||||||
|
const bool at_light_pass = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
VERTEX_SHADER_GLOBALS
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
vec2 select(vec2 a, vec2 b, bvec2 c) {
|
||||||
|
vec2 ret;
|
||||||
|
|
||||||
|
ret.x = c.x ? b.x : a.x;
|
||||||
|
ret.y = c.y ? b.y : a.y;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = color_attrib;
|
||||||
|
vec2 uv;
|
||||||
|
|
||||||
|
#ifdef USE_INSTANCING
|
||||||
|
mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
|
||||||
|
color *= instance_color;
|
||||||
|
|
||||||
|
#ifdef USE_INSTANCE_CUSTOM
|
||||||
|
vec4 instance_custom = instance_custom_data;
|
||||||
|
#else
|
||||||
|
vec4 instance_custom = vec4(0.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
mat4 extra_matrix_instance = extra_matrix;
|
||||||
|
vec4 instance_custom = vec4(0.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TEXTURE_RECT
|
||||||
|
|
||||||
|
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
|
||||||
|
uv = src_rect.xy + abs(src_rect.zw) * vertex.yx;
|
||||||
|
} else {
|
||||||
|
uv = src_rect.xy + abs(src_rect.zw) * vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// This is what is done in the GLES 3 bindings and should
|
||||||
|
// take care of flipped rects.
|
||||||
|
//
|
||||||
|
// But it doesn't.
|
||||||
|
// I don't know why, will need to investigate further.
|
||||||
|
|
||||||
|
outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0)));
|
||||||
|
|
||||||
|
// outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex;
|
||||||
|
#else
|
||||||
|
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
|
||||||
|
|
||||||
|
uv = uv_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float point_size = 1.0;
|
||||||
|
|
||||||
|
{
|
||||||
|
vec2 src_vtx = outvec.xy;
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
VERTEX_SHADER_CODE
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_PointSize = point_size;
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_MODULATE
|
||||||
|
// modulate doesn't need interpolating but we need to send it to the fragment shader
|
||||||
|
modulate_interp = modulate_attrib;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_LARGE_VERTEX
|
||||||
|
// transform is in attributes
|
||||||
|
vec2 temp;
|
||||||
|
|
||||||
|
temp = outvec.xy;
|
||||||
|
temp.x = (outvec.x * basis_attrib.x) + (outvec.y * basis_attrib.z);
|
||||||
|
temp.y = (outvec.x * basis_attrib.y) + (outvec.y * basis_attrib.w);
|
||||||
|
|
||||||
|
temp += translate_attrib;
|
||||||
|
outvec.xy = temp;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// transform is in uniforms
|
||||||
|
#if !defined(SKIP_TRANSFORM_USED)
|
||||||
|
outvec = extra_matrix_instance * outvec;
|
||||||
|
outvec = modelview_matrix * outvec;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // not large integer
|
||||||
|
|
||||||
|
color_interp = color;
|
||||||
|
|
||||||
|
#ifdef USE_PIXEL_SNAP
|
||||||
|
outvec.xy = floor(outvec + 0.5).xy;
|
||||||
|
// precision issue on some hardware creates artifacts within texture
|
||||||
|
// offset uv by a small amount to avoid
|
||||||
|
uv += 1e-5;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SKELETON
|
||||||
|
|
||||||
|
// look up transform from the "pose texture"
|
||||||
|
if (bone_weights != vec4(0.0)) {
|
||||||
|
highp mat4 bone_transform = mat4(0.0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
ivec2 tex_ofs = ivec2(int(bone_indices[i]) * 2, 0);
|
||||||
|
|
||||||
|
highp mat4 b = mat4(
|
||||||
|
texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(0, 0)),
|
||||||
|
texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(1, 0)),
|
||||||
|
vec4(0.0, 0.0, 1.0, 0.0),
|
||||||
|
vec4(0.0, 0.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
bone_transform += b * bone_weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 bone_matrix = skeleton_transform * transpose(bone_transform) * skeleton_transform_inverse;
|
||||||
|
|
||||||
|
outvec = bone_matrix * outvec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uv_interp = uv;
|
||||||
|
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;
|
||||||
|
|
||||||
|
transformed_light_uv = (mat3(light_matrix_inverse) * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
pos = outvec.xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_LIGHT_ANGLE
|
||||||
|
// we add a fixed offset because we are using the sign later,
|
||||||
|
// and don't want floating point error around 0.0
|
||||||
|
float la = abs(light_angle) - 1.0;
|
||||||
|
|
||||||
|
// vector light angle
|
||||||
|
vec4 vla;
|
||||||
|
vla.xy = vec2(cos(la), sin(la));
|
||||||
|
vla.zw = vec2(-vla.y, vla.x);
|
||||||
|
|
||||||
|
// vertical flip encoded in the sign
|
||||||
|
vla.zw *= sign(light_angle);
|
||||||
|
|
||||||
|
// apply the transform matrix.
|
||||||
|
// The rotate will be encoded in the transform matrix for single rects,
|
||||||
|
// and just the flips in the light angle.
|
||||||
|
// For batching we will encode the rotation and the flips
|
||||||
|
// in the light angle, and can use the same shader.
|
||||||
|
local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.xy, 0.0, 0.0))).xy);
|
||||||
|
local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.zw, 0.0, 0.0))).xy);
|
||||||
|
#else
|
||||||
|
local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(1.0, 0.0, 0.0, 0.0))).xy);
|
||||||
|
local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * 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 // not using light angle
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
[fragment]
|
||||||
|
|
||||||
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
#define lowp
|
||||||
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
#if defined(USE_HIGHP_PRECISION)
|
||||||
|
precision highp float;
|
||||||
|
precision highp int;
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform sampler2D color_texture; // texunit:-1
|
||||||
|
/* clang-format on */
|
||||||
|
uniform highp vec2 color_texpixel_size;
|
||||||
|
uniform mediump sampler2D normal_texture; // texunit:-2
|
||||||
|
|
||||||
|
in mediump vec2 uv_interp;
|
||||||
|
in mediump vec4 color_interp;
|
||||||
|
|
||||||
|
#ifdef USE_ATTRIB_MODULATE
|
||||||
|
in mediump vec4 modulate_interp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform highp float time;
|
||||||
|
|
||||||
|
uniform vec4 final_modulate;
|
||||||
|
|
||||||
|
#ifdef SCREEN_TEXTURE_USED
|
||||||
|
|
||||||
|
uniform sampler2D screen_texture; // texunit:-4
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SCREEN_UV_USED
|
||||||
|
|
||||||
|
uniform vec2 screen_pixel_size;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_LIGHTING
|
||||||
|
|
||||||
|
uniform highp mat4 light_matrix;
|
||||||
|
uniform highp mat4 light_local_matrix;
|
||||||
|
uniform highp mat4 shadow_matrix;
|
||||||
|
uniform highp vec4 light_color;
|
||||||
|
uniform highp vec4 light_shadow_color;
|
||||||
|
uniform highp vec2 light_pos;
|
||||||
|
uniform highp float shadowpixel_size;
|
||||||
|
uniform highp float shadow_gradient;
|
||||||
|
uniform highp float light_height;
|
||||||
|
uniform highp float light_outside_alpha;
|
||||||
|
uniform highp float shadow_distance_mult;
|
||||||
|
|
||||||
|
uniform lowp sampler2D light_texture; // texunit:-6
|
||||||
|
in vec4 light_uv_interp;
|
||||||
|
in vec2 transformed_light_uv;
|
||||||
|
|
||||||
|
in vec4 local_rot;
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
|
||||||
|
uniform highp sampler2D shadow_texture; // texunit:-5
|
||||||
|
in highp vec2 pos;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const bool at_light_pass = true;
|
||||||
|
#else
|
||||||
|
const bool at_light_pass = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool use_default_normal;
|
||||||
|
|
||||||
|
layout(location = 0) out mediump vec4 frag_color;
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
FRAGMENT_SHADER_GLOBALS
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
void light_compute(
|
||||||
|
inout vec4 light,
|
||||||
|
inout vec2 light_vec,
|
||||||
|
inout float light_height,
|
||||||
|
inout vec4 light_color,
|
||||||
|
vec2 light_uv,
|
||||||
|
inout vec4 shadow_color,
|
||||||
|
inout vec2 shadow_vec,
|
||||||
|
vec3 normal,
|
||||||
|
vec2 uv,
|
||||||
|
#if defined(SCREEN_UV_USED)
|
||||||
|
vec2 screen_uv,
|
||||||
|
#endif
|
||||||
|
vec4 color) {
|
||||||
|
|
||||||
|
#if defined(USE_LIGHT_SHADER_CODE)
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
LIGHT_SHADER_CODE
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = color_interp;
|
||||||
|
vec2 uv = uv_interp;
|
||||||
|
#ifdef USE_FORCE_REPEAT
|
||||||
|
//needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that don't support it
|
||||||
|
uv = mod(uv, vec2(1.0, 1.0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(COLOR_USED)
|
||||||
|
//default behavior, texture by color
|
||||||
|
color *= texture(color_texture, uv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SCREEN_UV_USED
|
||||||
|
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 normal;
|
||||||
|
|
||||||
|
#if defined(NORMAL_USED)
|
||||||
|
|
||||||
|
bool normal_used = true;
|
||||||
|
#else
|
||||||
|
bool normal_used = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (use_default_normal) {
|
||||||
|
normal.xy = texture(normal_texture, uv).xy * 2.0 - 1.0;
|
||||||
|
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
|
||||||
|
normal_used = true;
|
||||||
|
} else {
|
||||||
|
normal = vec3(0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
float normal_depth = 1.0;
|
||||||
|
|
||||||
|
#if defined(NORMALMAP_USED)
|
||||||
|
vec3 normal_map = vec3(0.0, 0.0, 1.0);
|
||||||
|
normal_used = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
FRAGMENT_SHADER_CODE
|
||||||
|
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
#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 USE_ATTRIB_MODULATE
|
||||||
|
color *= modulate_interp;
|
||||||
|
#else
|
||||||
|
#if !defined(MODULATE_USED)
|
||||||
|
color *= final_modulate;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_LIGHTING
|
||||||
|
|
||||||
|
vec2 light_vec = transformed_light_uv;
|
||||||
|
vec2 shadow_vec = transformed_light_uv;
|
||||||
|
|
||||||
|
if (normal_used) {
|
||||||
|
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
float att = 1.0;
|
||||||
|
|
||||||
|
vec2 light_uv = light_uv_interp.xy;
|
||||||
|
vec4 light = texture(light_texture, light_uv);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
float real_light_height = light_height;
|
||||||
|
vec4 real_light_color = light_color;
|
||||||
|
vec4 real_light_shadow_color = light_shadow_color;
|
||||||
|
|
||||||
|
#if defined(USE_LIGHT_SHADER_CODE)
|
||||||
|
//light is written by the light shader
|
||||||
|
light_compute(
|
||||||
|
light,
|
||||||
|
light_vec,
|
||||||
|
real_light_height,
|
||||||
|
real_light_color,
|
||||||
|
light_uv,
|
||||||
|
real_light_shadow_color,
|
||||||
|
shadow_vec,
|
||||||
|
normal,
|
||||||
|
uv,
|
||||||
|
#if defined(SCREEN_UV_USED)
|
||||||
|
screen_uv,
|
||||||
|
#endif
|
||||||
|
color);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
light *= real_light_color;
|
||||||
|
|
||||||
|
if (normal_used) {
|
||||||
|
vec3 light_normal = normalize(vec3(light_vec, -real_light_height));
|
||||||
|
light *= max(dot(-light_normal, normal), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color *= light;
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
|
||||||
|
#ifdef SHADOW_VEC_USED
|
||||||
|
mat3 inverse_light_matrix = mat3(light_matrix);
|
||||||
|
inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
|
||||||
|
inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
|
||||||
|
inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
|
||||||
|
shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy;
|
||||||
|
#else
|
||||||
|
shadow_vec = light_uv_interp.zw;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float angle_to_light = -atan(shadow_vec.x, shadow_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 = shadow_vec;
|
||||||
|
sh = 0.0 + (1.0 / 8.0);
|
||||||
|
} else if (abs_angle > 135.0 * PI / 180.0) {
|
||||||
|
point = -shadow_vec;
|
||||||
|
sh = 0.5 + (1.0 / 8.0);
|
||||||
|
} else if (angle_to_light > 0.0) {
|
||||||
|
point = vec2(shadow_vec.y, -shadow_vec.x);
|
||||||
|
sh = 0.25 + (1.0 / 8.0);
|
||||||
|
} else {
|
||||||
|
point = vec2(-shadow_vec.y, shadow_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(texture((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SHADOW_DEPTH(m_tex, m_uv) (texture((m_tex), (m_uv)).r)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHADOW_USE_GRADIENT
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
/* GLSL es 100 doesn't support line continuation characters(backslashes) */
|
||||||
|
#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); }
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHADOW_FILTER_NEAREST
|
||||||
|
|
||||||
|
SHADOW_TEST(su);
|
||||||
|
|
||||||
|
#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 * 2.0);
|
||||||
|
SHADOW_TEST(su + shadowpixel_size);
|
||||||
|
SHADOW_TEST(su);
|
||||||
|
SHADOW_TEST(su - shadowpixel_size);
|
||||||
|
SHADOW_TEST(su - shadowpixel_size * 2.0);
|
||||||
|
shadow_attenuation /= 5.0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHADOW_FILTER_PCF7
|
||||||
|
|
||||||
|
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 /= 7.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
|
||||||
|
|
||||||
|
//color *= shadow_attenuation;
|
||||||
|
color = mix(real_light_shadow_color, color, shadow_attenuation);
|
||||||
|
//use shadows
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//use lighting
|
||||||
|
#endif
|
||||||
|
|
||||||
|
frag_color = color;
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
|
||||||
|
#define MAX_LIGHTS_PER_ITEM 16
|
||||||
|
|
||||||
|
#define M_PI 3.14159265359
|
||||||
|
|
||||||
|
#define SDF_MAX_LENGTH 16384.0
|
||||||
|
|
||||||
|
//1 means enabled, 2+ means trails in use
|
||||||
|
#define FLAGS_INSTANCING_MASK 0x7F
|
||||||
|
#define FLAGS_INSTANCING_HAS_COLORS (1 << 7)
|
||||||
|
#define FLAGS_INSTANCING_HAS_CUSTOM_DATA (1 << 8)
|
||||||
|
|
||||||
|
#define FLAGS_CLIP_RECT_UV (1 << 9)
|
||||||
|
#define FLAGS_TRANSPOSE_RECT (1 << 10)
|
||||||
|
#define FLAGS_USING_LIGHT_MASK (1 << 11)
|
||||||
|
#define FLAGS_NINEPACH_DRAW_CENTER (1 << 12)
|
||||||
|
#define FLAGS_USING_PARTICLES (1 << 13)
|
||||||
|
|
||||||
|
#define FLAGS_NINEPATCH_H_MODE_SHIFT 16
|
||||||
|
#define FLAGS_NINEPATCH_V_MODE_SHIFT 18
|
||||||
|
|
||||||
|
#define FLAGS_LIGHT_COUNT_SHIFT 20
|
||||||
|
|
||||||
|
#define FLAGS_DEFAULT_NORMAL_MAP_USED (1 << 26)
|
||||||
|
#define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27)
|
||||||
|
|
||||||
|
#define FLAGS_USE_MSDF (1 << 28)
|
||||||
|
|
||||||
|
// must be always 128 bytes long
|
||||||
|
struct DrawData {
|
||||||
|
vec2 world_x;
|
||||||
|
vec2 world_y;
|
||||||
|
vec2 world_ofs;
|
||||||
|
uint flags;
|
||||||
|
uint specular_shininess;
|
||||||
|
#ifdef USE_PRIMITIVE
|
||||||
|
vec2 points[3];
|
||||||
|
vec2 uvs[3];
|
||||||
|
uint colors[6];
|
||||||
|
#else
|
||||||
|
vec4 modulation;
|
||||||
|
vec4 ninepatch_margins;
|
||||||
|
vec4 dst_rect; //for built-in rect and UV
|
||||||
|
vec4 src_rect;
|
||||||
|
vec2 pad;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
vec2 color_texture_pixel_size;
|
||||||
|
uint lights[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(std140) uniform GlobalVariableData { //ubo:1
|
||||||
|
vec4 global_variables[MAX_GLOBAL_VARIABLES];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform CanvasData { //ubo:0
|
||||||
|
mat4 canvas_transform;
|
||||||
|
mat4 screen_transform;
|
||||||
|
mat4 canvas_normal_transform;
|
||||||
|
vec4 canvas_modulation;
|
||||||
|
vec2 screen_pixel_size;
|
||||||
|
float time;
|
||||||
|
bool use_pixel_snap;
|
||||||
|
|
||||||
|
vec4 sdf_to_tex;
|
||||||
|
vec2 screen_to_sdf;
|
||||||
|
vec2 sdf_to_screen;
|
||||||
|
|
||||||
|
uint directional_light_count;
|
||||||
|
float tex_to_sdf;
|
||||||
|
uint pad1;
|
||||||
|
uint pad2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LIGHT_FLAGS_BLEND_MASK (3 << 16)
|
||||||
|
#define LIGHT_FLAGS_BLEND_MODE_ADD (0 << 16)
|
||||||
|
#define LIGHT_FLAGS_BLEND_MODE_SUB (1 << 16)
|
||||||
|
#define LIGHT_FLAGS_BLEND_MODE_MIX (2 << 16)
|
||||||
|
#define LIGHT_FLAGS_BLEND_MODE_MASK (3 << 16)
|
||||||
|
#define LIGHT_FLAGS_HAS_SHADOW (1 << 20)
|
||||||
|
#define LIGHT_FLAGS_FILTER_SHIFT 22
|
||||||
|
#define LIGHT_FLAGS_FILTER_MASK (3 << 22)
|
||||||
|
#define LIGHT_FLAGS_SHADOW_NEAREST (0 << 22)
|
||||||
|
#define LIGHT_FLAGS_SHADOW_PCF5 (1 << 22)
|
||||||
|
#define LIGHT_FLAGS_SHADOW_PCF13 (2 << 22)
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
mat2x4 texture_matrix; //light to texture coordinate matrix (transposed)
|
||||||
|
mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed)
|
||||||
|
vec4 color;
|
||||||
|
|
||||||
|
uint shadow_color; // packed
|
||||||
|
uint flags; //index to light texture
|
||||||
|
float shadow_pixel_size;
|
||||||
|
float height;
|
||||||
|
|
||||||
|
vec2 position;
|
||||||
|
float shadow_zfar_inv;
|
||||||
|
float shadow_y_ofs;
|
||||||
|
|
||||||
|
vec4 atlas_rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform LightData { //ubo:2
|
||||||
|
Light light_data[MAX_LIGHTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform DrawDataInstances { //ubo:3
|
||||||
|
|
||||||
|
DrawData draw_data[MAX_DRAW_DATA_INSTANCES];
|
||||||
|
};
|
|
@ -6,16 +6,12 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
|
||||||
from platform_methods import subprocess_main
|
from platform_methods import subprocess_main
|
||||||
|
|
||||||
|
|
||||||
class LegacyGLHeaderStruct:
|
class GLES3HeaderStruct:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.vertex_lines = []
|
self.vertex_lines = []
|
||||||
self.fragment_lines = []
|
self.fragment_lines = []
|
||||||
self.uniforms = []
|
self.uniforms = []
|
||||||
self.attributes = []
|
|
||||||
self.feedbacks = []
|
|
||||||
self.fbos = []
|
self.fbos = []
|
||||||
self.conditionals = []
|
|
||||||
self.enums = {}
|
|
||||||
self.texunits = []
|
self.texunits = []
|
||||||
self.texunit_names = []
|
self.texunit_names = []
|
||||||
self.ubos = []
|
self.ubos = []
|
||||||
|
@ -28,22 +24,65 @@ class LegacyGLHeaderStruct:
|
||||||
self.line_offset = 0
|
self.line_offset = 0
|
||||||
self.vertex_offset = 0
|
self.vertex_offset = 0
|
||||||
self.fragment_offset = 0
|
self.fragment_offset = 0
|
||||||
|
self.variant_defines=[]
|
||||||
|
self.variant_names=[]
|
||||||
|
self.specialization_names=[]
|
||||||
|
self.specialization_values=[]
|
||||||
|
|
||||||
|
|
||||||
def include_file_in_legacygl_header(filename, header_data, depth):
|
def include_file_in_gles3_header(filename, header_data, depth):
|
||||||
fs = open(filename, "r")
|
fs = open(filename, "r")
|
||||||
line = fs.readline()
|
line = fs.readline()
|
||||||
|
|
||||||
while line:
|
while line:
|
||||||
|
|
||||||
if line.find("[vertex]") != -1:
|
if line.find("=") != -1 and header_data.reading=="":
|
||||||
|
# Mode
|
||||||
|
eqpos = line.find("=")
|
||||||
|
defname = line[:eqpos].strip().upper()
|
||||||
|
define = line[eqpos+1:].strip()
|
||||||
|
header_data.variant_names.append( defname )
|
||||||
|
header_data.variant_defines.append( define )
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("=") != -1 and header_data.reading=="specializations":
|
||||||
|
# Specialization
|
||||||
|
eqpos = line.find("=")
|
||||||
|
specname = line[:eqpos].strip()
|
||||||
|
specvalue = line[eqpos+1:]
|
||||||
|
header_data.specialization_names.append( specname )
|
||||||
|
header_data.specialization_values.append( specvalue )
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("#[modes]") != -1:
|
||||||
|
# Nothing really, just skip
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
if line.find("#[specializations]") != -1:
|
||||||
|
header_data.reading = "specializations"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("#[vertex]") != -1:
|
||||||
header_data.reading = "vertex"
|
header_data.reading = "vertex"
|
||||||
line = fs.readline()
|
line = fs.readline()
|
||||||
header_data.line_offset += 1
|
header_data.line_offset += 1
|
||||||
header_data.vertex_offset = header_data.line_offset
|
header_data.vertex_offset = header_data.line_offset
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if line.find("[fragment]") != -1:
|
if line.find("#[fragment]") != -1:
|
||||||
header_data.reading = "fragment"
|
header_data.reading = "fragment"
|
||||||
line = fs.readline()
|
line = fs.readline()
|
||||||
header_data.line_offset += 1
|
header_data.line_offset += 1
|
||||||
|
@ -58,31 +97,15 @@ def include_file_in_legacygl_header(filename, header_data, depth):
|
||||||
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
||||||
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
||||||
header_data.vertex_included_files += [included_file]
|
header_data.vertex_included_files += [included_file]
|
||||||
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
||||||
header_data.fragment_included_files += [included_file]
|
header_data.fragment_included_files += [included_file]
|
||||||
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
|
||||||
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
|
||||||
line = fs.readline()
|
line = fs.readline()
|
||||||
|
|
||||||
if line.find("#ifdef ") != -1:
|
|
||||||
if line.find("#ifdef ") != -1:
|
|
||||||
ifdefline = line.replace("#ifdef ", "").strip()
|
|
||||||
|
|
||||||
if line.find("_EN_") != -1:
|
|
||||||
enumbase = ifdefline[: ifdefline.find("_EN_")]
|
|
||||||
ifdefline = ifdefline.replace("_EN_", "_")
|
|
||||||
line = line.replace("_EN_", "_")
|
|
||||||
if enumbase not in header_data.enums:
|
|
||||||
header_data.enums[enumbase] = []
|
|
||||||
if ifdefline not in header_data.enums[enumbase]:
|
|
||||||
header_data.enums[enumbase].append(ifdefline)
|
|
||||||
|
|
||||||
elif not ifdefline in header_data.conditionals:
|
|
||||||
header_data.conditionals += [ifdefline]
|
|
||||||
|
|
||||||
if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
|
if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
|
||||||
# texture unit
|
# texture unit
|
||||||
texunitstr = line[line.find(":") + 1 :].strip()
|
texunitstr = line[line.find(":") + 1 :].strip()
|
||||||
|
@ -144,33 +167,6 @@ def include_file_in_legacygl_header(filename, header_data, depth):
|
||||||
if not x in header_data.uniforms:
|
if not x in header_data.uniforms:
|
||||||
header_data.uniforms += [x]
|
header_data.uniforms += [x]
|
||||||
|
|
||||||
if line.strip().find("attribute ") == 0 and line.find("attrib:") != -1:
|
|
||||||
uline = line.replace("in ", "")
|
|
||||||
uline = uline.replace("attribute ", "")
|
|
||||||
uline = uline.replace("highp ", "")
|
|
||||||
uline = uline.replace(";", "")
|
|
||||||
uline = uline[uline.find(" ") :].strip()
|
|
||||||
|
|
||||||
if uline.find("//") != -1:
|
|
||||||
name, bind = uline.split("//")
|
|
||||||
if bind.find("attrib:") != -1:
|
|
||||||
name = name.strip()
|
|
||||||
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("\r", "")
|
||||||
line = line.replace("\n", "")
|
line = line.replace("\n", "")
|
||||||
|
|
||||||
|
@ -187,12 +183,14 @@ def include_file_in_legacygl_header(filename, header_data, depth):
|
||||||
return header_data
|
return header_data
|
||||||
|
|
||||||
|
|
||||||
def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
def build_gles3_header(filename, include, class_suffix, output_attribs):
|
||||||
header_data = LegacyGLHeaderStruct()
|
header_data = GLES3HeaderStruct()
|
||||||
include_file_in_legacygl_header(filename, header_data, 0)
|
include_file_in_gles3_header(filename, header_data, 0)
|
||||||
|
|
||||||
out_file = filename + ".gen.h"
|
out_file = filename + ".gen.h"
|
||||||
fd = open(out_file, "w")
|
fd = open(out_file, "w")
|
||||||
|
defspec = 0
|
||||||
|
defvariant = ""
|
||||||
|
|
||||||
enum_constants = []
|
enum_constants = []
|
||||||
|
|
||||||
|
@ -202,8 +200,8 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
||||||
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
||||||
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
||||||
fd.write("#ifndef " + out_file_ifdef + class_suffix + "_120\n")
|
fd.write("#ifndef " + out_file_ifdef + class_suffix + "_GLES3\n")
|
||||||
fd.write("#define " + out_file_ifdef + class_suffix + "_120\n")
|
fd.write("#define " + out_file_ifdef + class_suffix + "_GLES3\n")
|
||||||
|
|
||||||
out_file_class = (
|
out_file_class = (
|
||||||
out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
|
out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
|
||||||
|
@ -211,27 +209,42 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
fd.write("\n\n")
|
fd.write("\n\n")
|
||||||
fd.write('#include "' + include + '"\n\n\n')
|
fd.write('#include "' + include + '"\n\n\n')
|
||||||
fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n")
|
fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n")
|
||||||
fd.write('\t virtual String get_shader_name() const { return "' + out_file_class + '"; }\n')
|
|
||||||
|
|
||||||
fd.write("public:\n\n")
|
fd.write("public:\n\n")
|
||||||
|
|
||||||
if header_data.conditionals:
|
|
||||||
fd.write("\tenum Conditionals {\n")
|
|
||||||
for x in header_data.conditionals:
|
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
|
||||||
fd.write("\t};\n\n")
|
|
||||||
|
|
||||||
if header_data.uniforms:
|
if header_data.uniforms:
|
||||||
fd.write("\tenum Uniforms {\n")
|
fd.write("\tenum Uniforms {\n")
|
||||||
for x in header_data.uniforms:
|
for x in header_data.uniforms:
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
fd.write("\t\t" + x.upper() + ",\n")
|
||||||
fd.write("\t};\n\n")
|
fd.write("\t};\n\n")
|
||||||
|
|
||||||
|
if header_data.variant_names:
|
||||||
|
fd.write("\tenum ShaderVariant {\n")
|
||||||
|
for x in header_data.variant_names:
|
||||||
|
fd.write("\t\t" + x + ",\n")
|
||||||
|
fd.write("\t};\n\n")
|
||||||
|
else:
|
||||||
|
fd.write("\tenum ShaderVariant { DEFAULT };\n\n")
|
||||||
|
defvariant="=DEFAULT"
|
||||||
|
|
||||||
|
if header_data.specialization_names:
|
||||||
|
fd.write("\tenum Specializations {\n")
|
||||||
|
counter=0
|
||||||
|
for x in header_data.specialization_names:
|
||||||
|
fd.write("\t\t" + x.upper() + "=" + str(1<<counter)+",\n")
|
||||||
|
counter+=1
|
||||||
|
fd.write("\t};\n\n")
|
||||||
|
|
||||||
|
for i in range(len(header_data.specialization_names)):
|
||||||
|
defval = header_data.specialization_values[i].strip()
|
||||||
|
if (defval.upper() == "TRUE" or defval=="1"):
|
||||||
|
defspec|=(1<<i)
|
||||||
|
|
||||||
fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n")
|
fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n")
|
||||||
if header_data.conditionals:
|
|
||||||
fd.write(
|
fd.write(
|
||||||
"\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n"
|
"\t_FORCE_INLINE_ void version_bind_shader(RID p_version,ShaderVariant p_variant"+defvariant+",uint64_t p_specialization="+str(defspec)+") { _version_bind_shader(p_version,p_variant,p_specialization); }\n\n"
|
||||||
)
|
)
|
||||||
fd.write("\t#ifdef DEBUG_ENABLED\n ")
|
fd.write("\t#ifdef DEBUG_ENABLED\n ")
|
||||||
fd.write(
|
fd.write(
|
||||||
"\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n "
|
"\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n "
|
||||||
|
@ -368,64 +381,9 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
|
|
||||||
fd.write("\n\n#undef _FU\n\n\n")
|
fd.write("\n\n#undef _FU\n\n\n")
|
||||||
|
|
||||||
fd.write("\tvirtual void init() {\n\n")
|
fd.write("protected:\n\n")
|
||||||
|
|
||||||
enum_value_count = 0
|
fd.write("\tvirtual void _init() override {\n\n")
|
||||||
|
|
||||||
if header_data.enums:
|
|
||||||
|
|
||||||
fd.write("\t\t//Written using math, given nonstandarity of 64 bits integer constants..\n")
|
|
||||||
fd.write("\t\tstatic const Enum _enums[]={\n")
|
|
||||||
|
|
||||||
bitofs = len(header_data.conditionals)
|
|
||||||
enum_vals = []
|
|
||||||
|
|
||||||
for xv in header_data.enums:
|
|
||||||
x = header_data.enums[xv]
|
|
||||||
bits = 1
|
|
||||||
amt = len(x)
|
|
||||||
while 2 ** bits < amt:
|
|
||||||
bits += 1
|
|
||||||
strs = "{"
|
|
||||||
for i in range(amt):
|
|
||||||
strs += '"#define ' + x[i] + '\\n",'
|
|
||||||
|
|
||||||
c = {}
|
|
||||||
c["set_mask"] = "uint64_t(" + str(i) + ")<<" + str(bitofs)
|
|
||||||
c["clear_mask"] = (
|
|
||||||
"((uint64_t(1)<<40)-1) ^ (((uint64_t(1)<<" + str(bits) + ") - 1)<<" + str(bitofs) + ")"
|
|
||||||
)
|
|
||||||
enum_vals.append(c)
|
|
||||||
enum_constants.append(x[i])
|
|
||||||
|
|
||||||
strs += "NULL}"
|
|
||||||
|
|
||||||
fd.write(
|
|
||||||
"\t\t\t{(uint64_t(1<<" + str(bits) + ")-1)<<" + str(bitofs) + "," + str(bitofs) + "," + strs + "},\n"
|
|
||||||
)
|
|
||||||
bitofs += bits
|
|
||||||
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const EnumValue _enum_values[]={\n")
|
|
||||||
|
|
||||||
enum_value_count = len(enum_vals)
|
|
||||||
for x in enum_vals:
|
|
||||||
fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n")
|
|
||||||
|
|
||||||
fd.write("\t\t};\n\n")
|
|
||||||
|
|
||||||
conditionals_found = []
|
|
||||||
if header_data.conditionals:
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char* _conditional_strings[]={\n")
|
|
||||||
if 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")
|
|
||||||
|
|
||||||
if header_data.uniforms:
|
if header_data.uniforms:
|
||||||
|
|
||||||
|
@ -435,19 +393,18 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
fd.write('\t\t\t"' + x + '",\n')
|
fd.write('\t\t\t"' + x + '",\n')
|
||||||
fd.write("\t\t};\n\n")
|
fd.write("\t\t};\n\n")
|
||||||
else:
|
else:
|
||||||
fd.write("\t\tstatic const char **_uniform_strings=NULL;\n")
|
fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n")
|
||||||
|
|
||||||
if output_attribs:
|
variant_count = 1
|
||||||
if header_data.attributes:
|
if len(header_data.variant_defines)>0:
|
||||||
|
|
||||||
fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n")
|
fd.write("\t\tstatic const char* _variant_defines[]={\n")
|
||||||
for x in header_data.attributes:
|
for x in header_data.variant_defines:
|
||||||
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
fd.write('\t\t\t"' + x + '",\n')
|
||||||
fd.write("\t\t};\n\n")
|
fd.write("\t\t};\n\n")
|
||||||
else:
|
variant_count=len(header_data.variant_defines)
|
||||||
fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n")
|
else:
|
||||||
|
fd.write("\t\tstatic const char **_variant_defines[]={""};\n")
|
||||||
feedback_count = 0
|
|
||||||
|
|
||||||
if header_data.texunits:
|
if header_data.texunits:
|
||||||
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
|
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
|
||||||
|
@ -455,7 +412,29 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
||||||
fd.write("\t\t};\n\n")
|
fd.write("\t\t};\n\n")
|
||||||
else:
|
else:
|
||||||
fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n")
|
fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n")
|
||||||
|
|
||||||
|
if 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=nullptr;\n")
|
||||||
|
|
||||||
|
if header_data.specialization_names:
|
||||||
|
fd.write("\t\tstatic Specialization _spec_pairs[]={\n")
|
||||||
|
for i in range(len(header_data.specialization_names)):
|
||||||
|
defval = header_data.specialization_values[i].strip()
|
||||||
|
if (defval.upper() == "TRUE" or defval=="1"):
|
||||||
|
defal="true"
|
||||||
|
else:
|
||||||
|
defval="false"
|
||||||
|
|
||||||
|
fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n")
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
else:
|
||||||
|
fd.write("\t\tstatic Specialization *_spec_pairs=nullptr;\n")
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _vertex_code[]={\n")
|
fd.write("\t\tstatic const char _vertex_code[]={\n")
|
||||||
for x in header_data.vertex_lines:
|
for x in header_data.vertex_lines:
|
||||||
|
@ -465,8 +444,6 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
fd.write(str(ord("\n")) + ",")
|
fd.write(str(ord("\n")) + ",")
|
||||||
fd.write("\t\t0};\n\n")
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n")
|
|
||||||
|
|
||||||
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
||||||
for x in header_data.fragment_lines:
|
for x in header_data.fragment_lines:
|
||||||
for c in x:
|
for c in x:
|
||||||
|
@ -475,44 +452,23 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
fd.write(str(ord("\n")) + ",")
|
fd.write(str(ord("\n")) + ",")
|
||||||
fd.write("\t\t0};\n\n")
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
fd.write("\t\tstatic const int _fragment_code_start=" + str(header_data.fragment_offset) + ";\n")
|
fd.write(
|
||||||
|
"\t\tsetup(_vertex_code,_fragment_code,\""
|
||||||
if output_attribs:
|
+ out_file_class + "\","
|
||||||
fd.write(
|
+ str(len(header_data.uniforms))
|
||||||
"\t\tsetup(_conditional_strings,"
|
+ ",_uniform_strings,"
|
||||||
+ str(len(header_data.conditionals))
|
+ str(len(header_data.ubos))
|
||||||
+ ",_uniform_strings,"
|
+ ",_ubo_pairs,"
|
||||||
+ str(len(header_data.uniforms))
|
+ str(len(header_data.texunits))
|
||||||
+ ",_attribute_pairs,"
|
+ ",_texunit_pairs,"
|
||||||
+ str(len(header_data.attributes))
|
+ str(len(header_data.specialization_names))
|
||||||
+ ", _texunit_pairs,"
|
+ ",_spec_pairs,"
|
||||||
+ str(len(header_data.texunits))
|
+ str(variant_count)
|
||||||
+ ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
|
+ ",_variant_defines);\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}\n\n")
|
fd.write("\t}\n\n")
|
||||||
|
|
||||||
if enum_constants:
|
|
||||||
|
|
||||||
fd.write("\tenum EnumConditionals {\n")
|
|
||||||
for x in enum_constants:
|
|
||||||
fd.write("\t\t" + x.upper() + ",\n")
|
|
||||||
fd.write("\t};\n\n")
|
|
||||||
fd.write("\tvoid set_enum_conditional(EnumConditionals p_cond) { _set_enum_conditional(p_cond); }\n")
|
|
||||||
|
|
||||||
fd.write("};\n\n")
|
fd.write("};\n\n")
|
||||||
fd.write("#endif\n\n")
|
fd.write("#endif\n\n")
|
||||||
|
@ -521,7 +477,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
|
|
||||||
def build_gles3_headers(target, source, env):
|
def build_gles3_headers(target, source, env):
|
||||||
for x in source:
|
for x in source:
|
||||||
build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True)
|
build_gles3_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -0,0 +1,528 @@
|
||||||
|
"""Functions used to generate source files during build time
|
||||||
|
|
||||||
|
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from platform_methods import subprocess_main
|
||||||
|
|
||||||
|
|
||||||
|
class LegacyGLHeaderStruct:
|
||||||
|
def __init__(self):
|
||||||
|
self.vertex_lines = []
|
||||||
|
self.fragment_lines = []
|
||||||
|
self.uniforms = []
|
||||||
|
self.attributes = []
|
||||||
|
self.feedbacks = []
|
||||||
|
self.fbos = []
|
||||||
|
self.conditionals = []
|
||||||
|
self.enums = {}
|
||||||
|
self.texunits = []
|
||||||
|
self.texunit_names = []
|
||||||
|
self.ubos = []
|
||||||
|
self.ubo_names = []
|
||||||
|
|
||||||
|
self.vertex_included_files = []
|
||||||
|
self.fragment_included_files = []
|
||||||
|
|
||||||
|
self.reading = ""
|
||||||
|
self.line_offset = 0
|
||||||
|
self.vertex_offset = 0
|
||||||
|
self.fragment_offset = 0
|
||||||
|
|
||||||
|
|
||||||
|
def include_file_in_legacygl_header(filename, header_data, depth):
|
||||||
|
fs = open(filename, "r")
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
while line:
|
||||||
|
|
||||||
|
if line.find("[vertex]") != -1:
|
||||||
|
header_data.reading = "vertex"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.vertex_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.find("[fragment]") != -1:
|
||||||
|
header_data.reading = "fragment"
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
header_data.fragment_offset = header_data.line_offset
|
||||||
|
continue
|
||||||
|
|
||||||
|
while line.find("#include ") != -1:
|
||||||
|
includeline = line.replace("#include ", "").strip()[1:-1]
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
|
||||||
|
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
|
||||||
|
header_data.vertex_included_files += [included_file]
|
||||||
|
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
||||||
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
|
||||||
|
header_data.fragment_included_files += [included_file]
|
||||||
|
if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
|
||||||
|
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
|
||||||
|
|
||||||
|
line = fs.readline()
|
||||||
|
|
||||||
|
if line.find("#ifdef ") != -1:
|
||||||
|
if line.find("#ifdef ") != -1:
|
||||||
|
ifdefline = line.replace("#ifdef ", "").strip()
|
||||||
|
|
||||||
|
if line.find("_EN_") != -1:
|
||||||
|
enumbase = ifdefline[: ifdefline.find("_EN_")]
|
||||||
|
ifdefline = ifdefline.replace("_EN_", "_")
|
||||||
|
line = line.replace("_EN_", "_")
|
||||||
|
if enumbase not in header_data.enums:
|
||||||
|
header_data.enums[enumbase] = []
|
||||||
|
if ifdefline not in header_data.enums[enumbase]:
|
||||||
|
header_data.enums[enumbase].append(ifdefline)
|
||||||
|
|
||||||
|
elif not ifdefline in header_data.conditionals:
|
||||||
|
header_data.conditionals += [ifdefline]
|
||||||
|
|
||||||
|
if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
|
||||||
|
# texture unit
|
||||||
|
texunitstr = line[line.find(":") + 1 :].strip()
|
||||||
|
if texunitstr == "auto":
|
||||||
|
texunit = "-1"
|
||||||
|
else:
|
||||||
|
texunit = str(int(texunitstr))
|
||||||
|
uline = line[: line.lower().find("//")]
|
||||||
|
uline = uline.replace("uniform", "")
|
||||||
|
uline = uline.replace("highp", "")
|
||||||
|
uline = uline.replace(";", "")
|
||||||
|
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.texunit_names:
|
||||||
|
header_data.texunits += [(x, texunit)]
|
||||||
|
header_data.texunit_names += [x]
|
||||||
|
|
||||||
|
elif line.find("uniform") != -1 and line.lower().find("ubo:") != -1:
|
||||||
|
# uniform buffer object
|
||||||
|
ubostr = line[line.find(":") + 1 :].strip()
|
||||||
|
ubo = str(int(ubostr))
|
||||||
|
uline = line[: line.lower().find("//")]
|
||||||
|
uline = uline[uline.find("uniform") + len("uniform") :]
|
||||||
|
uline = uline.replace("highp", "")
|
||||||
|
uline = uline.replace(";", "")
|
||||||
|
uline = uline.replace("{", "").strip()
|
||||||
|
lines = uline.split(",")
|
||||||
|
for x in lines:
|
||||||
|
|
||||||
|
x = x.strip()
|
||||||
|
x = x[x.rfind(" ") + 1 :]
|
||||||
|
if x.find("[") != -1:
|
||||||
|
# unfiorm array
|
||||||
|
x = x[: x.find("[")]
|
||||||
|
|
||||||
|
if not x in header_data.ubo_names:
|
||||||
|
header_data.ubos += [(x, ubo)]
|
||||||
|
header_data.ubo_names += [x]
|
||||||
|
|
||||||
|
elif line.find("uniform") != -1 and line.find("{") == -1 and line.find(";") != -1:
|
||||||
|
uline = line.replace("uniform", "")
|
||||||
|
uline = uline.replace(";", "")
|
||||||
|
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.uniforms:
|
||||||
|
header_data.uniforms += [x]
|
||||||
|
|
||||||
|
if line.strip().find("attribute ") == 0 and line.find("attrib:") != -1:
|
||||||
|
uline = line.replace("in ", "")
|
||||||
|
uline = uline.replace("attribute ", "")
|
||||||
|
uline = uline.replace("highp ", "")
|
||||||
|
uline = uline.replace(";", "")
|
||||||
|
uline = uline[uline.find(" ") :].strip()
|
||||||
|
|
||||||
|
if uline.find("//") != -1:
|
||||||
|
name, bind = uline.split("//")
|
||||||
|
if bind.find("attrib:") != -1:
|
||||||
|
name = name.strip()
|
||||||
|
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", "")
|
||||||
|
|
||||||
|
if header_data.reading == "vertex":
|
||||||
|
header_data.vertex_lines += [line]
|
||||||
|
if header_data.reading == "fragment":
|
||||||
|
header_data.fragment_lines += [line]
|
||||||
|
|
||||||
|
line = fs.readline()
|
||||||
|
header_data.line_offset += 1
|
||||||
|
|
||||||
|
fs.close()
|
||||||
|
|
||||||
|
return header_data
|
||||||
|
|
||||||
|
|
||||||
|
def build_legacygl_header(filename, include, class_suffix, output_attribs):
|
||||||
|
header_data = LegacyGLHeaderStruct()
|
||||||
|
include_file_in_legacygl_header(filename, header_data, 0)
|
||||||
|
|
||||||
|
out_file = filename + ".gen.h"
|
||||||
|
fd = open(out_file, "w")
|
||||||
|
|
||||||
|
enum_constants = []
|
||||||
|
|
||||||
|
fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
|
||||||
|
|
||||||
|
out_file_base = out_file
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
|
||||||
|
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
|
||||||
|
out_file_ifdef = out_file_base.replace(".", "_").upper()
|
||||||
|
fd.write("#ifndef " + out_file_ifdef + class_suffix + "_120\n")
|
||||||
|
fd.write("#define " + out_file_ifdef + class_suffix + "_120\n")
|
||||||
|
|
||||||
|
out_file_class = (
|
||||||
|
out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
|
||||||
|
)
|
||||||
|
fd.write("\n\n")
|
||||||
|
fd.write('#include "' + include + '"\n\n\n')
|
||||||
|
fd.write("class " + out_file_class + " : public ShaderOLD" + class_suffix + " {\n\n")
|
||||||
|
fd.write('\t virtual String get_shader_name() const { return "' + out_file_class + '"; }\n')
|
||||||
|
|
||||||
|
fd.write("public:\n\n")
|
||||||
|
|
||||||
|
if header_data.conditionals:
|
||||||
|
fd.write("\tenum Conditionals {\n")
|
||||||
|
for x in header_data.conditionals:
|
||||||
|
fd.write("\t\t" + x.upper() + ",\n")
|
||||||
|
fd.write("\t};\n\n")
|
||||||
|
|
||||||
|
if header_data.uniforms:
|
||||||
|
fd.write("\tenum Uniforms {\n")
|
||||||
|
for x in header_data.uniforms:
|
||||||
|
fd.write("\t\t" + x.upper() + ",\n")
|
||||||
|
fd.write("\t};\n\n")
|
||||||
|
|
||||||
|
fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n")
|
||||||
|
if header_data.conditionals:
|
||||||
|
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#ifdef DEBUG_ENABLED\n ")
|
||||||
|
fd.write(
|
||||||
|
"\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n "
|
||||||
|
)
|
||||||
|
fd.write("\t#else\n ")
|
||||||
|
fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; \n\n ")
|
||||||
|
fd.write("\t#endif\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"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint vec2[2]={p_vec2.x,p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n"
|
||||||
|
)
|
||||||
|
fd.write(
|
||||||
|
"\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
fd.write(
|
||||||
|
"""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform3D& p_transform) { _FU
|
||||||
|
|
||||||
|
const Transform3D &tr = p_transform;
|
||||||
|
|
||||||
|
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(get_uniform(p_uniform),1,false,matrix);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fd.write(
|
||||||
|
"""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU
|
||||||
|
|
||||||
|
const Transform2D &tr = p_transform;
|
||||||
|
|
||||||
|
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(get_uniform(p_uniform),1,false,matrix);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fd.write(
|
||||||
|
"""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU
|
||||||
|
|
||||||
|
GLfloat matrix[16];
|
||||||
|
|
||||||
|
for (int i=0;i<4;i++) {
|
||||||
|
for (int j=0;j<4;j++) {
|
||||||
|
matrix[i*4+j]=p_matrix.matrix[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
||||||
|
}"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fd.write("\n\n#undef _FU\n\n\n")
|
||||||
|
|
||||||
|
fd.write("\tvirtual void init() {\n\n")
|
||||||
|
|
||||||
|
enum_value_count = 0
|
||||||
|
|
||||||
|
if header_data.enums:
|
||||||
|
|
||||||
|
fd.write("\t\t//Written using math, given nonstandarity of 64 bits integer constants..\n")
|
||||||
|
fd.write("\t\tstatic const Enum _enums[]={\n")
|
||||||
|
|
||||||
|
bitofs = len(header_data.conditionals)
|
||||||
|
enum_vals = []
|
||||||
|
|
||||||
|
for xv in header_data.enums:
|
||||||
|
x = header_data.enums[xv]
|
||||||
|
bits = 1
|
||||||
|
amt = len(x)
|
||||||
|
while 2 ** bits < amt:
|
||||||
|
bits += 1
|
||||||
|
strs = "{"
|
||||||
|
for i in range(amt):
|
||||||
|
strs += '"#define ' + x[i] + '\\n",'
|
||||||
|
|
||||||
|
c = {}
|
||||||
|
c["set_mask"] = "uint64_t(" + str(i) + ")<<" + str(bitofs)
|
||||||
|
c["clear_mask"] = (
|
||||||
|
"((uint64_t(1)<<40)-1) ^ (((uint64_t(1)<<" + str(bits) + ") - 1)<<" + str(bitofs) + ")"
|
||||||
|
)
|
||||||
|
enum_vals.append(c)
|
||||||
|
enum_constants.append(x[i])
|
||||||
|
|
||||||
|
strs += "NULL}"
|
||||||
|
|
||||||
|
fd.write(
|
||||||
|
"\t\t\t{(uint64_t(1<<" + str(bits) + ")-1)<<" + str(bitofs) + "," + str(bitofs) + "," + strs + "},\n"
|
||||||
|
)
|
||||||
|
bitofs += bits
|
||||||
|
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const EnumValue _enum_values[]={\n")
|
||||||
|
|
||||||
|
enum_value_count = len(enum_vals)
|
||||||
|
for x in enum_vals:
|
||||||
|
fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n")
|
||||||
|
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
|
||||||
|
conditionals_found = []
|
||||||
|
if header_data.conditionals:
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char* _conditional_strings[]={\n")
|
||||||
|
if 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")
|
||||||
|
|
||||||
|
if header_data.uniforms:
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char* _uniform_strings[]={\n")
|
||||||
|
if header_data.uniforms:
|
||||||
|
for x in header_data.uniforms:
|
||||||
|
fd.write('\t\t\t"' + x + '",\n')
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
else:
|
||||||
|
fd.write("\t\tstatic const char **_uniform_strings=NULL;\n")
|
||||||
|
|
||||||
|
if output_attribs:
|
||||||
|
if header_data.attributes:
|
||||||
|
|
||||||
|
fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n")
|
||||||
|
for x in header_data.attributes:
|
||||||
|
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
else:
|
||||||
|
fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n")
|
||||||
|
|
||||||
|
feedback_count = 0
|
||||||
|
|
||||||
|
if header_data.texunits:
|
||||||
|
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
|
||||||
|
for x in header_data.texunits:
|
||||||
|
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
|
||||||
|
fd.write("\t\t};\n\n")
|
||||||
|
else:
|
||||||
|
fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n")
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char _vertex_code[]={\n")
|
||||||
|
for x in header_data.vertex_lines:
|
||||||
|
for c in x:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
|
||||||
|
fd.write(str(ord("\n")) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n")
|
||||||
|
|
||||||
|
fd.write("\t\tstatic const char _fragment_code[]={\n")
|
||||||
|
for x in header_data.fragment_lines:
|
||||||
|
for c in x:
|
||||||
|
fd.write(str(ord(c)) + ",")
|
||||||
|
|
||||||
|
fd.write(str(ord("\n")) + ",")
|
||||||
|
fd.write("\t\t0};\n\n")
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
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}\n\n")
|
||||||
|
|
||||||
|
if enum_constants:
|
||||||
|
|
||||||
|
fd.write("\tenum EnumConditionals {\n")
|
||||||
|
for x in enum_constants:
|
||||||
|
fd.write("\t\t" + x.upper() + ",\n")
|
||||||
|
fd.write("\t};\n\n")
|
||||||
|
fd.write("\tvoid set_enum_conditional(EnumConditionals p_cond) { _set_enum_conditional(p_cond); }\n")
|
||||||
|
|
||||||
|
fd.write("};\n\n")
|
||||||
|
fd.write("#endif\n\n")
|
||||||
|
fd.close()
|
||||||
|
|
||||||
|
|
||||||
|
def build_gles3_headers(target, source, env):
|
||||||
|
for x in source:
|
||||||
|
build_legacygl_header(str(x), include="drivers/gles3/shader_old_gles3.h", class_suffix="GLES3", output_attribs=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
subprocess_main(globals())
|
Loading…
Reference in New Issue