New OpenGL batching canvas renderer

This commit is contained in:
clayjohn 2021-11-16 07:25:42 -08:00
parent 98ac002c34
commit 99064d57db
54 changed files with 2411 additions and 10131 deletions

View file

@ -1,421 +0,0 @@
/*************************************************************************/
/* rasterizer_array.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 RASTERIZER_ARRAY_H
#define RASTERIZER_ARRAY_H
/**
* Fast single-threaded growable array for POD types.
* For use in render drivers, not for general use.
* TO BE REPLACED by local_vector.
*/
#include "core/os/memory.h"
#include <string.h>
#include "core/templates/local_vector.h"
#include "core/templates/vector.h"
// very simple non-growable array, that keeps track of the size of a 'unit'
// which can be cast to whatever vertex format FVF required, and is initially
// created with enough memory to hold the biggest FVF.
// This allows multiple FVFs to use the same array.
class RasterizerUnitArrayGLES3 {
public:
RasterizerUnitArrayGLES3() {
_list = nullptr;
free();
}
~RasterizerUnitArrayGLES3() { free(); }
uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; }
const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; }
int size() const { return _size; }
int max_size() const { return _max_size; }
void free() {
if (_list) {
memdelete_arr(_list);
_list = 0;
}
_size = 0;
_max_size = 0;
_max_size_bytes = 0;
_unit_size_bytes = 0;
}
void create(int p_max_size_units, int p_max_unit_size_bytes) {
free();
_max_unit_size_bytes = p_max_unit_size_bytes;
_max_size = p_max_size_units;
_max_size_bytes = p_max_size_units * p_max_unit_size_bytes;
if (_max_size_bytes) {
_list = memnew_arr(uint8_t, _max_size_bytes);
}
}
void prepare(int p_unit_size_bytes) {
_unit_size_bytes = p_unit_size_bytes;
_size = 0;
}
// several items at a time
uint8_t *request(int p_num_items = 1) {
int old_size = _size;
_size += p_num_items;
if (_size <= _max_size) {
return get_unit(old_size);
}
// revert
_size = old_size;
return nullptr;
}
private:
uint8_t *_list;
int _size; // in units
int _max_size; // in units
int _max_size_bytes;
int _unit_size_bytes;
int _max_unit_size_bytes;
};
template <class T>
class RasterizerArray {
public:
RasterizerArray() {
_list = 0;
_size = 0;
_max_size = 0;
}
~RasterizerArray() { free(); }
T &operator[](unsigned int ui) { return _list[ui]; }
const T &operator[](unsigned int ui) const { return _list[ui]; }
void free() {
if (_list) {
memdelete_arr(_list);
_list = 0;
}
_size = 0;
_max_size = 0;
}
void create(int p_size) {
free();
if (p_size) {
_list = memnew_arr(T, p_size);
}
_size = 0;
_max_size = p_size;
}
void reset() { _size = 0; }
T *request_with_grow() {
T *p = request();
if (!p) {
grow();
return request_with_grow();
}
return p;
}
// none of that inefficient pass by value stuff here, thanks
T *request() {
if (_size < _max_size) {
return &_list[_size++];
}
return 0;
}
// several items at a time
T *request(int p_num_items) {
int old_size = _size;
_size += p_num_items;
if (_size <= _max_size) {
return &_list[old_size];
}
// revert
_size = old_size;
return 0;
}
int size() const { return _size; }
int max_size() const { return _max_size; }
const T *get_data() const { return _list; }
bool copy_from(const RasterizerArray<T> &o) {
// no resizing done here, it should be done manually
if (o.size() > _max_size)
return false;
// pod types only please!
memcpy(_list, o.get_data(), o.size() * sizeof(T));
_size = o.size();
return true;
}
// if you want this to be cheap, call reset before grow,
// to ensure there is no data to copy
void grow() {
unsigned int new_max_size = _max_size * 2;
if (!new_max_size)
new_max_size = 1;
T *new_list = memnew_arr(T, new_max_size);
// copy .. pod types only
if (_list) {
memcpy(new_list, _list, _size * sizeof(T));
}
unsigned int new_size = size();
free();
_list = new_list;
_size = new_size;
_max_size = new_max_size;
}
private:
T *_list;
int _size;
int _max_size;
};
template <class T>
class RasterizerArray_non_pod {
public:
RasterizerArray_non_pod() {
_size = 0;
}
const T &operator[](unsigned int ui) const { return _list[ui]; }
void create(int p_size) {
_list.resize(p_size);
_size = 0;
}
void reset() { _size = 0; }
void push_back(const T &val) {
while (true) {
if (_size < max_size()) {
_list.set(_size, val);
_size++;
return;
}
grow();
}
}
int size() const { return _size; }
int max_size() const { return _list.size(); }
private:
void grow() {
unsigned int new_max_size = _list.size() * 2;
if (!new_max_size)
new_max_size = 1;
_list.resize(new_max_size);
}
Vector<T> _list;
int _size;
};
// very simple non-growable array, that keeps track of the size of a 'unit'
// which can be cast to whatever vertex format FVF required, and is initially
// created with enough memory to hold the biggest FVF.
// This allows multiple FVFs to use the same array.
class RasterizerUnitArray {
public:
RasterizerUnitArray() {
_list = nullptr;
free();
}
~RasterizerUnitArray() { free(); }
uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; }
const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; }
int size() const { return _size; }
int max_size() const { return _max_size; }
int get_unit_size_bytes() const { return _unit_size_bytes; }
void free() {
if (_list) {
memdelete_arr(_list);
_list = 0;
}
_size = 0;
_max_size = 0;
_max_size_bytes = 0;
_unit_size_bytes = 0;
}
void create(int p_max_size_units, int p_max_unit_size_bytes) {
free();
_max_unit_size_bytes = p_max_unit_size_bytes;
_max_size = p_max_size_units;
_max_size_bytes = p_max_size_units * p_max_unit_size_bytes;
if (_max_size_bytes) {
_list = memnew_arr(uint8_t, _max_size_bytes);
}
}
void prepare(int p_unit_size_bytes) {
_unit_size_bytes = p_unit_size_bytes;
_size = 0;
}
// several items at a time
uint8_t *request(int p_num_items = 1) {
int old_size = _size;
_size += p_num_items;
if (_size <= _max_size) {
return get_unit(old_size);
}
// revert
_size = old_size;
return nullptr;
}
private:
uint8_t *_list;
int _size; // in units
int _max_size; // in units
int _max_size_bytes;
int _unit_size_bytes;
int _max_unit_size_bytes;
};
template <class T, bool force_trivial = false>
class RasterizerPooledList {
LocalVector<T, uint32_t, force_trivial> list;
LocalVector<uint32_t, uint32_t, true> freelist;
// not all list members are necessarily used
int _used_size;
public:
RasterizerPooledList() {
_used_size = 0;
}
int estimate_memory_use() const {
return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t));
}
const T &operator[](uint32_t p_index) const {
return list[p_index];
}
T &operator[](uint32_t p_index) {
return list[p_index];
}
int size() const { return _used_size; }
// returns the list id of the allocated item
uint32_t alloc() {
uint32_t id = 0;
_used_size++;
if (freelist.size()) {
// pop from freelist
int new_size = freelist.size() - 1;
id = freelist[new_size];
freelist.resize(new_size);
return id;
// return &list[r_id];
}
id = list.size();
list.resize(id + 1);
return id;
// return &list[r_id];
}
void free(const uint32_t &p_id) {
// should not be on free list already
CRASH_COND(p_id >= list.size());
freelist.push_back(p_id);
_used_size--;
}
};
template <class T, bool force_trivial = false>
class RasterizerPooledIndirectList {
public:
const T &operator[](uint32_t p_index) const {
return *_list[p_index];
}
T &operator[](uint32_t p_index) {
return *_list[p_index];
}
uint32_t alloc() {
uint32_t id = _list.alloc();
_list[id] = memnew(T);
return id;
}
void free(const uint32_t &p_id) {
CRASH_COND(!_list[p_id]);
memdelete_notnull(_list[p_id]);
_list[p_id] = nullptr;
_list.free(p_id);
}
~RasterizerPooledIndirectList() {
// autodelete
for (int n = 0; n < _list.size(); n++) {
if (_list[n]) {
memdelete_notnull(_list[n]);
}
}
}
private:
RasterizerPooledList<T *, true> _list;
};
#endif // RASTERIZER_ARRAY_H

View file

@ -1,67 +0,0 @@
/*************************************************************************/
/* rasterizer_asserts.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 RASTERIZER_ASSERTS_H
#define RASTERIZER_ASSERTS_H
// For flow control checking, we want an easy way to apply asserts that occur in debug development builds only.
// This is enforced by outputting a warning which will fail CI checks if the define is set in a PR.
#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
// only uncomment this define for error checking in development, not in the main repository
// as these checks will slow things down in debug builds.
//#define RASTERIZER_EXTRA_CHECKS
#endif
#ifdef RASTERIZER_EXTRA_CHECKS
#ifndef _MSC_VER
#warning do not define RASTERIZER_EXTRA_CHECKS in main repository builds
#endif
#define RAST_DEV_DEBUG_ASSERT(a) CRASH_COND(!(a))
#else
#define RAST_DEV_DEBUG_ASSERT(a)
#endif
// Also very useful, an assert check that only occurs in debug tools builds
#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
#define RAST_DEBUG_ASSERT(a) CRASH_COND(!(a))
#else
#define RAST_DEBUG_ASSERT(a)
#endif
// Thin wrapper around ERR_FAIL_COND to allow us to make it debug only
#ifdef DEBUG_ENABLED
#define RAST_FAIL_COND(m_cond) ERR_FAIL_COND(m_cond)
#else
#define RAST_FAIL_COND(m_cond) \
if (m_cond) { \
}
#endif
#endif // RASTERIZER_ASSERTS_H

File diff suppressed because it is too large Load diff

View file

@ -1,213 +0,0 @@
/*************************************************************************/
/* rasterizer_canvas_base_gles3.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 RASTERIZER_CANVAS_BASE_OPENGL_H
#define RASTERIZER_CANVAS_BASE_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#include "drivers/gles3/rasterizer_array.h"
#include "drivers/gles3/rasterizer_storage_common.h"
#include "rasterizer_scene_gles3.h"
#include "rasterizer_storage_gles3.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "shaders/canvas_old.glsl.gen.h"
#include "shaders/canvas_shadow.glsl.gen.h"
#include "shaders/lens_distorted.glsl.gen.h"
class RasterizerCanvasBaseGLES3 : public RendererCanvasRender {
public:
enum {
INSTANCE_ATTRIB_BASE = 8,
};
struct Uniforms {
Transform3D projection_matrix;
Transform2D modelview_matrix;
Transform2D extra_matrix;
Color final_modulate;
float time;
};
struct CanvasItemUBO {
float projection_matrix[16];
float time;
uint8_t padding[12];
};
struct Data {
enum { NUM_QUAD_ARRAY_VARIATIONS = 8 };
GLuint canvas_quad_vertices;
GLuint canvas_quad_array;
GLuint polygon_buffer;
GLuint polygon_buffer_quad_arrays[NUM_QUAD_ARRAY_VARIATIONS];
GLuint polygon_buffer_pointer_array;
GLuint polygon_index_buffer;
GLuint particle_quad_vertices;
GLuint particle_quad_array;
uint32_t polygon_buffer_size;
uint32_t polygon_index_buffer_size;
GLuint ninepatch_vertices;
GLuint ninepatch_elements;
} data;
struct State {
Uniforms uniforms;
CanvasItemUBO canvas_item_ubo_data;
GLuint canvas_item_ubo;
bool canvas_texscreen_used;
CanvasOldShaderGLES3 canvas_shader;
CanvasShadowShaderGLES3 canvas_shadow_shader;
LensDistortedShaderGLES3 lens_shader;
bool using_texture_rect;
bool using_light_angle;
bool using_modulate;
bool using_large_vertex;
bool using_ninepatch;
bool using_skeleton;
Transform2D skeleton_transform;
Transform2D skeleton_transform_inverse;
Size2i skeleton_texture_size;
RID current_tex;
RID current_normal;
RasterizerStorageGLES3::Texture *current_tex_ptr;
Transform3D vp;
Light *using_light;
bool using_shadow;
bool using_transparent_rt;
// new for Godot 4.0
// min mag filter is per item, and repeat
RS::CanvasItemTextureFilter current_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
RS::CanvasItemTextureRepeat current_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
} state;
typedef void Texture;
RasterizerSceneGLES3 *scene_render;
RasterizerStorageGLES3 *storage;
// allow user to choose api usage
GLenum _buffer_upload_usage_flag;
void _set_uniforms();
virtual RID light_internal_create();
virtual void light_internal_update(RID p_rid, Light *p_light);
virtual void light_internal_free(RID p_rid);
virtual void canvas_begin();
virtual void canvas_end();
protected:
void _legacy_draw_primitive(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material);
void _legacy_draw_line(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material);
void _legacy_draw_poly_triangles(Item::CommandPolygon *p_poly, RasterizerStorageGLES3::Material *p_material);
public:
void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const float *p_light_angles = nullptr);
void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = NULL, const int *p_bones = NULL);
void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
void _draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
void _bind_quad_buffer();
void _copy_texscreen(const Rect2 &p_rect);
void _copy_screen(const Rect2 &p_rect);
//virtual void draw_window_margins(int *black_margin, RID *black_image) override;
void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
virtual void reset_canvas();
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
// Copied from RasterizerCanvasDummy:
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override;
RID light_create() override;
void light_set_texture(RID p_rid, RID p_texture) override;
void light_set_use_shadow(RID p_rid, bool p_enable) override;
void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override;
void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override;
void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override;
RID occluder_polygon_create() override;
void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override;
void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override;
void set_shadow_texture_size(int p_size) override;
bool free(RID p_rid) override;
void update() override;
// End copied from RasterizerCanvasDummy.
RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
void _set_texture_rect_mode(bool p_texture_rect, bool p_light_angle = false, bool p_modulate = false, bool p_large_vertex = false);
// NEW API
struct PolyData {
LocalVector<int> indices;
LocalVector<Point2> points;
LocalVector<Color> colors;
LocalVector<Point2> uvs;
};
RendererCanvasRender::PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override;
void free_polygon(PolygonID p_polygon) override;
RasterizerPooledIndirectList<PolyData> _polydata;
//////////////////////
void initialize();
void finalize();
RasterizerCanvasBaseGLES3();
};
#endif // GLES3_BACKEND_ENABLED
#endif // RASTERIZER_CANVAS_BASE_OPENGL_H

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -31,41 +31,251 @@
#ifndef RASTERIZER_CANVAS_OPENGL_H
#define RASTERIZER_CANVAS_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "drivers/gles3/rasterizer_canvas_batcher.h"
#include "rasterizer_canvas_base_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "rasterizer_storage_gles3.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "shaders/canvas.glsl.gen.h"
class RasterizerSceneGLES3;
class RasterizerCanvasGLES3 : public RasterizerCanvasBaseGLES3, public RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3> {
friend class RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3>;
class RasterizerCanvasGLES3 : public RendererCanvasRender {
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
private:
// legacy codepath .. to remove after testing
void _legacy_canvas_render_item(Item *p_ci, RenderItemState &r_ris);
_FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4);
_FORCE_INLINE_ void _update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4);
// high level batch funcs
void canvas_render_items_implementation(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
void render_batches(Item::Command *const *p_commands, Item *p_current_clip, bool &r_reclip, RasterizerStorageGLES3::Material *p_material);
enum {
BASE_UNIFORM_BUFFER_OBJECT = 0,
MATERIAL_UNIFORM_BUFFER_OBJECT = 1,
TRANSFORMS_UNIFORM_BUFFER_OBJECT = 2,
CANVAS_TEXTURE_UNIFORM_BUFFER_OBJECT = 3,
};
// funcs used from rasterizer_canvas_batcher template
void gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const;
void gl_disable_scissor() const;
enum {
FLAGS_INSTANCING_MASK = 0x7F,
FLAGS_INSTANCING_HAS_COLORS = (1 << 7),
FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8),
FLAGS_CLIP_RECT_UV = (1 << 9),
FLAGS_TRANSPOSE_RECT = (1 << 10),
FLAGS_NINEPACH_DRAW_CENTER = (1 << 12),
FLAGS_USING_PARTICLES = (1 << 13),
FLAGS_USE_SKELETON = (1 << 15),
FLAGS_NINEPATCH_H_MODE_SHIFT = 16,
FLAGS_NINEPATCH_V_MODE_SHIFT = 18,
FLAGS_LIGHT_COUNT_SHIFT = 20,
FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 26),
FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27),
FLAGS_USE_MSDF = (1 << 28),
};
enum {
LIGHT_FLAGS_TEXTURE_MASK = 0xFFFF,
LIGHT_FLAGS_BLEND_SHIFT = 16,
LIGHT_FLAGS_BLEND_MASK = (3 << 16),
LIGHT_FLAGS_BLEND_MODE_ADD = (0 << 16),
LIGHT_FLAGS_BLEND_MODE_SUB = (1 << 16),
LIGHT_FLAGS_BLEND_MODE_MIX = (2 << 16),
LIGHT_FLAGS_BLEND_MODE_MASK = (3 << 16),
LIGHT_FLAGS_HAS_SHADOW = (1 << 20),
LIGHT_FLAGS_FILTER_SHIFT = 22
};
enum {
MAX_RENDER_ITEMS = 256 * 1024,
MAX_LIGHT_TEXTURES = 1024,
MAX_LIGHTS_PER_ITEM = 16,
DEFAULT_MAX_LIGHTS_PER_RENDER = 256,
};
public:
void canvas_render_items_begin(const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
void canvas_render_items_end();
void canvas_render_items_internal(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
void canvas_begin() override;
void canvas_end() override;
struct StateBuffer {
float canvas_transform[16];
float screen_transform[16];
float canvas_normal_transform[16];
float canvas_modulate[4];
float screen_pixel_size[2];
float time;
uint32_t use_pixel_snap;
float sdf_to_tex[4];
float sdf_to_screen[2];
float screen_to_sdf[2];
uint32_t directional_light_count;
float tex_to_sdf;
uint32_t pad1;
uint32_t pad2;
};
struct InstanceData {
float world[6];
float color_texture_pixel_size[2];
union {
//rect
struct {
float modulation[4];
union {
float msdf[4];
float ninepatch_margins[4];
};
float dst_rect[4];
float src_rect[4];
float pad[2];
};
//primitive
struct {
float points[6]; // vec2 points[3]
float uvs[6]; // vec2 points[3]
uint32_t colors[6]; // colors encoded as half
};
};
uint32_t flags;
uint32_t specular_shininess;
uint32_t lights[4];
};
struct Data {
GLuint canvas_quad_vertices;
GLuint canvas_quad_array;
GLuint particle_quad_vertices;
GLuint particle_quad_array;
GLuint ninepatch_vertices;
GLuint ninepatch_elements;
} data;
struct State {
GLuint canvas_state_buffer;
LocalVector<GLuint> canvas_instance_data_buffers;
LocalVector<GLsync> fences;
uint32_t current_buffer = 0;
InstanceData *instance_data_array;
bool canvas_texscreen_used;
CanvasShaderGLES3 canvas_shader;
RID canvas_shader_current_version;
RID canvas_shader_default_version;
//CanvasShadowShaderGLES3 canvas_shadow_shader;
//LensDistortedShaderGLES3 lens_shader;
bool using_texture_rect;
bool using_ninepatch;
bool using_skeleton;
Transform2D skeleton_transform;
Transform2D skeleton_transform_inverse;
Size2i skeleton_texture_size;
RID current_tex = RID();
RID current_normal = RID();
RID current_specular = RID();
RasterizerStorageGLES3::Texture *current_tex_ptr;
RID current_shader_version = RID();
RS::PrimitiveType current_primitive = RS::PRIMITIVE_MAX;
uint32_t current_primitive_points = 0;
Item::Command::Type current_command = Item::Command::TYPE_RECT;
bool end_batch = false;
Transform3D vp;
Light *using_light;
bool using_shadow;
bool using_transparent_rt;
// FROM RD Renderer
uint32_t max_lights_per_render;
uint32_t max_lights_per_item;
uint32_t max_instances_per_batch;
RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
} state;
Item *items[MAX_RENDER_ITEMS];
RID default_canvas_texture;
RID default_canvas_group_material;
RID default_canvas_group_shader;
typedef void Texture;
RasterizerSceneGLES3 *scene_render;
RasterizerStorageGLES3 *storage;
void _set_uniforms();
void canvas_begin();
void canvas_end();
//virtual void draw_window_margins(int *black_margin, RID *black_image) override;
void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
virtual void reset_canvas();
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override;
RID light_create() override;
void light_set_texture(RID p_rid, RID p_texture) override;
void light_set_use_shadow(RID p_rid, bool p_enable) override;
void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override;
void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override;
void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override;
RID occluder_polygon_create() override;
void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override;
void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override;
void set_shadow_texture_size(int p_size) override;
bool free(RID p_rid) override;
void update() override;
void _bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size);
struct PolygonBuffers {
GLuint vertex_buffer;
GLuint vertex_array;
GLuint index_buffer;
int count;
};
struct {
HashMap<PolygonID, PolygonBuffers> polygons;
PolygonID last_id;
} polygon_buffers;
RendererCanvasRender::PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override;
void free_polygon(PolygonID p_polygon) override;
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override;
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false);
void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index);
void _render_batch(uint32_t &p_max_index);
void _end_batch(uint32_t &p_max_index);
void _allocate_instance_data_buffer();
void initialize();
void finalize();
RasterizerCanvasGLES3();
~RasterizerCanvasGLES3();
};
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED
#endif // RASTERIZER_CANVAS_OPENGL_H

View file

@ -30,8 +30,7 @@
#include "rasterizer_gles3.h"
#ifdef GLES3_BACKEND_ENABLED
#include "shader_old_gles3.h"
#ifdef GLES3_ENABLED
#include "core/config/project_settings.h"
#include "core/os/os.h"
@ -91,21 +90,12 @@ void RasterizerGLES3::begin_frame(double frame_step) {
frame++;
delta = frame_step;
// from 3.2
time_total += frame_step * time_scale;
if (frame_step == 0) {
//to avoid hiccups
frame_step = 0.001;
}
time_total += frame_step;
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
time_total = Math::fmod(time_total, time_roll_over);
storage.frame.time[0] = time_total;
storage.frame.time[1] = Math::fmod(time_total, 3600);
storage.frame.time[2] = Math::fmod(time_total, 900);
storage.frame.time[3] = Math::fmod(time_total, 60);
storage.frame.time = time_total;
storage.frame.count++;
storage.frame.delta = frame_step;
@ -131,10 +121,11 @@ void RasterizerGLES3::end_frame(bool p_swap_buffers) {
// glClearColor(1, 0, 0, 1);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
if (p_swap_buffers)
if (p_swap_buffers) {
DisplayServer::get_singleton()->swap_buffers();
else
} else {
glFinish();
}
}
#ifdef CAN_DEBUG
@ -272,32 +263,22 @@ RasterizerGLES3::RasterizerGLES3() {
void RasterizerGLES3::prepare_for_blitting_render_targets() {
}
void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect) {
void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) {
ERR_FAIL_COND(storage.frame.current_rt);
// print_line("_blit_render_target_to_screen " + itos (p_screen) + ", rect " + String(Variant(p_screen_rect)));
RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
canvas._set_texture_rect_mode(true);
canvas.state.canvas_shader.set_custom_shader(0);
canvas.state.canvas_shader.bind();
// TODO: do we need a keep 3d linear option?
canvas.canvas_begin();
glDisable(GL_BLEND);
storage.bind_framebuffer_system();
glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1);
if (rt->external.fbo != 0) {
glBindTexture(GL_TEXTURE_2D, rt->external.color);
glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo);
} else {
glBindTexture(GL_TEXTURE_2D, rt->color);
glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
}
canvas.draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
glBindTexture(GL_TEXTURE_2D, 0);
canvas.canvas_end();
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
// is this p_screen useless in a multi window environment?
@ -313,7 +294,7 @@ void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_sc
RID rid_rt = blit.render_target;
Rect2 dst_rect = blit.dst_rect;
_blit_render_target_to_screen(rid_rt, dst_rect);
_blit_render_target_to_screen(rid_rt, p_screen, dst_rect);
}
}
@ -321,11 +302,10 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
if (p_image.is_null() || p_image->is_empty())
return;
int window_w = 640; //OS::get_singleton()->get_video_mode(0).width;
int window_h = 480; //OS::get_singleton()->get_video_mode(0).height;
Size2i win_size = DisplayServer::get_singleton()->screen_get_size();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, window_w, window_h);
glViewport(0, 0, win_size.width, win_size.height);
glDisable(GL_BLEND);
glDepthMask(GL_FALSE);
if (false) {
@ -346,27 +326,26 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
Rect2 screenrect;
if (p_scale) {
if (window_w > window_h) {
if (win_size.width > win_size.height) {
//scale horizontally
screenrect.size.y = window_h;
screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y;
screenrect.position.x = (window_w - screenrect.size.x) / 2;
screenrect.size.y = win_size.height;
screenrect.size.x = imgrect.size.x * win_size.height / imgrect.size.y;
screenrect.position.x = (win_size.width - screenrect.size.x) / 2;
} else {
//scale vertically
screenrect.size.x = window_w;
screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x;
screenrect.position.y = (window_h - screenrect.size.y) / 2;
screenrect.size.x = win_size.width;
screenrect.size.y = imgrect.size.y * win_size.width / imgrect.size.x;
screenrect.position.y = (win_size.height - screenrect.size.y) / 2;
}
} else {
screenrect = imgrect;
screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
screenrect.position += ((Size2(win_size.width, win_size.height) - screenrect.size) / 2.0).floor();
}
RasterizerStorageGLES3::Texture *t = storage.texture_owner.get_or_null(texture);
glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, t->tex_id);
canvas.draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
glBindTexture(GL_TEXTURE_2D, 0);
canvas.canvas_end();
@ -375,4 +354,4 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
end_frame(true);
}
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED

View file

@ -31,8 +31,7 @@
#ifndef RASTERIZER_OPENGL_H
#define RASTERIZER_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
@ -45,14 +44,13 @@ private:
float delta = 0;
double time_total = 0.0;
double time_scale = 1.0;
protected:
RasterizerCanvasGLES3 canvas;
RasterizerStorageGLES3 storage;
RasterizerCanvasGLES3 canvas;
RasterizerSceneGLES3 scene;
void _blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect);
void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect);
public:
RendererStorage *get_storage() { return &storage; }
@ -87,6 +85,6 @@ public:
~RasterizerGLES3() {}
};
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED
#endif

View file

@ -1,48 +0,0 @@
/*************************************************************************/
/* rasterizer_platforms.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 RASTERIZER_PLATFORMS_H
#define RASTERIZER_PLATFORMS_H
/////////////////////////////////////////////////////
// override for intellisense .. ONLY FOR DEVELOPMENT
//#ifndef X11_ENABLED
//#define X11_ENABLED
//#endif
//#define GLES3_BACKEND_ENABLED
/////////////////////////////////////////////////////
#if defined(GLES3_ENABLED) || defined(GLES_ENABLED)
#define GLES3_BACKEND_ENABLED
#endif // defined(GLES3_ENABLED) || defined(GLES_ENABLED)
#endif // RASTERIZER_PLATFORMS_H

View file

@ -29,7 +29,7 @@
/*************************************************************************/
#include "rasterizer_scene_gles3.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
// TODO: 3D support not implemented yet.
@ -471,4 +471,4 @@ void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter
RasterizerSceneGLES3::RasterizerSceneGLES3() {
}
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED

View file

@ -31,8 +31,7 @@
#ifndef RASTERIZER_SCENE_OPENGL_H
#define RASTERIZER_SCENE_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/math/camera_matrix.h"
#include "core/templates/rid_owner.h"
@ -41,12 +40,11 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
#include "shaders/scene.glsl.gen.h"
class RasterizerSceneGLES3 : public RendererSceneRender {
public:
struct State {
SceneShaderGLES3 scene_shader;
//SceneShaderGLES3 scene_shader;
} state;
GeometryInstance *geometry_instance_create(RID p_base) override;
@ -227,6 +225,6 @@ public:
RasterizerSceneGLES3();
};
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED
#endif // RASTERIZER_SCENE_OPENGL_H

View file

@ -1,77 +0,0 @@
/*************************************************************************/
/* rasterizer_storage_common.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 RASTERIZER_STORAGE_COMMON_H
#define RASTERIZER_STORAGE_COMMON_H
class RasterizerStorageCommon {
public:
enum FVF {
FVF_UNBATCHED,
FVF_REGULAR,
FVF_COLOR,
FVF_LIGHT_ANGLE,
FVF_MODULATED,
FVF_LARGE,
};
// these flags are specifically for batching
// some of the logic is thus in rasterizer_storage.cpp
// we could alternatively set bitflags for each 'uses' and test on the fly
enum BatchFlags {
PREVENT_COLOR_BAKING = 1 << 0,
PREVENT_VERTEX_BAKING = 1 << 1,
// custom vertex shaders using BUILTINS that vary per item
PREVENT_ITEM_JOINING = 1 << 2,
USE_MODULATE_FVF = 1 << 3,
USE_LARGE_FVF = 1 << 4,
};
enum BatchType : uint16_t {
BT_DEFAULT = 0,
BT_RECT = 1,
BT_LINE = 2,
BT_LINE_AA = 3,
BT_POLY = 4,
BT_DUMMY = 5, // dummy batch is just used to keep the batch creation loop simple
};
enum BatchTypeFlags {
BTF_DEFAULT = 1 << BT_DEFAULT,
BTF_RECT = 1 << BT_RECT,
BTF_LINE = 1 << BT_LINE,
BTF_LINE_AA = 1 << BT_LINE_AA,
BTF_POLY = 1 << BT_POLY,
};
};
#endif // RASTERIZER_STORAGE_COMMON_H

View file

@ -28,14 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
//#define OPENGL_DISABLE_RENDER_TARGETS
#include "rasterizer_storage_gles3.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/config/project_settings.h"
#include "core/math/transform_3d.h"
#include "drivers/gles3/rasterizer_storage_common.h"
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "servers/rendering/shader_language.h"
@ -1061,12 +1058,12 @@ void RasterizerStorageGLES3::_texture_set_state_from_flags(Texture *p_tex) {
if (((p_tex->flags & TEXTURE_FLAG_REPEAT) || (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT)) && p_tex->target != GL_TEXTURE_CUBE_MAP) {
if (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT) {
p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
} else {
p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
}
} else {
p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
}
}
@ -1285,21 +1282,43 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
}
RID RasterizerStorageGLES3::canvas_texture_allocate() {
return RID();
return canvas_texture_owner.allocate_rid();
}
void RasterizerStorageGLES3::canvas_texture_initialize(RID p_rid) {
canvas_texture_owner.initialize_rid(p_rid);
}
void RasterizerStorageGLES3::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
switch (p_channel) {
case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
ct->diffuse = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
ct->normal_map = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
ct->specular = p_texture;
} break;
}
}
void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
ct->specular_color.r = p_specular_color.r;
ct->specular_color.g = p_specular_color.g;
ct->specular_color.b = p_specular_color.b;
ct->specular_color.a = p_shininess;
}
void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
ct->texture_filter = p_filter;
}
void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
ct->texture_repeat = p_repeat;
}
RID RasterizerStorageGLES3::sky_create() {
@ -1309,169 +1328,14 @@ RID RasterizerStorageGLES3::sky_create() {
}
void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
Sky *sky = sky_owner.get_or_null(p_sky);
ERR_FAIL_COND(!sky);
if (sky->panorama.is_valid()) {
sky->panorama = RID();
glDeleteTextures(1, &sky->radiance);
sky->radiance = 0;
}
sky->panorama = p_panorama;
if (!sky->panorama.is_valid()) {
return; // the panorama was cleared
}
Texture *texture = texture_owner.get_or_null(sky->panorama);
if (!texture) {
sky->panorama = RID();
ERR_FAIL_COND(!texture);
}
// glBindVertexArray(0) and more
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
for (int i = 0; i < RS::ARRAY_MAX - 1; i++) {
//glDisableVertexAttribArray(i);
}
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, resources.radical_inverse_vdc_cache_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// New cubemap that will hold the mipmaps with different roughness values
glActiveTexture(GL_TEXTURE2);
glGenTextures(1, &sky->radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
int size = p_radiance_size / 2; //divide by two because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid)
GLenum internal_format = GL_RGB;
GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
// Set the initial (empty) mipmaps
// Mobile hardware (PowerVR specially) prefers this approach,
// the previous approach with manual lod levels kills the game.
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
// No filters for now
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Framebuffer
bind_framebuffer(resources.mipmap_blur_fbo);
int mipmaps = 6;
int lod = 0;
int mm_level = mipmaps;
size = p_radiance_size / 2;
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true);
shaders.cubemap_filter.bind();
// third, render to the framebuffer using separate textures, then copy to mipmaps
while (size >= 1) {
//make framebuffer size the texture size, need to use a separate texture for compatibility
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0);
if (lod == 1) {
//bind panorama for smaller lods
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
shaders.cubemap_filter.bind();
}
glViewport(0, 0, size, size);
bind_quad_array();
glActiveTexture(GL_TEXTURE2); //back to panorama
for (int i = 0; i < 6; i++) {
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::FACE_ID, i);
float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1;
roughness = MIN(1.0, roughness); //keep max at 1
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, roughness);
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, false);
//glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size);
}
size >>= 1;
mm_level--;
lod++;
}
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
// restore ranges
glActiveTexture(GL_TEXTURE2); //back to panorama
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE3); //back to panorama
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
//reset flags on Sky Texture that may have changed
texture_set_flags(sky->panorama, texture->flags);
// Framebuffer did its job. thank mr framebuffer
glActiveTexture(GL_TEXTURE0); //back to panorama
bind_framebuffer_system();
}
/* SHADER API */
RID RasterizerStorageGLES3::shader_allocate() {
Shader *shader = memnew(Shader);
shader->mode = RS::SHADER_SPATIAL;
shader->shader = &scene->state.scene_shader;
shader->mode = RS::SHADER_CANVAS_ITEM;
//shader->shader = &scene->state.scene_shader;
RID rid = shader_owner.make_rid(shader);
_shader_make_dirty(shader);
shader->self = rid;
@ -1510,16 +1374,22 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code)
String mode_string = ShaderLanguage::get_shader_type(p_code);
RS::ShaderMode mode;
if (mode_string == "canvas_item")
if (mode_string == "canvas_item") {
mode = RS::SHADER_CANVAS_ITEM;
else if (mode_string == "particles")
} else if (mode_string == "particles") {
mode = RS::SHADER_PARTICLES;
else
} else if (mode_string == "sky") {
mode = RS::SHADER_SKY;
} else if (mode_string == "spatial") {
mode = RS::SHADER_SPATIAL;
} else {
mode = RS::SHADER_MAX;
ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
}
if (shader->custom_code_id && mode != shader->mode) {
shader->shader->free_custom_shader(shader->custom_code_id);
shader->custom_code_id = 0;
if (shader->version.is_valid() && mode != shader->mode) {
shader->shader->version_free(shader->version);
shader->version = RID();
}
shader->mode = mode;
@ -1529,13 +1399,15 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code)
shader->shader = &canvas->state.canvas_shader;
} else if (mode == RS::SHADER_SPATIAL) {
shader->shader = &scene->state.scene_shader;
//shader->shader = &scene->state.scene_shader;
} else if (mode == RS::SHADER_PARTICLES) {
} else if (mode == RS::SHADER_SKY) {
} else {
return;
}
if (shader->custom_code_id == 0) {
shader->custom_code_id = shader->shader->create_custom_shader();
if (shader->version.is_null() && shader->shader) {
shader->version = shader->shader->version_create();
}
_shader_make_dirty(shader);
@ -1559,8 +1431,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
return; //just invalid, but no error
}
ShaderCompilerOLDGLES3::GeneratedCode gen_code;
ShaderCompilerOLDGLES3::IdentifierActions *actions = NULL;
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions *actions = NULL;
switch (p_shader->mode) {
case RS::SHADER_CANVAS_ITEM: {
@ -1573,7 +1445,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.uses_modulate = false;
p_shader->canvas_item.uses_color = false;
p_shader->canvas_item.uses_vertex = false;
p_shader->canvas_item.batch_flags = 0;
p_shader->canvas_item.uses_world_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
@ -1608,6 +1479,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
} break;
case RS::SHADER_SPATIAL: {
// TODO remove once 3D is added back
return;
p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
@ -1670,14 +1543,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
if (p_shader->spatial.uses_screen_texture && p_shader->spatial.uses_depth_texture) {
ERR_PRINT_ONCE("Using both SCREEN_TEXTURE and DEPTH_TEXTURE is not supported in OpenGL");
}
if (p_shader->spatial.uses_depth_texture && !config.support_depth_texture) {
ERR_PRINT_ONCE("Using DEPTH_TEXTURE is not permitted on this hardware, operation will fail.");
}
} break;
default: {
@ -1690,38 +1555,23 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
return;
}
p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.custom_defines);
Vector<StringName> texture_uniform_names;
for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
}
p_shader->texture_count = gen_code.texture_uniforms.size();
p_shader->texture_hints = gen_code.texture_hints;
p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
p_shader->texture_uniforms = gen_code.texture_uniforms;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
// some logic for batching
if (p_shader->mode == RS::SHADER_CANVAS_ITEM) {
if (p_shader->canvas_item.uses_modulate | p_shader->canvas_item.uses_color) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_COLOR_BAKING;
}
if (p_shader->canvas_item.uses_vertex) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_VERTEX_BAKING;
}
if (p_shader->canvas_item.uses_world_matrix | p_shader->canvas_item.uses_extra_matrix | p_shader->canvas_item.uses_projection_matrix | p_shader->canvas_item.uses_instance_custom) {
p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_ITEM_JOINING;
}
}
p_shader->shader->set_custom_shader(p_shader->custom_code_id);
p_shader->shader->bind();
// cache uniform locations
for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
_material_make_dirty(E->self());
}
p_shader->valid = true;
p_shader->version++;
}
void RasterizerStorageGLES3::update_dirty_shaders() {
@ -1905,31 +1755,6 @@ RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const
return RID();
}
void RasterizerStorageGLES3::shader_add_custom_define(RID p_shader, const String &p_define) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
shader->shader->add_custom_define(p_define);
_shader_make_dirty(shader);
}
void RasterizerStorageGLES3::shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
shader->shader->get_custom_defines(p_defines);
}
void RasterizerStorageGLES3::shader_remove_custom_define(RID p_shader, const String &p_define) {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
shader->shader->remove_custom_define(p_define);
_shader_make_dirty(shader);
}
/* COMMON MATERIAL API */
void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
@ -2186,8 +2011,8 @@ void RasterizerStorageGLES3::_update_material(Material *p_material) {
// uniforms and other things will be set in the use_material method in ShaderGLES3
if (p_material->shader && p_material->shader->texture_count > 0) {
p_material->textures.resize(p_material->shader->texture_count);
if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
p_material->textures.resize(p_material->shader->texture_uniforms.size());
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order < 0)
@ -2325,7 +2150,7 @@ RS::SurfaceData RasterizerStorageGLES3::mesh_get_surface(RID p_mesh, int p_surfa
}
int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const {
return 0;
return 1;
}
void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
@ -3125,39 +2950,20 @@ bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
/* RENDER TARGET */
void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
// FTODO
// if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
// // pending clear request. Do that first.
// glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
// glClearColor(storage->frame.clear_request_color.r,
// storage->frame.clear_request_color.g,
// storage->frame.clear_request_color.b,
// storage->frame.clear_request_color.a);
// glClear(GL_COLOR_BUFFER_BIT);
// }
if (rt) {
if (rt->allocate_is_dirty) {
rt->allocate_is_dirty = false;
_render_target_allocate(rt);
}
// if (p_render_target.is_valid()) {
// RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target);
frame.current_rt = rt;
ERR_FAIL_COND(!rt);
frame.clear_request = false;
glViewport(0, 0, rt->width, rt->height);
// print_line("_set_current_render_target w " + itos(rt->width) + " h " + itos(rt->height));
_dims.rt_width = rt->width;
_dims.rt_height = rt->height;
_dims.win_width = rt->width;
@ -3166,17 +2972,11 @@ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
} else {
frame.current_rt = NULL;
frame.clear_request = false;
// FTODO
// glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
bind_framebuffer_system();
}
}
void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
// do not allocate a render target with no size
if (rt->width <= 0 || rt->height <= 0)
return;
@ -3515,10 +3315,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
}
void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
// there is nothing to clear when DIRECT_TO_SCREEN is used
if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN])
return;
@ -3599,10 +3395,6 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
}
RID RasterizerStorageGLES3::render_target_create() {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
// return RID();
#endif
RenderTarget *rt = memnew(RenderTarget);
Texture *t = memnew(Texture);
@ -3631,10 +3423,6 @@ RID RasterizerStorageGLES3::render_target_create() {
}
void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3643,10 +3431,6 @@ void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int
}
void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3664,11 +3448,15 @@ void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_w
//_render_target_allocate(rt);
}
RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return RID();
#endif
// TODO: convert to Size2i internally
Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, Size2());
return Size2i(rt->width, rt->height);
}
RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@ -3680,10 +3468,6 @@ RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3789,10 +3573,6 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar
}
void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3825,10 +3605,6 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
}
bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return false;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
@ -3836,10 +3612,6 @@ bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3847,10 +3619,6 @@ void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3868,10 +3636,6 @@ void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::Vie
//}
void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3879,10 +3643,6 @@ void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, boo
}
void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@ -3894,10 +3654,6 @@ void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target
}
void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = true;
@ -3909,55 +3665,23 @@ void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, co
}
bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return false;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->clear_requested;
}
Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return Color();
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, Color());
return rt->clear_color;
}
void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = false;
}
void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) {
#ifdef OPENGL_DISABLE_RENDER_TARGETS
return;
#endif
// NEW for GLES...
// This is being called at the wrong time. Instead it will be performed
// at canvas begin
return;
/*
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->clear_requested) {
return;
}
const Color &c = rt->clear_color;
glClearColor(c.r, c.g, c.b, c.a);
// more bits?
glClear(GL_COLOR_BUFFER_BIT);
*/
}
void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
@ -4160,11 +3884,17 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
Texture *t = texture_owner.get_or_null(p_rid);
// can't free a render target texture
ERR_FAIL_COND_V(t->render_target, true);
if (t->canvas_texture) {
memdelete(t->canvas_texture);
}
info.texture_mem -= t->total_data_size;
texture_owner.free(p_rid);
memdelete(t);
return true;
} else if (canvas_texture_owner.owns(p_rid)) {
canvas_texture_owner.free(p_rid);
return true;
} else if (sky_owner.owns(p_rid)) {
Sky *sky = sky_owner.get_or_null(p_rid);
@ -4176,8 +3906,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.get_or_null(p_rid);
if (shader->shader && shader->custom_code_id) {
shader->shader->free_custom_shader(shader->custom_code_id);
if (shader->shader && shader->version.is_valid()) {
shader->shader->version_free(shader->version);
}
if (shader->dirty_list.in_list()) {
@ -4482,7 +4212,6 @@ void RasterizerStorageGLES3::initialize() {
}
}
// FTODO
config.keep_original_textures = true; // false
config.shrink_textures_x2 = false;
config.depth_internalformat = GL_DEPTH_COMPONENT;
@ -4654,10 +4383,12 @@ void RasterizerStorageGLES3::initialize() {
// OR max_vertex_texture_image_units is zero
config.use_skeleton_software = (config.float_texture_supported == false) || (config.max_vertex_texture_image_units == 0);
shaders.copy.init();
shaders.cubemap_filter.init();
bool ggx_hq = false; //GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
shaders.copy.initialize();
shaders.copy_version = shaders.copy.version_create(); //TODO
shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
//shaders.cubemap_filter.init();
//bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
//shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
{
// quad for copying stuff
@ -4831,4 +4562,8 @@ RasterizerStorageGLES3::RasterizerStorageGLES3() {
config.should_orphan = true;
}
#endif // GLES3_BACKEND_ENABLED
RasterizerStorageGLES3::~RasterizerStorageGLES3() {
shaders.copy.version_free(shaders.copy_version);
}
#endif // GLES3_ENABLED

View file

@ -31,21 +31,17 @@
#ifndef RASTERIZER_STORAGE_OPENGL_H
#define RASTERIZER_STORAGE_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "drivers/gles3/rasterizer_asserts.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "shader_compiler_old_gles3.h"
#include "shader_old_gles3.h"
#include "shaders/copy.glsl.gen.h"
#include "shaders/cubemap_filter.glsl.gen.h"
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
@ -134,14 +130,15 @@ public:
} resources;
mutable struct Shaders {
ShaderCompilerOLDGLES3 compiler;
ShaderCompiler compiler;
CopyShaderGLES3 copy;
CubemapFilterShaderGLES3 cubemap_filter;
RID copy_version;
//CubemapFilterShaderGLES3 cubemap_filter;
ShaderCompilerOLDGLES3::IdentifierActions actions_canvas;
ShaderCompilerOLDGLES3::IdentifierActions actions_scene;
ShaderCompilerOLDGLES3::IdentifierActions actions_particles;
ShaderCompiler::IdentifierActions actions_canvas;
ShaderCompiler::IdentifierActions actions_scene;
ShaderCompiler::IdentifierActions actions_particles;
} shaders;
@ -182,62 +179,6 @@ public:
void bind_quad_array() const;
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////DATA///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/*
struct Instantiable {
RID self;
SelfList<InstanceBaseDependency>::List instance_list;
_FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) {
SelfList<InstanceBaseDependency> *instances = instance_list.first();
while (instances) {
instances->self()->base_changed(p_aabb, p_materials);
instances = instances->next();
}
}
_FORCE_INLINE_ void instance_remove_deps() {
SelfList<InstanceBaseDependency> *instances = instance_list.first();
while (instances) {
instances->self()->base_removed();
instances = instances->next();
}
}
Instantiable() {}
~Instantiable() {}
};
struct GeometryOwner : public Instantiable {
};
struct Geometry : public Instantiable {
enum Type {
GEOMETRY_INVALID,
GEOMETRY_SURFACE,
GEOMETRY_IMMEDIATE,
GEOMETRY_MULTISURFACE
};
Type type;
RID material;
uint64_t last_pass;
uint32_t index;
void material_changed_notify() {}
Geometry() {
last_pass = 0;
index = 0;
}
};
*/
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////API////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
@ -257,6 +198,26 @@ public:
TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER
};
/* CANVAS TEXTURE API (2D) */
struct CanvasTexture {
RID diffuse;
RID normal_map;
RID specular;
Color specular_color = Color(1, 1, 1, 1);
float shininess = 1.0;
RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
Size2i size_cache = Size2i(1, 1);
bool use_normal_cache = false;
bool use_specular_cache = false;
bool cleared_cache = true;
};
RID_Owner<CanvasTexture, true> canvas_texture_owner;
struct RenderTarget;
struct Texture {
@ -309,6 +270,8 @@ public:
RS::TextureDetectCallback detect_normal;
void *detect_normal_ud;
CanvasTexture *canvas_texture = nullptr;
// some silly opengl shenanigans where
// texture coords start from bottom left, means we need to draw render target textures upside down
// to be compatible with vulkan etc.
@ -436,7 +399,7 @@ public:
glTexParameteri(p_target, GL_TEXTURE_MIN_FILTER, pmin);
glTexParameteri(p_target, GL_TEXTURE_MAG_FILTER, pmag);
}
void GLSetRepeat(RS::CanvasItemTextureRepeat p_repeat) {
void GLSetRepeat(GLenum p_target, RS::CanvasItemTextureRepeat p_repeat) {
if (p_repeat == state_repeat)
return;
state_repeat = p_repeat;
@ -451,8 +414,8 @@ public:
prep = GL_MIRRORED_REPEAT;
} break;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, prep);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, prep);
glTexParameteri(p_target, GL_TEXTURE_WRAP_S, prep);
glTexParameteri(p_target, GL_TEXTURE_WRAP_T, prep);
}
private:
@ -540,10 +503,10 @@ public:
void canvas_texture_initialize(RID p_rid) override;
void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) override;
void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) override;
void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) override;
/* SKY API */
// not sure if used in godot 4?
@ -567,22 +530,19 @@ public:
RID self;
RS::ShaderMode mode;
ShaderOLDGLES3 *shader;
ShaderGLES3 *shader;
String code;
SelfList<Material>::List materials;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
uint32_t texture_count;
uint32_t custom_code_id;
uint32_t version;
RID version;
SelfList<Shader> dirty_list;
Map<StringName, Map<int, RID>> default_textures;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
bool valid;
@ -610,12 +570,6 @@ public:
int light_mode;
// these flags are specifically for batching
// some of the logic is thus in rasterizer_storage.cpp
// we could alternatively set bitflags for each 'uses' and test on the fly
// defined in RasterizerStorageCommon::BatchFlags
unsigned int batch_flags;
bool uses_screen_texture;
bool uses_screen_uv;
bool uses_time;
@ -686,8 +640,7 @@ public:
dirty_list(this) {
shader = NULL;
valid = false;
custom_code_id = 0;
version = 1;
version = RID();
last_pass = 0;
}
};
@ -711,10 +664,6 @@ public:
RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
void shader_add_custom_define(RID p_shader, const String &p_define);
void shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const;
void shader_remove_custom_define(RID p_shader, const String &p_define);
void _update_shader(Shader *p_shader) const;
void update_dirty_shaders();
@ -838,6 +787,44 @@ public:
/* MULTIMESH API */
struct MultiMesh {
RID mesh;
int instances = 0;
RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D;
bool uses_colors = false;
bool uses_custom_data = false;
int visible_instances = -1;
AABB aabb;
bool aabb_dirty = false;
bool buffer_set = false;
uint32_t stride_cache = 0;
uint32_t color_offset_cache = 0;
uint32_t custom_data_offset_cache = 0;
Vector<float> data_cache; //used if individual setting is used
bool *data_cache_dirty_regions = nullptr;
uint32_t data_cache_used_dirty_regions = 0;
RID buffer; //storage buffer
RID uniform_set_3d;
RID uniform_set_2d;
bool dirty = false;
MultiMesh *dirty_list = nullptr;
Dependency dependency;
};
mutable RID_Owner<MultiMesh, true> multimesh_owner;
MultiMesh *multimesh_dirty_list = nullptr;
_FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const;
_FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb);
_FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb);
_FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
void _update_dirty_multimeshes();
RID multimesh_allocate() override;
void multimesh_initialize(RID p_rid) override;
void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override;
@ -862,6 +849,29 @@ public:
void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override;
int multimesh_get_visible_instances(RID p_multimesh) const override;
_FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
return multimesh->xform_format;
}
_FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
return multimesh->uses_colors;
}
_FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
return multimesh->uses_custom_data;
}
_FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
if (multimesh->visible_instances >= 0) {
return multimesh->visible_instances;
}
return multimesh->instances;
}
/* SKELETON API */
RID skeleton_allocate() override;
@ -1258,6 +1268,7 @@ public:
RID render_target_create() override;
void render_target_set_position(RID p_render_target, int p_x, int p_y) override;
void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
Size2i render_target_get_size(RID p_render_target);
RID render_target_get_texture(RID p_render_target) override;
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
@ -1330,7 +1341,7 @@ public:
bool clear_request;
Color clear_request_color;
float time[4];
float time;
float delta;
uint64_t count;
@ -1410,6 +1421,7 @@ public:
}
RasterizerStorageGLES3();
~RasterizerStorageGLES3();
};
inline bool RasterizerStorageGLES3::safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const {
@ -1445,10 +1457,9 @@ inline void RasterizerStorageGLES3::buffer_orphan_and_upload(unsigned int p_buff
}
#endif
}
RAST_DEV_DEBUG_ASSERT((p_offset + p_data_size) <= p_buffer_size);
glBufferSubData(p_target, p_offset, p_data_size, p_data);
}
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED
#endif // RASTERIZER_STORAGE_OPENGL_H

File diff suppressed because it is too large Load diff

View file

@ -1,106 +0,0 @@
/*************************************************************************/
/* shader_compiler_gles3.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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_COMPILER_OLD_OPENGL_H
#define SHADER_COMPILER_OLD_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#include "core/string/string_builder.h"
#include "core/templates/pair.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/shader_types.h"
#include "servers/rendering_server.h"
class ShaderCompilerOLDGLES3 {
public:
struct IdentifierActions {
Map<StringName, Pair<int *, int>> render_mode_values;
Map<StringName, bool *> render_mode_flags;
Map<StringName, bool *> usage_flag_pointers;
Map<StringName, bool *> write_flag_pointers;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
};
struct GeneratedCode {
Vector<CharString> custom_defines;
Vector<StringName> uniforms;
Vector<StringName> texture_uniforms;
Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
String vertex_global;
String vertex;
String fragment_global;
String fragment;
String light;
bool uses_fragment_time;
bool uses_vertex_time;
};
private:
ShaderLanguage parser;
struct DefaultIdentifierActions {
Map<StringName, String> renames;
Map<StringName, String> render_mode_defines;
Map<StringName, String> usage_defines;
};
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
String _dump_node_code(ShaderLanguage::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 = true);
StringName current_func_name;
StringName vertex_name;
StringName fragment_name;
StringName light_name;
StringName time_name;
Set<StringName> used_name_defines;
Set<StringName> used_flag_pointers;
Set<StringName> used_rmode_defines;
Set<StringName> internal_functions;
DefaultIdentifierActions actions[RS::SHADER_MAX];
// compatibility with godot 4
static ShaderLanguage::DataType _get_variable_type(const StringName &p_type);
public:
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
ShaderCompilerOLDGLES3();
};
#endif // GLES3_BACKEND_ENABLED
#endif // SHADER_COMPILER_OPENGL_H

View file

@ -29,7 +29,7 @@
/*************************************************************************/
#include "shader_gles3.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/io/compression.h"
#include "core/io/dir_access.h"
@ -111,8 +111,8 @@ void ShaderGLES3::_setup(const char *p_vertex_code, const char *p_fragment_code,
specialization_count = p_specialization_count;
specialization_default_mask = 0;
for (int i = 0; i < specialization_count; i++) {
if (specializations[i].defalut_value) {
specialization_default_mask |= (1 << i);
if (specializations[i].default_value) {
specialization_default_mask |= (uint64_t(1) << uint64_t(i));
}
}
variant_defines = p_variants;
@ -150,7 +150,7 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
#endif
for (int i = 0; i < specialization_count; i++) {
if (p_specialization & (1 << uint32_t(i))) {
if (p_specialization & (uint64_t(1) << uint64_t(i))) {
builder.append("#define " + String(specializations[i].name) + "\n");
}
}
@ -232,7 +232,7 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
glDeleteProgram(spec.id);
spec.id = 0;
ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?");
ERR_PRINT("No OpenGL vertex shader compiler log.");
} else {
if (iloglen == 0) {
iloglen = 4096; // buggy driver (Adreno 220+)
@ -263,24 +263,24 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
StringBuilder builder;
_build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT], p_specialization);
spec.vert_id = glCreateShader(GL_FRAGMENT_SHADER);
spec.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
String builder_string = builder.as_string();
CharString cs = builder_string.utf8();
const char *cstr = cs.ptr();
glShaderSource(spec.vert_id, 1, &cstr, nullptr);
glCompileShader(spec.vert_id);
glShaderSource(spec.frag_id, 1, &cstr, nullptr);
glCompileShader(spec.frag_id);
glGetShaderiv(spec.vert_id, GL_COMPILE_STATUS, &status);
glGetShaderiv(spec.frag_id, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLsizei iloglen;
glGetShaderiv(spec.vert_id, GL_INFO_LOG_LENGTH, &iloglen);
glGetShaderiv(spec.frag_id, GL_INFO_LOG_LENGTH, &iloglen);
if (iloglen < 0) {
glDeleteShader(spec.vert_id);
glDeleteShader(spec.frag_id);
glDeleteProgram(spec.id);
spec.id = 0;
ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?");
ERR_PRINT("No OpenGL fragment shader compiler log.");
} else {
if (iloglen == 0) {
iloglen = 4096; // buggy driver (Adreno 220+)
@ -288,7 +288,7 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
ilogmem[iloglen] = '\0';
glGetShaderInfoLog(spec.vert_id, iloglen, &iloglen, ilogmem);
glGetShaderInfoLog(spec.frag_id, iloglen, &iloglen, ilogmem);
String err_string = name + ": Fragment shader compilation failed:\n";
@ -297,7 +297,7 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
_display_error_with_code(err_string, builder_string);
Memory::free_static(ilogmem);
glDeleteShader(spec.vert_id);
glDeleteShader(spec.frag_id);
glDeleteProgram(spec.id);
spec.id = 0;
}
@ -309,6 +309,10 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
glAttachShader(spec.id, spec.frag_id);
glAttachShader(spec.id, spec.vert_id);
//for (int i = 0; i < attribute_pair_count; i++) {
// glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
//}
glLinkProgram(spec.id);
glGetProgramiv(spec.id, GL_LINK_STATUS, &status);
@ -370,9 +374,9 @@ void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_
}
for (int i = 0; i < ubo_count; i++) {
GLint loc = glGetUniformLocation(spec.id, ubo_pairs[i].name);
GLint loc = glGetUniformBlockIndex(spec.id, ubo_pairs[i].name);
if (loc >= 0) {
glUniform1i(loc, ubo_pairs[i].index);
glUniformBlockBinding(spec.id, loc, ubo_pairs[i].index);
}
}
// textures
@ -542,6 +546,11 @@ void ShaderGLES3::_save_to_cache(Version *p_version) {
}
void ShaderGLES3::_clear_version(Version *p_version) {
// Variants not compiled yet, just return
if (p_version->variants.size() == 0) {
return;
}
for (int i = 0; i < variant_count; i++) {
for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) {
if (it.valid) {
@ -559,6 +568,8 @@ void ShaderGLES3::_initialize_version(Version *p_version) {
ERR_FAIL_COND(p_version->variants.size() > 0);
p_version->variants.reserve(variant_count);
for (int i = 0; i < variant_count; i++) {
OAHashMap<uint64_t, Version::Specialization> variant;
p_version->variants.push_back(variant);
Version::Specialization spec;
_compile_specialization(spec, i, p_version, specialization_default_mask);
p_version->variants[i].insert(specialization_default_mask, spec);

View file

@ -40,8 +40,7 @@
#include "core/variant/variant.h"
#include "servers/rendering_server.h"
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
// This must come first to avoid windows.h mess
#include "platform_config.h"
@ -70,13 +69,17 @@ protected:
struct Specialization {
const char *name;
bool defalut_value = false;
bool default_value = false;
};
private:
//versions
CharString general_defines;
// A version is a high-level construct which is a combination of built-in and user-defined shader code
// Variants use #idefs to toggle behaviour on and off to change behaviour of the shader
// Specializations use #ifdefs to toggle behaviour on and off for performance, on supporting hardware, they will compile a version with everything enabled, and then compile more copies to improve performance
// Use specializations to enable and disabled advanced features, use variants to toggle behaviour when different data may be used (e.g. using a samplerArray vs a sampler)
struct Version {
Vector<StringName> texture_uniforms;
CharString uniforms;
@ -172,6 +175,7 @@ private:
int variant_count = 0;
int base_texture_index = 0;
Version::Specialization *current_shader = nullptr;
protected:
ShaderGLES3();
@ -209,6 +213,14 @@ protected:
ERR_FAIL_COND(!spec->ok); // Should never happen
glUseProgram(spec->id);
current_shader = spec;
}
_FORCE_INLINE_ int _version_get_uniform(int p_which, RID p_version, int p_variant, uint64_t p_specialization) {
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
Version *version = version_owner.get_or_null(p_version);
ERR_FAIL_COND_V(!version, -1);
return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which];
}
virtual void _init() = 0;

File diff suppressed because it is too large Load diff

View file

@ -1,277 +0,0 @@
/*************************************************************************/
/* 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

View file

@ -4,14 +4,4 @@ Import("env")
if "GLES3_GLSL" in env["BUILDERS"]:
env.GLES3_GLSL("canvas.glsl")
if "GLES3_OLD_GLSL" in env["BUILDERS"]:
env.GLES3_OLD_GLSL("copy.glsl")
env.GLES3_OLD_GLSL("canvas_old.glsl")
env.GLES3_OLD_GLSL("canvas_shadow.glsl")
env.GLES3_OLD_GLSL("scene.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")
env.GLES3_GLSL("copy.glsl")

View file

@ -1,22 +1,19 @@
/* clang-format off */
#[modes]
mode_quad =
mode_ninepatch = #define USE_NINEPATCH
mode_primitive = #define USE_PRIMITIVE
mode_attributes = #define USE_ATTRIBUTES
mode_ninepatch = #define USE_NINEPATCH
mode_primitive = #define USE_PRIMITIVE
mode_attributes = #define USE_ATTRIBUTES
#[specializations]
DISABLE_LIGHTING = false
DISABLE_LIGHTING = false
#[vertex]
#version 450
#VERSION_DEFINES
#ifdef USE_ATTRIBUTES
layout(location = 0) in vec2 vertex_attrib;
layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
@ -24,14 +21,16 @@ layout(location = 10) in uvec4 bone_attrib;
layout(location = 11) in vec4 weight_attrib;
#endif
/* clang-format on */
#include "canvas_uniforms_inc.glsl"
#include "stdlib_inc.glsl"
uniform sampler2D transforms_texture; //texunit:-1
out vec2 uv_interp;
out vec4 color_interp;
out vec2 vertex_interp;
flat out int draw_data_instance;
#ifdef USE_NINEPATCH
@ -52,6 +51,7 @@ layout(std140) uniform MaterialUniforms{
void main() {
vec4 instance_custom = vec4(0.0);
draw_data_instance = gl_InstanceID;
#ifdef USE_PRIMITIVE
//weird bug,
@ -60,18 +60,18 @@ void main() {
vec2 uv;
vec4 color;
if (gl_VertexIndex == 0) {
vertex = draw_data.points[0];
uv = draw_data.uvs[0];
color = vec4(unpackHalf2x16(draw_data.colors[0]), unpackHalf2x16(draw_data.colors[1]));
} else if (gl_VertexIndex == 1) {
vertex = draw_data.points[1];
uv = draw_data.uvs[1];
color = vec4(unpackHalf2x16(draw_data.colors[2]), unpackHalf2x16(draw_data.colors[3]));
if (gl_VertexID == 0) {
vertex = draw_data[draw_data_instance].point_a;
uv = draw_data[draw_data_instance].uv_a;
color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_a_rg), unpackHalf2x16(draw_data[draw_data_instance].color_a_ba));
} else if (gl_VertexID == 1) {
vertex = draw_data[draw_data_instance].point_b;
uv = draw_data[draw_data_instance].uv_b;
color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_b_rg), unpackHalf2x16(draw_data[draw_data_instance].color_b_ba));
} else {
vertex = draw_data.points[2];
uv = draw_data.uvs[2];
color = vec4(unpackHalf2x16(draw_data.colors[4]), unpackHalf2x16(draw_data.colors[5]));
vertex = draw_data[draw_data_instance].point_c;
uv = draw_data[draw_data_instance].uv_c;
color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_c_rg), unpackHalf2x16(draw_data[draw_data_instance].color_c_ba));
}
uvec4 bones = uvec4(0, 0, 0, 0);
vec4 bone_weights = vec4(0.0);
@ -79,7 +79,7 @@ void main() {
#elif defined(USE_ATTRIBUTES)
vec2 vertex = vertex_attrib;
vec4 color = color_attrib * draw_data.modulation;
vec4 color = color_attrib * draw_data[draw_data_instance].modulation;
vec2 uv = uv_attrib;
uvec4 bones = bone_attrib;
@ -87,24 +87,22 @@ void main() {
#else
vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
vec2 vertex_base = vertex_base_arr[gl_VertexIndex];
vec2 vertex_base = vertex_base_arr[gl_VertexID];
vec2 uv = draw_data.src_rect.xy + abs(draw_data.src_rect.zw) * ((draw_data.flags & FLAGS_TRANSPOSE_RECT) != 0 ? vertex_base.yx : vertex_base.xy);
vec4 color = draw_data.modulation;
vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0)));
vec2 uv = draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw) * ((draw_data[draw_data_instance].flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy);
vec4 color = draw_data[draw_data_instance].modulation;
vec2 vertex = draw_data[draw_data_instance].dst_rect.xy + abs(draw_data[draw_data_instance].dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data[draw_data_instance].src_rect.zw, vec2(0.0, 0.0)));
uvec4 bones = uvec4(0, 0, 0, 0);
#endif
mat4 world_matrix = mat4(vec4(draw_data.world_x, 0.0, 0.0), vec4(draw_data.world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data.world_ofs, 0.0, 1.0));
mat4 world_matrix = mat4(vec4(draw_data[draw_data_instance].world_x, 0.0, 0.0), vec4(draw_data[draw_data_instance].world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data[draw_data_instance].world_ofs, 0.0, 1.0));
#define FLAGS_INSTANCING_MASK 0x7F
#define FLAGS_INSTANCING_HAS_COLORS (1 << 7)
#define FLAGS_INSTANCING_HAS_CUSTOM_DATA (1 << 8)
uint instancing = draw_data.flags & FLAGS_INSTANCING_MASK;
// MultiMeshes don't batch, so always read from draw_data[0]
uint instancing = draw_data[0].flags & FLAGS_INSTANCING_MASK;
#ifdef USE_ATTRIBUTES
/*
if (instancing > 1) {
// trails
@ -112,7 +110,7 @@ void main() {
uint trail_size = instancing;
uint offset = trail_size * stride * gl_InstanceIndex;
uint offset = trail_size * stride * gl_InstanceID;
vec4 pcolor;
vec2 new_vertex;
@ -141,31 +139,32 @@ void main() {
vertex = new_vertex;
color *= pcolor;
} else
} else*/
#endif // USE_ATTRIBUTES
/*
{
if (instancing == 1) {
uint stride = 2;
{
if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_COLORS)) {
if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) {
stride += 1;
}
if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
stride += 1;
}
}
uint offset = stride * gl_InstanceIndex;
uint offset = stride * gl_InstanceID;
mat4 matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
offset += 2;
if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_COLORS)) {
if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) {
color *= transforms.data[offset];
offset += 1;
}
if (bool(draw_data.flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
instance_custom = transforms.data[offset];
}
@ -173,11 +172,11 @@ void main() {
world_matrix = world_matrix * matrix;
}
}
*/
#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE)
if (bool(draw_data.flags & FLAGS_USING_PARTICLES)) {
if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_PARTICLES)) {
//scale by texture size
vertex /= draw_data.color_texture_pixel_size;
vertex /= draw_data[draw_data_instance].color_texture_pixel_size;
}
#endif
@ -189,7 +188,7 @@ void main() {
}
#ifdef USE_NINEPATCH
pixel_size_interp = abs(draw_data.dst_rect.zw) * vertex_base;
pixel_size_interp = abs(draw_data[draw_data_instance].dst_rect.zw) * vertex_base;
#endif
#if !defined(SKIP_TRANSFORM_USED)
@ -198,7 +197,7 @@ void main() {
color_interp = color;
if (canvas_data.use_pixel_snap) {
if (use_pixel_snap) {
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
// offset uv by a small amount to avoid
@ -207,7 +206,7 @@ void main() {
#ifdef USE_ATTRIBUTES
#if 0
if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone
if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone
//skeleton transform
ivec4 bone_indicesi = ivec4(bone_indices);
@ -247,12 +246,12 @@ void main() {
#endif
#endif
vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
vertex_interp = vertex;
uv_interp = uv;
gl_Position = canvas_data.screen_transform * vec4(vertex, 0.0, 1.0);
gl_Position = screen_transform * vec4(vertex, 0.0, 1.0);
#ifdef USE_POINT_SIZE
gl_PointSize = point_size;
@ -261,11 +260,8 @@ void main() {
#[fragment]
#version 450
#VERSION_DEFINES
#include "canvas_uniforms_inc.glsl"
#include "stdlib_inc.glsl"
uniform sampler2D atlas_texture; //texunit:-2
uniform sampler2D shadow_atlas_texture; //texunit:-3
@ -279,6 +275,7 @@ uniform sampler2D color_texture; //texunit:0
in vec2 uv_interp;
in vec4 color_interp;
in vec2 vertex_interp;
flat in int draw_data_instance;
#ifdef USE_NINEPATCH
@ -298,27 +295,27 @@ uniform MaterialUniforms{
#endif
vec2 screen_uv_to_sdf(vec2 p_uv) {
return canvas_data.screen_to_sdf * p_uv;
return screen_to_sdf * p_uv;
}
float texture_sdf(vec2 p_sdf) {
vec2 uv = p_sdf * canvas_data.sdf_to_tex.xy + canvas_data.sdf_to_tex.zw;
float d = texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv).r;
vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw;
float d = texture(sdf_texture, uv).r;
d *= SDF_MAX_LENGTH;
return d * canvas_data.tex_to_sdf;
return d * tex_to_sdf;
}
vec2 texture_sdf_normal(vec2 p_sdf) {
vec2 uv = p_sdf * canvas_data.sdf_to_tex.xy + canvas_data.sdf_to_tex.zw;
vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw;
const float EPSILON = 0.001;
return normalize(vec2(
texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv + vec2(EPSILON, 0.0)).r - texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv - vec2(EPSILON, 0.0)).r,
texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv + vec2(0.0, EPSILON)).r - texture(sampler2D(sdf_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), uv - vec2(0.0, EPSILON)).r));
texture(sdf_texture, uv + vec2(EPSILON, 0.0)).r - texture(sdf_texture, uv - vec2(EPSILON, 0.0)).r,
texture(sdf_texture, uv + vec2(0.0, EPSILON)).r - texture(sdf_texture, uv - vec2(0.0, EPSILON)).r));
}
vec2 sdf_to_screen_uv(vec2 p_sdf) {
return p_sdf * canvas_data.sdf_to_screen;
return p_sdf * sdf_to_screen;
}
#GLOBALS
@ -355,7 +352,7 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo
} else if (pixel >= draw_size - margin_end) {
return (tex_size - (draw_size - pixel)) * tex_pixel_size;
} else {
if (!bool(draw_data.flags & FLAGS_NINEPACH_DRAW_CENTER)) {
if (!bool(draw_data[draw_data_instance].flags & FLAGS_NINEPACH_DRAW_CENTER)) {
draw_center--;
}
@ -419,39 +416,39 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
#endif
) {
float shadow;
uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK;
uint shadow_mode = light_data[light_base].flags & LIGHT_FLAGS_FILTER_MASK;
if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) {
shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x;
shadow = textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
} else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) {
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
shadow = 0.0;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
shadow /= 5.0;
} else { //PCF13
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
shadow = 0.0;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x;
shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 6.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 5.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 4.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 3.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 3.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 4.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 5.0, 0.0).x;
shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 6.0, 0.0).x;
shadow /= 13.0;
}
vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color);
vec4 shadow_color = unpackUnorm4x8(light_data[light_base].shadow_color);
#ifdef LIGHT_CODE_USED
shadow_color.rgb *= shadow_modulate;
#endif
@ -462,7 +459,7 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
}
void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) {
uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK;
uint blend_mode = light_data[light_base].flags & LIGHT_FLAGS_BLEND_MASK;
switch (blend_mode) {
case LIGHT_FLAGS_BLEND_MODE_ADD: {
@ -496,31 +493,31 @@ void main() {
int draw_center = 2;
uv = vec2(
map_ninepatch_axis(pixel_size_interp.x, abs(draw_data.dst_rect.z), draw_data.color_texture_pixel_size.x, draw_data.ninepatch_margins.x, draw_data.ninepatch_margins.z, int(draw_data.flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center),
map_ninepatch_axis(pixel_size_interp.y, abs(draw_data.dst_rect.w), draw_data.color_texture_pixel_size.y, draw_data.ninepatch_margins.y, draw_data.ninepatch_margins.w, int(draw_data.flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center));
map_ninepatch_axis(pixel_size_interp.x, abs(draw_data[draw_data_instance].dst_rect.z), draw_data[draw_data_instance].color_texture_pixel_size.x, draw_data[draw_data_instance].ninepatch_margins.x, draw_data[draw_data_instance].ninepatch_margins.z, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center),
map_ninepatch_axis(pixel_size_interp.y, abs(draw_data[draw_data_instance].dst_rect.w), draw_data[draw_data_instance].color_texture_pixel_size.y, draw_data[draw_data_instance].ninepatch_margins.y, draw_data[draw_data_instance].ninepatch_margins.w, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center));
if (draw_center == 0) {
color.a = 0.0;
}
uv = uv * draw_data.src_rect.zw + draw_data.src_rect.xy; //apply region if needed
uv = uv * draw_data[draw_data_instance].src_rect.zw + draw_data[draw_data_instance].src_rect.xy; //apply region if needed
#endif
if (bool(draw_data.flags & FLAGS_CLIP_RECT_UV)) {
uv = clamp(uv, draw_data.src_rect.xy, draw_data.src_rect.xy + abs(draw_data.src_rect.zw));
if (bool(draw_data[draw_data_instance].flags & FLAGS_CLIP_RECT_UV)) {
uv = clamp(uv, draw_data[draw_data_instance].src_rect.xy, draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw));
}
#endif
#ifndef USE_PRIMITIVE
if (bool(draw_data.flags & FLAGS_USE_MSDF)) {
float px_range = draw_data.ninepatch_margins.x;
float outline_thickness = draw_data.ninepatch_margins.y;
//float reserved1 = draw_data.ninepatch_margins.z;
//float reserved2 = draw_data.ninepatch_margins.w;
if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_MSDF)) {
float px_range = draw_data[draw_data_instance].ninepatch_margins.x;
float outline_thickness = draw_data[draw_data_instance].ninepatch_margins.y;
//float reserved1 = draw_data[draw_data_instance].ninepatch_margins.z;
//float reserved2 = draw_data[draw_data_instance].ninepatch_margins.w;
vec4 msdf_sample = texture(sampler2D(color_texture, texture_sampler), uv);
vec2 msdf_size = vec2(textureSize(sampler2D(color_texture, texture_sampler), 0));
vec4 msdf_sample = texture(color_texture, uv);
vec2 msdf_size = vec2(textureSize(color_texture, 0));
vec2 dest_size = vec2(1.0) / fwidth(uv);
float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
@ -538,11 +535,11 @@ void main() {
#else
{
#endif
color *= texture(sampler2D(color_texture, texture_sampler), uv);
color *= texture(color_texture, uv);
}
uint light_count = (draw_data.flags >> FLAGS_LIGHT_COUNT_SHIFT) & 0xF; //max 16 lights
bool using_light = light_count > 0 || canvas_data.directional_light_count > 0;
uint light_count = (draw_data[draw_data_instance].flags >> FLAGS_LIGHT_COUNT_SHIFT) & uint(0xF); //max 16 lights
bool using_light = light_count > uint(0) || directional_light_count > uint(0);
vec3 normal;
@ -552,8 +549,8 @@ void main() {
bool normal_used = false;
#endif
if (normal_used || (using_light && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) {
normal.xy = texture(sampler2D(normal_texture, texture_sampler), uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0);
if (normal_used || (using_light && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) {
normal.xy = texture(normal_texture, uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0);
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used = true;
} else {
@ -569,16 +566,16 @@ void main() {
bool specular_shininess_used = false;
#endif
if (specular_shininess_used || (using_light && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) {
specular_shininess = texture(sampler2D(specular_texture, texture_sampler), uv);
specular_shininess *= unpackUnorm4x8(draw_data.specular_shininess);
if (specular_shininess_used || (using_light && normal_used && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) {
specular_shininess = texture(specular_texture, uv);
specular_shininess *= unpackUnorm4x8(draw_data[draw_data_instance].specular_shininess);
specular_shininess_used = true;
} else {
specular_shininess = vec4(1.0);
}
#if defined(SCREEN_UV_USED)
vec2 screen_uv = gl_FragCoord.xy * canvas_data.screen_pixel_size;
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
#else
vec2 screen_uv = vec2(0.0);
#endif
@ -603,46 +600,46 @@ void main() {
if (normal_used) {
//convert by item transform
normal.xy = mat2(normalize(draw_data.world_x), normalize(draw_data.world_y)) * normal.xy;
normal.xy = mat2(normalize(draw_data[draw_data_instance].world_x), normalize(draw_data[draw_data_instance].world_y)) * normal.xy;
//convert by canvas transform
normal = normalize((canvas_data.canvas_normal_transform * vec4(normal, 0.0)).xyz);
normal = normalize((canvas_normal_transform * vec4(normal, 0.0)).xyz);
}
vec3 base_color = color.rgb;
if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) {
if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_LIGHT_MASK)) {
color = vec4(0.0); //invisible by default due to using light mask
}
#ifdef MODE_LIGHT_ONLY
color = vec4(0.0);
#else
color *= canvas_data.canvas_modulation;
color *= canvas_modulation;
#endif
#if !defined(DISABLE_LIGHTING) && !defined(MODE_UNSHADED)
for (uint i = 0; i < canvas_data.directional_light_count; i++) {
for (uint i = uint(0); i < directional_light_count; i++) {
uint light_base = i;
vec2 direction = light_array.data[light_base].position;
vec4 light_color = light_array.data[light_base].color;
vec2 direction = light_data[light_base].position;
vec4 light_color = light_data[light_base].color;
#ifdef LIGHT_CODE_USED
vec4 shadow_modulate = vec4(1.0);
light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true);
light_color = light_compute(light_vertex, vec3(direction, light_data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true);
#else
if (normal_used) {
vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_array.data[light_base].height));
vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_data[light_base].height));
light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used);
}
#endif
if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
vec4 shadow_uv = vec4(shadow_pos.x, light_array.data[light_base].shadow_y_ofs, shadow_pos.y * light_array.data[light_base].shadow_zfar_inv, 1.0);
vec4 shadow_uv = vec4(shadow_pos.x, light_data[light_base].shadow_y_ofs, shadow_pos.y * light_data[light_base].shadow_zfar_inv, 1.0);
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_CODE_USED
@ -657,36 +654,36 @@ void main() {
// Positional Lights
for (uint i = 0; i < MAX_LIGHTS_PER_ITEM; i++) {
for (uint i = uint(0); i < MAX_LIGHTS_PER_ITEM; i++) {
if (i >= light_count) {
break;
}
uint light_base;
if (i < 8) {
if (i < 4) {
light_base = draw_data.lights[0];
if (i < uint(8)) {
if (i < uint(4)) {
light_base = draw_data[draw_data_instance].lights.x;
} else {
light_base = draw_data.lights[1];
light_base = draw_data[draw_data_instance].lights.y;
}
} else {
if (i < 12) {
light_base = draw_data.lights[2];
if (i < uint(12)) {
light_base = draw_data[draw_data_instance].lights.z;
} else {
light_base = draw_data.lights[3];
light_base = draw_data[draw_data_instance].lights.w;
}
}
light_base >>= (i & 3) * 8;
light_base &= 0xFF;
light_base >>= (i & uint(3)) * uint(8);
light_base &= uint(0xFF);
vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_array.data[light_base].texture_matrix[0], light_array.data[light_base].texture_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
vec2 tex_uv_atlas = tex_uv * light_array.data[light_base].atlas_rect.zw + light_array.data[light_base].atlas_rect.xy;
vec4 light_color = textureLod(sampler2D(atlas_texture, texture_sampler), tex_uv_atlas, 0.0);
vec4 light_base_color = light_array.data[light_base].color;
vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_data[light_base].texture_matrix[0], light_data[light_base].texture_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
vec2 tex_uv_atlas = tex_uv * light_data[light_base].atlas_rect.zw + light_data[light_base].atlas_rect.xy;
vec4 light_color = textureLod(atlas_texture, tex_uv_atlas, 0.0);
vec4 light_base_color = light_data[light_base].color;
#ifdef LIGHT_CODE_USED
vec4 shadow_modulate = vec4(1.0);
vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
vec3 light_position = vec3(light_data[light_base].position, light_data[light_base].height);
light_color.rgb *= light_base_color.rgb;
light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false);
@ -695,7 +692,7 @@ void main() {
light_color.rgb *= light_base_color.rgb * light_base_color.a;
if (normal_used) {
vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
vec3 light_pos = vec3(light_data[light_base].position, light_data[light_base].height);
vec3 pos = light_vertex;
vec3 light_vec = normalize(light_pos - pos);
float cNdotL = max(0.0, dot(normal, light_vec));
@ -708,8 +705,8 @@ void main() {
light_color.a = 0.0;
}
if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
vec2 pos_norm = normalize(shadow_pos);
vec2 pos_abs = abs(pos_norm);
@ -735,10 +732,10 @@ void main() {
}
}
distance *= light_array.data[light_base].shadow_zfar_inv;
distance *= light_data[light_base].shadow_zfar_inv;
//float distance = length(shadow_pos);
vec4 shadow_uv = vec4(tex_ofs, light_array.data[light_base].shadow_y_ofs, distance, 1.0);
vec4 shadow_uv = vec4(tex_ofs, light_data[light_base].shadow_y_ofs, distance, 1.0);
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_CODE_USED

View file

@ -1,665 +0,0 @@
/* 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;
}

View file

@ -10,7 +10,7 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) highp vec3 vertex;
layout(location = 0) in highp vec3 vertex;
uniform highp mat4 projection_matrix;
/* clang-format on */

View file

@ -1,53 +1,62 @@
#define MAX_LIGHTS_PER_ITEM 16
#define MAX_LIGHTS_PER_ITEM uint(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_INSTANCING_MASK uint(0x7F)
#define FLAGS_INSTANCING_HAS_COLORS uint(1 << 7)
#define FLAGS_INSTANCING_HAS_CUSTOM_DATA uint(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_CLIP_RECT_UV uint(1 << 9)
#define FLAGS_TRANSPOSE_RECT uint(1 << 10)
#define FLAGS_USING_LIGHT_MASK uint(1 << 11)
#define FLAGS_NINEPACH_DRAW_CENTER uint(1 << 12)
#define FLAGS_USING_PARTICLES uint(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_DEFAULT_NORMAL_MAP_USED uint(1 << 26)
#define FLAGS_DEFAULT_SPECULAR_MAP_USED uint(1 << 27)
#define FLAGS_USE_MSDF (1 << 28)
#define FLAGS_USE_MSDF uint(1 << 28)
// must be always 128 bytes long
struct DrawData {
vec2 world_x;
vec2 world_y;
vec2 world_ofs;
uint flags;
uint specular_shininess;
vec2 color_texture_pixel_size;
#ifdef USE_PRIMITIVE
vec2 points[3];
vec2 uvs[3];
uint colors[6];
vec2 point_a;
vec2 point_b;
vec2 point_c;
vec2 uv_a;
vec2 uv_b;
vec2 uv_c;
uint color_a_rg;
uint color_a_ba;
uint color_b_rg;
uint color_b_ba;
uint color_c_rg;
uint color_c_ba;
#else
vec4 modulation;
vec4 ninepatch_margins;
vec4 dst_rect; //for built-in rect and UV
vec4 src_rect;
vec2 pad;
uint pad;
uint pad2;
#endif
vec2 color_texture_pixel_size;
uint lights[4];
}
uint flags;
uint specular_shininess;
uvec4 lights;
};
layout(std140) uniform GlobalVariableData { //ubo:1
vec4 global_variables[MAX_GLOBAL_VARIABLES];
@ -72,17 +81,17 @@ layout(std140) uniform CanvasData { //ubo:0
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_BLEND_MASK uint(3 << 16)
#define LIGHT_FLAGS_BLEND_MODE_ADD uint(0 << 16)
#define LIGHT_FLAGS_BLEND_MODE_SUB uint(1 << 16)
#define LIGHT_FLAGS_BLEND_MODE_MIX uint(2 << 16)
#define LIGHT_FLAGS_BLEND_MODE_MASK uint(3 << 16)
#define LIGHT_FLAGS_HAS_SHADOW uint(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)
#define LIGHT_FLAGS_FILTER_MASK uint(3 << 22)
#define LIGHT_FLAGS_SHADOW_NEAREST uint(0 << 22)
#define LIGHT_FLAGS_SHADOW_PCF5 uint(1 << 22)
#define LIGHT_FLAGS_SHADOW_PCF13 uint(2 << 22)
struct Light {
mat2x4 texture_matrix; //light to texture coordinate matrix (transposed)

View file

@ -1,5 +1,21 @@
/* clang-format off */
[vertex]
#[modes]
mode_default =
mode_cubemap = #define USE_CUBEMAP
mode_panorama = #define USE_PANORAMA
mode_copy_section = #define USE_COPY_SECTION
mode_asym_pano = #define USE_ASYM_PANO
mode_no_alpha = #define USE_NO_ALPHA
mode_custom_alpha = #define USE_CUSTOM_ALPHA
mode_multiplier = #define USE_MULTIPLIER
mode_sep_cbcr_texture = #define USE_SEP_CBCR_TEXTURE
mode_ycbcr_to_rgb = #define USE_YCBCR_TO_RGB
#[specializations]
#[vertex]
#ifdef USE_GLES_OVER_GL
#define lowp
@ -10,16 +26,16 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) highp vec4 vertex_attrib;
layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
layout(location = 4) vec3 cube_in;
layout(location = 4) in vec3 cube_in;
#else
layout(location = 4) vec2 uv_in;
layout(location = 4) in vec2 uv_in;
#endif
layout(location = 5) vec2 uv2_in;
layout(location = 5) in vec2 uv2_in;
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
out vec3 cube_interp;
@ -28,11 +44,6 @@ out vec2 uv_interp;
#endif
out vec2 uv2_interp;
// These definitions are here because the shader-wrapper builder does
// not understand `#elif defined()`
#ifdef USE_DISPLAY_TRANSFORM
#endif
#ifdef USE_COPY_SECTION
uniform highp vec4 copy_section;
#elif defined(USE_DISPLAY_TRANSFORM)
@ -60,7 +71,7 @@ void main() {
}
/* clang-format off */
[fragment]
#[fragment]
#define M_PI 3.14159265359
@ -96,7 +107,7 @@ uniform samplerCube source_cube; // texunit:0
uniform sampler2D source; // texunit:0
#endif
#ifdef SEP_CBCR_TEXTURE
#ifdef USE_SEP_CBCR_TEXTURE
uniform sampler2D CbCr; //texunit:1
#endif
@ -156,8 +167,8 @@ void main() {
vec4 color = texturePanorama(source, normalize(cube_normal.xyz));
#elif defined(USE_CUBEMAP)
vec4 color = textureCube(source_cube, normalize(cube_interp));
#elif defined(SEP_CBCR_TEXTURE)
vec4 color = texture(source_cube, normalize(cube_interp));
#elif defined(USE_SEP_CBCR_TEXTURE)
vec4 color;
color.r = texture(source, uv_interp).r;
color.gb = texture(CbCr, uv_interp).rg - vec2(0.5, 0.5);
@ -166,7 +177,7 @@ void main() {
vec4 color = texture(source, uv_interp);
#endif
#ifdef YCBCR_TO_RGB
#ifdef USE_YCBCR_TO_RGB
// YCbCr -> RGB conversion
// Using BT.601, which is the standard for SDTV is provided as a reference

View file

@ -10,9 +10,9 @@ precision mediump float;
precision mediump int;
#endif
layout(location = 0) highp vec4 vertex_attrib;
layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
layout(location = 4) vec2 uv_in;
layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;

View file

@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) highp vec2 vertex;
layout(location = 0) in highp vec2 vertex;
/* clang-format on */
layout(location = 4) highp vec2 uv;
layout(location = 4) in highp vec2 uv;
out highp vec2 uv_interp;

View file

@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) vec2 vertex_attrib;
layout(location = 0) in vec2 vertex_attrib;
/* clang-format on */
layout(location = 4) vec2 uv_in;
layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;

View file

@ -10,7 +10,7 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) highp vec2 vertex;
layout(location = 0) in highp vec2 vertex;
/* clang-format on */
uniform vec2 offset;

View file

@ -18,38 +18,38 @@ precision highp int;
// attributes
//
layout(location = 0) highp vec4 vertex_attrib;
layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
layout(location = 1) vec3 normal_attrib;
layout(location = 1) in vec3 normal_attrib;
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
layout(location = 2) vec4 tangent_attrib;
layout(location = 2) in vec4 tangent_attrib;
#endif
#if defined(ENABLE_COLOR_INTERP)
layout(location = 3) vec4 color_attrib;
layout(location = 3) in vec4 color_attrib;
#endif
#if defined(ENABLE_UV_INTERP)
layout(location = 4) vec2 uv_attrib;
layout(location = 4) in vec2 uv_attrib;
#endif
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
layout(location = 5) vec2 uv2_attrib;
layout(location = 5) in vec2 uv2_attrib;
#endif
#ifdef USE_SKELETON
#ifdef USE_SKELETON_SOFTWARE
layout(location = 13) highp vec4 bone_transform_row_0;
layout(location = 14) highp vec4 bone_transform_row_1;
layout(location = 15) highp vec4 bone_transform_row_2;
layout(location = 13) in highp vec4 bone_transform_row_0;
layout(location = 14) in highp vec4 bone_transform_row_1;
layout(location = 15) in highp vec4 bone_transform_row_2;
#else
layout(location = 6) vec4 bone_ids;
layout(location = 7) highp vec4 bone_weights;
layout(location = 6) in vec4 bone_ids;
layout(location = 7) in highp vec4 bone_weights;
uniform highp sampler2D bone_transforms; // texunit:-1
uniform ivec2 skeleton_texture_size;
@ -60,12 +60,12 @@ uniform ivec2 skeleton_texture_size;
#ifdef USE_INSTANCING
layout(location = 8) highp vec4 instance_xform_row_0;
layout(location = 9) highp vec4 instance_xform_row_1;
layout(location = 10) highp vec4 instance_xform_row_2;
layout(location = 8) in highp vec4 instance_xform_row_0;
layout(location = 9) in highp vec4 instance_xform_row_1;
layout(location = 10) in highp vec4 instance_xform_row_2;
layout(location = 11) highp vec4 instance_color;
layout(location = 12) highp vec4 instance_custom_data;
layout(location = 11) in highp vec4 instance_color;
layout(location = 12) in highp vec4 instance_custom_data;
#endif

View file

@ -0,0 +1,58 @@
//TODO: only needed by GLES_OVER_GL
uint float2half(uint f) {
return ((f >> uint(16)) & uint(0x8000)) |
((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
((f >> uint(13)) & uint(0x03ff));
}
uint half2float(uint h) {
return ((h & uint(0x8000)) << uint(16)) | (((h & uint(0x7c00)) + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13));
}
uint packHalf2x16(vec2 v) {
return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16);
}
vec2 unpackHalf2x16(uint v) {
return vec2(uintBitsToFloat(half2float(v & uint(0xffff))),
uintBitsToFloat(half2float(v >> uint(16))));
}
uint packUnorm2x16(vec2 v) {
uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0));
return uv.x | uv.y << uint(16);
}
vec2 unpackUnorm2x16(uint p) {
return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization
}
uint packSnorm2x16(vec2 v) {
uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0);
return uv.x | uv.y << uint(16);
}
vec2 unpackSnorm2x16(uint p) {
vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
}
uint packUnorm4x8(vec4 v) {
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24);
}
vec4 unpackUnorm4x8(uint p) {
return vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0
}
uint packSnorm4x8(vec4 v) {
uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0);
return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24);
}
vec4 unpackSnorm4x8(uint p) {
vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24)));
return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
}

View file

@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
layout(location = 0) vec2 vertex_attrib;
layout(location = 0) in vec2 vertex_attrib;
/* clang-format on */
layout(location = 4) vec2 uv_in;
layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;

View file

@ -29,7 +29,7 @@
/*************************************************************************/
#include "texture_loader_gles3.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/io/file_access.h"
#include "core/string/print_string.h"

View file

@ -31,8 +31,7 @@
#ifndef TEXTURE_LOADER_OPENGL_H
#define TEXTURE_LOADER_OPENGL_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_BACKEND_ENABLED
#ifdef GLES3_ENABLED
#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
@ -47,6 +46,6 @@ public:
virtual ~ResourceFormatGLES2Texture() {}
};
#endif // GLES3_BACKEND_ENABLED
#endif // GLES3_ENABLED
#endif // TEXTURE_LOADER_OPENGL_H

View file

@ -24,10 +24,10 @@ class GLES3HeaderStruct:
self.line_offset = 0
self.vertex_offset = 0
self.fragment_offset = 0
self.variant_defines=[]
self.variant_names=[]
self.specialization_names=[]
self.specialization_values=[]
self.variant_defines = []
self.variant_names = []
self.specialization_names = []
self.specialization_values = []
def include_file_in_gles3_header(filename, header_data, depth):
@ -36,25 +36,25 @@ def include_file_in_gles3_header(filename, header_data, depth):
while line:
if line.find("=") != -1 and header_data.reading=="":
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 )
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":
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 )
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
@ -66,7 +66,6 @@ def include_file_in_gles3_header(filename, header_data, depth):
header_data.line_offset += 1
header_data.vertex_offset = header_data.line_offset
continue
if line.find("#[specializations]") != -1:
header_data.reading = "specializations"
@ -225,116 +224,190 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
fd.write("\t};\n\n")
else:
fd.write("\tenum ShaderVariant { DEFAULT };\n\n")
defvariant="=DEFAULT"
defvariant = "=DEFAULT"
if header_data.specialization_names:
fd.write("\tenum Specializations {\n")
counter=0
counter = 0
for x in header_data.specialization_names:
fd.write("\t\t" + x.upper() + "=" + str(1<<counter)+",\n")
counter+=1
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_ 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#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]={(GLfloat)p_vec2.x,(GLfloat)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]={(GLint)p_vec2.x,(GLint)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]={(GLfloat)p_vec3.x,(GLfloat)p_vec3.y,(GLfloat)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"
)
defval = header_data.specialization_values[i].strip()
if defval.upper() == "TRUE" or defval == "1":
defspec |= 1 << i
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 */
(GLfloat)tr.basis.elements[0][0],
(GLfloat)tr.basis.elements[1][0],
(GLfloat)tr.basis.elements[2][0],
(GLfloat)0,
(GLfloat)tr.basis.elements[0][1],
(GLfloat)tr.basis.elements[1][1],
(GLfloat)tr.basis.elements[2][1],
(GLfloat)0,
(GLfloat)tr.basis.elements[0][2],
(GLfloat)tr.basis.elements[1][2],
(GLfloat)tr.basis.elements[2][2],
(GLfloat)0,
(GLfloat)tr.origin.x,
(GLfloat)tr.origin.y,
(GLfloat)tr.origin.z,
(GLfloat)1
};
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
}
"""
"\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(
"""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU
if header_data.uniforms:
fd.write(
"\t_FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { return _version_get_uniform(p_uniform,p_version,p_variant,p_specialization); }\n\n"
)
const Transform2D &tr = p_transform;
fd.write(
"\t#define _FU if (version_get_uniform(p_uniform,p_version,p_variant,p_specialization)<0) return; \n\n "
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color& p_color,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,col); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2& p_vec2,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU GLfloat vec2[2]={float(p_vec2.x),float(p_vec2.y)}; glUniform2fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i& p_vec2,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU GLint vec2[2]={GLint(p_vec2.x),GLint(p_vec2.y)}; glUniform2iv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3& p_vec3,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU GLfloat vec3[3]={float(p_vec3.x),float(p_vec3.y),float(p_vec3.z)}; glUniform3fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec3); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform2f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform3f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c); }\n\n"
)
fd.write(
"\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d,RID p_version,ShaderVariant p_variant"
+ defvariant
+ ",uint64_t p_specialization="
+ str(defspec)
+ ") { _FU glUniform4f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c,p_d); }\n\n"
)
fd.write(
"""\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D& p_transform,RID p_version,ShaderVariant p_variant"""
+ defvariant
+ """,uint64_t p_specialization="""
+ str(defspec)
+ """) { _FU
const Transform3D &tr = p_transform;
GLfloat matrix[16]={ /* build a 16x16 matrix */
(GLfloat)tr.basis.elements[0][0],
(GLfloat)tr.basis.elements[1][0],
(GLfloat)tr.basis.elements[2][0],
(GLfloat)0,
(GLfloat)tr.basis.elements[0][1],
(GLfloat)tr.basis.elements[1][1],
(GLfloat)tr.basis.elements[2][1],
(GLfloat)0,
(GLfloat)tr.basis.elements[0][2],
(GLfloat)tr.basis.elements[1][2],
(GLfloat)tr.basis.elements[2][2],
(GLfloat)0,
(GLfloat)tr.origin.x,
(GLfloat)tr.origin.y,
(GLfloat)tr.origin.z,
(GLfloat)1
};
glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
}
"""
)
fd.write(
"""_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D& p_transform,RID p_version,ShaderVariant p_variant"""
+ defvariant
+ """,uint64_t p_specialization="""
+ str(defspec)
+ """) { _FU
const Transform2D &tr = p_transform;
GLfloat matrix[16]={ /* build a 16x16 matrix */
(GLfloat)tr.elements[0][0],
@ -355,31 +428,33 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
(GLfloat)1
};
glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
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(
"""_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant"""
+ defvariant
+ """,uint64_t p_specialization="""
+ str(defspec)
+ """) { _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(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
}"""
)
fd.write("\n\n#undef _FU\n\n\n")
fd.write("protected:\n\n")
@ -396,15 +471,15 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n")
variant_count = 1
if len(header_data.variant_defines)>0:
if len(header_data.variant_defines) > 0:
fd.write("\t\tstatic const char* _variant_defines[]={\n")
for x in header_data.variant_defines:
fd.write('\t\t\t"' + x + '",\n')
fd.write("\t\t};\n\n")
variant_count=len(header_data.variant_defines)
variant_count = len(header_data.variant_defines)
else:
fd.write("\t\tstatic const char **_variant_defines[]={""};\n")
fd.write("\t\tstatic const char **_variant_defines[]={" "};\n")
if header_data.texunits:
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
@ -426,11 +501,11 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
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"
if defval.upper() == "TRUE" or defval == "1":
defal = "true"
else:
defval="false"
defval = "false"
fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n")
fd.write("\t\t};\n\n")
else:
@ -453,8 +528,9 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
fd.write("\t\t0};\n\n")
fd.write(
"\t\tsetup(_vertex_code,_fragment_code,\""
+ out_file_class + "\","
'\t\t_setup(_vertex_code,_fragment_code,"'
+ out_file_class
+ '",'
+ str(len(header_data.uniforms))
+ ",_uniform_strings,"
+ str(len(header_data.ubos))
@ -469,7 +545,6 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
fd.write("\t}\n\n")
fd.write("};\n\n")
fd.write("#endif\n\n")
fd.close()

View file

@ -1,528 +0,0 @@
"""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())

View file

@ -31,8 +31,6 @@
#ifndef DISPLAY_SERVER_X11_H
#define DISPLAY_SERVER_X11_H
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef X11_ENABLED
#include "servers/display_server.h"

View file

@ -33,8 +33,6 @@
#ifdef X11_ENABLED
#include "drivers/gles3/rasterizer_platforms.h"
#ifdef GLES3_ENABLED
#include "core/os/os.h"

View file

@ -48,7 +48,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
@ -79,10 +79,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
int depth_drawi = DEPTH_DRAW_OPAQUE;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@ -157,10 +157,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
}
print_line("\n**uniforms:\n" + gen_code.uniforms);
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]);
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]);
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -510,7 +510,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
{
//shader compiler
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";

View file

@ -129,7 +129,7 @@ public:
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@ -208,7 +208,7 @@ public:
}
SceneForwardClusteredShaderRD shader;
ShaderCompilerRD compiler;
ShaderCompiler compiler;
RID default_shader;
RID default_material;

View file

@ -51,7 +51,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
@ -81,10 +81,10 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
int depth_drawi = DEPTH_DRAW_OPAQUE;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@ -159,11 +159,11 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
}
print_line("\n**uniforms:\n" + gen_code.uniforms);
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]);
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]);
print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -498,7 +498,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
{
//shader compiler
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";

View file

@ -105,7 +105,7 @@ public:
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@ -184,7 +184,7 @@ public:
}
SceneForwardMobileShaderRD shader;
ShaderCompilerRD compiler;
ShaderCompiler compiler;
RID default_shader;
RID default_material;

View file

@ -1957,15 +1957,15 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
uses_screen_texture = false;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@ -2002,7 +2002,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
print_line("\n**fragment_code:\n" + gen_code.fragment);
print_line("\n**light_code:\n" + gen_code.light);
#endif
canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -2359,7 +2359,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
{
//shader compiler
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["VERTEX"] = "vertex";
actions.renames["LIGHT_VERTEX"] = "light_vertex";

View file

@ -35,10 +35,10 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_compiler.h"
class RendererCanvasRenderRD : public RendererCanvasRender {
RendererStorageRD *storage;
@ -148,7 +148,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID default_skeleton_uniform_buffer;
RID default_skeleton_texture_buffer;
ShaderCompilerRD compiler;
ShaderCompiler compiler;
} shader;
struct ShaderData : public RendererStorageRD::ShaderData {
@ -167,7 +167,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;

View file

@ -3837,9 +3837,9 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["fog"] = ShaderCompilerRD::STAGE_COMPUTE;
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE;
uses_time = false;
@ -3856,7 +3856,7 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
version = scene_singleton->volumetric_fog.shader.version_create();
}
scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines);
scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines);
ERR_FAIL_COND(!scene_singleton->volumetric_fog.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -5653,7 +5653,7 @@ void RendererSceneRenderRD::init() {
}
{
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["TIME"] = "scene_params.time";
actions.renames["PI"] = _MKSTR(Math_PI);

View file

@ -834,7 +834,7 @@ private:
float transform[16];
};
ShaderCompilerRD compiler;
ShaderCompiler compiler;
VolumetricFogShaderRD shader;
FogPushConstant push_constant;
RID volume_ubo;
@ -917,7 +917,7 @@ private:
RID pipeline;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;

View file

@ -50,9 +50,9 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["sky"] = ShaderCompilerRD::STAGE_FRAGMENT;
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT;
uses_time = false;
uses_half_res = false;
@ -112,7 +112,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
print_line("\n**light_code:\n" + gen_code.light);
#endif
scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!scene_singleton->sky.sky_shader.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -807,7 +807,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
{
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["COLOR"] = "color";
actions.renames["ALPHA"] = "alpha";

View file

@ -111,7 +111,7 @@ private:
PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@ -220,7 +220,7 @@ public:
struct SkyShader {
SkyShaderRD shader;
ShaderCompilerRD compiler;
ShaderCompiler compiler;
RID default_shader;
RID default_material;

View file

@ -2710,7 +2710,7 @@ RendererStorageRD::MaterialData::~MaterialData() {
}
}
void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton;
#ifdef TOOLS_ENABLED
Texture *roughness_detect_texture = nullptr;
@ -2936,7 +2936,7 @@ void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_
}
}
bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
if ((uint32_t)ubo_data.size() != p_ubo_size) {
p_uniform_dirty = true;
if (uniform_buffer.is_valid()) {
@ -5812,10 +5812,10 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
ShaderCompilerRD::GeneratedCode gen_code;
ShaderCompilerRD::IdentifierActions actions;
actions.entry_point_stages["start"] = ShaderCompilerRD::STAGE_COMPUTE;
actions.entry_point_stages["process"] = ShaderCompilerRD::STAGE_COMPUTE;
ShaderCompiler::GeneratedCode gen_code;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["start"] = ShaderCompiler::STAGE_COMPUTE;
actions.entry_point_stages["process"] = ShaderCompiler::STAGE_COMPUTE;
/*
uses_time = false;
@ -5837,7 +5837,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
version = base_singleton->particles_shader.shader.version_create();
}
base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines);
base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines);
ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@ -10016,7 +10016,7 @@ RendererStorageRD::RendererStorageRD() {
material_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs);
{
ShaderCompilerRD::DefaultIdentifierActions actions;
ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["COLOR"] = "PARTICLE.color";
actions.renames["VELOCITY"] = "PARTICLE.velocity";

View file

@ -36,7 +36,6 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/effects_rd.h"
#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
@ -44,6 +43,7 @@
#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_compiler.h"
class RendererStorageRD : public RendererStorage {
public:
static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
@ -152,7 +152,7 @@ public:
struct MaterialData {
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
@ -160,7 +160,7 @@ public:
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void free_parameters_uniform_set(RID p_uniform_set);
private:
@ -826,7 +826,7 @@ private:
};
ParticlesShaderRD shader;
ShaderCompilerRD compiler;
ShaderCompiler compiler;
RID default_shader;
RID default_material;
@ -877,7 +877,7 @@ private:
//PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;

View file

@ -1,5 +1,5 @@
/*************************************************************************/
/* shader_compiler_rd.cpp */
/* shader_compiler.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@ -28,11 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "shader_compiler_rd.h"
#include "shader_compiler.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
#include "renderer_storage_rd.h"
#include "servers/rendering_server.h"
#define SL ShaderLanguage
@ -277,7 +276,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
}
}
String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) {
String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) {
if (p_filter == ShaderLanguage::FILTER_DEFAULT) {
ERR_FAIL_COND_V(actions.default_filter == ShaderLanguage::FILTER_DEFAULT, String());
p_filter = actions.default_filter;
@ -289,7 +288,7 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte
return actions.sampler_array_name + "[" + itos(p_filter + (p_repeat == ShaderLanguage::REPEAT_ENABLE ? ShaderLanguage::FILTER_DEFAULT : 0)) + "]";
}
void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
int fidx = -1;
for (int i = 0; i < p_node->functions.size(); i++) {
@ -435,7 +434,7 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c
}
}
String ShaderCompilerRD::_dump_node_code(const 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 ShaderCompiler::_dump_node_code(const 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 code;
switch (p_node->type) {
@ -1332,12 +1331,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
return code;
}
ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) {
RS::GlobalVariableType gvt = ((RendererStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) {
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_type);
return RS::global_variable_type_get_shader_datatype(gvt);
}
Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
SL::ShaderCompileInfo info;
info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
@ -1383,7 +1382,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide
return OK;
}
void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) {
void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) {
actions = p_actions;
time_name = "TIME";
@ -1405,7 +1404,7 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) {
texture_functions.insert("texelFetch");
}
ShaderCompilerRD::ShaderCompilerRD() {
ShaderCompiler::ShaderCompiler() {
#if 0
/** SPATIAL SHADER **/

View file

@ -1,5 +1,5 @@
/*************************************************************************/
/* shader_compiler_rd.h */
/* shader_compiler.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef SHADER_COMPILER_RD_H
#define SHADER_COMPILER_RD_H
#ifndef SHADER_COMPILER_H
#define SHADER_COMPILER_H
#include "core/templates/pair.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/shader_types.h"
#include "servers/rendering_server.h"
class ShaderCompilerRD {
class ShaderCompiler {
public:
enum Stage {
STAGE_VERTEX,
@ -127,7 +127,7 @@ public:
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
void initialize(DefaultIdentifierActions p_actions);
ShaderCompilerRD();
ShaderCompiler();
};
#endif // SHADERCOMPILERRD_H
#endif // SHADER_COMPILER_H