[Bf-blender-cvs] [13c39e9] master: VBO offscreen selection drawing, cdderivedmesh

Antony Riakiotakis noreply at git.blender.org
Wed Jul 15 18:50:40 CEST 2015


Commit: 13c39e90b3c0ec6a470fbc3696cd73c2a65b49cf
Author: Antony Riakiotakis
Date:   Wed Jul 15 18:50:02 2015 +0200
Branches: master
https://developer.blender.org/rB13c39e90b3c0ec6a470fbc3696cd73c2a65b49cf

VBO offscreen selection drawing, cdderivedmesh

    Get rid of legacy drawing, it's only used for selection,
    in which case we can prepare a temporary color buffer and draw
    at once. Code is not complete here because we still redundantly
    set the draw color in the draw function and don't ommit hidden
    faces automatically. Still it works 100% without immediate mode
    now.

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_subwindow.c
M	source/blenderplayer/bad_level_call_stubs/stubs.c

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index c8bd7e9..62c6838 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -149,6 +149,7 @@ typedef enum DMDrawFlag {
 	DM_DRAW_ALWAYS_SMOOTH       = (1 << 1),
 	DM_DRAW_USE_ACTIVE_UV       = (1 << 2),
 	DM_DRAW_USE_TEXPAINT_UV     = (1 << 3),
+	DM_DRAW_SKIP_HIDDEN         = (1 << 4),
 } DMDrawFlag;
 
 typedef enum DMForeachFlag {
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index b773bfe..5b25a32 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -60,6 +60,8 @@
 #include "GPU_extensions.h"
 #include "GPU_glew.h"
 
+#include "WM_api.h"
+
 #include <string.h>
 #include <limits.h>
 #include <math.h>
@@ -635,14 +637,15 @@ static void cdDM_drawMappedFaces(
         void *userData, DMDrawFlag flag)
 {
 	CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
-	MVert *mv = cddm->mvert;
 	MFace *mf = cddm->mface;
 	MCol *mcol;
-	const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
-	const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
-	int colType, useColors = flag & DM_DRAW_USE_COLORS;
+	int colType, useColors = flag & DM_DRAW_USE_COLORS, useHide = flag & DM_DRAW_SKIP_HIDDEN;
 	int i, orig;
-
+	int start_element = 0, tot_element, tot_drawn;
+	int totpoly;
+	int tottri;
+	int mat_index;
+	GPUBuffer *findex_buffer = NULL;
 
 	/* double lookup */
 	const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
@@ -651,216 +654,153 @@ static void cdDM_drawMappedFaces(
 		index_mp_to_orig = NULL;
 	}
 
-	colType = CD_TEXTURE_MCOL;
-	mcol = DM_get_tessface_data_layer(dm, colType);
-	if (!mcol) {
-		colType = CD_PREVIEW_MCOL;
-		mcol = DM_get_tessface_data_layer(dm, colType);
-	}
-	if (!mcol) {
-		colType = CD_MCOL;
-		mcol = DM_get_tessface_data_layer(dm, colType);
-	}
-
 	cdDM_update_normals_from_pbvh(dm);
 
-	/* back-buffer always uses legacy since VBO's would need the
-	 * color array temporarily overwritten for drawing, then reset. */
+	/* fist, setup common buffers */
+	GPU_vertex_setup(dm);
+	GPU_triangle_setup(dm);
+
+	/* if we do selection, fill the selection buffer color */
 	if (G.f & G_BACKBUFSEL) {
-		DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
-		for (i = 0; i < dm->numTessFaceData; i++, mf++) {
-			int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH);
-			DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+		Mesh *me = userData;
+		unsigned int *fi_map;
 
-			orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
-			
-			if (orig == ORIGINDEX_NONE)
-				draw_option = setMaterial(mf->mat_nr + 1, NULL);
-			else if (setDrawOptions != NULL)
-				draw_option = setDrawOptions(userData, orig);
+		findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int), false);
+		fi_map = GPU_buffer_lock(findex_buffer);
 
-			if (draw_option != DM_DRAW_OPTION_SKIP) {
-				unsigned char *cp = NULL;
+		if (fi_map) {
+			for (i = 0; i < dm->numTessFaceData; i++, mf++) {
+				int selcol = 0xFFFFFFFF;
+				orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
 
-				if (draw_option == DM_DRAW_OPTION_STIPPLE) {
-					glEnable(GL_POLYGON_STIPPLE);
-					glPolygonStipple(stipple_quarttone);
+				if ((orig != ORIGINDEX_NONE) && (!useHide || !(me->mpoly[orig].flag & ME_HIDE))) {
+					WM_framebuffer_index_get(orig + 1, &selcol);
 				}
 
-				if (useColors && mcol)
-					cp = (unsigned char *)&mcol[i * 4];
-
-				/* no need to set shading mode to flat because
-				 *  normals are already used to change shading */
-				glShadeModel(GL_SMOOTH);
-				glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
-
-				if (lnors) {
-					if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-					glNormal3sv((const GLshort *)lnors[0][0]);
-					glVertex3fv(mv[mf->v1].co);
-					if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-					glNormal3sv((const GLshort *)lnors[0][1]);
-					glVertex3fv(mv[mf->v2].co);
-					if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-					glNormal3sv((const GLshort *)lnors[0][2]);
-					glVertex3fv(mv[mf->v3].co);
-					if (mf->v4) {
-						if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-						glNormal3sv((const GLshort *)lnors[0][3]);
-						glVertex3fv(mv[mf->v4].co);
-					}
-				}
-				else if (!drawSmooth) {
-					if (nors) {
-						glNormal3fv(nors);
-					}
-					else {
-						float nor[3];
-						if (mf->v4) {
-							normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
-						}
-						else {
-							normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
-						}
-						glNormal3fv(nor);
-					}
+				fi_map[start_element++] = selcol;
+				fi_map[start_element++] = selcol;
+				fi_map[start_element++] = selcol;
 
-					if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-					glVertex3fv(mv[mf->v1].co);
-					if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-					glVertex3fv(mv[mf->v2].co);
-					if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-					glVertex3fv(mv[mf->v3].co);
-					if (mf->v4) {
-						if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-						glVertex3fv(mv[mf->v4].co);
-					}
-				}
-				else {
-					if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-					glNormal3sv(mv[mf->v1].no);
-					glVertex3fv(mv[mf->v1].co);
-					if (cp) glColor3ub(cp[7], cp[6], cp[5]);
-					glNormal3sv(mv[mf->v2].no);
-					glVertex3fv(mv[mf->v2].co);
-					if (cp) glColor3ub(cp[11], cp[10], cp[9]);
-					glNormal3sv(mv[mf->v3].no);
-					glVertex3fv(mv[mf->v3].co);
-					if (mf->v4) {
-						if (cp) glColor3ub(cp[15], cp[14], cp[13]);
-						glNormal3sv(mv[mf->v4].no);
-						glVertex3fv(mv[mf->v4].co);
-					}
+				if (mf->v4) {
+					fi_map[start_element++] = selcol;
 				}
+			}
 
-				glEnd();
+			start_element = 0;
+			mf = cddm->mface;
 
-				if (draw_option == DM_DRAW_OPTION_STIPPLE)
-					glDisable(GL_POLYGON_STIPPLE);
-			}
-			
-			if (nors)
-				nors += 3;
-			if (lnors)
-				lnors++;
+			GPU_buffer_unlock(findex_buffer);
+			GPU_buffer_bind_as_color(findex_buffer);
 		}
 	}
-	else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
-		int start_element = 0, tot_element, tot_drawn;
-		int totpoly;
-		int tottri;
-		int mat_index;
-		
-		GPU_vertex_setup(dm);
+	else {
 		GPU_normal_setup(dm);
-		GPU_triangle_setup(dm);
-		if (useColors && mcol) {
-			GPU_color_setup(dm, colType);
+
+		if (useColors) {
+			colType = CD_TEXTURE_MCOL;
+			mcol = DM_get_tessface_data_layer(dm, colType);
+			if (!mcol) {
+				colType = CD_PREVIEW_MCOL;
+				mcol = DM_get_tessface_data_layer(dm, colType);
+			}
+			if (!mcol) {
+				colType = CD_MCOL;
+				mcol = DM_get_tessface_data_layer(dm, colType);
+			}
+
+			if (useColors && mcol) {
+				GPU_color_setup(dm, colType);
+			}
 		}
-		glShadeModel(GL_SMOOTH);
+	}
 		
-		tottri = dm->drawObject->tot_triangle_point;
 
-		if (tottri == 0) {
-			/* avoid buffer problems in following code */
-		}
-		else if (setDrawOptions == NULL) {
-			/* just draw the entire face array */
-			GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri);
-		}
-		else {
-			for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
-				GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
-				DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
-				int next_actualFace = bufmat->polys[0];
-				totpoly = bufmat->totpolys;
-
-				tot_element = 0;
-				tot_drawn = 0;
-				start_element = 0;
-
-				if (setMaterial)
-					draw_option = setMaterial(bufmat->mat_nr + 1, NULL);
-
-				if (draw_option != DM_DRAW_OPTION_SKIP) {
-					for (i = 0; i < totpoly; i++) {
-						//int actualFace = dm->drawObject->triangle_to_mface[i];
-						int actualFace = next_actualFace;
-						int flush = 0;
-						draw_option = DM_DRAW_OPTION_NORMAL;
+	glShadeModel(GL_SMOOTH);
 
-						if (i != totpoly - 1)
-							next_actualFace = bufmat->polys[i + 1];
+	tottri = dm->drawObject->tot_triangle_point;
 
-						orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
+	if (tottri == 0) {
+		/* avoid buffer problems in following code */
+	}
+	else if (setDrawOptions == NULL) {
+		/* just draw the entire face array */
+		GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri);
+	}
+	else {
+		for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
+			GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
+			DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+			int next_actualFace = bufmat->polys[0];
+			totpoly = bufmat->totpolys;
 
-						if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE))
-							draw_option = setDrawOptions(userData, orig);
+			tot_element = 0;
+			start_element = 0;
+			tot_drawn = 0;
 
-						if (draw_option == DM_DRAW_OPTION_STIPPLE) {
-							glEnable(GL_POLYGON_STIPPLE);
-							glPolygonStipple(stipple_quarttone);
-						}
+			if (setMaterial)
+				draw_option = setMaterial(bufmat->mat_nr + 1, NULL);
 
-						/* Goal is to draw as long of a contiguous triangle
-						 * array as possible, so draw when we hit either an
-						 * invisible triangle or at the end of the array */
+			if (draw_option != DM_DRAW_OPTION_SKIP) {
+				for (i = 0; i < totpoly; i++) {
+					int actualFace = next_actualFace;
+					int flush = 0;
+					draw_option = DM_DRAW_OPTION_NORMAL;
 
-						/* flush buffer if current triangle isn't drawable or it's last triangle... */
-						flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == totpoly - 1);
+					if (i != totpoly - 1)
+						next_actualFace = bufmat->polys[i + 1];
 
-						if (!flush && compareDrawOptions) {
-							flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
-						}
+					orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
 
-						tot_element += mf[actualFace].v4 ? 6 : 3;
+					if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE))
+						draw_option = setDrawOp

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list