Massive improvement to GLES2 performance, rewrote most ShaderGLES2 class.

This fixes #26337
This commit is contained in:
Juan Linietsky 2019-02-27 23:49:34 -03:00
parent 9ca6ffa341
commit 5efd693384
4 changed files with 225 additions and 598 deletions

View File

@ -1265,9 +1265,9 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
} }
int tc = p_material->textures.size(); int tc = p_material->textures.size();
Pair<StringName, RID> *textures = p_material->textures.ptrw(); const Pair<StringName, RID> *textures = p_material->textures.ptr();
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw(); const ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptr();
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size); state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);

View File

@ -69,51 +69,6 @@ ShaderGLES2 *ShaderGLES2::active = NULL;
#endif #endif
void ShaderGLES2::bind_uniforms() {
if (!uniforms_dirty)
return;
// regular uniforms
const Map<uint32_t, Variant>::Element *E = uniform_defaults.front();
while (E) {
int idx = E->key();
int location = version->uniform_location[idx];
if (location < 0) {
E = E->next();
continue;
}
Variant v;
v = E->value();
_set_uniform_variant(location, v);
E = E->next();
}
// camera uniforms
const Map<uint32_t, CameraMatrix>::Element *C = uniform_cameras.front();
while (C) {
int idx = C->key();
int location = version->uniform_location[idx];
if (location < 0) {
C = C->next();
continue;
}
glUniformMatrix4fv(location, 1, GL_FALSE, &(C->get().matrix[0][0]));
C = C->next();
}
uniforms_dirty = false;
}
GLint ShaderGLES2::get_uniform_location(int p_index) const { GLint ShaderGLES2::get_uniform_location(int p_index) const {
ERR_FAIL_COND_V(!version, -1); ERR_FAIL_COND_V(!version, -1);
@ -139,28 +94,6 @@ bool ShaderGLES2::bind() {
glUseProgram(version->id); glUseProgram(version->id);
// find out uniform names and locations
int count;
glGetProgramiv(version->id, GL_ACTIVE_UNIFORMS, &count);
version->uniform_names.resize(count);
for (int i = 0; i < count; i++) {
GLchar uniform_name[1024];
int len = 0;
GLint size = 0;
GLenum type;
glGetActiveUniform(version->id, i, 1024, &len, &size, &type, uniform_name);
uniform_name[len] = '\0';
String name = String((const char *)uniform_name);
version->uniform_names.write[i] = name;
}
bind_uniforms();
DEBUG_TEST_ERROR("use program"); DEBUG_TEST_ERROR("use program");
active = this; active = this;
@ -513,6 +446,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
String native_uniform_name = _mkid(cc->texture_uniforms[i]); String native_uniform_name = _mkid(cc->texture_uniforms[i]);
GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data()); GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
v.custom_uniform_locations[cc->texture_uniforms[i]] = location; v.custom_uniform_locations[cc->texture_uniforms[i]] = location;
glUniform1i(location, i);
} }
} }
@ -732,340 +666,315 @@ void ShaderGLES2::use_material(void *p_material) {
if (E->get().texture_order >= 0) if (E->get().texture_order >= 0)
continue; // this is a texture, doesn't go here continue; // this is a texture, doesn't go here
Map<StringName, GLint>::Element *L = v->custom_uniform_locations.find(E->key());
if (!L || L->get() < 0)
continue; //uniform not valid
GLuint location = L->get();
Map<StringName, Variant>::Element *V = material->params.find(E->key()); Map<StringName, Variant>::Element *V = material->params.find(E->key());
Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value;
value.first = E->get().type;
value.second = E->get().default_value;
if (V) { if (V) {
value.second = Vector<ShaderLanguage::ConstantNode::Value>();
value.second.resize(E->get().default_value.size());
switch (E->get().type) { switch (E->get().type) {
case ShaderLanguage::TYPE_BOOL: { case ShaderLanguage::TYPE_BOOL: {
if (value.second.size() < 1)
value.second.resize(1); bool boolean = V->get();
value.second.write[0].boolean = V->get(); glUniform1i(location, boolean ? 1 : 0);
} break; } break;
case ShaderLanguage::TYPE_BVEC2: { case ShaderLanguage::TYPE_BVEC2: {
if (value.second.size() < 2)
value.second.resize(2);
int flags = V->get(); int flags = V->get();
value.second.write[0].boolean = flags & 1; glUniform2i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0);
value.second.write[1].boolean = flags & 2;
} break; } break;
case ShaderLanguage::TYPE_BVEC3: { case ShaderLanguage::TYPE_BVEC3: {
if (value.second.size() < 3)
value.second.resize(3);
int flags = V->get(); int flags = V->get();
value.second.write[0].boolean = flags & 1; glUniform3i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0);
value.second.write[1].boolean = flags & 2;
value.second.write[2].boolean = flags & 4;
} break; } break;
case ShaderLanguage::TYPE_BVEC4: { case ShaderLanguage::TYPE_BVEC4: {
if (value.second.size() < 4)
value.second.resize(4);
int flags = V->get(); int flags = V->get();
value.second.write[0].boolean = flags & 1; glUniform4i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0, (flags & 8) ? 1 : 0);
value.second.write[1].boolean = flags & 2;
value.second.write[2].boolean = flags & 4;
value.second.write[3].boolean = flags & 8;
} break;
case ShaderLanguage::TYPE_INT: {
if (value.second.size() < 1)
value.second.resize(1);
int val = V->get();
value.second.write[0].sint = val;
} break;
case ShaderLanguage::TYPE_IVEC2: {
if (value.second.size() < 2)
value.second.resize(2);
PoolIntArray val = V->get();
for (int i = 0; i < val.size(); i++) {
value.second.write[i].sint = val[i];
}
} break;
case ShaderLanguage::TYPE_IVEC3: {
if (value.second.size() < 3)
value.second.resize(3);
PoolIntArray val = V->get();
for (int i = 0; i < val.size(); i++) {
value.second.write[i].sint = val[i];
}
} break;
case ShaderLanguage::TYPE_IVEC4: {
if (value.second.size() < 4)
value.second.resize(4);
PoolIntArray val = V->get();
for (int i = 0; i < val.size(); i++) {
value.second.write[i].sint = val[i];
}
} break; } break;
case ShaderLanguage::TYPE_INT:
case ShaderLanguage::TYPE_UINT: { case ShaderLanguage::TYPE_UINT: {
if (value.second.size() < 1) int value = V->get();
value.second.resize(1); glUniform1i(location, value);
uint32_t val = V->get();
value.second.write[0].uint = val;
} break; } break;
case ShaderLanguage::TYPE_IVEC2:
case ShaderLanguage::TYPE_UVEC2: { case ShaderLanguage::TYPE_UVEC2: {
if (value.second.size() < 2)
value.second.resize(2); Array r = V->get();
PoolIntArray val = V->get(); const int count = 2;
for (int i = 0; i < val.size(); i++) { if (r.size() == count) {
value.second.write[i].uint = val[i]; int values[count];
for (int i = 0; i < count; i++) {
values[i] = r[i];
}
glUniform2i(location, values[0], values[1]);
} }
} break; } break;
case ShaderLanguage::TYPE_IVEC3:
case ShaderLanguage::TYPE_UVEC3: { case ShaderLanguage::TYPE_UVEC3: {
if (value.second.size() < 3) Array r = V->get();
value.second.resize(3); const int count = 3;
PoolIntArray val = V->get(); if (r.size() == count) {
for (int i = 0; i < val.size(); i++) { int values[count];
value.second.write[i].uint = val[i]; for (int i = 0; i < count; i++) {
values[i] = r[i];
}
glUniform3i(location, values[0], values[1], values[2]);
} }
} break; } break;
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4: { case ShaderLanguage::TYPE_UVEC4: {
if (value.second.size() < 4) Array r = V->get();
value.second.resize(4); const int count = 4;
PoolIntArray val = V->get(); if (r.size() == count) {
for (int i = 0; i < val.size(); i++) { int values[count];
value.second.write[i].uint = val[i]; for (int i = 0; i < count; i++) {
values[i] = r[i];
}
glUniform4i(location, values[0], values[1], values[2], values[3]);
} }
} break; } break;
case ShaderLanguage::TYPE_FLOAT: { case ShaderLanguage::TYPE_FLOAT: {
if (value.second.size() < 1) float value = V->get();
value.second.resize(1); glUniform1f(location, value);
value.second.write[0].real = V->get();
} break; } break;
case ShaderLanguage::TYPE_VEC2: { case ShaderLanguage::TYPE_VEC2: {
if (value.second.size() < 2) Vector2 value = V->get();
value.second.resize(2); glUniform2f(location, value.x, value.y);
Vector2 val = V->get();
value.second.write[0].real = val.x;
value.second.write[1].real = val.y;
} break; } break;
case ShaderLanguage::TYPE_VEC3: { case ShaderLanguage::TYPE_VEC3: {
if (value.second.size() < 3) Vector3 value = V->get();
value.second.resize(3); glUniform3f(location, value.x, value.y, value.z);
Vector3 val = V->get();
value.second.write[0].real = val.x;
value.second.write[1].real = val.y;
value.second.write[2].real = val.z;
} break; } break;
case ShaderLanguage::TYPE_VEC4: { case ShaderLanguage::TYPE_VEC4: {
if (value.second.size() < 4) if (V->get().get_type() == Variant::COLOR) {
value.second.resize(4); Color value = V->get();
if (V->get().get_type() == Variant::PLANE) { glUniform4f(location, value.r, value.g, value.b, value.a);
Plane val = V->get(); } else if (V->get().get_type() == Variant::QUAT) {
value.second.write[0].real = val.normal.x; Quat value = V->get();
value.second.write[1].real = val.normal.y; glUniform4f(location, value.x, value.y, value.z, value.w);
value.second.write[2].real = val.normal.z;
value.second.write[3].real = val.d;
} else { } else {
Color val = V->get(); Plane value = V->get();
value.second.write[0].real = val.r; glUniform4f(location, value.normal.x, value.normal.y, value.normal.z, value.d);
value.second.write[1].real = val.g;
value.second.write[2].real = val.b;
value.second.write[3].real = val.a;
} }
} break; } break;
case ShaderLanguage::TYPE_MAT2: { case ShaderLanguage::TYPE_MAT2: {
Transform2D val = V->get();
if (value.second.size() < 4) { Transform2D tr = V->get();
value.second.resize(4); GLfloat matrix[4] = {
} /* build a 16x16 matrix */
tr.elements[0][0],
value.second.write[0].real = val.elements[0][0]; tr.elements[0][1],
value.second.write[1].real = val.elements[0][1]; tr.elements[1][0],
value.second.write[2].real = val.elements[1][0]; tr.elements[1][1],
value.second.write[3].real = val.elements[1][1]; };
glUniformMatrix2fv(location, 1, GL_FALSE, matrix);
} break; } break;
case ShaderLanguage::TYPE_MAT3: { case ShaderLanguage::TYPE_MAT3: {
Basis val = V->get(); Basis val = V->get();
if (value.second.size() < 9) { GLfloat mat[9] = {
value.second.resize(9); val.elements[0][0],
} val.elements[1][0],
val.elements[2][0],
val.elements[0][1],
val.elements[1][1],
val.elements[2][1],
val.elements[0][2],
val.elements[1][2],
val.elements[2][2],
};
glUniformMatrix3fv(location, 1, GL_FALSE, mat);
value.second.write[0].real = val.elements[0][0];
value.second.write[1].real = val.elements[0][1];
value.second.write[2].real = val.elements[0][2];
value.second.write[3].real = val.elements[1][0];
value.second.write[4].real = val.elements[1][1];
value.second.write[5].real = val.elements[1][2];
value.second.write[6].real = val.elements[2][0];
value.second.write[7].real = val.elements[2][1];
value.second.write[8].real = val.elements[2][2];
} break; } break;
case ShaderLanguage::TYPE_MAT4: { case ShaderLanguage::TYPE_MAT4: {
Transform val = V->get();
if (value.second.size() < 16) { Transform2D tr = V->get();
value.second.resize(16); 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(location, 1, GL_FALSE, matrix);
value.second.write[0].real = val.basis.elements[0][0];
value.second.write[1].real = val.basis.elements[0][1];
value.second.write[2].real = val.basis.elements[0][2];
value.second.write[3].real = 0;
value.second.write[4].real = val.basis.elements[1][0];
value.second.write[5].real = val.basis.elements[1][1];
value.second.write[6].real = val.basis.elements[1][2];
value.second.write[7].real = 0;
value.second.write[8].real = val.basis.elements[2][0];
value.second.write[9].real = val.basis.elements[2][1];
value.second.write[10].real = val.basis.elements[2][2];
value.second.write[11].real = 0;
value.second.write[12].real = val.origin[0];
value.second.write[13].real = val.origin[1];
value.second.write[14].real = val.origin[2];
value.second.write[15].real = 1;
} break; } break;
default: { default: {
ERR_PRINT("type missing, bug?");
} break; } break;
} }
} else { } else if (E->get().default_value.size()) {
if (value.second.size() == 0) { const Vector<ShaderLanguage::ConstantNode::Value> &values = E->get().default_value;
// No default value set... weird, let's just use zero for everything switch (E->get().type) {
size_t default_arg_size = 1; case ShaderLanguage::TYPE_BOOL: {
bool is_float = false; glUniform1i(location, values[0].boolean);
switch (E->get().type) { } break;
case ShaderLanguage::TYPE_BOOL:
case ShaderLanguage::TYPE_INT:
case ShaderLanguage::TYPE_UINT: {
default_arg_size = 1;
} break;
case ShaderLanguage::TYPE_FLOAT: { case ShaderLanguage::TYPE_BVEC2: {
default_arg_size = 1; glUniform2i(location, values[0].boolean, values[1].boolean);
is_float = true; } break;
} break;
case ShaderLanguage::TYPE_BVEC2: case ShaderLanguage::TYPE_BVEC3: {
case ShaderLanguage::TYPE_IVEC2: glUniform3i(location, values[0].boolean, values[1].boolean, values[2].boolean);
case ShaderLanguage::TYPE_UVEC2: { } break;
default_arg_size = 2;
} break;
case ShaderLanguage::TYPE_VEC2: { case ShaderLanguage::TYPE_BVEC4: {
default_arg_size = 2; glUniform4i(location, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean);
is_float = true; } break;
} break;
case ShaderLanguage::TYPE_BVEC3: case ShaderLanguage::TYPE_INT: {
case ShaderLanguage::TYPE_IVEC3: glUniform1i(location, values[0].sint);
case ShaderLanguage::TYPE_UVEC3: { } break;
default_arg_size = 3;
} break;
case ShaderLanguage::TYPE_VEC3: { case ShaderLanguage::TYPE_IVEC2: {
default_arg_size = 3; glUniform2i(location, values[0].sint, values[1].sint);
is_float = true; } break;
} break;
case ShaderLanguage::TYPE_BVEC4: case ShaderLanguage::TYPE_IVEC3: {
case ShaderLanguage::TYPE_IVEC4: glUniform3i(location, values[0].sint, values[1].sint, values[2].sint);
case ShaderLanguage::TYPE_UVEC4: { } break;
default_arg_size = 4;
} break;
case ShaderLanguage::TYPE_VEC4: { case ShaderLanguage::TYPE_IVEC4: {
default_arg_size = 4; glUniform4i(location, values[0].sint, values[1].sint, values[2].sint, values[3].sint);
is_float = true; } break;
} break;
default: { case ShaderLanguage::TYPE_UINT: {
// TODO matricies and all that stuff glUniform1i(location, values[0].uint);
default_arg_size = 1; } break;
} break;
}
value.second.resize(default_arg_size); case ShaderLanguage::TYPE_UVEC2: {
glUniform2i(location, values[0].uint, values[1].uint);
} break;
for (size_t i = 0; i < default_arg_size; i++) { case ShaderLanguage::TYPE_UVEC3: {
if (is_float) { glUniform3i(location, values[0].uint, values[1].uint, values[2].uint);
value.second.write[i].real = 0.0; } break;
} else {
value.second.write[i].uint = 0; case ShaderLanguage::TYPE_UVEC4: {
glUniform4i(location, values[0].uint, values[1].uint, values[2].uint, values[3].uint);
} break;
case ShaderLanguage::TYPE_FLOAT: {
glUniform1f(location, values[0].real);
} break;
case ShaderLanguage::TYPE_VEC2: {
glUniform2f(location, values[0].real, values[1].real);
} break;
case ShaderLanguage::TYPE_VEC3: {
glUniform3f(location, values[0].real, values[1].real, values[2].real);
} break;
case ShaderLanguage::TYPE_VEC4: {
glUniform4f(location, values[0].real, values[1].real, values[2].real, values[3].real);
} break;
case ShaderLanguage::TYPE_MAT2: {
GLfloat mat[4];
for (int i = 0; i < 4; i++) {
mat[i] = values[i].real;
} }
}
glUniformMatrix2fv(location, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_MAT3: {
GLfloat mat[9];
for (int i = 0; i < 9; i++) {
mat[i] = values[i].real;
}
glUniformMatrix3fv(location, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_MAT4: {
GLfloat mat[16];
for (int i = 0; i < 16; i++) {
mat[i] = values[i].real;
}
glUniformMatrix4fv(location, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_SAMPLER2D: {
} break;
case ShaderLanguage::TYPE_ISAMPLER2D: {
} break;
case ShaderLanguage::TYPE_USAMPLER2D: {
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
// Not implemented in GLES2
} break;
case ShaderLanguage::TYPE_VOID: {
// Nothing to do?
} break;
default: {
ERR_PRINT("type missing, bug?");
} break;
} }
} }
GLint location;
if (v->custom_uniform_locations.has(E->key())) {
location = v->custom_uniform_locations[E->key()];
} else {
int idx = v->uniform_names.find(E->key()); // TODO maybe put those in a Map?
if (idx < 0) {
location = -1;
} else {
location = v->uniform_location[idx];
}
}
_set_uniform_value(location, value);
} }
// bind textures
int tc = material->textures.size();
Pair<StringName, RID> *textures = material->textures.ptrw();
for (int i = 0; i < tc; i++) {
Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value;
value.first = ShaderLanguage::TYPE_INT;
value.second.resize(1);
value.second.write[0].sint = i;
// GLint location = get_uniform_location(textures[i].first);
// if (location < 0) {
// location = material->shader->uniform_locations[textures[i].first];
// }
GLint location = -1;
if (v->custom_uniform_locations.has(textures[i].first)) {
location = v->custom_uniform_locations[textures[i].first];
} else {
location = get_uniform_location(textures[i].first);
}
_set_uniform_value(location, value);
}
}
void ShaderGLES2::set_base_material_tex_index(int p_idx) {
} }
ShaderGLES2::ShaderGLES2() { ShaderGLES2::ShaderGLES2() {

View File

@ -1,4 +1,4 @@
/*************************************************************************/ /*************************************************************************/
/* shader_gles2.h */ /* shader_gles2.h */
/*************************************************************************/ /*************************************************************************/
/* This file is part of: */ /* This file is part of: */
@ -112,7 +112,6 @@ private:
GLuint id; GLuint id;
GLuint vert_id; GLuint vert_id;
GLuint frag_id; GLuint frag_id;
Vector<StringName> uniform_names;
GLint *uniform_location; GLint *uniform_location;
Vector<GLint> texture_uniform_locations; Vector<GLint> texture_uniform_locations;
Map<StringName, GLint> custom_uniform_locations; Map<StringName, GLint> custom_uniform_locations;
@ -177,9 +176,6 @@ private:
int max_image_units; int max_image_units;
Map<uint32_t, Variant> uniform_defaults;
Map<uint32_t, CameraMatrix> uniform_cameras;
Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > > uniform_values; Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > > uniform_values;
protected: protected:
@ -212,246 +208,11 @@ public:
static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; } static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; }
bool bind(); bool bind();
void unbind(); void unbind();
void bind_uniforms();
inline GLuint get_program() const { return version ? version->id : 0; } inline GLuint get_program() const { return version ? version->id : 0; }
void clear_caches(); void clear_caches();
_FORCE_INLINE_ void _set_uniform_value(GLint p_uniform, const Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > &value) {
if (p_uniform < 0)
return;
const Vector<ShaderLanguage::ConstantNode::Value> &values = value.second;
switch (value.first) {
case ShaderLanguage::TYPE_BOOL: {
glUniform1i(p_uniform, values[0].boolean);
} break;
case ShaderLanguage::TYPE_BVEC2: {
glUniform2i(p_uniform, values[0].boolean, values[1].boolean);
} break;
case ShaderLanguage::TYPE_BVEC3: {
glUniform3i(p_uniform, values[0].boolean, values[1].boolean, values[2].boolean);
} break;
case ShaderLanguage::TYPE_BVEC4: {
glUniform4i(p_uniform, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean);
} break;
case ShaderLanguage::TYPE_INT: {
glUniform1i(p_uniform, values[0].sint);
} break;
case ShaderLanguage::TYPE_IVEC2: {
glUniform2i(p_uniform, values[0].sint, values[1].sint);
} break;
case ShaderLanguage::TYPE_IVEC3: {
glUniform3i(p_uniform, values[0].sint, values[1].sint, values[2].sint);
} break;
case ShaderLanguage::TYPE_IVEC4: {
glUniform4i(p_uniform, values[0].sint, values[1].sint, values[2].sint, values[3].sint);
} break;
case ShaderLanguage::TYPE_UINT: {
glUniform1i(p_uniform, values[0].uint);
} break;
case ShaderLanguage::TYPE_UVEC2: {
glUniform2i(p_uniform, values[0].uint, values[1].uint);
} break;
case ShaderLanguage::TYPE_UVEC3: {
glUniform3i(p_uniform, values[0].uint, values[1].uint, values[2].uint);
} break;
case ShaderLanguage::TYPE_UVEC4: {
glUniform4i(p_uniform, values[0].uint, values[1].uint, values[2].uint, values[3].uint);
} break;
case ShaderLanguage::TYPE_FLOAT: {
glUniform1f(p_uniform, values[0].real);
} break;
case ShaderLanguage::TYPE_VEC2: {
glUniform2f(p_uniform, values[0].real, values[1].real);
} break;
case ShaderLanguage::TYPE_VEC3: {
glUniform3f(p_uniform, values[0].real, values[1].real, values[2].real);
} break;
case ShaderLanguage::TYPE_VEC4: {
glUniform4f(p_uniform, values[0].real, values[1].real, values[2].real, values[3].real);
} break;
case ShaderLanguage::TYPE_MAT2: {
GLfloat mat[4];
for (int i = 0; i < 4; i++) {
mat[i] = values[i].real;
}
glUniformMatrix2fv(p_uniform, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_MAT3: {
GLfloat mat[9];
for (int i = 0; i < 9; i++) {
mat[i] = values[i].real;
}
glUniformMatrix3fv(p_uniform, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_MAT4: {
GLfloat mat[16];
for (int i = 0; i < 16; i++) {
mat[i] = values[i].real;
}
glUniformMatrix4fv(p_uniform, 1, GL_FALSE, mat);
} break;
case ShaderLanguage::TYPE_SAMPLER2D: {
} break;
case ShaderLanguage::TYPE_ISAMPLER2D: {
} break;
case ShaderLanguage::TYPE_USAMPLER2D: {
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D: {
// Not implemented in GLES2
} break;
case ShaderLanguage::TYPE_VOID: {
// Nothing to do?
} break;
}
}
_FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform, const Variant &p_value) {
if (p_uniform < 0)
return; // do none
switch (p_value.get_type()) {
case Variant::BOOL:
case Variant::INT: {
int val = p_value;
glUniform1i(p_uniform, val);
} break;
case Variant::REAL: {
real_t val = p_value;
glUniform1f(p_uniform, val);
} break;
case Variant::COLOR: {
Color val = p_value;
glUniform4f(p_uniform, val.r, val.g, val.b, val.a);
} break;
case Variant::VECTOR2: {
Vector2 val = p_value;
glUniform2f(p_uniform, val.x, val.y);
} break;
case Variant::VECTOR3: {
Vector3 val = p_value;
glUniform3f(p_uniform, val.x, val.y, val.z);
} break;
case Variant::PLANE: {
Plane val = p_value;
glUniform4f(p_uniform, val.normal.x, val.normal.y, val.normal.z, val.d);
} break;
case Variant::QUAT: {
Quat val = p_value;
glUniform4f(p_uniform, val.x, val.y, val.z, val.w);
} break;
case Variant::TRANSFORM2D: {
Transform2D tr = p_value;
GLfloat matrix[16] = { /* build a 16x16 matrix */
tr.elements[0][0],
tr.elements[0][1],
0,
0,
tr.elements[1][0],
tr.elements[1][1],
0,
0,
0,
0,
1,
0,
tr.elements[2][0],
tr.elements[2][1],
0,
1
};
glUniformMatrix4fv(p_uniform, 1, false, matrix);
} break;
case Variant::BASIS:
case Variant::TRANSFORM: {
Transform tr = p_value;
GLfloat matrix[16] = { /* build a 16x16 matrix */
tr.basis.elements[0][0],
tr.basis.elements[1][0],
tr.basis.elements[2][0],
0,
tr.basis.elements[0][1],
tr.basis.elements[1][1],
tr.basis.elements[2][1],
0,
tr.basis.elements[0][2],
tr.basis.elements[1][2],
tr.basis.elements[2][2],
0,
tr.origin.x,
tr.origin.y,
tr.origin.z,
1
};
glUniformMatrix4fv(p_uniform, 1, false, matrix);
} break;
case Variant::OBJECT: {
} break;
default: { ERR_FAIL(); } // do nothing
}
}
uint32_t create_custom_shader(); uint32_t create_custom_shader();
void set_custom_shader_code(uint32_t p_code_id, void set_custom_shader_code(uint32_t p_code_id,
const String &p_vertex, const String &p_vertex,
@ -468,18 +229,6 @@ public:
uint32_t get_version_key() const { return conditional_version.version; } uint32_t get_version_key() const { return conditional_version.version; }
void set_uniform_default(int p_idx, const Variant &p_value) {
if (p_value.get_type() == Variant::NIL) {
uniform_defaults.erase(p_idx);
} else {
uniform_defaults[p_idx] = p_value;
}
uniforms_dirty = true;
}
// this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't // this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't
// like forward declared nested classes. // like forward declared nested classes.
void use_material(void *p_material); void use_material(void *p_material);
@ -487,31 +236,9 @@ public:
_FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; } _FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
_FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; } _FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {
uniform_cameras[p_idx] = p_mat;
uniforms_dirty = true;
}
_FORCE_INLINE_ void set_texture_uniform(int p_idx, const Variant &p_value) {
ERR_FAIL_COND(!version);
ERR_FAIL_INDEX(p_idx, version->texture_uniform_locations.size());
_set_uniform_variant(version->texture_uniform_locations[p_idx], p_value);
}
_FORCE_INLINE_ GLint get_texture_uniform_location(int p_idx) {
ERR_FAIL_COND_V(!version, -1);
ERR_FAIL_INDEX_V(p_idx, version->texture_uniform_locations.size(), -1);
return version->texture_uniform_locations[p_idx];
}
virtual void init() = 0; virtual void init() = 0;
void finish(); void finish();
void set_base_material_tex_index(int p_idx);
void add_custom_define(const String &p_define) { void add_custom_define(const String &p_define) {
custom_defines.push_back(p_define.utf8()); custom_defines.push_back(p_define.utf8());
} }

View File

@ -133,15 +133,6 @@ bool ShaderGLES3::bind() {
active = this; active = this;
uniforms_dirty = true; uniforms_dirty = true;
/*
* why on earth is this code here?
for (int i=0;i<texunit_pair_count;i++) {
glUniform1i(texunit_pairs[i].location, texunit_pairs[i].index);
DEBUG_TEST_ERROR("Uniform 1 i");
}
*/
return true; return true;
} }