[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