diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 296 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 15 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_subwindow.c | 7 | ||||
-rw-r--r-- | source/blenderplayer/bad_level_call_stubs/stubs.c | 2 |
8 files changed, 146 insertions, 179 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index c8bd7e99310..62c68380289 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -149,6 +149,7 @@ typedef enum DMDrawFlag { DM_DRAW_ALWAYS_SMOOTH = (1 << 1), DM_DRAW_USE_ACTIVE_UV = (1 << 2), DM_DRAW_USE_TEXPAINT_UV = (1 << 3), + DM_DRAW_SKIP_HIDDEN = (1 << 4), } DMDrawFlag; typedef enum DMForeachFlag { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b773bfe1e8f..5b25a32124d 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -60,6 +60,8 @@ #include "GPU_extensions.h" #include "GPU_glew.h" +#include "WM_api.h" + #include <string.h> #include <limits.h> #include <math.h> @@ -635,14 +637,15 @@ static void cdDM_drawMappedFaces( void *userData, DMDrawFlag flag) { CDDerivedMesh *cddm = (CDDerivedMesh *) dm; - MVert *mv = cddm->mvert; MFace *mf = cddm->mface; MCol *mcol; - const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); - const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); - int colType, useColors = flag & DM_DRAW_USE_COLORS; + int colType, useColors = flag & DM_DRAW_USE_COLORS, useHide = flag & DM_DRAW_SKIP_HIDDEN; int i, orig; - + int start_element = 0, tot_element, tot_drawn; + int totpoly; + int tottri; + int mat_index; + GPUBuffer *findex_buffer = NULL; /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); @@ -651,216 +654,153 @@ static void cdDM_drawMappedFaces( index_mp_to_orig = NULL; } - colType = CD_TEXTURE_MCOL; - mcol = DM_get_tessface_data_layer(dm, colType); - if (!mcol) { - colType = CD_PREVIEW_MCOL; - mcol = DM_get_tessface_data_layer(dm, colType); - } - if (!mcol) { - colType = CD_MCOL; - mcol = DM_get_tessface_data_layer(dm, colType); - } - cdDM_update_normals_from_pbvh(dm); - /* back-buffer always uses legacy since VBO's would need the - * color array temporarily overwritten for drawing, then reset. */ + /* fist, setup common buffers */ + GPU_vertex_setup(dm); + GPU_triangle_setup(dm); + + /* if we do selection, fill the selection buffer color */ 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); - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + Mesh *me = userData; + unsigned int *fi_map; - orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; - - if (orig == ORIGINDEX_NONE) - draw_option = setMaterial(mf->mat_nr + 1, NULL); - else if (setDrawOptions != NULL) - draw_option = setDrawOptions(userData, orig); + findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int), false); + fi_map = GPU_buffer_lock(findex_buffer); - if (draw_option != DM_DRAW_OPTION_SKIP) { - unsigned char *cp = NULL; + if (fi_map) { + for (i = 0; i < dm->numTessFaceData; i++, mf++) { + int selcol = 0xFFFFFFFF; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); + if ((orig != ORIGINDEX_NONE) && (!useHide || !(me->mpoly[orig].flag & ME_HIDE))) { + WM_framebuffer_index_get(orig + 1, &selcol); } - if (useColors && mcol) - cp = (unsigned char *)&mcol[i * 4]; - - /* no need to set shading mode to flat because - * normals are already used to change shading */ - glShadeModel(GL_SMOOTH); - glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); - - if (lnors) { - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3sv((const GLshort *)lnors[0][0]); - glVertex3fv(mv[mf->v1].co); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3sv((const GLshort *)lnors[0][1]); - glVertex3fv(mv[mf->v2].co); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3sv((const GLshort *)lnors[0][2]); - glVertex3fv(mv[mf->v3].co); - if (mf->v4) { - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3sv((const GLshort *)lnors[0][3]); - glVertex3fv(mv[mf->v4].co); - } - } - else if (!drawSmooth) { - 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); - } + fi_map[start_element++] = selcol; + fi_map[start_element++] = selcol; + fi_map[start_element++] = selcol; - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - glVertex3fv(mv[mf->v1].co); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glVertex3fv(mv[mf->v2].co); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glVertex3fv(mv[mf->v3].co); - if (mf->v4) { - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glVertex3fv(mv[mf->v4].co); - } - } - else { - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - glNormal3sv(mv[mf->v1].no); - glVertex3fv(mv[mf->v1].co); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glNormal3sv(mv[mf->v2].no); - glVertex3fv(mv[mf->v2].co); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glNormal3sv(mv[mf->v3].no); - glVertex3fv(mv[mf->v3].co); - if (mf->v4) { - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glNormal3sv(mv[mf->v4].no); - glVertex3fv(mv[mf->v4].co); - } + if (mf->v4) { + fi_map[start_element++] = selcol; } + } - glEnd(); + start_element = 0; + mf = cddm->mface; - if (draw_option == DM_DRAW_OPTION_STIPPLE) - glDisable(GL_POLYGON_STIPPLE); - } - - if (nors) - nors += 3; - if (lnors) - lnors++; + GPU_buffer_unlock(findex_buffer); + GPU_buffer_bind_as_color(findex_buffer); } } - else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int start_element = 0, tot_element, tot_drawn; - int totpoly; - int tottri; - int mat_index; - - GPU_vertex_setup(dm); + else { GPU_normal_setup(dm); - GPU_triangle_setup(dm); - if (useColors && mcol) { - GPU_color_setup(dm, colType); + + if (useColors) { + colType = CD_TEXTURE_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + if (!mcol) { + colType = CD_PREVIEW_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } + if (!mcol) { + colType = CD_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } + + if (useColors && mcol) { + GPU_color_setup(dm, colType); + } } - glShadeModel(GL_SMOOTH); + } - tottri = dm->drawObject->tot_triangle_point; - if (tottri == 0) { - /* avoid buffer problems in following code */ - } - else if (setDrawOptions == NULL) { - /* just draw the entire face array */ - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri); - } - else { - for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { - GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - int next_actualFace = bufmat->polys[0]; - totpoly = bufmat->totpolys; - - tot_element = 0; - tot_drawn = 0; - start_element = 0; - - if (setMaterial) - draw_option = setMaterial(bufmat->mat_nr + 1, NULL); - - if (draw_option != DM_DRAW_OPTION_SKIP) { - for (i = 0; i < totpoly; i++) { - //int actualFace = dm->drawObject->triangle_to_mface[i]; - int actualFace = next_actualFace; - int flush = 0; - draw_option = DM_DRAW_OPTION_NORMAL; + glShadeModel(GL_SMOOTH); - if (i != totpoly - 1) - next_actualFace = bufmat->polys[i + 1]; + tottri = dm->drawObject->tot_triangle_point; - orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; + if (tottri == 0) { + /* avoid buffer problems in following code */ + } + else if (setDrawOptions == NULL) { + /* just draw the entire face array */ + GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri); + } + else { + for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { + GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; + DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; + int next_actualFace = bufmat->polys[0]; + totpoly = bufmat->totpolys; - if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) - draw_option = setDrawOptions(userData, orig); + tot_element = 0; + start_element = 0; + tot_drawn = 0; - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - glEnable(GL_POLYGON_STIPPLE); - glPolygonStipple(stipple_quarttone); - } + if (setMaterial) + draw_option = setMaterial(bufmat->mat_nr + 1, NULL); - /* 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 */ + if (draw_option != DM_DRAW_OPTION_SKIP) { + for (i = 0; i < totpoly; i++) { + int actualFace = next_actualFace; + int flush = 0; + draw_option = DM_DRAW_OPTION_NORMAL; - /* 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 == totpoly - 1); + if (i != totpoly - 1) + next_actualFace = bufmat->polys[i + 1]; - if (!flush && compareDrawOptions) { - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; - tot_element += mf[actualFace].v4 ? 6 : 3; + if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) + draw_option = setDrawOptions(userData, orig); - if (flush) { - if (!ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) - tot_drawn += mf[actualFace].v4 ? 6 : 3; + if (draw_option == DM_DRAW_OPTION_STIPPLE) { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + } - if (tot_drawn) { - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); - tot_drawn = 0; - } + /* 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 */ - start_element = tot_element; + /* 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 == totpoly - 1); - if (draw_option == DM_DRAW_OPTION_STIPPLE) - glDisable(GL_POLYGON_STIPPLE); - } - else { + if (!flush && compareDrawOptions) { + flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; + } + + tot_element += mf[actualFace].v4 ? 6 : 3; + + if (flush) { + if (!ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) tot_drawn += mf[actualFace].v4 ? 6 : 3; + + if (tot_drawn) { + GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); + tot_drawn = 0; } - } - glShadeModel(GL_FLAT); + start_element = tot_element; + + if (draw_option == DM_DRAW_OPTION_STIPPLE) + glDisable(GL_POLYGON_STIPPLE); + } + else { + tot_drawn += mf[actualFace].v4 ? 6 : 3; + } } } } - GPU_buffer_unbind(); } + + glShadeModel(GL_FLAT); + + GPU_buffer_unbind(); + + if (G.f & G_BACKBUFSEL) + GPU_buffer_free(findex_buffer); + } static void cdDM_drawMappedFacesTex( diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 265b6874a8d..4203aa77dd0 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -8531,7 +8531,7 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob) DM_update_materials(dm, ob); if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) - dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, NULL, NULL, me, 0); + dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, NULL, NULL, me, DM_DRAW_SKIP_HIDDEN); else dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0); diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index dafc9ac84ed..8586728410c 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -172,6 +172,7 @@ void GPU_uv_setup(struct DerivedMesh *dm); void GPU_texpaint_uv_setup(struct DerivedMesh *dm); /* colType is the cddata MCol type to use! */ void GPU_color_setup(struct DerivedMesh *dm, int colType); +void GPU_buffer_bind_as_color(GPUBuffer *buffer); void GPU_edge_setup(struct DerivedMesh *dm); /* does not mix with other data */ void GPU_uvedge_setup(struct DerivedMesh *dm); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index ac6329910c9..9b588512794 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -764,6 +764,21 @@ void GPU_color_setup(DerivedMesh *dm, int colType) GLStates |= GPU_BUFFER_COLOR_STATE; } +void GPU_buffer_bind_as_color(GPUBuffer *buffer) +{ + glEnableClientState(GL_COLOR_ARRAY); + if (buffer->use_vbo) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); + } + else { + glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer->pointer); + } + + GLStates |= GPU_BUFFER_COLOR_STATE; +} + + void GPU_edge_setup(DerivedMesh *dm) { if (!gpu_buffer_setup_common(dm, GPU_BUFFER_EDGE)) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index fa9357f4eec..28e24e442ca 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -392,6 +392,7 @@ void wmOrtho2_pixelspace(const float x, const float y); /* utilities */ void WM_framebuffer_index_set(int index); +void WM_framebuffer_index_get(int index, int *r_col); int WM_framebuffer_to_index(unsigned int col); void WM_framebuffer_to_index_array(unsigned int *col, const unsigned int size); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 1583f9f9095..6b286bd19a5 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -459,6 +459,13 @@ void WM_framebuffer_index_set(int index) cpack(col); } +void WM_framebuffer_index_get(int index, int *r_col) +{ + *r_col = index_to_framebuffer(index); +} + + + #define INDEX_FROM_BUF_8(col) (((col & 0xC00000) >> 18) + ((col & 0xC000) >> 12) + ((col & 0xC0) >> 6)) #define INDEX_FROM_BUF_12(col) (((col & 0xF00000) >> 12) + ((col & 0xF000) >> 8) + ((col & 0xF0) >> 4)) #define INDEX_FROM_BUF_15_16(col) (((col & 0xF80000) >> 9) + ((col & 0xF800) >> 6) + ((col & 0xF8) >> 3)) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 9a9513e735c..0e664941c1a 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -316,6 +316,8 @@ bool WM_uilisttype_add(struct uiListType *ult) RET_ZERO void WM_uilisttype_freelink(struct uiListType *ult) RET_NONE void WM_uilisttype_free(void) RET_NONE +void WM_framebuffer_index_get(int index, int *r_col) RET_NONE + struct wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id) RET_NULL int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event) RET_ZERO void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference) RET_NONE |