summaryrefslogtreecommitdiff
path: root/drivers/gles2/rasterizer_scene_gles2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2/rasterizer_scene_gles2.cpp')
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp138
1 files changed, 137 insertions, 1 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 5f31bfe209..288a144b32 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -812,6 +812,14 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
}
} break;
+ case VS::INSTANCE_IMMEDIATE: {
+ RasterizerStorageGLES2::Immediate *im = storage->immediate_owner.getptr(instance->base);
+ ERR_CONTINUE(!im);
+
+ _add_geometry(im, instance, NULL, -1, p_depth_pass, p_shadow_pass);
+
+ } break;
+
default: {
} break;
@@ -931,6 +939,13 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
state.scene_shader.set_conditional(SceneShaderGLES2::ENABLE_UV2_INTERP, s->attribs[VS::ARRAY_TEX_UV2].enabled);
} break;
+ case VS::INSTANCE_IMMEDIATE: {
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_INSTANCING, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::ENABLE_COLOR_INTERP, true);
+ state.scene_shader.set_conditional(SceneShaderGLES2::ENABLE_UV_INTERP, true);
+ state.scene_shader.set_conditional(SceneShaderGLES2::ENABLE_UV2_INTERP, true);
+ } break;
+
default: {
} break;
@@ -1264,6 +1279,118 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
} break;
+
+ case VS::INSTANCE_IMMEDIATE: {
+ const RasterizerStorageGLES2::Immediate *im = static_cast<const RasterizerStorageGLES2::Immediate *>(p_element->geometry);
+
+ if (im->building) {
+ return;
+ }
+
+ bool restore_tex = false;
+
+ glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
+
+ for (const List<RasterizerStorageGLES2::Immediate::Chunk>::Element *E = im->chunks.front(); E; E = E->next()) {
+ const RasterizerStorageGLES2::Immediate::Chunk &c = E->get();
+
+ if (c.vertices.empty()) {
+ continue;
+ }
+
+ int vertices = c.vertices.size();
+
+ uint32_t buf_ofs = 0;
+
+ storage->info.render.vertices_count += vertices;
+
+ if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) {
+ RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(c.texture);
+
+ t = t->get_ptr();
+
+ if (t->redraw_if_visible) {
+ VisualServerRaster::redraw_request();
+ }
+
+#ifdef TOOLS_ENABLED
+ if (t->detect_3d) {
+ t->detect_3d(t->detect_3d_ud);
+ }
+#endif
+ if (t->render_target) {
+ t->render_target->used_in_frame = true;
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(t->target, t->tex_id);
+ restore_tex = true;
+ } else if (restore_tex) {
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, state.current_main_tex);
+ restore_tex = false;
+ }
+
+ if (!c.normals.empty()) {
+ glEnableVertexAttribArray(VS::ARRAY_NORMAL);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.normals.ptr());
+ glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs);
+ buf_ofs += sizeof(Vector3) * vertices;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_NORMAL);
+ }
+
+ if (!c.tangents.empty()) {
+ glEnableVertexAttribArray(VS::ARRAY_TANGENT);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Plane) * vertices, c.tangents.ptr());
+ glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, GL_FALSE, sizeof(Plane), ((uint8_t *)NULL) + buf_ofs);
+ buf_ofs += sizeof(Plane) * vertices;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_TANGENT);
+ }
+
+ if (!c.colors.empty()) {
+ glEnableVertexAttribArray(VS::ARRAY_COLOR);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Color) * vertices, c.colors.ptr());
+ glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), ((uint8_t *)NULL) + buf_ofs);
+ buf_ofs += sizeof(Color) * vertices;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_COLOR);
+ }
+
+ if (!c.uvs.empty()) {
+ glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uvs.ptr());
+ glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs);
+ buf_ofs += sizeof(Vector2) * vertices;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+ }
+
+ if (!c.uv2s.empty()) {
+ glEnableVertexAttribArray(VS::ARRAY_TEX_UV2);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector2) * vertices, c.uv2s.ptr());
+ glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)NULL) + buf_ofs);
+ buf_ofs += sizeof(Vector2) * vertices;
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV2);
+ }
+
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glBufferSubData(GL_ARRAY_BUFFER, buf_ofs, sizeof(Vector3) * vertices, c.vertices.ptr());
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3), ((uint8_t *)NULL) + buf_ofs);
+
+ glDrawArrays(gl_primitive[c.primitive], 0, c.vertices.size());
+ }
+
+ if (restore_tex) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, state.current_main_tex);
+ restore_tex = false;
+ }
+
+ } break;
}
}
@@ -1904,7 +2031,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
} break;
default: {
- print_line("uhm");
+ // FIXME: implement other background modes
} break;
}
}
@@ -2247,6 +2374,15 @@ void RasterizerSceneGLES2::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
+ {
+ uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048);
+
+ glGenBuffers(1, &state.immediate_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
+ glBufferData(GL_ARRAY_BUFFER, immediate_buffer_size * 1024, NULL, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+
// cubemaps for shadows
{
int max_shadow_cubemap_sampler_size = 512;