1
1

Compare commits

...

43 Commits

Author SHA1 Message Date
30f65b54a7 Merge branch 'master' into draw-colormanagement 2020-02-11 14:57:41 +01:00
9052c6fafa Fix crash when selecting in edit mode with eevee 2020-02-11 14:52:42 +01:00
a01e7d62c5 Style: Rename processor arguments in C api and glsl impl. 2020-02-11 14:52:09 +01:00
a9ad4c805e Add comment about UI color space 2020-02-11 13:21:31 +01:00
0db60af623 - Address reviewers comments 2020-02-11 01:49:06 +01:00
c7b319279e Merge branch 'master' into draw-colormanagement
# Conflicts:
#	source/blender/draw/engines/overlay/overlay_armature.c
2020-02-07 02:05:45 +01:00
863632e7e2 OCIO: Style fixes 2020-02-07 02:03:15 +01:00
61d66b528e Cleanup: Update comments & fix some style issues 2020-02-05 00:25:32 +01:00
c0675868a3 Overlay: Fix edit text overlay invert logic op not working
The result is still different as the inversion is done in scene refered
linear and not in sRGB space as it used to be.
2020-01-31 23:58:49 +01:00
f9914a8ef9 Overlay: Armature: Fix look regression because of linear space rendering
If rendering using linear color the blending of color is different.
So we compensate by using non linear mix of the color inside the shader and
modify color mixing on the cpu.
2020-01-31 19:40:56 +01:00
fe327c0970 Overlay: Put all colors inside draw_common.c for correct colormanagment.
The only exception is for text drawing where the color needs to be sRGB
bytes. This could be fixed in the future.

There are only two hardcoded values remaining but are rather not important:
- object center transform gizmo darkening.
- particle display default color.
2020-01-31 18:59:32 +01:00
691c6f94bb Cleanup: Workbench: Remove background code
We now use clear color to apply background color in render mode.
2020-01-31 04:21:56 +01:00
a7ac3a3ee3 Overlay: Support viewport background modes
Port code from Workbench.
2020-01-31 04:19:33 +01:00
711c4bba54 Cleanup: DRW: Remove unused code and redundant state changes 2020-01-31 04:18:28 +01:00
a3ee3b8f24 Overlay: Move Alt+B clipping bounds display from workbench to overlay 2020-01-29 04:10:55 +01:00
66e1ca26f0 Cleanup: OCIO: Remove immVertexFormat in GLSL implementation
This was only needed for cycles/external engines.
2020-01-28 02:25:52 +01:00
b180c8b847 Render API: Make external engine render in linear space for the viewport
This just replace the OCIO shader by a simple image shader without
color transformation.
2020-01-28 02:18:08 +01:00
089b55885c OCIO: Use GroupTransform to avoid doing 3 transforms instead of 2
This exposes OCIO::GroupTransform to C api to be able to chain the
display transform with a corrective transform to output display linear
colors.

For now the display code only use an exponent transform to go back to
linear but should use a ColorSpaceTransform once we have the correct
config.
2020-01-28 00:23:34 +01:00
5cab93d89f DRW: Remove drw_engines_draw_overlays routine
It makes no sense to have it separate now.
2020-01-27 01:28:41 +01:00
8de055452d Overlays: Fix wireframe shading not working 2020-01-27 01:24:58 +01:00
da240defef Overlay: Don't always allocate the antialiasing buffer and draw background...
...in the main overlay buffer.

This is required if we do caching in the future.
2020-01-26 21:36:46 +01:00
bef1c0d11e DRW: ColorManagement: Fix ghosting with cycles. 2020-01-26 21:08:30 +01:00
be68e89948 DRW: ColorManagement: Fix viewport render pipeline
The final output needs to be merged in another buffer. So we still use
the offscreen buffer for that.
2020-01-26 20:45:52 +01:00
5db185d1c4 GPUViewport: Fix image uv editor. 2020-01-26 17:33:19 +01:00
2616a0a9d6 GPUViewport: Add fallback colormanagment
Just assume sRGB display and no color correction.
2020-01-26 17:32:53 +01:00
adf98e6360 DRW: Move color management to the GPUViewport
This moves the colormanagement step at the blitting step of the viewport.
This means the overlay (including gizmos) must all be rendered in a
separate buffer (meaning they are more or less properly color managed).

The draw manager sets the display transform to apply to the GPUViewport.
2020-01-26 17:09:27 +01:00
419a818eec OCIO: Support overlay blending in linear colorspace in GLSL backend
This add the possibility for the caller to add an extra color texture
to composite on top of the main texture. The compositing is done in post
viewtransform linear space.

However, this means the caller needs to pass the proper color processor
to undo and apply the display transform.
2020-01-26 17:03:25 +01:00
281fb48440 DRW: Color Management: Rework code to accept new color transform needed 2020-01-25 01:11:04 +01:00
e18f0a4cfb Overlay: Add other background types (checker and gradient) 2020-01-24 19:24:04 +01:00
e9411b8ccf Overlay: Cleanup Image background implementation
The background images are now rendered normally on a cleared
canvas. They then get masked by the render when the background
is drawn with a special blend mode.
2020-01-24 18:08:20 +01:00
05dda64cf2 DRW: Color Management: Do some rearangement of the draw code
This puts the color management functions inside one file.

We group all post transform drawing into DRW_draw_callbacks_post_scene.
2020-01-24 16:23:51 +01:00
a25bb245e9 Overlay: Fix background covering the outline 2020-01-24 16:21:56 +01:00
34fd04f3b9 OCIO: Fix curve cache preventing curvemapping update 2020-01-23 01:57:37 +01:00
7d25c74615 DRW: Remove DrawEngineType draw_background function
This moves all background duties to the overlay engine which does alpha
under drawing (sort of).

This means keeping transparency info through the whole pipeline.

For now I just updated workbench which surely still need some cleanups.

Only Solid background is reimplemented.
2020-01-23 00:16:40 +01:00
a6bfab516e OCIO: Add back IMM hack
This is needed to avoid crash in some circumstances.
2020-01-23 00:01:44 +01:00
af37c863eb Cleanup: EEVEE: Remove alpha checker drawing
This will be ported to the overlay engine.
2020-01-22 19:36:34 +01:00
45dc1139e8 DRW: Move Color-Management handling to draw manager
This is first part of the color managmeent refactor.

The drawing of the overlays is done in a sRGB texture to retain some bits
of accuracy.

The transform is applied after the overlays blending for now.

There is much left to be done.
2020-01-22 19:36:34 +01:00
a23f7a85ca Cleanup: EEVEE: Move debug draw to eevee_renderpass.c 2020-01-22 19:36:34 +01:00
73f612fa3b GPU: Add sRGB framebuffer support
Only enable GL_FRAMEBUFFER_SRGB on framebuffer objects as the main
framebuffer is likely to be srgb, and as of now we don't use linear
color for area texture.
2020-01-22 19:36:34 +01:00
986ff34d1e GPUViewport: Cleanup and use always use RGBA16F 2020-01-22 19:36:34 +01:00
e00455381f Cleanup: OpenColorIO: Remove state tracking
Theses are useless. Better assume the state is has been changed.
2020-01-22 19:36:34 +01:00
fa010dddda DRW: Use Batch API instead of IMM for color managment
A little cleanup that should avoid some state changes and pipeline stall.
2020-01-22 19:36:34 +01:00
a0283355fc OpenColorIO: Improve/Cleanup Implementation
This split the shader cache into caches for Shader, Lut and CurveMapping.

This way we can have smoother updates when tweaking/animating the color
managment (i.e. exposure and gamma should only recompile the shader).

The curvemapping, predivide and dither options are no longer compile time
optimized but use uniforms. I did not measure any performance difference.
2020-01-22 19:36:34 +01:00
78 changed files with 2048 additions and 1727 deletions

View File

@@ -594,6 +594,43 @@ void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
MEM_freeN(id);
}
OCIO_GroupTransformRcPtr *FallbackImpl::createGroupTransform(void)
{
FallbackTransform *transform = new FallbackTransform();
transform->type = TRANSFORM_UNKNOWN;
return (OCIO_GroupTransformRcPtr *)transform;
}
void FallbackImpl::groupTransformSetDirection(OCIO_GroupTransformRcPtr * /*gt*/,
const bool /*forward */)
{
}
void FallbackImpl::groupTransformPushBack(OCIO_GroupTransformRcPtr * /*gt*/,
OCIO_ConstTransformRcPtr * /*transform*/)
{
}
void FallbackImpl::groupTransformRelease(OCIO_GroupTransformRcPtr * /*gt*/)
{
}
OCIO_ColorSpaceTransformRcPtr *FallbackImpl::createColorSpaceTransform(void)
{
FallbackTransform *transform = new FallbackTransform();
transform->type = TRANSFORM_UNKNOWN;
return (OCIO_ColorSpaceTransformRcPtr *)transform;
}
void FallbackImpl::colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr * /*ct*/,
const char * /*name*/)
{
}
void FallbackImpl::colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr * /*ct*/)
{
}
OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void)
{
FallbackTransform *transform = new FallbackTransform();
@@ -658,10 +695,12 @@ bool FallbackImpl::supportGLSLDraw(void)
}
bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
OCIO_ConstProcessorRcPtr * /*processor*/,
OCIO_ConstProcessorRcPtr * /*ocio_processor_scene_to_ui*/,
OCIO_ConstProcessorRcPtr * /*ocio_processor_ui_to_display*/,
OCIO_CurveMappingSettings * /*curve_mapping_settings*/,
float /*dither*/,
bool /*predivide*/)
bool /*predivide*/,
bool /*overlay*/)
{
return false;
}

View File

@@ -1,70 +1,68 @@
uniform sampler2D image_texture;
uniform sampler3D lut3d_texture;
/* Blender OpenColorIO implementation */
#ifdef USE_DITHER
uniform float dither;
#endif
in vec2 texCoord_interp;
out vec4 fragColor;
#ifdef USE_CURVE_MAPPING
/* Curve mapping parameters
*
* See documentation for OCIO_CurveMappingSettings to get fields descriptions.
* (this ones pretyt much copies stuff from C structure.)
*/
uniform sampler1D curve_mapping_texture;
uniform int curve_mapping_lut_size;
uniform int use_curve_mapping_extend_extrapolate;
uniform vec4 curve_mapping_mintable;
uniform vec4 curve_mapping_range;
uniform vec4 curve_mapping_ext_in_x;
uniform vec4 curve_mapping_ext_in_y;
uniform vec4 curve_mapping_ext_out_x;
uniform vec4 curve_mapping_ext_out_y;
uniform vec4 curve_mapping_first_x;
uniform vec4 curve_mapping_first_y;
uniform vec4 curve_mapping_last_x;
uniform vec4 curve_mapping_last_y;
uniform vec3 curve_mapping_black;
uniform vec3 curve_mapping_bwmul;
uniform sampler2D image_texture;
uniform sampler2D overlay_texture;
uniform sampler3D lut3d_texture;
uniform sampler3D lut3d_display_texture;
uniform float dither;
uniform bool predivide;
uniform bool curve_mapping;
uniform bool overlay;
layout(std140) uniform OCIO_GLSLCurveMappingParameters
{
/* Curve mapping parameters
*
* See documentation for OCIO_CurveMappingSettings to get fields descriptions.
* (this ones pretty much copies stuff from C structure.)
*/
vec4 curve_mapping_mintable;
vec4 curve_mapping_range;
vec4 curve_mapping_ext_in_x;
vec4 curve_mapping_ext_in_y;
vec4 curve_mapping_ext_out_x;
vec4 curve_mapping_ext_out_y;
vec4 curve_mapping_first_x;
vec4 curve_mapping_first_y;
vec4 curve_mapping_last_x;
vec4 curve_mapping_last_y;
vec4 curve_mapping_black;
vec4 curve_mapping_bwmul;
int curve_mapping_lut_size;
int curve_mapping_use_extend_extrapolate;
};
float read_curve_mapping(int table, int index)
{
/* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
* But is it actually correct to subtract 1 here?
*/
float texture_index = float(index) / float(curve_mapping_lut_size - 1);
return texture(curve_mapping_texture, texture_index)[table];
return texelFetch(curve_mapping_texture, index, 0)[table];
}
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
{
if (x <= first[0]) {
if (use_curve_mapping_extend_extrapolate == 0) {
if (curve_mapping_use_extend_extrapolate == 0) {
/* horizontal extrapolation */
return first[1];
}
else {
if (curve_mapping_ext_in_x[table] == 0.0)
return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
else
return first[1] +
curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
float fac = (curve_mapping_ext_in_x[table] != 0.0) ?
((x - first[0]) / curve_mapping_ext_in_x[table]) :
10000.0;
return first[1] + curve_mapping_ext_in_y[table] * fac;
}
}
else if (x >= last[0]) {
if (use_curve_mapping_extend_extrapolate == 0) {
if (curve_mapping_use_extend_extrapolate == 0) {
/* horizontal extrapolation */
return last[1];
}
else {
if (curve_mapping_ext_out_x[table] == 0.0)
return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
else
return last[1] +
curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
float fac = (curve_mapping_ext_out_x[table] != 0.0) ?
((x - last[0]) / curve_mapping_ext_out_x[table]) :
-10000.0;
return last[1] + curve_mapping_ext_out_y[table] * fac;
}
}
return 0.0;
@@ -92,80 +90,91 @@ float curvemap_evaluateF(int table, float value)
vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
}
else {
if (i < 0)
if (i < 0) {
return read_curve_mapping(table, 0);
if (i >= CM_TABLE)
}
if (i >= CM_TABLE) {
return read_curve_mapping(table, CM_TABLE);
}
fi = fi - float(i);
return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
float cm1 = read_curve_mapping(table, i);
float cm2 = read_curve_mapping(table, i + 1);
return mix(cm1, cm2, fi);
}
}
vec4 curvemapping_evaluate_premulRGBF(vec4 col)
{
vec4 result = col;
result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
result[3] = col[3];
col.rgb = (col.rgb - curve_mapping_black.rgb) * curve_mapping_bwmul.rgb;
vec4 result;
result.r = curvemap_evaluateF(0, col.r);
result.g = curvemap_evaluateF(1, col.g);
result.b = curvemap_evaluateF(2, col.b);
result.a = col.a;
return result;
}
#endif
#ifdef USE_DITHER
float dither_random_value(vec2 co)
{
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
}
vec2 round_to_pixel(vec2 st)
vec2 round_to_pixel(sampler2D tex, vec2 uv)
{
vec2 result;
vec2 size = textureSize(image_texture, 0);
result.x = float(int(st.x * size.x)) / size.x;
result.y = float(int(st.y * size.y)) / size.y;
return result;
vec2 size = textureSize(tex, 0);
return vec2(ivec2(uv * size)) / size;
}
vec4 apply_dither(vec2 st, vec4 col)
vec4 apply_dither(vec4 col, vec2 uv)
{
vec4 result;
float random_value = dither_random_value(round_to_pixel(st));
result.r = col.r + random_value;
result.g = col.g + random_value;
result.b = col.b + random_value;
result.a = col.a;
return result;
col.rgb += dither_random_value(uv);
return col;
}
#endif
void main()
vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv)
{
vec4 col = texture(image_texture, texCoord_interp.st);
#ifdef USE_CURVE_MAPPING
col = curvemapping_evaluate_premulRGBF(col);
#endif
#ifdef USE_PREDIVIDE
if (col[3] > 0.0 && col[3] < 1.0) {
float inv_alpha = 1.0 / col[3];
col[0] *= inv_alpha;
col[1] *= inv_alpha;
col[2] *= inv_alpha;
if (curve_mapping) {
col = curvemapping_evaluate_premulRGBF(col);
}
if (predivide) {
if (col.a > 0.0 && col.a < 1.0) {
col.rgb *= 1.0 / col.a;
}
}
#endif
/* NOTE: This is true we only do de-premul here and NO premul
* and the reason is simple -- opengl is always configured
* for straight alpha at this moment
*/
vec4 result = OCIODisplay(col, lut3d_texture);
col = OCIO_to_display_linear_with_look(col, lut3d_texture);
#ifdef USE_DITHER
result = apply_dither(texCoord_interp.st, result);
#endif
if (dither > 0.0) {
col = apply_dither(col, noise_uv);
}
fragColor = result;
if (overlay) {
col *= 1.0 - col_overlay.a;
col += col_overlay; /* Assumed unassociated alpha. */
}
col = OCIO_to_display_encoded(col, lut3d_display_texture);
return col;
}
/* ------------------------------------------------------------------------ */
in vec2 texCoord_interp;
out vec4 fragColor;
void main()
{
vec4 col = texture(image_texture, texCoord_interp.st);
vec4 col_overlay = texture(overlay_texture, texCoord_interp.st);
vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st);
fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv);
}

View File

@@ -307,6 +307,41 @@ void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
impl->OCIO_PackedImageDescRelease(id);
}
OCIO_GroupTransformRcPtr *OCIO_createGroupTransform(void)
{
return impl->createGroupTransform();
}
void OCIO_groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward)
{
impl->groupTransformSetDirection(gt, forward);
}
void OCIO_groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr)
{
impl->groupTransformPushBack(gt, tr);
}
void OCIO_groupTransformRelease(OCIO_GroupTransformRcPtr *gt)
{
impl->groupTransformRelease(gt);
}
OCIO_ColorSpaceTransformRcPtr *OCIO_createColorSpaceTransform(void)
{
return impl->createColorSpaceTransform();
}
void OCIO_colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name)
{
impl->colorSpaceTransformSetSrc(ct, name);
}
void OCIO_colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct)
{
impl->colorSpaceTransformRelease(ct);
}
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void)
{
return impl->createExponentTransform();
@@ -350,12 +385,20 @@ int OCIO_supportGLSLDraw(void)
}
int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
OCIO_ConstProcessorRcPtr *processor,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool predivide)
bool predivide,
bool overlay)
{
return (int)impl->setupGLSLDraw(state_r, processor, curve_mapping_settings, dither, predivide);
return (int)impl->setupGLSLDraw(state_r,
ocio_processor_scene_to_ui,
ocio_processor_ui_to_display,
curve_mapping_settings,
dither,
predivide,
overlay);
}
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)

View File

@@ -46,8 +46,10 @@ OCIO_DECLARE_HANDLE(OCIO_ConstContextRcPtr);
OCIO_DECLARE_HANDLE(OCIO_PackedImageDesc);
OCIO_DECLARE_HANDLE(OCIO_DisplayTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ColorSpaceTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ExponentTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_GroupTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstLookRcPtr);
/* Standard XYZ to linear sRGB transform, for fallback. */
@@ -198,6 +200,15 @@ OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_GroupTransformRcPtr *OCIO_createGroupTransform(void);
void OCIO_groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
void OCIO_groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr);
void OCIO_groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
OCIO_ColorSpaceTransformRcPtr *OCIO_createColorSpaceTransform(void);
void OCIO_colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
void OCIO_colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void);
void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
@@ -212,10 +223,12 @@ 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,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool predivide);
bool predivide,
bool overlay);
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);

View File

@@ -822,6 +822,51 @@ void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
OBJECT_GUARDED_DELETE((PackedImageDesc *)id, PackedImageDesc);
}
OCIO_GroupTransformRcPtr *OCIOImpl::createGroupTransform(void)
{
GroupTransformRcPtr *gt = OBJECT_GUARDED_NEW(GroupTransformRcPtr);
*gt = GroupTransform::Create();
return (OCIO_GroupTransformRcPtr *)gt;
}
void OCIOImpl::groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward)
{
TransformDirection dir = forward ? TRANSFORM_DIR_FORWARD : TRANSFORM_DIR_INVERSE;
(*(GroupTransformRcPtr *)gt)->setDirection(dir);
}
void OCIOImpl::groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr)
{
(*(GroupTransformRcPtr *)gt)->push_back(*(ConstTransformRcPtr *)tr);
}
void OCIOImpl::groupTransformRelease(OCIO_GroupTransformRcPtr *gt)
{
OBJECT_GUARDED_DELETE((GroupTransformRcPtr *)gt, GroupTransformRcPtr);
}
OCIO_ColorSpaceTransformRcPtr *OCIOImpl::createColorSpaceTransform(void)
{
ColorSpaceTransformRcPtr *ct = OBJECT_GUARDED_NEW(ColorSpaceTransformRcPtr);
*ct = ColorSpaceTransform::Create();
(*ct)->setDirection(TRANSFORM_DIR_FORWARD);
return (OCIO_ColorSpaceTransformRcPtr *)ct;
}
void OCIOImpl::colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name)
{
(*(ColorSpaceTransformRcPtr *)ct)->setSrc(name);
}
void OCIOImpl::colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct)
{
OBJECT_GUARDED_DELETE((ColorSpaceTransformRcPtr *)ct, ColorSpaceTransformRcPtr);
}
OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void)
{
ExponentTransformRcPtr *et = OBJECT_GUARDED_NEW(ExponentTransformRcPtr);

View File

@@ -117,6 +117,16 @@ class IOCIOImpl {
virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0;
virtual OCIO_GroupTransformRcPtr *createGroupTransform(void) = 0;
virtual void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward) = 0;
virtual void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt,
OCIO_ConstTransformRcPtr *transform) = 0;
virtual void groupTransformRelease(OCIO_GroupTransformRcPtr *gt) = 0;
virtual OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void) = 0;
virtual void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name) = 0;
virtual void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct) = 0;
virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0;
virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
const float *exponent) = 0;
@@ -132,10 +142,12 @@ class IOCIOImpl {
virtual bool supportGLSLDraw(void) = 0;
virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
OCIO_ConstProcessorRcPtr *processor,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool predivide) = 0;
bool predivide,
bool overlay) = 0;
virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
@@ -229,6 +241,15 @@ class FallbackImpl : public IOCIOImpl {
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_GroupTransformRcPtr *createGroupTransform(void);
void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *transform);
void groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void);
void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
OCIO_ExponentTransformRcPtr *createExponentTransform(void);
void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
@@ -243,10 +264,12 @@ class FallbackImpl : public IOCIOImpl {
bool supportGLSLDraw(void);
bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
OCIO_ConstProcessorRcPtr *processor,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool predivide);
bool predivide,
bool overlay);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);
@@ -339,6 +362,15 @@ class OCIOImpl : public IOCIOImpl {
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
OCIO_GroupTransformRcPtr *createGroupTransform(void);
void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *transform);
void groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void);
void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
OCIO_ExponentTransformRcPtr *createExponentTransform(void);
void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
@@ -353,10 +385,12 @@ class OCIOImpl : public IOCIOImpl {
bool supportGLSLDraw(void);
bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
OCIO_ConstProcessorRcPtr *processor,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool predivide);
bool predivide,
bool overlay);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);

View File

@@ -56,62 +56,108 @@ using namespace OCIO_NAMESPACE;
#include "ocio_impl.h"
static const int LUT3D_EDGE_SIZE = 64;
static const int LUT3D_TEXTURE_SIZE = sizeof(float) * 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE *
LUT3D_EDGE_SIZE;
static const int SHADER_CACHE_SIZE = 4;
#define UBO_BIND_LOC 0
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
typedef struct OCIO_GLSLShader {
/* Cache ID */
std::string lut3dCacheID;
std::string shaderCacheID;
/* Curve mapping parameters
*
* See documentation for OCIO_CurveMappingSettings to get fields descriptions.
* (this ones pretty much copies stuff from C structure.)
*/
struct OCIO_GLSLCurveMappingParameters {
float curve_mapping_mintable[4];
float curve_mapping_range[4];
float curve_mapping_ext_in_x[4];
float curve_mapping_ext_in_y[4];
float curve_mapping_ext_out_x[4];
float curve_mapping_ext_out_y[4];
float curve_mapping_first_x[4];
float curve_mapping_first_y[4];
float curve_mapping_last_x[4];
float curve_mapping_last_y[4];
float curve_mapping_black[4];
float curve_mapping_bwmul[4];
int curve_mapping_lut_size;
int curve_mapping_use_extend_extrapolate;
int _pad[2];
/** WARNING: Needs to be 16byte aligned. Used as UBO data. */
};
/* LUT */
bool lut3d_texture_allocated; /* boolean flag indicating whether
* lut texture is allocated
*/
bool lut3d_texture_valid;
GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
float *lut3d; /* 3D LUT table */
/* Dither */
bool use_dither;
/* Curve Mapping */
bool use_curve_mapping;
bool curve_mapping_texture_allocated;
bool curve_mapping_texture_valid;
GLuint curve_mapping_texture;
size_t curve_mapping_cache_id;
/* Alpha Predivide */
bool use_predivide;
/* GLSL stuff */
GLuint ocio_shader;
GLuint vert_shader;
struct OCIO_GLSLShader {
/** Cache IDs */
std::string cacheId;
/** TODO(fclem): Remove. IMM shader interface. */
struct GPUShaderInterface *interface;
/** OpenGL Shader objects handles. */
GLuint frag;
GLuint vert;
GLuint program;
GPUShaderInterface *shader_interface;
} GLSLDrawState;
/** Uniform locations. */
GLint dither_loc;
GLint overlay_loc;
GLint overlay_tex_loc;
GLint predivide_loc;
GLint curve_mapping_loc;
/** Error checking. */
bool valid;
};
typedef struct OCIO_GLSLDrawState {
struct OCIO_GLSLLut3d {
/** Cache IDs */
std::string cacheId;
/** OpenGL Texture handles. 0 if not allocated. */
GLuint texture;
GLuint texture_display;
/** Error checking. */
bool valid;
};
struct OCIO_GLSLCurveMappping {
/** Cache IDs */
size_t cacheId;
/** OpenGL Uniform Buffer handle. 0 if not allocated. */
GLuint buffer;
/** OpenGL Texture handles. 0 if not allocated. */
GLuint texture;
/** Error checking. */
bool valid;
};
struct OCIO_GLSLCacheHandle {
size_t cache_id;
void *data;
};
struct OCIO_GLSLDrawState {
/* Shader Cache */
OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE];
OCIO_GLSLCacheHandle shader_cache[SHADER_CACHE_SIZE];
OCIO_GLSLCacheHandle lut3d_cache[SHADER_CACHE_SIZE];
OCIO_GLSLCacheHandle curvemap_cache[SHADER_CACHE_SIZE];
};
/* Previous OpenGL state. */
GLint last_texture, last_texture_unit;
} OCIO_GLSLDrawState;
static OCIO_GLSLDrawState *allocateOpenGLState(void)
{
return (OCIO_GLSLDrawState *)MEM_callocN(sizeof(OCIO_GLSLDrawState), "OCIO OpenGL State struct");
}
static GLuint compileShaderText(GLenum shaderType, const char *text)
/* -------------------------------------------------------------------- */
/** \name Shader
* \{ */
static GLuint compileShaderText(GLenum shader_type, const char *text)
{
GLuint shader;
GLint stat;
shader = glCreateShader(shaderType);
shader = glCreateShader(shader_type);
glShaderSource(shader, 1, (const GLchar **)&text, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
@@ -127,15 +173,16 @@ static GLuint compileShaderText(GLenum shaderType, const char *text)
return shader;
}
static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader)
static GLuint linkShaders(GLuint frag, GLuint vert)
{
if (!ocio_shader || !vert_shader)
if (!frag || !vert) {
return 0;
}
GLuint program = glCreateProgram();
glAttachShader(program, ocio_shader);
glAttachShader(program, vert_shader);
glAttachShader(program, frag);
glAttachShader(program, vert);
glLinkProgram(program);
@@ -155,133 +202,379 @@ static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader)
return program;
}
static OCIO_GLSLDrawState *allocateOpenGLState(void)
static void updateGLSLShader(OCIO_GLSLShader *shader,
ConstProcessorRcPtr *processor_scene_to_ui,
ConstProcessorRcPtr *processpr_ui_to_display,
GpuShaderDesc *shader_desc,
const std::string &cache_id)
{
return (OCIO_GLSLDrawState *)MEM_callocN(sizeof(OCIO_GLSLDrawState), "OCIO OpenGL State struct");
}
/* Ensure LUT texture and array are allocated */
static bool ensureLUT3DAllocated(OCIO_GLSLShader *shader)
{
int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
if (shader->lut3d_texture_allocated)
return shader->lut3d_texture_valid;
glGenTextures(1, &shader->lut3d_texture);
shader->lut3d = (float *)MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
/* clean glError buffer */
while (glGetError() != GL_NO_ERROR) {
if (shader->cacheId == cache_id) {
return;
}
glTexImage3D(GL_TEXTURE_3D,
0,
GL_RGB16F_ARB,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
0,
GL_RGB,
GL_FLOAT,
shader->lut3d);
/* Delete any previous shader. */
glDeleteProgram(shader->program);
glDeleteShader(shader->frag);
glDeleteShader(shader->vert);
shader->lut3d_texture_allocated = true;
if (shader->interface) {
GPU_shaderinterface_discard(shader->interface);
}
/* GL_RGB16F_ARB could be not supported at some drivers
* in this case we could not use GLSL display
*/
shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR;
{
/* Vertex shader */
std::ostringstream osv;
return shader->lut3d_texture_valid;
osv << "#version 330\n";
osv << datatoc_gpu_shader_display_transform_vertex_glsl;
shader->vert = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
}
{
/* Fragment shader */
std::ostringstream os;
os << "#version 330\n";
/* Work around OpenColorIO not supporting latest GLSL yet. */
os << "#define texture2D texture\n";
os << "#define texture3D texture\n";
shader_desc->setFunctionName("OCIO_to_display_linear_with_look");
os << (*processor_scene_to_ui)->getGpuShaderText(*shader_desc) << "\n";
shader_desc->setFunctionName("OCIO_to_display_encoded");
os << (*processpr_ui_to_display)->getGpuShaderText(*shader_desc) << "\n";
os << datatoc_gpu_shader_display_transform_glsl;
shader->frag = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
}
/* shader_Program */
if (shader->frag && shader->vert) {
shader->program = linkShaders(shader->frag, shader->vert);
}
if (shader->program) {
shader->dither_loc = glGetUniformLocation(shader->program, "dither");
shader->overlay_tex_loc = glGetUniformLocation(shader->program, "overlay_texture");
shader->overlay_loc = glGetUniformLocation(shader->program, "overlay");
shader->predivide_loc = glGetUniformLocation(shader->program, "predivide");
shader->curve_mapping_loc = glGetUniformLocation(shader->program, "curve_mapping");
glUseProgram(shader->program);
/* Set texture bind point uniform once. This is saved by the shader. */
glUniform1i(glGetUniformLocation(shader->program, "image_texture"), 0);
glUniform1i(glGetUniformLocation(shader->program, "lut3d_texture"), 2);
glUniform1i(glGetUniformLocation(shader->program, "lut3d_display_texture"), 3);
glUniform1i(glGetUniformLocation(shader->program, "curve_mapping_texture"), 4);
/* Set UBO binding location. */
GLuint index = glGetUniformBlockIndex(shader->program, "OCIO_GLSLCurveMappingParameters");
glUniformBlockBinding(shader->program, index, UBO_BIND_LOC);
/* TODO(fclem) Remove this. Make caller always assume viewport space and
* specify texco via vertex attribs. */
shader->interface = GPU_shaderinterface_create(shader->program);
}
shader->cacheId = cache_id;
shader->valid = (shader->program != 0);
}
static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader,
static void ensureGLSLShader(OCIO_GLSLShader **shader_ptr,
ConstProcessorRcPtr *processor_scene_to_ui,
ConstProcessorRcPtr *processpr_ui_to_display,
GpuShaderDesc *shader_desc,
const std::string &cache_id)
{
if (*shader_ptr != NULL) {
return;
}
OCIO_GLSLShader *shader = OBJECT_GUARDED_NEW(OCIO_GLSLShader);
updateGLSLShader(shader, processor_scene_to_ui, processpr_ui_to_display, shader_desc, cache_id);
*shader_ptr = shader;
}
static void freeGLSLShader(OCIO_GLSLShader *shader)
{
glDeleteProgram(shader->program);
glDeleteShader(shader->frag);
glDeleteShader(shader->vert);
if (shader->interface) {
GPU_shaderinterface_discard(shader->interface);
}
OBJECT_GUARDED_DELETE(shader, OCIO_GLSLShader);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Lut3D
* \{ */
static void updateGLSLLut3d(OCIO_GLSLLut3d *lut3d,
ConstProcessorRcPtr *processor_scene_to_ui,
ConstProcessorRcPtr *processpr_ui_to_display,
GpuShaderDesc *shader_desc,
const std::string &cache_id)
{
if (lut3d->cacheId == cache_id)
return;
float *lut_data = (float *)MEM_mallocN(LUT3D_TEXTURE_SIZE, __func__);
ConstProcessorRcPtr *ocio_processors[2] = {processor_scene_to_ui, processpr_ui_to_display};
for (int i = 0; i < 2; i++) {
ConstProcessorRcPtr *processor = ocio_processors[i];
GLuint texture = (&lut3d->texture)[i];
(*processor)->getGpuLut3D(lut_data, *shader_desc);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, texture);
glTexSubImage3D(GL_TEXTURE_3D,
0,
0,
0,
0,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
GL_RGB,
GL_FLOAT,
lut_data);
}
MEM_freeN(lut_data);
lut3d->cacheId = cache_id;
}
static void ensureGLSLLut3d(OCIO_GLSLLut3d **lut3d_ptr,
ConstProcessorRcPtr *processor_scene_to_ui,
ConstProcessorRcPtr *processpr_ui_to_display,
GpuShaderDesc *shaderDesc,
const std::string &cache_id)
{
if (*lut3d_ptr != NULL) {
return;
}
OCIO_GLSLLut3d *lut3d = OBJECT_GUARDED_NEW(OCIO_GLSLLut3d);
glGenTextures(3, &lut3d->texture);
for (int i = 0; i < 2; i++) {
GLuint texture = (&lut3d->texture)[i];
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_3D,
0,
GL_RGB16F,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
0,
GL_RGB,
GL_FLOAT,
NULL);
}
updateGLSLLut3d(lut3d, processor_scene_to_ui, processpr_ui_to_display, shaderDesc, cache_id);
lut3d->valid = (lut3d->texture != 0);
*lut3d_ptr = lut3d;
}
static void freeGLSLLut3d(OCIO_GLSLLut3d *lut3d)
{
glDeleteTextures(1, &lut3d->texture);
OBJECT_GUARDED_DELETE(lut3d, OCIO_GLSLLut3d);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Curve Mapping
* \{ */
static void allocateCurveMappingTexture(OCIO_GLSLCurveMappping *curvemap,
OCIO_CurveMappingSettings *curve_mapping_settings)
{
if (shader->curve_mapping_texture_allocated)
return shader->curve_mapping_texture_valid;
glGenTextures(1, &shader->curve_mapping_texture);
glGenTextures(1, &curvemap->texture);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
glBindTexture(GL_TEXTURE_1D, curvemap->texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
/* clean glError buffer */
while (glGetError() != GL_NO_ERROR) {
}
glTexImage1D(GL_TEXTURE_1D,
0,
GL_RGBA16F,
curve_mapping_settings->lut_size,
0,
GL_RGBA,
GL_FLOAT,
curve_mapping_settings->lut);
shader->curve_mapping_texture_allocated = true;
/* GL_RGB16F_ARB could be not supported at some drivers
* in this case we could not use GLSL display
*/
shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
return shader->curve_mapping_texture_valid;
/* Do not initialize. Only if used. */
int lut_size = curve_mapping_settings ? curve_mapping_settings->lut_size : 1;
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F, lut_size, 0, GL_RGBA, GL_FLOAT, NULL);
}
static void freeGLSLShader(OCIO_GLSLShader *shader)
/* curve_mapping_settings can be null. In this case we alloc a dummy curvemap. */
static void ensureGLSLCurveMapping(OCIO_GLSLCurveMappping **curvemap_ptr,
OCIO_CurveMappingSettings *curve_mapping_settings)
{
if (shader->curve_mapping_texture_allocated) {
glDeleteTextures(1, &shader->curve_mapping_texture);
if (*curvemap_ptr != NULL) {
return;
}
if (shader->lut3d_texture_allocated) {
glDeleteTextures(1, &shader->lut3d_texture);
}
OCIO_GLSLCurveMappping *curvemap = OBJECT_GUARDED_NEW(OCIO_GLSLCurveMappping);
if (shader->lut3d) {
MEM_freeN(shader->lut3d);
}
/* Texture. */
allocateCurveMappingTexture(curvemap, curve_mapping_settings);
if (shader->program) {
glDeleteProgram(shader->program);
}
/* Uniform buffer object. */
glGenBuffers(1, &curvemap->buffer);
glBindBuffer(GL_UNIFORM_BUFFER, curvemap->buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(OCIO_GLSLCurveMappingParameters), 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
if (shader->shader_interface) {
GPU_shaderinterface_discard(shader->shader_interface);
}
curvemap->valid = (curvemap->texture != 0);
curvemap->cacheId = 0;
if (shader->ocio_shader) {
glDeleteShader(shader->ocio_shader);
}
using std::string;
shader->lut3dCacheID.~string();
shader->shaderCacheID.~string();
MEM_freeN(shader);
*curvemap_ptr = curvemap;
}
static void freeGLSLCurveMapping(OCIO_GLSLCurveMappping *curvemap)
{
glDeleteTextures(1, &curvemap->texture);
glDeleteBuffers(1, &curvemap->buffer);
OBJECT_GUARDED_DELETE(curvemap, OCIO_GLSLCurveMappping);
}
static void updateGLSLCurveMapping(OCIO_GLSLCurveMappping *curvemap,
OCIO_CurveMappingSettings *curve_mapping_settings,
size_t cacheId)
{
/* No need to continue if curvemapping is not used. Just use whatever is in this cache. */
if (curve_mapping_settings == NULL)
return;
if (curvemap->cacheId == cacheId)
return;
if (curvemap->cacheId == 0) {
/* This cache was previously used as dummy. Recreate the texture. */
glDeleteTextures(1, &curvemap->texture);
allocateCurveMappingTexture(curvemap, curve_mapping_settings);
}
/* Update texture. */
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, curvemap->texture);
glTexSubImage1D(GL_TEXTURE_1D,
0,
0,
curve_mapping_settings->lut_size,
GL_RGBA,
GL_FLOAT,
curve_mapping_settings->lut);
/* Update uniforms. */
OCIO_GLSLCurveMappingParameters data;
for (int i = 0; i < 4; i++) {
data.curve_mapping_range[i] = curve_mapping_settings->range[i];
data.curve_mapping_mintable[i] = curve_mapping_settings->mintable[i];
data.curve_mapping_ext_in_x[i] = curve_mapping_settings->ext_in_x[i];
data.curve_mapping_ext_in_y[i] = curve_mapping_settings->ext_in_y[i];
data.curve_mapping_ext_out_x[i] = curve_mapping_settings->ext_out_x[i];
data.curve_mapping_ext_out_y[i] = curve_mapping_settings->ext_out_y[i];
data.curve_mapping_first_x[i] = curve_mapping_settings->first_x[i];
data.curve_mapping_first_y[i] = curve_mapping_settings->first_y[i];
data.curve_mapping_last_x[i] = curve_mapping_settings->last_x[i];
data.curve_mapping_last_y[i] = curve_mapping_settings->last_y[i];
}
for (int i = 0; i < 3; i++) {
data.curve_mapping_black[i] = curve_mapping_settings->black[i];
data.curve_mapping_bwmul[i] = curve_mapping_settings->bwmul[i];
}
data.curve_mapping_lut_size = curve_mapping_settings->lut_size;
data.curve_mapping_use_extend_extrapolate = curve_mapping_settings->use_extend_extrapolate;
glBindBuffer(GL_UNIFORM_BUFFER, curvemap->buffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(OCIO_GLSLCurveMappingParameters), &data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
curvemap->cacheId = cacheId;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name LRU cache
* \{ */
static size_t hash_string(const char *str)
{
size_t i = 0, c;
while ((c = *str++)) {
i = i * 37 + c;
}
return i;
}
static OCIO_GLSLCacheHandle *cacheSearch(OCIO_GLSLCacheHandle cache[SHADER_CACHE_SIZE],
size_t cache_id)
{
OCIO_GLSLCacheHandle *cached_item = &cache[0];
for (int i = 0; i < SHADER_CACHE_SIZE; i++, cached_item++) {
if (cached_item->data == NULL) {
continue;
}
else if (cached_item->cache_id == cache_id) {
/* LRU cache, so move to front. */
OCIO_GLSLCacheHandle found_item = *cached_item;
for (int j = i; j > 0; j--) {
cache[j] = cache[j - 1];
}
cache[0] = found_item;
return &cache[0];
}
}
/* LRU cache, shift other items back so we can insert at the front. */
OCIO_GLSLCacheHandle last_item = cache[SHADER_CACHE_SIZE - 1];
for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
cache[j] = cache[j - 1];
}
/* Copy last to front and let the caller initialize it. */
cache[0] = last_item;
return &cache[0];
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name OCIO GLSL Implementation
* \{ */
/* Detect if we can support GLSL drawing */
bool OCIOImpl::supportGLSLDraw()
{
/* uses GL_RGB16F_ARB */
return GLEW_VERSION_3_0 || GLEW_ARB_texture_float;
/* Minimum supported version 3.3 does meet all requirements. */
return true;
}
/**
@@ -295,14 +588,21 @@ bool OCIOImpl::supportGLSLDraw()
* restore OpenGL context to it's pre-GLSL draw state.
*/
bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
OCIO_ConstProcessorRcPtr *processor,
OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
OCIO_CurveMappingSettings *curve_mapping_settings,
float dither,
bool use_predivide)
bool use_predivide,
bool use_overlay)
{
ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *)processor;
ConstProcessorRcPtr processor_scene_to_ui = *(ConstProcessorRcPtr *)ocio_processor_scene_to_ui;
ConstProcessorRcPtr processpr_ui_to_display = *(
ConstProcessorRcPtr *)ocio_processor_ui_to_display;
bool use_curve_mapping = curve_mapping_settings != NULL;
bool use_dither = dither > std::numeric_limits<float>::epsilon();
if (!processor_scene_to_ui || !processor_scene_to_ui) {
return false;
}
/* Create state if needed. */
OCIO_GLSLDrawState *state;
@@ -310,235 +610,108 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
*state_r = allocateOpenGLState();
state = *state_r;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture);
glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
/* Compute cache IDs. */
GpuShaderDesc shaderDesc;
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
shaderDesc.setFunctionName("OCIODisplay");
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
const char *shader_cache_str = processor_scene_to_ui->getGpuShaderTextCacheID(shaderDesc);
const char *lut3d_cache_str = processor_scene_to_ui->getGpuLut3DCacheID(shaderDesc);
/* Used for comparison. */
std::string shaderCacheID = shader_cache_str;
std::string lut3dCacheID = lut3d_cache_str;
/* Find matching cached shader. */
OCIO_GLSLShader *shader = NULL;
for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
OCIO_GLSLShader *cached_shader = state->shader_cache[i];
if (cached_shader == NULL) {
continue;
}
size_t shader_cache_id = hash_string(shader_cache_str);
size_t lut3d_cache_id = hash_string(lut3d_cache_str);
size_t curvemap_cache_id = curve_mapping_settings ? curve_mapping_settings->cache_id : 0;
if (cached_shader->lut3dCacheID == lut3dCacheID &&
cached_shader->shaderCacheID == shaderCacheID &&
cached_shader->use_predivide == use_predivide &&
cached_shader->use_curve_mapping == use_curve_mapping &&
cached_shader->use_dither == use_dither) {
/* LRU cache, so move to front. */
for (int j = i; j > 0; j--) {
state->shader_cache[j] = state->shader_cache[j - 1];
}
state->shader_cache[0] = cached_shader;
OCIO_GLSLCacheHandle *shader_handle = cacheSearch(state->shader_cache, shader_cache_id);
OCIO_GLSLCacheHandle *lut3d_handle = cacheSearch(state->lut3d_cache, lut3d_cache_id);
/* We cannot keep more than one cache for curvemap because their cache id is a pointer.
* The pointer cannot be the same for one update but can be the same after a second update. */
OCIO_GLSLCacheHandle *curvemap_handle = &state->curvemap_cache[0];
shader = cached_shader;
break;
}
}
OCIO_GLSLShader **shader_ptr = (OCIO_GLSLShader **)&shader_handle->data;
OCIO_GLSLLut3d **lut3d_ptr = (OCIO_GLSLLut3d **)&lut3d_handle->data;
OCIO_GLSLCurveMappping **curvemap_ptr = (OCIO_GLSLCurveMappping **)&curvemap_handle->data;
if (shader == NULL) {
/* LRU cache, shift other items back so we can insert at the front. */
OCIO_GLSLShader *last_shader = state->shader_cache[SHADER_CACHE_SIZE - 1];
if (last_shader) {
freeGLSLShader(last_shader);
}
for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
state->shader_cache[j] = state->shader_cache[j - 1];
}
ensureGLSLShader(
shader_ptr, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
ensureGLSLLut3d(
lut3d_ptr, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
ensureGLSLCurveMapping(curvemap_ptr, curve_mapping_settings);
/* Allocate memory for shader. */
shader = (OCIO_GLSLShader *)MEM_callocN(sizeof(OCIO_GLSLShader), "OCIO GLSL Shader");
state->shader_cache[0] = shader;
OCIO_GLSLShader *shader = (OCIO_GLSLShader *)shader_handle->data;
OCIO_GLSLLut3d *shader_lut = (OCIO_GLSLLut3d *)lut3d_handle->data;
OCIO_GLSLCurveMappping *shader_curvemap = (OCIO_GLSLCurveMappping *)curvemap_handle->data;
new (&shader->lut3dCacheID) std::string();
new (&shader->shaderCacheID) std::string();
updateGLSLShader(
shader, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
updateGLSLLut3d(
shader_lut, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, lut3dCacheID);
updateGLSLCurveMapping(shader_curvemap, curve_mapping_settings, curvemap_cache_id);
shader->lut3dCacheID = lut3dCacheID;
shader->shaderCacheID = shaderCacheID;
shader->use_curve_mapping = use_curve_mapping;
shader->use_dither = use_dither;
shader->use_predivide = use_predivide;
/* Update handles cache keys. */
shader_handle->cache_id = shader_cache_id;
lut3d_handle->cache_id = lut3d_cache_id;
curvemap_handle->cache_id = curvemap_cache_id;
bool valid = true;
if (shader->valid && shader_lut->valid && shader_curvemap->valid) {
/* Bind textures to sampler units. Texture 0 is set by caller.
* Uniforms have already been set for texture bind points.*/
/* Compute 3D LUT. */
if (valid && ensureLUT3DAllocated(shader)) {
ocio_processor->getGpuLut3D(shader->lut3d, shaderDesc);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_3D, shader_lut->texture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
glTexSubImage3D(GL_TEXTURE_3D,
0,
0,
0,
0,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
LUT3D_EDGE_SIZE,
GL_RGB,
GL_FLOAT,
shader->lut3d);
}
else {
valid = false;
}
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_3D, shader_lut->texture_display);
/* Allocate curve mapping texture. */
if (valid && use_curve_mapping) {
if (!ensureCurveMappingAllocated(shader, curve_mapping_settings)) {
valid = false;
}
}
if (valid) {
/* Vertex shader */
std::ostringstream osv;
osv << "#version 330\n";
osv << datatoc_gpu_shader_display_transform_vertex_glsl;
shader->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
/* Fragment shader */
std::ostringstream os;
os << "#version 330\n";
/* Work around OpenColorIO not supporting latest GLSL yet. */
os << "#define texture2D texture\n";
os << "#define texture3D texture\n";
if (use_predivide) {
os << "#define USE_PREDIVIDE\n";
}
if (use_dither) {
os << "#define USE_DITHER\n";
}
if (use_curve_mapping) {
os << "#define USE_CURVE_MAPPING\n";
}
os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
os << datatoc_gpu_shader_display_transform_glsl;
shader->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
/* Program */
if (shader->ocio_shader && shader->vert_shader) {
shader->program = linkShaders(shader->ocio_shader, shader->vert_shader);
}
if (shader->program) {
if (shader->shader_interface) {
GPU_shaderinterface_discard(shader->shader_interface);
}
shader->shader_interface = GPU_shaderinterface_create(shader->program);
}
}
}
/* Update curve mapping texture. */
if (use_curve_mapping && shader->curve_mapping_texture_allocated) {
if (shader->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
glTexSubImage1D(GL_TEXTURE_1D,
0,
0,
curve_mapping_settings->lut_size,
GL_RGBA,
GL_FLOAT,
curve_mapping_settings->lut);
}
}
/* Bind Shader. */
if (shader->program) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
if (use_curve_mapping) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
}
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_1D, shader_curvemap->texture);
glActiveTexture(GL_TEXTURE0);
/* IMM needs vertex format even if we don't draw with it.
*
* NOTE: The only reason why it's here is because of Cycles viewport.
* All other areas are managing their own vertex formats.
* Doing it here is probably harmless, but kind of stupid.
*
* TODO(sergey): Look into some nicer solution.
*/
GPUVertFormat *format = immVertexFormat();
GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindProgram(shader->program, shader->shader_interface);
/* Bind UBO. */
glBindBufferBase(GL_UNIFORM_BUFFER, 0, shader_curvemap->buffer);
immUniform1i("image_texture", 0);
immUniform1i("lut3d_texture", 1);
/* TODO(fclem) remove remains of IMM. */
immBindProgram(shader->program, shader->interface);
if (use_dither) {
immUniform1f("dither", dither);
}
if (use_curve_mapping) {
immUniform1i("curve_mapping_texture", 2);
immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
immUniform1i("use_curve_mapping_extend_extrapolate",
curve_mapping_settings->use_extend_extrapolate);
immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y);
immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x);
immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y);
immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x);
immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y);
immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x);
immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y);
immUniform3fv("curve_mapping_black", curve_mapping_settings->black);
immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul);
}
/* Bind Shader and set uniforms. */
// glUseProgram(shader->program);
glUniform1f(shader->dither_loc, dither);
glUniform1i(shader->overlay_tex_loc, use_overlay ? 1 : 0);
glUniform1i(shader->overlay_loc, use_overlay);
glUniform1i(shader->predivide_loc, use_predivide);
glUniform1i(shader->curve_mapping_loc, use_curve_mapping);
return true;
}
else {
glActiveTexture(state->last_texture_unit);
glBindTexture(GL_TEXTURE_2D, state->last_texture);
return false;
}
return false;
}
void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState * /*state*/)
{
glActiveTexture(state->last_texture_unit);
glBindTexture(GL_TEXTURE_2D, state->last_texture);
immUnbindProgram();
}
void OCIOImpl::freeGLState(OCIO_GLSLDrawState *state)
{
for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
if (state->shader_cache[i]) {
freeGLSLShader(state->shader_cache[i]);
if (state->shader_cache[i].data) {
freeGLSLShader((OCIO_GLSLShader *)state->shader_cache[i].data);
}
if (state->lut3d_cache[i].data) {
freeGLSLLut3d((OCIO_GLSLLut3d *)state->lut3d_cache[i].data);
}
if (state->curvemap_cache[i].data) {
freeGLSLCurveMapping((OCIO_GLSLCurveMappping *)state->curvemap_cache[i].data);
}
}
MEM_freeN(state);
}
/** \} */

View File

@@ -56,6 +56,7 @@ set(SRC
intern/draw_cache_impl_mesh.c
intern/draw_cache_impl_metaball.c
intern/draw_cache_impl_particles.c
intern/draw_color_management.c
intern/draw_common.c
intern/draw_debug.c
intern/draw_hair.c
@@ -121,6 +122,7 @@ set(SRC
engines/select/select_engine.c
engines/overlay/overlay_antialiasing.c
engines/overlay/overlay_armature.c
engines/overlay/overlay_background.c
engines/overlay/overlay_edit_curve.c
engines/overlay/overlay_edit_mesh.c
engines/overlay/overlay_edit_text.c
@@ -146,6 +148,7 @@ set(SRC
intern/draw_cache_extract.h
intern/draw_cache_impl.h
intern/draw_cache_inline.h
intern/draw_color_management.h
intern/draw_common.h
intern/draw_debug.h
intern/draw_hair_private.h
@@ -237,7 +240,6 @@ data_to_c_simple(engines/eevee/shaders/volumetric_resolve_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_scatter_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_cavity_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_cavity_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl SRC)
@@ -329,6 +331,8 @@ data_to_c_simple(engines/overlay/shaders/armature_stick_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/armature_stick_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/armature_wire_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/armature_wire_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/background_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/clipbound_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/depth_only_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_curve_handle_geom.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_curve_handle_vert.glsl SRC)

View File

@@ -52,18 +52,18 @@ struct rcti;
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
struct GPUFrameBuffer *default_fb;
struct GPUFrameBuffer *overlay_fb;
struct GPUFrameBuffer *in_front_fb;
struct GPUFrameBuffer *color_only_fb;
struct GPUFrameBuffer *depth_only_fb;
struct GPUFrameBuffer *multisample_fb;
struct GPUFrameBuffer *overlay_only_fb;
} DefaultFramebufferList;
typedef struct DefaultTextureList {
struct GPUTexture *color;
struct GPUTexture *color_overlay;
struct GPUTexture *depth;
struct GPUTexture *depth_in_front;
struct GPUTexture *multisample_color;
struct GPUTexture *multisample_depth;
} DefaultTextureList;
void DRW_engines_register(void);

View File

@@ -245,7 +245,6 @@ DrawEngineType draw_engine_basic_type = {
&basic_cache_init,
&basic_cache_populate,
&basic_cache_finish,
NULL,
&basic_draw_scene,
NULL,
NULL,

View File

@@ -174,11 +174,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
/* Alpha checker if background is not drawn in viewport. */
if (!DRW_state_is_image_render() && !DRW_state_draw_background()) {
effects->enabled_effects |= EFFECT_ALPHA_CHECKER;
}
/**
* MinMax Pyramid
*/
@@ -342,31 +337,6 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call(grp, quad, NULL);
}
if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) {
GPUShader *checker_sh = GPU_shader_get_builtin_shader(GPU_SHADER_2D_CHECKER);
copy_v4_fl4(effects->color_checker_dark, 0.15f, 0.15f, 0.15f, 1.0f);
copy_v4_fl4(effects->color_checker_light, 0.2f, 0.2f, 0.2f, 1.0f);
DRW_PASS_CREATE(psl->alpha_checker,
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL);
grp = DRW_shgroup_create(checker_sh, psl->alpha_checker);
DRW_shgroup_uniform_vec4(grp, "color1", effects->color_checker_dark, 1);
DRW_shgroup_uniform_vec4(grp, "color2", effects->color_checker_light, 1);
DRW_shgroup_uniform_int_copy(grp, "size", 8);
DRW_shgroup_call(grp, quad, NULL);
float viewmat[4][4], winmat[4][4];
unit_m4(viewmat);
unit_m4(winmat);
/* Winmat must be negative. */
swap_v3_v3(winmat[0], winmat[1]);
/* Using default view bypasses the culling. */
const DRWView *default_view = DRW_view_default_get();
effects->checker_view = DRW_view_create_sub(default_view, viewmat, winmat);
}
}
void EEVEE_effects_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -524,21 +494,6 @@ void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, i
DRW_stats_group_end();
}
void EEVEE_draw_alpha_checker(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) {
DRW_view_set_active(effects->checker_view);
DRW_draw_pass(psl->alpha_checker);
DRW_view_set_active(NULL);
}
}
static void EEVEE_velocity_resolve(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;

View File

@@ -22,10 +22,11 @@
#include "DRW_render.h"
#include "draw_color_management.h" /* TODO remove dependency */
#include "BLI_rand.h"
#include "BKE_object.h"
#include "BKE_global.h" /* for G.debug_value */
#include "DEG_depsgraph_query.h"
@@ -183,13 +184,11 @@ static void eevee_cache_finish(void *vedata)
* the background and the scene pass are visible.
* Note: we could break it up in two passes using some depth test
* to reduce the fillrate */
static void eevee_draw_background(void *vedata)
static void eevee_draw_scene(void *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
/* Default framebuffer and texture */
@@ -338,79 +337,15 @@ static void eevee_draw_background(void *vedata)
}
if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
/* Tonemapping and transfer result to default framebuffer. */
bool use_render_settings = stl->g_data->use_color_render_settings;
/* Transfer result to default framebuffer. */
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
/* Draw checkerboard with alpha under. */
EEVEE_draw_alpha_checker(vedata);
DRW_transform_none(stl->effects->final_tx);
}
else {
EEVEE_renderpasses_draw(sldata, vedata);
}
/* Debug : Output buffer to view. */
switch (G.debug_value) {
case 1:
if (txl->maxzbuffer) {
DRW_transform_to_display(txl->maxzbuffer, false, false);
}
break;
case 2:
if (effects->ssr_pdf_output) {
DRW_transform_to_display(effects->ssr_pdf_output, false, false);
}
break;
case 3:
if (effects->ssr_normal_input) {
DRW_transform_to_display(effects->ssr_normal_input, false, false);
}
break;
case 4:
if (effects->ssr_specrough_input) {
DRW_transform_to_display(effects->ssr_specrough_input, false, false);
}
break;
case 5:
if (txl->color_double_buffer) {
DRW_transform_to_display(txl->color_double_buffer, false, false);
}
break;
case 6:
if (effects->gtao_horizons_debug) {
DRW_transform_to_display(effects->gtao_horizons_debug, false, false);
}
break;
case 7:
if (effects->gtao_horizons) {
DRW_transform_to_display(effects->gtao_horizons, false, false);
}
break;
case 8:
if (effects->sss_irradiance) {
DRW_transform_to_display(effects->sss_irradiance, false, false);
}
break;
case 9:
if (effects->sss_radius) {
DRW_transform_to_display(effects->sss_radius, false, false);
}
break;
case 10:
if (effects->sss_albedo) {
DRW_transform_to_display(effects->sss_albedo, false, false);
}
break;
case 11:
if (effects->velocity_tx) {
DRW_transform_to_display(effects->velocity_tx, false, false);
}
break;
default:
break;
}
EEVEE_renderpasses_draw_debug(vedata);
EEVEE_volumes_free_smoke_textures();
@@ -525,8 +460,7 @@ DrawEngineType draw_engine_eevee_type = {
&eevee_cache_init,
&EEVEE_cache_populate,
&eevee_cache_finish,
&eevee_draw_background,
NULL, /* Everything is drawn in the background pass (see comment on function) */
&eevee_draw_scene,
&eevee_view_update,
&eevee_id_update,
&eevee_render_to_image,

View File

@@ -523,7 +523,6 @@ typedef enum EEVEE_EffectsFlag {
EFFECT_VELOCITY_BUFFER = (1 << 12), /* Not really an effect but a feature */
EFFECT_TAA_REPROJECT = (1 << 13), /* should be mutually exclusive with EFFECT_TAA */
EFFECT_DEPTH_DOUBLE_BUFFER = (1 << 14), /* Not really an effect but a feature */
EFFECT_ALPHA_CHECKER = (1 << 15), /* Not really an effect but a feature */
} EEVEE_EffectsFlag;
typedef struct EEVEE_EffectsInfo {
@@ -588,7 +587,6 @@ typedef struct EEVEE_EffectsInfo {
/* Alpha Checker */
float color_checker_dark[4];
float color_checker_light[4];
struct DRWView *checker_view;
/* Other */
float prev_persmat[4][4];
/* Lookdev */
@@ -1057,6 +1055,7 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eScenePassType renderpass_type);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
void EEVEE_renderpasses_free(void);
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata);

View File

@@ -23,6 +23,10 @@
#include "DRW_engine.h"
#include "DRW_render.h"
#include "draw_color_management.h" /* TODO remove dependency. */
#include "BKE_global.h" /* for G.debug_value */
#include "BLI_string_utils.h"
#include "DEG_depsgraph_query.h"
@@ -239,6 +243,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
DRW_state_is_opengl_render();
UNUSED_VARS(needs_color_transfer);
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 &&
@@ -261,7 +266,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (is_valid) {
EEVEE_renderpasses_postprocess(sldata, vedata, render_pass);
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_to_display(txl->renderpass, needs_color_transfer, false);
DRW_transform_none(txl->renderpass);
}
else {
/* Draw state is not valid for this pass, clear the buffer */
@@ -276,3 +281,54 @@ void EEVEE_renderpasses_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.postprocess_sh);
}
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata)
{
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
GPUTexture *tx = NULL;
/* Debug : Output buffer to view. */
switch (G.debug_value) {
case 1:
tx = txl->maxzbuffer;
break;
case 2:
tx = effects->ssr_pdf_output;
break;
case 3:
tx = effects->ssr_normal_input;
break;
case 4:
tx = effects->ssr_specrough_input;
break;
case 5:
tx = txl->color_double_buffer;
break;
case 6:
tx = effects->gtao_horizons;
break;
case 7:
tx = effects->gtao_horizons;
break;
case 8:
tx = effects->sss_irradiance;
break;
case 9:
tx = effects->sss_radius;
break;
case 10:
tx = effects->sss_albedo;
break;
case 11:
tx = effects->velocity_tx;
break;
default:
break;
}
if (tx) {
DRW_transform_none(tx);
}
}

View File

@@ -198,7 +198,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
/**
* Reset for each "redraw". When rendering using ogl render,
* we accumulate the redraw inside the drawing loop in eevee_draw_background().
* we accumulate the redraw inside the drawing loop in eevee_draw_scene().
**/
effects->taa_render_sample = 1;
effects->taa_view = NULL;
@@ -251,7 +251,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
(effects->taa_current_sample < effects->taa_total_sample)) ||
DRW_state_is_image_render()) {
if (view_is_valid) {
/* Viewport rendering updates the matrices in `eevee_draw_background` */
/* Viewport rendering updates the matrices in `eevee_draw_scene` */
if (!DRW_state_is_image_render()) {
effects->taa_current_sample += 1;
repro_flag = 0;

View File

@@ -236,6 +236,12 @@ static void external_draw_scene(void *vedata)
* OpenGL render is used for quick preview (thumbnails or sequencer preview)
* where using the rendering engine to preview doesn't make so much sense. */
if (draw_ctx->evil_C) {
float clear_col[4] = {0, 0, 0, 0};
/* This is to keep compatibility with external engine. */
/* TODO(fclem) remove it eventually. */
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_color(dfbl->default_fb, clear_col);
external_draw_scene_do(vedata);
}
@@ -266,7 +272,6 @@ static DrawEngineType draw_engine_external_type = {
&external_cache_init,
&external_cache_populate,
&external_cache_finish,
NULL,
&external_draw_scene,
NULL,
NULL,

View File

@@ -1180,7 +1180,6 @@ DrawEngineType draw_engine_gpencil_type = {
&GPENCIL_cache_init,
&GPENCIL_cache_populate,
&GPENCIL_cache_finish,
NULL,
&GPENCIL_draw_scene,
NULL,
NULL,

View File

@@ -524,7 +524,6 @@ void DRW_gpencil_free_runtime_data(void *ved);
if ((lvl > 0) && (fbl->multisample_fb != NULL) && (DRW_state_is_fbo())) { \
DRW_stats_query_start("GP Multisample Resolve"); \
GPU_framebuffer_bind(fb); \
DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \
DRW_stats_query_end(); \
} \
} \

View File

@@ -83,7 +83,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
GPUTexture *line_tex = NULL;
if (pd->antialiasing.enabled) {
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_RGBA8, DRW_TEX_FILTER);
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_SRGB8_A8, DRW_TEX_FILTER);
DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0);
color_tex = txl->overlay_color_tx;
@@ -194,9 +194,7 @@ void OVERLAY_antialiasing_end(OVERLAY_Data *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (pd->antialiasing.enabled) {
GPU_framebuffer_bind(dfbl->color_only_fb);
GPU_framebuffer_bind(dfbl->overlay_only_fb);
DRW_draw_pass(psl->antialiasing_ps);
GPU_framebuffer_bind(dfbl->default_fb);
}
}

View File

@@ -88,26 +88,6 @@ typedef struct ArmatureDrawContext {
OVERLAY_ExtraCallBuffers *extras;
/**
* Follow `TH_*` naming except for mixed colors.
*/
struct {
float select[4];
float edge_select[4];
float bone_select[4]; /* tint */
float wire[4];
float wire_edit[4];
float bone_solid[4];
float bone_active_unselect[4]; /* mix */
float bone_pose[4];
float bone_pose_active[4];
float bone_pose_active_unselect[4]; /* mix */
float text_hi[4];
float text[4];
float vertex_select[4];
float vertex[4];
} color;
/* not a theme, this is an override */
const float *const_color;
float const_wire;
@@ -684,31 +664,28 @@ static void drw_shgroup_bone_relationship_lines(ArmatureDrawContext *ctx,
const float start[3],
const float end[3])
{
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, ctx->color.wire);
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorWire);
}
static void drw_shgroup_bone_ik_lines(ArmatureDrawContext *ctx,
const float start[3],
const float end[3])
{
float fcolor[4] = {0.8f, 0.5f, 0.0f, 1.0f}; /* add theme! */
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor);
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLine);
}
static void drw_shgroup_bone_ik_no_target_lines(ArmatureDrawContext *ctx,
const float start[3],
const float end[3])
{
float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor);
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLineNoTarget);
}
static void drw_shgroup_bone_ik_spline_lines(ArmatureDrawContext *ctx,
const float start[3],
const float end[3])
{
float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor);
drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLineSpline);
}
/** \} */
@@ -725,10 +702,6 @@ enum {
PCHAN_COLOR_NORMAL = 0, /* normal drawing */
PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */
PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */
PCHAN_COLOR_LINEBONE, /* for the middle of line-bones */
};
/* This function sets the color-set for coloring a certain bone */
@@ -791,14 +764,6 @@ static void cp_shade_color3ub(uchar cp[3], const int offset)
cp[2] = b;
}
static void cp_shade_color3f(float cp[3], const float offset)
{
add_v3_fl(cp, offset);
CLAMP(cp[0], 0, 255);
CLAMP(cp[1], 0, 255);
CLAMP(cp[2], 0, 255);
}
/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
static bool set_pchan_color(const ArmatureDrawContext *ctx,
short colCode,
@@ -813,7 +778,6 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
case PCHAN_COLOR_NORMAL: {
if (bcolor) {
uchar cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_uchar(cp, bcolor->active);
if (!(boneflag & BONE_SELECTED)) {
@@ -828,159 +792,58 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
copy_v3_v3_uchar(cp, bcolor->solid);
cp_shade_color3ub(cp, -50);
}
rgb_uchar_to_float(fcolor, cp);
/* Meh, hardcoded srgb transform here. */
srgb_to_linearrgb_v4(fcolor, fcolor);
}
else {
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseActive);
}
else if (boneflag & BONE_DRAW_ACTIVE) {
UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseActiveUnsel);
}
else if (boneflag & BONE_SELECTED) {
UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
copy_v4_v4(fcolor, G_draw.block.colorBonePose);
}
else {
UI_GetThemeColor4fv(TH_WIRE, fcolor);
copy_v4_v4(fcolor, G_draw.block.colorWire);
}
}
return true;
}
case PCHAN_COLOR_SOLID: {
UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
if (bcolor) {
float solid_bcolor[3];
rgb_uchar_to_float(solid_bcolor, (uchar *)bcolor->solid);
interp_v3_v3v3(fcolor, fcolor, solid_bcolor, 1.0f);
rgb_uchar_to_float(fcolor, (uchar *)bcolor->solid);
/* Meh, hardcoded srgb transform here. */
srgb_to_linearrgb_v4(fcolor, fcolor);
}
else {
copy_v4_v4(fcolor, G_draw.block.colorBoneSolid);
}
return true;
}
case PCHAN_COLOR_CONSTS: {
if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
uchar cp[4];
if (constflag & PCHAN_HAS_TARGET) {
rgba_uchar_args_set(cp, 255, 150, 0, 80);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseTarget);
}
else if (constflag & PCHAN_HAS_IK) {
rgba_uchar_args_set(cp, 255, 255, 0, 80);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseIK);
}
else if (constflag & PCHAN_HAS_SPLINEIK) {
rgba_uchar_args_set(cp, 200, 255, 0, 80);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseSplineIK);
}
else if (constflag & PCHAN_HAS_CONST) {
rgba_uchar_args_set(cp, 0, 255, 120, 80);
copy_v4_v4(fcolor, G_draw.block.colorBonePoseConstraint);
}
else {
return false;
}
rgba_uchar_to_float(fcolor, cp);
return true;
}
return false;
}
case PCHAN_COLOR_SPHEREBONE_BASE: {
if (bcolor) {
uchar cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_uchar(cp, bcolor->active);
}
else if (boneflag & BONE_SELECTED) {
copy_v3_v3_uchar(cp, bcolor->select);
}
else {
copy_v3_v3_uchar(cp, bcolor->solid);
}
rgb_uchar_to_float(fcolor, cp);
}
else {
if (boneflag & BONE_DRAW_ACTIVE) {
UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor);
}
else if (boneflag & BONE_SELECTED) {
UI_GetThemeColor4fv(TH_BONE_POSE, fcolor);
}
else {
UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor);
}
}
return true;
}
case PCHAN_COLOR_SPHEREBONE_END: {
if (bcolor) {
uchar cp[4] = {255};
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3_uchar(cp, bcolor->active);
cp_shade_color3ub(cp, 10);
}
else if (boneflag & BONE_SELECTED) {
copy_v3_v3_uchar(cp, bcolor->select);
cp_shade_color3ub(cp, -30);
}
else {
copy_v3_v3_uchar(cp, bcolor->solid);
cp_shade_color3ub(cp, -30);
}
rgb_uchar_to_float(fcolor, cp);
}
else {
if (boneflag & BONE_DRAW_ACTIVE) {
UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor);
}
else if (boneflag & BONE_SELECTED) {
UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor);
}
else {
UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor);
}
}
break;
}
case PCHAN_COLOR_LINEBONE: {
/* inner part in background color or constraint */
if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) {
uchar cp[4];
if (constflag & PCHAN_HAS_TARGET) {
rgba_uchar_args_set(cp, 255, 150, 0, 255);
}
else if (constflag & PCHAN_HAS_IK) {
rgba_uchar_args_set(cp, 255, 255, 0, 255);
}
else if (constflag & PCHAN_HAS_SPLINEIK) {
rgba_uchar_args_set(cp, 200, 255, 0, 255);
}
else if (constflag & PCHAN_HAS_CONST) {
rgba_uchar_args_set(cp, 0, 255, 120, 255);
}
else if (constflag) {
UI_GetThemeColor4ubv(TH_BONE_POSE, cp);
} /* PCHAN_HAS_ACTION */
rgb_uchar_to_float(fcolor, cp);
}
else {
if (bcolor) {
const uchar *cp = bcolor->solid;
rgb_uchar_to_float(fcolor, (uchar *)cp);
fcolor[3] = 204.f / 255.f;
}
else {
UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor);
}
}
return true;
}
}
return false;
@@ -994,9 +857,7 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx,
static void bone_locked_color_shade(float color[4])
{
float locked_color[4];
UI_GetThemeColor4fv(TH_BONE_LOCKED_WEIGHT, locked_color);
float *locked_color = G_draw.block.colorBoneLocked;
interp_v3_v3v3(color, color, locked_color, locked_color[3]);
}
@@ -1009,7 +870,7 @@ static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
const short constflag)
{
if (ctx->const_color) {
return ctx->color.bone_solid;
return G_draw.block.colorBoneSolid;
}
if (arm->flag & ARM_POSEMODE) {
@@ -1024,7 +885,7 @@ static const float *get_bone_solid_color(const ArmatureDrawContext *ctx,
return disp_color;
}
return ctx->color.bone_solid;
return G_draw.block.colorBoneSolid;
}
static const float *get_bone_solid_with_consts_color(const ArmatureDrawContext *ctx,
@@ -1035,7 +896,7 @@ static const float *get_bone_solid_with_consts_color(const ArmatureDrawContext *
const short constflag)
{
if (ctx->const_color) {
return ctx->color.bone_solid;
return G_draw.block.colorBoneSolid;
}
const float *col = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag);
@@ -1079,18 +940,18 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
else if (eBone) {
if (boneflag & BONE_SELECTED) {
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3(disp_color, ctx->color.edge_select);
copy_v3_v3(disp_color, G_draw.block.colorBoneActive);
}
else {
copy_v3_v3(disp_color, ctx->color.bone_select);
copy_v3_v3(disp_color, G_draw.block.colorBoneSelect);
}
}
else {
if (boneflag & BONE_DRAW_ACTIVE) {
copy_v3_v3(disp_color, ctx->color.bone_active_unselect);
copy_v3_v3(disp_color, G_draw.block.colorBoneActiveUnsel);
}
else {
copy_v3_v3(disp_color, ctx->color.wire_edit);
copy_v3_v3(disp_color, G_draw.block.colorWireEdit);
}
}
}
@@ -1103,7 +964,7 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
}
}
else {
copy_v3_v3(disp_color, ctx->color.vertex);
copy_v3_v3(disp_color, G_draw.block.colorVertex);
}
disp_color[3] = get_bone_wire_thickness(ctx, boneflag);
@@ -1111,13 +972,12 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
return disp_color;
}
#define HINT_MUL 0.5f
#define HINT_SHADE 0.2f
static void bone_hint_color_shade(float hint_color[4], const float color[4])
{
mul_v3_v3fl(hint_color, color, HINT_MUL);
cp_shade_color3f(hint_color, -HINT_SHADE);
/* Increase contrast. */
mul_v3_v3v3(hint_color, color, color);
/* Decrease value to add mode shading to the shape. */
mul_v3_fl(hint_color, 0.1f);
hint_color[3] = 1.0f;
}
@@ -1131,7 +991,7 @@ static const float *get_bone_hint_color(const ArmatureDrawContext *ctx,
static float hint_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
if (ctx->const_color) {
bone_hint_color_shade(hint_color, ctx->color.bone_solid);
bone_hint_color_shade(hint_color, G_draw.block.colorBoneSolid);
}
else {
const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag);
@@ -1412,11 +1272,11 @@ static void draw_axes(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *p
float final_col[4];
const float *col = (ctx->const_color) ?
ctx->const_color :
(BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? ctx->color.text_hi :
ctx->color.text;
(BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.colorTextHi :
G_draw.block.colorText;
copy_v4_v4(final_col, col);
/* Mix with axes color. */
final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.3 : 0.8;
final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
drw_shgroup_bone_axes(ctx, BONE_VAR(eBone, pchan, disp_mat), final_col);
}
@@ -1431,10 +1291,10 @@ static void draw_points(ArmatureDrawContext *ctx,
float col_solid_root[4], col_solid_tail[4], col_wire_root[4], col_wire_tail[4];
float col_hint_root[4], col_hint_tail[4];
copy_v4_v4(col_solid_root, ctx->color.bone_solid);
copy_v4_v4(col_solid_tail, ctx->color.bone_solid);
copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : ctx->color.vertex);
copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : ctx->color.vertex);
copy_v4_v4(col_solid_root, G_draw.block.colorBoneSolid);
copy_v4_v4(col_solid_tail, G_draw.block.colorBoneSolid);
copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex);
copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex);
const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE);
const float envelope_ignore = -1.0f;
@@ -1444,10 +1304,10 @@ static void draw_points(ArmatureDrawContext *ctx,
/* Edit bone points can be selected */
if (eBone) {
if (eBone->flag & BONE_ROOTSEL) {
copy_v3_v3(col_wire_root, ctx->color.vertex_select);
copy_v3_v3(col_wire_root, G_draw.block.colorVertexSelect);
}
if (eBone->flag & BONE_TIPSEL) {
copy_v3_v3(col_wire_tail, ctx->color.vertex_select);
copy_v3_v3(col_wire_tail, G_draw.block.colorVertexSelect);
}
}
else if (arm->flag & ARM_POSEMODE) {
@@ -1635,12 +1495,12 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
else {
if (eBone) {
if (eBone->flag & BONE_TIPSEL) {
col_tail = ctx->color.vertex_select;
col_tail = G_draw.block.colorVertexSelect;
}
if (boneflag & BONE_SELECTED) {
col_bone = ctx->color.edge_select;
col_bone = G_draw.block.colorBoneActive;
}
col_wire = ctx->color.wire;
col_wire = G_draw.block.colorWire;
}
/* Draw root point if we are not connected to our parent. */
@@ -1648,7 +1508,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx,
(pchan->bone->parent && (pchan->bone->flag & BONE_CONNECTED)))) {
if (eBone) {
col_head = (eBone->flag & BONE_ROOTSEL) ? ctx->color.vertex_select : col_bone;
col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.colorVertexSelect : col_bone;
}
else {
col_head = col_bone;
@@ -1989,6 +1849,7 @@ static void draw_bone_name(ArmatureDrawContext *ctx,
bool highlight = (pchan && (arm->flag & ARM_POSEMODE) && (boneflag & BONE_SELECTED)) ||
(eBone && (eBone->flag & BONE_SELECTED));
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor4ubv(highlight ? TH_TEXT_HI : TH_TEXT, color);
float *head = pchan ? pchan->pose_head : eBone->head;
@@ -2289,28 +2150,6 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
ctx->const_wire = (((ob->base_flag & BASE_SELECTED) || (arm->drawtype == ARM_WIRE)) ?
1.5f :
((!is_filled || is_transparent) ? 1.0f : 0.0f));
/** See: 'set_pchan_color'*/
#define NO_ALPHA(c) (((c)[3] = 1.0f), (c))
UI_GetThemeColor3fv(TH_SELECT, NO_ALPHA(ctx->color.select));
UI_GetThemeColorShade3fv(TH_EDGE_SELECT, 60, NO_ALPHA(ctx->color.edge_select));
UI_GetThemeColorShade3fv(TH_EDGE_SELECT, -20, NO_ALPHA(ctx->color.bone_select));
UI_GetThemeColor3fv(TH_WIRE, NO_ALPHA(ctx->color.wire));
UI_GetThemeColor3fv(TH_WIRE_EDIT, NO_ALPHA(ctx->color.wire_edit));
UI_GetThemeColor3fv(TH_BONE_SOLID, NO_ALPHA(ctx->color.bone_solid));
UI_GetThemeColorBlendShade3fv(
TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, NO_ALPHA(ctx->color.bone_active_unselect));
UI_GetThemeColor3fv(TH_BONE_POSE, NO_ALPHA(ctx->color.bone_pose));
UI_GetThemeColor3fv(TH_BONE_POSE_ACTIVE, NO_ALPHA(ctx->color.bone_pose_active));
UI_GetThemeColorBlendShade3fv(
TH_WIRE, TH_BONE_POSE, 0.15f, 0, NO_ALPHA(ctx->color.bone_pose_active_unselect));
UI_GetThemeColor3fv(TH_TEXT_HI, NO_ALPHA(ctx->color.text_hi));
UI_GetThemeColor3fv(TH_TEXT, NO_ALPHA(ctx->color.text));
UI_GetThemeColor3fv(TH_VERTEX_SELECT, NO_ALPHA(ctx->color.vertex_select));
UI_GetThemeColor3fv(TH_VERTEX, NO_ALPHA(ctx->color.vertex));
#undef NO_ALPHA
}
void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob)

View File

@@ -0,0 +1,112 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2020, Blender Foundation.
*/
/** \file
* \ingroup draw_engine
*/
#include "DRW_render.h"
#include "UI_resources.h"
#include "overlay_private.h"
#include "draw_manager_text.h"
#define BG_SOLID 0
#define BG_GRADIENT 1
#define BG_CHECKER 2
void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
const RegionView3D *rv3d = draw_ctx->rv3d;
const BoundBox *bb = rv3d->clipbb;
const View3D *v3d = draw_ctx->v3d;
bool draw_clipping_bounds = (pd->clipping_state != 0);
{
float color_override[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int background_type;
if (!DRW_state_draw_background()) {
background_type = BG_CHECKER;
}
else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD && scene->world) {
background_type = BG_SOLID;
/* TODO(fclem) this is a scene refered linear color. we should convert
* it to display linear here. */
copy_v3_v3(color_override, &scene->world->horr);
color_override[3] = 1.0f;
}
else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) {
background_type = BG_SOLID;
copy_v3_v3(color_override, v3d->shading.background_color);
color_override[3] = 1.0f;
}
else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
background_type = BG_GRADIENT;
}
else {
background_type = BG_SOLID;
}
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND;
DRW_PASS_CREATE(psl->background_ps, state);
GPUShader *sh = OVERLAY_shader_background();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->background_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &dtxl->color);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec4_copy(grp, "colorOverride", color_override);
DRW_shgroup_uniform_int_copy(grp, "bgType", background_type);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
if (draw_clipping_bounds) {
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | DRW_STATE_CULL_BACK;
DRW_PASS_CREATE(psl->clipping_frustum_ps, state);
GPUShader *sh = OVERLAY_shader_clipbound();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->clipping_frustum_ps);
DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.colorClippingBorder);
DRW_shgroup_uniform_vec3(grp, "boundbox", &bb->vec[0][0], 8);
struct GPUBatch *cube = DRW_cache_cube_get();
DRW_shgroup_call(grp, cube, NULL);
}
else {
psl->clipping_frustum_ps = NULL;
}
}
void OVERLAY_background_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
if (DRW_state_is_fbo()) {
if (psl->clipping_frustum_ps) {
DRW_draw_pass(psl->clipping_frustum_ps);
}
DRW_draw_pass(psl->background_ps);
}
}

View File

@@ -56,7 +56,9 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
DRW_PASS_CREATE(psl->edit_text_overlay_ps, state | pd->clipping_state);
sh = OVERLAY_shader_uniform_color();
pd->edit_text_overlay_grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps);
pd->edit_text_overlay_grp = grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps);
DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
}
}

View File

@@ -144,6 +144,7 @@ static void OVERLAY_cache_init(void *vedata)
}
OVERLAY_antialiasing_cache_init(vedata);
OVERLAY_armature_cache_init(vedata);
OVERLAY_background_cache_init(vedata);
OVERLAY_extra_cache_init(vedata);
OVERLAY_facing_cache_init(vedata);
OVERLAY_grid_cache_init(vedata);
@@ -389,11 +390,25 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_Data *data = vedata;
OVERLAY_PrivateData *pd = data->stl->pd;
OVERLAY_FramebufferList *fbl = data->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (DRW_state_is_fbo()) {
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(dfbl->overlay_only_fb);
GPU_framebuffer_clear_color(dfbl->overlay_only_fb, clear_col);
}
OVERLAY_image_background_draw(vedata);
OVERLAY_background_draw(vedata);
OVERLAY_antialiasing_start(vedata);
DRW_view_set_active(NULL);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
OVERLAY_outline_draw(vedata);
if (DRW_state_is_fbo()) {
@@ -503,7 +518,6 @@ DrawEngineType draw_engine_overlay_type = {
&OVERLAY_cache_init,
&OVERLAY_cache_populate,
&OVERLAY_cache_finish,
NULL,
&OVERLAY_draw_scene,
NULL,
NULL,

View File

@@ -344,10 +344,13 @@ void OVERLAY_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
}
static void OVERLAY_bounds(
OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id, char boundtype, bool around_origin)
static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
Object *ob,
const float *color,
char boundtype,
bool around_origin)
{
float color[4], center[3], size[3], tmp[4][4], final_mat[4][4];
float center[3], size[3], tmp[4][4], final_mat[4][4];
BoundBox bb_local;
if (ob->type == OB_MBALL && !BKE_mball_is_basis(ob)) {
@@ -362,7 +365,6 @@ static void OVERLAY_bounds(
BKE_boundbox_init_from_minmax(bb, min, max);
}
UI_GetThemeColor4fv(theme_id, color);
BKE_boundbox_calc_size_aabb(bb, size);
if (around_origin) {
@@ -425,28 +427,28 @@ static void OVERLAY_bounds(
}
}
static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id)
static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
{
switch (ob->rigidbody_object->shape) {
case RB_SHAPE_BOX:
OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_BOX, true);
OVERLAY_bounds(cb, ob, color, OB_BOUND_BOX, true);
break;
case RB_SHAPE_SPHERE:
OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_SPHERE, true);
OVERLAY_bounds(cb, ob, color, OB_BOUND_SPHERE, true);
break;
case RB_SHAPE_CONE:
OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CONE, true);
OVERLAY_bounds(cb, ob, color, OB_BOUND_CONE, true);
break;
case RB_SHAPE_CYLINDER:
OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CYLINDER, true);
OVERLAY_bounds(cb, ob, color, OB_BOUND_CYLINDER, true);
break;
case RB_SHAPE_CAPSULE:
OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CAPSULE, true);
OVERLAY_bounds(cb, ob, color, OB_BOUND_CAPSULE, true);
break;
}
}
static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id)
static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color)
{
if (ob->data == NULL) {
return;
@@ -477,14 +479,12 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, int
BLI_assert(0);
}
float mat[4][4], color[4];
float mat[4][4];
size_to_mat4(mat, texcosize);
copy_v3_v3(mat[3], texcoloc);
mul_m4_m4m4(mat, ob->obmat, mat);
UI_GetThemeColor4fv(theme_id, color);
DRW_buffer_add_entry(cb->empty_cube, color, mat);
}
@@ -600,7 +600,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
float *color_p;
DRW_object_wire_theme_get(ob, view_layer, &color_p);
/* Remove the alpha. */
float color[4] = {color_p[0], color_p[1], color_p[2], 1.0f};
float color[4] = {UNPACK3(color_p), 1.0f};
/* Pack render data into object matrix. */
union {
float mat[4][4];
@@ -867,13 +867,13 @@ static void camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers *cb,
/* Index must start in 1, to mimic BKE_tracking_track_get_indexed. */
int track_index = 1;
float bundle_color_custom[3];
float *bundle_color_solid = G_draw.block.colorBundleSolid;
float *bundle_color_unselected = G_draw.block.colorWire;
uchar text_color_selected[4], text_color_unselected[4];
float bundle_color_unselected[4], bundle_color_solid[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor4ubv(TH_SELECT, text_color_selected);
UI_GetThemeColor4ubv(TH_TEXT, text_color_unselected);
UI_GetThemeColor4fv(TH_WIRE, bundle_color_unselected);
UI_GetThemeColor4fv(TH_BUNDLE_SOLID, bundle_color_solid);
float camera_mat[4][4], normal_mat[4][4];
BKE_tracking_get_camera_object_matrix(ob, camera_mat);
@@ -910,7 +910,10 @@ static void camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers *cb,
const float *bundle_color;
if (track->flag & TRACK_CUSTOMCOLOR) {
bundle_color = track->color;
/* Meh, hardcoded srgb transform here. */
/* TODO change the actual DNA color to be linear. */
srgb_to_linearrgb_v3_v3(bundle_color_custom, track->color);
bundle_color = bundle_color_custom;
}
else if (is_solid_bundle) {
bundle_color = bundle_color_solid;
@@ -1346,6 +1349,7 @@ static void OVERLAY_gpencil_color_names(Object *ob)
ViewLayer *view_layer = draw_ctx->view_layer;
int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
uchar color[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor4ubv(theme_id, color);
struct DRWTextStore *dt = DRW_text_cache_ensure();
@@ -1525,6 +1529,7 @@ static void OVERLAY_object_name(Object *ob, int theme_id)
{
struct DRWTextStore *dt = DRW_text_cache_ensure();
uchar color[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor4ubv(theme_id, color);
DRW_text_cache_add(dt,
@@ -1576,11 +1581,11 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
if (draw_bounds) {
OVERLAY_bounds(cb, ob, theme_id, ob->boundtype, false);
OVERLAY_bounds(cb, ob, color, ob->boundtype, false);
}
/* Helpers for when we're transforming origins. */
if (draw_xform) {
float color_xform[4] = {0.75f, 0.75f, 0.75f, 0.5f};
float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f};
DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat);
}
/* don't show object extras in set's */
@@ -1595,10 +1600,10 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
OVERLAY_object_name(ob, theme_id);
}
if (draw_texspace) {
OVERLAY_texture_space(cb, ob, theme_id);
OVERLAY_texture_space(cb, ob, color);
}
if (ob->rigidbody_object != NULL) {
OVERLAY_collision(cb, ob, theme_id);
OVERLAY_collision(cb, ob, color);
}
if (ob->dtx & OB_AXIS) {
DRW_buffer_add_entry(cb->empty_axes, color, ob->obmat);

View File

@@ -53,11 +53,8 @@ void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
OVERLAY_PrivateData *pd = vedata->stl->pd;
DRWState state;
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL;
DRW_PASS_CREATE(psl->image_background_under_ps, state);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->image_background_over_ps, state);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_PREMUL;
DRW_PASS_CREATE(psl->image_background_ps, state);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
DRW_PASS_CREATE(psl->image_empties_ps, state | pd->clipping_state);
@@ -330,29 +327,18 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
mul_m4_m4m4(mat, norm_obmat, mat);
const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0;
float color_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
float color_premult_alpha[4] = {bgpic->alpha, bgpic->alpha, bgpic->alpha, bgpic->alpha};
/* When drawing background we do 2 passes.
* - One alpha over, which works where background is visible.
* - One alpha under, works under partially visible objects. (only in cycles)
* This approach is not ideal and should be revisited.
**/
for (int i = 0; i < (is_foreground ? 1 : 2); i++) {
DRWPass *pass = is_foreground ? psl->image_foreground_ps :
((i == 0) ? psl->image_background_under_ps :
psl->image_background_over_ps);
GPUShader *sh = OVERLAY_shader_image();
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
float *color = (is_foreground || i == 1) ? color_alpha : color_premult_alpha;
DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
DRW_shgroup_uniform_bool_copy(grp, "imgLinear", !DRW_state_do_color_management());
DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
DRWPass *pass = is_foreground ? psl->image_foreground_ps : psl->image_background_ps;
GPUShader *sh = OVERLAY_shader_image();
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
DRW_shgroup_uniform_vec4_copy(grp, "color", color_premult_alpha);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
}
}
}
@@ -427,7 +413,6 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend);
DRW_shgroup_uniform_bool_copy(grp, "imgLinear", false);
DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT);
DRW_shgroup_uniform_vec4_copy(grp, "color", ob->color);
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
@@ -438,30 +423,25 @@ void OVERLAY_image_cache_finish(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
DRW_pass_sort_shgroup_reverse(psl->image_background_under_ps);
DRW_pass_sort_shgroup_z(psl->image_empties_blend_ps);
DRW_pass_sort_shgroup_z(psl->image_empties_front_ps);
DRW_pass_sort_shgroup_z(psl->image_empties_back_ps);
}
void OVERLAY_image_background_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
DRW_draw_pass(psl->image_background_ps);
DRW_draw_pass(psl->image_empties_back_ps);
}
void OVERLAY_image_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_FramebufferList *fbl = vedata->fbl;
const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DRW_view_set_active(pd->view_reference_images);
DRW_draw_pass(psl->image_background_over_ps);
if (DRW_state_is_fbo() && !DRW_pass_is_empty(psl->image_background_under_ps)) {
GPU_framebuffer_bind(dfbl->default_fb);
DRW_draw_pass(psl->image_background_under_ps);
GPU_framebuffer_bind(fbl->overlay_default_fb);
}
DRW_draw_pass(psl->image_empties_back_ps);
DRW_draw_pass(psl->image_empties_ps);
DRW_draw_pass(psl->image_empties_blend_ps);

View File

@@ -75,10 +75,10 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
MetaBall *mb = ob->data;
const float *color;
const float col_radius[4] = {0.63f, 0.19f, 0.19f, 1.0f}; /* 0x3030A0 */
const float col_radius_select[4] = {0.94f, 0.63f, 0.63f, 1.0f}; /* 0xA0A0F0 */
const float col_stiffness[4] = {0.19f, 0.63f, 0.19f, 1.0f}; /* 0x30A030 */
const float col_stiffness_select[4] = {0.63f, 0.94f, 0.63f, 1.0f}; /* 0xA0F0A0 */
const float *col_radius = G_draw.block.colorMballRadius;
const float *col_radius_select = G_draw.block.colorMballRadiusSelect;
const float *col_stiffness = G_draw.block.colorMballStiffness;
const float *col_stiffness_select = G_draw.block.colorMballStiffnessSelect;
int select_id = 0;
if (is_select) {

View File

@@ -174,6 +174,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
if (show_frame_no || (show_keyframes_no && show_keyframes)) {
int i;
uchar col[4], col_kf[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
UI_GetThemeColor3ubv(TH_TEXT_HI, col);
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col_kf);
col[3] = col_kf[3] = 255;

View File

@@ -55,6 +55,8 @@ typedef struct OVERLAY_PassList {
DRWPass *armature_ps[2];
DRWPass *armature_bone_select_ps;
DRWPass *armature_transp_ps;
DRWPass *background_ps;
DRWPass *clipping_frustum_ps;
DRWPass *edit_curve_wire_ps[2];
DRWPass *edit_curve_handle_ps;
DRWPass *edit_lattice_ps;
@@ -75,8 +77,7 @@ typedef struct OVERLAY_PassList {
DRWPass *extra_grid_ps;
DRWPass *facing_ps;
DRWPass *grid_ps;
DRWPass *image_background_under_ps;
DRWPass *image_background_over_ps;
DRWPass *image_background_ps;
DRWPass *image_empties_ps;
DRWPass *image_empties_back_ps;
DRWPass *image_empties_blend_ps;
@@ -402,6 +403,9 @@ void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata);
void OVERLAY_pose_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_pose_draw(OVERLAY_Data *vedata);
void OVERLAY_background_cache_init(OVERLAY_Data *vedata);
void OVERLAY_background_draw(OVERLAY_Data *vedata);
void OVERLAY_bone_instance_data_set_color_hint(BoneInstanceData *data, const float hint_color[4]);
void OVERLAY_bone_instance_data_set_color(BoneInstanceData *data, const float bone_color[4]);
@@ -481,6 +485,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_image_cache_finish(OVERLAY_Data *vedata);
void OVERLAY_image_draw(OVERLAY_Data *vedata);
void OVERLAY_image_background_draw(OVERLAY_Data *vedata);
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata);
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata);
@@ -532,6 +537,8 @@ GPUShader *OVERLAY_shader_armature_shape_wire(void);
GPUShader *OVERLAY_shader_armature_sphere(bool use_outline);
GPUShader *OVERLAY_shader_armature_stick(void);
GPUShader *OVERLAY_shader_armature_wire(void);
GPUShader *OVERLAY_shader_background(void);
GPUShader *OVERLAY_shader_clipbound(void);
GPUShader *OVERLAY_shader_depth_only(void);
GPUShader *OVERLAY_shader_edit_curve_handle(void);
GPUShader *OVERLAY_shader_edit_curve_point(void);

View File

@@ -47,6 +47,8 @@ extern char datatoc_armature_stick_frag_glsl[];
extern char datatoc_armature_stick_vert_glsl[];
extern char datatoc_armature_wire_frag_glsl[];
extern char datatoc_armature_wire_vert_glsl[];
extern char datatoc_background_frag_glsl[];
extern char datatoc_clipbound_vert_glsl[];
extern char datatoc_depth_only_vert_glsl[];
extern char datatoc_edit_curve_handle_geom_glsl[];
extern char datatoc_edit_curve_handle_vert_glsl[];
@@ -129,6 +131,8 @@ typedef struct OVERLAY_Shaders {
GPUShader *armature_sphere_solid;
GPUShader *armature_stick;
GPUShader *armature_wire;
GPUShader *background;
GPUShader *clipbound;
GPUShader *depth_only;
GPUShader *edit_curve_handle;
GPUShader *edit_curve_point;
@@ -198,6 +202,31 @@ GPUShader *OVERLAY_shader_antialiasing(void)
return sh_data->antialiasing;
}
GPUShader *OVERLAY_shader_background(void)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
if (!sh_data->background) {
sh_data->background = GPU_shader_create_from_arrays({
.vert = (const char *[]){datatoc_common_fullscreen_vert_glsl, NULL},
.frag =
(const char *[]){datatoc_common_globals_lib_glsl, datatoc_background_frag_glsl, NULL},
});
}
return sh_data->background;
}
GPUShader *OVERLAY_shader_clipbound(void)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
if (!sh_data->clipbound) {
sh_data->clipbound = GPU_shader_create_from_arrays({
.vert = (const char *[]){datatoc_common_view_lib_glsl, datatoc_clipbound_vert_glsl, NULL},
.frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
});
}
return sh_data->clipbound;
}
GPUShader *OVERLAY_shader_depth_only(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();

View File

@@ -20,7 +20,7 @@ void main()
/* Smooth lighting factor. */
const float s = 0.2; /* [0.0-0.5] range */
float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0);
fragColor.rgb = mix(finalStateColor, finalBoneColor, fac);
fragColor.rgb = mix(finalStateColor, finalBoneColor, fac * fac);
fragColor.a = alpha;
}
lineOutput = vec4(0.0);

View File

@@ -28,7 +28,7 @@ void main()
/* Smooth lighting factor. */
const float s = 0.2; /* [0.0-0.5] range */
float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0);
finalColor.rgb = mix(state_color.rgb, bone_color.rgb, fac);
finalColor.rgb = mix(state_color.rgb, bone_color.rgb, fac * fac);
finalColor.a = 1.0;
vec4 worldPosition = model_mat * vec4(pos, 1.0);

View File

@@ -64,7 +64,7 @@ void main()
/* Smooth lighting factor. */
const float s = 0.2; /* [0.0-0.5] range */
float fac = clamp((dot(n, l) * (1.0 - s)) + s, 0.0, 1.0);
fragColor.rgb = mix(finalStateColor, finalBoneColor, fac);
fragColor.rgb = mix(finalStateColor, finalBoneColor, fac * fac);
/* 2x2 dither pattern to smooth the lighting. */
float dither = (0.5 + dot(vec2(ivec2(gl_FragCoord.xy) & ivec2(1)), vec2(1.0, 2.0))) * 0.25;

View File

@@ -0,0 +1,73 @@
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
uniform int bgType;
uniform vec4 colorOverride;
in vec4 uvcoordsvar;
out vec4 fragColor;
#define BG_SOLID 0
#define BG_GRADIENT 1
#define BG_CHECKER 2
/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */
#define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0))
const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)),
vec4(P(12.0), P(4.0), P(14.0), P(6.0)),
vec4(P(3.0), P(11.0), P(1.0), P(9.0)),
vec4(P(15.0), P(7.0), P(13.0), P(5.0)));
float dither(void)
{
ivec2 co = ivec2(gl_FragCoord.xy) % 4;
return dither_mat4x4[co.x][co.y];
}
void main()
{
/* The blend equation is:
* resutl.rgb = SRC.rgb * (1 - DST.a) + DST.rgb * (SRC.a)
* result.a = SRC.a * 0 + DST.a * SRC.a
* This removes the alpha channel and put the background behind reference images
* while masking the reference images by the render alpha.
*/
float alpha = texture(colorBuffer, uvcoordsvar.st).a;
float depth = texture(depthBuffer, uvcoordsvar.st).r;
vec3 bg_col;
switch (bgType) {
case BG_SOLID:
bg_col = colorBackground.rgb;
break;
case BG_GRADIENT:
/* XXX do interpolation in a non-linear space to have a better visual result. */
vec3 col_high = pow(colorBackground.rgb, vec3(1.0 / 2.2));
vec3 col_low = pow(colorBackgroundGradient.rgb, vec3(1.0 / 2.2));
bg_col = mix(col_low, col_high, uvcoordsvar.t);
/* Convert back to linear. */
bg_col = pow(bg_col, vec3(2.2));
/* Dither to hide low precision buffer. (Could be improved) */
bg_col += dither();
break;
case BG_CHECKER:
float size = 8.0 * sizePixel;
ivec2 p = ivec2(floor(gl_FragCoord.xy / size));
bool check = mod(p.x, 2) == mod(p.y, 2);
bg_col = (check) ? colorCheckerLow.rgb : colorCheckerHigh.rgb;
break;
}
bg_col = mix(bg_col, colorOverride.rgb, colorOverride.a);
/* Mimic alpha under behavior. Result is premultiplied. */
fragColor = vec4(bg_col, 1.0) * (1.0 - alpha);
/* Special case: If the render is not transparent, do not clear alpha values. */
if (depth == 1.0 && alpha == 1.0) {
fragColor.a = 1.0;
}
}

View File

@@ -0,0 +1,13 @@
uniform vec3 boundbox[8];
void main()
{
vec3 world_pos = boundbox[gl_VertexID];
gl_Position = point_world_to_ndc(world_pos);
/* Result in a position at 1.0 (far plane). Small epsilon to avoid precision issue.
* This mimics the effect of infinite projection matrix
* (see http://www.terathon.com/gdc07_lengyel.pdf). */
gl_Position.z = gl_Position.w - 2.4e-7;
}

View File

@@ -2,7 +2,6 @@
uniform sampler2D imgTexture;
uniform bool imgPremultiplied;
uniform bool imgAlphaBlend;
uniform bool imgLinear;
uniform vec4 color;
in vec2 uvs;
@@ -13,12 +12,8 @@ void main()
{
vec2 uvs_clamped = clamp(uvs, 0.0, 1.0);
vec4 tex_color;
if (imgLinear) {
tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped);
}
else {
tex_color = texture_read_as_srgb(imgTexture, imgPremultiplied, uvs_clamped);
}
tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped);
fragColor = tex_color * color;
if (!imgAlphaBlend) {

View File

@@ -368,7 +368,6 @@ DrawEngineType draw_engine_select_type = {
&select_cache_init,
&select_cache_populate,
NULL,
NULL,
&select_draw_scene,
NULL,
NULL,

View File

@@ -1,5 +0,0 @@
vec3 background_color(WorldData world_data, float y)
{
return mix(world_data.background_color_low, world_data.background_color_high, y).xyz +
(world_data.background_dither_factor * bayer_dither_noise());
}

View File

@@ -5,17 +5,12 @@ struct LightData {
};
struct WorldData {
vec4 background_color_low;
vec4 background_color_high;
vec4 object_outline_color;
vec4 shadow_direction_vs;
LightData lights[4];
vec4 ambient_color;
int num_lights;
int matcap_orientation;
float background_alpha;
float curvature_ridge;
float curvature_valley;
float background_dither_factor;
int pad[2];
};

View File

@@ -13,11 +13,10 @@ layout(std140) uniform world_block
void main()
{
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
vec3 background = background_color(world_data, uv_viewport.y);
#ifndef V3D_SHADING_OBJECT_OUTLINE
fragColor = vec4(background, world_data.background_alpha);
fragColor = vec4(0.0);
#else /* !V3D_SHADING_OBJECT_OUTLINE */
@@ -25,16 +24,7 @@ void main()
uint object_id = texelFetch(objectId, texel, 0).r;
float object_outline = calculate_object_outline(objectId, texel, object_id);
if (object_outline == 0.0) {
fragColor = vec4(background, world_data.background_alpha);
}
else {
/* Do correct alpha blending. */
vec4 background_color = vec4(background, 1.0) * world_data.background_alpha;
vec4 outline_color = vec4(world_data.object_outline_color.rgb, 1.0);
fragColor = mix(outline_color, background_color, object_outline);
fragColor = vec4(fragColor.rgb / max(1e-8, fragColor.a), fragColor.a);
}
fragColor = vec4(world_data.object_outline_color.rgb, 1.0) * (1.0 - object_outline);
#endif /* !V3D_SHADING_OBJECT_OUTLINE */
}

View File

@@ -25,21 +25,11 @@ void main()
vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4);
#ifndef ALPHA_COMPOSITE
vec3 bg_color = background_color(world_data, uv_viewport.y);
fragColor = vec4(trans_color, 1.0 - trans_revealage);
bg_color = (world_data.background_alpha == 0.0) ? trans_color : bg_color;
vec4 color = mix(
vec4(trans_color, 1.0), vec4(bg_color, world_data.background_alpha), trans_revealage);
# ifdef V3D_SHADING_OBJECT_OUTLINE
#ifdef V3D_SHADING_OBJECT_OUTLINE
uint object_id = texelFetch(objectId, texel, 0).r;
float outline = calculate_object_outline(objectId, texel, object_id);
color = mix(vec4(world_data.object_outline_color.rgb, 1.0), color, outline);
# endif
fragColor = color;
#else
fragColor = vec4(trans_color, 1.0 - trans_revealage);
fragColor = mix(vec4(world_data.object_outline_color.rgb, 1.0), fragColor, outline);
#endif
}

View File

@@ -58,13 +58,12 @@ static void workbench_solid_cache_finish(void *vedata)
workbench_deferred_cache_finish(data);
}
static void workbench_solid_draw_background(void *vedata)
static void workbench_solid_draw_scene(void *vedata)
{
WORKBENCH_Data *data = vedata;
const int num_samples = workbench_num_viewport_rendering_iterations(data);
for (int sample = 0; sample < num_samples; sample++) {
workbench_deferred_draw_background(data);
workbench_deferred_draw_scene(data);
}
workbench_deferred_draw_finish(data);
@@ -113,8 +112,7 @@ DrawEngineType draw_engine_workbench_solid = {
&workbench_solid_cache_init,
&workbench_solid_cache_populate,
&workbench_solid_cache_finish,
&workbench_solid_draw_background,
NULL,
&workbench_solid_draw_scene,
&workbench_solid_view_update,
&workbench_solid_id_update,
&workbench_render_to_image,

View File

@@ -56,13 +56,12 @@ static void workbench_transparent_cache_finish(void *vedata)
workbench_forward_cache_finish(data);
}
static void workbench_transparent_draw_background(void *vedata)
static void workbench_transparent_draw_scene(void *vedata)
{
WORKBENCH_Data *data = vedata;
const int num_samples = workbench_num_viewport_rendering_iterations(data);
for (int sample = 0; sample < num_samples; sample++) {
workbench_forward_draw_background(data);
workbench_forward_draw_scene(data);
}
workbench_forward_draw_finish(data);
@@ -91,8 +90,7 @@ DrawEngineType draw_engine_workbench_transparent = {
&workbench_transparent_cache_init,
&workbench_transparent_cache_populate,
&workbench_transparent_cache_finish,
&workbench_transparent_draw_background,
NULL,
&workbench_transparent_draw_scene,
&workbench_transparent_view_update,
NULL,
NULL,

View File

@@ -99,8 +99,27 @@ static void workbench_world_data_update_shadow_direction_vs(WORKBENCH_PrivateDat
/* Shadow direction. */
mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, light_direction);
}
/* \} */
void workbench_clear_color_get(float color[4])
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
if (!DRW_state_is_scene_render() || !DRW_state_draw_background()) {
zero_v4(color);
}
else if (scene->world) {
copy_v3_v3(color, &scene->world->horr);
color[3] = 1.0f;
}
else {
zero_v3(color);
color[3] = 1.0f;
}
}
void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info)
{
effect_info->jitter_index = 0;
@@ -152,39 +171,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
WORKBENCH_UBO_World *wd = &wpd->world_data;
wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
wd->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
if ((scene->world != NULL) &&
(!v3d || (v3d && ((v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) ||
(v3d->shading.type == OB_RENDER))))) {
copy_v3_v3(wd->background_color_low, &scene->world->horr);
copy_v3_v3(wd->background_color_high, &scene->world->horr);
}
else if (v3d && (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT)) {
copy_v3_v3(wd->background_color_low, v3d->shading.background_color);
copy_v3_v3(wd->background_color_high, v3d->shading.background_color);
}
else if (v3d) {
UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK,
wd->background_color_low);
UI_GetThemeColor3fv(TH_BACK, wd->background_color_high);
/* XXX: Really quick conversion to avoid washed out background.
* Needs to be addressed properly (color managed using ocio). */
if (wpd->use_color_management) {
srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
}
else {
copy_v3_v3(wd->background_color_high, wd->background_color_high);
copy_v3_v3(wd->background_color_low, wd->background_color_low);
}
}
else {
zero_v3(wd->background_color_low);
zero_v3(wd->background_color_high);
}
wd->background_dither_factor = workbench_background_dither_factor(wpd);
studiolight_update_world(wpd, wpd->studio_light, wd);
@@ -197,13 +183,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
/* Will be NULL when rendering. */
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
wpd->world_clip_planes = rv3d->clip;
UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, wpd->world_clip_planes_color);
if (wpd->use_color_management) {
srgb_to_linearrgb_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
}
else {
copy_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color);
}
}
else {
wpd->world_clip_planes = NULL;
@@ -298,5 +277,4 @@ void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
}
DRW_UBO_FREE_SAFE(wpd->dof_ubo);
GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch);
}

View File

@@ -105,7 +105,6 @@ extern char datatoc_workbench_shadow_geom_glsl[];
extern char datatoc_workbench_shadow_caps_geom_glsl[];
extern char datatoc_workbench_shadow_debug_frag_glsl[];
extern char datatoc_workbench_background_lib_glsl[];
extern char datatoc_workbench_cavity_lib_glsl[];
extern char datatoc_workbench_common_lib_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
@@ -122,7 +121,6 @@ static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
if (!FLAT_ENABLED(wpd)) {
BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
@@ -260,7 +258,6 @@ static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd)
const char *defines = (index) ? "#define V3D_SHADING_OBJECT_OUTLINE\n" : NULL;
char *frag = BLI_string_joinN(datatoc_workbench_data_lib_glsl,
datatoc_workbench_common_lib_glsl,
datatoc_workbench_background_lib_glsl,
datatoc_workbench_object_outline_lib_glsl,
datatoc_workbench_deferred_background_frag_glsl);
e_data.background_sh[index] = DRW_shader_create_fullscreen(frag, defines);
@@ -481,8 +478,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
const eGPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F :
GPU_R11F_G11F_B10F;
const eGPUTextureFormat comp_tex_format = GPU_RGBA16F;
const eGPUTextureFormat col_tex_format = workbench_color_texture_format(wpd);
const eGPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8;
@@ -718,8 +714,12 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
/* Background Pass */
{
psl->background_pass = DRW_pass_create("Background",
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
if (DRW_state_is_scene_render()) {
/* Composite the scene over cleared background. */
state |= DRW_STATE_BLEND_ALPHA_PREMUL;
}
psl->background_pass = DRW_pass_create("Background", state);
grp = DRW_shgroup_create(wpd->background_sh, psl->background_pass);
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
@@ -727,14 +727,6 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
}
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
if (RV3D_CLIPPING_ENABLED(draw_ctx->v3d, draw_ctx->rv3d)) {
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
grp = DRW_shgroup_create(shader, psl->background_pass);
wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL);
DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
}
}
/* Deferred Mix Pass */
@@ -1269,30 +1261,6 @@ void workbench_deferred_cache_finish(WORKBENCH_Data *vedata)
}
}
void workbench_deferred_draw_background(WORKBENCH_Data *vedata)
{
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_FramebufferList *fbl = vedata->fbl;
WORKBENCH_PrivateData *wpd = stl->g_data;
const float clear_depth = 1.0f;
const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
uint clear_stencil = 0x00;
DRW_stats_group_start("Clear Background");
if (OBJECT_ID_PASS_ENABLED(wpd)) {
/* From all the color buffers, only object id needs to be cleared. */
GPU_framebuffer_bind(fbl->id_clear_fb);
GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_color);
}
GPU_framebuffer_bind(fbl->prepass_fb);
int clear_bits = GPU_DEPTH_BIT;
SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil);
DRW_stats_group_end();
}
void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
{
WORKBENCH_PassList *psl = vedata->psl;
@@ -1306,8 +1274,21 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
workbench_taa_draw_scene_start(vedata);
}
/* clear in background */
const float clear_depth = 1.0f;
const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
uint clear_stencil = 0x00;
int clear_bits = GPU_DEPTH_BIT;
SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
if (OBJECT_ID_PASS_ENABLED(wpd)) {
/* From all the color buffers, only object id needs to be cleared. */
GPU_framebuffer_bind(fbl->id_clear_fb);
GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_col);
}
GPU_framebuffer_bind(fbl->prepass_fb);
GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_col, clear_depth, clear_stencil);
DRW_draw_pass(psl->prepass_pass);
DRW_draw_pass(psl->prepass_hair_pass);
@@ -1334,6 +1315,13 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->cavity_pass);
}
if (DRW_state_is_scene_render()) {
float clear_color[4];
workbench_clear_color_get(clear_color);
GPU_framebuffer_bind(fbl->composite_fb);
GPU_framebuffer_clear_color(fbl->composite_fb, clear_color);
}
if (SHADOW_ENABLED(wpd)) {
#ifdef DEBUG_SHADOW_VOLUME
GPU_framebuffer_bind(fbl->composite_fb);

View File

@@ -22,6 +22,8 @@
#include "ED_screen.h"
#include "draw_color_management.h"
#include "workbench_private.h"
void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx)
@@ -53,16 +55,9 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx)
}
}
static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *wpd)
static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *UNUSED(wpd))
{
if (DRW_state_do_color_management()) {
/* Display space result for viewport. */
DRW_transform_to_display(tx, wpd->use_color_render_settings, wpd->use_color_render_settings);
}
else {
/* Linear result for render. */
DRW_transform_none(tx);
}
DRW_transform_none(tx);
}
void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx)

View File

@@ -72,7 +72,6 @@ extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
extern char datatoc_workbench_background_lib_glsl[];
extern char datatoc_workbench_checkerboard_depth_frag_glsl[];
extern char datatoc_workbench_object_outline_lib_glsl[];
extern char datatoc_workbench_curvature_lib_glsl[];
@@ -128,7 +127,6 @@ static char *workbench_build_forward_composite_frag(void)
BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_forward_composite_frag_glsl);
@@ -367,8 +365,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F :
GPU_R11F_G11F_B10F;
const eGPUTextureFormat comp_tex_format = GPU_RGBA16F;
e_data.object_id_tx = DRW_texture_pool_query_2d(
size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
@@ -420,6 +417,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
/* Composite */
{
int state = DRW_STATE_WRITE_COLOR;
if (DRW_state_is_scene_render()) {
/* Composite the scene over cleared background. */
state |= DRW_STATE_BLEND_ALPHA_PREMUL;
}
psl->composite_pass = DRW_pass_create("Composite", state);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
@@ -433,19 +434,6 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
/* TODO(campbell): displays but masks geometry,
* only use with wire or solid-without-xray for now. */
if ((wpd->shading.type != OB_WIRE && !XRAY_FLAG_ENABLED(wpd)) &&
RV3D_CLIPPING_ENABLED(draw_ctx->v3d, draw_ctx->rv3d)) {
psl->background_pass = DRW_pass_create("Background",
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND);
grp = DRW_shgroup_create(shader, psl->background_pass);
wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d);
DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL);
DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1);
}
{
workbench_aa_create_pass(vedata, &e_data.transparent_accum_tx);
}
@@ -783,16 +771,6 @@ void workbench_forward_cache_finish(WORKBENCH_Data *UNUSED(vedata))
{
}
void workbench_forward_draw_background(WORKBENCH_Data *UNUSED(vedata))
{
const float clear_depth = 1.0f;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DRW_stats_group_start("Clear depth");
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_depth_stencil(dfbl->default_fb, clear_depth, 0xFF);
DRW_stats_group_end();
}
void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
{
WORKBENCH_PassList *psl = vedata->psl;
@@ -827,6 +805,13 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
/* Composite */
GPU_framebuffer_bind(fbl->composite_fb);
if (DRW_state_is_scene_render()) {
float clear_color[4];
workbench_clear_color_get(clear_color);
GPU_framebuffer_clear_color(fbl->composite_fb, clear_color);
}
DRW_draw_pass(psl->composite_pass);
DRW_draw_pass(psl->volume_pass);

View File

@@ -183,19 +183,14 @@ typedef struct WORKBENCH_UBO_Light {
} WORKBENCH_UBO_Light;
typedef struct WORKBENCH_UBO_World {
float background_color_low[4];
float background_color_high[4];
float object_outline_color[4];
float shadow_direction_vs[4];
WORKBENCH_UBO_Light lights[4];
float ambient_color[4];
int num_lights;
int matcap_orientation;
float background_alpha;
float curvature_ridge;
float curvature_valley;
float background_dither_factor;
int pad[2];
} WORKBENCH_UBO_World;
BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
@@ -249,8 +244,6 @@ typedef struct WORKBENCH_PrivateData {
bool is_playback;
float (*world_clip_planes)[4];
struct GPUBatch *world_clip_planes_batch;
float world_clip_planes_color[4];
/* Volumes */
bool volumes_do;
@@ -434,26 +427,15 @@ BLI_INLINE eGPUTextureFormat workbench_color_texture_format(const WORKBENCH_Priv
TEXTURE_DRAWING_ENABLED(wpd)) {
result = GPU_RGBA16F;
}
else if (workbench_is_in_vertex_paint_mode() || VERTEX_COLORS_ENABLED(wpd)) {
else {
result = GPU_RGBA16;
}
else {
result = GPU_RGBA8;
}
return result;
}
BLI_INLINE bool workbench_background_dither_factor(const WORKBENCH_PrivateData *wpd)
{
/* Only apply dithering when rendering on a RGBA8 texture.
* The dithering will remove banding when using a gradient as background */
return workbench_color_texture_format(wpd) == GPU_RGBA8;
}
/* workbench_deferred.c */
void workbench_deferred_engine_init(WORKBENCH_Data *vedata);
void workbench_deferred_engine_free(void);
void workbench_deferred_draw_background(WORKBENCH_Data *vedata);
void workbench_deferred_draw_scene(WORKBENCH_Data *vedata);
void workbench_deferred_draw_finish(WORKBENCH_Data *vedata);
void workbench_deferred_cache_init(WORKBENCH_Data *vedata);
@@ -463,7 +445,6 @@ void workbench_deferred_cache_finish(WORKBENCH_Data *vedata);
/* workbench_forward.c */
void workbench_forward_engine_init(WORKBENCH_Data *vedata);
void workbench_forward_engine_free(void);
void workbench_forward_draw_background(WORKBENCH_Data *vedata);
void workbench_forward_draw_scene(WORKBENCH_Data *vedata);
void workbench_forward_draw_finish(WORKBENCH_Data *vedata);
void workbench_forward_cache_init(WORKBENCH_Data *vedata);
@@ -567,6 +548,7 @@ void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info);
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
void workbench_private_data_get_light_direction(float r_light_direction[3]);
void workbench_clear_color_get(float color[4]);
/* workbench_volume.c */
void workbench_volume_engine_init(void);

View File

@@ -159,7 +159,6 @@ void workbench_render(WORKBENCH_Data *data,
if (RE_engine_test_break(engine)) {
break;
}
workbench_deferred_draw_background(data);
workbench_deferred_draw_scene(data);
}
@@ -186,7 +185,6 @@ void workbench_render(WORKBENCH_Data *data,
break;
}
workbench_forward_draw_background(data);
workbench_forward_draw_scene(data);
}

View File

@@ -122,7 +122,6 @@ typedef struct DrawEngineType {
void (*cache_populate)(void *vedata, struct Object *ob);
void (*cache_finish)(void *vedata);
void (*draw_background)(void *vedata);
void (*draw_scene)(void *vedata);
void (*view_update)(void *vedata);
@@ -138,13 +137,16 @@ typedef struct DrawEngineType {
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
struct GPUFrameBuffer *default_fb;
struct GPUFrameBuffer *overlay_fb;
struct GPUFrameBuffer *in_front_fb;
struct GPUFrameBuffer *color_only_fb;
struct GPUFrameBuffer *depth_only_fb;
struct GPUFrameBuffer *overlay_only_fb;
} DefaultFramebufferList;
typedef struct DefaultTextureList {
struct GPUTexture *color;
struct GPUTexture *color_overlay;
struct GPUTexture *depth;
struct GPUTexture *depth_in_front;
} DefaultTextureList;
@@ -209,14 +211,6 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo);
} \
} while (0)
void DRW_transform_to_display(struct GPUTexture *tex,
bool use_view_transform,
bool use_render_settings);
void DRW_transform_none(struct GPUTexture *tex);
void DRW_multisamples_resolve(struct GPUTexture *src_depth,
struct GPUTexture *src_color,
bool use_depth);
/* Shaders */
struct GPUShader *DRW_shader_create(const char *vert,
const char *geom,
@@ -302,7 +296,7 @@ typedef enum {
DRW_STATE_BLEND_ALPHA = (1 << 18),
/** Use that if color is already premult by alpha. */
DRW_STATE_BLEND_ALPHA_PREMUL = (1 << 19),
DRW_STATE_BLEND_ALPHA_UNDER_PREMUL = (1 << 20),
DRW_STATE_BLEND_BACKGROUND = (1 << 20),
DRW_STATE_BLEND_OIT = (1 << 21),
DRW_STATE_BLEND_MUL = (1 << 22),
/** Use dual source blending. WARNING: Only one color buffer allowed. */

View File

@@ -679,20 +679,30 @@ GPUBatch *DRW_cache_cube_get(void)
if (!SHC.drw_cube) {
GPUVertFormat format = extra_vert_format();
const int tri_len = ARRAY_SIZE(bone_box_solid_tris);
const int vert_len = ARRAY_SIZE(bone_box_verts);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bone_box_solid_tris) * 3);
GPU_vertbuf_data_alloc(vbo, vert_len);
GPUIndexBufBuilder elb;
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len);
int v = 0;
for (int i = 0; i < ARRAY_SIZE(bone_box_solid_tris); i++) {
for (int a = 0; a < 3; a++) {
float x = bone_box_verts[bone_box_solid_tris[i][a]][0];
float y = bone_box_verts[bone_box_solid_tris[i][a]][1] * 2.0f - 1.0f;
float z = bone_box_verts[bone_box_solid_tris[i][a]][2];
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, VCLASS_EMPTY_SCALED});
}
for (int i = 0; i < vert_len; i++) {
float x = bone_box_verts[i][0];
float y = bone_box_verts[i][1] * 2.0f - 1.0f;
float z = bone_box_verts[i][2];
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, VCLASS_EMPTY_SCALED});
}
SHC.drw_cube = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
for (int i = 0; i < tri_len; i++) {
const uint *tri_indices = bone_box_solid_tris[i];
GPU_indexbuf_add_tri_verts(&elb, tri_indices[0], tri_indices[1], tri_indices[2]);
}
SHC.drw_cube = GPU_batch_create_ex(
GPU_PRIM_TRIS, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
}
return SHC.drw_cube;
}

View File

@@ -0,0 +1,63 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2020, Blender Foundation.
*/
/** \file
* \ingroup draw
*/
#include <stdio.h>
#include "draw_manager.h"
#include "DRW_render.h"
#include "GPU_batch.h"
#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "GPU_texture.h"
#include "BKE_colortools.h"
#include "IMB_colormanagement.h"
#include "draw_color_management.h"
/* -------------------------------------------------------------------- */
/** \name Color Management
* \{ */
/* Draw texture to framebuffer without any color transforms */
void DRW_transform_none(GPUTexture *tex)
{
drw_state_set(DRW_STATE_WRITE_COLOR);
GPU_matrix_identity_set();
GPU_matrix_identity_projection_set();
/* Draw as texture for final render (without immediate mode). */
GPUBatch *geom = DRW_cache_fullscreen_quad_get();
GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR);
GPU_batch_uniform_4f(geom, "color", 1.0f, 1.0f, 1.0f, 1.0f);
GPU_batch_uniform_1i(geom, "image", 0);
GPU_texture_bind(tex, 0);
GPU_batch_draw(geom);
GPU_texture_unbind(tex);
}
/** \} */

View File

@@ -0,0 +1,28 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright 2020, Blender Foundation.
*/
/** \file
* \ingroup draw
*/
#ifndef __DRAW_COLOR_MANAGEMENT_H__
#define __DRAW_COLOR_MANAGEMENT_H__
void DRW_transform_none(struct GPUTexture *tex);
#endif /* __DRAW_COLOR_MANAGEMENT_H__ */

View File

@@ -88,6 +88,10 @@ void DRW_globals_update(void)
UI_GetThemeColor4fv(TH_FACE_DOT, gb->colorFaceDot);
UI_GetThemeColor4fv(TH_SKIN_ROOT, gb->colorSkinRoot);
UI_GetThemeColor4fv(TH_BACK, gb->colorBackground);
UI_GetThemeColor4fv(TH_BACK_GRAD, gb->colorBackgroundGradient);
UI_COLOR_RGBA_FROM_U8(0x26, 0x26, 0x26, 0xFF, gb->colorCheckerLow);
UI_COLOR_RGBA_FROM_U8(0x33, 0x33, 0x33, 0xFF, gb->colorCheckerHigh);
UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, gb->colorClippingBorder);
/* Custom median color to slightly affect the edit mesh colors. */
interp_v4_v4v4(gb->colorEditMeshMiddle, gb->colorVertexSelect, gb->colorWireEdit, 0.35f);
@@ -108,6 +112,26 @@ void DRW_globals_update(void)
zero_v4(gb->colorFaceFreestyle);
#endif
UI_GetThemeColor4fv(TH_TEXT, gb->colorText);
UI_GetThemeColor4fv(TH_TEXT_HI, gb->colorTextHi);
/* Bone colors */
UI_GetThemeColor4fv(TH_BONE_POSE, gb->colorBonePose);
UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, gb->colorBonePoseActive);
UI_GetThemeColorShade4fv(TH_EDGE_SELECT, 60, gb->colorBoneActive);
UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, gb->colorBoneSelect);
UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, gb->colorBonePoseActiveUnsel);
UI_GetThemeColorBlendShade3fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, gb->colorBoneActiveUnsel);
UI_COLOR_RGBA_FROM_U8(255, 150, 0, 80, gb->colorBonePoseTarget);
UI_COLOR_RGBA_FROM_U8(255, 255, 0, 80, gb->colorBonePoseIK);
UI_COLOR_RGBA_FROM_U8(200, 255, 0, 80, gb->colorBonePoseSplineIK);
UI_COLOR_RGBA_FROM_U8(0, 255, 120, 80, gb->colorBonePoseConstraint);
UI_GetThemeColor4fv(TH_BONE_SOLID, gb->colorBoneSolid);
UI_GetThemeColor4fv(TH_BONE_LOCKED_WEIGHT, gb->colorBoneLocked);
copy_v4_fl4(gb->colorBoneIKLine, 0.8f, 0.5f, 0.0f, 1.0f);
copy_v4_fl4(gb->colorBoneIKLineNoTarget, 0.8f, 0.8f, 0.2f, 1.0f);
copy_v4_fl4(gb->colorBoneIKLineSpline, 0.8f, 0.8f, 0.2f, 1.0f);
/* Curve */
UI_GetThemeColor4fv(TH_HANDLE_FREE, gb->colorHandleFree);
UI_GetThemeColor4fv(TH_HANDLE_AUTO, gb->colorHandleAuto);
@@ -125,10 +149,14 @@ void DRW_globals_update(void)
UI_GetThemeColor4fv(TH_NURB_SEL_VLINE, gb->colorNurbSelVline);
UI_GetThemeColor4fv(TH_ACTIVE_SPLINE, gb->colorActiveSpline);
UI_GetThemeColor4fv(TH_BONE_POSE, gb->colorBonePose);
UI_GetThemeColor4fv(TH_CFRAME, gb->colorCurrentFrame);
/* Metaball */
UI_COLOR_RGBA_FROM_U8(0xA0, 0x30, 0x30, 0xFF, gb->colorMballRadius);
UI_COLOR_RGBA_FROM_U8(0xF0, 0xA0, 0xA0, 0xFF, gb->colorMballRadiusSelect);
UI_COLOR_RGBA_FROM_U8(0x30, 0xA0, 0x30, 0xFF, gb->colorMballStiffness);
UI_COLOR_RGBA_FROM_U8(0xA0, 0xF0, 0xA0, 0xFF, gb->colorMballStiffnessSelect);
/* Grid */
UI_GetThemeColorShade4fv(TH_GRID, 10, gb->colorGrid);
/* emphasise division lines lighter instead of darker, if background is darker than grid */
@@ -173,7 +201,7 @@ void DRW_globals_update(void)
invert_v2(gb->sizeViewportInv);
/* Color management. */
if (!DRW_state_do_color_management()) {
{
float *color = gb->UBO_FIRST_COLOR;
do {
/* TODO more accurate transform. */

View File

@@ -79,6 +79,10 @@ typedef struct GlobalsUboStorage {
float colorLightNoAlpha[4];
float colorBackground[4];
float colorBackgroundGradient[4];
float colorCheckerLow[4];
float colorCheckerHigh[4];
float colorClippingBorder[4];
float colorEditMeshMiddle[4];
float colorHandleFree[4];
@@ -98,6 +102,30 @@ typedef struct GlobalsUboStorage {
float colorActiveSpline[4];
float colorBonePose[4];
float colorBonePoseActive[4];
float colorBonePoseActiveUnsel[4];
float colorBonePoseConstraint[4];
float colorBonePoseIK[4];
float colorBonePoseSplineIK[4];
float colorBonePoseTarget[4];
float colorBoneSolid[4];
float colorBoneLocked[4];
float colorBoneActive[4];
float colorBoneActiveUnsel[4];
float colorBoneSelect[4];
float colorBoneIKLine[4];
float colorBoneIKLineNoTarget[4];
float colorBoneIKLineSpline[4];
float colorText[4];
float colorTextHi[4];
float colorBundleSolid[4];
float colorMballRadius[4];
float colorMballRadiusSelect[4];
float colorMballStiffness[4];
float colorMballStiffnessSelect[4];
float colorCurrentFrame[4];

View File

@@ -80,6 +80,7 @@
#include "draw_manager_text.h"
#include "draw_manager_profiling.h"
#include "draw_color_management.h"
/* only for callbacks */
#include "draw_cache_impl.h"
@@ -131,33 +132,6 @@ static void drw_state_ensure_not_reused(DRWManager *dst)
}
#endif
/* -------------------------------------------------------------------- */
void DRW_draw_callbacks_pre_scene(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
}
void DRW_draw_callbacks_post_scene(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
}
struct DRWTextStore *DRW_text_cache_ensure(void)
{
BLI_assert(DST.text_store_p);
if (*DST.text_store_p == NULL) {
*DST.text_store_p = DRW_text_cache_create();
}
return *DST.text_store_p;
}
/* -------------------------------------------------------------------- */
/** \name Settings
* \{ */
@@ -299,199 +273,38 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
/** \name Color Management
* \{ */
/* Use color management profile to draw texture to framebuffer */
void DRW_transform_to_display(GPUTexture *tex, bool use_view_transform, bool use_render_settings)
static void drw_viewport_colormanagement_set(void)
{
drw_state_set(DRW_STATE_WRITE_COLOR);
Scene *scene = DST.draw_ctx.scene;
View3D *v3d = DST.draw_ctx.v3d;
GPUVertFormat *vert_format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
ColorManagedDisplaySettings *display_settings = &scene->display_settings;
ColorManagedViewSettings view_settings;
float dither = 0.0f;
const float dither = 1.0f;
bool use_render_settings = v3d && (v3d->shading.type == OB_RENDER);
bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
bool use_ocio = false;
/* Should we apply the view transform */
if (DRW_state_do_color_management()) {
Scene *scene = DST.draw_ctx.scene;
ColorManagedDisplaySettings *display_settings = &scene->display_settings;
ColorManagedViewSettings view_settings;
if (use_render_settings) {
/* Use full render settings, for renders with scene lighting. */
view_settings = scene->view_settings;
}
else if (use_view_transform) {
/* Use only view transform + look and nothing else for lookdev without
* scene lighting, as exposure depends on scene light intensity. */
BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
STRNCPY(view_settings.look, scene->view_settings.look);
}
else {
/* For workbench use only default view transform in configuration,
* using no scene settings. */
BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
}
use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(
&view_settings, display_settings, NULL, dither, false);
if (use_render_settings) {
/* Use full render settings, for renders with scene lighting. */
view_settings = scene->view_settings;
dither = scene->r.dither_intensity;
}
if (!use_ocio) {
/* View transform is already applied for offscreen, don't apply again, see: T52046 */
if (DST.options.is_image_render && !DST.options.is_scene_render) {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
else {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
}
immUniform1i("image", 0);
}
GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
float mat[4][4];
unit_m4(mat);
immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
/* Full screen triangle */
immBegin(GPU_PRIM_TRIS, 3);
immAttr2f(texco, 0.0f, 0.0f);
immVertex2f(pos, -1.0f, -1.0f);
immAttr2f(texco, 2.0f, 0.0f);
immVertex2f(pos, 3.0f, -1.0f);
immAttr2f(texco, 0.0f, 2.0f);
immVertex2f(pos, -1.0f, 3.0f);
immEnd();
GPU_texture_unbind(tex);
if (use_ocio) {
IMB_colormanagement_finish_glsl_draw();
else if (use_view_transform) {
/* Use only view transform + look and nothing else for lookdev without
* scene lighting, as exposure depends on scene light intensity. */
BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
STRNCPY(view_settings.look, scene->view_settings.look);
dither = scene->r.dither_intensity;
}
else {
immUnbindProgram();
}
}
/* Draw texture to framebuffer without any color transforms */
void DRW_transform_none(GPUTexture *tex)
{
drw_state_set(DRW_STATE_WRITE_COLOR);
/* Draw as texture for final render (without immediate mode). */
GPUBatch *geom = DRW_cache_fullscreen_quad_get();
GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR);
GPU_texture_bind(tex, 0);
const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GPU_batch_uniform_4fv(geom, "color", white);
float mat[4][4];
unit_m4(mat);
GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
GPU_batch_program_use_begin(geom);
GPU_batch_bind(geom);
GPU_batch_draw_advanced(geom, 0, 0, 0, 0);
GPU_batch_program_use_end(geom);
GPU_texture_unbind(tex);
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Multisample Resolve
* \{ */
/**
* Use manual multisample resolve pass.
* Much quicker than blitting back and forth.
* Assume destination fb is bound.
*/
void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth)
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL;
if (use_depth) {
state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
}
drw_state_set(state);
int samples = GPU_texture_samples(src_depth);
BLI_assert(samples > 0);
BLI_assert(GPU_texture_samples(src_color) == samples);
GPUBatch *geom = DRW_cache_fullscreen_quad_get();
int builtin;
if (use_depth) {
switch (samples) {
case 2:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
break;
case 4:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST;
break;
case 8:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST;
break;
case 16:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST;
break;
default:
BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
break;
}
}
else {
switch (samples) {
case 2:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
break;
case 4:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4;
break;
case 8:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8;
break;
case 16:
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16;
break;
default:
BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
break;
}
/* For workbench use only default view transform in configuration,
* using no scene settings. */
BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
}
GPU_batch_program_set_builtin(geom, builtin);
if (use_depth) {
GPU_texture_bind(src_depth, 0);
GPU_batch_uniform_1i(geom, "depthMulti", 0);
}
GPU_texture_bind(src_color, 1);
GPU_batch_uniform_1i(geom, "colorMulti", 1);
float mat[4][4];
unit_m4(mat);
GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
/* avoid gpuMatrix calls */
GPU_batch_program_use_begin(geom);
GPU_batch_bind(geom);
GPU_batch_draw_advanced(geom, 0, 0, 0, 0);
GPU_batch_program_use_end(geom);
GPU_viewport_colorspace_set(DST.viewport, &view_settings, display_settings, dither);
}
/** \} */
@@ -1204,39 +1017,6 @@ static void drw_engines_cache_finish(void)
MEM_freeN(DST.vedata_array);
}
static bool drw_engines_draw_background(void)
{
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
if (engine->draw_background) {
PROFILE_START(stime);
DRW_stats_group_start(engine->idname);
engine->draw_background(data);
DRW_stats_group_end();
PROFILE_END_UPDATE(data->background_time, stime);
return true;
}
}
/* No draw engines draw the background. We clear the background.
* We draw the background after drawing of the scene so the camera background
* images can be drawn using ALPHA Under. Otherwise the background always
* interfered with the alpha blending. */
DRW_clear_background();
return false;
}
static void drw_draw_background_alpha_under(void)
{
/* No draw_background found, doing default background */
const bool do_alpha_checker = !DRW_state_draw_background();
DRW_draw_background(do_alpha_checker);
}
static void drw_engines_draw_scene(void)
{
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
@@ -1492,6 +1272,112 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Callbacks
* \{ */
void DRW_draw_callbacks_pre_scene(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
if (DST.draw_ctx.evil_C) {
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
DRW_state_reset();
}
}
void DRW_draw_callbacks_post_scene(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
ARegion *ar = DST.draw_ctx.ar;
View3D *v3d = DST.draw_ctx.v3d;
Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
const bool do_annotations = (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
if (DST.draw_ctx.evil_C) {
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DRW_state_reset();
GPU_framebuffer_bind(dfbl->overlay_fb);
/* Disable sRGB encoding from the fixed function pipeline since all the drawing in this
* function is done with sRGB color. Avoid double transform. */
glDisable(GL_FRAMEBUFFER_SRGB);
/* annotations - temporary drawing buffer (3d space) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (do_annotations) {
GPU_depth_test(false);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true);
GPU_depth_test(true);
}
drw_debug_draw();
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
GPU_depth_test(false);
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
/* Callback can be nasty and do whatever they want with the state.
* Don't trust them! */
DRW_state_reset();
/* needed so gizmo isn't obscured */
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
GPU_depth_test(false);
DRW_draw_gizmo_3d();
}
GPU_depth_test(false);
drw_engines_draw_text();
DRW_draw_region_info();
/* annotations - temporary drawing buffer (screenspace) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
GPU_depth_test(false);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
}
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
/* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
* 'DRW_draw_region_info' sets the projection in pixel-space. */
GPU_depth_test(false);
DRW_draw_gizmo_2d();
}
if (G.debug_value > 20 && G.debug_value < 30) {
GPU_depth_test(false);
/* local coordinate visible rect inside region, to accommodate overlapping ui */
const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
DRW_stats_draw(rect);
}
GPU_depth_test(true);
}
}
struct DRWTextStore *DRW_text_cache_ensure(void)
{
BLI_assert(DST.text_store_p);
if (*DST.text_store_p == NULL) {
*DST.text_store_p = DRW_text_cache_create();
}
return *DST.text_store_p;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Main Draw Loops (DRW_draw)
* \{ */
@@ -1533,8 +1419,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
DST.draw_ctx.evil_C = evil_C;
DST.viewport = viewport;
@@ -1554,7 +1438,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
.evil_C = DST.draw_ctx.evil_C,
};
drw_context_state_init();
drw_viewport_var_init();
drw_viewport_colormanagement_set();
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
/* Check if scene needs to perform the populate loop */
@@ -1622,89 +1508,19 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
/* Start Drawing */
DRW_state_reset();
GPU_framebuffer_bind(DST.default_framebuffer);
GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF);
DRW_hair_update();
const bool background_drawn = drw_engines_draw_background();
GPU_framebuffer_bind(DST.default_framebuffer);
DRW_draw_callbacks_pre_scene();
if (DST.draw_ctx.evil_C) {
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
}
drw_engines_draw_scene();
if (!background_drawn) {
drw_draw_background_alpha_under();
}
drw_debug_draw();
/* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
GPU_flush();
/* annotations - temporary drawing buffer (3d space) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (do_annotations) {
GPU_depth_test(false);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true);
GPU_depth_test(true);
}
DRW_draw_callbacks_post_scene();
DRW_state_reset();
if (DST.draw_ctx.evil_C) {
GPU_depth_test(false);
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
GPU_depth_test(true);
/* Callback can be nasty and do whatever they want with the state.
* Don't trust them! */
DRW_state_reset();
}
GPU_depth_test(false);
drw_engines_draw_text();
GPU_depth_test(true);
if (DST.draw_ctx.evil_C) {
/* needed so gizmo isn't obscured */
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
glDisable(GL_DEPTH_TEST);
DRW_draw_gizmo_3d();
}
DRW_draw_region_info();
/* annotations - temporary drawing buffer (screenspace) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
GPU_depth_test(false);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
GPU_depth_test(true);
}
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
/* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
* 'DRW_draw_region_info' sets the projection in pixel-space. */
GPU_depth_test(false);
DRW_draw_gizmo_2d();
GPU_depth_test(true);
}
}
DRW_stats_reset();
if (G.debug_value > 20 && G.debug_value < 30) {
GPU_depth_test(false);
/* local coordinate visible rect inside region, to accommodate overlapping ui */
const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
DRW_stats_draw(rect);
GPU_depth_test(true);
}
if (WM_draw_region_get_bound_viewport(ar)) {
/* Don't unbind the framebuffer yet in this case and let
@@ -1755,10 +1571,10 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
/* Create temporary viewport if needed. */
GPUViewport *render_viewport = viewport;
if (viewport == NULL) {
render_viewport = GPU_viewport_create_from_offscreen(ofs);
render_viewport = GPU_viewport_create();
}
GPU_framebuffer_restore();
GPU_viewport_bind_from_offscreen(render_viewport, ofs);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1767,15 +1583,12 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
DST.options.draw_background = draw_background;
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management);
/* Free temporary viewport. */
if (viewport == NULL) {
/* don't free data owned by 'ofs' */
GPU_viewport_clear_from_offscreen(render_viewport);
GPU_viewport_free(render_viewport);
}
/* we need to re-bind (annoying!) */
GPU_offscreen_bind(ofs, false);
}
/* Helper to check if exit object type to render. */
@@ -2379,8 +2192,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
DRW_state_lock(0);
DRW_draw_callbacks_post_scene();
DRW_state_reset();
drw_engines_disable();
@@ -2477,9 +2288,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
DRW_hair_update();
DRW_draw_callbacks_pre_scene();
drw_engines_draw_scene();
DRW_draw_callbacks_post_scene();
DRW_state_reset();

View File

@@ -234,11 +234,11 @@ void drw_state_set(DRWState state)
/* Blending (all buffer) */
{
int test;
if (CHANGED_ANY_STORE_VAR(DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL |
DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_MUL |
DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT |
DRW_STATE_BLEND_ALPHA_UNDER_PREMUL | DRW_STATE_BLEND_CUSTOM,
test)) {
if (CHANGED_ANY_STORE_VAR(
DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_BLEND_ADD |
DRW_STATE_BLEND_MUL | DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT |
DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_CUSTOM | DRW_STATE_LOGIC_INVERT,
test)) {
if (test) {
glEnable(GL_BLEND);
@@ -248,8 +248,12 @@ void drw_state_set(DRWState state)
GL_ONE,
GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
}
else if ((state & DRW_STATE_BLEND_ALPHA_UNDER_PREMUL) != 0) {
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
else if ((state & DRW_STATE_BLEND_BACKGROUND) != 0) {
/* Special blend to add color under and multiply dst by alpha. */
glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA,
GL_SRC_ALPHA, /* RGB */
GL_ZERO,
GL_SRC_ALPHA); /* Alpha */
}
else if ((state & DRW_STATE_BLEND_ALPHA_PREMUL) != 0) {
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -279,6 +283,13 @@ void drw_state_set(DRWState state)
* Can only be used with one Draw Buffer. */
glBlendFunc(GL_ONE, GL_SRC1_COLOR);
}
else if ((state & DRW_STATE_LOGIC_INVERT) != 0) {
/* Replace logic op by blend func to support floating point framebuffer. */
glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR,
GL_ZERO, /* RGB */
GL_ZERO,
GL_ONE); /* Alpha */
}
else {
BLI_assert(0);
}
@@ -324,21 +335,6 @@ void drw_state_set(DRWState state)
}
}
/* Logic Ops */
{
int test;
if ((test = CHANGED_TO(DRW_STATE_LOGIC_INVERT))) {
if (test == 1) {
glLogicOp(GL_INVERT);
glEnable(GL_COLOR_LOGIC_OP);
}
else {
glLogicOp(GL_COPY);
glDisable(GL_COLOR_LOGIC_OP);
}
}
}
/* Clip Planes */
{
int test;

View File

@@ -57,95 +57,6 @@ void DRW_draw_region_info(void)
view3d_draw_region_info(draw_ctx->evil_C, ar);
}
/* ************************* Background ************************** */
void DRW_clear_background()
{
GPU_clear_color(0.0, 0.0, 0.0, 0.0);
GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT);
}
void DRW_draw_background(bool do_alpha_checker)
{
drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL);
if (do_alpha_checker) {
/* Transparent render, do alpha checker. */
GPU_matrix_push();
GPU_matrix_identity_set();
GPU_matrix_identity_projection_set();
imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f);
GPU_matrix_pop();
}
else {
float m[4][4];
unit_m4(m);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint color = GPU_vertformat_attr_add(
format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
uchar col_hi[3], col_lo[3];
GPU_matrix_push();
GPU_matrix_identity_set();
GPU_matrix_projection_set(m);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER);
UI_GetThemeColor3ubv(TH_BACK, col_hi);
UI_GetThemeColor3ubv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, col_lo);
immBegin(GPU_PRIM_TRI_FAN, 4);
immAttr3ubv(color, col_lo);
immVertex2f(pos, -1.0f, -1.0f);
immVertex2f(pos, 1.0f, -1.0f);
immAttr3ubv(color, col_hi);
immVertex2f(pos, 1.0f, 1.0f);
immVertex2f(pos, -1.0f, 1.0f);
immEnd();
immUnbindProgram();
GPU_matrix_pop();
}
}
GPUBatch *DRW_draw_background_clipping_batch_from_rv3d(const RegionView3D *rv3d)
{
const BoundBox *bb = rv3d->clipbb;
const uint clipping_index[6][4] = {
{0, 1, 2, 3},
{0, 4, 5, 1},
{4, 7, 6, 5},
{7, 3, 2, 6},
{1, 5, 6, 2},
{7, 4, 0, 3},
};
GPUVertBuf *vbo;
GPUIndexBuf *el;
GPUIndexBufBuilder elb = {0};
/* Elements */
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, ARRAY_SIZE(clipping_index) * 2, ARRAY_SIZE(bb->vec));
for (int i = 0; i < ARRAY_SIZE(clipping_index); i++) {
const uint *idx = clipping_index[i];
GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]);
}
el = GPU_indexbuf_build(&elb);
GPUVertFormat format = {0};
uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bb->vec));
GPU_vertbuf_attr_fill(vbo, pos_id, bb->vec);
return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, el, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
}
/* **************************** 3D Cursor ******************************** */
static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer)

View File

@@ -30,6 +30,4 @@ void DRW_draw_cursor(void);
void DRW_draw_gizmo_3d(void);
void DRW_draw_gizmo_2d(void);
struct GPUBatch *DRW_draw_background_clipping_batch_from_rv3d(const struct RegionView3D *rv3d);
#endif /* __DRAW_VIEW_H__ */

View File

@@ -42,6 +42,10 @@ layout(std140) uniform globalsBlock
vec4 colorLightNoAlpha;
vec4 colorBackground;
vec4 colorBackgroundGradient;
vec4 colorCheckerLow;
vec4 colorCheckerHigh;
vec4 colorClippingBorder;
vec4 colorEditMeshMiddle;
vec4 colorHandleFree;
@@ -61,6 +65,30 @@ layout(std140) uniform globalsBlock
vec4 colorActiveSpline;
vec4 colorBonePose;
vec4 colorBonePoseActive;
vec4 colorBonePoseActiveUnsel;
vec4 colorBonePoseConstraint;
vec4 colorBonePoseIK;
vec4 colorBonePoseSplineIK;
vec4 colorBonePoseTarget;
vec4 colorBoneSolid;
vec4 colorBoneLocked;
vec4 colorBoneActive;
vec4 colorBoneActiveUnsel;
vec4 colorBoneSelect;
vec4 colorBoneIKLine;
vec4 colorBoneIKLineNoTarget;
vec4 colorBoneIKLineSpline;
vec4 colorText;
vec4 colorTextHi;
vec4 colorBundleSolid;
vec4 colorMballRadius;
vec4 colorMballRadiusSelect;
vec4 colorMballStiffness;
vec4 colorMballStiffnessSelect;
vec4 colorCurrentFrame;

View File

@@ -577,7 +577,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
if (ibuf->rect_float) {
if (ibuf->float_colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(
view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true);
view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true, false);
}
else {
ok = IMB_colormanagement_setup_glsl_draw(
@@ -586,7 +586,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
}
else {
ok = IMB_colormanagement_setup_glsl_draw_from_space(
view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false);
view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false, false);
}
if (ok) {

View File

@@ -646,13 +646,18 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
ar->draw_buffer->viewport[ar->draw_buffer->stereo ? sima->iuser.multiview_eye : 0];
DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
GPU_framebuffer_bind(fbl->default_fb);
GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
GPU_clear(GPU_COLOR_BIT);
GPU_framebuffer_bind(fbl->overlay_fb);
glDisable(GL_FRAMEBUFFER_SRGB);
/* XXX not supported yet, disabling for now */
scene->r.scemode &= ~R_COMP_CROP;
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
GPU_clear_color(col[0], col[1], col[2], 0.0f);
GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
GPU_depth_test(false);

View File

@@ -168,7 +168,7 @@ data_to_c_simple(shaders/gpu_shader_2D_image_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_multi_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_desaturate_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_overlays_merge_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)

View File

@@ -126,6 +126,7 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
void GPU_batch_program_set_imm_shader(GPUBatch *batch);
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUBuiltinShader shader_id,

View File

@@ -183,7 +183,7 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_3D_DEPTH_ONLY,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/* basic image drawing */
GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB,
GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
/**

View File

@@ -99,6 +99,7 @@ typedef enum eGPUTextureFormat {
GPU_R11F_G11F_B10F,
GPU_DEPTH32F_STENCIL8,
GPU_DEPTH24_STENCIL8,
GPU_SRGB8_A8,
/* Texture only format */
GPU_RGB16F,
@@ -124,7 +125,6 @@ typedef enum eGPUTextureFormat {
/* Special formats texture only */
#if 0
GPU_SRGB8_A8,
GPU_SRGB8,
GPU_RGB9_E5,
GPU_COMPRESSED_RG_RGTC2,

View File

@@ -102,8 +102,15 @@ 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);
void GPU_viewport_clear_from_offscreen(GPUViewport *viewport);
void GPU_viewport_colorspace_set(GPUViewport *viewport,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float dither);
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs);
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
struct GPUOffScreen *ofs,
bool display_colorspace);
ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport);
struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *viewport);

View File

@@ -979,6 +979,17 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT);
}
/* Bind program bound to IMM to the batch.
* XXX Use this with much care. Drawing with the GPUBatch API is not compatible with IMM.
* DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
void GPU_batch_program_set_imm_shader(GPUBatch *batch)
{
GLuint program;
GPUShaderInterface *interface;
immGetProgram(&program, &interface);
GPU_batch_program_set(batch, program, interface);
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@@ -513,6 +513,7 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
if (GPU_framebuffer_active_get() != fb) {
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
glEnable(GL_FRAMEBUFFER_SRGB);
}
gpu_framebuffer_current_set(fb);
@@ -547,6 +548,7 @@ void GPU_framebuffer_restore(void)
if (GPU_framebuffer_active_get() != NULL) {
glBindFramebuffer(GL_FRAMEBUFFER, GPU_framebuffer_default());
gpu_framebuffer_current_set(NULL);
glDisable(GL_FRAMEBUFFER_SRGB);
}
}

View File

@@ -168,6 +168,13 @@ void immUnbindProgram(void)
imm.bound_program = 0;
}
/* XXX do not use it. Special hack to use OCIO with batch API. */
void immGetProgram(GLuint *program, GPUShaderInterface **shaderface)
{
*program = imm.bound_program;
*shaderface = (GPUShaderInterface *)imm.shader_interface;
}
#if TRUST_NO_ONE
static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType prim_type)
{

View File

@@ -80,7 +80,7 @@ extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[];
extern char datatoc_gpu_shader_3D_image_vert_glsl[];
extern char datatoc_gpu_shader_image_frag_glsl[];
extern char datatoc_gpu_shader_image_linear_frag_glsl[];
extern char datatoc_gpu_shader_image_overlays_merge_frag_glsl[];
extern char datatoc_gpu_shader_image_color_frag_glsl[];
extern char datatoc_gpu_shader_image_desaturate_frag_glsl[];
extern char datatoc_gpu_shader_image_varying_color_frag_glsl[];
@@ -1008,10 +1008,10 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_2D_smooth_color_vert_glsl,
.frag = datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl,
},
[GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] =
[GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.vert = datatoc_gpu_shader_2D_image_vert_glsl,
.frag = datatoc_gpu_shader_image_linear_frag_glsl,
.frag = datatoc_gpu_shader_image_overlays_merge_frag_glsl,
},
[GPU_SHADER_2D_IMAGE] =
{

View File

@@ -44,4 +44,7 @@ struct GPUShader {
#endif
};
/* XXX do not use it. Special hack to use OCIO with batch API. */
void immGetProgram(GLuint *program, GPUShaderInterface **shaderface);
#endif /* __GPU_SHADER_PRIVATE_H__ */

View File

@@ -51,7 +51,7 @@ static struct GPUTextureGlobal {
} GG = {NULL, NULL, NULL};
/* Maximum number of FBOs a texture can be attached to. */
#define GPU_TEX_MAX_FBO_ATTACHED 10
#define GPU_TEX_MAX_FBO_ATTACHED 12
typedef enum eGPUTextureFormatFlag {
GPU_FORMAT_DEPTH = (1 << 0),
@@ -183,6 +183,7 @@ static int gpu_get_component_count(eGPUTextureFormat format)
case GPU_RGBA16F:
case GPU_RGBA16:
case GPU_RGBA32F:
case GPU_SRGB8_A8:
return 4;
case GPU_RGB16F:
case GPU_R11F_G11F_B10F:
@@ -221,7 +222,7 @@ static void gpu_validate_data_format(eGPUTextureFormat tex_format, eGPUDataForma
}
}
/* Byte formats */
else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI)) {
else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI, GPU_SRGB8_A8)) {
BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
}
/* Special case */
@@ -349,6 +350,7 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
case GPU_DEPTH_COMPONENT32F:
case GPU_RGBA8UI:
case GPU_RGBA8:
case GPU_SRGB8_A8:
case GPU_R11F_G11F_B10F:
case GPU_R32F:
case GPU_R32UI:
@@ -398,6 +400,8 @@ static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
return GL_RGBA8;
case GPU_RGBA8UI:
return GL_RGBA8UI;
case GPU_SRGB8_A8:
return GL_SRGB8_ALPHA8;
case GPU_R32F:
return GL_R32F;
case GPU_R32UI:

View File

@@ -27,8 +27,13 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_math_vector.h"
#include "BLI_memblock.h"
#include "BKE_colortools.h"
#include "IMB_colormanagement.h"
#include "DNA_vec_types.h"
#include "DNA_userdef_types.h"
@@ -61,7 +66,6 @@ typedef struct ViewportTempTexture {
struct GPUViewport {
int size[2];
int samples;
int flag;
/* If engine_handles mismatch we free all ViewportEngineData in this viewport */
@@ -80,6 +84,14 @@ struct GPUViewport {
/* Profiling data */
double cache_time;
/* Color management. */
ColorManagedViewSettings view_settings;
ColorManagedDisplaySettings display_settings;
float dither;
/* TODO(fclem) the uvimage display use the viewport but do not set any view transform for the
* moment. The end goal would be to let the GPUViewport do the color management. */
bool do_color_management;
};
enum {
@@ -93,7 +105,6 @@ static void gpu_viewport_buffers_free(FramebufferList *fbl,
static void gpu_viewport_storage_free(StorageList *stl, int stl_len);
static void gpu_viewport_passes_free(PassList *psl, int psl_len);
static void gpu_viewport_texture_pool_free(GPUViewport *viewport);
static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth);
void GPU_viewport_tag_update(GPUViewport *viewport)
{
@@ -113,67 +124,13 @@ GPUViewport *GPU_viewport_create(void)
viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList");
viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList");
viewport->idatalist = DRW_instance_data_list_create();
viewport->do_color_management = false;
viewport->size[0] = viewport->size[1] = -1;
return viewport;
}
GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs)
{
GPUViewport *viewport = GPU_viewport_create();
GPUTexture *color, *depth;
GPUFrameBuffer *fb;
viewport->size[0] = GPU_offscreen_width(ofs);
viewport->size[1] = GPU_offscreen_height(ofs);
GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth);
if (GPU_texture_samples(color)) {
viewport->txl->multisample_color = color;
viewport->txl->multisample_depth = depth;
viewport->fbl->multisample_fb = fb;
gpu_viewport_default_fb_create(viewport, true);
}
else {
viewport->fbl->default_fb = fb;
viewport->txl->color = color;
viewport->txl->depth = depth;
GPU_framebuffer_ensure_config(
&viewport->fbl->color_only_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(viewport->txl->color)});
GPU_framebuffer_ensure_config(
&viewport->fbl->depth_only_fb,
{GPU_ATTACHMENT_TEXTURE(viewport->txl->depth), GPU_ATTACHMENT_NONE});
/* TODO infront buffer */
}
return viewport;
}
/**
* Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
*/
void GPU_viewport_clear_from_offscreen(GPUViewport *viewport)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
if (dfbl->multisample_fb) {
/* GPUViewport expect the final result to be in default_fb but
* GPUOffscreen wants it in its multisample_fb, so we sync it back. */
GPU_framebuffer_blit(
dfbl->default_fb, 0, dfbl->multisample_fb, 0, GPU_COLOR_BIT | GPU_DEPTH_BIT);
dfbl->multisample_fb = NULL;
dtxl->multisample_color = NULL;
dtxl->multisample_depth = NULL;
}
else {
viewport->fbl->default_fb = NULL;
dtxl->color = NULL;
dtxl->depth = NULL;
}
}
void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
{
ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
@@ -268,8 +225,7 @@ void *GPU_viewport_texture_list_get(GPUViewport *viewport)
void GPU_viewport_size_get(const GPUViewport *viewport, int size[2])
{
size[0] = viewport->size[0];
size[1] = viewport->size[1];
copy_v2_v2_int(size, viewport->size);
}
/**
@@ -279,8 +235,7 @@ void GPU_viewport_size_get(const GPUViewport *viewport, int size[2])
*/
void GPU_viewport_size_set(GPUViewport *viewport, const int size[2])
{
viewport->size[0] = size[0];
viewport->size[1] = size[1];
copy_v2_v2_int(viewport->size, size);
}
double *GPU_viewport_cache_time_get(GPUViewport *viewport)
@@ -383,69 +338,61 @@ void GPU_viewport_cache_release(GPUViewport *viewport)
}
}
static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth)
static void gpu_viewport_default_fb_create(GPUViewport *viewport)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
int *size = viewport->size;
bool ok = true;
dtxl->color = GPU_texture_create_2d(
size[0], size[1], high_bitdepth ? GPU_RGBA16F : GPU_RGBA8, NULL, NULL);
dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL);
dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL);
if (!(dtxl->depth && dtxl->color)) {
/* Can be shared with GPUOffscreen. */
if (dtxl->depth == NULL) {
dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
}
if (!dtxl->depth || !dtxl->color) {
ok = false;
goto cleanup;
}
GPU_framebuffer_ensure_config(
&dfbl->default_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
GPU_framebuffer_ensure_config(&dfbl->default_fb,
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(dtxl->color),
});
GPU_framebuffer_ensure_config(&dfbl->overlay_fb,
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
});
GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_NONE,
});
GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(dtxl->color),
});
GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb,
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
});
ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL);
cleanup:
if (!ok) {
GPU_viewport_free(viewport);
DRW_opengl_context_disable();
return;
}
GPU_framebuffer_restore();
}
static void gpu_viewport_default_multisample_fb_create(GPUViewport *viewport)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
int *size = viewport->size;
int samples = viewport->samples;
bool ok = true;
dtxl->multisample_color = GPU_texture_create_2d_multisample(
size[0], size[1], GPU_RGBA8, NULL, samples, NULL);
dtxl->multisample_depth = GPU_texture_create_2d_multisample(
size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, samples, NULL);
if (!(dtxl->multisample_depth && dtxl->multisample_color)) {
ok = false;
goto cleanup;
}
GPU_framebuffer_ensure_config(&dfbl->multisample_fb,
{GPU_ATTACHMENT_TEXTURE(dtxl->multisample_depth),
GPU_ATTACHMENT_TEXTURE(dtxl->multisample_color)});
ok = ok && GPU_framebuffer_check_valid(dfbl->multisample_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL);
cleanup:
if (!ok) {
@@ -462,15 +409,15 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
DefaultFramebufferList *dfbl = viewport->fbl;
int fbl_len, txl_len;
int rect_size[2];
/* add one pixel because of scissor test */
int rect_w = BLI_rcti_size_x(rect) + 1;
int rect_h = BLI_rcti_size_y(rect) + 1;
rect_size[0] = BLI_rcti_size_x(rect) + 1;
rect_size[1] = BLI_rcti_size_y(rect) + 1;
DRW_opengl_context_enable();
if (dfbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1] ||
U.ogl_multisamples != viewport->samples) {
if (!equals_v2v2_int(viewport->size, rect_size)) {
gpu_viewport_buffers_free((FramebufferList *)viewport->fbl,
default_fbl_len,
(TextureList *)viewport->txl,
@@ -486,36 +433,115 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
}
}
viewport->size[0] = rect_w;
viewport->size[1] = rect_h;
viewport->samples = U.ogl_multisamples;
copy_v2_v2_int(viewport->size, rect_size);
gpu_viewport_texture_pool_clear_users(viewport);
/* Multisample Buffer */
if (viewport->samples > 0) {
if (!dfbl->default_fb) {
gpu_viewport_default_multisample_fb_create(viewport);
}
if (!dfbl->default_fb) {
gpu_viewport_default_fb_create(viewport);
}
}
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
GPUTexture *color, *depth;
GPUFrameBuffer *fb;
viewport->size[0] = GPU_offscreen_width(ofs);
viewport->size[1] = GPU_offscreen_height(ofs);
GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth);
/* This is the only texture we can share. */
dtxl->depth = depth;
gpu_viewport_texture_pool_clear_users(viewport);
if (!dfbl->default_fb) {
gpu_viewport_default_fb_create(viewport, false);
gpu_viewport_default_fb_create(viewport);
}
}
void GPU_viewport_colorspace_set(GPUViewport *viewport,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float dither)
{
memcpy(&viewport->view_settings, view_settings, sizeof(*view_settings));
memcpy(&viewport->display_settings, display_settings, sizeof(*display_settings));
viewport->dither = dither;
viewport->do_color_management = true;
}
static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
const rctf *rect_pos,
const rctf *rect_uv,
bool display_colorspace)
{
DefaultTextureList *dtxl = viewport->txl;
GPUTexture *color = dtxl->color;
GPUTexture *color_overlay = dtxl->color_overlay;
GPUVertFormat *vert_format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
bool use_ocio = false;
if (viewport->do_color_management && display_colorspace) {
use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(&viewport->view_settings,
&viewport->display_settings,
NULL,
viewport->dither,
false,
true);
}
if (!use_ocio) {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
immUniform1i("display_transform", display_colorspace);
immUniform1i("image_texture", 0);
immUniform1i("overlays_texture", 1);
}
GPU_texture_bind(color, 0);
GPU_texture_bind(color_overlay, 1);
immBegin(GPU_PRIM_TRI_STRIP, 4);
immAttr2f(texco, rect_uv->xmin, rect_uv->ymin);
immVertex2f(pos, rect_pos->xmin, rect_pos->ymin);
immAttr2f(texco, rect_uv->xmax, rect_uv->ymin);
immVertex2f(pos, rect_pos->xmax, rect_pos->ymin);
immAttr2f(texco, rect_uv->xmin, rect_uv->ymax);
immVertex2f(pos, rect_pos->xmin, rect_pos->ymax);
immAttr2f(texco, rect_uv->xmax, rect_uv->ymax);
immVertex2f(pos, rect_pos->xmax, rect_pos->ymax);
immEnd();
GPU_texture_unbind(color);
GPU_texture_unbind(color_overlay);
if (use_ocio) {
IMB_colormanagement_finish_glsl_draw();
}
else {
immUnbindProgram();
}
}
void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
GPUTexture *color = dtxl->color;
if (dfbl->default_fb == NULL) {
return;
}
DefaultTextureList *dtxl = viewport->txl;
GPUTexture *color = dtxl->color;
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
@@ -526,27 +552,58 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
const float halfx = GLA_PIXEL_OFS / w;
const float halfy = GLA_PIXEL_OFS / h;
float x1 = rect->xmin;
float x2 = rect->xmin + w;
float y1 = rect->ymin;
float y2 = rect->ymin + h;
rctf pos_rect = {
.xmin = rect->xmin,
.ymin = rect->ymin,
.xmax = rect->xmin + w,
.ymax = rect->ymin + h,
};
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
rctf uv_rect = {
.xmin = halfx,
.ymin = halfy,
.xmax = halfx + 1.0f,
.ymax = halfy + 1.0f,
};
GPU_texture_bind(color, 0);
glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0);
glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"),
halfx,
halfy,
1.0f + halfx,
1.0f + halfy);
glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), x1, y1, x2, y2);
glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f);
gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, true);
}
GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
/**
* Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
*/
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
struct GPUOffScreen *ofs,
bool display_colorspace)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
GPU_texture_unbind(color);
if (dfbl->default_fb == NULL) {
return;
}
GPU_depth_test(false);
GPU_offscreen_bind(ofs, false);
rctf pos_rect = {
.xmin = -1.0f,
.ymin = -1.0f,
.xmax = 1.0f,
.ymax = 1.0f,
};
rctf uv_rect = {
.xmin = 0.0f,
.ymin = 0.0f,
.xmax = 1.0f,
.ymax = 1.0f,
};
gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, display_colorspace);
/* This one is from the offscreen. Don't free it with the viewport. */
dtxl->depth = NULL;
}
void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))

View File

@@ -1,33 +0,0 @@
/* Display a linear image texture into sRGB space */
uniform sampler2D image;
in vec2 texCoord_interp;
out vec4 fragColor;
float linearrgb_to_srgb(float c)
{
if (c < 0.0031308) {
return (c < 0.0) ? 0.0 : c * 12.92;
}
else {
return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
}
}
void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
{
col_to.r = linearrgb_to_srgb(col_from.r);
col_to.g = linearrgb_to_srgb(col_from.g);
col_to.b = linearrgb_to_srgb(col_from.b);
col_to.a = col_from.a;
}
void main()
{
fragColor = texture(image, texCoord_interp.st);
linearrgb_to_srgb(fragColor, fragColor);
}

View File

@@ -0,0 +1,42 @@
/* Merge overlays texture on top of image texture and transform to display space (assume sRGB) */
uniform sampler2D image_texture;
uniform sampler2D overlays_texture;
uniform bool display_transform;
in vec2 texCoord_interp;
out vec4 fragColor;
float linearrgb_to_srgb(float c)
{
if (c < 0.0031308) {
return (c < 0.0) ? 0.0 : c * 12.92;
}
else {
return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
}
}
void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
{
col_to.r = linearrgb_to_srgb(col_from.r);
col_to.g = linearrgb_to_srgb(col_from.g);
col_to.b = linearrgb_to_srgb(col_from.b);
col_to.a = col_from.a;
}
void main()
{
fragColor = texture(image_texture, texCoord_interp.st);
vec4 overlay_col = texture(overlays_texture, texCoord_interp.st);
fragColor *= 1.0 - overlay_col.a;
fragColor += overlay_col;
if (display_transform) {
linearrgb_to_srgb(fragColor, fragColor);
}
}

View File

@@ -332,7 +332,8 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(
const struct ColorManagedDisplaySettings *display_settings,
struct ColorSpace *colorspace,
float dither,
bool predivide);
bool predivide,
bool do_overlay_merge);
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C,
float dither,

View File

@@ -105,7 +105,12 @@ typedef struct ColormanageProcessor {
static struct global_glsl_state {
/* Actual processor used for GLSL baked LUTs. */
OCIO_ConstProcessorRcPtr *processor;
/* UI colorspace here refers to the display linear color space,
* i.e: The linear color space w.r.t. display chromaticity and radiometry.
* We separate the colormanagement process into two steps to be able to
* merge UI using alpha blending in the correct color space. */
OCIO_ConstProcessorRcPtr *processor_scene_to_ui;
OCIO_ConstProcessorRcPtr *processor_ui_to_display;
/* Settings of processor for comparison. */
char look[MAX_COLORSPACE_NAME];
@@ -121,7 +126,6 @@ static struct global_glsl_state {
/* Container for GLSL state needed for OCIO module. */
struct OCIO_GLSLDrawState *ocio_glsl_state;
struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
} global_glsl_state = {NULL};
static struct global_color_picking_state {
@@ -711,8 +715,12 @@ void colormanagement_init(void)
void colormanagement_exit(void)
{
if (global_glsl_state.processor) {
OCIO_processorRelease(global_glsl_state.processor);
if (global_glsl_state.processor_scene_to_ui) {
OCIO_processorRelease(global_glsl_state.processor_scene_to_ui);
}
if (global_glsl_state.processor_ui_to_display) {
OCIO_processorRelease(global_glsl_state.processor_ui_to_display);
}
if (global_glsl_state.curve_mapping) {
@@ -727,10 +735,6 @@ void colormanagement_exit(void)
OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
}
if (global_glsl_state.transform_ocio_glsl_state) {
OCIO_freeOGLState(global_glsl_state.transform_ocio_glsl_state);
}
if (global_color_picking_state.processor_to) {
OCIO_processorRelease(global_color_picking_state.processor_to);
}
@@ -837,7 +841,8 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *loo
const char *display,
float exposure,
float gamma,
const char *from_colorspace)
const char *from_colorspace,
const bool linear_output)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_DisplayTransformRcPtr *dt;
@@ -883,14 +888,45 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *loo
OCIO_exponentTransformRelease(et);
}
processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)dt);
OCIO_GroupTransformRcPtr *gt = OCIO_createGroupTransform();
OCIO_groupTransformSetDirection(gt, true);
OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)dt);
if (linear_output) {
/* TODO use correct function display. */
OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform();
OCIO_exponentTransformSetValue(et, (float[4]){2.2f, 2.2f, 2.2f, 1.0f});
OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)et);
OCIO_exponentTransformRelease(et);
}
processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)gt);
OCIO_groupTransformRelease(gt);
OCIO_displayTransformRelease(dt);
OCIO_configRelease(config);
return processor;
}
static OCIO_ConstProcessorRcPtr *create_display_encoded_buffer_processor(
const char *UNUSED(display))
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_ConstProcessorRcPtr *processor;
/* TODO use correct function display. */
OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform();
OCIO_exponentTransformSetValue(et, (float[4]){1.0f / 2.2f, 1.0f / 2.2f, 1.0f / 2.2f, 1.0f});
processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)et);
OCIO_exponentTransformRelease(et);
OCIO_configRelease(config);
return processor;
}
static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace,
const char *to_colorspace)
{
@@ -3725,7 +3761,8 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(
display_settings->display_device,
applied_view_settings->exposure,
applied_view_settings->gamma,
global_role_scene_linear);
global_role_scene_linear,
false);
if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
cm_processor->curve_mapping = BKE_curvemapping_copy(applied_view_settings->curve_mapping);
@@ -3934,7 +3971,7 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
bool need_update = false;
need_update = global_glsl_state.processor == NULL ||
need_update = global_glsl_state.processor_scene_to_ui == NULL ||
check_glsl_display_processor_changed(
view_settings, display_settings, from_colorspace) ||
use_curve_mapping != global_glsl_state.use_curve_mapping;
@@ -3989,17 +4026,26 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
}
/* Free old processor, if any. */
if (global_glsl_state.processor) {
OCIO_processorRelease(global_glsl_state.processor);
if (global_glsl_state.processor_scene_to_ui) {
OCIO_processorRelease(global_glsl_state.processor_scene_to_ui);
}
if (global_glsl_state.processor_ui_to_display) {
OCIO_processorRelease(global_glsl_state.processor_ui_to_display);
}
/* We're using display OCIO processor, no RGB curves yet. */
global_glsl_state.processor = create_display_buffer_processor(global_glsl_state.look,
global_glsl_state.view,
global_glsl_state.display,
global_glsl_state.exposure,
global_glsl_state.gamma,
global_glsl_state.input);
global_glsl_state.processor_scene_to_ui = create_display_buffer_processor(
global_glsl_state.look,
global_glsl_state.view,
global_glsl_state.display,
global_glsl_state.exposure,
global_glsl_state.gamma,
global_glsl_state.input,
true);
global_glsl_state.processor_ui_to_display = create_display_encoded_buffer_processor(
global_glsl_state.display);
}
}
@@ -4026,7 +4072,8 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(
const ColorManagedDisplaySettings *display_settings,
struct ColorSpace *from_colorspace,
float dither,
bool predivide)
bool predivide,
bool do_overlay_merge)
{
ColorManagedViewSettings default_view_settings;
const ColorManagedViewSettings *applied_view_settings;
@@ -4047,7 +4094,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(
from_colorspace ? from_colorspace->name :
global_role_scene_linear);
if (global_glsl_state.processor == NULL) {
if (global_glsl_state.processor_scene_to_ui == NULL) {
/* Happens when requesting non-existing color space or LUT in the
* configuration file does not exist.
*/
@@ -4056,10 +4103,12 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(
return OCIO_setupGLSLDraw(
&global_glsl_state.ocio_glsl_state,
global_glsl_state.processor,
global_glsl_state.processor_scene_to_ui,
global_glsl_state.processor_ui_to_display,
global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL,
dither,
predivide);
predivide,
do_overlay_merge);
}
/* Configures GLSL shader for conversion from scene linear to display space */
@@ -4069,7 +4118,7 @@ bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_se
bool predivide)
{
return IMB_colormanagement_setup_glsl_draw_from_space(
view_settings, display_settings, NULL, dither, predivide);
view_settings, display_settings, NULL, dither, predivide, false);
}
/**
@@ -4087,7 +4136,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const 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, dither, predivide);
view_settings, display_settings, from_colorspace, dither, predivide, false);
}
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */

View File

@@ -101,6 +101,7 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = {
# include "IMB_colormanagement.h"
# include "GPU_extensions.h"
# include "GPU_shader.h"
# include "DEG_depsgraph_query.h"
@@ -126,15 +127,21 @@ static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *sc
return BKE_render_preview_pixel_size(&scene->r);
}
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *UNUSED(scene))
{
IMB_colormanagement_setup_glsl_draw(
&scene->view_settings, &scene->display_settings, scene->r.dither_intensity, false);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_COLOR);
GPU_shader_bind(shader);
int img_loc = GPU_shader_get_uniform_ensure(shader, "image");
int color_loc = GPU_shader_get_uniform_ensure(shader, "color");
GPU_shader_uniform_int(shader, img_loc, 0);
GPU_shader_uniform_vector(shader, color_loc, 3, 1, (float[3]){1.0f, 1.0f, 1.0f});
}
static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
{
IMB_colormanagement_finish_glsl_draw();
GPU_shader_unbind();
}
static void engine_update(RenderEngine *engine, Main *bmain, Depsgraph *depsgraph)