[Bf-blender-cvs] [3d74e55] wiggly-widgets: Initial VBO code for GPU subsurf.

Antony Riakiotakis noreply at git.blender.org
Tue Dec 16 18:26:37 CET 2014


Commit: 3d74e55dd7628d8d72e114911651b737c371409e
Author: Antony Riakiotakis
Date:   Tue Dec 16 18:23:43 2014 +0100
Branches: wiggly-widgets
https://developer.blender.org/rB3d74e55dd7628d8d72e114911651b737c371409e

Initial VBO code for GPU subsurf.

This commit adds a few generalizations to the VBO
code so that modifiers can create and populate their own GPU objects.

The VBO code originally supported CDDerivedMesh only. The design moves
slightly towards the viewport refactor where the rendering system
requests data from modifiers.

What we do have is support for solid shading with multiple
materials, flat/smooth shading and a big performance boost.
Performance could

In this commit only basic support for vertices and normals is provided
and some features from blender's VBO system, such as mapping to
original faces, unique element indices for vertices and loose vertex/
and can be added later. The one feature that is missing now is the quick
navigation feature of the multires modifier (which uses the same code).

- Why this commit is made on the widget branch -

Facemap widgets need to avoid drawing the whole mesh when we do
collision detection on them. For subsurf drawing we need to iterate
through the whole mesh every time. What we need instead is sort
indexed elemet drawing according to the facemap each face belongs to.
This screams VBOs but since I was going to add that, I thought that
I could push it a bit further and add proper solid shading support.

===================================================================

M	release/scripts/modules/sys_info.py
M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c

===================================================================

diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index 7fd97c4..acbeb50 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -167,8 +167,11 @@ def write_sysinfo(op):
         output.write("\nImplementation Dependent OpenGL Limits:\n")
         output.write(lilies)
         limit = bgl.Buffer(bgl.GL_INT, 1)
+        limit_fl = bgl.Buffer(bgl.GL_FLOAT, 2)
         bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_UNITS, limit)
         output.write("Maximum Fixed Function Texture Units:\t%d\n" % limit[0])
+        bgl.glGetFloatv(bgl.GL_MAX_TEXTURE_UNITS, limit_fl)
+        output.write("Point Sprite Size Range:\t Max: %f Min: %f\n" % (limit_fl[0], limit_fl[1]))
 
         output.write("\nGLSL:\n")
         if version[0] > '1':
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index da4fcb4..8b801d7 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -466,6 +466,10 @@ struct DerivedMesh {
 	                           void (*setMaterial)(void *userData, int matnr, void *attribs),
 	                           bool (*setFace)(void *userData, int index), void *userData);
 
+	struct GPUDrawObject *(*gpuObjectNew)(DerivedMesh *dm);
+	void (*copy_gpu_data)(DerivedMesh *dm, int type, float *varray, int *index,
+	                      int *mat_orig_to_new, void *user_data);
+	
 	/** Release reference to the DerivedMesh. This function decides internally
 	 * if the DerivedMesh will be freed, or cached for later use. */
 	void (*release)(DerivedMesh *dm);
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 6ac8569..bcaf78b 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -395,7 +395,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg
 	MEdge *medge = cddm->medge;
 	int i;
 	int prevstart = 0;
-	int prevdraw = 1;
+	bool prevdraw = true;
 	bool draw = true;
 	
 	if (cddm->pbvh && cddm->pbvh_draw &&
@@ -417,14 +417,14 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg
 			draw = false;
 		}
 		if (prevdraw != draw) {
-			if (prevdraw > 0 && (i - prevstart) > 0) {
+			if (prevdraw && (i - prevstart) > 0) {
 				GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
 			}
 			prevstart = i;
 		}
 		prevdraw = draw;
 	}
-	if (prevdraw > 0 && (i - prevstart) > 0) {
+	if (prevdraw && (i - prevstart) > 0) {
 		GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
 	}
 	GPU_buffer_unbind();
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index c777fcd..ee2f7d2 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -72,6 +72,7 @@
 #include "GPU_draw.h"
 #include "GPU_extensions.h"
 #include "GPU_glew.h"
+#include "GPU_buffers.h"
 
 #include "CCGSubSurf.h"
 
@@ -1729,12 +1730,25 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm)
 	}
 }
 
+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;
@@ -1744,7 +1758,8 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
 }
 
 /* Only used by non-editmesh types */
-static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial)
+static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray, int *vindex,
+                                    int *mat_orig_to_new, void *UNUSED(user_data))
 {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
 	CCGSubSurf *ss = ccgdm->ss;
@@ -1753,13 +1768,277 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	int gridFaces = gridSize - 1;
 	DMFlagMat *faceFlags = ccgdm->faceFlags;
-	int step = (fast) ? gridSize - 1 : 1;
 	int i, totface = ccgSubSurf_getNumFaces(ss);
-	int drawcurrent = 0, matnr = -1, shademodel = -1;
+	int matnr, shademodel;
+	int start;
 
 	CCG_key_top_level(&key, ss);
 	ccgdm_pbvh_update(ccgdm);
 
+	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));
+		short (*ln)[4][3] = NULL;
+
+		if (faceFlags) {
+			shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
+			matnr = faceFlags[index].mat_nr;
+		}
+		else {
+			shademodel = GL_SMOOTH;
+			matnr = 0;
+		}
+
+		if (lnors) {
+			ln = lnors;
+			lnors += gridFaces * gridFaces * numVerts;
+		}
+
+		for (S = 0; S < numVerts; S++) {
+			CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+
+			if (ln) {
+				/* Can't use quad strips here... */
+				glBegin(GL_QUADS);
+				for (y = 0; y < gridFaces; y ++) {
+					for (x = 0; x < gridFaces; x ++) {
+						start = vindex[mat_orig_to_new[matnr]];
+						
+						normal_short_to_float_v3(&varray[start], ln[0][1]);
+						normal_short_to_float_v3(&varray[start + 3], ln[0][2]);
+						normal_short_to_float_v3(&varray[start + 6], ln[0][3]);
+				
+						normal_short_to_float_v3(&varray[start + 9], ln[0][3]);
+						normal_short_to_float_v3(&varray[start + 12], ln[0][1]);
+						normal_short_to_float_v3(&varray[start + 15], ln[0][0]);
+						
+						vindex[mat_orig_to_new[matnr]] += 18;
+						
+						ln ++;
+					}
+				}
+				glEnd();
+			}
+			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);
+
+						start = vindex[mat_orig_to_new[matnr]];
+						
+						copy_v3_v3(&varray[start], d);
+						copy_v3_v3(&varray[start + 3], c);
+						copy_v3_v3(&varray[start + 6], b);
+				
+						copy_v3_v3(&varray[start + 9], b);
+						copy_v3_v3(&varray[start + 12], d);
+						copy_v3_v3(&varray[start + 15], a);
+						
+						vindex[mat_orig_to_new[matnr]] += 18;
+					}
+				}
+			}
+			else {
+				for (y = 0; y < gridFaces; y ++) {
+					for (x = 0; x < gridFaces; x ++) {
+						float no[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, no);
+	
+						start = vindex[mat_orig_to_new[matnr]];
+						
+						copy_v3_v3(&varray[start], no);
+						copy_v3_v3(&varray[start + 3], no);
+						copy_v3_v3(&varray[start + 6], no);
+				
+						copy_v3_v3(&varray[start + 9], no);
+						copy_v3_v3(&varray[start + 12], no);
+						copy_v3_v3(&varray[start + 15], no);
+						
+						vindex[mat_orig_to_new[matnr]] += 18;
+					}
+				}
+			}
+		}
+	}
+}
+
+/* Only used by non-editmesh types */
+static void ccgDM_prepare_vertex_data(DerivedMesh *dm, float *varray, int *vindex,
+                                      int *mat_orig_to_new, void *UNUSED(user_data))
+{
+	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);
+	int matnr = -1, start;
+	
+	CCG_key_top_level(&key, ss);
+	ccgdm_pbvh_update(ccgdm);
+	
+	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));
+		
+		if (faceFlags) {
+			matnr = faceFlags[index].mat_nr;
+		}
+		else {
+			matnr = 0;
+		}
+		
+		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);
+
+					start = vindex[mat_orig_to_new[matnr]];
+					
+					copy_v3_v3(&varray[start], d);
+					copy_v3_v3(&varray[start + 3], c);
+					copy_v3_v3(&varray[start + 6], b);
+			
+					copy_v3_v3(&varray[start + 9], b);
+					copy_v3_v3(&varray[start + 12], d);
+					copy_v3_v3(&varray[start + 15], a);
+					
+					vindex[mat_orig_to_new[matnr]] += 18;
+				}
+			}
+		}
+	}
+}
+
+static void ccgDM_copy_gpu_data(DerivedMesh *dm, int type, float *varray, int *index,
+                         int *mat_orig_to_new, void *UNUSED(user_data))
+{	
+	switch(type) {
+		case GPU_BUFFER_VERTEX:
+			ccgDM_prepare_vertex_data(dm, varray, index, mat_orig_to_new, NULL);
+			break;
+		case GPU_BUFFER_NORMAL:
+			ccgDM_prepare_normal_data(dm, varray, index, mat_orig_to_new, NULL);
+			break;
+		default:
+			break;
+	}
+}
+
+static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm) {
+//	GPUBufferMaterial *mat;
+	int *mat_orig_to_new;
+	CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+	CCGSubSurf *ss = ccgdm->ss;
+	GPUDrawObject *gdo;
+	DMFlagMat *faceFlags 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list