[Bf-blender-cvs] [cb4c62eee6c] temp-gpu-image-engine: First rendered pixel with the new image engine.
Jeroen Bakker
noreply at git.blender.org
Mon Nov 29 11:13:48 CET 2021
Commit: cb4c62eee6c08717e3a31a1146f004919eebf6a8
Author: Jeroen Bakker
Date: Mon Nov 29 11:10:45 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rBcb4c62eee6c08717e3a31a1146f004919eebf6a8
First rendered pixel with the new image engine.
===================================================================
M source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
===================================================================
diff --git a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
index ca460604297..4b9d4fe04f6 100644
--- a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
@@ -28,28 +28,76 @@
namespace blender::draw::image_engine {
-using namespace blender::bke::image::partial_update;
+constexpr float EPSILON_UV_BOUNDS = 0.00001f;
-/* TODO: Should we use static class functions in stead of a namespace. */
-namespace clipping {
+/**
+ * \brief Accessor to texture slots.
+ *
+ * Texture slots info is stored in IMAGE_PrivateData. The GPUTextures are stored in
+ * IMAGE_TextureList. This class simplifies accessing texture slots by providing
+ */
+struct PrivateDataAccessor {
+ IMAGE_PrivateData *pd;
+ IMAGE_TextureList *txl;
+ PrivateDataAccessor(IMAGE_PrivateData *pd, IMAGE_TextureList *txl) : pd(pd)
+ {
+ }
-/** \brief Update the texture slot uv and screen space bounds. */
-static void update_texture_slots_bounds(const ARegion *region,
- const AbstractSpaceAccessor *space,
- IMAGE_PrivateData *pd)
-{
- // each texture
- BLI_rctf_init(
- &pd->screen_space.texture_infos[0].clipping_bounds, 0, region->winx, 0, region->winy);
- // TODO: calculate the correct visible uv bounds.
- BLI_rctf_init(&pd->screen_space.texture_infos[0].uv_bounds, 0.0, 1.0, 0.0, 1.0);
+ /** \brief Clear dirty flag from all texture slots. */
+ void clear_dirty_flag()
+ {
+ for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+ pd->screen_space.texture_infos[i].dirty = false;
+ }
+ }
- /* Mark the other textures as invalid. */
- for (int i = 1; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
- BLI_rctf_init_minmax(&pd->screen_space.texture_infos[i].clipping_bounds);
- BLI_rctf_init_minmax(&pd->screen_space.texture_infos[i].uv_bounds);
+ /** \brief Update the texture slot uv and screen space bounds. */
+ void update_screen_space_bounds(const ARegion *region)
+ {
+ /* Create a single texture that covers the visible screen space. */
+ BLI_rctf_init(
+ &pd->screen_space.texture_infos[0].clipping_bounds, 0, region->winx, 0, region->winy);
+
+ /* Mark the other textures as invalid. */
+ for (int i = 1; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+ BLI_rctf_init_minmax(&pd->screen_space.texture_infos[i].clipping_bounds);
+ }
}
-}
+
+ void update_uv_bounds()
+ {
+
+ /* Calculate the uv coordinates of the screen space visible corners. */
+ float inverse_mat[4][4];
+ DRW_view_viewmat_get(NULL, inverse_mat, true);
+
+ rctf new_uv_bounds;
+ float uv_min[3];
+ static const float screen_space_co1[3] = {0.0, 0.0, 0.0};
+ mul_v3_m4v3(uv_min, inverse_mat, screen_space_co1);
+
+ static const float screen_space_co2[3] = {1.0, 1.0, 0.0};
+ float uv_max[3];
+ mul_v3_m4v3(uv_max, inverse_mat, screen_space_co2);
+ BLI_rctf_init(&new_uv_bounds, uv_min[0], uv_max[0], uv_min[1], uv_max[1]);
+
+ if (!BLI_rctf_compare(
+ &pd->screen_space.texture_infos[0].uv_bounds, &new_uv_bounds, EPSILON_UV_BOUNDS)) {
+ pd->screen_space.texture_infos[0].uv_bounds = new_uv_bounds;
+ pd->screen_space.texture_infos[0].dirty = true;
+ }
+
+ /* Mark the other textures as invalid. */
+ for (int i = 1; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+ BLI_rctf_init_minmax(&pd->screen_space.texture_infos[i].clipping_bounds);
+ }
+ }
+};
+
+using namespace blender::bke::image::partial_update;
+
+/* TODO: Should we use static class functions in stead of a namespace. */
+namespace clipping {
static void update_texture_slots_visibility(const AbstractSpaceAccessor *space,
IMAGE_PrivateData *pd)
@@ -151,7 +199,7 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
DRW_texture_ensure_fullscreen_2d(
&txl->screen_space.textures[i], GPU_RGBA16F, static_cast<DRWTextureFlag>(0));
}
- pd->screen_space.texture_infos[i].dirty = should_be_created;
+ pd->screen_space.texture_infos[i].dirty |= should_be_created;
}
}
@@ -218,19 +266,39 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
int texture_size = texture_width * texture_height;
float *data = static_cast<float *>(MEM_mallocN(sizeof(float) * 4 * texture_size, __func__));
- int offset = 0;
- for (int y = 0; y < texture_height; y++) {
- float v = y / (float)texture_height;
- for (int x = 0; x < texture_width; x++) {
- float u = x / (float)texture_width;
- copy_v4_fl4(&data[offset * 4],
- uv_bounds->xmin * u + uv_bounds->xmax * (1.0 - u),
- uv_bounds->ymin * v + uv_bounds->ymax * (1.0 - v),
- 0.0,
- 1.0);
- offset++;
+
+ LISTBASE_FOREACH (ImageTile *, image_tile, &pd->image->tiles) {
+
+ ImBuf *image_buffer = pd->ibuf;
+ if (image_buffer == nullptr) {
+ memset(data, 0, texture_size * 4 * sizeof(float));
+ /* TODO: remove break when tiles are supported. */
+ break;
+ }
+ if (image_buffer->rect_float == nullptr) {
+ break;
}
+
+ int offset = 0;
+ for (int y = 0; y < texture_height; y++) {
+ float yf = y / (float)texture_height;
+ float v = uv_bounds->ymax * yf + uv_bounds->ymin * (1.0 - yf);
+ for (int x = 0; x < texture_width; x++) {
+ float xf = x / (float)texture_width;
+ float u = uv_bounds->xmax * xf + uv_bounds->xmin * (1.0 - xf);
+ nearest_interpolation_color(image_buffer,
+ nullptr,
+ &data[offset * 4],
+ u * image_buffer->x,
+ v * image_buffer->y);
+ offset++;
+ }
+ }
+ /* TODO: render other tiles as well. But we should do that with a scale copy algo in stead
+ * of the pixel sampling we do currently. */
+ break;
}
+
GPU_texture_update(gpu_texture, GPU_DATA_FLOAT, data);
MEM_freeN(data);
@@ -256,6 +324,7 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
IMAGE_TextureList *txl = vedata->txl;
IMAGE_StorageList *stl = vedata->stl;
IMAGE_PrivateData *pd = stl->pd;
+ PrivateDataAccessor pda(pd, txl);
if (!partial_update_is_valid(pd, image)) {
partial_update_free(pd);
@@ -265,7 +334,9 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
// Step: Find out which screen space textures are needed to draw on the screen. Remove the
// screen space textures that aren't needed.
const ARegion *region = draw_ctx->region;
- clipping::update_texture_slots_bounds(region, space, pd);
+ pda.clear_dirty_flag();
+ pda.update_screen_space_bounds(region);
+ pda.update_uv_bounds();
clipping::update_texture_slots_visibility(space, pd);
update_texture_slot_allocation(txl, pd);
More information about the Bf-blender-cvs
mailing list