diff options
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 1035 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 36 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 11 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 138 |
5 files changed, 451 insertions, 771 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 7f49fc60bde..e3950567d80 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -343,106 +343,64 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) static void cdDM_drawVerts(DerivedMesh *dm) { - CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mv = cddm->mvert; - int i; - - if (GPU_buffer_legacy(dm)) { - glBegin(GL_POINTS); - for (i = 0; i < dm->numVertData; i++, mv++) - glVertex3fv(mv->co); - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - if (!GPU_buffer_legacy(dm)) { - if (dm->drawObject->tot_triangle_point) - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); - else - glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); - } - GPU_buffer_unbind(); - } + GPU_vertex_setup(dm); + if (dm->drawObject->tot_triangle_point) + glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); + else + glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); + GPU_buffer_unbind(); } static void cdDM_drawUVEdges(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MFace *mf = cddm->mface; - MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); int i; if (mf) { - if (GPU_buffer_legacy(dm)) { - glBegin(GL_LINES); - for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) { - if (!(mf->flag & ME_HIDE)) { - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - - if (!mf->v4) { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[0]); - } - else { - glVertex2fv(tf->uv[2]); - glVertex2fv(tf->uv[3]); - - glVertex2fv(tf->uv[3]); - glVertex2fv(tf->uv[0]); - } - } + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + int curpos = 0; + + GPU_uvedge_setup(dm); + for (i = 0; i < dm->numTessFaceData; i++, mf++) { + if (!(mf->flag & ME_HIDE)) { + draw = 1; } - glEnd(); - } - else { - int prevstart = 0; - int prevdraw = 1; - int draw = 1; - int curpos = 0; - - GPU_uvedge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numTessFaceData; i++, mf++) { - if (!(mf->flag & ME_HIDE)) { - draw = 1; - } - else { - draw = 0; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (curpos - prevstart) > 0) { - glDrawArrays(GL_LINES, prevstart, curpos - prevstart); - } - prevstart = curpos; - } - if (mf->v4) { - curpos += 8; - } - else { - curpos += 6; - } - prevdraw = draw; - } + else { + draw = 0; + } + if (prevdraw != draw) { if (prevdraw > 0 && (curpos - prevstart) > 0) { glDrawArrays(GL_LINES, prevstart, curpos - prevstart); } + prevstart = curpos; + } + if (mf->v4) { + curpos += 8; } - GPU_buffer_unbind(); + else { + curpos += 6; + } + prevdraw = draw; + } + if (prevdraw > 0 && (curpos - prevstart) > 0) { + glDrawArrays(GL_LINES, prevstart, curpos - prevstart); } + GPU_buffer_unbind(); } } static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; MEdge *medge = cddm->medge; int i; - + int prevstart = 0; + int prevdraw = 1; + bool draw = true; + if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { @@ -451,97 +409,60 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg return; } - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawEdges\n"); - glBegin(GL_LINES); - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && - (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) - { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); - } + GPU_edge_setup(dm); + for (i = 0; i < dm->numEdgeData; i++, medge++) { + if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && + (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) + { + draw = true; } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int prevstart = 0; - int prevdraw = 1; - bool draw = true; - - GPU_edge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) && - (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) - { - draw = true; - } - else { - draw = false; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (i - prevstart) > 0) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); - } - prevstart = i; - } - prevdraw = draw; - } + else { + draw = false; + } + if (prevdraw != draw) { if (prevdraw > 0 && (i - prevstart) > 0) { GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + prevstart = i; } - GPU_buffer_unbind(); + prevdraw = draw; } + if (prevdraw > 0 && (i - prevstart) > 0) { + GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); + } + GPU_buffer_unbind(); } static void cdDM_drawLooseEdges(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; MEdge *medge = cddm->medge; int i; - - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n"); - glBegin(GL_LINES); - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if (medge->flag & ME_LOOSEEDGE) { - glVertex3fv(mvert[medge->v1].co); - glVertex3fv(mvert[medge->v2].co); - } + + int prevstart = 0; + int prevdraw = 1; + int draw = 1; + + GPU_edge_setup(dm); + for (i = 0; i < dm->numEdgeData; i++, medge++) { + if (medge->flag & ME_LOOSEEDGE) { + draw = 1; } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int prevstart = 0; - int prevdraw = 1; - int draw = 1; - - GPU_edge_setup(dm); - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->numEdgeData; i++, medge++) { - if (medge->flag & ME_LOOSEEDGE) { - draw = 1; - } - else { - draw = 0; - } - if (prevdraw != draw) { - if (prevdraw > 0 && (i - prevstart) > 0) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); - } - prevstart = i; - } - prevdraw = draw; - } + else { + draw = 0; + } + if (prevdraw != draw) { if (prevdraw > 0 && (i - prevstart) > 0) { GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + prevstart = i; } - GPU_buffer_unbind(); + prevdraw = draw; + } + if (prevdraw > 0 && (i - prevstart) > 0) { + GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2); } + GPU_buffer_unbind(); } static void cdDM_drawFacesSolid(DerivedMesh *dm, @@ -549,11 +470,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, bool UNUSED(fast), DMSetMaterial setMaterial) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mvert = cddm->mvert; - MFace *mface = cddm->mface; - const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); - const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); - int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1; + int a; if (cddm->pbvh && cddm->pbvh_draw) { if (dm->numTessFaceData) { @@ -566,101 +483,17 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, return; } - - if (GPU_buffer_legacy(dm)) { - DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n"); - glBegin(glmode = GL_QUADS); - for (a = 0; a < dm->numTessFaceData; a++, mface++) { - int new_glmode, new_matnr, new_shademodel; - - new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES; - new_matnr = mface->mat_nr + 1; - new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; - - - if ((new_glmode != glmode) || (new_shademodel != shademodel) || - (setMaterial && (new_matnr != matnr))) - { - glEnd(); - - if (setMaterial) { - drawCurrentMat = setMaterial(matnr = new_matnr, NULL); - } - - glShadeModel(shademodel = new_shademodel); - glBegin(glmode = new_glmode); - } - - if (drawCurrentMat) { - if (lnors) { - glNormal3sv((const GLshort *)lnors[0][0]); - glVertex3fv(mvert[mface->v1].co); - glNormal3sv((const GLshort *)lnors[0][1]); - glVertex3fv(mvert[mface->v2].co); - glNormal3sv((const GLshort *)lnors[0][2]); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glNormal3sv((const GLshort *)lnors[0][3]); - glVertex3fv(mvert[mface->v4].co); - } - } - else if (shademodel == GL_FLAT) { - if (nors) { - glNormal3fv(nors); - } - else { - /* TODO make this better (cache facenormals as layer?) */ - float nor[3]; - if (mface->v4) { - normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); - } - else { - normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); - } - glNormal3fv(nor); - } - glVertex3fv(mvert[mface->v1].co); - glVertex3fv(mvert[mface->v2].co); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glVertex3fv(mvert[mface->v4].co); - } - } - else { /* shademodel == GL_SMOOTH */ - glNormal3sv(mvert[mface->v1].no); - glVertex3fv(mvert[mface->v1].co); - glNormal3sv(mvert[mface->v2].no); - glVertex3fv(mvert[mface->v2].co); - glNormal3sv(mvert[mface->v3].no); - glVertex3fv(mvert[mface->v3].co); - if (mface->v4) { - glNormal3sv(mvert[mface->v4].no); - glVertex3fv(mvert[mface->v4].co); - } - } - } - - if (nors) - nors += 3; - if (lnors) - lnors++; - } - glEnd(); - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - if (!GPU_buffer_legacy(dm)) { - glShadeModel(GL_SMOOTH); - for (a = 0; a < dm->drawObject->totmaterial; a++) { - if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { - glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, - dm->drawObject->materials[a].totpoint); - } - } + + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + glShadeModel(GL_SMOOTH); + for (a = 0; a < dm->drawObject->totmaterial; a++) { + if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { + glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, + dm->drawObject->materials[a].totpoint); } - GPU_buffer_unbind(); } + GPU_buffer_unbind(); glShadeModel(GL_FLAT); } @@ -672,15 +505,15 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, void *userData, DMDrawFlag uvflag) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mv = cddm->mvert; const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); - const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); MCol *mcol; int i, orig; int colType, startFace = 0; bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; + int tottri; + int next_actualFace; + /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); @@ -717,208 +550,81 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } cdDM_update_normals_from_pbvh(dm); - - if (GPU_buffer_legacy(dm)) { - int mat_nr_cache = -1; - MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE); - MTFace *tf_stencil_base = NULL; - MTFace *tf_stencil = NULL; - - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { - int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE); - tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil); + + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + if (uvflag & DM_DRAW_USE_TEXPAINT_UV) + GPU_texpaint_uv_setup(dm); + else + GPU_uv_setup(dm); + if (mcol) { + GPU_color_setup(dm, colType); + } + + tottri = dm->drawObject->tot_triangle_point / 3; + next_actualFace = dm->drawObject->triangle_to_mface[0]; + + glShadeModel(GL_SMOOTH); + /* lastFlag = 0; */ /* UNUSED */ + for (i = 0; i < tottri; i++) { + int actualFace = next_actualFace; + DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + int flush = 0; + + if (i != tottri - 1) + next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; + + if (drawParams) { + draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); } - - DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n"); - for (i = 0; i < dm->numTessFaceData; i++, mf++) { - MVert *mvert; - DMDrawOption draw_option; - unsigned char *cp = NULL; - - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) { - if (mf->mat_nr != mat_nr_cache) { - tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr); - - mat_nr_cache = mf->mat_nr; - } - } - - tf = tf_base ? tf_base + i : NULL; - tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL; - - if (drawParams) { - draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr); - } - else { - if (index_mf_to_mpoly) { - orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); - if (orig == ORIGINDEX_NONE) { - /* XXX, this is not really correct - * it will draw the previous faces context for this one when we don't know its settings. - * but better then skipping it altogether. - campbell */ - draw_option = DM_DRAW_OPTION_NORMAL; - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, orig, i); - } - else { - if (nors) { - nors += 3; - } - continue; - } + else { + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); + if (orig == ORIGINDEX_NONE) { + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; } else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, i, i); - } - else { - if (nors) { - nors += 3; - } - continue; + draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr); } } - - if (draw_option != DM_DRAW_OPTION_SKIP) { - if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol) - cp = (unsigned char *) &mcol[i * 4]; - - if (!(lnors || (mf->flag & ME_SMOOTH))) { - if (nors) { - glNormal3fv(nors); - } - else { - float nor[3]; - if (mf->v4) { - normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); - } - else { - normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); - } - glNormal3fv(nor); - } - } - - glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - if (tf) glTexCoord2fv(tf->uv[0]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[0]); - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - mvert = &mv[mf->v1]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][0]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (tf) glTexCoord2fv(tf->uv[1]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[1]); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - mvert = &mv[mf->v2]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][1]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (tf) glTexCoord2fv(tf->uv[2]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[2]); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - mvert = &mv[mf->v3]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][2]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - - if (mf->v4) { - if (tf) glTexCoord2fv(tf->uv[3]); - if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[3]); - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - mvert = &mv[mf->v4]; - if (lnors) glNormal3sv((const GLshort *)lnors[0][3]); - else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no); - glVertex3fv(mvert->co); - } - glEnd(); + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr); } - - if (nors) - nors += 3; - if (lnors) - lnors++; - } - } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - if (uvflag & DM_DRAW_USE_TEXPAINT_UV) - GPU_texpaint_uv_setup(dm); - else - GPU_uv_setup(dm); - if (mcol) { - GPU_color_setup(dm, colType); } - - if (!GPU_buffer_legacy(dm)) { - int tottri = dm->drawObject->tot_triangle_point / 3; - int next_actualFace = dm->drawObject->triangle_to_mface[0]; - - glShadeModel(GL_SMOOTH); - /* lastFlag = 0; */ /* UNUSED */ - for (i = 0; i < tottri; i++) { - int actualFace = next_actualFace; - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int flush = 0; - - if (i != tottri - 1) - next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - - if (drawParams) { - draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); - } - else { - if (index_mf_to_mpoly) { - orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); - if (orig == ORIGINDEX_NONE) { - /* XXX, this is not really correct - * it will draw the previous faces context for this one when we don't know its settings. - * but better then skipping it altogether. - campbell */ - draw_option = DM_DRAW_OPTION_NORMAL; - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr); - } - } - else if (drawParamsMapped) { - draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr); - } - } - - /* flush buffer if current triangle isn't drawable or it's last triangle */ - flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); - - if (!flush && compareDrawOptions) { - /* also compare draw options and flush buffer if they're different + + /* flush buffer if current triangle isn't drawable or it's last triangle */ + flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); + + if (!flush && compareDrawOptions) { + /* also compare draw options and flush buffer if they're different * need for face selection highlight in edit mode */ - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - if (flush) { - int first = startFace * 3; - /* Add one to the length if we're drawing at the end of the array */ - int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; - - if (count) { - if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) - GPU_color_switch(1); - else - GPU_color_switch(0); - - glDrawArrays(GL_TRIANGLES, first, count); - } - - startFace = i + 1; - } + flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; + } + + if (flush) { + int first = startFace * 3; + /* Add one to the length if we're drawing at the end of the array */ + int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; + + if (count) { + if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) + GPU_color_switch(1); + else + GPU_color_switch(0); + + glDrawArrays(GL_TRIANGLES, first, count); } + + startFace = i + 1; } - - GPU_buffer_unbind(); - glShadeModel(GL_FLAT); } + + GPU_buffer_unbind(); + glShadeModel(GL_FLAT); + } static void cdDM_drawFacesTex(DerivedMesh *dm, @@ -968,7 +674,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, /* back-buffer always uses legacy since VBO's would need the * color array temporarily overwritten for drawing, then reset. */ - if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) { + if (G.f & G_BACKBUFSEL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); for (i = 0; i < dm->numTessFaceData; i++, mf++) { int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH); @@ -1070,85 +776,85 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ int prevstart = 0; + int tottri; + GPU_vertex_setup(dm); GPU_normal_setup(dm); if (useColors && mcol) { GPU_color_setup(dm, colType); } - if (!GPU_buffer_legacy(dm)) { - int tottri = dm->drawObject->tot_triangle_point / 3; - glShadeModel(GL_SMOOTH); + tottri = dm->drawObject->tot_triangle_point / 3; + glShadeModel(GL_SMOOTH); + + if (tottri == 0) { + /* avoid buffer problems in following code */ + } + if (setDrawOptions == NULL) { + /* just draw the entire face array */ + glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); + } + else { + /* we need to check if the next material changes */ + int next_actualFace = dm->drawObject->triangle_to_mface[0]; + int prev_mat_nr = -1; - if (tottri == 0) { - /* avoid buffer problems in following code */ - } - if (setDrawOptions == NULL) { - /* just draw the entire face array */ - glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); - } - else { - /* we need to check if the next material changes */ - int next_actualFace = dm->drawObject->triangle_to_mface[0]; - int prev_mat_nr = -1; + for (i = 0; i < tottri; i++) { + //int actualFace = dm->drawObject->triangle_to_mface[i]; + int actualFace = next_actualFace; + MFace *mface = mf + actualFace; + /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ + DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + int flush = 0; - for (i = 0; i < tottri; i++) { - //int actualFace = dm->drawObject->triangle_to_mface[i]; - int actualFace = next_actualFace; - MFace *mface = mf + actualFace; - /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int flush = 0; - - if (i != tottri - 1) - next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - - orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; - - if (mface->mat_nr != prev_mat_nr) { - if (setMaterial) - draw_option = setMaterial(mface->mat_nr + 1, NULL); - - prev_mat_nr = mface->mat_nr; - } + if (i != tottri - 1) + next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; + + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; + + if (mface->mat_nr != prev_mat_nr) { + if (setMaterial) + draw_option = setMaterial(mface->mat_nr + 1, NULL); - if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) - draw_option = setDrawOptions(userData, orig); - - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); - } - - /* Goal is to draw as long of a contiguous triangle + prev_mat_nr = mface->mat_nr; + } + + if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) + draw_option = setDrawOptions(userData, orig); + + if (draw_option == DM_DRAW_OPTION_STIPPLE) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } + + /* Goal is to draw as long of a contiguous triangle * array as possible, so draw when we hit either an * invisible triangle or at the end of the array */ - - /* flush buffer if current triangle isn't drawable or it's last triangle... */ - flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); - - /* ... or when material setting is dissferent */ - flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr; - - if (!flush && compareDrawOptions) { - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - if (flush) { - int first = prevstart * 3; - /* Add one to the length if we're drawing at the end of the array */ - int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; - - if (count) - glDrawArrays(GL_TRIANGLES, first, count); - - prevstart = i + 1; - - if (draw_option == DM_DRAW_OPTION_STIPPLE) - glDisable(GL_POLYGON_STIPPLE); - } + + /* flush buffer if current triangle isn't drawable or it's last triangle... */ + flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); + + /* ... or when material setting is dissferent */ + flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr; + + if (!flush && compareDrawOptions) { + flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; + } + + if (flush) { + int first = prevstart * 3; + /* Add one to the length if we're drawing at the end of the array */ + int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; + + if (count) + glDrawArrays(GL_TRIANGLES, first, count); + + prevstart = i + 1; + + if (draw_option == DM_DRAW_OPTION_STIPPLE) + glDisable(GL_POLYGON_STIPPLE); } } - + glShadeModel(GL_FLAT); } GPU_buffer_unbind(); @@ -1276,7 +982,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, glShadeModel(GL_SMOOTH); - if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) { + if (setDrawOptions != NULL) { DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n"); memset(&attribs, 0, sizeof(attribs)); @@ -1335,11 +1041,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, ln3 = &lnors[a][2]; ln4 = &lnors[a][3]; } - + cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal); cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal); cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); - + if (mface->v4) cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal); else @@ -1353,214 +1059,213 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int numdata = 0, elementsize = 0, offset; int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; int i; - + const MFace *mf = mface; GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ memset(&attribs, 0, sizeof(attribs)); - + GPU_vertex_setup(dm); GPU_normal_setup(dm); - - if (!GPU_buffer_legacy(dm)) { - for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { - - a = dm->drawObject->triangle_to_mface[i]; - - mface = mf + a; - new_matnr = mface->mat_nr + 1; - - if (new_matnr != matnr) { - numfaces = curface - start; - if (numfaces > 0) { - - if (do_draw) { - - if (numdata != 0) { - - GPU_buffer_unlock(buffer); - - GPU_interleaved_attrib_setup(buffer, datatypes, numdata); - } - - glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3); - - if (numdata != 0) { - - GPU_buffer_free(buffer); - - buffer = NULL; - } - + + for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { + + a = dm->drawObject->triangle_to_mface[i]; + + mface = mf + a; + new_matnr = mface->mat_nr + 1; + + if (new_matnr != matnr) { + numfaces = curface - start; + if (numfaces > 0) { + + if (do_draw) { + + if (numdata != 0) { + + GPU_buffer_unlock(buffer); + + GPU_interleaved_attrib_setup(buffer, datatypes, numdata); + } + + glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3); + + if (numdata != 0) { + + GPU_buffer_free(buffer); + + buffer = NULL; } + } - numdata = 0; - start = curface; - /* prevdraw = do_draw; */ /* UNUSED */ - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) { - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - - if (attribs.totorco && attribs.orco.array) { - datatypes[numdata].index = attribs.orco.gl_index; - datatypes[numdata].size = 3; + } + numdata = 0; + start = curface; + /* prevdraw = do_draw; */ /* UNUSED */ + do_draw = setMaterial(matnr = new_matnr, &gattribs); + if (do_draw) { + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + + if (attribs.totorco && attribs.orco.array) { + datatypes[numdata].index = attribs.orco.gl_index; + datatypes[numdata].size = 3; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + for (b = 0; b < attribs.tottface; b++) { + if (attribs.tface[b].array) { + datatypes[numdata].index = attribs.tface[b].gl_index; + datatypes[numdata].size = 2; datatypes[numdata].type = GL_FLOAT; numdata++; } - for (b = 0; b < attribs.tottface; b++) { - if (attribs.tface[b].array) { - datatypes[numdata].index = attribs.tface[b].gl_index; - datatypes[numdata].size = 2; - datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - for (b = 0; b < attribs.totmcol; b++) { - if (attribs.mcol[b].array) { - datatypes[numdata].index = attribs.mcol[b].gl_index; - datatypes[numdata].size = 4; - datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; - } - } - if (attribs.tottang && attribs.tang.array) { - datatypes[numdata].index = attribs.tang.gl_index; + } + for (b = 0; b < attribs.totmcol; b++) { + if (attribs.mcol[b].array) { + datatypes[numdata].index = attribs.mcol[b].gl_index; datatypes[numdata].size = 4; - datatypes[numdata].type = GL_FLOAT; + datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; } - if (numdata != 0) { - elementsize = GPU_attrib_element_size(datatypes, numdata); - buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point); - if (buffer == NULL) { - GPU_buffer_unbind(); - dm->drawObject->legacy = 1; - return; - } - varray = GPU_buffer_lock_stream(buffer); - if (varray == NULL) { - GPU_buffer_unbind(); - GPU_buffer_free(buffer); - dm->drawObject->legacy = 1; - return; - } + } + if (attribs.tottang && attribs.tang.array) { + datatypes[numdata].index = attribs.tang.gl_index; + datatypes[numdata].size = 4; + datatypes[numdata].type = GL_FLOAT; + numdata++; + } + if (numdata != 0) { + elementsize = GPU_attrib_element_size(datatypes, numdata); + buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, true); + if (buffer == NULL) { + GPU_buffer_unbind(); + buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, true); + return; } - else { - /* if the buffer was set, don't use it again. - * prevdraw was assumed true but didnt run so set to false - [#21036] */ - /* prevdraw = 0; */ /* UNUSED */ - buffer = NULL; + varray = GPU_buffer_lock_stream(buffer); + if (varray == NULL) { + GPU_buffer_unbind(); + GPU_buffer_free(buffer); + fprintf(stderr, "Out of memory, can't draw object\n"); + return; } } + else { + /* if the buffer was set, don't use it again. + * prevdraw was assumed true but didnt run so set to false - [#21036] */ + /* prevdraw = 0; */ /* UNUSED */ + buffer = NULL; + } } - + } + + if (do_draw && numdata != 0) { + offset = 0; + if (attribs.totorco && attribs.orco.array) { + copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); + offset += sizeof(float) * 3; + } + for (b = 0; b < attribs.tottface; b++) { + if (attribs.tface[b].array) { + MTFace *tf = &attribs.tface[b].array[a]; + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); + + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); + offset += sizeof(float) * 2; + } + } + for (b = 0; b < attribs.totmcol; b++) { + if (attribs.mcol[b].array) { + MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; + GLubyte col[4]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 1]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); + cp = &attribs.mcol[b].array[a * 4 + 2]; + col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; + copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); + offset += sizeof(unsigned char) * 4; + } + } + if (attribs.tottang && attribs.tang.array) { + const float *tang = attribs.tang.array[a * 4 + 0]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); + tang = attribs.tang.array[a * 4 + 1]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); + tang = attribs.tang.array[a * 4 + 2]; + copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); + offset += sizeof(float) * 4; + } + (void)offset; + } + curface++; + if (mface->v4) { if (do_draw && numdata != 0) { offset = 0; if (attribs.totorco && attribs.orco.array) { - copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); + copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); offset += sizeof(float) * 3; } for (b = 0; b < attribs.tottface; b++) { if (attribs.tface[b].array) { MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); - - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); + copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); offset += sizeof(float) * 2; } } for (b = 0; b < attribs.totmcol; b++) { if (attribs.mcol[b].array) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; + MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; GLubyte col[4]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 1]; + cp = &attribs.mcol[b].array[a * 4 + 3]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 2]; + cp = &attribs.mcol[b].array[a * 4 + 0]; col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); offset += sizeof(unsigned char) * 4; } } if (attribs.tottang && attribs.tang.array) { - const float *tang = attribs.tang.array[a * 4 + 0]; + const float *tang = attribs.tang.array[a * 4 + 2]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); - tang = attribs.tang.array[a * 4 + 1]; + tang = attribs.tang.array[a * 4 + 3]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); - tang = attribs.tang.array[a * 4 + 2]; + tang = attribs.tang.array[a * 4 + 0]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); offset += sizeof(float) * 4; } (void)offset; } curface++; - if (mface->v4) { - if (do_draw && numdata != 0) { - offset = 0; - if (attribs.totorco && attribs.orco.array) { - copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); - copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); - offset += sizeof(float) * 3; - } - for (b = 0; b < attribs.tottface; b++) { - if (attribs.tface[b].array) { - MTFace *tf = &attribs.tface[b].array[a]; - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); - copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); - offset += sizeof(float) * 2; - } - } - for (b = 0; b < attribs.totmcol; b++) { - if (attribs.mcol[b].array) { - MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; - GLubyte col[4]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 3]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); - cp = &attribs.mcol[b].array[a * 4 + 0]; - col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; - copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); - offset += sizeof(unsigned char) * 4; - } - } - if (attribs.tottang && attribs.tang.array) { - const float *tang = attribs.tang.array[a * 4 + 2]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); - tang = attribs.tang.array[a * 4 + 3]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); - tang = attribs.tang.array[a * 4 + 0]; - copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); - offset += sizeof(float) * 4; - } - (void)offset; - } - curface++; - i++; - } + i++; } - numfaces = curface - start; - if (numfaces > 0) { - if (do_draw) { - if (numdata != 0) { - GPU_buffer_unlock(buffer); - GPU_interleaved_attrib_setup(buffer, datatypes, numdata); - } - glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3); + } + numfaces = curface - start; + if (numfaces > 0) { + if (do_draw) { + if (numdata != 0) { + GPU_buffer_unlock(buffer); + GPU_interleaved_attrib_setup(buffer, datatypes, numdata); } + glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3); } - GPU_buffer_unbind(); } + GPU_buffer_unbind(); + GPU_buffer_free(buffer); } - + glShadeModel(GL_FLAT); } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 376d3d3099c..929231186f4 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -3024,7 +3024,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P * avoid this if we can! */ DAG_id_tag_update(ob->data, 0); } - else if (!GPU_buffer_legacy(ob->derivedFinal)) { + else { /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; } diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 408b41719da..911403f45cb 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -562,14 +562,6 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, const bool has_mc } } -static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), const bool has_mcol, int UNUSED(matnr)) -{ - if (has_mcol) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_NO_MCOL; -} - static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mcol), int matnr) { Material *ma = give_current_material(Gtexdraw.ob, matnr + 1); @@ -929,24 +921,16 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag); } } - else { - if (GPU_buffer_legacy(dm)) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) - dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag); - else - dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag); - } - else { - drawTFace_userData userData; - - update_tface_color_layer(dm); - - userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); - userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - userData.me = NULL; - - dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag); - } + else { + drawTFace_userData userData; + + update_tface_color_layer(dm); + + userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); + userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + userData.me = NULL; + + dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag); } /* draw game engine text hack */ diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index ba461d5f8a2..e9b600a9267 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -54,6 +54,7 @@ typedef struct GPUBuffer { int size; /* in bytes */ void *pointer; /* used with vertex arrays */ unsigned int id; /* used with vertex buffer objects */ + bool use_vbo; /* true for VBOs, false for vertex arrays */ } GPUBuffer; typedef struct GPUBufferMaterial { @@ -85,6 +86,7 @@ typedef struct GPUDrawObject { GPUBuffer *points; GPUBuffer *normals; GPUBuffer *uv; + GPUBuffer *uv_tex; GPUBuffer *colors; GPUBuffer *edges; GPUBuffer *uvedges; @@ -113,10 +115,6 @@ typedef struct GPUDrawObject { /* caches of the original DerivedMesh values */ int totvert; int totedge; - - /* if there was a failure allocating some buffer, use old - * rendering code */ - bool legacy; } GPUDrawObject; /* used for GLSL materials */ @@ -129,7 +127,7 @@ typedef struct GPUAttrib { void GPU_global_buffer_pool_free(void); void GPU_global_buffer_pool_free_unused(void); -GPUBuffer *GPU_buffer_alloc(int size); +GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays); void GPU_buffer_free(GPUBuffer *buffer); GPUDrawObject *GPU_drawobject_new(struct DerivedMesh *dm); @@ -161,9 +159,6 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, /* called after drawing */ void GPU_buffer_unbind(void); -/* used to check whether to use the old (without buffers) code */ -bool GPU_buffer_legacy(struct DerivedMesh *dm); - /* Buffers for non-DerivedMesh drawing */ typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index b5a576b509c..54743247fea 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -62,6 +62,8 @@ #include "bmesh.h" +#include "gpu_extensions_private.h" + typedef enum { GPU_BUFFER_VERTEX_STATE = (1 << 0), GPU_BUFFER_NORMAL_STATE = (1 << 1), @@ -76,7 +78,6 @@ typedef enum { #define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n)) /* -1 - undefined, 0 - vertex arrays, 1 - VBOs */ -static int useVBOs = -1; static GPUBufferState GLStates = 0; static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } }; @@ -111,10 +112,6 @@ static GPUBufferPool *gpu_buffer_pool_new(void) { GPUBufferPool *pool; - /* enable VBOs if supported */ - if (useVBOs == -1) - useVBOs = (GLEW_ARB_vertex_buffer_object ? 1 : 0); - pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool"); pool->maxsize = MAX_FREE_GPU_BUFFERS; @@ -158,7 +155,7 @@ static void gpu_buffer_pool_delete_last(GPUBufferPool *pool) return; /* delete the buffer's data */ - if (useVBOs) + if (last->use_vbo) glDeleteBuffersARB(1, &last->id); else MEM_freeN(last->pointer); @@ -226,7 +223,7 @@ void GPU_global_buffer_pool_free_unused(void) * * Thread-unsafe version for internal usage only. */ -static GPUBuffer *gpu_buffer_alloc_intern(int size) +static GPUBuffer *gpu_buffer_alloc_intern(int size, bool use_VBO) { GPUBufferPool *pool; GPUBuffer *buf; @@ -251,6 +248,10 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) for (i = 0; i < pool->totbuf; i++) { bufsize = pool->buffers[i]->size; + /* only return a buffer that matches the VBO preference */ + if (pool->buffers[i]->use_vbo != use_VBO) + continue; + /* check for an exact size match */ if (bufsize == size) { bestfit = i; @@ -279,8 +280,9 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) /* no acceptable buffer found in the pool, create a new one */ buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer"); buf->size = size; + buf->use_vbo = use_VBO; - if (useVBOs == 1) { + if (use_VBO) { /* create a new VBO and initialize it to the requested * size */ glGenBuffersARB(1, &buf->id); @@ -307,9 +309,10 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size) } /* Same as above, but safe for threading. */ -GPUBuffer *GPU_buffer_alloc(int size) +GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays) { GPUBuffer *buffer; + bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO) && !force_vertex_arrays; if (size == 0) { /* Early out, no lock needed in this case. */ @@ -317,7 +320,7 @@ GPUBuffer *GPU_buffer_alloc(int size) } BLI_mutex_lock(&buffer_mutex); - buffer = gpu_buffer_alloc_intern(size); + buffer = gpu_buffer_alloc_intern(size, use_VBOs); BLI_mutex_unlock(&buffer_mutex); return buffer; @@ -577,6 +580,7 @@ void GPU_drawobject_free(DerivedMesh *dm) GPU_buffer_free(gdo->points); GPU_buffer_free(gdo->normals); GPU_buffer_free(gdo->uv); + GPU_buffer_free(gdo->uv_tex); GPU_buffer_free(gdo->colors); GPU_buffer_free(gdo->edges); GPU_buffer_free(gdo->uvedges); @@ -585,6 +589,22 @@ void GPU_drawobject_free(DerivedMesh *dm) dm->drawObject = NULL; } +static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, int size, bool use_VBOs) +{ + gpu_buffer_free_intern(buffer); + gpu_buffer_pool_delete_last(pool); + buffer = NULL; + + /* try freeing an entry from the pool + * and reallocating the buffer */ + if (pool->totbuf > 0) { + gpu_buffer_pool_delete_last(pool); + buffer = gpu_buffer_alloc_intern(size, use_VBOs); + } + + return buffer; +} + typedef void (*GPUBufferCopyFunc)(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *user_data); @@ -598,7 +618,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, int *mat_orig_to_new; int *cur_index_per_mat; int i; - bool success; + bool use_VBOs = (GLEW_ARB_vertex_buffer_object == 1) && !(U.gameflags & USER_DISABLE_VBO); GLboolean uploaded; pool = gpu_get_global_buffer_pool(); @@ -606,11 +626,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, BLI_mutex_lock(&buffer_mutex); /* alloc a GPUBuffer; fall back to legacy mode on failure */ - if (!(buffer = gpu_buffer_alloc_intern(size))) - dm->drawObject->legacy = 1; - - /* nothing to do for legacy mode */ - if (dm->drawObject->legacy) { + if (!(buffer = gpu_buffer_alloc_intern(size, use_VBOs))) { BLI_mutex_unlock(&buffer_mutex); return NULL; } @@ -628,8 +644,8 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, mat_orig_to_new[object->materials[i].mat_nr] = i; } - if (useVBOs) { - success = 0; + if (use_VBOs) { + bool success = false; while (!success) { /* bind the buffer and discard previous data, @@ -639,32 +655,22 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, /* attempt to map the buffer */ if (!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) { - /* failed to map the buffer; delete it */ - gpu_buffer_free_intern(buffer); - gpu_buffer_pool_delete_last(pool); - buffer = NULL; - - /* try freeing an entry from the pool - * and reallocating the buffer */ - if (pool->totbuf > 0) { - gpu_buffer_pool_delete_last(pool); - buffer = gpu_buffer_alloc_intern(size); - } - + buffer = gpu_try_realloc(pool, buffer, size, true); + /* allocation still failed; fall back * to legacy mode */ if (!buffer) { - dm->drawObject->legacy = 1; - success = 1; + use_VBOs = false; + success = true; } } else { - success = 1; + success = true; } } /* check legacy fallback didn't happen */ - if (dm->drawObject->legacy == 0) { + if (use_VBOs) { uploaded = GL_FALSE; /* attempt to upload the data to the VBO */ while (uploaded == GL_FALSE) { @@ -677,15 +683,16 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, } glBindBufferARB(target, 0); } - else { + if (!use_VBOs) { /* VBO not supported, use vertex array fallback */ - if (buffer->pointer) { + if (!buffer || !buffer->pointer) { + buffer = gpu_try_realloc(pool, buffer, size, false); + } + + if (buffer) { varray = buffer->pointer; (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user); } - else { - dm->drawObject->legacy = 1; - } } MEM_freeN(cur_index_per_mat); @@ -1019,7 +1026,7 @@ static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBuffer case GPU_BUFFER_UV: return &gdo->uv; case GPU_BUFFER_UV_TEXPAINT: - return &gdo->uv; + return &gdo->uv_tex; case GPU_BUFFER_EDGE: return &gdo->edges; case GPU_BUFFER_UVEDGE: @@ -1105,7 +1112,7 @@ void GPU_vertex_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->points->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id); glVertexPointer(3, GL_FLOAT, 0, 0); } @@ -1122,7 +1129,7 @@ void GPU_normal_setup(DerivedMesh *dm) return; glEnableClientState(GL_NORMAL_ARRAY); - if (useVBOs) { + if (dm->drawObject->normals->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id); glNormalPointer(GL_FLOAT, 0, 0); } @@ -1139,7 +1146,7 @@ void GPU_uv_setup(DerivedMesh *dm) return; glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if (useVBOs) { + if (dm->drawObject->uv->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id); glTexCoordPointer(2, GL_FLOAT, 0, 0); } @@ -1156,8 +1163,8 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm) return; glEnableClientState(GL_TEXTURE_COORD_ARRAY); - if (useVBOs) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id); + if (dm->drawObject->uv_tex->use_vbo) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv_tex->id); glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0); glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1165,10 +1172,10 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm) glClientActiveTexture(GL_TEXTURE0); } else { - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer); + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv_tex->pointer); glClientActiveTexture(GL_TEXTURE2); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float)); + glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv_tex->pointer + 2 * sizeof(float)); glClientActiveTexture(GL_TEXTURE0); } @@ -1202,7 +1209,7 @@ void GPU_color_setup(DerivedMesh *dm, int colType) return; glEnableClientState(GL_COLOR_ARRAY); - if (useVBOs) { + if (dm->drawObject->colors->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->colors->id); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); } @@ -1222,7 +1229,7 @@ void GPU_edge_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->edges->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id); glVertexPointer(3, GL_FLOAT, 0, 0); } @@ -1232,7 +1239,7 @@ void GPU_edge_setup(DerivedMesh *dm) GLStates |= GPU_BUFFER_VERTEX_STATE; - if (useVBOs) + if (dm->drawObject->edges->use_vbo) glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, dm->drawObject->edges->id); GLStates |= GPU_BUFFER_ELEMENT_STATE; @@ -1244,7 +1251,7 @@ void GPU_uvedge_setup(DerivedMesh *dm) return; glEnableClientState(GL_VERTEX_ARRAY); - if (useVBOs) { + if (dm->drawObject->uvedges->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uvedges->id); glVertexPointer(2, GL_FLOAT, 0, 0); } @@ -1300,7 +1307,7 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda } elementsize = GPU_attrib_element_size(data, numdata); - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); for (i = 0; i < numdata; i++) { glEnableVertexAttribArrayARB(data[i].index); @@ -1343,7 +1350,8 @@ void GPU_buffer_unbind(void) if (GLStates & GPU_BUFFER_COLOR_STATE) glDisableClientState(GL_COLOR_ARRAY); if (GLStates & GPU_BUFFER_ELEMENT_STATE) { - if (useVBOs) { + /* not guaranteed we used VBOs but in that case it's just a no-op */ + if (GLEW_ARB_vertex_buffer_object) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } } @@ -1359,7 +1367,8 @@ void GPU_buffer_unbind(void) break; } - if (useVBOs) + /* not guaranteed we used VBOs but in that case it's just a no-op */ + if (GLEW_ARB_vertex_buffer_object) glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } @@ -1377,19 +1386,6 @@ void GPU_color_switch(int mode) } } -/* return 1 if drawing should be done using old immediate-mode - * code, 0 otherwise */ -bool GPU_buffer_legacy(DerivedMesh *dm) -{ - int test = (U.gameflags & USER_DISABLE_VBO); - if (test) - return 1; - - if (dm->drawObject == NULL) - dm->drawObject = GPU_drawobject_new(dm); - return dm->drawObject->legacy; -} - void *GPU_buffer_lock(GPUBuffer *buffer) { float *varray; @@ -1397,7 +1393,7 @@ void *GPU_buffer_lock(GPUBuffer *buffer) if (!buffer) return 0; - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); return varray; @@ -1414,7 +1410,7 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer) if (!buffer) return 0; - if (useVBOs) { + if (buffer->use_vbo) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); /* discard previous data, avoid stalling gpu */ glBufferDataARB(GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB); @@ -1428,7 +1424,7 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer) void GPU_buffer_unlock(GPUBuffer *buffer) { - if (useVBOs) { + if (buffer->use_vbo) { if (buffer) { /* note: this operation can fail, could return * an error code from this function? */ @@ -1442,7 +1438,7 @@ void GPU_buffer_unlock(GPUBuffer *buffer) void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count) { glDrawElements(mode, count, GL_UNSIGNED_INT, - (useVBOs ? + (elements->use_vbo ? (void *)(start * sizeof(unsigned int)) : ((int *)elements->pointer) + start)); } |