Fix T54329: brush texture preview not working.
authorSebastian Parborg <zeddb>
Thu, 6 Sep 2018 14:33:41 +0000 (16:33 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Thu, 6 Sep 2018 15:10:54 +0000 (17:10 +0200)
With the removal of blender internal, the texture preview had to be
rewritten. Now we evaluate and write the texture directly to the
preview buffer instead of going through the renderer.

Differential Revision: https://developer.blender.org/D3670

source/blender/editors/render/render_preview.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/source/pipeline.c

index 0059d782eaf51591b7c7d2af28281a45d5550fb1..7253f07fea4f601e87e6a051771a39c77681a899 100644 (file)
@@ -95,6 +95,7 @@
 
 #include "RE_pipeline.h"
 #include "RE_engine.h"
+#include "RE_shader_ext.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -727,6 +728,61 @@ static void shader_preview_updatejob(void *spv)
        }
 }
 
+/* Renders texture directly to render buffer. */
+static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene* sce, Render *re)
+{
+       /* Setup output buffer. */
+       int width = sp->sizex;
+       int height = sp->sizey;
+
+       /* This is needed otherwise no RenderResult is created. */
+       sce->r.scemode &= ~R_BUTS_PREVIEW;
+       RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, width, height, NULL);
+       RE_SetScene(re, sce);
+
+       /* Create buffer in empty RenderView created in the init step. */
+       RenderResult *rr = RE_AcquireResultWrite(re);
+       RenderView *rv = (RenderView *)rr->views.first;
+       rv->rectf = MEM_callocN(sizeof(float) * 4 * width * height, "texture render result");
+       RE_ReleaseResult(re);
+
+       /* Get texture image pool (if any) */
+       struct ImagePool *img_pool = BKE_image_pool_new();
+       BKE_texture_fetch_images_for_pool(tex, img_pool);
+
+       /* Fill in image buffer. */
+       float *rect_float = rv->rectf;
+       float tex_coord[3] = {0.0f, 0.0f, 0.0f};
+       bool color_manage = true;
+
+       for (int y = 0; y < height; y++) {
+               /* Tex coords between -1.0f and 1.0f. */
+               tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f;
+
+               for (int x = 0; x < width; x++) {
+                       tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f;
+
+                       /* Evaluate texture at tex_coord .*/
+                       TexResult texres = {0};
+                       BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage);
+
+                       rect_float[0] = texres.tr;
+                       rect_float[1] = texres.tg;
+                       rect_float[2] = texres.tb;
+                       rect_float[3] = 1.0f;
+
+                       rect_float += 4;
+               }
+
+               /* Check if we should cancel texture preview. */
+               if (shader_preview_break(sp)) {
+                       break;
+               }
+       }
+
+       BKE_image_pool_free(img_pool);
+}
+
 static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int first)
 {
        Render *re;
@@ -803,7 +859,13 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
                ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex;
 
        /* entire cycle for render engine */
-       RE_PreviewRender(re, pr_main, sce);
+       if (idtype == ID_TE) {
+               shader_preview_texture(sp, (Tex *)id, sce, re);
+       }
+       else {
+               /* Render preview scene */
+               RE_PreviewRender(re, pr_main, sce);
+       }
 
        ((Camera *)sce->camera->data)->lens = oldlens;
 
index cf52bb11d5903aa13fb65013c98be78ab334d047..84e6c9ddd55ea1be73deb2d580875bde9d973be7 100644 (file)
@@ -336,6 +336,7 @@ struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int pas
 void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]);
 void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]);
 struct Scene *RE_GetScene(struct Render *re);
+void RE_SetScene(struct Render *re, struct Scene *sce);
 
 bool RE_is_rendering_allowed(struct Scene *scene, struct ViewLayer *single_layer, struct Object *camera_override, struct ReportList *reports);
 
index b6fe518b90681fd70f25b2c1c644e2620be83a33..b9ebaa8c184c082fc5bb83b10f37af7945182c31 100644 (file)
@@ -364,6 +364,13 @@ Scene *RE_GetScene(Render *re)
        return NULL;
 }
 
+void RE_SetScene(Render *re, Scene* sce)
+{
+       if (re) {
+               re->scene = sce;
+       }
+}
+
 /**
  * Same as #RE_AcquireResultImage but creating the necessary views to store the result
  * fill provided result struct with a copy of thew views of what is done so far the