Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-07-15 19:50:02 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-07-15 19:50:02 +0300
commit13c39e90b3c0ec6a470fbc3696cd73c2a65b49cf (patch)
treec4e7113f2dd911e5438eb68d4e9f49efa7e1fe1e /source/blender
parent2daa4db8a0cb23dfd0ca417ead2413e20ec18fe7 (diff)
VBO offscreen selection drawing, cdderivedmesh
Get rid of legacy drawing, it's only used for selection, in which case we can prepare a temporary color buffer and draw at once. Code is not complete here because we still redundantly set the draw color in the draw function and don't ommit hidden faces automatically. Still it works 100% without immediate mode now.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h1
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c296
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/gpu/GPU_buffers.h1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c15
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c7
7 files changed, 144 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))