add initial GLES2 3D renderer
This commit is contained in:
parent
bfb21be871
commit
b64171e79c
18 changed files with 6372 additions and 2330 deletions
|
@ -54,10 +54,26 @@ void RasterizerCanvasGLES2::_set_uniforms() {
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix);
|
||||||
|
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES2::FINAL_MODULATE, state.uniforms.final_modulate);
|
state.canvas_shader.set_uniform(CanvasShaderGLES2::FINAL_MODULATE, state.uniforms.final_modulate);
|
||||||
|
|
||||||
|
state.canvas_shader.set_uniform(CanvasShaderGLES2::TIME, storage->frame.time[0]);
|
||||||
|
|
||||||
|
if (storage->frame.current_rt) {
|
||||||
|
Vector2 screen_pixel_size;
|
||||||
|
screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
|
||||||
|
screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
|
||||||
|
|
||||||
|
state.canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasGLES2::canvas_begin() {
|
void RasterizerCanvasGLES2::canvas_begin() {
|
||||||
|
|
||||||
|
state.canvas_shader.bind();
|
||||||
|
if (storage->frame.current_rt) {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
||||||
|
glColorMask(1, 1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (storage->frame.clear_request) {
|
if (storage->frame.clear_request) {
|
||||||
glClearColor(storage->frame.clear_request_color.r,
|
glClearColor(storage->frame.clear_request_color.r,
|
||||||
storage->frame.clear_request_color.g,
|
storage->frame.clear_request_color.g,
|
||||||
|
@ -67,10 +83,12 @@ void RasterizerCanvasGLES2::canvas_begin() {
|
||||||
storage->frame.clear_request = false;
|
storage->frame.clear_request = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (storage->frame.current_rt) {
|
if (storage->frame.current_rt) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
||||||
glColorMask(1, 1, 1, 1);
|
glColorMask(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
reset_canvas();
|
reset_canvas();
|
||||||
|
|
||||||
|
@ -312,7 +330,7 @@ void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_v
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip) {
|
void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material) {
|
||||||
|
|
||||||
int command_count = p_item->commands.size();
|
int command_count = p_item->commands.size();
|
||||||
Item::Command **commands = p_item->commands.ptrw();
|
Item::Command **commands = p_item->commands.ptrw();
|
||||||
|
@ -329,9 +347,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||||
state.canvas_shader.bind();
|
if (state.canvas_shader.bind()) {
|
||||||
|
_set_uniforms();
|
||||||
_set_uniforms();
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
_bind_canvas_texture(RID(), RID());
|
_bind_canvas_texture(RID(), RID());
|
||||||
|
|
||||||
|
@ -359,7 +378,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
|
|
||||||
_draw_gui_primitive(4, verts, NULL, NULL);
|
_draw_gui_primitive(4, verts, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Item::Command::TYPE_RECT: {
|
case Item::Command::TYPE_RECT: {
|
||||||
|
@ -373,8 +391,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
RasterizerStorageGLES2::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map);
|
RasterizerStorageGLES2::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map);
|
||||||
|
|
||||||
|
@ -454,8 +474,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
|
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
||||||
glVertexAttrib4fv(VS::ARRAY_COLOR, np->color.components);
|
glVertexAttrib4fv(VS::ARRAY_COLOR, np->color.components);
|
||||||
|
@ -472,8 +494,16 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
// state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
// state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
|
|
||||||
|
Rect2 source = np->source;
|
||||||
|
if (source.size.x == 0 && source.size.y == 0) {
|
||||||
|
source.size.x = tex->width;
|
||||||
|
source.size.y = tex->height;
|
||||||
|
}
|
||||||
|
|
||||||
// prepare vertex buffer
|
// prepare vertex buffer
|
||||||
|
|
||||||
|
// this buffer contains [ POS POS UV UV ] *
|
||||||
|
|
||||||
float buffer[16 * 2 + 16 * 2];
|
float buffer[16 * 2 + 16 * 2];
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -483,106 +513,106 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
buffer[(0 * 4 * 4) + 0] = np->rect.position.x;
|
buffer[(0 * 4 * 4) + 0] = np->rect.position.x;
|
||||||
buffer[(0 * 4 * 4) + 1] = np->rect.position.y;
|
buffer[(0 * 4 * 4) + 1] = np->rect.position.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x;
|
buffer[(0 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
|
||||||
buffer[(0 * 4 * 4) + 3] = np->source.position.y * texpixel_size.y;
|
buffer[(0 * 4 * 4) + 3] = source.position.y * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
||||||
buffer[(0 * 4 * 4) + 5] = np->rect.position.y;
|
buffer[(0 * 4 * 4) + 5] = np->rect.position.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
buffer[(0 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
||||||
buffer[(0 * 4 * 4) + 7] = np->source.position.y * texpixel_size.y;
|
buffer[(0 * 4 * 4) + 7] = source.position.y * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
||||||
buffer[(0 * 4 * 4) + 9] = np->rect.position.y;
|
buffer[(0 * 4 * 4) + 9] = np->rect.position.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
buffer[(0 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
||||||
buffer[(0 * 4 * 4) + 11] = np->source.position.y * texpixel_size.y;
|
buffer[(0 * 4 * 4) + 11] = source.position.y * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
buffer[(0 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
||||||
buffer[(0 * 4 * 4) + 13] = np->rect.position.y;
|
buffer[(0 * 4 * 4) + 13] = np->rect.position.y;
|
||||||
|
|
||||||
buffer[(0 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x;
|
buffer[(0 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
|
||||||
buffer[(0 * 4 * 4) + 15] = np->source.position.y * texpixel_size.y;
|
buffer[(0 * 4 * 4) + 15] = source.position.y * texpixel_size.y;
|
||||||
|
|
||||||
// second row
|
// second row
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 0] = np->rect.position.x;
|
buffer[(1 * 4 * 4) + 0] = np->rect.position.x;
|
||||||
buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP];
|
buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP];
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x;
|
buffer[(1 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
|
||||||
buffer[(1 * 4 * 4) + 3] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
buffer[(1 * 4 * 4) + 3] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
||||||
buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP];
|
buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP];
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
buffer[(1 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
||||||
buffer[(1 * 4 * 4) + 7] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
buffer[(1 * 4 * 4) + 7] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
||||||
buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP];
|
buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP];
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
buffer[(1 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
||||||
buffer[(1 * 4 * 4) + 11] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
buffer[(1 * 4 * 4) + 11] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
||||||
buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP];
|
buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP];
|
||||||
|
|
||||||
buffer[(1 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x;
|
buffer[(1 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
|
||||||
buffer[(1 * 4 * 4) + 15] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
buffer[(1 * 4 * 4) + 15] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y;
|
||||||
|
|
||||||
// thrid row
|
// thrid row
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 0] = np->rect.position.x;
|
buffer[(2 * 4 * 4) + 0] = np->rect.position.x;
|
||||||
buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x;
|
buffer[(2 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
|
||||||
buffer[(2 * 4 * 4) + 3] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
buffer[(2 * 4 * 4) + 3] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
||||||
buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
buffer[(2 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
||||||
buffer[(2 * 4 * 4) + 7] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
buffer[(2 * 4 * 4) + 7] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
||||||
buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
buffer[(2 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
||||||
buffer[(2 * 4 * 4) + 11] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
buffer[(2 * 4 * 4) + 11] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
||||||
buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM];
|
||||||
|
|
||||||
buffer[(2 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x;
|
buffer[(2 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
|
||||||
buffer[(2 * 4 * 4) + 15] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
buffer[(2 * 4 * 4) + 15] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y;
|
||||||
|
|
||||||
// fourth row
|
// fourth row
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 0] = np->rect.position.x;
|
buffer[(3 * 4 * 4) + 0] = np->rect.position.x;
|
||||||
buffer[(3 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y;
|
buffer[(3 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x;
|
buffer[(3 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
|
||||||
buffer[(3 * 4 * 4) + 3] = (np->source.position.y + np->source.size.y) * texpixel_size.y;
|
buffer[(3 * 4 * 4) + 3] = (source.position.y + source.size.y) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT];
|
||||||
buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y;
|
buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
buffer[(3 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x;
|
||||||
buffer[(3 * 4 * 4) + 7] = (np->source.position.y + np->source.size.y) * texpixel_size.y;
|
buffer[(3 * 4 * 4) + 7] = (source.position.y + source.size.y) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT];
|
||||||
buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y;
|
buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
buffer[(3 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x;
|
||||||
buffer[(3 * 4 * 4) + 11] = (np->source.position.y + np->source.size.y) * texpixel_size.y;
|
buffer[(3 * 4 * 4) + 11] = (source.position.y + source.size.y) * texpixel_size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
buffer[(3 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
|
||||||
buffer[(3 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y;
|
buffer[(3 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y;
|
||||||
|
|
||||||
buffer[(3 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x;
|
buffer[(3 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
|
||||||
buffer[(3 * 4 * 4) + 15] = (np->source.position.y + np->source.size.y) * texpixel_size.y;
|
buffer[(3 * 4 * 4) + 15] = (source.position.y + source.size.y) * texpixel_size.y;
|
||||||
|
|
||||||
// print_line(String::num((np->source.position.y + np->source.size.y) * texpixel_size.y));
|
// print_line(String::num((source.position.y + source.size.y) * texpixel_size.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
|
glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
|
||||||
|
@ -610,8 +640,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||||
|
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
static const int num_points = 32;
|
static const int num_points = 32;
|
||||||
|
|
||||||
|
@ -639,8 +671,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
||||||
|
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
|
RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
|
||||||
|
|
||||||
|
@ -658,8 +692,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||||
|
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
_bind_canvas_texture(RID(), RID());
|
_bind_canvas_texture(RID(), RID());
|
||||||
|
|
||||||
|
@ -689,8 +725,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
|
||||||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
||||||
|
|
||||||
if (state.canvas_shader.bind())
|
if (state.canvas_shader.bind()) {
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
state.canvas_shader.use_material((void *)p_material, 2);
|
||||||
|
}
|
||||||
|
|
||||||
ERR_CONTINUE(primitive->points.size() < 1);
|
ERR_CONTINUE(primitive->points.size() < 1);
|
||||||
|
|
||||||
|
@ -759,42 +797,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
|
void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
|
||||||
|
|
||||||
// This isn't really working yet, so disabling for now.
|
// This isn't really working yet, so disabling for now.
|
||||||
|
|
||||||
/*
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
state.canvas_texscreen_used = true;
|
|
||||||
|
|
||||||
Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height);
|
|
||||||
Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y);
|
|
||||||
|
|
||||||
if (p_rect != Rect2()) {
|
|
||||||
// only use section
|
|
||||||
|
|
||||||
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
storage->shaders.copy.bind();
|
|
||||||
storage->shaders.copy.set_uniform(CopyShaderGLES2::COPY_SECTION, copy_section);
|
|
||||||
|
|
||||||
_bind_quad_buffer();
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->copy_screen_effect.fbo);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
glDisableVertexAttribArray(VS::ARRAY_VERTEX);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
|
||||||
|
|
||||||
state.canvas_shader.bind();
|
|
||||||
_bind_canvas_texture(state.current_tex, state.current_normal);
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
|
void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
|
||||||
|
@ -850,10 +852,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
Item *material_owner = ci->material_owner ? ci->material_owner : ci;
|
Item *material_owner = ci->material_owner ? ci->material_owner : ci;
|
||||||
|
|
||||||
RID material = material_owner->material;
|
RID material = material_owner->material;
|
||||||
|
RasterizerStorageGLES2::Material *material_ptr = storage->material_owner.getornull(material);
|
||||||
|
|
||||||
if (material != canvas_last_material || rebind_shader) {
|
if (material != canvas_last_material || rebind_shader) {
|
||||||
|
|
||||||
RasterizerStorageGLES2::Material *material_ptr = storage->material_owner.getornull(material);
|
|
||||||
RasterizerStorageGLES2::Shader *shader_ptr = NULL;
|
RasterizerStorageGLES2::Shader *shader_ptr = NULL;
|
||||||
|
|
||||||
if (material_ptr) {
|
if (material_ptr) {
|
||||||
|
@ -880,7 +882,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
int tc = material_ptr->textures.size();
|
int tc = material_ptr->textures.size();
|
||||||
RID *textures = material_ptr->textures.ptrw();
|
Pair<StringName, RID> *textures = material_ptr->textures.ptrw();
|
||||||
|
|
||||||
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();
|
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();
|
||||||
|
|
||||||
|
@ -888,7 +890,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2 + i);
|
glActiveTexture(GL_TEXTURE2 + i);
|
||||||
|
|
||||||
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i]);
|
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);
|
||||||
|
|
||||||
if (!t) {
|
if (!t) {
|
||||||
|
|
||||||
|
@ -919,10 +921,12 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
|
|
||||||
glBindTexture(t->target, t->tex_id);
|
glBindTexture(t->target, t->tex_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
state.canvas_shader.set_custom_shader(0);
|
state.canvas_shader.set_custom_shader(0);
|
||||||
state.canvas_shader.bind();
|
state.canvas_shader.bind();
|
||||||
}
|
}
|
||||||
|
state.canvas_shader.use_material((void *)material_ptr, 2);
|
||||||
|
|
||||||
shader_cache = shader_ptr;
|
shader_cache = shader_ptr;
|
||||||
|
|
||||||
|
@ -977,7 +981,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
||||||
|
|
||||||
_set_uniforms();
|
_set_uniforms();
|
||||||
|
|
||||||
_canvas_item_render_commands(p_item_list, NULL, reclip);
|
_canvas_item_render_commands(p_item_list, NULL, reclip, material_ptr);
|
||||||
|
|
||||||
rebind_shader = true; // hacked in for now.
|
rebind_shader = true; // hacked in for now.
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
_FORCE_INLINE_ 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);
|
_FORCE_INLINE_ 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);
|
||||||
_FORCE_INLINE_ 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);
|
_FORCE_INLINE_ 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);
|
||||||
|
|
||||||
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip);
|
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material);
|
||||||
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
|
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
|
||||||
|
|
||||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
|
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
|
||||||
|
|
|
@ -348,10 +348,10 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
|
||||||
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
||||||
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||||
|
|
||||||
|
canvas->state.canvas_shader.set_custom_shader(0);
|
||||||
canvas->state.canvas_shader.bind();
|
canvas->state.canvas_shader.bind();
|
||||||
|
|
||||||
canvas->canvas_begin();
|
canvas->canvas_begin();
|
||||||
canvas->state.canvas_shader.set_uniform(CanvasShaderGLES2::BLIT_PASS, true);
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -361,8 +361,6 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
|
||||||
|
|
||||||
canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
|
canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
|
||||||
|
|
||||||
canvas->state.canvas_shader.set_uniform(CanvasShaderGLES2::BLIT_PASS, false);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
canvas->canvas_end();
|
canvas->canvas_end();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,10 +33,10 @@
|
||||||
/* Must come before shaders or the Windows build fails... */
|
/* Must come before shaders or the Windows build fails... */
|
||||||
#include "rasterizer_storage_gles2.h"
|
#include "rasterizer_storage_gles2.h"
|
||||||
|
|
||||||
|
#include "shaders/cube_to_dp.glsl.gen.h"
|
||||||
#include "shaders/scene.glsl.gen.h"
|
#include "shaders/scene.glsl.gen.h"
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "drivers/gles3/shaders/cube_to_dp.glsl.gen.h"
|
|
||||||
#include "drivers/gles3/shaders/effect_blur.glsl.gen.h"
|
#include "drivers/gles3/shaders/effect_blur.glsl.gen.h"
|
||||||
#include "drivers/gles3/shaders/exposure.glsl.gen.h"
|
#include "drivers/gles3/shaders/exposure.glsl.gen.h"
|
||||||
#include "drivers/gles3/shaders/resolve.glsl.gen.h"
|
#include "drivers/gles3/shaders/resolve.glsl.gen.h"
|
||||||
|
@ -52,6 +52,13 @@
|
||||||
|
|
||||||
class RasterizerSceneGLES2 : public RasterizerScene {
|
class RasterizerSceneGLES2 : public RasterizerScene {
|
||||||
public:
|
public:
|
||||||
|
RID default_material;
|
||||||
|
RID default_material_twosided;
|
||||||
|
RID default_shader;
|
||||||
|
RID default_shader_twosided;
|
||||||
|
|
||||||
|
uint64_t scene_pass;
|
||||||
|
|
||||||
RasterizerStorageGLES2 *storage;
|
RasterizerStorageGLES2 *storage;
|
||||||
struct State {
|
struct State {
|
||||||
|
|
||||||
|
@ -63,7 +70,10 @@ public:
|
||||||
GLuint current_main_tex;
|
GLuint current_main_tex;
|
||||||
|
|
||||||
SceneShaderGLES2 scene_shader;
|
SceneShaderGLES2 scene_shader;
|
||||||
// CubeToDpShaderGLES3 cube_to_dp_shader;
|
CubeToDpShaderGLES2 cube_to_dp_shader;
|
||||||
|
|
||||||
|
GLuint sky_verts;
|
||||||
|
|
||||||
// ResolveShaderGLES3 resolve_shader;
|
// ResolveShaderGLES3 resolve_shader;
|
||||||
// ScreenSpaceReflectionShaderGLES3 ssr_shader;
|
// ScreenSpaceReflectionShaderGLES3 ssr_shader;
|
||||||
// EffectBlurShaderGLES3 effect_blur_shader;
|
// EffectBlurShaderGLES3 effect_blur_shader;
|
||||||
|
@ -128,7 +138,6 @@ public:
|
||||||
|
|
||||||
GLuint env_radiance_ubo;
|
GLuint env_radiance_ubo;
|
||||||
|
|
||||||
GLuint sky_verts;
|
|
||||||
GLuint sky_array;
|
GLuint sky_array;
|
||||||
|
|
||||||
GLuint directional_ubo;
|
GLuint directional_ubo;
|
||||||
|
@ -169,11 +178,72 @@ public:
|
||||||
|
|
||||||
/* SHADOW ATLAS API */
|
/* SHADOW ATLAS API */
|
||||||
|
|
||||||
|
uint64_t shadow_atlas_realloc_tolerance_msec;
|
||||||
|
|
||||||
|
struct ShadowAtlas : public RID_Data {
|
||||||
|
enum {
|
||||||
|
QUADRANT_SHIFT = 27,
|
||||||
|
SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1,
|
||||||
|
SHADOW_INVALID = 0xFFFFFFFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Quadrant {
|
||||||
|
uint32_t subdivision;
|
||||||
|
|
||||||
|
struct Shadow {
|
||||||
|
RID owner;
|
||||||
|
uint64_t version;
|
||||||
|
uint64_t alloc_tick;
|
||||||
|
|
||||||
|
Shadow() {
|
||||||
|
version = 0;
|
||||||
|
alloc_tick = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<Shadow> shadows;
|
||||||
|
|
||||||
|
Quadrant() {
|
||||||
|
subdivision = 0;
|
||||||
|
}
|
||||||
|
} quadrants[4];
|
||||||
|
|
||||||
|
int size_order[4];
|
||||||
|
uint32_t smallest_subdiv;
|
||||||
|
|
||||||
|
int size;
|
||||||
|
|
||||||
|
GLuint fbo;
|
||||||
|
GLuint depth;
|
||||||
|
|
||||||
|
Map<RID, uint32_t> shadow_owners;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ShadowCubeMap {
|
||||||
|
GLuint fbo[6];
|
||||||
|
GLuint cubemap;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<ShadowCubeMap> shadow_cubemaps;
|
||||||
|
|
||||||
|
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||||
|
|
||||||
RID shadow_atlas_create();
|
RID shadow_atlas_create();
|
||||||
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
||||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
||||||
|
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
||||||
|
|
||||||
|
struct DirectionalShadow {
|
||||||
|
GLuint fbo;
|
||||||
|
GLuint depth;
|
||||||
|
|
||||||
|
int light_count;
|
||||||
|
int size;
|
||||||
|
int current_light;
|
||||||
|
} directional_shadow;
|
||||||
|
|
||||||
virtual int get_directional_light_shadow_size(RID p_light_intance);
|
virtual int get_directional_light_shadow_size(RID p_light_intance);
|
||||||
virtual void set_directional_shadow_count(int p_count);
|
virtual void set_directional_shadow_count(int p_count);
|
||||||
|
|
||||||
|
@ -196,6 +266,36 @@ public:
|
||||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
|
virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
|
||||||
|
|
||||||
/* ENVIRONMENT API */
|
/* ENVIRONMENT API */
|
||||||
|
|
||||||
|
struct Environment : public RID_Data {
|
||||||
|
VS::EnvironmentBG bg_mode;
|
||||||
|
|
||||||
|
RID sky;
|
||||||
|
float sky_custom_fov;
|
||||||
|
|
||||||
|
Color bg_color;
|
||||||
|
float bg_energy;
|
||||||
|
float sky_ambient;
|
||||||
|
|
||||||
|
Color ambient_color;
|
||||||
|
float ambient_energy;
|
||||||
|
float ambient_sky_contribution;
|
||||||
|
|
||||||
|
int canvas_max_layer;
|
||||||
|
|
||||||
|
Environment() {
|
||||||
|
bg_mode = VS::ENV_BG_CLEAR_COLOR;
|
||||||
|
sky_custom_fov = 0.0;
|
||||||
|
bg_energy = 1.0;
|
||||||
|
sky_ambient = 0;
|
||||||
|
ambient_energy = 1.0;
|
||||||
|
ambient_sky_contribution = 0.0;
|
||||||
|
canvas_max_layer = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Environment> environment_owner;
|
||||||
|
|
||||||
virtual RID environment_create();
|
virtual RID environment_create();
|
||||||
|
|
||||||
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
|
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
|
||||||
|
@ -228,6 +328,43 @@ public:
|
||||||
virtual int environment_get_canvas_max_layer(RID p_env);
|
virtual int environment_get_canvas_max_layer(RID p_env);
|
||||||
|
|
||||||
/* LIGHT INSTANCE */
|
/* LIGHT INSTANCE */
|
||||||
|
|
||||||
|
struct LightInstance : public RID_Data {
|
||||||
|
|
||||||
|
struct ShadowTransform {
|
||||||
|
CameraMatrix camera;
|
||||||
|
Transform transform;
|
||||||
|
float farplane;
|
||||||
|
float split;
|
||||||
|
float bias_scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
ShadowTransform shadow_transform[4];
|
||||||
|
|
||||||
|
RID self;
|
||||||
|
RID light;
|
||||||
|
|
||||||
|
RasterizerStorageGLES2::Light *light_ptr;
|
||||||
|
Transform transform;
|
||||||
|
|
||||||
|
Vector3 light_vector;
|
||||||
|
Vector3 spot_vector;
|
||||||
|
float linear_att;
|
||||||
|
|
||||||
|
// TODO passes and all that stuff ?
|
||||||
|
uint64_t last_scene_pass;
|
||||||
|
uint64_t last_scene_shadow_pass;
|
||||||
|
|
||||||
|
uint16_t light_index;
|
||||||
|
uint16_t light_directional_index;
|
||||||
|
|
||||||
|
Rect2 directional_rect;
|
||||||
|
|
||||||
|
Set<RID> shadow_atlases; // atlases where this light is registered
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||||
|
|
||||||
virtual RID light_instance_create(RID p_light);
|
virtual RID light_instance_create(RID p_light);
|
||||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
|
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
|
||||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
|
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
|
||||||
|
@ -242,6 +379,180 @@ public:
|
||||||
|
|
||||||
/* RENDER LIST */
|
/* RENDER LIST */
|
||||||
|
|
||||||
|
struct RenderList {
|
||||||
|
enum {
|
||||||
|
DEFAULT_MAX_ELEMENTS = 65536,
|
||||||
|
SORT_FLAG_SKELETON = 1,
|
||||||
|
SORT_FLAG_INSTANCING = 2,
|
||||||
|
MAX_DIRECTIONAL_LIGHTS = 16,
|
||||||
|
MAX_LIGHTS = 4096,
|
||||||
|
MAX_REFLECTIONS = 1024,
|
||||||
|
|
||||||
|
SORT_KEY_PRIORITY_SHIFT = 56,
|
||||||
|
SORT_KEY_PRIORITY_MASK = 0xFF,
|
||||||
|
//depth layer for opaque (56-52)
|
||||||
|
SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT = 52,
|
||||||
|
SORT_KEY_OPAQUE_DEPTH_LAYER_MASK = 0xF,
|
||||||
|
//64 bits unsupported in MSVC
|
||||||
|
#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 49)
|
||||||
|
#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 48)
|
||||||
|
#define SORT_KEY_LIGHTMAP_CAPTURE_FLAG (uint64_t(1) << 47)
|
||||||
|
#define SORT_KEY_LIGHTMAP_FLAG (uint64_t(1) << 46)
|
||||||
|
#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 45)
|
||||||
|
#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 44)
|
||||||
|
SORT_KEY_SHADING_SHIFT = 44,
|
||||||
|
SORT_KEY_SHADING_MASK = 63,
|
||||||
|
//44-28 material index
|
||||||
|
SORT_KEY_MATERIAL_INDEX_SHIFT = 28,
|
||||||
|
//28-8 geometry index
|
||||||
|
SORT_KEY_GEOMETRY_INDEX_SHIFT = 8,
|
||||||
|
//bits 5-7 geometry type
|
||||||
|
SORT_KEY_GEOMETRY_TYPE_SHIFT = 5,
|
||||||
|
//bits 0-5 for flags
|
||||||
|
SORT_KEY_OPAQUE_PRE_PASS = 8,
|
||||||
|
SORT_KEY_CULL_DISABLED_FLAG = 4,
|
||||||
|
SORT_KEY_SKELETON_FLAG = 2,
|
||||||
|
SORT_KEY_MIRROR_FLAG = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int max_elements;
|
||||||
|
|
||||||
|
struct Element {
|
||||||
|
RasterizerScene::InstanceBase *instance;
|
||||||
|
|
||||||
|
RasterizerStorageGLES2::Geometry *geometry;
|
||||||
|
RasterizerStorageGLES2::Material *material;
|
||||||
|
RasterizerStorageGLES2::GeometryOwner *owner;
|
||||||
|
|
||||||
|
uint64_t sort_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
Element *base_elements;
|
||||||
|
Element **elements;
|
||||||
|
|
||||||
|
int element_count;
|
||||||
|
int alpha_element_count;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
element_count = 0;
|
||||||
|
alpha_element_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sorts
|
||||||
|
|
||||||
|
struct SortByKey {
|
||||||
|
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||||
|
return A->sort_key < B->sort_key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_key(bool p_alpha) {
|
||||||
|
SortArray<Element *, SortByKey> sorter;
|
||||||
|
|
||||||
|
if (p_alpha) {
|
||||||
|
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||||
|
} else {
|
||||||
|
sorter.sort(elements, element_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SortByDepth {
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||||
|
return A->instance->depth < B->instance->depth;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_depth(bool p_alpha) { //used for shadows
|
||||||
|
|
||||||
|
SortArray<Element *, SortByDepth> sorter;
|
||||||
|
if (p_alpha) {
|
||||||
|
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||||
|
} else {
|
||||||
|
sorter.sort(elements, element_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SortByReverseDepthAndPriority {
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||||
|
uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT);
|
||||||
|
uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT);
|
||||||
|
if (layer_A == layer_B) {
|
||||||
|
return A->instance->depth > B->instance->depth;
|
||||||
|
} else {
|
||||||
|
return layer_A < layer_B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
|
||||||
|
|
||||||
|
SortArray<Element *, SortByReverseDepthAndPriority> sorter;
|
||||||
|
if (p_alpha) {
|
||||||
|
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||||
|
} else {
|
||||||
|
sorter.sort(elements, element_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// element adding and stuff
|
||||||
|
|
||||||
|
_FORCE_INLINE_ Element *add_element() {
|
||||||
|
if (element_count + alpha_element_count >= max_elements)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
elements[element_count] = &base_elements[element_count];
|
||||||
|
return elements[element_count++];
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ Element *add_alpha_element() {
|
||||||
|
if (element_count + alpha_element_count >= max_elements) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idx = max_elements - alpha_element_count - 1;
|
||||||
|
elements[idx] = &base_elements[idx];
|
||||||
|
alpha_element_count++;
|
||||||
|
return elements[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
element_count = 0;
|
||||||
|
alpha_element_count = 0;
|
||||||
|
|
||||||
|
elements = memnew_arr(Element *, max_elements);
|
||||||
|
base_elements = memnew_arr(Element, max_elements);
|
||||||
|
|
||||||
|
for (int i = 0; i < max_elements; i++) {
|
||||||
|
elements[i] = &base_elements[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderList() {
|
||||||
|
max_elements = DEFAULT_MAX_ELEMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
~RenderList() {
|
||||||
|
memdelete_arr(elements);
|
||||||
|
memdelete_arr(base_elements);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderList render_list;
|
||||||
|
|
||||||
|
void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass);
|
||||||
|
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
|
||||||
|
|
||||||
|
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
|
||||||
|
void _render_render_list(RenderList::Element **p_elements, int p_element_count, const RID *p_light_cull_result, int p_light_cull_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
|
||||||
|
|
||||||
|
void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
|
||||||
|
|
||||||
|
void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_use_radiance_map, bool p_reverse_cull, bool p_shadow_atlas = false, bool p_skeleton_tex = false, Size2i p_skeleton_tex_size = Size2i(0, 0));
|
||||||
|
void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
|
||||||
|
void _render_geometry(RenderList::Element *p_element);
|
||||||
|
|
||||||
virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
|
||||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
|
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
|
||||||
virtual bool free(RID p_rid);
|
virtual bool free(RID p_rid);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,7 @@
|
||||||
#ifndef RASTERIZERSTORAGEGLES2_H
|
#ifndef RASTERIZERSTORAGEGLES2_H
|
||||||
#define RASTERIZERSTORAGEGLES2_H
|
#define RASTERIZERSTORAGEGLES2_H
|
||||||
|
|
||||||
|
#include "dvector.h"
|
||||||
#include "self_list.h"
|
#include "self_list.h"
|
||||||
#include "servers/visual/rasterizer.h"
|
#include "servers/visual/rasterizer.h"
|
||||||
#include "servers/visual/shader_language.h"
|
#include "servers/visual/shader_language.h"
|
||||||
|
@ -37,11 +38,11 @@
|
||||||
#include "shader_gles2.h"
|
#include "shader_gles2.h"
|
||||||
|
|
||||||
#include "shaders/copy.glsl.gen.h"
|
#include "shaders/copy.glsl.gen.h"
|
||||||
|
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||||
/*
|
/*
|
||||||
#include "shaders/blend_shape.glsl.gen.h"
|
#include "shaders/blend_shape.glsl.gen.h"
|
||||||
#include "shaders/canvas.glsl.gen.h"
|
#include "shaders/canvas.glsl.gen.h"
|
||||||
#include "shaders/copy.glsl.gen.h"
|
#include "shaders/copy.glsl.gen.h"
|
||||||
#include "shaders/cubemap_filter.glsl.gen.h"
|
|
||||||
#include "shaders/particles.glsl.gen.h"
|
#include "shaders/particles.glsl.gen.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -76,6 +77,10 @@ public:
|
||||||
|
|
||||||
Set<String> extensions;
|
Set<String> extensions;
|
||||||
|
|
||||||
|
bool float_texture_supported;
|
||||||
|
bool s3tc_supported;
|
||||||
|
bool etc1_supported;
|
||||||
|
|
||||||
bool keep_original_textures;
|
bool keep_original_textures;
|
||||||
|
|
||||||
bool no_depth_prepass;
|
bool no_depth_prepass;
|
||||||
|
@ -89,8 +94,13 @@ public:
|
||||||
GLuint normal_tex;
|
GLuint normal_tex;
|
||||||
GLuint aniso_tex;
|
GLuint aniso_tex;
|
||||||
|
|
||||||
|
GLuint radical_inverse_vdc_cache_tex;
|
||||||
|
|
||||||
GLuint quadie;
|
GLuint quadie;
|
||||||
GLuint quadie_array;
|
|
||||||
|
size_t skeleton_transform_buffer_size;
|
||||||
|
GLuint skeleton_transform_buffer;
|
||||||
|
PoolVector<float> skeleton_transform_cpu_buffer;
|
||||||
|
|
||||||
} resources;
|
} resources;
|
||||||
|
|
||||||
|
@ -99,6 +109,7 @@ public:
|
||||||
ShaderCompilerGLES2 compiler;
|
ShaderCompilerGLES2 compiler;
|
||||||
|
|
||||||
CopyShaderGLES2 copy;
|
CopyShaderGLES2 copy;
|
||||||
|
CubemapFilterShaderGLES2 cubemap_filter;
|
||||||
|
|
||||||
ShaderCompilerGLES2::IdentifierActions actions_canvas;
|
ShaderCompilerGLES2::IdentifierActions actions_canvas;
|
||||||
ShaderCompilerGLES2::IdentifierActions actions_scene;
|
ShaderCompilerGLES2::IdentifierActions actions_scene;
|
||||||
|
@ -139,10 +150,72 @@ public:
|
||||||
|
|
||||||
} info;
|
} info;
|
||||||
|
|
||||||
|
void bind_quad_array() const;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////DATA///////////////////////////////////////////////////
|
//////////////////////////////////DATA///////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Instanciable : public RID_Data {
|
||||||
|
SelfList<RasterizerScene::InstanceBase>::List instance_list;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void instance_change_notify() {
|
||||||
|
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
|
||||||
|
|
||||||
|
while (instances) {
|
||||||
|
instances->self()->base_changed();
|
||||||
|
instances = instances->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void instance_material_change_notify() {
|
||||||
|
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
|
||||||
|
|
||||||
|
while (instances) {
|
||||||
|
instances->self()->base_material_changed();
|
||||||
|
instances = instances->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void instance_remove_deps() {
|
||||||
|
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
|
||||||
|
|
||||||
|
while (instances) {
|
||||||
|
instances->self()->base_removed();
|
||||||
|
instances = instances->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Instanciable() {}
|
||||||
|
|
||||||
|
virtual ~Instanciable() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeometryOwner : public Instanciable {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Geometry : public Instanciable {
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
GEOMETRY_INVALID,
|
||||||
|
GEOMETRY_SURFACE,
|
||||||
|
GEOMETRY_IMMEDIATE,
|
||||||
|
GEOMETRY_MULTISURFACE
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
RID material;
|
||||||
|
uint64_t last_pass;
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
virtual void material_changed_notify() {}
|
||||||
|
|
||||||
|
Geometry() {
|
||||||
|
last_pass = 0;
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////API////////////////////////////////////////////////////
|
//////////////////////////////////API////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -171,6 +244,10 @@ public:
|
||||||
int total_data_size;
|
int total_data_size;
|
||||||
bool ignore_mipmaps;
|
bool ignore_mipmaps;
|
||||||
|
|
||||||
|
bool compressed;
|
||||||
|
|
||||||
|
bool srgb;
|
||||||
|
|
||||||
int mipmaps;
|
int mipmaps;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
|
@ -184,6 +261,15 @@ public:
|
||||||
|
|
||||||
bool redraw_if_visible;
|
bool redraw_if_visible;
|
||||||
|
|
||||||
|
VisualServer::TextureDetectCallback detect_3d;
|
||||||
|
void *detect_3d_ud;
|
||||||
|
|
||||||
|
VisualServer::TextureDetectCallback detect_srgb;
|
||||||
|
void *detect_srgb_ud;
|
||||||
|
|
||||||
|
VisualServer::TextureDetectCallback detect_normal;
|
||||||
|
void *detect_normal_ud;
|
||||||
|
|
||||||
Texture() {
|
Texture() {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
|
@ -198,6 +284,8 @@ public:
|
||||||
total_data_size = 0;
|
total_data_size = 0;
|
||||||
ignore_mipmaps = false;
|
ignore_mipmaps = false;
|
||||||
|
|
||||||
|
compressed = false;
|
||||||
|
|
||||||
active = false;
|
active = false;
|
||||||
|
|
||||||
tex_id = 0;
|
tex_id = 0;
|
||||||
|
@ -236,7 +324,7 @@ public:
|
||||||
|
|
||||||
mutable RID_Owner<Texture> texture_owner;
|
mutable RID_Owner<Texture> texture_owner;
|
||||||
|
|
||||||
Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type);
|
Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed);
|
||||||
|
|
||||||
virtual RID texture_create();
|
virtual RID texture_create();
|
||||||
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
|
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
|
||||||
|
@ -272,6 +360,15 @@ public:
|
||||||
|
|
||||||
/* SKY API */
|
/* SKY API */
|
||||||
|
|
||||||
|
struct Sky : public RID_Data {
|
||||||
|
|
||||||
|
RID panorama;
|
||||||
|
GLuint radiance;
|
||||||
|
int radiance_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Sky> sky_owner;
|
||||||
|
|
||||||
virtual RID sky_create();
|
virtual RID sky_create();
|
||||||
virtual void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
|
virtual void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
|
||||||
|
|
||||||
|
@ -332,7 +429,6 @@ public:
|
||||||
|
|
||||||
} canvas_item;
|
} canvas_item;
|
||||||
|
|
||||||
/*
|
|
||||||
struct Spatial {
|
struct Spatial {
|
||||||
|
|
||||||
enum BlendMode {
|
enum BlendMode {
|
||||||
|
@ -369,6 +465,7 @@ public:
|
||||||
bool uses_discard;
|
bool uses_discard;
|
||||||
bool uses_sss;
|
bool uses_sss;
|
||||||
bool uses_screen_texture;
|
bool uses_screen_texture;
|
||||||
|
bool uses_depth_texture;
|
||||||
bool uses_time;
|
bool uses_time;
|
||||||
bool writes_modelview_or_projection;
|
bool writes_modelview_or_projection;
|
||||||
bool uses_vertex_lighting;
|
bool uses_vertex_lighting;
|
||||||
|
@ -379,7 +476,6 @@ public:
|
||||||
struct Particles {
|
struct Particles {
|
||||||
|
|
||||||
} particles;
|
} particles;
|
||||||
*/
|
|
||||||
|
|
||||||
bool uses_vertex_time;
|
bool uses_vertex_time;
|
||||||
bool uses_fragment_time;
|
bool uses_fragment_time;
|
||||||
|
@ -419,7 +515,7 @@ public:
|
||||||
Map<StringName, Variant> params;
|
Map<StringName, Variant> params;
|
||||||
SelfList<Material> list;
|
SelfList<Material> list;
|
||||||
SelfList<Material> dirty_list;
|
SelfList<Material> dirty_list;
|
||||||
Vector<RID> textures;
|
Vector<Pair<StringName, RID> > textures;
|
||||||
float line_width;
|
float line_width;
|
||||||
int render_priority;
|
int render_priority;
|
||||||
|
|
||||||
|
@ -449,6 +545,11 @@ public:
|
||||||
mutable SelfList<Material>::List _material_dirty_list;
|
mutable SelfList<Material>::List _material_dirty_list;
|
||||||
void _material_make_dirty(Material *p_material) const;
|
void _material_make_dirty(Material *p_material) const;
|
||||||
|
|
||||||
|
void _material_add_geometry(RID p_material, Geometry *p_geometry);
|
||||||
|
void _material_remove_geometry(RID p_material, Geometry *p_geometry);
|
||||||
|
|
||||||
|
void _update_material(Material *p_material);
|
||||||
|
|
||||||
mutable RID_Owner<Material> material_owner;
|
mutable RID_Owner<Material> material_owner;
|
||||||
|
|
||||||
virtual RID material_create();
|
virtual RID material_create();
|
||||||
|
@ -473,6 +574,109 @@ public:
|
||||||
void update_dirty_materials();
|
void update_dirty_materials();
|
||||||
|
|
||||||
/* MESH API */
|
/* MESH API */
|
||||||
|
|
||||||
|
struct Mesh;
|
||||||
|
|
||||||
|
struct Surface : public Geometry {
|
||||||
|
|
||||||
|
struct Attrib {
|
||||||
|
bool enabled;
|
||||||
|
bool integer;
|
||||||
|
GLuint index;
|
||||||
|
GLint size;
|
||||||
|
GLenum type;
|
||||||
|
GLboolean normalized;
|
||||||
|
GLsizei stride;
|
||||||
|
uint32_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
Attrib attribs[VS::ARRAY_MAX];
|
||||||
|
|
||||||
|
Mesh *mesh;
|
||||||
|
uint32_t format;
|
||||||
|
|
||||||
|
GLuint vertex_id;
|
||||||
|
GLuint index_id;
|
||||||
|
|
||||||
|
struct BlendShape {
|
||||||
|
GLuint vertex_id;
|
||||||
|
GLuint array_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<BlendShape> blend_shapes;
|
||||||
|
|
||||||
|
AABB aabb;
|
||||||
|
|
||||||
|
int array_len;
|
||||||
|
int index_array_len;
|
||||||
|
int max_bone;
|
||||||
|
|
||||||
|
int array_byte_size;
|
||||||
|
int index_array_byte_size;
|
||||||
|
|
||||||
|
VS::PrimitiveType primitive;
|
||||||
|
|
||||||
|
Vector<AABB> skeleton_bone_aabb;
|
||||||
|
Vector<bool> skeleton_bone_used;
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
PoolVector<uint8_t> data;
|
||||||
|
PoolVector<uint8_t> index_data;
|
||||||
|
|
||||||
|
int total_data_size;
|
||||||
|
|
||||||
|
Surface() {
|
||||||
|
array_byte_size = 0;
|
||||||
|
index_array_byte_size = 0;
|
||||||
|
|
||||||
|
array_len = 0;
|
||||||
|
index_array_len = 0;
|
||||||
|
|
||||||
|
mesh = NULL;
|
||||||
|
|
||||||
|
primitive = VS::PRIMITIVE_POINTS;
|
||||||
|
|
||||||
|
active = false;
|
||||||
|
|
||||||
|
total_data_size = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultiMesh;
|
||||||
|
|
||||||
|
struct Mesh : public GeometryOwner {
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
Vector<Surface *> surfaces;
|
||||||
|
|
||||||
|
int blend_shape_count;
|
||||||
|
VS::BlendShapeMode blend_shape_mode;
|
||||||
|
|
||||||
|
AABB custom_aabb;
|
||||||
|
|
||||||
|
mutable uint64_t last_pass;
|
||||||
|
|
||||||
|
SelfList<MultiMesh>::List multimeshes;
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void update_multimeshes() {
|
||||||
|
SelfList<MultiMesh> *mm = multimeshes.first();
|
||||||
|
|
||||||
|
while (mm) {
|
||||||
|
mm->self()->instance_material_change_notify();
|
||||||
|
mm = mm->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh() {
|
||||||
|
blend_shape_mode = VS::BLEND_SHAPE_MODE_NORMALIZED;
|
||||||
|
blend_shape_count = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Mesh> mesh_owner;
|
||||||
|
|
||||||
virtual RID mesh_create();
|
virtual RID mesh_create();
|
||||||
|
|
||||||
virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>());
|
virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>());
|
||||||
|
@ -512,6 +716,55 @@ public:
|
||||||
|
|
||||||
/* MULTIMESH API */
|
/* MULTIMESH API */
|
||||||
|
|
||||||
|
struct MultiMesh : public GeometryOwner {
|
||||||
|
|
||||||
|
RID mesh;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
VS::MultimeshTransformFormat transform_format;
|
||||||
|
VS::MultimeshColorFormat color_format;
|
||||||
|
VS::MultimeshCustomDataFormat custom_data_format;
|
||||||
|
|
||||||
|
Vector<float> data;
|
||||||
|
|
||||||
|
AABB aabb;
|
||||||
|
|
||||||
|
SelfList<MultiMesh> update_list;
|
||||||
|
SelfList<MultiMesh> mesh_list;
|
||||||
|
|
||||||
|
int visible_instances;
|
||||||
|
|
||||||
|
int xform_floats;
|
||||||
|
int color_floats;
|
||||||
|
int custom_data_floats;
|
||||||
|
|
||||||
|
bool dirty_aabb;
|
||||||
|
bool dirty_data;
|
||||||
|
|
||||||
|
MultiMesh() :
|
||||||
|
update_list(this),
|
||||||
|
mesh_list(this) {
|
||||||
|
dirty_aabb = true;
|
||||||
|
dirty_data = true;
|
||||||
|
|
||||||
|
xform_floats = 0;
|
||||||
|
color_floats = 0;
|
||||||
|
custom_data_floats = 0;
|
||||||
|
|
||||||
|
visible_instances = -1;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
transform_format = VS::MULTIMESH_TRANSFORM_2D;
|
||||||
|
color_format = VS::MULTIMESH_COLOR_NONE;
|
||||||
|
custom_data_format = VS::MULTIMESH_CUSTOM_DATA_NONE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<MultiMesh> multimesh_owner;
|
||||||
|
|
||||||
|
SelfList<MultiMesh>::List multimesh_update_list;
|
||||||
|
|
||||||
virtual RID multimesh_create();
|
virtual RID multimesh_create();
|
||||||
|
|
||||||
virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE);
|
virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data = VS::MULTIMESH_CUSTOM_DATA_NONE);
|
||||||
|
@ -521,7 +774,7 @@ public:
|
||||||
virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
|
virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
|
||||||
virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform);
|
virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform);
|
||||||
virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
|
virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
|
||||||
virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color);
|
virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_custom_data);
|
||||||
|
|
||||||
virtual RID multimesh_get_mesh(RID p_multimesh) const;
|
virtual RID multimesh_get_mesh(RID p_multimesh) const;
|
||||||
|
|
||||||
|
@ -557,6 +810,33 @@ public:
|
||||||
|
|
||||||
/* SKELETON API */
|
/* SKELETON API */
|
||||||
|
|
||||||
|
struct Skeleton : RID_Data {
|
||||||
|
|
||||||
|
bool use_2d;
|
||||||
|
|
||||||
|
int size;
|
||||||
|
|
||||||
|
// TODO use float textures for storage
|
||||||
|
|
||||||
|
Vector<float> bone_data;
|
||||||
|
|
||||||
|
GLuint tex_id;
|
||||||
|
|
||||||
|
SelfList<Skeleton> update_list;
|
||||||
|
Set<RasterizerScene::InstanceBase *> instances;
|
||||||
|
|
||||||
|
Skeleton() :
|
||||||
|
update_list(this) {
|
||||||
|
tex_id = 0;
|
||||||
|
size = 0;
|
||||||
|
use_2d = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Skeleton> skeleton_owner;
|
||||||
|
|
||||||
|
SelfList<Skeleton>::List skeleton_update_list;
|
||||||
|
|
||||||
void update_dirty_skeletons();
|
void update_dirty_skeletons();
|
||||||
|
|
||||||
virtual RID skeleton_create();
|
virtual RID skeleton_create();
|
||||||
|
@ -568,8 +848,38 @@ public:
|
||||||
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
|
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
|
||||||
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
|
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
|
||||||
|
|
||||||
|
void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size);
|
||||||
|
|
||||||
/* Light API */
|
/* Light API */
|
||||||
|
|
||||||
|
struct Light : Instanciable {
|
||||||
|
VS::LightType type;
|
||||||
|
float param[VS::LIGHT_PARAM_MAX];
|
||||||
|
|
||||||
|
Color color;
|
||||||
|
Color shadow_color;
|
||||||
|
|
||||||
|
RID projector;
|
||||||
|
|
||||||
|
bool shadow;
|
||||||
|
bool negative;
|
||||||
|
bool reverse_cull;
|
||||||
|
|
||||||
|
uint32_t cull_mask;
|
||||||
|
|
||||||
|
VS::LightOmniShadowMode omni_shadow_mode;
|
||||||
|
VS::LightOmniShadowDetail omni_shadow_detail;
|
||||||
|
|
||||||
|
VS::LightDirectionalShadowMode directional_shadow_mode;
|
||||||
|
VS::LightDirectionalShadowDepthRangeMode directional_range_mode;
|
||||||
|
|
||||||
|
bool directional_blend_splits;
|
||||||
|
|
||||||
|
uint64_t version;
|
||||||
|
};
|
||||||
|
|
||||||
|
mutable RID_Owner<Light> light_owner;
|
||||||
|
|
||||||
virtual RID light_create(VS::LightType p_type);
|
virtual RID light_create(VS::LightType p_type);
|
||||||
|
|
||||||
virtual void light_set_color(RID p_light, const Color &p_color);
|
virtual void light_set_color(RID p_light, const Color &p_color);
|
||||||
|
@ -831,6 +1141,8 @@ public:
|
||||||
void initialize();
|
void initialize();
|
||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
|
void _copy_screen();
|
||||||
|
|
||||||
virtual bool has_os_feature(const String &p_feature) const;
|
virtual bool has_os_feature(const String &p_feature) const;
|
||||||
|
|
||||||
virtual void update_dirty_resources();
|
virtual void update_dirty_resources();
|
||||||
|
|
|
@ -325,7 +325,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
uniform_code += ";\n";
|
uniform_code += ";\n";
|
||||||
|
|
||||||
if (SL::is_sampler_type(E->get().type)) {
|
if (SL::is_sampler_type(E->get().type)) {
|
||||||
r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key());
|
r_gen_code.texture_uniforms.write[E->get().texture_order] = E->key();
|
||||||
r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
|
r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
|
||||||
} else {
|
} else {
|
||||||
r_gen_code.uniforms.write[E->get().order] = E->key();
|
r_gen_code.uniforms.write[E->get().order] = E->key();
|
||||||
|
@ -507,7 +507,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
case SL::OP_ASSIGN_DIV:
|
case SL::OP_ASSIGN_DIV:
|
||||||
case SL::OP_ASSIGN_SHIFT_LEFT:
|
case SL::OP_ASSIGN_SHIFT_LEFT:
|
||||||
case SL::OP_ASSIGN_SHIFT_RIGHT:
|
case SL::OP_ASSIGN_SHIFT_RIGHT:
|
||||||
case SL::OP_ASSIGN_MOD:
|
|
||||||
case SL::OP_ASSIGN_BIT_AND:
|
case SL::OP_ASSIGN_BIT_AND:
|
||||||
case SL::OP_ASSIGN_BIT_OR:
|
case SL::OP_ASSIGN_BIT_OR:
|
||||||
case SL::OP_ASSIGN_BIT_XOR: {
|
case SL::OP_ASSIGN_BIT_XOR: {
|
||||||
|
@ -518,6 +517,16 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case SL::OP_ASSIGN_MOD: {
|
||||||
|
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true);
|
||||||
|
code += " = ";
|
||||||
|
code += "mod(";
|
||||||
|
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true);
|
||||||
|
code += ", ";
|
||||||
|
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += ")";
|
||||||
|
} break;
|
||||||
|
|
||||||
case SL::OP_BIT_INVERT:
|
case SL::OP_BIT_INVERT:
|
||||||
case SL::OP_NEGATE:
|
case SL::OP_NEGATE:
|
||||||
case SL::OP_NOT:
|
case SL::OP_NOT:
|
||||||
|
@ -552,6 +561,45 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
code += "textureCube";
|
code += "textureCube";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (var_node->name == "textureLod") {
|
||||||
|
// emit texture call
|
||||||
|
|
||||||
|
if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) {
|
||||||
|
code += "texture2DLod";
|
||||||
|
} else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) {
|
||||||
|
code += "textureCubeLod";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (var_node->name == "mix") {
|
||||||
|
|
||||||
|
switch (op_node->arguments[3]->get_datatype()) {
|
||||||
|
|
||||||
|
case SL::TYPE_BVEC2: {
|
||||||
|
code += "select2";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case SL::TYPE_BVEC3: {
|
||||||
|
code += "select3";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case SL::TYPE_BVEC4: {
|
||||||
|
code += "select4";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case SL::TYPE_VEC2:
|
||||||
|
case SL::TYPE_VEC3:
|
||||||
|
case SL::TYPE_VEC4:
|
||||||
|
case SL::TYPE_FLOAT: {
|
||||||
|
|
||||||
|
code += "mix";
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
SL::DataType type = op_node->arguments[3]->get_datatype();
|
||||||
|
print_line(String("uhhhh invalid mix with type: ") + itos(type));
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (p_default_actions.renames.has(var_node->name)) {
|
} else if (p_default_actions.renames.has(var_node->name)) {
|
||||||
code += p_default_actions.renames[var_node->name];
|
code += p_default_actions.renames[var_node->name];
|
||||||
} else if (internal_functions.has(var_node->name)) {
|
} else if (internal_functions.has(var_node->name)) {
|
||||||
|
@ -590,6 +638,15 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case SL::OP_MOD: {
|
||||||
|
|
||||||
|
code += "mod(";
|
||||||
|
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += ", ";
|
||||||
|
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += ")";
|
||||||
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
code += "(";
|
code += "(";
|
||||||
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
@ -751,10 +808,10 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
|
||||||
/** SPATIAL SHADER **/
|
/** SPATIAL SHADER **/
|
||||||
|
|
||||||
actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
|
actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
|
||||||
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix";
|
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_matrix";
|
||||||
actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix";
|
actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_inverse_matrix";
|
||||||
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
|
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
|
||||||
actions[VS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
|
actions[VS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "projection_inverse_matrix";
|
||||||
actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
|
actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
|
||||||
|
|
||||||
actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
|
actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
|
||||||
|
|
|
@ -33,7 +33,10 @@
|
||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
#include "string_builder.h"
|
#include "string_builder.h"
|
||||||
|
|
||||||
//#define DEBUG_OPENGL
|
#include "rasterizer_gles2.h"
|
||||||
|
#include "rasterizer_storage_gles2.h"
|
||||||
|
|
||||||
|
// #define DEBUG_OPENGL
|
||||||
|
|
||||||
// #include "shaders/copy.glsl.gen.h"
|
// #include "shaders/copy.glsl.gen.h"
|
||||||
|
|
||||||
|
@ -54,7 +57,7 @@
|
||||||
|
|
||||||
ShaderGLES2 *ShaderGLES2::active = NULL;
|
ShaderGLES2 *ShaderGLES2::active = NULL;
|
||||||
|
|
||||||
//#define DEBUG_SHADER
|
// #define DEBUG_SHADER
|
||||||
|
|
||||||
#ifdef DEBUG_SHADER
|
#ifdef DEBUG_SHADER
|
||||||
|
|
||||||
|
@ -83,7 +86,10 @@ void ShaderGLES2::bind_uniforms() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variant &v = E->value();
|
Variant v;
|
||||||
|
|
||||||
|
v = E->value();
|
||||||
|
|
||||||
_set_uniform_variant(location, v);
|
_set_uniform_variant(location, v);
|
||||||
E = E->next();
|
E = E->next();
|
||||||
}
|
}
|
||||||
|
@ -128,6 +134,28 @@ 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;
|
||||||
|
@ -228,7 +256,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_v)
|
if (!_v)
|
||||||
version_map[conditional_version];
|
version_map[conditional_version] = Version();
|
||||||
|
|
||||||
Version &v = version_map[conditional_version];
|
Version &v = version_map[conditional_version];
|
||||||
|
|
||||||
|
@ -389,6 +417,10 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
||||||
strings.push_back(fragment_code3.get_data());
|
strings.push_back(fragment_code3.get_data());
|
||||||
|
|
||||||
#ifdef DEBUG_SHADER
|
#ifdef DEBUG_SHADER
|
||||||
|
|
||||||
|
if (cc) {
|
||||||
|
DEBUG_PRINT("\nFragment Code:\n\n" + String(cc->fragment_globals));
|
||||||
|
}
|
||||||
DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
|
DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -500,9 +532,18 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc) {
|
if (cc) {
|
||||||
v.custom_uniform_locations.resize(cc->custom_uniforms.size());
|
// uniforms
|
||||||
for (int i = 0; i < cc->custom_uniforms.size(); i++) {
|
for (int i = 0; i < cc->custom_uniforms.size(); i++) {
|
||||||
v.custom_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->custom_uniforms[i]).ascii().get_data());
|
StringName native_uniform_name = "m_" + cc->custom_uniforms[i];
|
||||||
|
GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data());
|
||||||
|
v.custom_uniform_locations[cc->custom_uniforms[i]] = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
// textures
|
||||||
|
for (int i = 0; i < cc->texture_uniforms.size(); i++) {
|
||||||
|
StringName native_uniform_name = "m_" + cc->texture_uniforms[i];
|
||||||
|
GLint location = glGetUniformLocation(v.id, ((String)native_uniform_name).ascii().get_data());
|
||||||
|
v.custom_uniform_locations[cc->texture_uniforms[i]] = location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,6 +701,7 @@ void ShaderGLES2::set_custom_shader_code(uint32_t p_code_id,
|
||||||
cc->light = p_light;
|
cc->light = p_light;
|
||||||
cc->custom_uniforms = p_uniforms;
|
cc->custom_uniforms = p_uniforms;
|
||||||
cc->custom_defines = p_custom_defines;
|
cc->custom_defines = p_custom_defines;
|
||||||
|
cc->texture_uniforms = p_texture_uniforms;
|
||||||
cc->version++;
|
cc->version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,6 +717,341 @@ void ShaderGLES2::free_custom_shader(uint32_t p_code_id) {
|
||||||
custom_code_map.erase(p_code_id);
|
custom_code_map.erase(p_code_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) {
|
||||||
|
RasterizerStorageGLES2::Material *material = (RasterizerStorageGLES2::Material *)p_material;
|
||||||
|
|
||||||
|
if (!material) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!material->shader) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Version *v = version_map.getptr(conditional_version);
|
||||||
|
|
||||||
|
CustomCode *cc = NULL;
|
||||||
|
if (v) {
|
||||||
|
cc = custom_code_map.getptr(v->code_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind uniforms
|
||||||
|
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
if (E->get().texture_order >= 0)
|
||||||
|
continue; // this is a texture, doesn't go here
|
||||||
|
|
||||||
|
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) {
|
||||||
|
value.second = Vector<ShaderLanguage::ConstantNode::Value>();
|
||||||
|
value.second.resize(E->get().default_value.size());
|
||||||
|
switch (E->get().type) {
|
||||||
|
case ShaderLanguage::TYPE_BOOL: {
|
||||||
|
if (value.second.size() < 1)
|
||||||
|
value.second.resize(1);
|
||||||
|
value.second.write[0].boolean = V->get();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC2: {
|
||||||
|
if (value.second.size() < 2)
|
||||||
|
value.second.resize(2);
|
||||||
|
int flags = V->get();
|
||||||
|
value.second.write[0].boolean = flags & 1;
|
||||||
|
value.second.write[1].boolean = flags & 2;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC3: {
|
||||||
|
if (value.second.size() < 3)
|
||||||
|
value.second.resize(3);
|
||||||
|
int flags = V->get();
|
||||||
|
value.second.write[0].boolean = flags & 1;
|
||||||
|
value.second.write[1].boolean = flags & 2;
|
||||||
|
value.second.write[2].boolean = flags & 4;
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC4: {
|
||||||
|
if (value.second.size() < 4)
|
||||||
|
value.second.resize(4);
|
||||||
|
int flags = V->get();
|
||||||
|
value.second.write[0].boolean = flags & 1;
|
||||||
|
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;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_UINT: {
|
||||||
|
if (value.second.size() < 1)
|
||||||
|
value.second.resize(1);
|
||||||
|
uint32_t val = V->get();
|
||||||
|
value.second.write[0].uint = val;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_UVEC2: {
|
||||||
|
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].uint = val[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_UVEC3: {
|
||||||
|
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].uint = val[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_UVEC4: {
|
||||||
|
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].uint = val[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_FLOAT: {
|
||||||
|
if (value.second.size() < 1)
|
||||||
|
value.second.resize(1);
|
||||||
|
value.second.write[0].real = V->get();
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC2: {
|
||||||
|
if (value.second.size() < 2)
|
||||||
|
value.second.resize(2);
|
||||||
|
Vector2 val = V->get();
|
||||||
|
value.second.write[0].real = val.x;
|
||||||
|
value.second.write[1].real = val.y;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC3: {
|
||||||
|
if (value.second.size() < 3)
|
||||||
|
value.second.resize(3);
|
||||||
|
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;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC4: {
|
||||||
|
if (value.second.size() < 4)
|
||||||
|
value.second.resize(4);
|
||||||
|
if (V->get().get_type() == Variant::PLANE) {
|
||||||
|
Plane val = V->get();
|
||||||
|
value.second.write[0].real = val.normal.x;
|
||||||
|
value.second.write[1].real = val.normal.y;
|
||||||
|
value.second.write[2].real = val.normal.z;
|
||||||
|
value.second.write[3].real = val.d;
|
||||||
|
} else {
|
||||||
|
Color val = V->get();
|
||||||
|
value.second.write[0].real = val.r;
|
||||||
|
value.second.write[1].real = val.g;
|
||||||
|
value.second.write[2].real = val.b;
|
||||||
|
value.second.write[3].real = val.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_MAT2: {
|
||||||
|
Transform2D val = V->get();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_MAT3: {
|
||||||
|
Basis val = V->get();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_MAT4: {
|
||||||
|
Transform val = V->get();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_SAMPLER2D: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_ISAMPLER2D: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_USAMPLER2D: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_SAMPLERCUBE: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value.second.size() == 0) {
|
||||||
|
// No default value set... weird, let's just use zero for everything
|
||||||
|
size_t default_arg_size = 1;
|
||||||
|
bool is_float = false;
|
||||||
|
switch (E->get().type) {
|
||||||
|
case ShaderLanguage::TYPE_BOOL:
|
||||||
|
case ShaderLanguage::TYPE_INT:
|
||||||
|
case ShaderLanguage::TYPE_UINT: {
|
||||||
|
default_arg_size = 1;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_FLOAT: {
|
||||||
|
default_arg_size = 1;
|
||||||
|
is_float = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC2:
|
||||||
|
case ShaderLanguage::TYPE_IVEC2:
|
||||||
|
case ShaderLanguage::TYPE_UVEC2: {
|
||||||
|
default_arg_size = 2;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC2: {
|
||||||
|
default_arg_size = 2;
|
||||||
|
is_float = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC3:
|
||||||
|
case ShaderLanguage::TYPE_IVEC3:
|
||||||
|
case ShaderLanguage::TYPE_UVEC3: {
|
||||||
|
default_arg_size = 3;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC3: {
|
||||||
|
default_arg_size = 3;
|
||||||
|
is_float = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_BVEC4:
|
||||||
|
case ShaderLanguage::TYPE_IVEC4:
|
||||||
|
case ShaderLanguage::TYPE_UVEC4: {
|
||||||
|
default_arg_size = 4;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case ShaderLanguage::TYPE_VEC4: {
|
||||||
|
default_arg_size = 4;
|
||||||
|
is_float = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// TODO matricies and all that stuff
|
||||||
|
default_arg_size = 1;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.second.resize(default_arg_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < default_arg_size; i++) {
|
||||||
|
if (is_float) {
|
||||||
|
value.second.write[i].real = 0.0;
|
||||||
|
} else {
|
||||||
|
value.second.write[i].uint = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GLint location = get_uniform_location(E->key());
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = material->shader->texture_hints.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 = p_num_predef_textures + 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) {
|
void ShaderGLES2::set_base_material_tex_index(int p_idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,11 @@
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
|
#include "core/pair.h"
|
||||||
|
#include "servers/visual/shader_language.h"
|
||||||
|
|
||||||
|
class RasterizerStorageGLES2;
|
||||||
|
|
||||||
class ShaderGLES2 {
|
class ShaderGLES2 {
|
||||||
protected:
|
protected:
|
||||||
struct Enum {
|
struct Enum {
|
||||||
|
@ -105,9 +110,10 @@ 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;
|
||||||
Vector<GLint> custom_uniform_locations;
|
Map<StringName, GLint> custom_uniform_locations;
|
||||||
uint32_t code_version;
|
uint32_t code_version;
|
||||||
bool ok;
|
bool ok;
|
||||||
Version() {
|
Version() {
|
||||||
|
@ -169,6 +175,168 @@ 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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ShaderGLES2();
|
||||||
|
|
||||||
|
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_ ShaderGLES2 *get_active() { return active; }
|
||||||
|
bool bind();
|
||||||
|
void unbind();
|
||||||
|
void bind_uniforms();
|
||||||
|
|
||||||
|
inline GLuint get_program() const { return version ? version->id : 0; }
|
||||||
|
|
||||||
|
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 < 0; 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 < 0; 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform, const Variant &p_value) {
|
_FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform, const Variant &p_value) {
|
||||||
|
|
||||||
if (p_uniform < 0)
|
if (p_uniform < 0)
|
||||||
|
@ -261,50 +429,14 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
glUniformMatrix4fv(p_uniform, 1, false, matrix);
|
glUniformMatrix4fv(p_uniform, 1, false, matrix);
|
||||||
|
} break;
|
||||||
|
case Variant::OBJECT: {
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
default: { ERR_FAIL(); } // do nothing
|
default: { ERR_FAIL(); } // do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<uint32_t, Variant> uniform_defaults;
|
|
||||||
Map<uint32_t, CameraMatrix> uniform_cameras;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
_FORCE_INLINE_ int _get_uniform(int p_which) const;
|
|
||||||
_FORCE_INLINE_ void _set_conditional(int p_which, bool p_value);
|
|
||||||
|
|
||||||
void setup(const char **p_conditional_defines,
|
|
||||||
int p_conditional_count,
|
|
||||||
const char **p_uniform_names,
|
|
||||||
int p_uniform_count,
|
|
||||||
const AttributePair *p_attribute_pairs,
|
|
||||||
int p_attribute_count,
|
|
||||||
const TexUnitPair *p_texunit_pairs,
|
|
||||||
int p_texunit_pair_count,
|
|
||||||
const char *p_vertex_code,
|
|
||||||
const char *p_fragment_code,
|
|
||||||
int p_vertex_code_start,
|
|
||||||
int p_fragment_code_start);
|
|
||||||
|
|
||||||
ShaderGLES2();
|
|
||||||
|
|
||||||
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_ ShaderGLES2 *get_active() { return active; }
|
|
||||||
bool bind();
|
|
||||||
void unbind();
|
|
||||||
void bind_uniforms();
|
|
||||||
|
|
||||||
inline GLuint get_program() const { return version ? version->id : 0; }
|
|
||||||
|
|
||||||
void clear_caches();
|
|
||||||
|
|
||||||
uint32_t create_custom_shader();
|
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,
|
||||||
|
@ -331,6 +463,10 @@ public:
|
||||||
uniforms_dirty = true;
|
uniforms_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't
|
||||||
|
// like forward declared nested classes.
|
||||||
|
void use_material(void *p_material, int p_num_predef_textures);
|
||||||
|
|
||||||
uint32_t get_version() const { return new_conditional_version.version; }
|
uint32_t get_version() const { return new_conditional_version.version; }
|
||||||
|
|
||||||
void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {
|
void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) {
|
||||||
|
|
|
@ -8,8 +8,8 @@ if 'GLES2_GLSL' in env['BUILDERS']:
|
||||||
env.GLES2_GLSL('canvas.glsl');
|
env.GLES2_GLSL('canvas.glsl');
|
||||||
# env.GLES2_GLSL('canvas_shadow.glsl');
|
# env.GLES2_GLSL('canvas_shadow.glsl');
|
||||||
env.GLES2_GLSL('scene.glsl');
|
env.GLES2_GLSL('scene.glsl');
|
||||||
# env.GLES2_GLSL('cubemap_filter.glsl');
|
env.GLES2_GLSL('cubemap_filter.glsl');
|
||||||
# env.GLES2_GLSL('cube_to_dp.glsl');
|
env.GLES2_GLSL('cube_to_dp.glsl');
|
||||||
# env.GLES2_GLSL('blend_shape.glsl');
|
# env.GLES2_GLSL('blend_shape.glsl');
|
||||||
# env.GLES2_GLSL('screen_space_reflection.glsl');
|
# env.GLES2_GLSL('screen_space_reflection.glsl');
|
||||||
# env.GLES2_GLSL('effect_blur.glsl');
|
# env.GLES2_GLSL('effect_blur.glsl');
|
||||||
|
|
|
@ -27,7 +27,7 @@ uniform vec4 src_rect;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform bool blit_pass;
|
uniform highp float time;
|
||||||
|
|
||||||
VERTEX_SHADER_GLOBALS
|
VERTEX_SHADER_GLOBALS
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ uniform mediump sampler2D normal_texture; // texunit:1
|
||||||
varying mediump vec2 uv_interp;
|
varying mediump vec2 uv_interp;
|
||||||
varying mediump vec4 color_interp;
|
varying mediump vec4 color_interp;
|
||||||
|
|
||||||
uniform bool blit_pass;
|
uniform highp float time;
|
||||||
|
|
||||||
uniform vec4 final_modulate;
|
uniform vec4 final_modulate;
|
||||||
|
|
||||||
|
@ -127,6 +127,10 @@ void main() {
|
||||||
vec4 color = color_interp;
|
vec4 color = color_interp;
|
||||||
|
|
||||||
color *= texture2D(color_texture, uv_interp);
|
color *= texture2D(color_texture, uv_interp);
|
||||||
|
|
||||||
|
#ifdef SCREEN_UV_USED
|
||||||
|
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
FRAGMENT_SHADER_CODE
|
FRAGMENT_SHADER_CODE
|
||||||
|
|
|
@ -9,11 +9,20 @@ precision mediump int;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
attribute highp vec4 vertex_attrib; // attrib:0
|
attribute highp vec4 vertex_attrib; // attrib:0
|
||||||
|
|
||||||
|
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
||||||
|
attribute vec3 cube_in; // attrib:4
|
||||||
|
#else
|
||||||
attribute vec2 uv_in; // attrib:4
|
attribute vec2 uv_in; // attrib:4
|
||||||
|
#endif
|
||||||
|
|
||||||
attribute vec2 uv2_in; // attrib:5
|
attribute vec2 uv2_in; // attrib:5
|
||||||
|
|
||||||
|
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
||||||
|
varying vec3 cube_interp;
|
||||||
|
#else
|
||||||
varying vec2 uv_interp;
|
varying vec2 uv_interp;
|
||||||
|
#endif
|
||||||
varying vec2 uv2_interp;
|
varying vec2 uv2_interp;
|
||||||
|
|
||||||
#ifdef USE_COPY_SECTION
|
#ifdef USE_COPY_SECTION
|
||||||
|
@ -22,7 +31,12 @@ uniform vec4 copy_section;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
|
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
||||||
|
cube_interp = cube_in;
|
||||||
|
#else
|
||||||
uv_interp = uv_in;
|
uv_interp = uv_in;
|
||||||
|
#endif
|
||||||
|
|
||||||
uv2_interp = uv2_in;
|
uv2_interp = uv2_in;
|
||||||
gl_Position = vertex_attrib;
|
gl_Position = vertex_attrib;
|
||||||
|
|
||||||
|
@ -34,6 +48,8 @@ void main() {
|
||||||
|
|
||||||
[fragment]
|
[fragment]
|
||||||
|
|
||||||
|
#define M_PI 3.14159265359
|
||||||
|
|
||||||
#ifdef USE_GLES_OVER_GL
|
#ifdef USE_GLES_OVER_GL
|
||||||
#define mediump
|
#define mediump
|
||||||
#define highp
|
#define highp
|
||||||
|
@ -42,21 +58,59 @@ precision mediump float;
|
||||||
precision mediump int;
|
precision mediump int;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
|
||||||
|
varying vec3 cube_interp;
|
||||||
|
#else
|
||||||
varying vec2 uv_interp;
|
varying vec2 uv_interp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_CUBEMAP
|
||||||
|
uniform samplerCube source_cube; // texunit:0
|
||||||
|
#else
|
||||||
uniform sampler2D source; // texunit:0
|
uniform sampler2D source; // texunit:0
|
||||||
|
#endif
|
||||||
|
|
||||||
varying vec2 uv2_interp;
|
varying vec2 uv2_interp;
|
||||||
|
|
||||||
|
#ifdef USE_MULTIPLIER
|
||||||
|
uniform float multiplier;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CUSTOM_ALPHA
|
#ifdef USE_CUSTOM_ALPHA
|
||||||
uniform float custom_alpha;
|
uniform float custom_alpha;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_PANORAMA) || defined(USE_ASYM_PANO)
|
||||||
|
|
||||||
|
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
||||||
|
|
||||||
|
vec2 st = vec2(
|
||||||
|
atan(normal.x, normal.z),
|
||||||
|
acos(normal.y)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(st.x < 0.0)
|
||||||
|
st.x += M_PI*2.0;
|
||||||
|
|
||||||
|
st/=vec2(M_PI*2.0,M_PI);
|
||||||
|
|
||||||
|
return texture2D(pano,st);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
//vec4 color = color_interp;
|
#ifdef USE_PANORAMA
|
||||||
|
|
||||||
|
vec4 color = texturePanorama(source, normalize(cube_interp));
|
||||||
|
|
||||||
|
#elif defined(USE_CUBEMAP)
|
||||||
|
vec4 color = textureCube(source_cube, normalize(cube_interp));
|
||||||
|
#else
|
||||||
vec4 color = texture2D( source, uv_interp );
|
vec4 color = texture2D( source, uv_interp );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_NO_ALPHA
|
#ifdef USE_NO_ALPHA
|
||||||
|
@ -67,6 +121,9 @@ void main() {
|
||||||
color.a=custom_alpha;
|
color.a=custom_alpha;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_MULTIPLIER
|
||||||
|
color.rgb *= multiplier;
|
||||||
|
#endif
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
[vertex]
|
[vertex]
|
||||||
|
|
||||||
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
layout(location=0) in highp vec4 vertex_attrib;
|
attribute highp vec4 vertex_attrib; // attrib:0
|
||||||
layout(location=4) in vec2 uv_in;
|
attribute vec2 uv_in; // attrib:4
|
||||||
|
|
||||||
out vec2 uv_interp;
|
varying vec2 uv_interp;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
|
@ -14,9 +21,16 @@ void main() {
|
||||||
|
|
||||||
[fragment]
|
[fragment]
|
||||||
|
|
||||||
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform highp samplerCube source_cube; //texunit:0
|
uniform highp samplerCube source_cube; //texunit:0
|
||||||
in vec2 uv_interp;
|
varying vec2 uv_interp;
|
||||||
|
|
||||||
uniform bool z_flip;
|
uniform bool z_flip;
|
||||||
uniform highp float z_far;
|
uniform highp float z_far;
|
||||||
|
@ -49,7 +63,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 ));
|
//normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 ));
|
||||||
float depth = texture(source_cube,normal).r;
|
float depth = textureCube(source_cube,normal).r;
|
||||||
|
|
||||||
// absolute values for direction cosines, bigger value equals closer to basis axis
|
// absolute values for direction cosines, bigger value equals closer to basis axis
|
||||||
vec3 unorm = abs(normal);
|
vec3 unorm = abs(normal);
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
[vertex]
|
[vertex]
|
||||||
|
|
||||||
|
#ifdef USE_GLES_OVER_GL
|
||||||
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
layout(location=0) in highp vec2 vertex;
|
attribute highp vec2 vertex; // attrib:0
|
||||||
|
attribute highp vec2 uv; // attrib:4
|
||||||
|
|
||||||
layout(location=4) in highp vec2 uv;
|
varying highp vec2 uv_interp;
|
||||||
|
|
||||||
out highp vec2 uv_interp;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
|
@ -15,106 +21,99 @@ void main() {
|
||||||
|
|
||||||
[fragment]
|
[fragment]
|
||||||
|
|
||||||
|
#extension GL_ARB_shader_texture_lod : require
|
||||||
|
|
||||||
precision highp float;
|
#ifdef USE_GLES_OVER_GL
|
||||||
precision highp int;
|
#define mediump
|
||||||
|
#define highp
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
#ifdef USE_SOURCE_PANORAMA
|
||||||
uniform sampler2D source_panorama; //texunit:0
|
uniform sampler2D source_panorama; //texunit:0
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
|
|
||||||
uniform sampler2DArray source_dual_paraboloid_array; //texunit:0
|
|
||||||
uniform int source_array_index;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
|
|
||||||
uniform samplerCube source_cube; //texunit:0
|
uniform samplerCube source_cube; //texunit:0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform int face_id;
|
uniform int face_id;
|
||||||
uniform float roughness;
|
uniform float roughness;
|
||||||
in highp vec2 uv_interp;
|
varying highp vec2 uv_interp;
|
||||||
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
|
||||||
|
|
||||||
|
uniform sampler2D radical_inverse_vdc_cache; // texunit:1
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
#define M_PI 3.14159265359
|
||||||
|
|
||||||
|
#ifdef LOW_QUALITY
|
||||||
|
|
||||||
vec3 texelCoordToVec(vec2 uv, int faceID)
|
#define SAMPLE_COUNT 64
|
||||||
{
|
|
||||||
mat3 faceUvVectors[6];
|
|
||||||
/*
|
|
||||||
// -x
|
|
||||||
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
|
|
||||||
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
|
|
||||||
|
|
||||||
// +x
|
#else
|
||||||
faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z
|
|
||||||
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face
|
|
||||||
|
|
||||||
// -y
|
#define SAMPLE_COUNT 512
|
||||||
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z
|
|
||||||
faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face
|
|
||||||
|
|
||||||
// +y
|
#endif
|
||||||
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z
|
|
||||||
faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face
|
|
||||||
|
|
||||||
// -z
|
#ifdef USE_SOURCE_PANORAMA
|
||||||
faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
|
|
||||||
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face
|
|
||||||
|
|
||||||
// +z
|
vec4 texturePanorama(sampler2D pano, vec3 normal) {
|
||||||
faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face
|
|
||||||
*/
|
|
||||||
|
|
||||||
// -x
|
vec2 st = vec2(
|
||||||
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
|
atan(normal.x, normal.z),
|
||||||
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
acos(normal.y)
|
||||||
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
|
);
|
||||||
|
|
||||||
// +x
|
if(st.x < 0.0)
|
||||||
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
|
st.x += M_PI*2.0;
|
||||||
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
|
|
||||||
|
|
||||||
// -y
|
st/=vec2(M_PI*2.0,M_PI);
|
||||||
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
|
|
||||||
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
|
|
||||||
|
|
||||||
// +y
|
return texture2DLod(pano,st,0.0);
|
||||||
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
|
|
||||||
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
|
|
||||||
|
|
||||||
// -z
|
|
||||||
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
|
|
||||||
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
|
|
||||||
|
|
||||||
// +z
|
|
||||||
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
|
||||||
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
|
||||||
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
|
|
||||||
|
|
||||||
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
|
|
||||||
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
|
|
||||||
return normalize(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
|
#endif
|
||||||
{
|
|
||||||
|
vec3 texelCoordToVec(vec2 uv, int faceID) {
|
||||||
|
mat3 faceUvVectors[6];
|
||||||
|
|
||||||
|
// -x
|
||||||
|
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
|
||||||
|
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
||||||
|
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
|
||||||
|
|
||||||
|
// +x
|
||||||
|
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
|
||||||
|
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
||||||
|
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
|
||||||
|
|
||||||
|
// -y
|
||||||
|
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
||||||
|
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
|
||||||
|
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
|
||||||
|
|
||||||
|
// +y
|
||||||
|
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
||||||
|
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
|
||||||
|
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
|
||||||
|
|
||||||
|
// -z
|
||||||
|
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
|
||||||
|
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
||||||
|
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
|
||||||
|
|
||||||
|
// +z
|
||||||
|
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
|
||||||
|
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
|
||||||
|
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
|
||||||
|
|
||||||
|
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
|
||||||
|
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
|
||||||
|
return normalize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
|
||||||
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
|
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
|
||||||
|
|
||||||
// Compute distribution direction
|
// Compute distribution direction
|
||||||
|
@ -136,159 +135,53 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
|
||||||
return TangentX * H.x + TangentY * H.y + N * H.z;
|
return TangentX * H.x + TangentY * H.y + N * H.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
|
float radical_inverse_VdC(int i) {
|
||||||
float GGX(float NdotV, float a)
|
return texture2D(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x;
|
||||||
{
|
|
||||||
float k = a / 2.0;
|
|
||||||
return NdotV / (NdotV * (1.0 - k) + k);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
|
vec2 Hammersley(int i, int N) {
|
||||||
float G_Smith(float a, float nDotV, float nDotL)
|
return vec2(float(i) / float(N), radical_inverse_VdC(i));
|
||||||
{
|
|
||||||
return GGX(nDotL, a * a) * GGX(nDotV, a * a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float radicalInverse_VdC(uint bits) {
|
|
||||||
bits = (bits << 16u) | (bits >> 16u);
|
|
||||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
|
||||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
|
||||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
|
||||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
|
||||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 Hammersley(uint i, uint N) {
|
|
||||||
return vec2(float(i)/float(N), radicalInverse_VdC(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LOW_QUALITY
|
|
||||||
|
|
||||||
#define SAMPLE_COUNT 64u
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define SAMPLE_COUNT 512u
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform bool z_flip;
|
uniform bool z_flip;
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
|
|
||||||
vec4 texturePanorama(vec3 normal,sampler2D pano ) {
|
|
||||||
|
|
||||||
vec2 st = vec2(
|
|
||||||
atan(normal.x, normal.z),
|
|
||||||
acos(normal.y)
|
|
||||||
);
|
|
||||||
|
|
||||||
if(st.x < 0.0)
|
|
||||||
st.x += M_PI*2.0;
|
|
||||||
|
|
||||||
st/=vec2(M_PI*2.0,M_PI);
|
|
||||||
|
|
||||||
return textureLod(pano,st,0.0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
|
|
||||||
|
|
||||||
|
|
||||||
vec4 textureDualParaboloidArray(vec3 normal) {
|
|
||||||
|
|
||||||
vec3 norm = normalize(normal);
|
|
||||||
norm.xy/=1.0+abs(norm.z);
|
|
||||||
norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
|
|
||||||
if (norm.z<0.0) {
|
|
||||||
norm.y=0.5-norm.y+0.5;
|
|
||||||
}
|
|
||||||
return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
#ifdef USE_DUAL_PARABOLOID
|
vec3 color = vec3(0.0);
|
||||||
|
|
||||||
vec3 N = vec3( uv_interp * 2.0 - 1.0, 0.0 );
|
vec2 uv = (uv_interp * 2.0) - 1.0;
|
||||||
N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y));
|
vec3 N = texelCoordToVec(uv, face_id);
|
||||||
N = normalize(N);
|
|
||||||
|
|
||||||
if (z_flip) {
|
vec4 sum = vec4(0.0);
|
||||||
N.y=-N.y; //y is flipped to improve blending between both sides
|
|
||||||
N.z=-N.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (int sample_num = 0; sample_num < SAMPLE_COUNT; sample_num++) {
|
||||||
|
|
||||||
#else
|
vec2 xi = Hammersley(sample_num, SAMPLE_COUNT);
|
||||||
vec2 uv = (uv_interp * 2.0) - 1.0;
|
|
||||||
vec3 N = texelCoordToVec(uv, face_id);
|
|
||||||
#endif
|
|
||||||
//vec4 color = color_interp;
|
|
||||||
|
|
||||||
#ifdef USE_DIRECT_WRITE
|
vec3 H = ImportanceSampleGGX(xi, roughness, N);
|
||||||
|
vec3 V = N;
|
||||||
|
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||||
|
|
||||||
|
float NdotL = clamp(dot(N, L), 0.0, 1.0);
|
||||||
|
|
||||||
|
if (NdotL > 0.0) {
|
||||||
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
#ifdef USE_SOURCE_PANORAMA
|
||||||
|
sum.rgb += texturePanorama(source_panorama, H).rgb * NdotL;
|
||||||
frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
|
|
||||||
|
|
||||||
frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
|
|
||||||
|
|
||||||
N.y=-N.y;
|
|
||||||
frag_color=vec4(texture(N,source_cube).rgb,1.0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
H.y = -H.y;
|
||||||
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
|
sum.rgb += textureCubeLod(source_cube, H, 0.0).rgb * NdotL;
|
||||||
|
|
||||||
for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) {
|
|
||||||
vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT);
|
|
||||||
|
|
||||||
vec3 H = ImportanceSampleGGX( xi, roughness, N );
|
|
||||||
vec3 V = N;
|
|
||||||
vec3 L = normalize(2.0 * dot( V, H ) * H - V);
|
|
||||||
|
|
||||||
float ndotl = clamp(dot(N, L),0.0,1.0);
|
|
||||||
|
|
||||||
if (ndotl>0.0) {
|
|
||||||
#ifdef USE_SOURCE_PANORAMA
|
|
||||||
sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
|
sum.a += NdotL;
|
||||||
|
|
||||||
sum.rgb += textureDualParaboloidArray(H).rgb *ndotl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
|
|
||||||
H.y=-H.y;
|
|
||||||
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
|
|
||||||
#endif
|
|
||||||
sum.a += ndotl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sum /= sum.a;
|
sum /= sum.a;
|
||||||
|
|
||||||
frag_color = vec4(sum.rgb, 1.0);
|
gl_FragColor = vec4(sum.rgb, 1.0);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
45
drivers/gles2/shaders/stdlib.glsl
Normal file
45
drivers/gles2/shaders/stdlib.glsl
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
vec2 select2(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 select3(vec3 a, vec3 b, bvec3 c)
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
|
||||||
|
ret.x = c.x ? b.x : a.x;
|
||||||
|
ret.y = c.y ? b.y : a.y;
|
||||||
|
ret.z = c.z ? b.z : a.z;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 select4(vec4 a, vec4 b, bvec4 c)
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
|
||||||
|
ret.x = c.x ? b.x : a.x;
|
||||||
|
ret.y = c.y ? b.y : a.y;
|
||||||
|
ret.z = c.z ? b.z : a.z;
|
||||||
|
ret.w = c.w ? b.w : a.w;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord)
|
||||||
|
{
|
||||||
|
float x_coord = float(2 * coord.x + 1) / float(size.x * 2);
|
||||||
|
float y_coord = float(2 * coord.y + 1) / float(size.y * 2);
|
||||||
|
|
||||||
|
x_coord = float(coord.x) / float(size.x);
|
||||||
|
y_coord = float(coord.y) / float(size.y);
|
||||||
|
|
||||||
|
return texture2DLod(tex, vec2(x_coord, y_coord), 0.0);
|
||||||
|
}
|
|
@ -259,6 +259,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2
|
||||||
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, 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 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 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, 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) { _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) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n")
|
||||||
|
|
Loading…
Reference in a new issue