RenderEngine API: add viewport draw utility functions to bind a GLSL fragment
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 30 Aug 2013 23:49:35 +0000 (23:49 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 30 Aug 2013 23:49:35 +0000 (23:49 +0000)
shader for converting colors from linear to display space, based on the scene
color management settings.

if engine.support_display_space_shader(scene): # test graphics card support
engine.bind_display_space_shader(scene)
# draw pixels ..
engine.unbind_display_space_shader()

intern/opencolorio/fallback_impl.cc
intern/opencolorio/ocio_capi.cc
intern/opencolorio/ocio_capi.h
intern/opencolorio/ocio_impl.h
intern/opencolorio/ocio_impl_glsl.cc
source/blender/editors/render/render_internal.c
source/blender/editors/screen/glutil.c
source/blender/imbuf/IMB_colormanagement.h
source/blender/imbuf/intern/colormanagement.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_render.c

index 37f624e1f8b69ad38a27f2258560f7fb414a6a93..9d6561fb4cbf593e2ad83e1d352728e0326c124d 100644 (file)
@@ -381,6 +381,11 @@ void FallbackImpl::matrixTransformScale(float * , float * , const float *)
 {
 }
 
+bool FallbackImpl::supportGLSLDraw(void)
+{
+       return false;
+}
+
 bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide)
 {
        return false;
index c8db2c2b5310c97197dd609aebaa67a0e3bb6e38..49f8d2ca41e83ea4fb5269d947857b30941a8d35 100644 (file)
@@ -283,6 +283,11 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4
        impl->matrixTransformScale(m44, offset4, scale4f);
 }
 
+int OCIO_supportGLSLDraw(void)
+{
+       return (int) impl->supportGLSLDraw();
+}
+
 int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide)
 {
        return (int) impl->setupGLSLDraw(state_r, processor, (bool) predivide);
index 3632a0da1c65e5ff03a72a0156567f303533b552..0b3102a290dd8068f634df1b11c909bd954dab0a 100644 (file)
@@ -121,6 +121,7 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
 
 void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4);
 
+int OCIO_supportGLSLDraw(void);
 int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide);
 void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
 void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
index a328470ccb5e6dbc58532d8813e6936ff0be676e..a1e743bf2f61c083fc6f0b025574b961571f34e0 100644 (file)
@@ -96,6 +96,7 @@ public:
 
        virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
 
+       virtual bool supportGLSLDraw(void) = 0;
        virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide) = 0;
        virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
        virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
@@ -169,6 +170,7 @@ public:
 
        void matrixTransformScale(float * m44, float * offset4, const float * scale4);
 
+       bool supportGLSLDraw(void);
        bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
        void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
        void freeGLState(struct OCIO_GLSLDrawState *state_r);
@@ -243,6 +245,7 @@ public:
 
        void matrixTransformScale(float * m44, float * offset4, const float * scale4);
 
+       bool supportGLSLDraw(void);
        bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
        void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
        void freeGLState(struct OCIO_GLSLDrawState *state_r);
index 54be1e0f33994f3c249af046412330c1159d6f86..1a3132fa4b3de800e436c2c79466ac430063000c 100644 (file)
 #include <sstream>
 #include <string.h>
 
-#ifdef __APPLE__
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
-#else
 #include <GL/glew.h>
-#endif
 
 #include <OpenColorIO/OpenColorIO.h>
 
@@ -202,6 +197,13 @@ static bool ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
        return state->lut3d_texture_valid;
 }
 
+/* Detect if we can support GLSL drawing */
+bool OCIOImpl::supportGLSLDraw()
+{
+       /* GLSL and GL_RGB16F_ARB */
+       return GLEW_VERSION_2_0 && (GLEW_VERSION_3_0 || GLEW_ARB_texture_float);
+}
+
 /**
  * Setup OpenGL contexts for a transform defined by processor using GLSL
  * All LUT allocating baking and shader compilation happens here.
index d3818e1cac79be48e36ea4aea55160475df25228..b1978c001f35307b36c00f50e2d8cedebd712068 100644 (file)
@@ -1125,7 +1125,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
 
                /* Try using GLSL display transform. */
                if (force_fallback == false) {
-                       if (IMB_colormanagement_setup_glsl_draw(NULL, &scene->display_settings, TRUE)) {
+                       if (IMB_colormanagement_setup_glsl_draw(NULL, &scene->display_settings, TRUE, FALSE)) {
                                glEnable(GL_BLEND);
                                glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
                                glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT,
index 723dce5e22627ef882dbc3c7cefe4928626b5974..785c21481c51dc9276f287e03a07d31e099cf196 100644 (file)
@@ -1091,15 +1091,18 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
                if (ibuf->rect_float) {
                        if (ibuf->float_colorspace) {
                                ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
-                                                                                   ibuf->float_colorspace, TRUE);
+                                                                                   ibuf->float_colorspace,
+                                                                                   TRUE, FALSE);
                        }
                        else {
-                               ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, TRUE);
+                               ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings,
+                                                                        TRUE, FALSE);
                        }
                }
                else {
                        ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
-                                                                           ibuf->rect_colorspace, FALSE);
+                                                                           ibuf->rect_colorspace,
+                                                                           FALSE, FALSE);
                }
 
                if (ok) {
index 7399b8554aa779aaaf9c8118601294da7ef12128..3d2eab56d142dfd1566aa1af8f8acc0dfd544b31 100644 (file)
@@ -159,15 +159,20 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
 
 /* ** OpenGL drawing routines using GLSL for color space transform ** */
 
+/* Test if GLSL drawing is supported for combination of graphics card and this configuration */
+int IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings,
+                                          int skip_curves);
 /* Configures GLSL shader for conversion from scene linear to display space */
 int IMB_colormanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
                                         const struct ColorManagedDisplaySettings *display_settings,
-                                        int predivide);
+                                        int predivide,
+                                        int skip_curves);
 /* Same as above, but display space conversion happens from a specified space */
 int IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings,
                                                    const struct ColorManagedDisplaySettings *display_settings,
                                                    struct ColorSpace *colorspace,
-                                                   int predivide);
+                                                   int predivide,
+                                                   int skip_curves);
 /* Same as setup_glsl_draw, but color management settings are guessing from a given context */
 int IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, int predivide);
 /* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
index 0167eaccef0c3c21a4e137e943b5e403df2fd212..2c4863c359831470a8ba3e65370b6aac91b883d3 100644 (file)
@@ -2807,6 +2807,17 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
        }
 }
 
+int IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *view_settings,
+                                          int skip_curves)
+{
+       /* curves not supported yet */
+       if (!skip_curves)
+               if (view_settings && (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES))
+                       return 0;
+
+       return OCIO_supportGLSLDraw();
+}
+
 /**
  * Configures GLSL shader for conversion from specified to
  * display color space
@@ -2822,7 +2833,8 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
  */
 int IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings,
                                                    const ColorManagedDisplaySettings *display_settings,
-                                                   struct ColorSpace *from_colorspace, int predivide)
+                                                   struct ColorSpace *from_colorspace, int predivide,
+                                                   int skip_curves)
 {
        ColorManagedViewSettings default_view_settings;
        const ColorManagedViewSettings *applied_view_settings;
@@ -2840,8 +2852,9 @@ int IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSetting
        }
 
        /* RGB curves mapping is not supported on GPU yet. */
-       if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
-               return FALSE;
+       if (!skip_curves)
+               if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
+                       return FALSE;
 
        /* Make sure OCIO processor is up-to-date. */
        update_glsl_display_processor(applied_view_settings, display_settings,
@@ -2853,10 +2866,10 @@ int IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSetting
 /* Configures GLSL shader for conversion from scene linear to display space */
 int IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
                                         const ColorManagedDisplaySettings *display_settings,
-                                        int predivide)
+                                        int predivide, int skip_curves)
 {
        return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
-                                                             NULL, predivide);
+                                                             NULL, predivide, skip_curves);
 }
 
 /* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
@@ -2867,7 +2880,7 @@ int IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C,
 
        IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
 
-       return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide);
+       return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide, FALSE);
 }
 
 /* Same as setup_glsl_draw, but color management settings are guessing from a given context */
index ebd06475c79dad804d0b6cca930e6562918216c9..933f06cec8cce0574c84ac0056757346b3adb71f 100644 (file)
@@ -584,6 +584,7 @@ static void rna_ColorManagement_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
                return;
 
        if (GS(id->name) == ID_SCE) {
+               DAG_id_tag_update(id, 0);
                WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
        }
 }
index 82cdfcdd6312a22d0f0fb1e5376dde5521c49369..5b809a5170505109890745062dabff525321adc1 100644 (file)
@@ -49,6 +49,9 @@
 #include "BKE_context.h"
 #include "BKE_report.h"
 
+#include "IMB_colormanagement.h"
+#include "GPU_extensions.h"
+
 /* RenderEngine Callbacks */
 
 static void engine_tag_redraw(RenderEngine *engine)
@@ -61,6 +64,23 @@ static void engine_tag_update(RenderEngine *engine)
        engine->flag |= RE_ENGINE_DO_UPDATE;
 }
 
+static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
+{
+       return IMB_colormanagement_support_glsl_draw(&scene->view_settings, true);
+}
+
+static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
+{
+       IMB_colormanagement_setup_glsl_draw(&scene->view_settings,
+                                           &scene->display_settings,
+                                           false, true);
+}
+
+static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
+{
+       IMB_colormanagement_finish_glsl_draw();
+}
+
 static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
 {
        extern FunctionRNA rna_RenderEngine_update_func;
@@ -342,14 +362,15 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_RNAPTR);
 
        /* tag for redraw */
-       RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
+       func = RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
        RNA_def_function_ui_description(func, "Request redraw for viewport rendering");
 
        /* tag for update */
-       RNA_def_function(srna, "tag_update", "engine_tag_update");
+       func = RNA_def_function(srna, "tag_update", "engine_tag_update");
        RNA_def_function_ui_description(func, "Request update call for viewport rendering");
 
        func = RNA_def_function(srna, "begin_result", "RE_engine_begin_result");
+       RNA_def_function_ui_description(func, "Create render result to write linear floating point render layers and passes");
        prop = RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
        RNA_def_property_flag(prop, PROP_REQUIRED);
        prop = RNA_def_int(func, "y", 0, 0, INT_MAX, "Y", "", 0, INT_MAX);
@@ -363,39 +384,61 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_function_return(func, prop);
 
        func = RNA_def_function(srna, "update_result", "RE_engine_update_result");
+       RNA_def_function_ui_description(func, "Signal that pixels have been updated and can be redrawn in the user interface");
        prop = RNA_def_pointer(func, "result", "RenderResult", "Result", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
 
        func = RNA_def_function(srna, "end_result", "RE_engine_end_result");
+       RNA_def_function_ui_description(func, "All pixels in the render result have been set and are final");
        prop = RNA_def_pointer(func, "result", "RenderResult", "Result", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
        RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results");
 
        func = RNA_def_function(srna, "test_break", "RE_engine_test_break");
+       RNA_def_function_ui_description(func, "Test if the render operation should been cancelled, this is a fast call that should be used regularly for responsiveness");
        prop = RNA_def_boolean(func, "do_break", 0, "Break", "");
        RNA_def_function_return(func, prop);
 
        func = RNA_def_function(srna, "update_stats", "RE_engine_update_stats");
+       RNA_def_function_ui_description(func, "Update and signal to redraw render status text");
        prop = RNA_def_string(func, "stats", "", 0, "Stats", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
        prop = RNA_def_string(func, "info", "", 0, "Info", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
 
        func = RNA_def_function(srna, "update_progress", "RE_engine_update_progress");
+       RNA_def_function_ui_description(func, "Update progress percentage of render");
        prop = RNA_def_float(func, "progress", 0, 0.0f, 1.0f, "", "Percentage of render that's done", 0.0f, 1.0f);
        RNA_def_property_flag(prop, PROP_REQUIRED);
 
        func = RNA_def_function(srna, "update_memory_stats", "RE_engine_update_memory_stats");
+       RNA_def_function_ui_description(func, "Update memory usage statistics");
        RNA_def_float(func, "memory_used", 0, 0.0f, FLT_MAX, "", "Current memory usage in megabytes", 0.0f, FLT_MAX);
        RNA_def_float(func, "memory_peak", 0, 0.0f, FLT_MAX, "", "Peak memory usage in megabytes", 0.0f, FLT_MAX);
        RNA_def_property_flag(prop, PROP_REQUIRED);
 
        func = RNA_def_function(srna, "report", "RE_engine_report");
+       RNA_def_function_ui_description(func, "Report info, warning or error messages");
        prop = RNA_def_enum_flag(func, "type", wm_report_items, 0, "Type", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
        prop = RNA_def_string(func, "message", "", 0, "Report Message", "");
        RNA_def_property_flag(prop, PROP_REQUIRED);
 
+       func = RNA_def_function(srna, "bind_display_space_shader", "engine_bind_display_space_shader");
+       RNA_def_function_ui_description(func, "Bind GLSL fragment shader that converts linear colors to display space colors using scene color management settings");
+       prop = RNA_def_pointer(func, "scene", "Scene", "", "");
+       RNA_def_property_flag(prop, PROP_REQUIRED);
+
+       func = RNA_def_function(srna, "unbind_display_space_shader", "engine_unbind_display_space_shader");
+       RNA_def_function_ui_description(func, "Unbind GLSL display space shader, must always be called after binding the shader");
+
+       func = RNA_def_function(srna, "support_display_space_shader", "engine_support_display_space_shader");
+       RNA_def_function_ui_description(func, "Test if GLSL display space shader is supported for the combination of graphics card and scene settings");
+       prop = RNA_def_pointer(func, "scene", "Scene", "", "");
+       RNA_def_property_flag(prop, PROP_REQUIRED);
+       prop = RNA_def_boolean(func, "supported", 0, "Supported", "");
+       RNA_def_function_return(func, prop);
+
        RNA_define_verify_sdna(0);
 
        prop = RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE);