diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-07-19 10:28:54 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-07-20 15:16:38 +0300 |
commit | f0f60d775def20ff3a3699704b33c66712d50c6a (patch) | |
tree | c9c4ec927a9eb447e1a0f9753a74eb99c470d5b5 /source/blender | |
parent | 9a0634a253421c02dbb6d2864db49e4d382ea2a3 (diff) |
OpenSubdiv: Initial work to support UV maps in textured OSD viewport
A bit work in progress, currently the following limitations:
- Texture shading only, Material shading will come later
- No UVs subdivision yet
- Always uses active UV and currently changing active UV will
not properly update the viewport.
Well, need to start somewhere :)
Diffstat (limited to 'source/blender')
6 files changed, 139 insertions, 67 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 828a6bb16ac..c4886a21740 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -313,9 +313,6 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a ss->osd_vao = 0; ss->skip_grids = false; ss->osd_compute = 0; - ss->osd_uvs_invalid = true; - ss->osd_subsurf_uv = 0; - ss->osd_uv_index = -1; ss->osd_next_face_ptex_index = 0; ss->osd_coarse_coords = NULL; ss->osd_num_coarse_coords = 0; diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h index 0cdf3acf075..7e8059e62fc 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h +++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h @@ -254,11 +254,6 @@ struct CCGSubSurf { * to fill in PTex index of CCGFace. */ int osd_next_face_ptex_index; - - /* ** Needs review. ** */ - bool osd_subsurf_uv; - int osd_uv_index; - bool osd_uvs_invalid; #endif }; diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c index 2bb55c2d1ed..c715c1fa1ee 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c @@ -190,7 +190,6 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm) /* ** Make sure both GPU and CPU backends are properly reset. ** */ ss->osd_coarse_coords_invalid = true; - ss->osd_uvs_invalid = true; /* Reset GPU part. */ ss->osd_mesh_invalid = true; @@ -256,8 +255,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl) ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner( ss->osd_topology_refiner, compute_type, - ss->subdivLevels, - ss->osd_subsurf_uv); + ss->subdivLevels); ss->osd_topology_refiner = NULL; if (UNLIKELY(ss->osd_mesh == NULL)) { @@ -290,7 +288,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl) ss->osd_coarse_coords_invalid = false; } - openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl, ss->osd_uv_index); + openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl); return true; } diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index c4317f4d740..72e5f9f1346 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c @@ -62,6 +62,11 @@ typedef struct ConvDMStorage { *vert_poly_mem, *edge_poly_mem; #endif + + MEdge *medge; + MLoop *mloop; + MPoly *mpoly; + MLoopUV *mloopuv; } ConvDMStorage; static OpenSubdiv_SchemeType conv_dm_get_type( @@ -99,9 +104,7 @@ static int conv_dm_get_num_face_verts(const OpenSubdiv_Converter *converter, int face) { ConvDMStorage *storage = converter->user_data; - DerivedMesh *dm = storage->dm; - const MPoly *mp = dm->getPolyArray(dm); - const MPoly *mpoly = &mp[face]; + const MPoly *mpoly = &storage->mpoly[face]; return mpoly->totloop; } @@ -110,13 +113,10 @@ static void conv_dm_get_face_verts(const OpenSubdiv_Converter *converter, int *face_verts) { ConvDMStorage *storage = converter->user_data; - DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); - const MPoly *mpoly = &mp[face]; + const MPoly *mpoly = &storage->mpoly[face]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - face_verts[loop] = ml[mpoly->loopstart + loop].v; + face_verts[loop] = storage->mloop[mpoly->loopstart + loop].v; } } @@ -125,13 +125,10 @@ static void conv_dm_get_face_edges(const OpenSubdiv_Converter *converter, int *face_edges) { ConvDMStorage *storage = converter->user_data; - DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); - const MPoly *mpoly = &mp[face]; + const MPoly *mpoly = &storage->mpoly[face]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - face_edges[loop] = ml[mpoly->loopstart + loop].e; + face_edges[loop] = storage->mloop[mpoly->loopstart + loop].e; } } @@ -140,9 +137,7 @@ static void conv_dm_get_edge_verts(const OpenSubdiv_Converter *converter, int *edge_verts) { ConvDMStorage *storage = converter->user_data; - DerivedMesh *dm = storage->dm; - const MEdge *me = dm->getEdgeArray(dm); - const MEdge *medge = &me[edge]; + const MEdge *medge = &storage->medge[edge]; edge_verts[0] = medge->v1; edge_verts[1] = medge->v2; } @@ -153,14 +148,12 @@ static int conv_dm_get_num_edge_faces(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); int num = 0, poly; for (poly = 0; poly < dm->getNumPolys(dm); poly++) { - const MPoly *mpoly = &mp[poly]; + const MPoly *mpoly = &user_data->mpoly[poly]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *mloop = &ml[mpoly->loopstart + loop]; + const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop]; if (mloop->e == edge) { ++num; break; @@ -180,14 +173,12 @@ static void conv_dm_get_edge_faces(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); int num = 0, poly; for (poly = 0; poly < dm->getNumPolys(dm); poly++) { - const MPoly *mpoly = &mp[poly]; + const MPoly *mpoly = &user_data->mpoly[poly]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *mloop = &ml[mpoly->loopstart + loop]; + const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop]; if (mloop->e == edge) { edge_faces[num++] = poly; break; @@ -205,9 +196,8 @@ static float conv_dm_get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge) { ConvDMStorage *storage = converter->user_data; - DerivedMesh *dm = storage->dm; CCGSubSurf *ss = storage->ss; - const MEdge *medge = dm->getEdgeArray(dm); + const MEdge *medge = storage->medge; return (float)medge[edge].crease / 255.0f * ss->subdivLevels; } @@ -217,10 +207,9 @@ static int conv_dm_get_num_vert_edges(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MEdge *me = dm->getEdgeArray(dm); int num = 0, edge; for (edge = 0; edge < dm->getNumEdges(dm); edge++) { - const MEdge *medge = &me[edge]; + const MEdge *medge = &user_data->medge[edge]; if (medge->v1 == vert || medge->v2 == vert) { ++num; } @@ -238,10 +227,9 @@ static void conv_dm_get_vert_edges(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MEdge *me = dm->getEdgeArray(dm); int num = 0, edge; for (edge = 0; edge < dm->getNumEdges(dm); edge++) { - const MEdge *medge = &me[edge]; + const MEdge *medge = &user_data->medge[edge]; if (medge->v1 == vert || medge->v2 == vert) { vert_edges[num++] = edge; } @@ -259,14 +247,12 @@ static int conv_dm_get_num_vert_faces(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); int num = 0, poly; for (poly = 0; poly < dm->getNumPolys(dm); poly++) { - const MPoly *mpoly = &mp[poly]; + const MPoly *mpoly = &user_data->mpoly[poly]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *mloop = &ml[mpoly->loopstart + loop]; + const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop]; if (mloop->v == vert) { ++num; break; @@ -286,14 +272,12 @@ static void conv_dm_get_vert_faces(const OpenSubdiv_Converter *converter, ConvDMStorage *storage = converter->user_data; #ifndef USE_MESH_ELEMENT_MAPPING DerivedMesh *dm = storage->dm; - const MLoop *ml = dm->getLoopArray(dm); - const MPoly *mp = dm->getPolyArray(dm); int num = 0, poly; for (poly = 0; poly < dm->getNumPolys(dm); poly++) { - const MPoly *mpoly = &mp[poly]; + const MPoly *mpoly = &storage->mpoly[poly]; int loop; for (loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *mloop = &ml[mpoly->loopstart + loop]; + const MLoop *mloop = &storage->mloop[mpoly->loopstart + loop]; if (mloop->v == vert) { vert_faces[num++] = poly; break; @@ -307,6 +291,24 @@ static void conv_dm_get_vert_faces(const OpenSubdiv_Converter *converter, #endif } +static int conv_dm_get_num_uv_layers(const OpenSubdiv_Converter *converter) +{ + ConvDMStorage *storage = converter->user_data; + DerivedMesh *dm = storage->dm; + return CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV); +} + +static void conv_dm_get_face_corner_uv(const OpenSubdiv_Converter *converter, + int face, + int corner, + float r_uv[2]) +{ + ConvDMStorage *storage = converter->user_data; + MPoly *mpoly = &storage->mpoly[face]; + MLoopUV *mloopuv = &storage->mloopuv[mpoly->loopstart + corner]; + copy_v2_v2(r_uv, mloopuv->uv); +} + static void conv_dm_free_user_data(const OpenSubdiv_Converter *converter) { ConvDMStorage *user_data = converter->user_data; @@ -348,9 +350,18 @@ void ccgSubSurf_converter_setup_from_derivedmesh( converter->get_num_vert_faces = conv_dm_get_num_vert_faces; converter->get_vert_faces = conv_dm_get_vert_faces; + converter->get_num_uv_layers = conv_dm_get_num_uv_layers; + converter->get_face_corner_uv = conv_dm_get_face_corner_uv; + user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__); user_data->ss = ss; user_data->dm = dm; + + user_data->medge = dm->getEdgeArray(dm); + user_data->mloop = dm->getLoopArray(dm); + user_data->mpoly = dm->getPolyArray(dm); + user_data->mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV); + converter->free_user_data = conv_dm_free_user_data; converter->user_data = user_data; @@ -548,6 +559,19 @@ static void conv_ccg_get_vert_faces(const OpenSubdiv_Converter *converter, } } +static int conv_ccg_get_num_uv_layers(const OpenSubdiv_Converter *UNUSED(converter)) +{ + return 0; +} + +static void conv_ccg_get_face_corner_uv(const OpenSubdiv_Converter * UNUSED(converter), + int UNUSED(face), + int UNUSED(corner), + float r_uv[2]) +{ + zero_v2(r_uv); +} + void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, OpenSubdiv_Converter *converter) { @@ -571,6 +595,9 @@ void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, converter->get_num_vert_faces = conv_ccg_get_num_vert_faces; converter->get_vert_faces = conv_ccg_get_vert_faces; + converter->get_num_uv_layers = conv_ccg_get_num_uv_layers; + converter->get_face_corner_uv = conv_ccg_get_face_corner_uv; + converter->free_user_data = NULL; converter->user_data = ss; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index f73dbd8078f..b9efe23a4b3 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3386,19 +3386,6 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, int mat_index; int tot_element, start_element, tot_drawn; -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - if (ccgSubSurf_prepareGLMesh(ss, true) == false) { - return; - } - ccgSubSurf_drawGLMesh(ss, true, -1, -1); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - if (use_colors) { colType = CD_TEXTURE_MLOOPCOL; mloopcol = dm->getLoopDataArray(dm, colType); @@ -3412,6 +3399,77 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, } } +#ifdef WITH_OPENSUBDIV + if (ccgdm->useGpuBackend) { + if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true) == false)) { + return; + } + if (drawParams == NULL) { + ccgSubSurf_drawGLMesh(ss, true, -1, -1); + return; + } + const int level = ccgSubSurf_getSubdivisionLevels(ss); + const int face_side = 1 << level; + const int grid_side = 1 << (level - 1); + const int face_patches = face_side * face_side; + const int grid_patches = grid_side * grid_side; + const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss); + int current_patch = 0; + int mat_nr = -1; + int start_draw_patch = 0, num_draw_patches = 0; + for (i = 0; i < num_base_faces; ++i) { + const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i); + const int num_patches = (num_face_verts == 4) ? face_patches + : num_face_verts * grid_patches; + if (faceFlags) { + mat_nr = faceFlags[i].mat_nr + 1; + } + else { + mat_nr = 0; + } + + if (drawParams != NULL) { + MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[i] : NULL; + draw_option = drawParams(tp, (mloopcol != NULL), mat_nr); + } + else { + draw_option = (drawParamsMapped) + ? drawParamsMapped(userData, i, mat_nr) + : DM_DRAW_OPTION_NORMAL; + } + + flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1); + + if (!flush && compareDrawOptions) { + flush |= compareDrawOptions(userData, i, min_ii(i + 1, num_base_faces - 1)) == 0; + } + + current_patch += num_patches; + + if (flush) { + if (draw_option != DM_DRAW_OPTION_SKIP) { + num_draw_patches += num_patches; + } + if (num_draw_patches != 0) { + ccgSubSurf_drawGLMesh(ss, + true, + start_draw_patch, + num_draw_patches); + } + start_draw_patch = current_patch; + num_draw_patches = 0; + } + else { + num_draw_patches += num_patches; + } + } + return; + } +#endif + + CCG_key_top_level(&key, ss); + ccgdm_pbvh_update(ccgdm); + GPU_vertex_setup(dm); GPU_normal_setup(dm); GPU_triangle_setup(dm); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 3c028ff0805..8ec932f4184 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -868,14 +868,12 @@ static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) BLI_dynstr_append(ds, datatoc_gpu_shader_geometry_glsl); /* Generate varying assignments. */ - /* TODO(sergey): Disabled for now, needs revisit. */ -#if 0 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, - "\tINTERP_FACE_VARYING_2(var%d, " + "\t// INTERP_FACE_VARYING_2(var%d, " "fvar%d_offset, st);\n", input->attribid, input->attribid); @@ -883,7 +881,6 @@ static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) } } } -#endif BLI_dynstr_append(ds, "}\n"); code = BLI_dynstr_get_cstring(ds); |