mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
New OpenGL batching canvas renderer
This commit is contained in:
parent
98ac002c34
commit
99064d57db
@ -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
|
@ -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
@ -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
@ -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 *¤t_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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
@ -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
|
@ -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);
|
||||
|
@ -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
@ -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
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
58
drivers/gles3/shaders/stdlib_inc.glsl
Normal file
58
drivers/gles3/shaders/stdlib_inc.glsl
Normal 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));
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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())
|
@ -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"
|
||||
|
@ -33,8 +33,6 @@
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
|
||||
#include "drivers/gles3/rasterizer_platforms.h"
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
#include "core/os/os.h"
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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 **/
|
@ -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
|
Loading…
Reference in New Issue
Block a user