Commit: 25d86e4459efb1e109afceb91f377d30d63487bd Author: Antony Riakiotakis Date: Tue Jul 28 16:58:59 2015 +0200 Branches: temp_display_optimization https://developer.blender.org/rB25d86e4459efb1e109afceb91f377d30d63487bd
First basic GPU upload for edit derived meshes. Normals, coordinates and triangles work. =================================================================== M source/blender/blenkernel/intern/editderivedmesh.c =================================================================== diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 8f251b7..3e3886a 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -55,6 +55,7 @@ #include "MEM_guardedalloc.h" +#include "GPU_buffers.h" #include "GPU_extensions.h" #include "GPU_glew.h" @@ -347,6 +348,246 @@ static void emDM_foreachMappedEdge( } } +static void emDM_buffer_copy_vertex( + DerivedMesh *dm, float *varray) +{ + BMIter iter, iterv; + EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; + BMEditMesh *em = bmdm->em; + BMesh *bm = em->bm; + + BMVert *v; + BMFace *efa; + + int start = 0; + + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM(v, &iterv, efa, BM_VERTS_OF_FACE) { + copy_v3_v3(&varray[start], v->co); + start += 3; + } + } + + /* copy loose points + j = dm->drawObject->tot_loop_verts * 3; + for (i = 0; i < dm->drawObject->totvert; i++) { + if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_loop_verts) { + copy_v3_v3(&varray[j], mvert[i].co); + j += 3; + } + } + */ +} + +static void emDM_buffer_copy_normal( + DerivedMesh *dm, short *varray) +{ + BMIter iter, iterl; + EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; + BMEditMesh *em = bmdm->em; + BMesh *bm = em->bm; + BMLoop *l; + BMFace *efa; + + int i; + int start; + + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); + + const float (*polyNos)[3] = NULL; + const float (*vertexNos)[3] = NULL; + + if (bmdm->vertexCos) { + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + polyNos = bmdm->polyNos; + vertexNos = bmdm->vertexNos; + } + + start = 0; + + BM_ITER_MESH_INDEX(efa, &iter, bm, BM_FACES_OF_MESH, i) { + const bool smoothnormal = BM_elem_flag_test(efa, BM_ELEM_SMOOTH); + + BM_ITER_ELEM(l, &iterl, efa, BM_LOOPS_OF_FACE) { + if (lnors) { + /* Copy loop normals */ + normal_float_to_short_v3(&varray[start], lnors[BM_elem_index_get(l)]); + } + else if (smoothnormal) { + /* Copy vertex normal */ + if (vertexNos) + normal_float_to_short_v3(&varray[start], vertexNos[BM_elem_index_get(l->v)]); + else + normal_float_to_short_v3(&varray[start], l->v->no); + } + else { + if (polyNos) + normal_float_to_short_v3(&varray[start], polyNos[i]); + else + normal_float_to_short_v3(&varray[start], efa->no); + } + start += 4; + } + } +} + +typedef struct FaceCount { + unsigned int i_visible; + unsigned int i_hidden; + unsigned int i_tri_visible; + unsigned int i_tri_hidden; +} FaceCount; + +static void emDM_buffer_copy_triangles( + DerivedMesh *dm, unsigned int *varray, + const int *mat_orig_to_new) +{ + GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials; + int i, j, start; + + BMIter iter; + EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; + BMEditMesh *em = bmdm->em; + BMesh *bm = em->bm; + BMLoop *(*lt)[3] = bmdm->em->looptris; + + BMFace *efa; + + const int totmat = dm->drawObject->totmaterial; + + FaceCount *fc = MEM_mallocN(sizeof(*fc) * totmat, "gpumaterial.facecount"); + + for (i = 0; i < totmat; i++) { + fc[i].i_visible = 0; + fc[i].i_tri_visible = 0; + fc[i].i_hidden = gpumaterials[i].totpolys - 1; + fc[i].i_tri_hidden = gpumaterials[i].totelements - 1; + } + + BM_mesh_elem_index_ensure(bm, BM_LOOP); + + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + int tottri = efa->len - 2; + int mati = mat_orig_to_new[efa->mat_nr]; + gpumat = gpumaterials + mati; + + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + for (j = 0; j < tottri; j++, lt++) { + start = gpumat->start + fc[mati].i_tri_hidden; + /* v1 v2 v3 */ + varray[start--] = BM_elem_index_get((*lt)[2]); + varray[start--] = BM_elem_index_get((*lt)[1]); + varray[start--] = BM_elem_index_get((*lt)[0]); + fc[mati].i_tri_hidden -= 3; + } + gpumat->polys[fc[mati].i_hidden--] = i; + } + else { + for (j = 0; j < tottri; j++, lt++) { + start = gpumat->start + fc[mati].i_tri_visible; + /* v1 v2 v3 */ + varray[start++] = BM_elem_index_get((*lt)[0]); + varray[start++] = BM_elem_index_get((*lt)[1]); + varray[start++] = BM_elem_index_get((*lt)[2]); + fc[mati].i_tri_visible += 3; + } + gpumat->polys[fc[mati].i_visible++] = i; + } + } + + /* set the visible polygons */ + for (i = 0; i < totmat; i++) { + gpumaterials[i].totvisiblepolys = fc[i].i_visible; + } + + MEM_freeN(fc); +} + +static void emDM_copy_gpu_data( + DerivedMesh *dm, int type, void *varray_p, + const int *mat_orig_to_new, const void *UNUSED(user_data)) +{ + /* 'varray_p' cast is redundant but include for self-documentation */ + switch (type) { + case GPU_BUFFER_VERTEX: + emDM_buffer_copy_vertex(dm, (float *)varray_p); + break; + case GPU_BUFFER_NORMAL: + emDM_buffer_copy_normal(dm, (short *)varray_p); + break; + case GPU_BUFFER_COLOR: +// cdDM_buffer_copy_mcol(dm, (unsigned char *)varray_p, user_data); + break; + case GPU_BUFFER_UV: +// cdDM_buffer_copy_uv(dm, (float *)varray_p); + break; + case GPU_BUFFER_UV_TEXPAINT: +// cdDM_buffer_copy_uv_texpaint(dm, (float *)varray_p); + break; + case GPU_BUFFER_EDGE: +// cdDM_buffer_copy_edge(dm, (unsigned int *)varray_p); + break; + case GPU_BUFFER_UVEDGE: +// cdDM_buffer_copy_uvedge(dm, (float *)varray_p); + break; + case GPU_BUFFER_TRIANGLES: + emDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new); + break; + default: + break; + } +} + + +/* see GPUDrawObject's structure definition for a description of the + * data being initialized here */ +static GPUDrawObject *emDM_GPUobject_new(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; + BMEditMesh *em = bmdm->em; + BMesh *bm = em->bm; + GPUDrawObject *gdo; + + BMIter iter; + const BMFace *efa; + const int tottri = bmdm->em->tottri; + + int totmat = dm->totmat; + GPUBufferMaterial *mat_info; + int i; + + /* object contains at least one material (default included) so zero means uninitialized dm */ + BLI_assert(totmat != 0); + + /* get the number of points used by each material, treating + * each quad as two triangles */ + mat_info = MEM_callocN(sizeof(*mat_info) * totmat, "GPU_drawobject_new.mat_orig_to_new"); + + BM_ITER_MESH_INDEX(efa, &iter, bm, BM_FACES_OF_MESH, i) { + const int mat_nr = efa->mat_nr; + mat_info[mat_nr].totpolys++; + mat_info[mat_nr].totelements += 3 * (efa->len - 2); + mat_info[mat_nr].totloops += efa->len; + } + + /* create the GPUDrawObject */ + gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); + + gdo->totvert = bm->totvert; + gdo->totedge = bm->totedge; + + GPU_buffer_material_finalize(gdo, mat_info, totmat); + + gdo->tot_loop_verts = dm->getNumLoops(dm); + + /* store total number of points used for triangles */ + gdo->tot_triangle_point = tottri * 3; + + return gdo; +} + + static void emDM_drawMappedEdges( DerivedMesh *dm, DMSetDrawOptions setDrawOptions, @@ -555,7 +796,6 @@ static void emDM_drawMappedFaces( DMDrawOption draw_option; int i, flush; const int skip_normals = !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; unsigned char(*color_vert_array)[4] = em->derivedVertColor; @@ -580,6 +820,15 @@ static void emDM_drawMappedFaces( glDisable(GL_LIGHTING); /* grr */ } + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + GPU_triangle_setup(dm); + if (dm->drawObject->triangles) { + GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, dm->drawObject->materials[0].totelements); + } + GPU_buffers_unbind(); + return; + if (bmdm->vertexCos) { short prev_mat_nr = -1; @@ -1883,6 +2132,9 @@ DerivedMesh *getEditDerivedBMesh( bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL; bmdm->dm.drawUVEdges = emDM_drawUVEdges; + bmdm->dm.gpuObjectNew = emDM_GPUobject_new; + bmdm->dm.copy_gpu_data = emDM_copy_gpu_data; + bmdm->dm.release = emDM_release; bmdm->vertexCos = (const float (*)[3])vertexCos; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs