Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-08-25 16:05:28 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-08-25 16:11:56 +0300
commitf1e68474e051667b85ac804bded8fa2c8e0ff374 (patch)
tree9e3470179f56bff64807d944ad8af32141fcbc45 /intern/opensubdiv
parent50917edad54d2be0f5e3a6630382e28ab1fd32e0 (diff)
OpenSubdiv: Support for multiple materials in solid shading mode
Implementation is less optimal compared to non-opensubdiv drawing but it is now as good as we can do it without affecting on how patches are being created by OpenSubdiv.
Diffstat (limited to 'intern/opensubdiv')
-rw-r--r--intern/opensubdiv/opensubdiv_capi.h4
-rw-r--r--intern/opensubdiv/opensubdiv_converter.cc11
-rw-r--r--intern/opensubdiv/opensubdiv_converter_capi.h6
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc76
4 files changed, 50 insertions, 47 deletions
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index c86e739f12b..c09d0326264 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -135,8 +135,8 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
/* Draw patches which corresponds to a given partition. */
void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
int fill_quads,
- int start_partition,
- int num_partitions);
+ int start_patch,
+ int num_patches);
/* ** Utility functions ** */
int openSubdiv_supportGPUDisplay(void);
diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc
index 09880742895..5d43cafd1f3 100644
--- a/intern/opensubdiv/opensubdiv_converter.cc
+++ b/intern/opensubdiv/opensubdiv_converter.cc
@@ -574,6 +574,17 @@ int openSubdiv_topologyRefinerGetNumFaces(
return base_level.GetNumFaces();
}
+int openSubdiv_topologyRefinerGetNumFaceVerts(
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+ int face)
+{
+ using OpenSubdiv::Far::TopologyLevel;
+ using OpenSubdiv::Far::TopologyRefiner;
+ const TopologyRefiner *refiner = (const TopologyRefiner *)topology_refiner;
+ const TopologyLevel &base_level = refiner->GetLevel(0);
+ return base_level.GetFaceVertices(face).size();
+}
+
int openSubdiv_topologyRefnerCompareConverter(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
OpenSubdiv_Converter *converter)
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h
index 7c96d3d8b96..ac1e8301a42 100644
--- a/intern/opensubdiv/opensubdiv_converter_capi.h
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -94,7 +94,7 @@ void openSubdiv_deleteTopologyRefinerDescr(
OpenSubdiv_TopologyRefinerDescr *topology_refiner);
/* TODO(sergey): Those calls are not strictly related on conversion.
- * needs some dedicated fiel perhaps.
+ * needs some dedicated file perhaps.
*/
int openSubdiv_topologyRefinerGetSubdivLevel(
@@ -109,6 +109,10 @@ int openSubdiv_topologyRefinerGetNumEdges(
int openSubdiv_topologyRefinerGetNumFaces(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner);
+int openSubdiv_topologyRefinerGetNumFaceVerts(
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+ int face);
+
int openSubdiv_topologyRefnerCompareConverter(
const OpenSubdiv_TopologyRefinerDescr *topology_refiner,
OpenSubdiv_Converter *converter);
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 9498f936b6b..803265dbe28 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -575,46 +575,41 @@ static void finish_patchDraw(bool fill_quads)
}
}
-#if 0
static void draw_partition_patches_range(PartitionedGLMeshInterface *mesh,
GLuint program,
- int start_partition,
- int num_partitions)
+ int start_patch,
+ int num_patches)
{
- /* Glue patches from all partitions in the range together. */
- int patch_index = -1, start_element = -1, num_elements = 0;
- for (int partition = start_partition;
- partition < start_partition + num_partitions;
- ++partition)
- {
- OsdDrawContext::PatchArrayVector const &patches =
- mesh->GetPatchArrays(partition);
- for (int i = 0; i < (int)patches.size(); ++i) {
- OsdDrawContext::PatchArray const &patch = patches[i];
- OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
- OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
- if (patchType == OpenSubdiv::FarPatchTables::QUADS) {
- if (start_element == -1) {
- patch_index = patch.GetPatchIndex();
- start_element = patch.GetVertIndex();
- }
+ int traversed_patches = 0, num_remained_patches = num_patches;
+ const OpenSubdiv::Osd::PatchArrayVector& patches =
+ mesh->GetPatchTable()->GetPatchArrays();
+ for (int i = 0; i < (int)patches.size(); ++i) {
+ const OpenSubdiv::Osd::PatchArray& patch = patches[i];
+ OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
+ OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
- assert(patch.GetVertIndex() == start_element + num_elements);
- num_elements += patch.GetNumIndices();
+ if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
+ const int num_block_patches = patch.GetNumPatches();
+ if (start_patch >= traversed_patches &&
+ start_patch < traversed_patches + num_block_patches)
+ {
+ const int num_control_verts = desc.GetNumControlVertices();
+ const int start_draw_patch = start_patch - traversed_patches;
+ const int num_draw_patches = std::min(num_remained_patches,
+ num_block_patches - start_draw_patch);
+ perform_drawElements(program,
+ i,
+ num_draw_patches * num_control_verts,
+ patch.GetIndexBase() + start_draw_patch * num_control_verts);
+ num_remained_patches -= num_draw_patches;
}
- else {
- assert(!"Discontinuitied are not supported yet.");
+ if (num_remained_patches == 0) {
+ break;
}
+ traversed_patches += num_block_patches;
}
- }
-
- /* Perform actual draw. */
- perform_drawElements(program,
- patch_index,
- num_elements,
- start_element);
+ }
}
-#endif
static void draw_all_patches(PartitionedGLMeshInterface *mesh,
GLuint program)
@@ -637,8 +632,8 @@ static void draw_all_patches(PartitionedGLMeshInterface *mesh,
void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
int fill_quads,
- int start_partition,
- int num_partitions)
+ int start_patch,
+ int num_patches)
{
PartitionedGLMeshInterface *mesh =
(PartitionedGLMeshInterface *)(gl_mesh->descriptor);
@@ -649,18 +644,11 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
/* Setup GLSL/OpenGL to draw patches in current context. */
GLuint program = preapre_patchDraw(mesh, fill_quads != 0);
- if (start_partition != -1) {
-#if 0
+ if (start_patch != -1) {
draw_partition_patches_range(mesh,
program,
- start_partition,
- num_partitions);
-#else
- (void)num_partitions;
- if(start_partition == 0) {
- draw_all_patches(mesh, program);
- }
-#endif
+ start_patch,
+ num_patches);
}
else {
draw_all_patches(mesh, program);