[Bf-blender-cvs] [25d86e4] temp_display_optimization: First basic GPU upload for edit derived meshes.
Antony Riakiotakis
noreply at git.blender.org
Tue Jul 28 17:00:07 CEST 2015
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;
More information about the Bf-blender-cvs
mailing list