Welcome to mirror list, hosted at ThFree Co, Russian Federation.

draw_color_management.cc « intern « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: bb11f1ab3add6b7c45da0546e3b1224f3d3da70c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2020 Blender Foundation. */

/** \file
 * \ingroup draw
 */

#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 "DNA_space_types.h"
#include "DNA_view3d_types.h"

#include "BKE_colortools.h"

#include "IMB_colormanagement.h"

#include "draw_color_management.h"

namespace blender::draw::color_management {

enum class eDRWColorManagementType {
  ViewTransform = 0,
  ViewTransformAndLook,
  UseRenderSettings,
};

static float dither_get(eDRWColorManagementType color_management_type, const Scene &scene)
{
  if (ELEM(color_management_type,
           eDRWColorManagementType::ViewTransformAndLook,
           eDRWColorManagementType::UseRenderSettings)) {
    return scene.r.dither_intensity;
  }
  return 0.0f;
}

static eDRWColorManagementType drw_color_management_type_for_v3d(const Scene &scene,
                                                                 const View3D &v3d)
{

  const bool use_workbench = BKE_scene_uses_blender_workbench(&scene);
  const bool use_scene_lights = V3D_USES_SCENE_LIGHTS(&v3d);
  const bool use_scene_world = V3D_USES_SCENE_WORLD(&v3d);

  if ((use_workbench && v3d.shading.type == OB_RENDER) || use_scene_lights || use_scene_world) {
    return eDRWColorManagementType::UseRenderSettings;
  }
  if (v3d.shading.type >= OB_MATERIAL) {
    return eDRWColorManagementType::ViewTransformAndLook;
  }
  return eDRWColorManagementType::ViewTransform;
}

static eDRWColorManagementType drw_color_management_type_for_space_image(const SpaceImage &sima)
{
  Image *image = sima.image;

  /* Use inverse logic as there isn't a setting for `Color And Alpha`. */
  const eSpaceImage_Flag display_channels_mode = static_cast<eSpaceImage_Flag>(sima.flag);
  const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) == 0;

  if (display_color_channel && image && (image->source != IMA_SRC_GENERATED) &&
      ((image->flag & IMA_VIEW_AS_RENDER) != 0)) {
    return eDRWColorManagementType::UseRenderSettings;
  }
  return eDRWColorManagementType::ViewTransform;
}

static eDRWColorManagementType drw_color_management_type_for_space_node(const SpaceNode &snode)
{
  const eSpaceNode_Flag display_channels_mode = static_cast<eSpaceNode_Flag>(snode.flag);
  const bool display_color_channel = (display_channels_mode & SNODE_SHOW_ALPHA) == 0;
  if (display_color_channel) {
    return eDRWColorManagementType::UseRenderSettings;
  }
  return eDRWColorManagementType::ViewTransform;
}

static eDRWColorManagementType drw_color_management_type_get(const Scene &scene,
                                                             const View3D *v3d,
                                                             const SpaceLink *space_data)
{
  if (v3d) {
    return drw_color_management_type_for_v3d(scene, *v3d);
  }
  if (space_data) {
    switch (space_data->spacetype) {
      case SPACE_IMAGE: {
        const SpaceImage *sima = static_cast<const SpaceImage *>(
            static_cast<const void *>(space_data));
        return drw_color_management_type_for_space_image(*sima);
      }
      case SPACE_NODE: {
        const SpaceNode *snode = static_cast<const SpaceNode *>(
            static_cast<const void *>(space_data));
        return drw_color_management_type_for_space_node(*snode);
      }
    }
  }
  return eDRWColorManagementType::UseRenderSettings;
}

static void viewport_settings_apply(GPUViewport &viewport,
                                    const Scene &scene,
                                    const eDRWColorManagementType color_management_type)
{
  const ColorManagedDisplaySettings *display_settings = &scene.display_settings;
  ColorManagedViewSettings view_settings;

  switch (color_management_type) {
    case eDRWColorManagementType::ViewTransform: {
      /* For workbench use only default view transform in configuration,
       * using no scene settings. */
      BKE_color_managed_view_settings_init_render(&view_settings, display_settings, nullptr);
      break;
    }
    case eDRWColorManagementType::ViewTransformAndLook: {
      /* 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, nullptr);
      STRNCPY(view_settings.view_transform, scene.view_settings.view_transform);
      STRNCPY(view_settings.look, scene.view_settings.look);
      break;
    }
    case eDRWColorManagementType::UseRenderSettings: {
      /* Use full render settings, for renders with scene lighting. */
      view_settings = scene.view_settings;
      break;
    }
  }

  const float dither = dither_get(color_management_type, scene);
  GPU_viewport_colorspace_set(&viewport, &view_settings, display_settings, dither);
}

static void viewport_color_management_set(GPUViewport &viewport)
{
  const DRWContextState *draw_ctx = DRW_context_state_get();

  const eDRWColorManagementType color_management_type = drw_color_management_type_get(
      *draw_ctx->scene, draw_ctx->v3d, draw_ctx->space_data);
  viewport_settings_apply(viewport, *draw_ctx->scene, color_management_type);
}

}  // namespace blender::draw::color_management

/* -------------------------------------------------------------------- */
/** \name Color Management
 * \{ */

void DRW_viewport_colormanagement_set(GPUViewport *viewport)
{
  blender::draw::color_management::viewport_color_management_set(*viewport);
}

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_texture_bind(geom, "image", tex);

  GPU_batch_draw(geom);

  GPU_texture_unbind(tex);
}

/** \} */