RenderEngine API: add viewport draw utility functions to bind a GLSL fragment

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()
This commit is contained in:
Brecht Van Lommel 2013-08-30 23:49:35 +00:00
parent 6785874e7a
commit 60ff60dcdc
11 changed files with 100 additions and 19 deletions

@ -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;

@ -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);

@ -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);

@ -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);

@ -36,12 +36,7 @@
#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.

@ -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,

@ -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) {

@ -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 */

@ -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 */

@ -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);
}
}

@ -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);