[Bf-blender-cvs] [2711c39] opensubdiv-modifier: OpenSubdiv: Reduce number of glGet* per mesh drawing

Sergey Sharybin noreply at git.blender.org
Thu Jul 17 20:11:32 CEST 2014


Commit: 2711c3923734b5d2bded2ad0bfb55afbaee230e3
Author: Sergey Sharybin
Date:   Thu Jul 17 13:21:36 2014 +0600
https://developer.blender.org/rB2711c3923734b5d2bded2ad0bfb55afbaee230e3

OpenSubdiv: Reduce number of glGet* per mesh drawing

This also reduces number of inverse matrix calculation by
updating light model and transformation matricies once per
mesh drawing.

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

M	intern/opensubdiv/gpu_shader_opensubd_display.glsl
M	intern/opensubdiv/opensubdiv_capi.cc
M	intern/opensubdiv/opensubdiv_capi.h
M	intern/opensubdiv/opensubdiv_gpu_capi.cc
M	source/blender/blenkernel/intern/CCGSubSurf.c

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

diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index 9055d9de..d1cb670 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -31,6 +31,7 @@
 struct VertexData {
 	vec4 position;
 	vec3 normal;
+	vec2 uv;
 };
 
 #ifdef VERTEX_SHADER
@@ -87,23 +88,21 @@ in block {
 
 uniform samplerBuffer FVarDataBuffer;
 
-out vec3 varying_position;
-out vec3 varying_normal;
-out vec2 varying_st;
+out block {
+	VertexData v;
+} outpt;
 
 #ifdef FLAT_SHADING
 void emit(int index, vec3 normal)
 {
-	varying_position = inpt[index].v.position.xyz;
-	varying_normal = normal;
+	outpt.v.position = inpt[index].v.position;
+	outpt.v.normal = normal;
 
 	/* TODO(sergey): Only uniform subdivisions atm. */
 	vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
 	vec2 st = quadst[index];
 
-	vec2 uv;
-	INTERP_FACE_VARYING_2(uv, 0, st);
-	varying_st = uv;
+	INTERP_FACE_VARYING_2(outpt.v.uv, 0, st);
 
 	gl_Position = projectionMatrix * inpt[index].v.position;
 	EmitVertex();
@@ -111,16 +110,14 @@ void emit(int index, vec3 normal)
 #else
 void emit(int index)
 {
-	varying_position = inpt[index].v.position.xyz;
-	varying_normal = inpt[index].v.normal;
+	outpt.v.position = inpt[index].v.position;
+	outpt.v.normal = inpt[index].v.normal;
 
 	/* TODO(sergey): Only uniform subdivisions atm. */
 	vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
 	vec2 st = quadst[index];
 
-	vec2 uv;
-	INTERP_FACE_VARYING_2(uv, 0, st);
-	varying_st = uv;
+	INTERP_FACE_VARYING_2(outpt.v.uv, 0, st);
 
 	gl_Position = projectionMatrix * inpt[index].v.position;
 	EmitVertex();
@@ -197,16 +194,16 @@ uniform float shininess;
 uniform sampler2D texture_buffer;
 #endif
 
-in vec3 varying_position;
-in vec3 varying_normal;
-in vec2 varying_st;
+in block {
+	VertexData v;
+} inpt;
 
 void main()
 {
 #ifdef WIREFRAME
 	gl_FragColor = diffuse;
 #else
-	vec3 N = varying_normal;
+	vec3 N = inpt.v.normal;
 
 	if (!gl_FrontFacing)
 		N = -N;
@@ -226,7 +223,8 @@ void main()
 
 		vec4 Plight = lightSource[i].position;
 		vec3 l = (Plight.w == 0.0)
-			? normalize(Plight.xyz) : normalize(Plight.xyz - varying_position);
+			? normalize(Plight.xyz) : normalize(Plight.xyz -
+			                                    inpt.v.position.xyz);
 
 		/* Specular light. */
 		vec3 light_specular = lightSource[i].specular.rgb;
@@ -240,7 +238,7 @@ void main()
 	/* Compute diffuse color. */
 	float alpha;
 #ifdef USE_TEXTURE
-	L_diffuse *= texture2D(texture_buffer, varying_st).rgb;
+	L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
 #else
 	L_diffuse *= diffuse.rgb;
 #endif
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index 67d307a..eb0e07f 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -555,6 +555,8 @@ int openSubdiv_getAvailableControllers(void)
 
 void openSubdiv_cleanup(void)
 {
+	openSubdiv_osdGLDisplayDeinit();
+
 #define DELETE_DESCRIPTOR(var, class) \
 	if (var != NULL) { \
 		delete (class*) var->descriptor; \
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index 2050de4..c596dd1 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -81,13 +81,28 @@ void openSubdiv_osdGLMeshUpdateVertexBuffer(OpenSubdiv_GLMesh *gl_mesh,
                                             int num_verts);
 void openSubdiv_osdGLMeshRefine(OpenSubdiv_GLMesh *gl_mesh);
 void openSubdiv_osdGLMeshSynchronize(OpenSubdiv_GLMesh *gl_mesh);
+void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh);
+
+/* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */
+void openSubdiv_osdGLDisplayInit(void);
+void openSubdiv_osdGLDisplayDeinit(void);
+
+/* ** Actual drawing ** */
+
+/* Initialize all the invariants which stays the same for every single path,
+ * for example lighting model stays untouched for the whole mesh.
+ *
+ * TODO(sergey): Some of the stuff could be initialized once for all meshes.
+ */
+void openSubdiv_osdGLMeshDisplayPrepare(void);
+
+/* Draw patches which corresponds to a given partition. */
 void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
                                  int fill_quads,
-                                 int material);
-void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh);
+                                 int partition);
 
+/* ** Utility functions ** */
 int openSubdiv_getAvailableControllers(void);
-
 void openSubdiv_cleanup(void);
 
 #ifdef __cplusplus
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 5b26418..b3d9733 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -68,6 +68,20 @@ typedef struct Lighting {
 	Light lights[NUM_SOLID_LIGHTS];
 } Lighting;
 
+typedef struct Transform {
+	float projection_matrix[16];
+	float model_view_matrix[16];
+	float normal_matrix[9];
+} Transform;
+
+static GLuint g_flat_fill_program = 0;
+static GLuint g_smooth_fill_program = 0;
+static GLuint g_wireframe_program = 0;
+
+static GLuint g_lighting_ub = 0;
+static Lighting g_lighting_data;
+static Transform g_transform;
+
 /* TODO(sergey): This is actually duplicated code from BLI. */
 namespace {
 void copy_m3_m3(float m1[3][3], float m2[3][3])
@@ -233,10 +247,9 @@ GLuint linkProgram(const char *define)
 		exit(1);
 	}
 
-	GLuint uboIndex = glGetUniformBlockIndex(program, "Lighting");
-	if (uboIndex != GL_INVALID_INDEX) {
-		glUniformBlockBinding(program, uboIndex, 0);
-	}
+	glUniformBlockBinding(program,
+	                      glGetUniformBlockIndex(program, "Lighting"),
+	                      0);
 
 #if 0  /* Used for textured view */
 	glProgramUniform1i(program,
@@ -252,54 +265,28 @@ GLuint linkProgram(const char *define)
 }
 
 void bindProgram(PartitionedGLMeshInterface *mesh,
-                 int program,
-                 GLuint lighting_ub,
-                 Lighting *lightingData)
+                 int program)
 {
 	glUseProgram(program);
 
 	/* Matricies */
-	float projection_matrix[16], model_view_matrix[16], normal_matrix[9];
-	glGetFloatv(GL_PROJECTION_MATRIX, projection_matrix);
-	glGetFloatv(GL_MODELVIEW_MATRIX, model_view_matrix);
-
 	glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"),
 	                   1, false,
-	                   model_view_matrix);
-
+	                   g_transform.model_view_matrix);
 	glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"),
 	                   1, false,
-	                   projection_matrix);
-
-	copy_m3_m4((float (*)[3])normal_matrix, (float (*)[4])model_view_matrix);
-	invert_m3((float (*)[3])normal_matrix);
-	transpose_m3((float (*)[3])normal_matrix);
+	                   g_transform.projection_matrix);
 	glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"),
 	                   1, false,
-	                   normal_matrix);
+	                   g_transform.normal_matrix);
 
 	/* Ligthing */
-	for (int i = 0; i < NUM_SOLID_LIGHTS; ++i) {
-		glGetLightfv(GL_LIGHT0 + i,
-		             GL_POSITION,
-		             lightingData->lights[i].position);
-		glGetLightfv(GL_LIGHT0 + i,
-		             GL_AMBIENT,
-		             lightingData->lights[i].ambient);
-		glGetLightfv(GL_LIGHT0 + i,
-		             GL_DIFFUSE,
-		             lightingData->lights[i].diffuse);
-		glGetLightfv(GL_LIGHT0 + i,
-		             GL_SPECULAR,
-		             lightingData->lights[i].specular);
-	}
-
-	glBindBuffer(GL_UNIFORM_BUFFER, lighting_ub);
+	glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
 	glBufferSubData(GL_UNIFORM_BUFFER,
-	                0, sizeof(Lighting), lightingData);
+	                0, sizeof(g_lighting_data), &g_lighting_data);
 	glBindBuffer(GL_UNIFORM_BUFFER, 0);
 
-	glBindBufferBase(GL_UNIFORM_BUFFER, 0, lighting_ub);
+	glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
 
 	/* Color */
 	GLboolean use_lighting;
@@ -319,9 +306,7 @@ void bindProgram(PartitionedGLMeshInterface *mesh,
 	else {
 		float color[4];
 		glGetFloatv(GL_CURRENT_COLOR, color);
-		glUniform4fv(glGetUniformLocation(program, "diffuse"),
-		             1,
-		             color);
+		glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
 	}
 
 	/* Face-fertex data */
@@ -335,41 +320,82 @@ void bindProgram(PartitionedGLMeshInterface *mesh,
 }  /* namespace */
 #endif
 
-void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
-                                 int fill_quads,
-                                 int material)
+void openSubdiv_osdGLDisplayInit(void)
 {
 #ifndef OPENSUBDIV_LEGACY_DRAW
-	static GLuint flat_fill_program;
-	static GLuint smooth_fill_program;
-	static GLuint wireframe_program;
 	static bool need_init = true;
-
-	static GLuint lighting_ub = 0;
-	static Lighting lightingData = {
-		{{  { 0.5,  0.2f, 1.0f, 0.0f },
-		    { 0.1f, 0.1f, 0.1f, 1.0f },
-		    { 0.7f, 0.7f, 0.7f, 1.0f },
-		    { 0.8f, 0.8f, 0.8f, 1.0f } },
-
-		 { { -0.8f, 0.4f, -1.0f, 0.0f },
-		   {  0.0f, 0.0f,  0.0f, 1.0f },
-		   {  0.5f, 0.5f,  0.5f, 1.0f },
-		   {  0.8f, 0.8f,  0.8f, 1.0f } }}
-	};
 	if (need_init) {
-		flat_fill_program = linkProgram("#define FLAT_SHADING\n");
-		smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n");
-		wireframe_program = linkProgram("#define WIREFRAME\n");
+		g_flat_fill_program = linkProgram("#define FLAT_SHADING\n");
+		g_smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n");
+		g_wireframe_program = linkProgram("#define WIREFRAME\n");
+
+		/* We start with totally emoty lighting setup. */
+		memset(&g_lighting_data, 0, sizeof(g_lighting_data));
 
-		glGenBuffers(1, &lighting_ub);
-		glBindBuffer(GL_UNIFORM_BUFFER, lighting_ub);
+		glGenBuffers(1, &g_lighting_ub);
+		glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
 		glBufferData(GL_UNIFORM_BUFFER,
-		             sizeof(lightingData), NULL, GL_STATIC_DRAW);
+		             sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
 
 		need_init = false;
 	}
 #endif
+}
+
+void openSubdiv_osdGLDisplayDeinit(void)
+{
+#ifndef OPENSUBDIV_LEGACY_DRAW


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list