2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-10-03 15:35:01 +00:00
|
|
|
* 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
|
2011-11-29 10:54:47 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2009-10-03 15:35:01 +00:00
|
|
|
*
|
|
|
|
* 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-10-03 15:35:01 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup gpu
|
2014-01-19 23:14:24 +11:00
|
|
|
*
|
2015-11-25 19:49:31 -05:00
|
|
|
* Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
|
2011-02-27 20:25:53 +00:00
|
|
|
*/
|
|
|
|
|
2009-11-25 13:40:43 +00:00
|
|
|
#include <limits.h>
|
2009-11-25 18:20:46 +00:00
|
|
|
#include <stddef.h>
|
2009-10-03 15:35:01 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
2009-10-05 16:48:52 +00:00
|
|
|
|
2012-03-14 06:32:25 +00:00
|
|
|
#include "BLI_bitmap.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_ghash.h"
|
2020-03-05 14:53:23 +01:00
|
|
|
#include "BLI_hash.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_math.h"
|
|
|
|
#include "BLI_math_color.h"
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
#include "BLI_math_color_blend.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2009-10-05 16:48:52 +00:00
|
|
|
|
|
|
|
#include "DNA_meshdata_types.h"
|
2020-07-09 17:16:24 +02:00
|
|
|
#include "DNA_userdef_types.h"
|
2009-10-05 16:48:52 +00:00
|
|
|
|
2009-10-03 15:35:01 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_ccg.h"
|
2015-07-31 21:04:23 +10:00
|
|
|
#include "BKE_mesh.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_paint.h"
|
2014-05-05 22:21:30 +03:00
|
|
|
#include "BKE_pbvh.h"
|
2020-04-01 01:03:20 +02:00
|
|
|
#include "BKE_subdiv_ccg.h"
|
2009-10-05 16:48:52 +00:00
|
|
|
|
2017-05-10 20:14:52 +10:00
|
|
|
#include "GPU_batch.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "GPU_buffers.h"
|
2017-05-10 20:14:52 +10:00
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
#include "gpu_private.h"
|
|
|
|
|
2012-12-30 18:24:54 +00:00
|
|
|
#include "bmesh.h"
|
|
|
|
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
/* XXX: the rest of the code in this file is used for optimized PBVH
|
2012-04-22 11:54:53 +00:00
|
|
|
* drawing and doesn't interact at all with the buffer code above */
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
|
2014-01-02 22:22:36 +02:00
|
|
|
struct GPU_PBVH_Buffers {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBuf *index_buf, *index_buf_fast;
|
2019-02-14 20:24:13 +01:00
|
|
|
GPUIndexBuf *index_lines_buf, *index_lines_buf_fast;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vert_buf;
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
|
2019-02-14 20:24:13 +01:00
|
|
|
GPUBatch *lines;
|
|
|
|
GPUBatch *lines_fast;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *triangles;
|
|
|
|
GPUBatch *triangles_fast;
|
2015-08-03 19:08:50 +02:00
|
|
|
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
/* mesh pointers in case buffer allocation fails */
|
2015-07-17 03:36:03 +10:00
|
|
|
const MPoly *mpoly;
|
|
|
|
const MLoop *mloop;
|
|
|
|
const MLoopTri *looptri;
|
2015-07-11 03:25:28 +10:00
|
|
|
const MVert *mvert;
|
2015-07-17 03:36:03 +10:00
|
|
|
|
2014-04-27 00:24:11 +10:00
|
|
|
const int *face_indices;
|
2015-07-17 03:36:03 +10:00
|
|
|
int face_indices_len;
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
|
|
|
|
/* grid pointers */
|
2012-05-10 20:33:09 +00:00
|
|
|
CCGKey gridkey;
|
|
|
|
CCGElem **grids;
|
2012-03-06 02:40:08 +00:00
|
|
|
const DMFlagMat *grid_flag_mats;
|
2013-07-22 23:20:48 +00:00
|
|
|
BLI_bitmap *const *grid_hidden;
|
2014-04-27 00:24:11 +10:00
|
|
|
const int *grid_indices;
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
int totgrid;
|
|
|
|
|
2015-11-25 19:49:31 -05:00
|
|
|
bool use_bmesh;
|
2019-09-27 22:42:57 +02:00
|
|
|
bool clear_bmesh_on_flush;
|
2012-12-30 18:24:54 +00:00
|
|
|
|
2018-09-12 12:18:35 +10:00
|
|
|
uint tot_tri, tot_quad;
|
2012-10-06 16:42:11 +00:00
|
|
|
|
2019-05-04 00:46:26 +02:00
|
|
|
short material_index;
|
|
|
|
|
2012-10-06 16:42:11 +00:00
|
|
|
/* The PBVH ensures that either all faces in the node are
|
2013-06-06 06:02:46 +00:00
|
|
|
* smooth-shaded or all faces are flat-shaded */
|
2015-11-25 19:49:31 -05:00
|
|
|
bool smooth;
|
2012-10-22 17:33:53 +00:00
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
bool show_overlay;
|
2011-11-05 03:29:37 +00:00
|
|
|
};
|
2015-03-23 15:29:42 -04:00
|
|
|
|
2018-03-19 18:09:00 -03:00
|
|
|
static struct {
|
2019-09-27 22:42:57 +02:00
|
|
|
GPUVertFormat format;
|
2020-03-05 14:53:23 +01:00
|
|
|
uint pos, nor, msk, col, fset;
|
2019-09-27 22:42:57 +02:00
|
|
|
} g_vbo_id = {{0}};
|
2017-05-10 20:14:52 +10:00
|
|
|
|
2019-02-14 20:24:13 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name PBVH Utils
|
|
|
|
* \{ */
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
void gpu_pbvh_init()
|
|
|
|
{
|
|
|
|
/* Initialize vertex buffer (match 'VertexBufferFormat'). */
|
|
|
|
if (g_vbo_id.format.attr_len == 0) {
|
|
|
|
g_vbo_id.pos = GPU_vertformat_attr_add(
|
|
|
|
&g_vbo_id.format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
g_vbo_id.nor = GPU_vertformat_attr_add(
|
|
|
|
&g_vbo_id.format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
|
|
/* TODO: Do not allocate these `.msk` and `.col` when they are not used. */
|
|
|
|
g_vbo_id.msk = GPU_vertformat_attr_add(
|
2020-03-15 00:03:37 +01:00
|
|
|
&g_vbo_id.format, "msk", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
2019-09-27 22:42:57 +02:00
|
|
|
g_vbo_id.col = GPU_vertformat_attr_add(
|
2020-01-17 16:05:19 +01:00
|
|
|
&g_vbo_id.format, "ac", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
2020-03-05 14:53:23 +01:00
|
|
|
g_vbo_id.fset = GPU_vertformat_attr_add(
|
|
|
|
&g_vbo_id.format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
2019-09-27 22:42:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void gpu_pbvh_exit()
|
|
|
|
{
|
|
|
|
/* Nothing to do. */
|
|
|
|
}
|
|
|
|
|
2018-03-19 18:09:00 -03:00
|
|
|
/* Allocates a non-initialized buffer to be sent to GPU.
|
|
|
|
* Return is false it indicates that the memory map failed. */
|
2018-09-12 12:18:35 +10:00
|
|
|
static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, uint vert_len)
|
2017-05-10 20:14:52 +10:00
|
|
|
{
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Keep so we can test #GPU_USAGE_DYNAMIC buffer use.
|
|
|
|
* Not that format initialization match in both blocks.
|
|
|
|
* Do this to keep braces balanced - otherwise indentation breaks. */
|
|
|
|
#if 0
|
2018-03-19 18:09:00 -03:00
|
|
|
if (buffers->vert_buf == NULL) {
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Initialize vertex buffer (match 'VertexBufferFormat'). */
|
2019-09-27 22:42:57 +02:00
|
|
|
buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&g_vbo_id.format, GPU_USAGE_DYNAMIC);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
|
2018-03-19 18:09:00 -03:00
|
|
|
}
|
2018-07-08 13:14:49 +02:00
|
|
|
else if (vert_len != buffers->vert_buf->vertex_len) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_resize(buffers->vert_buf, vert_len);
|
2018-03-19 18:09:00 -03:00
|
|
|
}
|
|
|
|
#else
|
2019-04-17 08:56:59 +02:00
|
|
|
if (buffers->vert_buf == NULL) {
|
|
|
|
/* Initialize vertex buffer (match 'VertexBufferFormat'). */
|
2019-09-27 22:42:57 +02:00
|
|
|
buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&g_vbo_id.format, GPU_USAGE_STATIC);
|
2018-03-19 18:09:00 -03:00
|
|
|
}
|
2020-09-06 16:40:07 +02:00
|
|
|
if (GPU_vertbuf_get_data(buffers->vert_buf) == NULL ||
|
|
|
|
GPU_vertbuf_get_vertex_len(buffers->vert_buf) != vert_len) {
|
2020-05-19 21:27:10 +02:00
|
|
|
/* Allocate buffer if not allocated yet or size changed. */
|
|
|
|
GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len);
|
|
|
|
}
|
2018-03-19 18:09:00 -03:00
|
|
|
#endif
|
2019-09-27 22:42:57 +02:00
|
|
|
|
2020-09-06 16:40:07 +02:00
|
|
|
return GPU_vertbuf_get_data(buffers->vert_buf) != NULL;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
|
|
|
|
{
|
|
|
|
if (buffers->triangles == NULL) {
|
|
|
|
buffers->triangles = GPU_batch_create(prim,
|
|
|
|
buffers->vert_buf,
|
2019-04-17 01:38:15 +02:00
|
|
|
/* can be NULL if buffer is empty */
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->index_buf);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) {
|
|
|
|
buffers->triangles_fast = GPU_batch_create(prim, buffers->vert_buf, buffers->index_buf_fast);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (buffers->lines == NULL) {
|
2019-04-17 01:38:15 +02:00
|
|
|
buffers->lines = GPU_batch_create(GPU_PRIM_LINES,
|
|
|
|
buffers->vert_buf,
|
|
|
|
/* can be NULL if buffer is empty */
|
|
|
|
buffers->index_lines_buf);
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if ((buffers->lines_fast == NULL) && buffers->index_lines_buf_fast) {
|
|
|
|
buffers->lines_fast = GPU_batch_create(
|
|
|
|
GPU_PRIM_LINES, buffers->vert_buf, buffers->index_lines_buf_fast);
|
2019-02-14 20:24:13 +01:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/** \} */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Mesh PBVH
|
2019-02-14 20:24:13 +01:00
|
|
|
* \{ */
|
|
|
|
|
2020-03-26 15:50:03 +01:00
|
|
|
static bool gpu_pbvh_is_looptri_visible(const MLoopTri *lt,
|
|
|
|
const MVert *mvert,
|
|
|
|
const MLoop *mloop,
|
|
|
|
const int *sculpt_face_sets)
|
|
|
|
{
|
|
|
|
return (!paint_is_face_hidden(lt, mvert, mloop) && sculpt_face_sets &&
|
|
|
|
sculpt_face_sets[lt->poly] > SCULPT_FACE_SET_NONE);
|
|
|
|
}
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
/* Threaded - do not call any functions that use OpenGL calls! */
|
2019-04-17 08:56:59 +02:00
|
|
|
void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|
|
|
const MVert *mvert,
|
|
|
|
const float *vmask,
|
2019-04-16 14:00:16 +02:00
|
|
|
const MLoopCol *vcol,
|
2020-03-05 14:53:23 +01:00
|
|
|
const int *sculpt_face_sets,
|
|
|
|
const int face_sets_color_seed,
|
2020-03-09 20:10:56 +01:00
|
|
|
const int face_sets_color_default,
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
const MPropCol *vtcol,
|
2019-04-17 08:56:59 +02:00
|
|
|
const int update_flags)
|
|
|
|
{
|
2019-09-28 19:15:06 +02:00
|
|
|
const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
|
2020-03-05 14:53:23 +01:00
|
|
|
const bool show_face_sets = sculpt_face_sets &&
|
|
|
|
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
|
2020-07-09 17:16:24 +02:00
|
|
|
const bool show_vcol = (vcol || (vtcol && U.experimental.use_sculpt_vertex_colors)) &&
|
|
|
|
(update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
|
2019-04-17 08:56:59 +02:00
|
|
|
bool empty_mask = true;
|
2020-03-21 18:09:43 +01:00
|
|
|
bool default_face_set = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
{
|
2020-05-14 15:27:11 +02:00
|
|
|
const int totelem = buffers->tot_tri * 3;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Build VBO */
|
|
|
|
if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) {
|
2019-09-28 19:15:06 +02:00
|
|
|
GPUVertBufRaw pos_step = {0};
|
|
|
|
GPUVertBufRaw nor_step = {0};
|
|
|
|
GPUVertBufRaw msk_step = {0};
|
2020-03-05 14:53:23 +01:00
|
|
|
GPUVertBufRaw fset_step = {0};
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
GPUVertBufRaw col_step = {0};
|
2019-09-28 19:15:06 +02:00
|
|
|
|
|
|
|
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.pos, &pos_step);
|
|
|
|
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.nor, &nor_step);
|
2020-03-05 14:53:23 +01:00
|
|
|
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.msk, &msk_step);
|
|
|
|
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.fset, &fset_step);
|
2019-09-28 19:15:06 +02:00
|
|
|
if (show_vcol) {
|
|
|
|
GPU_vertbuf_attr_get_raw_data(buffers->vert_buf, g_vbo_id.col, &col_step);
|
|
|
|
}
|
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
/* calculate normal for each polygon only once */
|
|
|
|
uint mpoly_prev = UINT_MAX;
|
|
|
|
short no[3] = {0, 0, 0};
|
2019-09-28 19:15:06 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
for (uint i = 0; i < buffers->face_indices_len; i++) {
|
|
|
|
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
|
|
|
|
const uint vtri[3] = {
|
|
|
|
buffers->mloop[lt->tri[0]].v,
|
|
|
|
buffers->mloop[lt->tri[1]].v,
|
|
|
|
buffers->mloop[lt->tri[2]].v,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!gpu_pbvh_is_looptri_visible(lt, mvert, buffers->mloop, sculpt_face_sets)) {
|
|
|
|
continue;
|
2020-03-05 14:53:23 +01:00
|
|
|
}
|
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
/* Face normal and mask */
|
|
|
|
if (lt->poly != mpoly_prev && !buffers->smooth) {
|
|
|
|
const MPoly *mp = &buffers->mpoly[lt->poly];
|
|
|
|
float fno[3];
|
|
|
|
BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno);
|
|
|
|
normal_float_to_short_v3(no, fno);
|
|
|
|
mpoly_prev = lt->poly;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-16 14:00:16 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
|
|
|
|
if (show_face_sets) {
|
|
|
|
const int fset = abs(sculpt_face_sets[lt->poly]);
|
|
|
|
/* Skip for the default color Face Set to render it white. */
|
|
|
|
if (fset != face_sets_color_default) {
|
2020-09-18 19:30:02 +02:00
|
|
|
BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
|
2020-05-14 15:27:11 +02:00
|
|
|
default_face_set = false;
|
2019-04-16 14:00:16 +02:00
|
|
|
}
|
|
|
|
}
|
2020-03-05 14:53:23 +01:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
float fmask = 0.0f;
|
|
|
|
uchar cmask = 0;
|
|
|
|
if (show_mask && !buffers->smooth) {
|
|
|
|
fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
|
|
|
|
cmask = (uchar)(fmask * 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint j = 0; j < 3; j++) {
|
|
|
|
const MVert *v = &mvert[vtri[j]];
|
|
|
|
copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), v->co);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
if (buffers->smooth) {
|
|
|
|
copy_v3_v3_short(no, v->no);
|
2020-03-05 14:53:23 +01:00
|
|
|
}
|
2020-05-14 15:27:11 +02:00
|
|
|
copy_v3_v3_short(GPU_vertbuf_raw_step(&nor_step), no);
|
2020-03-05 14:53:23 +01:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
if (show_mask && buffers->smooth) {
|
|
|
|
cmask = (uchar)(vmask[vtri[j]] * 255);
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
*(uchar *)GPU_vertbuf_raw_step(&msk_step) = cmask;
|
|
|
|
empty_mask = empty_mask && (cmask == 0);
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
/* Vertex Colors. */
|
2020-05-14 15:27:11 +02:00
|
|
|
if (show_vcol) {
|
2020-06-24 16:45:17 +02:00
|
|
|
ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
2020-07-09 17:16:24 +02:00
|
|
|
if (vtcol && U.experimental.use_sculpt_vertex_colors) {
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]);
|
|
|
|
scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]);
|
|
|
|
scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]);
|
|
|
|
scol[3] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[3]);
|
|
|
|
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const uint loop_index = lt->tri[j];
|
|
|
|
const MLoopCol *mcol = &vcol[loop_index];
|
|
|
|
scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
|
|
|
|
scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
|
|
|
|
scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
|
|
|
|
scol[3] = unit_float_to_ushort_clamp(mcol->a * (1.0f / 255.0f));
|
|
|
|
memcpy(GPU_vertbuf_raw_step(&col_step), scol, sizeof(scol));
|
|
|
|
}
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2020-06-24 16:45:17 +02:00
|
|
|
/* Face Sets. */
|
2020-08-08 13:29:21 +10:00
|
|
|
memcpy(GPU_vertbuf_raw_step(&fset_step), face_set_color, sizeof(uchar[3]));
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
|
|
|
|
gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-04 00:46:26 +02:00
|
|
|
/* Get material index from the first face of this buffer. */
|
|
|
|
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[0]];
|
|
|
|
const MPoly *mp = &buffers->mpoly[lt->poly];
|
|
|
|
buffers->material_index = mp->mat_nr;
|
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
buffers->show_overlay = !empty_mask || !default_face_set;
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->mvert = mvert;
|
|
|
|
}
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
/* Threaded - do not call any functions that use OpenGL calls! */
|
2020-05-14 15:27:11 +02:00
|
|
|
GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
|
2019-04-17 08:56:59 +02:00
|
|
|
const MLoop *mloop,
|
|
|
|
const MLoopTri *looptri,
|
|
|
|
const MVert *mvert,
|
|
|
|
const int *face_indices,
|
2020-03-05 14:53:23 +01:00
|
|
|
const int *sculpt_face_sets,
|
2019-10-09 19:03:57 +02:00
|
|
|
const int face_indices_len,
|
|
|
|
const struct Mesh *mesh)
|
2019-04-17 08:56:59 +02:00
|
|
|
{
|
|
|
|
GPU_PBVH_Buffers *buffers;
|
|
|
|
int i, tottri;
|
2019-10-09 19:03:57 +02:00
|
|
|
int tot_real_edges = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* smooth or flat for all */
|
|
|
|
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
buffers->show_overlay = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Count the number of visible triangles */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (i = 0, tottri = 0; i < face_indices_len; i++) {
|
2019-04-17 08:56:59 +02:00
|
|
|
const MLoopTri *lt = &looptri[face_indices[i]];
|
2020-03-09 11:59:57 -03:00
|
|
|
if (gpu_pbvh_is_looptri_visible(lt, mvert, mloop, sculpt_face_sets)) {
|
2019-10-09 19:03:57 +02:00
|
|
|
int r_edges[3];
|
|
|
|
BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
if (r_edges[j] != -1) {
|
|
|
|
tot_real_edges++;
|
|
|
|
}
|
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
tottri++;
|
2019-04-22 09:32:37 +10:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (tottri == 0) {
|
|
|
|
buffers->tot_tri = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->mpoly = mpoly;
|
|
|
|
buffers->mloop = mloop;
|
|
|
|
buffers->looptri = looptri;
|
|
|
|
buffers->face_indices = face_indices;
|
|
|
|
buffers->face_indices_len = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
return buffers;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
/* Fill the only the line buffer. */
|
|
|
|
GPUIndexBufBuilder elb_lines;
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tot_real_edges, INT_MAX);
|
|
|
|
int vert_idx = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
for (i = 0; i < face_indices_len; i++) {
|
|
|
|
const MLoopTri *lt = &looptri[face_indices[i]];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
/* Skip hidden faces */
|
|
|
|
if (!gpu_pbvh_is_looptri_visible(lt, mvert, mloop, sculpt_face_sets)) {
|
|
|
|
continue;
|
2017-05-10 20:14:52 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-14 15:27:11 +02:00
|
|
|
int r_edges[3];
|
|
|
|
BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges);
|
|
|
|
if (r_edges[0] != -1) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 0, vert_idx * 3 + 1);
|
2009-10-03 15:35:01 +00:00
|
|
|
}
|
2020-05-14 15:27:11 +02:00
|
|
|
if (r_edges[1] != -1) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 1, vert_idx * 3 + 2);
|
|
|
|
}
|
|
|
|
if (r_edges[2] != -1) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, vert_idx * 3 + 2, vert_idx * 3 + 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
vert_idx++;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2020-05-14 15:27:11 +02:00
|
|
|
buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->tot_tri = tottri;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->mpoly = mpoly;
|
|
|
|
buffers->mloop = mloop;
|
|
|
|
buffers->looptri = looptri;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->face_indices = face_indices;
|
|
|
|
buffers->face_indices_len = face_indices_len;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
return buffers;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/** \} */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Grid PBVH
|
2019-02-14 20:24:13 +01:00
|
|
|
* \{ */
|
|
|
|
|
2020-04-01 01:03:20 +02:00
|
|
|
static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers *buffers,
|
2020-04-01 10:41:34 +11:00
|
|
|
SubdivCCG *UNUSED(subdiv_ccg),
|
|
|
|
const int *UNUSED(face_sets),
|
2020-07-13 11:27:09 +02:00
|
|
|
const int *grid_indices,
|
2020-04-01 01:03:20 +02:00
|
|
|
uint visible_quad_len,
|
|
|
|
int totgrid,
|
|
|
|
int gridsize)
|
2019-04-17 08:56:59 +02:00
|
|
|
{
|
|
|
|
GPUIndexBufBuilder elb, elb_lines;
|
|
|
|
GPUIndexBufBuilder elb_fast, elb_lines_fast;
|
|
|
|
|
|
|
|
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX);
|
|
|
|
GPU_indexbuf_init(&elb_fast, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX);
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX);
|
|
|
|
GPU_indexbuf_init(&elb_lines_fast, GPU_PRIM_LINES, 4 * totgrid, INT_MAX);
|
|
|
|
|
|
|
|
if (buffers->smooth) {
|
|
|
|
uint offset = 0;
|
|
|
|
const uint grid_vert_len = gridsize * gridsize;
|
|
|
|
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
|
|
|
|
uint v0, v1, v2, v3;
|
|
|
|
bool grid_visible = false;
|
|
|
|
|
|
|
|
BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
|
|
|
|
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int j = 0; j < gridsize - 1; j++) {
|
|
|
|
for (int k = 0; k < gridsize - 1; k++) {
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Skip hidden grid face */
|
|
|
|
if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Indices in a Clockwise QUAD disposition. */
|
|
|
|
v0 = offset + j * gridsize + k;
|
|
|
|
v1 = v0 + 1;
|
|
|
|
v2 = v1 + gridsize;
|
|
|
|
v3 = v2 - 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
|
|
|
|
GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (j + 2 == gridsize) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
|
2019-02-22 04:00:19 +01:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
grid_visible = true;
|
2019-02-22 04:00:19 +01:00
|
|
|
}
|
2019-09-13 16:18:18 +02:00
|
|
|
|
|
|
|
if (grid_visible) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
|
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (grid_visible) {
|
|
|
|
/* Grid corners */
|
|
|
|
v0 = offset;
|
|
|
|
v1 = offset + gridsize - 1;
|
|
|
|
v2 = offset + grid_vert_len - 1;
|
|
|
|
v3 = offset + grid_vert_len - gridsize;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
|
|
|
|
GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
|
2019-02-22 04:00:19 +01:00
|
|
|
}
|
2018-09-14 12:19:41 +02:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint offset = 0;
|
2020-03-06 17:18:10 +01:00
|
|
|
const uint grid_vert_len = square_uint(gridsize - 1) * 4;
|
2019-04-17 08:56:59 +02:00
|
|
|
for (int i = 0; i < totgrid; i++, offset += grid_vert_len) {
|
|
|
|
bool grid_visible = false;
|
|
|
|
BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]];
|
|
|
|
|
|
|
|
uint v0, v1, v2, v3;
|
|
|
|
for (int j = 0; j < gridsize - 1; j++) {
|
|
|
|
for (int k = 0; k < gridsize - 1; k++) {
|
|
|
|
/* Skip hidden grid face */
|
|
|
|
if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* VBO data are in a Clockwise QUAD disposition. */
|
|
|
|
v0 = offset + (j * (gridsize - 1) + k) * 4;
|
|
|
|
v1 = v0 + 1;
|
|
|
|
v2 = v0 + 2;
|
|
|
|
v3 = v0 + 3;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1);
|
|
|
|
GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v0, v3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (j + 2 == gridsize) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
|
2018-09-14 12:19:41 +02:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
grid_visible = true;
|
2019-02-22 04:00:19 +01:00
|
|
|
}
|
2019-09-13 16:18:18 +02:00
|
|
|
|
|
|
|
if (grid_visible) {
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
|
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (grid_visible) {
|
|
|
|
/* Grid corners */
|
|
|
|
v0 = offset;
|
|
|
|
v1 = offset + (gridsize - 1) * 4 - 3;
|
|
|
|
v2 = offset + grid_vert_len - 2;
|
|
|
|
v3 = offset + grid_vert_len - (gridsize - 1) * 4 + 3;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1);
|
|
|
|
GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-09-14 12:19:41 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->index_buf = GPU_indexbuf_build(&elb);
|
|
|
|
buffers->index_buf_fast = GPU_indexbuf_build(&elb_fast);
|
|
|
|
buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
|
|
|
|
buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines_fast);
|
|
|
|
}
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
|
|
|
|
const struct DMFlagMat *grid_flag_mats,
|
2020-07-13 11:27:09 +02:00
|
|
|
const int *grid_indices)
|
2019-09-27 22:42:57 +02:00
|
|
|
{
|
|
|
|
const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
|
|
|
|
|
|
|
if (buffers->smooth != smooth) {
|
|
|
|
buffers->smooth = smooth;
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->triangles);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
|
|
|
|
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Threaded - do not call any functions that use OpenGL calls! */
|
2019-04-17 08:56:59 +02:00
|
|
|
void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
|
2020-04-01 01:03:20 +02:00
|
|
|
SubdivCCG *subdiv_ccg,
|
2019-04-17 08:56:59 +02:00
|
|
|
CCGElem **grids,
|
2020-04-01 01:03:20 +02:00
|
|
|
const struct DMFlagMat *grid_flag_mats,
|
2019-04-17 08:56:59 +02:00
|
|
|
int *grid_indices,
|
|
|
|
int totgrid,
|
2020-04-01 01:03:20 +02:00
|
|
|
const int *sculpt_face_sets,
|
|
|
|
const int face_sets_color_seed,
|
|
|
|
const int face_sets_color_default,
|
|
|
|
const struct CCGKey *key,
|
2019-04-17 08:56:59 +02:00
|
|
|
const int update_flags)
|
|
|
|
{
|
|
|
|
const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
|
2019-04-16 14:00:16 +02:00
|
|
|
const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
|
2020-04-15 21:20:39 +02:00
|
|
|
const bool show_face_sets = sculpt_face_sets &&
|
|
|
|
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
|
2019-04-17 08:56:59 +02:00
|
|
|
bool empty_mask = true;
|
2020-04-01 01:03:20 +02:00
|
|
|
bool default_face_set = true;
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
int i, j, k, x, y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Build VBO */
|
|
|
|
const int has_mask = key->has_mask;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
2019-04-17 08:56:59 +02:00
|
|
|
|
2020-03-06 17:18:10 +01:00
|
|
|
uint vert_per_grid = (buffers->smooth) ? key->grid_area : (square_i(key->grid_size - 1) * 4);
|
2019-09-27 22:42:57 +02:00
|
|
|
uint vert_count = totgrid * vert_per_grid;
|
2019-04-17 08:56:59 +02:00
|
|
|
|
|
|
|
if (buffers->index_buf == NULL) {
|
|
|
|
uint visible_quad_len = BKE_pbvh_count_grid_quads(
|
|
|
|
(BLI_bitmap **)buffers->grid_hidden, grid_indices, totgrid, key->grid_size);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* totally hidden node, return here to avoid BufferData with zero below. */
|
|
|
|
if (visible_quad_len == 0) {
|
|
|
|
return;
|
2018-09-14 12:19:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-01 01:03:20 +02:00
|
|
|
gpu_pbvh_grid_fill_index_buffers(buffers,
|
|
|
|
subdiv_ccg,
|
|
|
|
sculpt_face_sets,
|
|
|
|
grid_indices,
|
|
|
|
visible_quad_len,
|
|
|
|
totgrid,
|
|
|
|
key->grid_size);
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
uint vbo_index_offset = 0;
|
|
|
|
/* Build VBO */
|
|
|
|
if (gpu_pbvh_vert_buf_data_set(buffers, vert_count)) {
|
|
|
|
GPUIndexBufBuilder elb_lines;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (buffers->index_lines_buf == NULL) {
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, totgrid * key->grid_area * 2, vert_count);
|
|
|
|
}
|
|
|
|
|
2019-09-08 00:12:26 +10:00
|
|
|
for (i = 0; i < totgrid; i++) {
|
2020-04-01 01:03:20 +02:00
|
|
|
const int grid_index = grid_indices[i];
|
|
|
|
CCGElem *grid = grids[grid_index];
|
2019-04-17 08:56:59 +02:00
|
|
|
int vbo_index = vbo_index_offset;
|
|
|
|
|
2020-04-01 01:03:20 +02:00
|
|
|
uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
|
|
|
|
|
2020-04-15 21:20:39 +02:00
|
|
|
if (show_face_sets && subdiv_ccg && sculpt_face_sets) {
|
2020-04-22 16:32:16 +02:00
|
|
|
const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, grid_index);
|
2020-04-01 01:03:20 +02:00
|
|
|
|
|
|
|
const int fset = abs(sculpt_face_sets[face_index]);
|
|
|
|
/* Skip for the default color Face Set to render it white. */
|
|
|
|
if (fset != face_sets_color_default) {
|
2020-09-18 19:30:02 +02:00
|
|
|
BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
|
2020-04-01 01:03:20 +02:00
|
|
|
default_face_set = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (buffers->smooth) {
|
|
|
|
for (y = 0; y < key->grid_size; y++) {
|
|
|
|
for (x = 0; x < key->grid_size; x++) {
|
|
|
|
CCGElem *elem = CCG_grid_elem(key, grid, x, y);
|
|
|
|
GPU_vertbuf_attr_set(
|
|
|
|
buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem));
|
|
|
|
|
|
|
|
short no_short[3];
|
|
|
|
normal_float_to_short_v3(no_short, CCG_elem_no(key, elem));
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short);
|
|
|
|
|
|
|
|
if (has_mask && show_mask) {
|
|
|
|
float fmask = *CCG_elem_mask(key, elem);
|
2020-03-15 00:03:37 +01:00
|
|
|
uchar cmask = (uchar)(fmask * 255);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &cmask);
|
|
|
|
empty_mask = empty_mask && (cmask == 0);
|
2012-05-10 20:36:24 +00:00
|
|
|
}
|
2019-04-16 14:00:16 +02:00
|
|
|
|
|
|
|
if (show_vcol) {
|
2020-08-07 22:36:11 +10:00
|
|
|
const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
2019-04-16 14:00:16 +02:00
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &vcol);
|
|
|
|
}
|
|
|
|
|
2020-04-01 01:03:20 +02:00
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, vbo_index, &face_set_color);
|
2020-03-05 14:53:23 +01:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
vbo_index += 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-09-14 12:19:41 +02:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
vbo_index_offset += key->grid_area;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (j = 0; j < key->grid_size - 1; j++) {
|
|
|
|
for (k = 0; k < key->grid_size - 1; k++) {
|
|
|
|
CCGElem *elems[4] = {
|
|
|
|
CCG_grid_elem(key, grid, k, j),
|
|
|
|
CCG_grid_elem(key, grid, k + 1, j),
|
|
|
|
CCG_grid_elem(key, grid, k + 1, j + 1),
|
|
|
|
CCG_grid_elem(key, grid, k, j + 1),
|
|
|
|
};
|
|
|
|
float *co[4] = {
|
|
|
|
CCG_elem_co(key, elems[0]),
|
|
|
|
CCG_elem_co(key, elems[1]),
|
|
|
|
CCG_elem_co(key, elems[2]),
|
|
|
|
CCG_elem_co(key, elems[3]),
|
|
|
|
};
|
|
|
|
|
|
|
|
float fno[3];
|
|
|
|
short no_short[3];
|
|
|
|
/* Note: Clockwise indices ordering, that's why we invert order here. */
|
|
|
|
normal_quad_v3(fno, co[3], co[2], co[1], co[0]);
|
|
|
|
normal_float_to_short_v3(no_short, fno);
|
|
|
|
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 0, co[0]);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 0, no_short);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 1, co[1]);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 1, no_short);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 2, co[2]);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 2, no_short);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 3, co[3]);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short);
|
|
|
|
|
|
|
|
if (has_mask && show_mask) {
|
2020-03-15 00:03:37 +01:00
|
|
|
float fmask = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) +
|
2019-04-17 08:56:59 +02:00
|
|
|
*CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) *
|
|
|
|
0.25f;
|
2020-03-15 00:03:37 +01:00
|
|
|
uchar cmask = (uchar)(fmask * 255);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &cmask);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &cmask);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &cmask);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &cmask);
|
|
|
|
empty_mask = empty_mask && (cmask == 0);
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2019-05-04 00:46:26 +02:00
|
|
|
|
2020-08-07 22:36:11 +10:00
|
|
|
const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
2019-04-16 14:00:16 +02:00
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &vcol);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &vcol);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &vcol);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 3, &vcol);
|
2020-03-05 14:53:23 +01:00
|
|
|
|
2020-04-01 01:03:20 +02:00
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, vbo_index + 0, &face_set_color);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, vbo_index + 1, &face_set_color);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, vbo_index + 2, &face_set_color);
|
|
|
|
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, vbo_index + 3, &face_set_color);
|
2020-03-05 14:53:23 +01:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
vbo_index += 4;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2020-03-06 17:18:10 +01:00
|
|
|
vbo_index_offset += square_i(key->grid_size - 1) * 4;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-04 00:46:26 +02:00
|
|
|
/* Get material index from the first face of this buffer. */
|
|
|
|
buffers->material_index = grid_flag_mats[grid_indices[0]].mat_nr;
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->grids = grids;
|
|
|
|
buffers->grid_indices = grid_indices;
|
|
|
|
buffers->totgrid = totgrid;
|
|
|
|
buffers->grid_flag_mats = grid_flag_mats;
|
|
|
|
buffers->gridkey = *key;
|
2020-04-01 01:03:20 +02:00
|
|
|
buffers->show_overlay = !empty_mask || !default_face_set;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
/* Threaded - do not call any functions that use OpenGL calls! */
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden)
|
|
|
|
{
|
|
|
|
GPU_PBVH_Buffers *buffers;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
|
|
|
|
buffers->grid_hidden = grid_hidden;
|
|
|
|
buffers->totgrid = totgrid;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
buffers->show_overlay = false;
|
2019-04-17 08:56:59 +02:00
|
|
|
|
|
|
|
return buffers;
|
|
|
|
}
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
|
2012-02-22 23:30:56 +00:00
|
|
|
#undef FILL_QUAD_BUFFER
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/** \} */
|
2019-02-14 20:24:13 +01:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name BMesh PBVH
|
2019-02-14 20:24:13 +01:00
|
|
|
* \{ */
|
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
/* Output a BMVert into a VertexBufferFormat array at v_index. */
|
|
|
|
static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
|
|
|
|
GPUVertBuf *vert_buf,
|
|
|
|
int v_index,
|
|
|
|
const float fno[3],
|
|
|
|
const float *fmask,
|
|
|
|
const int cd_vert_mask_offset,
|
|
|
|
const bool show_mask,
|
|
|
|
const bool show_vcol,
|
|
|
|
bool *empty_mask)
|
2019-04-17 08:56:59 +02:00
|
|
|
{
|
2019-10-02 18:02:41 +02:00
|
|
|
/* Vertex should always be visible if it's used by a visible face. */
|
|
|
|
BLI_assert(!BM_elem_flag_test(v, BM_ELEM_HIDDEN));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
/* Set coord, normal, and mask */
|
|
|
|
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, v_index, v->co);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
short no_short[3];
|
|
|
|
normal_float_to_short_v3(no_short, fno ? fno : v->no);
|
|
|
|
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, v_index, no_short);
|
2019-04-16 14:00:16 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
if (show_mask) {
|
|
|
|
float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
|
2020-03-15 00:03:37 +01:00
|
|
|
uchar cmask = (uchar)(effective_mask * 255);
|
|
|
|
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, v_index, &cmask);
|
|
|
|
*empty_mask = *empty_mask && (cmask == 0);
|
2019-10-02 18:02:41 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
if (show_vcol) {
|
2020-08-07 22:36:11 +10:00
|
|
|
const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
|
2019-10-02 18:02:41 +02:00
|
|
|
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol);
|
2012-12-30 18:24:54 +00:00
|
|
|
}
|
2020-03-05 14:53:23 +01:00
|
|
|
|
|
|
|
/* Add default face sets color to avoid artifacts. */
|
2020-08-07 22:36:11 +10:00
|
|
|
const uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
|
2020-03-05 14:53:23 +01:00
|
|
|
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.fset, v_index, &face_set);
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
|
|
|
|
static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts, GSet *bm_other_verts)
|
|
|
|
{
|
|
|
|
GSetIterator gs_iter;
|
|
|
|
int totvert = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GSET_ITER (gs_iter, bm_unique_verts) {
|
|
|
|
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
|
2019-04-22 09:32:37 +10:00
|
|
|
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
|
2019-04-17 08:56:59 +02:00
|
|
|
totvert++;
|
2019-04-22 09:32:37 +10:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
|
|
|
GSET_ITER (gs_iter, bm_other_verts) {
|
|
|
|
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
|
2019-04-22 09:32:37 +10:00
|
|
|
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
|
2019-04-17 08:56:59 +02:00
|
|
|
totvert++;
|
2019-04-22 09:32:37 +10:00
|
|
|
}
|
2012-12-30 18:24:54 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
return totvert;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Return the total number of visible faces */
|
|
|
|
static int gpu_bmesh_face_visible_count(GSet *bm_faces)
|
|
|
|
{
|
|
|
|
GSetIterator gh_iter;
|
|
|
|
int totface = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GSET_ITER (gh_iter, bm_faces) {
|
|
|
|
BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:32:37 +10:00
|
|
|
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
2019-04-17 08:56:59 +02:00
|
|
|
totface++;
|
2019-04-22 09:32:37 +10:00
|
|
|
}
|
2012-12-30 18:24:54 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
return totface;
|
|
|
|
}
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers)
|
|
|
|
{
|
|
|
|
if (buffers->smooth) {
|
|
|
|
/* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->triangles);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Creates a vertex buffer (coordinate, normal, color) and, if smooth
|
2019-09-27 22:42:57 +02:00
|
|
|
* shading, an element index buffer.
|
|
|
|
* Threaded - do not call any functions that use OpenGL calls! */
|
2019-04-17 08:56:59 +02:00
|
|
|
void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|
|
|
BMesh *bm,
|
|
|
|
GSet *bm_faces,
|
|
|
|
GSet *bm_unique_verts,
|
|
|
|
GSet *bm_other_verts,
|
|
|
|
const int update_flags)
|
|
|
|
{
|
|
|
|
const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
|
2019-04-16 14:00:16 +02:00
|
|
|
const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
|
2019-10-02 18:02:41 +02:00
|
|
|
int tottri, totvert;
|
2019-04-17 08:56:59 +02:00
|
|
|
bool empty_mask = true;
|
2019-09-13 16:18:18 +02:00
|
|
|
BMFace *f = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Count visible triangles */
|
|
|
|
tottri = gpu_bmesh_face_visible_count(bm_faces);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (buffers->smooth) {
|
|
|
|
/* Count visible vertices */
|
|
|
|
totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
totvert = tottri * 3;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
if (!tottri) {
|
2019-06-06 10:46:47 -03:00
|
|
|
if (BLI_gset_len(bm_faces) != 0) {
|
|
|
|
/* Node is just hidden. */
|
|
|
|
}
|
|
|
|
else {
|
2019-09-27 22:42:57 +02:00
|
|
|
buffers->clear_bmesh_on_flush = true;
|
2019-06-06 10:46:47 -03:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers->tot_tri = 0;
|
|
|
|
return;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-06 10:46:47 -03:00
|
|
|
/* TODO, make mask layer optional for bmesh buffer */
|
|
|
|
const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* Fill vertex buffer */
|
2019-10-02 18:02:41 +02:00
|
|
|
if (!gpu_pbvh_vert_buf_data_set(buffers, totvert)) {
|
|
|
|
/* Memory map failed */
|
|
|
|
return;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
int v_index = 0;
|
2019-04-17 08:56:59 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
if (buffers->smooth) {
|
|
|
|
/* Fill the vertex and triangle buffer in one pass over faces. */
|
|
|
|
GPUIndexBufBuilder elb, elb_lines;
|
|
|
|
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, totvert);
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
GHash *bm_vert_to_index = BLI_ghash_int_new_ex("bm_vert_to_index", totvert);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
GSetIterator gs_iter;
|
|
|
|
GSET_ITER (gs_iter, bm_faces) {
|
|
|
|
f = BLI_gsetIterator_getKey(&gs_iter);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
|
|
|
BMVert *v[3];
|
|
|
|
BM_face_as_array_vert_tri(f, v);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
uint idx[3];
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
void **idx_p;
|
|
|
|
if (!BLI_ghash_ensure_p(bm_vert_to_index, v[i], &idx_p)) {
|
|
|
|
/* Add vertex to the vertex buffer each time a new one is encountered */
|
|
|
|
*idx_p = POINTER_FROM_UINT(v_index);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
gpu_bmesh_vert_to_buffer_copy(v[i],
|
|
|
|
buffers->vert_buf,
|
|
|
|
v_index,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
cd_vert_mask_offset,
|
|
|
|
show_mask,
|
|
|
|
show_vcol,
|
|
|
|
&empty_mask);
|
|
|
|
|
|
|
|
idx[i] = v_index;
|
|
|
|
v_index++;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-10-02 18:02:41 +02:00
|
|
|
else {
|
|
|
|
/* Vertex already in the vertex buffer, just get the index. */
|
|
|
|
idx[i] = POINTER_AS_UINT(*idx_p);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
|
|
|
|
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, idx[0], idx[1]);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, idx[1], idx[2]);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, idx[2], idx[0]);
|
|
|
|
}
|
2012-12-30 18:24:54 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
BLI_ghash_free(bm_vert_to_index, NULL, NULL);
|
|
|
|
|
|
|
|
buffers->tot_tri = tottri;
|
|
|
|
if (buffers->index_buf == NULL) {
|
|
|
|
buffers->index_buf = GPU_indexbuf_build(&elb);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
|
|
|
|
}
|
|
|
|
buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
|
|
|
else {
|
2019-10-02 18:02:41 +02:00
|
|
|
GSetIterator gs_iter;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
GPUIndexBufBuilder elb_lines;
|
|
|
|
GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, tottri * 3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
GSET_ITER (gs_iter, bm_faces) {
|
|
|
|
f = BLI_gsetIterator_getKey(&gs_iter);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
BLI_assert(f->len == 3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
|
|
|
|
BMVert *v[3];
|
|
|
|
float fmask = 0.0f;
|
|
|
|
int i;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
BM_face_as_array_vert_tri(f, v);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-10-02 18:02:41 +02:00
|
|
|
/* Average mask value */
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
|
|
|
|
}
|
|
|
|
fmask /= 3.0f;
|
|
|
|
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v_index + 0, v_index + 1);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
|
|
|
|
GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
gpu_bmesh_vert_to_buffer_copy(v[i],
|
|
|
|
buffers->vert_buf,
|
|
|
|
v_index++,
|
|
|
|
f->no,
|
|
|
|
&fmask,
|
|
|
|
cd_vert_mask_offset,
|
|
|
|
show_mask,
|
|
|
|
show_vcol,
|
|
|
|
&empty_mask);
|
2018-03-19 18:09:00 -03:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-10-02 18:02:41 +02:00
|
|
|
|
|
|
|
buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
|
|
|
|
buffers->tot_tri = tottri;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-04 00:46:26 +02:00
|
|
|
/* Get material index from the last face we iterated on. */
|
2019-09-13 16:18:18 +02:00
|
|
|
buffers->material_index = (f) ? f->mat_nr : 0;
|
2019-05-04 00:46:26 +02:00
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
buffers->show_overlay = !empty_mask;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/** \} */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Generic
|
2019-02-14 20:24:13 +01:00
|
|
|
* \{ */
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
/* Threaded - do not call any functions that use OpenGL calls! */
|
2019-04-17 08:56:59 +02:00
|
|
|
GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
|
|
|
|
{
|
|
|
|
GPU_PBVH_Buffers *buffers;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
|
|
|
|
buffers->use_bmesh = true;
|
|
|
|
buffers->smooth = smooth_shading;
|
2020-03-21 18:09:43 +01:00
|
|
|
buffers->show_overlay = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
return buffers;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires)
|
|
|
|
{
|
|
|
|
if (wires) {
|
|
|
|
return (fast && buffers->lines_fast) ? buffers->lines_fast : buffers->lines;
|
2019-02-14 20:24:13 +01:00
|
|
|
}
|
2020-08-07 12:39:35 +02:00
|
|
|
|
|
|
|
return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-21 18:09:43 +01:00
|
|
|
bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers)
|
2019-04-17 08:56:59 +02:00
|
|
|
{
|
2020-03-21 18:09:43 +01:00
|
|
|
return buffers->show_overlay;
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
|
|
|
|
2019-05-04 00:46:26 +02:00
|
|
|
short GPU_pbvh_buffers_material_index_get(GPU_PBVH_Buffers *buffers)
|
|
|
|
{
|
|
|
|
return buffers->material_index;
|
|
|
|
}
|
|
|
|
|
2020-05-18 18:07:09 +02:00
|
|
|
static void gpu_pbvh_buffers_clear(GPU_PBVH_Buffers *buffers)
|
|
|
|
{
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->triangles);
|
|
|
|
GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
|
|
|
|
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
|
|
|
|
GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
|
|
|
|
}
|
|
|
|
|
2019-09-27 22:42:57 +02:00
|
|
|
void GPU_pbvh_buffers_update_flush(GPU_PBVH_Buffers *buffers)
|
|
|
|
{
|
|
|
|
/* Free empty bmesh node buffers. */
|
|
|
|
if (buffers->clear_bmesh_on_flush) {
|
2020-05-18 18:07:09 +02:00
|
|
|
gpu_pbvh_buffers_clear(buffers);
|
2019-10-02 18:02:41 +02:00
|
|
|
buffers->clear_bmesh_on_flush = false;
|
2019-09-27 22:42:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Force flushing to the GPU. */
|
2020-09-06 16:40:07 +02:00
|
|
|
if (buffers->vert_buf && GPU_vertbuf_get_data(buffers->vert_buf)) {
|
2019-09-27 22:42:57 +02:00
|
|
|
GPU_vertbuf_use(buffers->vert_buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
|
|
|
|
{
|
|
|
|
if (buffers) {
|
2020-05-18 18:07:09 +02:00
|
|
|
gpu_pbvh_buffers_clear(buffers);
|
2019-04-17 08:56:59 +02:00
|
|
|
MEM_freeN(buffers);
|
== GPU Buffers ==
This patch attempts to clean up and document the GPU buffers
code. There are a few bug fixes as well.
Patch reviewed here: http://codereview.appspot.com/4631052/
Summary:
* Bugfix: make GPU_buffer_copy_normal convert from shorts to floats
correctly, also fixed the use of cached face normal CustomData.
* Bugfix: changed the `mat_nr' field of GPUBufferMaterial from char to
short.
* Changed color buffer setup to not alloc a temporary copy of color
data, just passes the MCol data in directly.
* Changed the GPU buffer pool code to make clearer what operates
specifically on the global pool.
* Lots of refactoring for GPU_drawobject_new; should operate mostly
the same (except got rid of one unecessary allocation), just split
into more functions and without macros now.
* Converted some #defines into enumerations.
* Made some stuff private, pulled out of header file.
* Deleted unused function GPU_buffer_pool_free_unused().
* Removed GPU_interleaved_setup and related #defines. (I think this
was used for editmode VBOs, but those were disabled.)
* Added lots of comments.
* Added a few comments in the code signed `--nicholas' to note places
where I am unsure about design or usage, would be good to address
these better.
* Code formatting changed to be more consistent with the rest of
Blender.
* Renamed some fields and variables to be more consistent with
Blender's naming conventions.
* Renamed some fields and variables to use more descriptive names,
e.g. renamed `redir' to `mat_orig_to_new'.
* Removed print outs with DEBUG_VBO -- don't feel too strongly about
this one, just not used elsewhere in Blender, could be easily added
back if others disagree though.
* Moved the PBVH drawing code down to the bottom of the file, before
was sitting in the middle of the other VBO code
2011-07-08 19:58:02 +00:00
|
|
|
}
|
2019-04-17 08:56:59 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:56:59 +02:00
|
|
|
/** \} */
|