[Bf-blender-cvs] [95963ce] opensubdiv-modifier: OpenSubdiv: Hook up UV attributes from OSD to GPU_material pipeline
Sergey Sharybin
noreply at git.blender.org
Fri Jul 25 13:02:06 CEST 2014
Commit: 95963cefa36dc88063e07e2716f5e77d46836147
Author: Sergey Sharybin
Date: Fri Jul 25 16:36:46 2014 +0600
Branches: opensubdiv-modifier
https://developer.blender.org/rB95963cefa36dc88063e07e2716f5e77d46836147
OpenSubdiv: Hook up UV attributes from OSD to GPU_material pipeline
For now active UV map is used for all the attributes, but that's
rather simple to fix now.
===================================================================
M intern/opensubdiv/opensubdiv_capi.cc
M intern/opensubdiv/opensubdiv_capi.h
M source/blender/blenkernel/intern/CCGSubSurf.c
M source/blender/blenkernel/intern/CCGSubSurf.h
M source/blender/blenkernel/intern/subsurf_ccg.c
M source/blender/gpu/intern/gpu_codegen.c
M source/blender/gpu/intern/gpu_codegen.h
M source/blender/gpu/shaders/gpu_shader_geometry.glsl
===================================================================
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index e4400be..9b4c0aa 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -319,7 +319,8 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
OpenSubdiv_EvaluatorDescr *evaluator_descr,
int controller_type,
int level,
- int scheme)
+ int scheme,
+ int subdivide_uvs)
{
OpenSubdiv_ComputeController *controller =
openSubdiv_getController(controller_type);
@@ -345,7 +346,9 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
get_partition_per_face(*hmesh, &idsOnPtexFaces);
hmesh->SetFVarInterpolateBoundaryMethod(
- OsdHbrMesh::k_InterpolateBoundaryNone);
+ subdivide_uvs
+ ? OsdHbrMesh::k_InterpolateBoundaryEdgeAndCorner
+ : OsdHbrMesh::k_InterpolateBoundaryNone);
hmesh->SetFVarPropagateCorners(false);
OsdMeshBitset bits;
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index 0e18080..b20e95a 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -67,7 +67,8 @@ OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
OpenSubdiv_EvaluatorDescr *evaluator_descr,
int controller_type,
int level,
- int scheme);
+ int scheme,
+ int subdivide_uvs);
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh);
unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer(
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index cfc17c8..a8858cf 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -473,6 +473,7 @@ struct CCGSubSurf {
bool osd_uvs_invalid;
int osd_uv_index;
+ bool osd_subsurf_uv;
#endif
};
@@ -939,6 +940,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
ss->osd_compute = 0;
ss->osd_uvs_invalid = false;
ss->osd_uv_index = -1;
+ ss->osd_subsurf_uv = 0;
#endif
return ss;
@@ -2367,7 +2369,8 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl)
ss->osd_evaluator,
compute_type,
ss->subdivLevels,
- scheme);
+ scheme,
+ ss->osd_subsurf_uv);
if (UNLIKELY(ss->osd_mesh == NULL)) {
/* Most likely compute device is not available. */
@@ -2543,7 +2546,9 @@ static bool opensubdiv_initEvaluator(CCGSubSurf *ss)
scheme) != 0;
}
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, DerivedMesh *dm)
+void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
+ DerivedMesh *dm,
+ bool subdivide_uvs)
{
/* TODO(sergey): Do we have shorter way to do this? */
int active = CustomData_get_active_layer(&dm->loopData,
@@ -2559,12 +2564,17 @@ void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, DerivedMesh *dm)
ss->osd_uvs_invalid = true;
}
+ if (subdivide_uvs != ss->osd_subsurf_uv) {
+ ss->osd_uvs_invalid = true;
+ }
+
if (mloopuv == NULL || !ss->osd_uvs_invalid) {
return;
}
ss->osd_uvs_invalid = false;
ss->osd_uv_index = active;
+ ss->osd_subsurf_uv = subdivide_uvs;
if (ss->osd_mesh) {
ss->osd_mesh_invalid = true;
}
@@ -3097,6 +3107,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
ss->osd_coords_invalid = true;
+
/* Make sure OSD evaluator is up-to-date. */
if (opensubdiv_ensureEvaluator(ss)) {
if (ss->skip_grids == false) {
@@ -3107,6 +3118,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
opensubdiv_evaluateGrids(ss);
}
else {
+ BLI_assert(ss->meshIFC.numLayers == 3);
opensubdiv_updateCoarseNormals(ss);
}
}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index db74a59..9e40835 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -196,7 +196,9 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
struct DerivedMesh;
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, struct DerivedMesh *dm);
+void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
+ struct DerivedMesh *dm,
+ bool subdivide_uvs);
#endif
#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index e191d95..ea00bd5 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -4288,7 +4288,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
ccgSubSurf_setNumLayers(ss, 4);
#ifdef WITH_OPENSUBDIV
- ccgSubSurf_setUVCoordsFromDM(ss, dm);
+ ccgSubSurf_setUVCoordsFromDM(ss, dm, useSubsurfUv);
#endif
}
}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index b29ed64..93a2cef 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -641,10 +641,48 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
return code;
}
-static char *code_generate_geometry(bool use_opensubdiv)
+static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv)
{
if (use_opensubdiv) {
- return datatoc_gpu_shader_geometry_glsl;
+ DynStr *ds = BLI_dynstr_new();
+ GPUNode *node;
+ GPUInput *input;
+ char *code;
+
+ /* Generate varying declarations. */
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ if (input->attribtype == CD_MTFACE) {
+ BLI_dynstr_appendf(ds, "varying %s var%d;\n",
+ GPU_DATATYPE_STR[input->type],
+ input->attribid);
+ }
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, datatoc_gpu_shader_geometry_glsl);
+
+ /* Generate varying assignments. */
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ if (input->attribtype == CD_MTFACE) {
+ BLI_dynstr_appendf(ds, "\tvar%d = outpt.v.uv;\n",
+ input->attribid);
+ }
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "}\n\n");
+ code = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ //if (G.debug & G_DEBUG) printf("%s\n", code);
+
+ return code;
}
return NULL;
}
@@ -659,10 +697,17 @@ static char *code_generate_vertex(ListBase *nodes)
for (node=nodes->first; node; node=node->next) {
for (input=node->inputs.first; input; input=input->next) {
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ bool is_mtface = input->attribtype == CD_MTFACE;
+ if (is_mtface) {
+ BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+ }
BLI_dynstr_appendf(ds, "attribute %s att%d;\n",
GPU_DATATYPE_STR[input->type], input->attribid);
BLI_dynstr_appendf(ds, "varying %s var%d;\n",
GPU_DATATYPE_STR[input->type], input->attribid);
+ if (is_mtface) {
+ BLI_dynstr_appendf(ds, "#endif\n");
+ }
}
}
}
@@ -677,8 +722,16 @@ static char *code_generate_vertex(ListBase *nodes)
BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid);
BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid);
}
- else
+ else {
+ bool is_mtface = input->attribtype == CD_MTFACE;
+ if (is_mtface) {
+ BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+ }
BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid);
+ if (is_mtface) {
+ BLI_dynstr_appendf(ds, "#endif\n");
+ }
+ }
}
/* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */
else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
@@ -1415,7 +1468,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
/* generate code and compile with opengl */
fragmentcode = code_generate_fragment(nodes, outlink->output, name);
- geometrycode = code_generate_geometry(use_opensubdiv);
+ geometrycode = code_generate_geometry(nodes, use_opensubdiv);
vertexcode = code_generate_vertex(nodes);
shader = GPU_shader_create(vertexcode, geometrycode, fragmentcode, glsl_material_library, NULL);
@@ -1433,6 +1486,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
pass->output = outlink->output;
pass->shader = shader;
pass->fragmentcode = fragmentcode;
+ pass->geometrycode = geometrycode;
pass->vertexcode = vertexcode;
pass->libcode = glsl_material_library;
@@ -1449,6 +1503,8 @@ void GPU_pass_free(GPUPass *pass)
GPU_inputs_free(&pass->inputs);
if (pass->fragmentcode)
MEM_freeN(pass->fragmentcode);
+ if (pass->geometrycode)
+ MEM_freeN(pass->geometrycode);
if (pass->vertexcode)
MEM_freeN(pass->vertexcode);
MEM_freeN(pass);
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index dde8daf..656c49f 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -167,6 +167,7 @@ struct GPUPass {
struct GPUOutput *output;
struct GPUShader *shader;
char *fragmentcode;
+ char *geometrycode;
char *vertexcode;
const char *libcode;
};
diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
index 544eca9..4069d9e 100644
--- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -29,6 +29,8 @@ out block {
VertexData v;
} outpt;
+void set_mtface_vertex_attrs();
+
void emit_flat(int index, vec3 normal)
{
outpt.v.position = inpt[index].v.position;
@@ -44,6 +46,8 @@ void emit_flat(int index, vec3 normal)
INTERP_FACE_VARYING_2(o
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list