From 83adc544382689217e19564fd5f2dd62160956cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 7 Feb 2017 11:20:15 +0100 Subject: Clay-Engine (merge clay-engine) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initial work by Clément Foucault with contributions from Dalai Felinto (mainly per-collection engine settings logic, and depsgraph iterator placeholder). This makes Blender require OpenGL 3.3. Which means Intel graphic card and OSX will break. Disable CLAY_ENGINE in CMake in those cases. This is a prototype render engine intended to help the design of real render engines. This is mainly an engine with enphasis in matcap and ambient occlusion. Implemented Features -------------------- * Clay Render Engine, following the new API, to be used as reference for future engines * A more complete Matcap customization with more options * Per-Collection render engine settings * New Ground Truth AO - not enabled Missing Features ---------------- * Finish object edit mode - Fix shaders to use new matrix - Fix artifacts when edge does off screen - Fix depth issue - Selection sillhouette - Mesh wires - Use mesh normals (for higher quality matcap) - Non-Mesh objects drawing - Widget drawing - Performance issues * Finish mesh edit mode - Derived-Mesh-less edit mode API (mesh_rende.c) * General edit mode - Per-collection edit mode settings * General engines - Per-collection engine settings (they are their, but they still need to be flushed by depsgraph, and used by the drawing code) --- source/blender/gpu/intern/gpu_viewport.c | 196 ++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 3 deletions(-) (limited to 'source/blender/gpu/intern/gpu_viewport.c') diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index a4fb3494639..b1964857ab1 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -31,10 +31,19 @@ * System that manages viewport drawing. */ +#include + +#include "BLI_rect.h" + +#include "DNA_vec_types.h" + +#include "GPU_framebuffer.h" #include "GPU_glew.h" #include "GPU_immediate.h" -#include "GPU_viewport.h" #include "GPU_texture.h" +#include "GPU_viewport.h" + +#include "DRW_engine.h" #include "MEM_guardedalloc.h" @@ -43,19 +52,200 @@ struct GPUViewport { /* debug */ GPUTexture *debug_depth; - int debug_width, debug_height; + int size[2]; + + /* Viewport Buffer Storage */ + /* TODO indentify to what engine conf are theses buffers */ + DefaultFramebufferList *fbl; + DefaultTextureList *txl; + DefaultPassList *psl; }; +static void GPU_viewport_buffers_free(GPUViewport *viewport); +static void GPU_viewport_passes_free(GPUViewport *viewport); + GPUViewport *GPU_viewport_create(void) { GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport"); + viewport->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList"); + viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList"); + viewport->psl = MEM_callocN(sizeof(PassList), "PassList"); + viewport->size[0] = viewport->size[1] = -1; + return viewport; } +void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss) +{ + *fbs = viewport->fbl; + *txs = viewport->txl; + *pss = viewport->psl; +} + +void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) +{ + /* add one pixel because of scissor test */ + int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1; + +#ifndef WITH_VIEWPORT_CACHE_TEST + /* TODO for testing only, we need proper cache invalidation */ + GPU_viewport_passes_free(viewport); +#endif + + if (viewport->fbl->default_fb) { + if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) { + GPU_viewport_buffers_free(viewport); + } + } + + if (!viewport->fbl->default_fb) { + bool ok = true; + viewport->size[0] = rect_w; + viewport->size[1] = rect_h; + + viewport->fbl->default_fb = GPU_framebuffer_create(); + if (!viewport->fbl->default_fb) { + ok = false; + goto cleanup; + } + + /* Color */ + /* No multi samples for now */ + viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL); + if (!viewport->txl->color) { + ok = false; + goto cleanup; + } + + if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) { + ok = false; + goto cleanup; + } + + /* Depth */ + viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL); + if (!viewport->txl->depth) { + ok = false; + goto cleanup; + } + else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) { + ok = false; + goto cleanup; + } + else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) { + ok = false; + goto cleanup; + } + +cleanup: + if (!ok) { + GPU_viewport_free(viewport); + MEM_freeN(viewport); + return; + } + + GPU_framebuffer_restore(); + } + + GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0); +} + +static void draw_ofs_to_screen(GPUViewport *viewport) +{ + GPUTexture *color = viewport->txl->color; + + const float w = (float)GPU_texture_width(color); + const float h = (float)GPU_texture_height(color); + + VertexFormat *format = immVertexFormat(); + unsigned texcoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT); + unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); + + GPU_texture_bind(color, 0); + + immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ + + immBegin(GL_QUADS, 4); + + immAttrib2f(texcoord, 0.0f, 0.0f); + immVertex2f(pos, 0.0f, 0.0f); + + immAttrib2f(texcoord, 1.0f, 0.0f); + immVertex2f(pos, w, 0.0f); + + immAttrib2f(texcoord, 1.0f, 1.0f); + immVertex2f(pos, w, h); + + immAttrib2f(texcoord, 0.0f, 1.0f); + immVertex2f(pos, 0.0f, h); + + immEnd(); + + GPU_texture_unbind(color); + + immUnbindProgram(); +} + +void GPU_viewport_unbind(GPUViewport *viewport) +{ + if (viewport->fbl->default_fb) { + GPU_framebuffer_texture_unbind(NULL, NULL); + GPU_framebuffer_restore(); + + glEnable(GL_SCISSOR_TEST); + + /* This might be bandwidth limiting */ + draw_ofs_to_screen(viewport); + } +} + +static void GPU_viewport_buffers_free(GPUViewport *viewport) +{ + FramebufferList *fbl = (FramebufferList *)viewport->fbl; + TextureList *txl = (TextureList *)viewport->txl; + int i; + for (i = MAX_BUFFERS - 1; i > -1; --i) { + GPUFrameBuffer *fb = fbl->framebuffers[i]; + if (fb) { + GPU_framebuffer_free(fb); + fbl->framebuffers[i] = NULL; + } + } + for (i = MAX_TEXTURES - 1; i > -1; --i) { + GPUTexture *tex = txl->textures[i]; + if (tex) { + GPU_texture_free(tex); + txl->textures[i] = NULL; + } + } +} + +static void GPU_viewport_passes_free(GPUViewport *viewport) +{ + PassList *psl = (PassList *)viewport->psl; + int i; + + for (i = MAX_PASSES - 1; i > -1; --i) { + struct DRWPass *pass = psl->passes[i]; + if (pass) { + DRW_pass_free(pass); + MEM_freeN(pass); + psl->passes[i] = NULL; + } + } +} + void GPU_viewport_free(GPUViewport *viewport) { GPU_viewport_debug_depth_free(viewport); - MEM_freeN(viewport); + GPU_viewport_buffers_free(viewport); + GPU_viewport_passes_free(viewport); + + MEM_freeN(viewport->fbl); + MEM_freeN(viewport->txl); + MEM_freeN(viewport->psl); } /****************** debug ********************/ -- cgit v1.2.3