[Bf-blender-cvs] [80c3624] opensubdiv-modifier: OpenSubdiv: Initial work towards UV maps support

Sergey Sharybin noreply at git.blender.org
Wed Jul 16 19:01:59 CEST 2014


Commit: 80c3624c9eea1bf2f6c779d127469bb01fc2a910
Author: Sergey Sharybin
Date:   Wed Jul 16 22:57:51 2014 +0600
https://developer.blender.org/rB80c3624c9eea1bf2f6c779d127469bb01fc2a910

OpenSubdiv: Initial work towards UV maps support

This lands basic test of pass UV coordinates to the coarse mesh
via evaluator C-API and implements all the needed interpolation
in the GLSL shader.

This code is not used still because GLSL shader is not in use
because enabling it will make it impossible to run anything on
the older cards.

Still need to do some runtime check for this..

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

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

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

diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index 1c9d6b0..9055d9de 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -65,19 +65,46 @@ layout(line_strip, max_vertices = 8) out;
 
 uniform mat4 modelViewMatrix;
 uniform mat4 projectionMatrix;
+uniform int PrimitiveIdBase;
 
 in block {
 	VertexData v;
 } inpt[4];
 
+#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord)  \
+	{ \
+		vec2 v[4]; \
+		int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
+		for (int i = 0; i < 4; ++i) { \
+			int index = (primOffset + i) * 2 + fvarOffset; \
+			v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \
+			            texelFetch(FVarDataBuffer, index + 1).s); \
+		} \
+		result = mix(mix(v[0], v[1], tessCoord.s), \
+		             mix(v[3], v[2], tessCoord.s), \
+		             tessCoord.t); \
+	}
+
+uniform samplerBuffer FVarDataBuffer;
+
 out vec3 varying_position;
 out vec3 varying_normal;
+out vec2 varying_st;
 
 #ifdef FLAT_SHADING
 void emit(int index, vec3 normal)
 {
 	varying_position = inpt[index].v.position.xyz;
 	varying_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;
+
 	gl_Position = projectionMatrix * inpt[index].v.position;
 	EmitVertex();
 }
@@ -86,6 +113,15 @@ void emit(int index)
 {
 	varying_position = inpt[index].v.position.xyz;
 	varying_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;
+
 	gl_Position = projectionMatrix * inpt[index].v.position;
 	EmitVertex();
 }
@@ -93,6 +129,8 @@ void emit(int index)
 
 void main()
 {
+	gl_PrimitiveID = gl_PrimitiveIDIn;
+
 #ifdef FLAT_SHADING
 	vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
 	vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
@@ -155,8 +193,13 @@ uniform vec4 diffuse;
 uniform vec4 specular;
 uniform float shininess;
 
+#ifdef USE_TEXTURE
+uniform sampler2D texture_buffer;
+#endif
+
 in vec3 varying_position;
 in vec3 varying_normal;
+in vec2 varying_st;
 
 void main()
 {
@@ -196,7 +239,11 @@ void main()
 
 	/* Compute diffuse color. */
 	float alpha;
+#ifdef USE_TEXTURE
+	L_diffuse *= texture2D(texture_buffer, varying_st).rgb;
+#else
 	L_diffuse *= diffuse.rgb;
+#endif
 	alpha = diffuse.a;
 
 	/* Sum lighting. */
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index 610ef5b..67d307a 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -333,6 +333,27 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
 	topology = (OsdUtilSubdivTopology *)openSubdiv_getEvaluatorTopologyDescr(
 		evaluator_descr);
 
+#if 0
+	if (topology->fvNames.size() == 0) {
+		for (int i = 0; i < 8840; ++i) {
+			topology->fvData.push_back(0.0f);
+			topology->fvData.push_back(0.0f);
+
+			topology->fvData.push_back(1.0f);
+			topology->fvData.push_back(0.0f);
+
+			topology->fvData.push_back(1.0f);
+			topology->fvData.push_back(1.0f);
+
+			topology->fvData.push_back(0.0f);
+			topology->fvData.push_back(1.0f);
+		}
+
+		topology->fvNames.push_back("u");
+		topology->fvNames.push_back("v");
+	}
+#endif
+
 	if (util_mesh.Initialize(*topology,
 	                         NULL,
 	                         get_osd_scheme(scheme)) == false) {
@@ -344,6 +365,10 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
 	std::vector<int> idsOnPtexFaces;
 	get_partition_per_face(*hmesh, &idsOnPtexFaces);
 
+	hmesh->SetFVarInterpolateBoundaryMethod(
+	        OsdHbrMesh::k_InterpolateBoundaryNone);
+	hmesh->SetFVarPropagateCorners(false);
+
 	OsdMeshBitset bits;
 	/* TODO(sergey): Adaptive subdivisions are not currently
 	 * possible because of the lack of tessellation shader.
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 39f57dc..6a26269 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -50,6 +50,7 @@
 #include "opensubdiv_partitioned.h"
 
 using OpenSubdiv::OsdGLMeshInterface;
+using OpenSubdiv::PartitionedGLMeshInterface;
 
 extern "C" char datatoc_gpu_shader_opensubd_display_glsl[];
 
@@ -233,13 +234,25 @@ GLuint linkProgram(const char *define)
 	}
 
 	GLuint uboIndex = glGetUniformBlockIndex(program, "Lighting");
-	if (uboIndex != GL_INVALID_INDEX)
+	if (uboIndex != GL_INVALID_INDEX) {
 		glUniformBlockBinding(program, uboIndex, 0);
+	}
+
+#if 0  /* Used for textured view */
+	glProgramUniform1i(program,
+	                   glGetUniformLocation(program, "texture_buffer"),
+	                   0);  /* GL_TEXTURE0 */
+#endif
+
+	glProgramUniform1i(program,
+	                   glGetUniformLocation(program, "FVarDataBuffer"),
+	                   4);  /* GL_TEXTURE4 */
 
 	return program;
 }
 
-void bindProgram(int program,
+void bindProgram(PartitionedGLMeshInterface *mesh,
+                 int program,
                  GLuint lighting_ub,
                  Lighting *lightingData)
 {
@@ -304,11 +317,18 @@ void bindProgram(int program,
 		glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
 	}
 	else {
-		float currentColor[4];
-		glGetFloatv(GL_CURRENT_COLOR, currentColor);
+		float color[4];
+		glGetFloatv(GL_CURRENT_COLOR, color);
 		glUniform4fv(glGetUniformLocation(program, "diffuse"),
 		             1,
-		             currentColor);
+		             color);
+	}
+
+	/* Face-fertex data */
+	if (mesh->GetDrawContext()->GetFvarDataTextureBuffer()) {
+		glActiveTexture(GL_TEXTURE4);
+		glBindTexture(GL_TEXTURE_BUFFER,
+		              mesh->GetDrawContext()->GetFvarDataTextureBuffer());
 	}
 }
 
@@ -350,7 +370,6 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
 		need_init = false;
 	}
 #endif
-	using OpenSubdiv::PartitionedGLMeshInterface;
 	using OpenSubdiv::OsdDrawContext;
 	using OpenSubdiv::FarPatchTables;
 
@@ -379,7 +398,8 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
 		program = wireframe_program;
 	}
 
-	bindProgram(program,
+	bindProgram(mesh,
+	            program,
 	            lighting_ub,
 	            &lightingData);
 #else
@@ -394,11 +414,22 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
 		OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
 
 		if (patchType == OpenSubdiv::FarPatchTables::QUADS) {
+#ifndef OPENSUBDIV_LEGACY_DRAW
+			glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"),
+			            patch.GetPatchIndex());
+
 			glDrawElements(GL_LINES_ADJACENCY,
 			               patch.GetNumIndices(),
 			               GL_UNSIGNED_INT,
 			               (void *)(patch.GetVertIndex() *
 			                        sizeof(unsigned int)));
+#else
+			glDrawElements(GL_QUADS,
+			               patch.GetNumIndices(),
+			               GL_UNSIGNED_INT,
+			               (void *)(patch.GetVertIndex() *
+			                        sizeof(unsigned int)));
+#endif
 		}
 	}
 
@@ -408,6 +439,7 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
 	}
 	glBindVertexArray(0);
 #ifndef OPENSUBDIV_LEGACY_DRAW
+	glActiveTexture(GL_TEXTURE0);
 	/* TODO(sergey): Store previously used program and roll back to it? */
 	glUseProgram(0);
 #endif
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index dfe2e1e..e829223 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -64,6 +64,8 @@
 #include "BKE_paint.h"
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
 
 #include "PIL_time.h"
 
@@ -2411,6 +2413,31 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 
 	(void) compareDrawOptions;
 
+#ifdef WITH_OPENSUBDIV
+	if (ccgdm->useGpuBackend) {
+		int mat_nr;
+		bool drawSmooth;
+		MTFace tmp_tf = {{{0}}};
+
+		if (faceFlags) {
+			drawSmooth = (lnors || (faceFlags[0].flag & ME_SMOOTH));
+			mat_nr = faceFlags[0].mat_nr;
+		}
+		else {
+			drawSmooth = 1;
+			mat_nr = 0;
+		}
+
+		tmp_tf.tpage = G.main->image.first;
+		if (drawParams != NULL)
+			drawParams(&tmp_tf, (mcol != NULL), mat_nr);
+
+		ccgSubSurf_prepareGLMesh(ss);
+		ccgSubSurf_drawGLMesh(ss, true, -1);
+		return;
+	}
+#endif
+
 	CCG_key_top_level(&key, ss);
 	ccgdm_pbvh_update(ccgdm);




More information about the Bf-blender-cvs mailing list