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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c2255
1 files changed, 10 insertions, 2245 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 1f1270b85b6..9ea6ef62e4e 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -69,6 +69,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
@@ -77,12 +78,6 @@
# include "BLI_array.h"
#endif
-#include "GPU_draw.h"
-#include "GPU_glew.h"
-#include "GPU_buffers.h"
-#include "GPU_shader.h"
-#include "GPU_basic_shader.h"
-
#include "CCGSubSurf.h"
#ifdef WITH_OPENSUBDIV
@@ -1775,47 +1770,7 @@ static void ccgDM_foreachMappedLoop(
}
}
-static void ccgDM_drawVerts(DerivedMesh *dm)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- CCGVertIterator vi;
- CCGEdgeIterator ei;
- CCGFaceIterator fi;
-
- glBegin(GL_POINTS);
- for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(&vi);
- glVertex3fv(ccgSubSurf_getVertData(ss, v));
- }
-
- for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
- int x;
-
- for (x = 1; x < edgeSize - 1; x++)
- glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
- }
-
- for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(&fi);
- int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- glVertex3fv(ccgSubSurf_getFaceCenterData(f));
- for (S = 0; S < numVerts; S++)
- for (x = 1; x < gridSize - 1; x++)
- glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
- for (S = 0; S < numVerts; S++)
- for (y = 1; y < gridSize - 1; y++)
- for (x = 1; x < gridSize - 1; x++)
- glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
- }
- glEnd();
-}
-
-static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
+static void UNUSED_FUNCTION(ccgdm_pbvh_update)(CCGDerivedMesh *ccgdm)
{
if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
CCGFace **faces;
@@ -1830,2179 +1785,6 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
}
}
-static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
-{
- GPUDrawObject *gdo;
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- /* TODO(sergey): We currently only support all edges drawing. */
- if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) {
- ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1);
- }
- return;
- }
-#endif
-
- ccgdm_pbvh_update(ccgdm);
-
-/* old debug feature for edges, unsupported for now */
-#if 0
- int useAging = 0;
-
- if (!(G.f & G_BACKBUFSEL)) {
- CCGSubSurf *ss = ccgdm->ss;
- ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
-
- /* it needs some way to upload this to VBO now */
- if (useAging) {
- int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
- glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
- }
- }
-#endif
-
- GPU_edge_setup(dm);
- gdo = dm->drawObject;
- if (gdo->edges && gdo->points) {
- if (drawAllEdges && drawLooseEdges) {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, (gdo->totedge - gdo->totinterior) * 2);
- }
- else if (drawAllEdges) {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2);
- }
- else {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2);
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, gdo->tot_loose_edge_drawn * 2);
- }
- }
-
- if (gdo->edges && ccgdm->drawInteriorEdges) {
- GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->interior_offset * 2, gdo->totinterior * 2);
- }
- GPU_buffers_unbind();
-}
-
-static void ccgDM_drawLooseEdges(DerivedMesh *dm)
-{
- int start;
- int count;
-
-#ifdef WITH_OPENSUBDIV
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- if (ccgdm->useGpuBackend) {
- /* TODO(sergey): Needs implementation. */
- return;
- }
-#endif
-
- GPU_edge_setup(dm);
-
- start = (dm->drawObject->loose_edge_offset * 2);
- count = (dm->drawObject->interior_offset - dm->drawObject->loose_edge_offset) * 2;
-
- if (count) {
- GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count);
- }
-
- GPU_buffers_unbind();
-}
-
-static void ccgDM_NormalFast(float *a, float *b, float *c, float *d, float no[3])
-{
- float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
- float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
-
- no[0] = b_dY * a_cZ - b_dZ * a_cY;
- no[1] = b_dZ * a_cX - b_dX * a_cZ;
- no[2] = b_dX * a_cY - b_dY * a_cX;
-
- normalize_v3(no);
-}
-
-
-static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
-{
- float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
- float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
- float no[3];
-
- no[0] = b_dY * a_cZ - b_dZ * a_cY;
- no[1] = b_dZ * a_cX - b_dX * a_cZ;
- no[2] = b_dX * a_cY - b_dY * a_cX;
-
- /* don't normalize, GL_NORMALIZE is enabled */
- glNormal3fv(no);
-}
-
-/* Only used by non-editmesh types */
-static void ccgDM_buffer_copy_normal(
- DerivedMesh *dm, short *varray)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- int shademodel;
- int start = 0;
-
- /* we are in sculpt mode, disable loop normals (since they won't get updated) */
- if (ccgdm->pbvh)
- lnors = NULL;
-
- CCG_key_top_level(&key, ss);
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- const float (*ln)[3] = NULL;
-
- if (faceFlags) {
- shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
- }
- else {
- shademodel = GL_SMOOTH;
- }
-
- if (lnors) {
- ln = lnors;
- lnors += gridFaces * gridFaces * numVerts * 4;
- }
-
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
-
- if (ln) {
- /* Can't use quad strips here... */
- for (y = 0; y < gridFaces; y ++) {
- for (x = 0; x < gridFaces; x ++) {
- normal_float_to_short_v3(&varray[start + 0], ln[0]);
- normal_float_to_short_v3(&varray[start + 4], ln[3]);
- normal_float_to_short_v3(&varray[start + 8], ln[2]);
- normal_float_to_short_v3(&varray[start + 12], ln[1]);
-
- start += 16;
- ln += 4;
- }
- }
- }
- else if (shademodel == GL_SMOOTH) {
- for (y = 0; y < gridFaces; y ++) {
- for (x = 0; x < gridFaces; x ++) {
- float *a = CCG_grid_elem_no(&key, faceGridData, x, y );
- float *b = CCG_grid_elem_no(&key, faceGridData, x + 1, y);
- float *c = CCG_grid_elem_no(&key, faceGridData, x + 1, y + 1);
- float *d = CCG_grid_elem_no(&key, faceGridData, x, y + 1);
-
- normal_float_to_short_v3(&varray[start], a);
- normal_float_to_short_v3(&varray[start + 4], b);
- normal_float_to_short_v3(&varray[start + 8], c);
- normal_float_to_short_v3(&varray[start + 12], d);
-
- start += 16;
- }
- }
- }
- else {
- for (y = 0; y < gridFaces; y ++) {
- for (x = 0; x < gridFaces; x ++) {
- float f_no[3];
- short f_no_s[3];
-
- float *a = CCG_grid_elem_co(&key, faceGridData, x, y );
- float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y );
- float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- ccgDM_NormalFast(a, b, c, d, f_no);
- normal_float_to_short_v3(f_no_s, f_no);
-
- copy_v3_v3_short(&varray[start], f_no_s);
- copy_v3_v3_short(&varray[start + 4], f_no_s);
- copy_v3_v3_short(&varray[start + 8], f_no_s);
- copy_v3_v3_short(&varray[start + 12], f_no_s);
-
- start += 16;
- }
- }
- }
- }
- }
-}
-
-typedef struct FaceCount {
- unsigned int i_visible;
- unsigned int i_hidden;
- unsigned int i_tri_visible;
- unsigned int i_tri_hidden;
-} FaceCount;
-
-
-/* Only used by non-editmesh types */
-static void ccgDM_buffer_copy_triangles(
- DerivedMesh *dm, unsigned int *varray,
- const int *mat_orig_to_new)
-{
- GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
- const int gpu_totmat = dm->drawObject->totmaterial;
- const short dm_totmat = dm->totmat;
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- short mat_nr = -1;
- int start;
- int totloops = 0;
- FaceCount *fc = MEM_mallocN(sizeof(*fc) * gpu_totmat, "gpumaterial.facecount");
-
- CCG_key_top_level(&key, ss);
-
- for (i = 0; i < gpu_totmat; i++) {
- fc[i].i_visible = 0;
- fc[i].i_tri_visible = 0;
- fc[i].i_hidden = gpumaterials[i].totpolys - 1;
- fc[i].i_tri_hidden = gpumaterials[i].totelements - 1;
- }
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- bool is_hidden;
- int mati;
-
- if (faceFlags) {
- mat_nr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat);
- is_hidden = (faceFlags[index].flag & ME_HIDE) != 0;
- }
- else {
- mat_nr = 0;
- is_hidden = false;
- }
- mati = mat_orig_to_new[mat_nr];
- gpumat = dm->drawObject->materials + mati;
-
- if (is_hidden) {
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- start = gpumat->start + fc[mati].i_tri_hidden;
-
- varray[start--] = totloops;
- varray[start--] = totloops + 2;
- varray[start--] = totloops + 3;
-
- varray[start--] = totloops;
- varray[start--] = totloops + 1;
- varray[start--] = totloops + 2;
-
- fc[mati].i_tri_hidden -= 6;
-
- totloops += 4;
- }
- }
- }
- gpumat->polys[fc[mati].i_hidden--] = i;
- }
- else {
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- start = gpumat->start + fc[mati].i_tri_visible;
-
- varray[start++] = totloops + 3;
- varray[start++] = totloops + 2;
- varray[start++] = totloops;
-
- varray[start++] = totloops + 2;
- varray[start++] = totloops + 1;
- varray[start++] = totloops;
-
- fc[mati].i_tri_visible += 6;
-
- totloops += 4;
- }
- }
- }
- gpumat->polys[fc[mati].i_visible++] = i;
- }
- }
-
- /* set the visible polygons */
- for (i = 0; i < gpu_totmat; i++) {
- gpumaterials[i].totvisiblepolys = fc[i].i_visible;
- }
-
- MEM_freeN(fc);
-}
-
-
-/* Only used by non-editmesh types */
-static void ccgDM_buffer_copy_vertex(
- DerivedMesh *dm, void *varray_p)
-{
- float *varray = varray_p;
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- int totedge = ccgSubSurf_getNumEdges(ss);
- int start = 0;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
-
- CCG_key_top_level(&key, ss);
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *a = CCG_grid_elem_co(&key, faceGridData, x, y);
- float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
- float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- copy_v3_v3(&varray[start], a);
- copy_v3_v3(&varray[start + 3], b);
- copy_v3_v3(&varray[start + 6], c);
- copy_v3_v3(&varray[start + 9], d);
-
- start += 12;
- }
- }
- }
- }
-
- /* upload loose points */
- for (i = 0; i < totedge; i++) {
- CCGEdge *e = ccgdm->edgeMap[i].edge;
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
-
- if (!ccgSubSurf_getEdgeNumFaces(e)) {
- int j = 0;
- for (j = 0; j < edgeSize; j++) {
- copy_v3_v3(&varray[start], CCG_elem_offset_co(&key, edgeData, j));
- start += 3;
- }
- }
- }
-}
-
-/* Only used by non-editmesh types */
-static void ccgDM_buffer_copy_color(
- DerivedMesh *dm, unsigned char *varray,
- const void *user_data)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- const unsigned char *mloopcol = user_data;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- int start = 0;
- int iface = 0;
-
- CCG_key_top_level(&key, ss);
-
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- copy_v4_v4_uchar(&varray[start + 0], &mloopcol[iface * 16 + 0]);
- copy_v4_v4_uchar(&varray[start + 4], &mloopcol[iface * 16 + 12]);
- copy_v4_v4_uchar(&varray[start + 8], &mloopcol[iface * 16 + 8]);
- copy_v4_v4_uchar(&varray[start + 12], &mloopcol[iface * 16 + 4]);
-
- start += 16;
- iface++;
- }
- }
- }
- }
-}
-
-static void ccgDM_buffer_copy_uv(
- DerivedMesh *dm, void *varray_p)
-{
- float *varray = varray_p;
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- MLoopUV *mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- int start = 0;
-
- CCG_key_top_level(&key, ss);
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- copy_v2_v2(&varray[start + 0], mloopuv[0].uv);
- copy_v2_v2(&varray[start + 2], mloopuv[3].uv);
- copy_v2_v2(&varray[start + 4], mloopuv[2].uv);
- copy_v2_v2(&varray[start + 6], mloopuv[1].uv);
-
- mloopuv += 4;
- start += 8;
- }
- }
- }
- }
-}
-
-static void ccgDM_buffer_copy_uv_texpaint(
- DerivedMesh *dm, float *varray)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int i, totface = ccgSubSurf_getNumFaces(ss);
- int start = 0;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int dm_totmat = dm->totmat;
- MLoopUV **mloopuv_base;
- MLoopUV *stencil_base;
- int stencil;
-
- CCG_key_top_level(&key, ss);
-
- /* should have been checked for before, reassert */
- BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV));
- mloopuv_base = MEM_mallocN(dm_totmat * sizeof(*mloopuv_base), "texslots");
-
- for (i = 0; i < dm_totmat; i++) {
- mloopuv_base[i] = DM_paint_uvlayer_active_get(dm, i);
- }
-
- stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV);
- stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil);
-
- start = 0;
-
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int matnr;
-
- if (faceFlags) {
- matnr = faceFlags[index].mat_nr;
- }
- else {
- matnr = 0;
- }
-
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- /* divide by 4, gives us current loop-index */
- unsigned int i_ml = start / 4;
- copy_v2_v2(&varray[start + 0], mloopuv_base[matnr][i_ml + 0].uv);
- copy_v2_v2(&varray[start + 2], stencil_base[i_ml + 0].uv);
- copy_v2_v2(&varray[start + 4], mloopuv_base[matnr][i_ml + 3].uv);
- copy_v2_v2(&varray[start + 6], stencil_base[i_ml + 3].uv);
- copy_v2_v2(&varray[start + 8], mloopuv_base[matnr][i_ml + 2].uv);
- copy_v2_v2(&varray[start + 10], stencil_base[i_ml + 2].uv);
- copy_v2_v2(&varray[start + 12], mloopuv_base[matnr][i_ml + 1].uv);
- copy_v2_v2(&varray[start + 14], stencil_base[i_ml + 1].uv);
- start += 16;
- }
- }
- }
- }
-
- MEM_freeN(mloopuv_base);
-}
-
-static void ccgDM_buffer_copy_uvedge(
- DerivedMesh *dm, float *varray)
-{
- int i, totpoly;
- int start;
- const MLoopUV *mloopuv;
-#ifndef USE_LOOP_LAYOUT_FAST
- const MPoly *mpoly = dm->getPolyArray(dm);
-#endif
-
- if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) {
- return;
- }
-
- totpoly = dm->getNumPolys(dm);
- start = 0;
-
-#ifndef USE_LOOP_LAYOUT_FAST
- for (i = 0; i < totpoly; i++, mpoly++) {
- for (j = 0; j < mpoly->totloop; j++) {
- copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv);
- copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv);
- start += 4;
- }
- }
-#else
- for (i = 0; i < totpoly; i++) {
- copy_v2_v2(&varray[start + 0], mloopuv[(i * 4) + 0].uv);
- copy_v2_v2(&varray[start + 2], mloopuv[(i * 4) + 1].uv);
-
- copy_v2_v2(&varray[start + 4], mloopuv[(i * 4) + 1].uv);
- copy_v2_v2(&varray[start + 6], mloopuv[(i * 4) + 2].uv);
-
- copy_v2_v2(&varray[start + 8], mloopuv[(i * 4) + 2].uv);
- copy_v2_v2(&varray[start + 10], mloopuv[(i * 4) + 3].uv);
-
- copy_v2_v2(&varray[start + 12], mloopuv[(i * 4) + 3].uv);
- copy_v2_v2(&varray[start + 14], mloopuv[(i * 4) + 0].uv);
-
- start += 16;
- }
-#endif
-}
-
-static void ccgDM_buffer_copy_edge(
- DerivedMesh *dm, unsigned int *varray)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- /* getEdgeSuze returns num of verts, edges is one less */
- int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss) - 1;
- int totedge = ccgSubSurf_getNumEdges(ss);
- int grid_face_side = ccgSubSurf_getGridSize(ss) - 1;
- int totface = ccgSubSurf_getNumFaces(ss);
- unsigned int index_start;
- unsigned int tot_interior = 0;
- unsigned int grid_tot_face = grid_face_side * grid_face_side;
-
- unsigned int iloose, inorm, iloosehidden, inormhidden;
- unsigned int tot_loose_hidden = 0, tot_loose = 0;
- unsigned int tot_hidden = 0, tot = 0;
- unsigned int iloosevert;
- /* int tot_interior = 0; */
-
- /* first, handle hidden/loose existing edges, then interior edges */
- for (j = 0; j < totedge; j++) {
- CCGEdge *e = ccgdm->edgeMap[j].edge;
-
- if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) {
- if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose_hidden++;
- else tot_hidden++;
- }
- else {
- if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose++;
- else tot++;
- }
- }
-
- inorm = 0;
- inormhidden = tot * edgeSize;
- iloose = (tot + tot_hidden) * edgeSize;
- iloosehidden = (tot + tot_hidden + tot_loose) * edgeSize;
- iloosevert = dm->drawObject->tot_loop_verts;
-
- /* part one, handle all normal edges */
- for (j = 0; j < totedge; j++) {
- CCGFace *f;
- int fhandle = 0;
- int totvert = 0;
- unsigned int S = 0;
- CCGEdge *e = ccgdm->edgeMap[j].edge;
- bool isloose = !ccgSubSurf_getEdgeNumFaces(e);
-
- if (!isloose) {
- CCGVert *v1, *v2;
- CCGVert *ev1 = ccgSubSurf_getEdgeVert0(e);
- CCGVert *ev2 = ccgSubSurf_getEdgeVert1(e);
-
- f = ccgSubSurf_getEdgeFace(e, 0);
- fhandle = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- totvert = ccgSubSurf_getFaceNumVerts(f);
-
- /* find the index of vertices in the face */
- for (i = 0; i < totvert; i++) {
- v1 = ccgSubSurf_getFaceVert(f, i);
- v2 = ccgSubSurf_getFaceVert(f, (i + 1) % totvert);
-
- if ((ev1 == v1 && ev2 == v2) || (ev1 == v2 && ev2 == v1)) {
- S = i;
- break;
- }
- }
- }
-
- if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) {
- if (isloose) {
- for (i = 0; i < edgeSize; i++) {
- varray[iloosehidden * 2] = iloosevert;
- varray[iloosehidden * 2 + 1] = iloosevert + 1;
- iloosehidden++;
- iloosevert++;
- }
- /* we are through with this loose edge and moving to the next, so increase by one */
- iloosevert++;
- }
- else {
- index_start = ccgdm->faceMap[fhandle].startFace;
-
- for (i = 0; i < grid_face_side; i++) {
- varray[inormhidden * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
- varray[inormhidden * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
- varray[inormhidden * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
- varray[inormhidden * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
- inormhidden += 2;
- }
- }
- }
- else {
- if (isloose) {
- for (i = 0; i < edgeSize; i++) {
- varray[iloose * 2] = iloosevert;
- varray[iloose * 2 + 1] = iloosevert + 1;
- iloose++;
- iloosevert++;
- }
- /* we are through with this loose edge and moving to the next, so increase by one */
- iloosevert++;
- }
- else {
- index_start = ccgdm->faceMap[fhandle].startFace;
-
- for (i = 0; i < grid_face_side; i++) {
- varray[inorm * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
- varray[inorm * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
- varray[inorm * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
- varray[inorm * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
- inorm += 2;
- }
- }
- }
- }
-
- /* part two, handle interior edges */
- inorm = totedge * grid_face_side * 2;
-
- index_start = 0;
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- unsigned int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- for (x = 1; x < grid_face_side; x++) {
- for (y = 0; y < grid_face_side; y++) {
- unsigned int tmp = (index_start + x * grid_face_side + y) * 4;
- varray[inorm * 2] = tmp;
- varray[inorm * 2 + 1] = tmp + 1;
- inorm++;
- }
- }
- for (x = 0; x < grid_face_side; x++) {
- for (y = 0; y < grid_face_side; y++) {
- unsigned int tmp = (index_start + x * grid_face_side + y) * 4;
- varray[inorm * 2] = tmp + 3;
- varray[inorm * 2 + 1] = tmp;
- inorm++;
- }
- }
-
- tot_interior += grid_face_side * (2 * grid_face_side - 1);
- index_start += grid_tot_face;
- }
- }
-
- dm->drawObject->tot_loose_edge_drawn = tot_loose * edgeSize;
- dm->drawObject->loose_edge_offset = (tot + tot_hidden) * edgeSize;
- dm->drawObject->tot_edge_drawn = tot * edgeSize;
-
- dm->drawObject->interior_offset = totedge * edgeSize;
- dm->drawObject->totinterior = tot_interior;
-}
-
-static void ccgDM_copy_gpu_data(
- DerivedMesh *dm, int type, void *varray_p,
- const int *mat_orig_to_new, const void *user_data)
-{
- /* 'varray_p' cast is redundant but include for self-documentation */
- switch (type) {
- case GPU_BUFFER_VERTEX:
- ccgDM_buffer_copy_vertex(dm, (float *)varray_p);
- break;
- case GPU_BUFFER_NORMAL:
- ccgDM_buffer_copy_normal(dm, (short *)varray_p);
- break;
- case GPU_BUFFER_UV:
- ccgDM_buffer_copy_uv(dm, (float *)varray_p);
- break;
- case GPU_BUFFER_UV_TEXPAINT:
- ccgDM_buffer_copy_uv_texpaint(dm, (float *)varray_p);
- break;
- case GPU_BUFFER_COLOR:
- ccgDM_buffer_copy_color(dm, (unsigned char *)varray_p, user_data);
- break;
- case GPU_BUFFER_UVEDGE:
- ccgDM_buffer_copy_uvedge(dm, (float *)varray_p);
- break;
- case GPU_BUFFER_EDGE:
- ccgDM_buffer_copy_edge(dm, (unsigned int *)varray_p);
- break;
- case GPU_BUFFER_TRIANGLES:
- ccgDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new);
- break;
- default:
- break;
- }
-}
-
-static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- GPUDrawObject *gdo;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
- const short dm_totmat = (faceFlags) ? dm->totmat : 1;
- GPUBufferMaterial *matinfo;
- int i;
- unsigned int tot_internal_edges = 0;
- int edgeVerts = ccgSubSurf_getEdgeSize(ss);
- int edgeSize = edgeVerts - 1;
-
- int totedge = ccgSubSurf_getNumEdges(ss);
- int totface = ccgSubSurf_getNumFaces(ss);
-
- /* object contains at least one material (default included) so zero means uninitialized dm */
- BLI_assert(dm_totmat != 0);
-
- matinfo = MEM_callocN(sizeof(*matinfo) * dm_totmat, "GPU_drawobject_new.mat_orig_to_new");
-
- if (faceFlags) {
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- const short new_matnr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat);
- matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6;
- matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4;
- matinfo[new_matnr].totpolys++;
- tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
- }
- }
- else {
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- matinfo[0].totelements += numVerts * gridFaces * gridFaces * 6;
- matinfo[0].totloops += numVerts * gridFaces * gridFaces * 4;
- matinfo[0].totpolys++;
- tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
- }
- }
-
- /* create the GPUDrawObject */
- gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
- gdo->totvert = 0; /* used to count indices, doesn't really matter for ccgsubsurf */
- gdo->totedge = (totedge * edgeSize + tot_internal_edges);
-
- GPU_buffer_material_finalize(gdo, matinfo, dm_totmat);
-
- /* store total number of points used for triangles */
- gdo->tot_triangle_point = ccgSubSurf_getNumFinalFaces(ss) * 6;
- gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4;
-
- /* finally, count loose points */
- for (i = 0; i < totedge; i++) {
- CCGEdge *e = ccgdm->edgeMap[i].edge;
-
- if (!ccgSubSurf_getEdgeNumFaces(e))
- gdo->tot_loose_point += edgeVerts;
- }
-
- return gdo;
-}
-
-/* Only used by non-editmesh types */
-static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial)
-{
- int a;
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
-
- ccgdm_pbvh_update(ccgdm);
-
- if (ccgdm->pbvh && ccgdm->multires.mmd) {
- if (BKE_pbvh_has_faces(ccgdm->pbvh)) {
- BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
- setMaterial, false, fast);
- }
-
- return;
- }
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- CCGSubSurf *ss = ccgdm->ss;
- const DMFlagMat *faceFlags = ccgdm->faceFlags;
- const int level = ccgSubSurf_getSubdivisionLevels(ss);
- const int face_side = 1 << level;
- const int grid_side = 1 << (level - 1);
- const int face_patches = face_side * face_side;
- const int grid_patches = grid_side * grid_side;
- const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
- int i, current_patch = 0;
- int mat_nr = -1;
- bool draw_smooth = false;
- int start_draw_patch = -1, num_draw_patches = 0;
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, setMaterial != NULL, -1) == false)) {
- return;
- }
- if (setMaterial == NULL) {
- ccgSubSurf_drawGLMesh(ss,
- true,
- -1,
- -1);
- return;
- }
- for (i = 0; i < num_base_faces; ++i) {
- const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
- const int num_patches = (num_face_verts == 4) ? face_patches
- : num_face_verts * grid_patches;
- int new_matnr;
- bool new_draw_smooth;
- if (faceFlags) {
- new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
- new_matnr = (faceFlags[i].mat_nr + 1);
- }
- else {
- new_draw_smooth = true;
- new_matnr = 1;
- }
- if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) {
- if (num_draw_patches != 0) {
- bool do_draw = setMaterial(mat_nr, NULL);
- if (do_draw) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- }
- start_draw_patch = current_patch;
- num_draw_patches = num_patches;
- mat_nr = new_matnr;
- draw_smooth = new_draw_smooth;
- }
- else {
- num_draw_patches += num_patches;
- }
- current_patch += num_patches;
- }
- if (num_draw_patches != 0) {
- bool do_draw = setMaterial(mat_nr, NULL);
- if (do_draw) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- }
- glShadeModel(GL_SMOOTH);
- return;
- }
-#endif
-
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
- for (a = 0; a < dm->drawObject->totmaterial; a++) {
- if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
- GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, dm->drawObject->materials[a].start,
- dm->drawObject->materials[a].totelements);
- }
- }
- GPU_buffers_unbind();
-}
-
-typedef struct {
- DMVertexAttribs attribs;
- int numdata;
-
- GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
-} GPUMaterialConv;
-
-/* Only used by non-editmesh types */
-static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
- DMSetMaterial setMaterial,
- DMSetDrawOptions setDrawOptions,
- void *userData)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- GPUVertexAttribs gattribs;
- int a, b;
- const DMFlagMat *faceFlags = ccgdm->faceFlags;
- unsigned char *varray;
- size_t max_element_size = 0;
- int tot_loops = 0;
- int totpoly = ccgSubSurf_getNumFaces(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- const int level = ccgSubSurf_getSubdivisionLevels(ss);
- const int face_side = 1 << level;
- const int grid_side = 1 << (level - 1);
- const int face_patches = face_side * face_side;
- const int grid_patches = grid_side * grid_side;
- const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
- int i, current_patch = 0;
- int mat_nr = -1;
- bool draw_smooth = false;
- int start_draw_patch = -1, num_draw_patches = 0;
- GPU_draw_update_fvar_offset(dm);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false, -1) == false)) {
- return;
- }
- for (i = 0; i < num_base_faces; ++i) {
- const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
- const int num_patches = (num_face_verts == 4) ? face_patches
- : num_face_verts * grid_patches;
- int new_matnr;
- bool new_draw_smooth;
-
- if (faceFlags) {
- new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
- new_matnr = (faceFlags[i].mat_nr + 1);
- }
- else {
- new_draw_smooth = true;
- new_matnr = 1;
- }
- if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) {
- if (num_draw_patches != 0) {
- bool do_draw = setMaterial(mat_nr, &gattribs);
- if (do_draw) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- }
- start_draw_patch = current_patch;
- num_draw_patches = num_patches;
- mat_nr = new_matnr;
- draw_smooth = new_draw_smooth;
- }
- else {
- num_draw_patches += num_patches;
- }
- current_patch += num_patches;
- }
- if (num_draw_patches != 0) {
- bool do_draw = setMaterial(mat_nr, &gattribs);
- if (do_draw) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- }
- glShadeModel(GL_SMOOTH);
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgdm_pbvh_update(ccgdm);
-
- if (setDrawOptions != NULL) {
- const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- DMVertexAttribs attribs = {{{NULL}}};
- int i;
- int matnr = -1;
- int do_draw = 0;
-
-#define PASSATTRIB(dx, dy, vert) { \
- if (attribs.totorco) \
- index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
- else \
- index = 0; \
- DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
- DM_draw_attrib_vertex_uniforms(&attribs); \
-} (void)0
-
- totpoly = ccgSubSurf_getNumFaces(ss);
- for (a = 0, i = 0; i < totpoly; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- const float (*ln)[3] = NULL;
- int S, x, y, drawSmooth;
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int origIndex = ccgDM_getFaceMapIndex(ss, f);
-
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int new_matnr;
-
- if (faceFlags) {
- drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
- new_matnr = faceFlags[index].mat_nr + 1;
- }
- else {
- drawSmooth = 1;
- new_matnr = 1;
- }
-
- if (lnors) {
- ln = lnors;
- lnors += (gridFaces * gridFaces * numVerts) * 4;
- }
-
- if (new_matnr != matnr) {
- do_draw = setMaterial(matnr = new_matnr, &gattribs);
- if (do_draw)
- DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
- }
-
- if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) &&
- (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP)))
- {
- a += gridFaces * gridFaces * numVerts;
- continue;
- }
-
- glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- CCGElem *vda, *vdb;
-
- if (ln) {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
- float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
- float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 1, 1);
- glNormal3fv(ln[1]);
- glVertex3fv(dco);
- PASSATTRIB(1, 1, 2);
- glNormal3fv(ln[2]);
- glVertex3fv(cco);
- PASSATTRIB(1, 0, 3);
- glNormal3fv(ln[3]);
- glVertex3fv(bco);
- PASSATTRIB(0, 0, 0);
- glNormal3fv(ln[0]);
- glVertex3fv(aco);
-
- ln += 4;
- a++;
- }
- }
- glEnd();
- }
- else if (drawSmooth) {
- for (y = 0; y < gridFaces; y++) {
- glBegin(GL_QUAD_STRIP);
- for (x = 0; x < gridFaces; x++) {
- vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
- vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 0, 0);
- glNormal3fv(CCG_elem_no(&key, vda));
- glVertex3fv(CCG_elem_co(&key, vda));
-
- PASSATTRIB(0, 1, 1);
- glNormal3fv(CCG_elem_no(&key, vdb));
- glVertex3fv(CCG_elem_co(&key, vdb));
-
- if (x != gridFaces - 1)
- a++;
- }
-
- vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
- vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 0, 3);
- glNormal3fv(CCG_elem_no(&key, vda));
- glVertex3fv(CCG_elem_co(&key, vda));
-
- PASSATTRIB(0, 1, 2);
- glNormal3fv(CCG_elem_no(&key, vdb));
- glVertex3fv(CCG_elem_co(&key, vdb));
-
- glEnd();
-
- a++;
- }
- }
- else {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
- float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
- float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- ccgDM_glNormalFast(aco, bco, cco, dco);
-
- PASSATTRIB(0, 1, 1);
- glVertex3fv(dco);
- PASSATTRIB(1, 1, 2);
- glVertex3fv(cco);
- PASSATTRIB(1, 0, 3);
- glVertex3fv(bco);
- PASSATTRIB(0, 0, 0);
- glVertex3fv(aco);
-
- a++;
- }
- }
- glEnd();
- }
- }
- }
-
- glShadeModel(GL_SMOOTH);
-#undef PASSATTRIB
- }
- else {
- GPUMaterialConv *matconv;
- size_t offset;
- int *mat_orig_to_new;
- int tot_active_mat;
- GPUBuffer *buffer = NULL;
-
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
-
- tot_active_mat = dm->drawObject->totmaterial;
-
- matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat,
- "cdDM_drawMappedFacesGLSL.matconv");
- mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
- "cdDM_drawMappedFacesGLSL.mat_orig_to_new");
-
- /* part one, check what attributes are needed per material */
- for (a = 0; a < tot_active_mat; a++) {
- int new_matnr;
- int do_draw;
-
- new_matnr = dm->drawObject->materials[a].mat_nr;
-
- /* map from original material index to new
- * GPUBufferMaterial index */
- mat_orig_to_new[new_matnr] = a;
- do_draw = setMaterial(new_matnr + 1, &gattribs);
-
- if (do_draw) {
- int numdata = 0;
- DM_vertex_attributes_from_gpu(dm, &gattribs, &matconv[a].attribs);
-
- if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) {
- matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index;
- matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index;
- matconv[a].datatypes[numdata].size = 3;
- matconv[a].datatypes[numdata].type = GL_FLOAT;
- numdata++;
- }
- for (b = 0; b < matconv[a].attribs.tottface; b++) {
- if (matconv[a].attribs.tface[b].array) {
- matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index;
- matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index;
- matconv[a].datatypes[numdata].size = 2;
- matconv[a].datatypes[numdata].type = GL_FLOAT;
- numdata++;
- }
- }
- for (b = 0; b < matconv[a].attribs.totmcol; b++) {
- if (matconv[a].attribs.mcol[b].array) {
- matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index;
- matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index;
- matconv[a].datatypes[numdata].size = 4;
- matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE;
- numdata++;
- }
- }
- for (b = 0; b < matconv[a].attribs.tottang; b++) {
- if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) {
- matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index;
- matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index;
- matconv[a].datatypes[numdata].size = 4;
- matconv[a].datatypes[numdata].type = GL_FLOAT;
- numdata++;
- }
- }
- if (numdata != 0) {
- matconv[a].numdata = numdata;
- max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size);
- }
- }
- }
-
- /* part two, generate and fill the arrays with the data */
- if (max_element_size > 0) {
- buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts);
-
- varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY);
- if (varray == NULL) {
- GPU_buffers_unbind();
- GPU_buffer_free(buffer);
- MEM_freeN(mat_orig_to_new);
- MEM_freeN(matconv);
- fprintf(stderr, "Out of memory, can't draw object\n");
- return;
- }
-
- for (a = 0; a < totpoly; a++) {
- CCGFace *f = ccgdm->faceMap[a].face;
- int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int i;
-
- if (faceFlags) {
- i = mat_orig_to_new[faceFlags[orig_index].mat_nr];
- }
- else {
- i = mat_orig_to_new[0];
- }
-
- if (matconv[i].numdata != 0) {
- for (S = 0; S < numVerts; S++) {
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
-
- offset = tot_loops * max_element_size;
-
- if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) {
- int index;
-
- index = getFaceIndex(ss, f, S, x, y, edgeSize, gridSize);
- copy_v3_v3((float *)&varray[offset],
- (float *)matconv[i].attribs.orco.array[index]);
- index = getFaceIndex(ss, f, S, x + 1, y, edgeSize, gridSize);
- copy_v3_v3((float *)&varray[offset + max_element_size],
- (float *)matconv[i].attribs.orco.array[index]);
- index = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize);
- copy_v3_v3((float *)&varray[offset + 2 * max_element_size],
- (float *)matconv[i].attribs.orco.array[index]);
- index = getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize);
- copy_v3_v3((float *)&varray[offset + 3 * max_element_size],
- (float *)matconv[i].attribs.orco.array[index]);
-
- offset += sizeof(float) * 3;
- }
- for (b = 0; b < matconv[i].attribs.tottface; b++) {
- if (matconv[i].attribs.tface[b].array) {
- const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array + tot_loops;
-
- copy_v2_v2((float *)&varray[offset], mloopuv[0].uv);
- copy_v2_v2((float *)&varray[offset + max_element_size], mloopuv[3].uv);
- copy_v2_v2((float *)&varray[offset + 2 * max_element_size], mloopuv[2].uv);
- copy_v2_v2((float *)&varray[offset + 3 * max_element_size], mloopuv[1].uv);
-
- offset += sizeof(float) * 2;
- }
- }
- for (b = 0; b < matconv[i].attribs.totmcol; b++) {
- if (matconv[i].attribs.mcol[b].array) {
- const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array + tot_loops;
-
- copy_v4_v4_uchar(&varray[offset], &mloopcol[0].r);
- copy_v4_v4_uchar(&varray[offset + max_element_size], &mloopcol[3].r);
- copy_v4_v4_uchar(&varray[offset + 2 * max_element_size], &mloopcol[2].r);
- copy_v4_v4_uchar(&varray[offset + 3 * max_element_size], &mloopcol[1].r);
-
- offset += sizeof(unsigned char) * 4;
- }
- }
- for (b = 0; b < matconv[i].attribs.tottang; b++) {
- if (matconv[i].attribs.tottang && matconv[i].attribs.tang[b].array) {
- const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang[b].array + tot_loops;
-
- copy_v4_v4((float *)&varray[offset], looptang[0]);
- copy_v4_v4((float *)&varray[offset + max_element_size], looptang[3]);
- copy_v4_v4((float *)&varray[offset + 2 * max_element_size], looptang[2]);
- copy_v4_v4((float *)&varray[offset + 3 * max_element_size], looptang[1]);
-
- offset += sizeof(float) * 4;
- }
- }
-
- tot_loops += 4;
- }
- }
- }
- }
- else {
- tot_loops += 4 * numVerts * gridFaces * gridFaces;
- }
- }
- GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY);
- }
-
- for (a = 0; a < tot_active_mat; a++) {
- int new_matnr;
- int do_draw;
-
- new_matnr = dm->drawObject->materials[a].mat_nr;
-
- do_draw = setMaterial(new_matnr + 1, &gattribs);
-
- if (do_draw) {
- if (matconv[a].numdata) {
- GPU_interleaved_attrib_setup(buffer, matconv[a].datatypes, matconv[a].numdata, max_element_size);
- }
- GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES,
- dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements);
- if (matconv[a].numdata) {
- GPU_interleaved_attrib_unbind();
- }
- }
- }
-
- GPU_buffers_unbind();
- if (buffer)
- GPU_buffer_free(buffer);
-
- MEM_freeN(mat_orig_to_new);
- MEM_freeN(matconv);
- }
-}
-
-static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
-{
- dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
-}
-
-/* Only used by non-editmesh types */
-static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
- void (*setMaterial)(void *userData, int matnr, void *attribs),
- bool (*setFace)(void *userData, int index), void *userData)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- GPUVertexAttribs gattribs;
- DMVertexAttribs attribs = {{{NULL}}};
- int gridSize = ccgSubSurf_getGridSize(ss);
- int gridFaces = gridSize - 1;
- int edgeSize = ccgSubSurf_getEdgeSize(ss);
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- int a, i, numVerts, matnr, totface;
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- const int level = ccgSubSurf_getSubdivisionLevels(ss);
- const int face_side = 1 << level;
- const int grid_side = 1 << (level - 1);
- const int face_patches = face_side * face_side;
- const int grid_patches = grid_side * grid_side;
- const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
- int current_patch = 0;
- int mat_nr = -1;
- bool draw_smooth = false;
- int start_draw_patch = -1, num_draw_patches = 0;
- GPU_draw_update_fvar_offset(dm);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) {
- return;
- }
- for (i = 0; i < num_base_faces; ++i) {
- const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
- const int num_patches = (num_face_verts == 4) ? face_patches
- : num_face_verts * grid_patches;
- int new_matnr;
- bool new_draw_smooth;
-
- if (faceFlags) {
- new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
- new_matnr = (faceFlags[i].mat_nr + 1);
- }
- else {
- new_draw_smooth = true;
- new_matnr = 1;
- }
- if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) {
- if (num_draw_patches != 0) {
- setMaterial(userData, mat_nr, &gattribs);
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- start_draw_patch = current_patch;
- num_draw_patches = num_patches;
- mat_nr = new_matnr;
- draw_smooth = new_draw_smooth;
- }
- else {
- num_draw_patches += num_patches;
- }
- current_patch += num_patches;
- }
- if (num_draw_patches != 0) {
- setMaterial(userData, mat_nr, &gattribs);
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- glShadeModel(GL_SMOOTH);
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgdm_pbvh_update(ccgdm);
-
- matnr = -1;
-
-#define PASSATTRIB(dx, dy, vert) { \
- if (attribs.totorco) \
- index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
- else \
- index = 0; \
- DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \
- DM_draw_attrib_vertex_uniforms(&attribs); \
-} (void)0
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (a = 0, i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- const float (*ln)[3] = NULL;
- int S, x, y, drawSmooth;
- int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int origIndex = ccgDM_getFaceMapIndex(ss, f);
- int new_matnr;
-
- numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- /* get flags */
- if (faceFlags) {
- drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
- new_matnr = faceFlags[index].mat_nr + 1;
- }
- else {
- drawSmooth = 1;
- new_matnr = 1;
- }
-
- if (lnors) {
- ln = lnors;
- lnors += (gridFaces * gridFaces * numVerts) * 4;
- }
-
- /* material */
- if (new_matnr != matnr) {
- setMaterial(userData, matnr = new_matnr, &gattribs);
- DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
- }
-
- /* face hiding */
- if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
- a += gridFaces * gridFaces * numVerts;
- continue;
- }
-
- /* draw face*/
- glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- CCGElem *vda, *vdb;
-
- if (ln) {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
- float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
- float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 1, 1);
- glNormal3fv(ln[1]);
- glVertex3fv(dco);
- PASSATTRIB(1, 1, 2);
- glNormal3fv(ln[2]);
- glVertex3fv(cco);
- PASSATTRIB(1, 0, 3);
- glNormal3fv(ln[3]);
- glVertex3fv(bco);
- PASSATTRIB(0, 0, 0);
- glNormal3fv(ln[0]);
- glVertex3fv(aco);
-
- ln += 4;
- a++;
- }
- }
- glEnd();
- }
- else if (drawSmooth) {
- for (y = 0; y < gridFaces; y++) {
- glBegin(GL_QUAD_STRIP);
- for (x = 0; x < gridFaces; x++) {
- vda = CCG_grid_elem(&key, faceGridData, x, y);
- vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 0, 0);
- glNormal3fv(CCG_elem_no(&key, vda));
- glVertex3fv(CCG_elem_co(&key, vda));
-
- PASSATTRIB(0, 1, 1);
- glNormal3fv(CCG_elem_no(&key, vdb));
- glVertex3fv(CCG_elem_co(&key, vdb));
-
- if (x != gridFaces - 1)
- a++;
- }
-
- vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
- vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- PASSATTRIB(0, 0, 3);
- glNormal3fv(CCG_elem_no(&key, vda));
- glVertex3fv(CCG_elem_co(&key, vda));
-
- PASSATTRIB(0, 1, 2);
- glNormal3fv(CCG_elem_no(&key, vdb));
- glVertex3fv(CCG_elem_co(&key, vdb));
-
- glEnd();
-
- a++;
- }
- }
- else {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
- float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
- float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- ccgDM_glNormalFast(aco, bco, cco, dco);
-
- PASSATTRIB(0, 1, 1);
- glVertex3fv(dco);
- PASSATTRIB(1, 1, 2);
- glVertex3fv(cco);
- PASSATTRIB(1, 0, 3);
- glVertex3fv(bco);
- PASSATTRIB(0, 0, 0);
- glVertex3fv(aco);
-
- a++;
- }
- }
- glEnd();
- }
- }
- }
-
- glShadeModel(GL_SMOOTH);
-#undef PASSATTRIB
-}
-
-static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
- DMSetDrawOptionsTex drawParams,
- DMSetDrawOptionsMappedTex drawParamsMapped,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int colType;
- const MLoopCol *mloopcol = NULL;
- MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- DMDrawOption draw_option;
- int i, totpoly;
- bool flush;
- const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0;
- const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
- unsigned int next_actualFace;
- unsigned int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
- int mat_index;
- int tot_element, start_element, tot_drawn;
-
- if (use_colors) {
- colType = CD_TEXTURE_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- if (!mloopcol) {
- colType = CD_PREVIEW_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- if (!mloopcol) {
- colType = CD_MLOOPCOL;
- mloopcol = dm->getLoopDataArray(dm, colType);
- }
- }
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- const int active_uv_layer = CustomData_get_active_layer_index(&dm->loopData, CD_MLOOPUV);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, active_uv_layer) == false)) {
- return;
- }
- if (drawParams == NULL) {
- ccgSubSurf_drawGLMesh(ss, true, -1, -1);
- return;
- }
- const int level = ccgSubSurf_getSubdivisionLevels(ss);
- const int face_side = 1 << level;
- const int grid_side = 1 << (level - 1);
- const int face_patches = face_side * face_side;
- const int grid_patches = grid_side * grid_side;
- const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
- int current_patch = 0;
- int mat_nr = -1;
- int start_draw_patch = 0, num_draw_patches = 0;
- bool draw_smooth = false;
- for (i = 0; i < num_base_faces; ++i) {
- const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
- const int num_patches = (num_face_verts == 4) ? face_patches
- : num_face_verts * grid_patches;
- if (faceFlags) {
- mat_nr = faceFlags[i].mat_nr;
- draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
- }
- else {
- mat_nr = 0;
- draw_smooth = false;
- }
-
- if (drawParams != NULL) {
- MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[i] : NULL;
- draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
- }
- else {
- draw_option = (drawParamsMapped)
- ? drawParamsMapped(userData, i, mat_nr)
- : DM_DRAW_OPTION_NORMAL;
- }
-
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1);
-
- const int next_face = min_ii(i + 1, num_base_faces - 1);
- if (!flush && compareDrawOptions) {
- flush |= compareDrawOptions(userData, i, next_face) == 0;
- }
- if (!flush && faceFlags) {
- bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH);
- flush |= (new_draw_smooth != draw_smooth);
- }
-
- current_patch += num_patches;
-
- if (flush) {
- if (draw_option != DM_DRAW_OPTION_SKIP) {
- num_draw_patches += num_patches;
- }
- if (num_draw_patches != 0) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss,
- true,
- start_draw_patch,
- num_draw_patches);
- }
- start_draw_patch = current_patch;
- num_draw_patches = 0;
- }
- else {
- num_draw_patches += num_patches;
- }
- }
- glShadeModel(GL_SMOOTH);
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgdm_pbvh_update(ccgdm);
-
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- GPU_triangle_setup(dm);
- if (flag & DM_DRAW_USE_TEXPAINT_UV)
- GPU_texpaint_uv_setup(dm);
- else
- GPU_uv_setup(dm);
- if (mloopcol) {
- GPU_color_setup(dm, colType);
- }
-
- next_actualFace = 0;
-
- /* lastFlag = 0; */ /* UNUSED */
- for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
- GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
- next_actualFace = bufmat->polys[0];
- totpoly = bufmat->totpolys;
-
- tot_element = 0;
- tot_drawn = 0;
- start_element = 0;
-
- for (i = 0; i < totpoly; i++) {
- int polyindex = bufmat->polys[i];
- CCGFace *f = ccgdm->faceMap[polyindex].face;
- int numVerts = ccgSubSurf_getFaceNumVerts(f);
- int index = ccgDM_getFaceMapIndex(ss, f);
- int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
- int mat_nr;
- int facequads = numVerts * gridFaces * gridFaces;
- int actualFace = ccgdm->faceMap[polyindex].startFace;
-
- if (i != totpoly - 1) {
- polyindex = bufmat->polys[i + 1];
- next_actualFace = ccgdm->faceMap[polyindex].startFace;
- }
-
- if (faceFlags) {
- mat_nr = faceFlags[orig_index].mat_nr;
- }
- else {
- mat_nr = 0;
- }
-
- if (drawParams) {
- MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[actualFace] : NULL;
- draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
- }
- else if (index != ORIGINDEX_NONE)
- draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
- else
- draw_option = DM_DRAW_OPTION_NORMAL;
-
- /* flush buffer if current triangle isn't drawable or it's last triangle */
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1);
-
- if (!flush && compareDrawOptions) {
- /* also compare draw options and flush buffer if they're different
- * need for face selection highlight in edit mode */
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- tot_element += facequads * 6;
-
- if (flush) {
- if (draw_option != DM_DRAW_OPTION_SKIP)
- tot_drawn += facequads * 6;
-
- if (tot_drawn) {
- if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
- GPU_color_switch(1);
- else
- GPU_color_switch(0);
-
- GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
- tot_drawn = 0;
- }
-
- start_element = tot_element;
- }
- else {
- tot_drawn += facequads * 6;
- }
- }
- }
-
-
- GPU_buffers_unbind();
-}
-
-static void ccgDM_drawFacesTex(DerivedMesh *dm,
- DMSetDrawOptionsTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
-}
-
-static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptionsMappedTex setDrawOptions,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
-}
-
-/* same as cdDM_drawUVEdges */
-static void ccgDM_drawUVEdges(DerivedMesh *dm)
-{
- MPoly *mpoly = dm->getPolyArray(dm);
- int totpoly = dm->getNumPolys(dm);
- int prevstart = 0;
- bool prevdraw = true;
- int curpos = 0;
- int i;
-
- GPU_uvedge_setup(dm);
- for (i = 0; i < totpoly; i++, mpoly++) {
- const bool draw = (mpoly->flag & ME_HIDE) == 0;
-
- if (prevdraw != draw) {
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- prevstart = curpos;
- }
-
- curpos += 2 * mpoly->totloop;
- prevdraw = draw;
- }
- if (prevdraw && (curpos != prevstart)) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- GPU_buffers_unbind();
-}
-
-static void ccgDM_drawMappedFaces(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
- DMSetMaterial setMaterial,
- DMCompareDrawOptions compareDrawOptions,
- void *userData, DMDrawFlag flag)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- MLoopCol *mloopcol = NULL;
- const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
- int i, gridSize = ccgSubSurf_getGridSize(ss);
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int useColors = flag & DM_DRAW_USE_COLORS;
- int gridFaces = gridSize - 1, totface;
- int prev_mat_nr = -1;
-
- if (ccgdm->pbvh) {
- if (G.debug_value == 14)
- BKE_pbvh_draw_BB(ccgdm->pbvh);
- }
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- int new_matnr;
- bool draw_smooth, do_draw = true;
- if (setDrawOptions == NULL) {
- /* TODO(sergey): This is for cases when vertex colors or weights
- * are visualising. Currently we don't have CD layers for this data
- * and here we only make it so there's no garbage displayed.
- *
- * In the future we'll either need to have CD for this data or pass
- * this data as face-varying or vertex-varying data in OSD mesh.
- */
- glColor3f(0.8f, 0.8f, 0.8f);
- }
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) {
- return;
- }
- if (faceFlags) {
- draw_smooth = (faceFlags[0].flag & ME_SMOOTH);
- new_matnr = (faceFlags[0].mat_nr + 1);
- }
- else {
- draw_smooth = true;
- new_matnr = 1;
- }
- if (setMaterial) {
- setMaterial(new_matnr, NULL);
- }
- if (setDrawOptions) {
- if (setDrawOptions(userData, 0) == DM_DRAW_OPTION_SKIP) {
- do_draw = false;
- }
- }
- if (do_draw) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss, true, -1, -1);
- glShadeModel(GL_SMOOTH);
- }
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
-
- /* currently unused -- each original face is handled separately */
- (void)compareDrawOptions;
-
- if (useColors) {
- mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL);
- if (!mloopcol)
- mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL);
- }
-
- totface = ccgSubSurf_getNumFaces(ss);
- for (i = 0; i < totface; i++) {
- CCGFace *f = ccgdm->faceMap[i].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
- int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
- int origIndex;
- unsigned char *cp = NULL;
- const float (*ln)[3] = NULL;
-
- origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
-
- if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1;
- else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
- else drawSmooth = 1;
-
- if (mloopcol) {
- cp = (unsigned char *)mloopcol;
- mloopcol += gridFaces * gridFaces * numVerts * 4;
- }
-
- if (lnors) {
- ln = lnors;
- lnors += (gridFaces * gridFaces * numVerts) * 4;
- }
-
- {
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
-
- if (setMaterial) {
- int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1;
-
- if (mat_nr != prev_mat_nr) {
- setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */
- prev_mat_nr = mat_nr;
- }
- }
-
- if (setDrawOptions && (index != ORIGINDEX_NONE))
- draw_option = setDrawOptions(userData, index);
-
- if (draw_option != DM_DRAW_OPTION_SKIP) {
- if (draw_option == DM_DRAW_OPTION_STIPPLE) {
- GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
- GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
- }
-
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (ln) {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
- float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
- float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- if (cp) glColor4ubv(&cp[4]);
- glNormal3fv(ln[1]);
- glVertex3fv(d);
- if (cp) glColor4ubv(&cp[8]);
- glNormal3fv(ln[2]);
- glVertex3fv(c);
- if (cp) glColor4ubv(&cp[12]);
- glNormal3fv(ln[3]);
- glVertex3fv(b);
- if (cp) glColor4ubv(&cp[0]);
- glNormal3fv(ln[0]);
- glVertex3fv(a);
-
- if (cp) cp += 16;
- ln += 4;
- }
- }
- glEnd();
- }
- else if (drawSmooth) {
- for (y = 0; y < gridFaces; y++) {
- CCGElem *a, *b;
- glBegin(GL_QUAD_STRIP);
- for (x = 0; x < gridFaces; x++) {
- a = CCG_grid_elem(&key, faceGridData, x, y + 0);
- b = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- if (cp) glColor4ubv(&cp[0]);
- glNormal3fv(CCG_elem_no(&key, a));
- glVertex3fv(CCG_elem_co(&key, a));
- if (cp) glColor4ubv(&cp[4]);
- glNormal3fv(CCG_elem_no(&key, b));
- glVertex3fv(CCG_elem_co(&key, b));
-
- if (x != gridFaces - 1) {
- if (cp) cp += 16;
- }
- }
-
- a = CCG_grid_elem(&key, faceGridData, x, y + 0);
- b = CCG_grid_elem(&key, faceGridData, x, y + 1);
-
- if (cp) glColor4ubv(&cp[12]);
- glNormal3fv(CCG_elem_no(&key, a));
- glVertex3fv(CCG_elem_co(&key, a));
- if (cp) glColor4ubv(&cp[8]);
- glNormal3fv(CCG_elem_no(&key, b));
- glVertex3fv(CCG_elem_co(&key, b));
-
- if (cp) cp += 16;
-
- glEnd();
- }
- }
- else {
- glBegin(GL_QUADS);
- for (y = 0; y < gridFaces; y++) {
- for (x = 0; x < gridFaces; x++) {
- float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
- float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
- float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
- float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
-
- ccgDM_glNormalFast(a, b, c, d);
-
- if (cp) glColor4ubv(&cp[4]);
- glVertex3fv(d);
- if (cp) glColor4ubv(&cp[8]);
- glVertex3fv(c);
- if (cp) glColor4ubv(&cp[12]);
- glVertex3fv(b);
- if (cp) glColor4ubv(&cp[0]);
- glVertex3fv(a);
-
- if (cp) cp += 16;
- }
- }
- glEnd();
- }
- }
- if (draw_option == DM_DRAW_OPTION_STIPPLE)
- GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
- }
- }
- }
-}
-
-static void ccgDM_drawMappedEdges(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
- void *userData)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator ei;
- CCGKey key;
- int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- /* TODO(sergey): Only draw edges from base mesh. */
- if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) {
- if (!setDrawOptions || (setDrawOptions(userData, 0) != DM_DRAW_OPTION_SKIP)) {
- ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1);
- }
- }
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
-
- for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
- int index = ccgDM_getEdgeMapIndex(ss, e);
-
- glBegin(GL_LINE_STRIP);
- if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
- if (useAging && !(G.f & G_BACKBUFSEL)) {
- int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
- glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
- }
-
- for (i = 0; i < edgeSize - 1; i++) {
- glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
- glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
- }
- }
- glEnd();
- }
-}
-
-static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
- DMSetDrawInterpOptions setDrawInterpOptions,
- void *userData)
-{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- CCGEdgeIterator ei;
- int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
-
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- BLI_assert(!"Not currently supported");
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
-
- for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
- int index = ccgDM_getEdgeMapIndex(ss, e);
-
- glBegin(GL_LINE_STRIP);
- if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
- for (i = 0; i < edgeSize; i++) {
- setDrawInterpOptions(userData, index, (float) i / (edgeSize - 1));
-
- if (useAging && !(G.f & G_BACKBUFSEL)) {
- int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
- glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
- }
-
- glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
- }
- }
- glEnd();
- }
-}
-
static void ccgDM_foreachMappedFaceCenter(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no[3]),
@@ -4045,7 +1827,7 @@ static void ccgDM_release(DerivedMesh *dm)
if (ccgdm->multires.mmd) {
if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
- multires_modifier_update_mdisps(dm);
+ multires_modifier_update_mdisps(dm, NULL);
if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
multires_modifier_update_hidden(dm);
}
@@ -4546,7 +2328,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
}
else if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
+ Mesh *me = BKE_object_get_original_mesh(ob);
const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
@@ -4570,7 +2352,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos, totvert);
MEM_freeN(vertCos);
}
}
@@ -4687,23 +2469,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop;
ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
- ccgdm->dm.drawVerts = ccgDM_drawVerts;
- ccgdm->dm.drawEdges = ccgDM_drawEdges;
- ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
- ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
- ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
- ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
- ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
- ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
- ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
- ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
- ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
-
- ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
- ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
- ccgdm->dm.gpuObjectNew = ccgDM_GPUObjectNew;
- ccgdm->dm.copy_gpu_data = ccgDM_copy_gpu_data;
-
ccgdm->dm.release = ccgDM_release;
}
@@ -5155,8 +2920,7 @@ static bool subsurf_use_gpu_backend(SubsurfFlags flags)
*/
return
(flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
- (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE) &&
- (openSubdiv_supportGPUDisplay());
+ (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
#else
(void)flags;
return false;
@@ -5166,6 +2930,7 @@ static bool subsurf_use_gpu_backend(SubsurfFlags flags)
struct DerivedMesh *subsurf_make_derived_from_derived(
struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
+ struct Scene *scene,
float (*vertCos)[3],
SubsurfFlags flags)
{
@@ -5179,7 +2944,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
/* note: editmode calculation can only run once per
* modifier stack evaluation (uses freed cache) [#36299] */
if (flags & SUBSURF_FOR_EDIT_MODE) {
- int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels, false) : smd->levels;
+ int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels;
/* TODO(sergey): Same as emCache below. */
if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
@@ -5200,7 +2965,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
else if (flags & SUBSURF_USE_RENDER_PARAMS) {
/* Do not use cache in render mode. */
CCGSubSurf *ss;
- int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels, true) : smd->renderLevels;
+ int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->renderLevels, true) : smd->renderLevels;
if (levels == 0)
return dm;
@@ -5216,7 +2981,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
}
else {
int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
- int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels, false) : smd->levels;
+ int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels;
CCGSubSurf *ss;
/* It is quite possible there is a much better place to do this. It