[Bf-blender-cvs] [6e040b045ab] blender2.8: GPU: add offscreen buffer drawing utility functions.

Brecht Van Lommel noreply at git.blender.org
Tue Feb 13 20:19:09 CET 2018


Commit: 6e040b045ab1d94a877ab6f72f431c9b64e1121c
Author: Brecht Van Lommel
Date:   Tue Feb 13 18:18:04 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB6e040b045ab1d94a877ab6f72f431c9b64e1121c

GPU: add offscreen buffer drawing utility functions.

===================================================================

M	source/blender/editors/render/render_opengl.c
M	source/blender/editors/screen/screen_draw.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/editors/space_view3d/view3d_draw_legacy.c
M	source/blender/gpu/GPU_framebuffer.h
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_framebuffer.c
M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/python/intern/gpu_offscreen.c

===================================================================

diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 6e969067985..8eb9283790b 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -652,7 +652,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
 	sizey = (scene->r.size * scene->r.ysch) / 100;
 
 	/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
-	ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out);
+	ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out);
 
 	if (!ofs) {
 		BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 2e4e9127ed6..6ea0a34c21d 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -499,7 +499,7 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
 void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect)
 {
 	char err_out[256] = "unknown";
-	GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, false, err_out);
+	GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out);
 
 	GPU_offscreen_bind(offscreen, true);
 	glClearColor(0.0, 0.0, 0.0, 0.0);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index f96dead513c..c3a42cc0cad 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1918,6 +1918,10 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
 	view3d_draw_view(C, ar);
 	GPU_viewport_unbind(rv3d->viewport);
 
+	rcti rect = ar->winrct;
+	BLI_rcti_translate(&rect, -ar->winrct.xmin, -ar->winrct.ymin);
+	GPU_viewport_draw_to_screen(rv3d->viewport, &rect);
+
 	v3d->flag |= V3D_INVALID_BACKBUF;
 }
 
@@ -2130,7 +2134,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
 
 	if (own_ofs) {
 		/* bind */
-		ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, false, err_out);
+		ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
 		if (ofs == NULL) {
 			return NULL;
 		}
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index aeb2cd11e39..1c6916d3820 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -286,7 +286,7 @@ static void backdrawview3d(
 		}
 
 		if (!rv3d->gpuoffscreen) {
-			rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, false, error);
+			rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, true, false, error);
 
 			if (!rv3d->gpuoffscreen)
 				fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index c58d98c201e..31f24aa7c2e 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -83,14 +83,16 @@ void GPU_framebuffer_recursive_downsample(
  * - wrapper around framebuffer and texture for simple offscreen drawing
  * - changes size if graphics card can't support it */
 
-GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256]);
+GPUOffScreen *GPU_offscreen_create(int width, int height, int samples,
+        bool depth, bool high_bitdepth, char err_out[256]);
 void GPU_offscreen_free(GPUOffScreen *ofs);
 void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
 void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
 void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y);
 int GPU_offscreen_width(const GPUOffScreen *ofs);
 int GPU_offscreen_height(const GPUOffScreen *ofs);
-int GPU_offscreen_color_texture(const GPUOffScreen *ofs);
+struct GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs);
 
 void GPU_offscreen_viewport_data_get(
         GPUOffScreen *ofs,
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 580ff64befb..dff7e278ae1 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -98,6 +98,7 @@ typedef struct ViewportEngineData_Info {
 GPUViewport *GPU_viewport_create(void);
 void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
 void GPU_viewport_unbind(GPUViewport *viewport);
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect);
 void GPU_viewport_free(GPUViewport *viewport);
 
 GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 7b1f5c80246..2c38319906c 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -641,7 +641,7 @@ struct GPUOffScreen {
 	GPUTexture *depth;
 };
 
-GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high_bitdepth, char err_out[256])
+GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool depth, bool high_bitdepth, char err_out[256])
 {
 	GPUOffScreen *ofs;
 
@@ -663,15 +663,17 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool high
 		}
 	}
 
-	ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out);
-	if (!ofs->depth) {
-		GPU_offscreen_free(ofs);
-		return NULL;
-	}
+	if (depth) {
+		ofs->depth = GPU_texture_create_depth_with_stencil_multisample(width, height, samples, err_out);
+		if (!ofs->depth) {
+			GPU_offscreen_free(ofs);
+			return NULL;
+		}
 
-	if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) {
-		GPU_offscreen_free(ofs);
-		return NULL;
+		if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, 0)) {
+			GPU_offscreen_free(ofs);
+			return NULL;
+		}
 	}
 
 	if (high_bitdepth) {
@@ -731,6 +733,24 @@ void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
 	glEnable(GL_SCISSOR_TEST);
 }
 
+void GPU_offscreen_blit(GPUOffScreen *ofs, int x, int y)
+{
+	const int w = GPU_texture_width(ofs->color);
+	const int h = GPU_texture_height(ofs->color);
+
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs->fb->object);
+	GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+
+	if (status == GL_FRAMEBUFFER_COMPLETE) {
+		glBlitFramebuffer(0, 0, w, h, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+	}
+	else {
+		gpu_print_framebuffer_error(status, NULL);
+	}
+
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+}
+
 void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
 {
 	const int w = GPU_texture_width(ofs->color);
@@ -818,9 +838,9 @@ int GPU_offscreen_height(const GPUOffScreen *ofs)
 	return GPU_texture_height(ofs->color);
 }
 
-int GPU_offscreen_color_texture(const GPUOffScreen *ofs)
+GPUTexture *GPU_offscreen_color_texture(const GPUOffScreen *ofs)
 {
-	return GPU_texture_opengl_bindcode(ofs->color);
+	return ofs->color;
 }
 
 /* only to be used by viewport code! */
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 3ef53b3a6c3..fc045805874 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -474,7 +474,7 @@ cleanup:
 	GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
 }
 
-static void draw_ofs_to_screen(GPUViewport *viewport)
+static void draw_ofs_to_screen(GPUViewport *viewport, const rcti *rect)
 {
 	DefaultTextureList *dtxl = viewport->txl;
 
@@ -483,6 +483,9 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
 	const float w = (float)GPU_texture_width(color);
 	const float h = (float)GPU_texture_height(color);
 
+	BLI_assert(w == BLI_rcti_size_x(rect) + 1);
+	BLI_assert(h == BLI_rcti_size_y(rect) + 1);
+
 	Gwn_VertFormat *format = immVertexFormat();
 	unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 	unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -495,16 +498,16 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
 	immBegin(GWN_PRIM_TRI_STRIP, 4);
 
 	immAttrib2f(texcoord, 0.0f, 0.0f);
-	immVertex2f(pos, 0.0f, 0.0f);
+	immVertex2f(pos, rect->xmin, rect->ymin);
 
 	immAttrib2f(texcoord, 1.0f, 0.0f);
-	immVertex2f(pos, w, 0.0f);
+	immVertex2f(pos, rect->xmin + w, rect->ymin);
 
 	immAttrib2f(texcoord, 0.0f, 1.0f);
-	immVertex2f(pos, 0.0f, h);
+	immVertex2f(pos, rect->xmin, rect->ymin + h);
 
 	immAttrib2f(texcoord, 1.0f, 1.0f);
-	immVertex2f(pos, w, h);
+	immVertex2f(pos, rect->xmin + w, rect->ymin + h);
 
 	immEnd();
 
@@ -523,9 +526,16 @@ void GPU_viewport_unbind(GPUViewport *viewport)
 
 		glEnable(GL_SCISSOR_TEST);
 		glDisable(GL_DEPTH_TEST);
+	}
+}
 
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+{
+	DefaultFramebufferList *dfbl = viewport->fbl;
+
+	if (dfbl->default_fb) {
 		/* This might be bandwidth limiting */
-		draw_ofs_to_screen(viewport);
+		draw_ofs_to_screen(viewport, rect);
 	}
 }
 
diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c
index 91d407d18a8..2da0227cdca 100644
--- a/source/blender/python/intern/gpu_offscreen.c
+++ b/source/blender/python/intern/gpu_offscreen.c
@@ -39,6 +39,7 @@
 
 #include "GPU_compositing.h"
 #include "GPU_framebuffer.h"
+#include "GPU_texture.h"
 
 #include "../mathutils/mathutils.h"
 
@@ -89,7 +90,8 @@ PyDoc_STRVAR(pygpu_offscreen_color_texture_doc, "Color texture.\n\n:type: int");
 static PyObject *pygpu_offscreen_color_texture_get(BPy_GPUOffScreen *self, void *UNUSED(type))
 {
 	BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
-	return PyLong_FromLong(GPU_offscreen_color_texture(self->ofs));
+	GPUTexture *texture = GPU_offscreen_color_texture(self->ofs);
+	return PyLong_FromLong(GPU_texture_opengl_bindcode(texture));
 }

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list