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:
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c310
-rw-r--r--source/blender/gpu/GPU_buffers.h4
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c17
3 files changed, 241 insertions, 90 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 7d21b3304cd..a57dc034ffa 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1772,13 +1772,8 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
{
+ GPUDrawObject *gdo;
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
- int totedge = ccgSubSurf_getNumEdges(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- int useAging;
#ifdef WITH_OPENSUBDIV
if (ccgdm->useGpuBackend) {
@@ -1790,99 +1785,68 @@ static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEd
}
#endif
- CCG_key_top_level(&key, ss);
ccgdm_pbvh_update(ccgdm);
- ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
-
- for (j = 0; j < totedge; j++) {
- CCGEdge *e = ccgdm->edgeMap[j].edge;
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
-
- if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
- continue;
+/* old debug feature for edges, unsupported for now */
+#if 0
+ int useAging = 0;
- if (!drawAllEdges && ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
- continue;
+ if (!(G.f & G_BACKBUFSEL)) {
+ CCGSubSurf *ss = ccgdm->ss;
+ ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
- if (useAging && !(G.f & G_BACKBUFSEL)) {
+ /* 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);
}
-
- glBegin(GL_LINE_STRIP);
- 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();
}
+#endif
- if (useAging && !(G.f & G_BACKBUFSEL)) {
- glColor3ub(0, 0, 0);
+ 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, dm->drawObject->tot_loose_edge_drawn * 2);
+ }
}
if (ccgdm->drawInteriorEdges) {
- int totface = ccgSubSurf_getNumFaces(ss);
-
- for (j = 0; j < totface; j++) {
- CCGFace *f = ccgdm->faceMap[j].face;
- int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
-
- for (S = 0; S < numVerts; S++) {
- CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
-
- glBegin(GL_LINE_STRIP);
- for (x = 0; x < gridSize; x++)
- glVertex3fv(CCG_elem_offset_co(&key, faceGridData, x));
- glEnd();
- for (y = 1; y < gridSize - 1; y++) {
- glBegin(GL_LINE_STRIP);
- for (x = 0; x < gridSize; x++)
- glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
- glEnd();
- }
- for (x = 1; x < gridSize - 1; x++) {
- glBegin(GL_LINE_STRIP);
- for (y = 0; y < gridSize; y++)
- glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
- glEnd();
- }
- }
- }
+ GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->interior_offset * 2, gdo->totinterior * 2);
}
+ GPU_buffers_unbind();
}
static void ccgDM_drawLooseEdges(DerivedMesh *dm)
{
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGSubSurf *ss = ccgdm->ss;
- CCGKey key;
- int totedge = ccgSubSurf_getNumEdges(ss);
- int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int start;
+ int count;
#ifdef WITH_OPENSUBDIV
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
if (ccgdm->useGpuBackend) {
/* TODO(sergey): Needs implementation. */
return;
}
#endif
- CCG_key_top_level(&key, ss);
+ GPU_edge_setup(dm);
- for (j = 0; j < totedge; j++) {
- CCGEdge *e = ccgdm->edgeMap[j].edge;
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+ start = (dm->drawObject->loose_edge_offset * 2);
+ count = (dm->drawObject->interior_offset - dm->drawObject->loose_edge_offset) * 2;
- if (!ccgSubSurf_getEdgeNumFaces(e)) {
- glBegin(GL_LINE_STRIP);
- 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();
- }
+ 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])
@@ -2073,7 +2037,9 @@ static void ccgDM_buffer_copy_vertex(
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);
ccgdm_pbvh_update(ccgdm);
@@ -2101,6 +2067,20 @@ static void ccgDM_buffer_copy_vertex(
}
}
}
+
+ /* 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 */
@@ -2286,6 +2266,158 @@ static void ccgDM_buffer_copy_uvedge(
#endif
}
+static void ccgDM_buffer_copy_edge(
+ DerivedMesh *dm, unsigned int *varray)
+{
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+ CCGSubSurf *ss = ccgdm->ss;
+ int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
+ 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;
+
+ int iloose, inorm, iloosehidden, inormhidden;
+ int tot_loose_hidden = 0, tot_loose = 0;
+ int tot_hidden = 0, tot = 0;
+ unsigned int iloosevert = dm->drawObject->tot_loop_verts;
+ /* 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 * grid_face_side;
+ /* multiply by two for loose edges, the indices are copied in a different way */
+ iloose = (tot + tot_hidden) * grid_face_side * 2;
+ iloosehidden = (tot + tot_hidden + tot_loose) * grid_face_side * 2;
+
+ /* part one, handle all normal edges */
+ for (j = 0; j < totedge; j++) {
+ CCGFace *f;
+ int fhandle;
+ int totvert;
+ unsigned int S;
+ 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 (!ccgSubSurf_getEdgeNumFaces(e)) {
+ for (i = 0; i < edgeSize - 1; i++) {
+ varray[iloosehidden * 2] = iloosevert;
+ varray[iloosehidden * 2 + 1] = iloosevert + 1;
+ iloosehidden++;
+ iloosevert++;
+ }
+ }
+ else {
+ index_start = ccgdm->faceMap[fhandle].startFace;
+
+ for (i = 0; i < grid_face_side; i++) {
+ varray[inormhidden * 4] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
+ varray[inormhidden * 4 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
+ varray[inormhidden * 4 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
+ varray[inormhidden * 4 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
+ inormhidden++;
+ }
+ }
+ }
+ else {
+ if (!ccgSubSurf_getEdgeNumFaces(e)) {
+ for (i = 0; i < edgeSize - 1; i++) {
+ varray[iloose * 2] = iloosevert;
+ varray[iloose * 2 + 1] = iloosevert + 1;
+ iloose++;
+ iloosevert++;
+ }
+ }
+ else {
+ index_start = ccgdm->faceMap[fhandle].startFace;
+
+ for (i = 0; i < grid_face_side; i++) {
+ varray[inorm * 4] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
+ varray[inorm * 4 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
+ varray[inorm * 4 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
+ varray[inorm * 4 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
+ inorm++;
+ }
+ }
+ }
+ }
+
+ /* 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.0 * grid_face_side - 1);
+ index_start += grid_tot_face;
+ }
+ }
+
+ dm->drawObject->tot_loose_edge_drawn = tot_loose * (edgeSize - 1) * 2;
+ dm->drawObject->loose_edge_offset = (tot + tot_hidden) * grid_face_side * 2;
+ dm->drawObject->tot_edge_drawn = tot * grid_face_side * 2;
+
+ dm->drawObject->interior_offset = totedge * grid_face_side * 2;
+ 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)
@@ -2310,6 +2442,9 @@ static void ccgDM_copy_gpu_data(
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;
@@ -2336,13 +2471,16 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
int gridFaces = gridSize - 1;
int totmat = (faceFlags) ? dm->totmat : 1;
GPUMaterialInfo *matinfo;
- int i, curmat, curelement, totface;
+ int i, curmat, curelement;
+ unsigned int tot_internal_edges = 0;
+ int edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+ 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(totmat != 0);
- totface = ccgSubSurf_getNumFaces(ss);
-
matinfo = MEM_callocN(sizeof(*matinfo) * totmat, "GPU_drawobject_new.mat_orig_to_new");
if (faceFlags) {
@@ -2354,20 +2492,24 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
matinfo[new_matnr].elements += numVerts * gridFaces * gridFaces * 6;
matinfo[new_matnr].loops += numVerts * gridFaces * gridFaces * 4;
matinfo[new_matnr].polys++;
+ tot_internal_edges += numVerts * gridFaces * (2.0 * gridFaces - 1);
}
}
else {
for (i = 0; i < totface; i++) {
- matinfo[0].elements += gridFaces * gridFaces * 6;
- matinfo[0].loops += gridFaces * gridFaces * 4;
+ CCGFace *f = ccgdm->faceMap[i].face;
+ int numVerts = ccgSubSurf_getFaceNumVerts(f);
+ matinfo[0].elements += numVerts * gridFaces * gridFaces * 6;
+ matinfo[0].loops += numVerts * gridFaces * gridFaces * 4;
matinfo[0].polys++;
+ tot_internal_edges += numVerts * gridFaces * (2.0 * gridFaces - 1);
}
}
/* create the GPUDrawObject */
gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
- gdo->totvert = ccgSubSurf_getNumFinalFaces(ss) * 6;
- gdo->totedge = ccgSubSurf_getNumFinalEdges(ss) * 2;
+ gdo->totvert = ccgSubSurf_getNumFinalFaces(ss) * 4; /* doesn't really matter since we don't use indices */
+ gdo->totedge = (totedge * gridFaces * 2 + tot_internal_edges);
/* count the number of materials used by this DerivedMesh */
for (i = 0; i < totmat; i++) {
@@ -2397,6 +2539,8 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
/* store total number of points used for triangles */
gdo->tot_triangle_point = curelement;
+ gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4;
+
mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat,
"GPUDrawObject.mat_orig_to_new");
@@ -2419,10 +2563,18 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
}
else {
mat = &gdo->materials[0];
- for (i = 0; i < totface; i++)
+ for (i = 0; i < totface; i++) {
mat->polys[mat->counter++] = i;
+ }
}
+ /* finally, count loose points */
+ for (i = 0; i < totedge; i++) {
+ CCGEdge *e = ccgdm->edgeMap[i].edge;
+
+ if (!ccgSubSurf_getEdgeNumFaces(e))
+ gdo->tot_loose_point += edgeSize;
+ }
MEM_freeN(mat_orig_to_new);
MEM_freeN(matinfo);
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index fc8b3726b84..a50d63d89ec 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -124,6 +124,10 @@ typedef struct GPUDrawObject {
unsigned int loose_edge_offset;
unsigned int tot_loose_edge_drawn;
unsigned int tot_edge_drawn;
+
+ /* for subsurf, offset where drawing of interior edges starts */
+ unsigned int interior_offset;
+ unsigned int totinterior;
} GPUDrawObject;
/* currently unused */
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 346e2292af9..7c71b32e5ca 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -613,24 +613,19 @@ static size_t gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
{
switch (type) {
case GPU_BUFFER_VERTEX:
- return sizeof(float) * gpu_buffer_type_settings[type].num_components * (dm->drawObject->tot_triangle_point + dm->drawObject->tot_loose_point);
+ return sizeof(float) * gpu_buffer_type_settings[type].num_components * (dm->drawObject->tot_loop_verts + dm->drawObject->tot_loose_point);
case GPU_BUFFER_NORMAL:
- return sizeof(short) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+ return sizeof(short) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
case GPU_BUFFER_COLOR:
- return sizeof(char) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+ return sizeof(char) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
case GPU_BUFFER_UV:
- return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+ return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
case GPU_BUFFER_UV_TEXPAINT:
- return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+ return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
case GPU_BUFFER_EDGE:
return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->totedge;
case GPU_BUFFER_UVEDGE:
- /* each face gets 3 points, 3 edges per triangle, and
- * each edge has its own, non-shared coords, so each
- * tri corner needs minimum of 4 floats, quads used
- * less so here we can over allocate and assume all
- * tris. */
- return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+ return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_loop_verts;
case GPU_BUFFER_TRIANGLES:
return sizeof(int) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
default: