diff options
Diffstat (limited to 'source/blender/draw/engines/image/image_batches.hh')
-rw-r--r-- | source/blender/draw/engines/image/image_batches.hh | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/source/blender/draw/engines/image/image_batches.hh b/source/blender/draw/engines/image/image_batches.hh new file mode 100644 index 00000000000..5f82504197a --- /dev/null +++ b/source/blender/draw/engines/image/image_batches.hh @@ -0,0 +1,106 @@ +/* + * 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 2021, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#pragma once + +#include "image_texture_info.hh" + +/** \brief Create GPUBatch for a IMAGE_ScreenSpaceTextureInfo. */ +class BatchUpdater { + TextureInfo &info; + + GPUVertFormat format = {0}; + int pos_id; + int uv_id; + + public: + BatchUpdater(TextureInfo &info) : info(info) + { + } + + void update_batch() + { + ensure_clear_batch(); + ensure_format(); + init_batch(); + } + + void discard_batch() + { + GPU_BATCH_DISCARD_SAFE(info.batch); + } + + private: + void ensure_clear_batch() + { + GPU_BATCH_CLEAR_SAFE(info.batch); + if (info.batch == nullptr) { + info.batch = GPU_batch_calloc(); + } + } + + void init_batch() + { + GPUVertBuf *vbo = create_vbo(); + GPU_batch_init_ex(info.batch, GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO); + } + + GPUVertBuf *create_vbo() + { + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 4); + float pos[4][2]; + fill_tri_fan_from_rctf(pos, info.clipping_bounds); + float uv[4][2]; + fill_tri_fan_from_rctf(uv, info.clipping_uv_bounds); + + for (int i = 0; i < 4; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, pos[i]); + GPU_vertbuf_attr_set(vbo, uv_id, i, uv[i]); + } + + return vbo; + } + + static void fill_tri_fan_from_rctf(float result[4][2], rctf &rect) + { + result[0][0] = rect.xmin; + result[0][1] = rect.ymin; + result[1][0] = rect.xmax; + result[1][1] = rect.ymin; + result[2][0] = rect.xmax; + result[2][1] = rect.ymax; + result[3][0] = rect.xmin; + result[3][1] = rect.ymax; + } + + void ensure_format() + { + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + pos_id = GPU_vertformat_attr_id_get(&format, "pos"); + uv_id = GPU_vertformat_attr_id_get(&format, "uv"); + } + } +}; |