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:
Diffstat (limited to 'source/blender/gpu/intern/gpu_buffers.c')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c156
1 files changed, 132 insertions, 24 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index e6bac9afdfb..6eda6d35ff3 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -55,7 +55,16 @@
#include "BLI_ghash.h"
#include "BLI_threads.h"
+
#include "bmesh.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_ccg.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_paint.h"
+#include "BKE_material.h"
+#include "BKE_pbvh.h"
#include "DNA_meshdata_types.h"
#include "DNA_userdef_types.h"
@@ -68,15 +77,18 @@
#include <string.h>
typedef enum {
- GPU_BUFFER_VERTEX_STATE = 1,
- GPU_BUFFER_NORMAL_STATE = 2,
- GPU_BUFFER_TEXCOORD_STATE = 4,
- GPU_BUFFER_COLOR_STATE = 8,
- GPU_BUFFER_ELEMENT_STATE = 16,
+ GPU_BUFFER_VERTEX_STATE = (1 << 0),
+ GPU_BUFFER_NORMAL_STATE = (1 << 1),
+ GPU_BUFFER_TEXCOORD_UNIT_0_STATE = (1 << 2),
+ GPU_BUFFER_TEXCOORD_UNIT_2_STATE = (1 << 3),
+ GPU_BUFFER_COLOR_STATE = (1 << 4),
+ GPU_BUFFER_ELEMENT_STATE = (1 << 5),
} GPUBufferState;
#define MAX_GPU_ATTRIB_DATA 32
+#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
+
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
static int useVBOs = -1;
static GPUBufferState GLStates = 0;
@@ -843,6 +855,61 @@ static void GPU_buffer_copy_uv(DerivedMesh *dm, float *varray, int *index, int *
}
}
+
+static void GPU_buffer_copy_uv_texpaint(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
+{
+ int start;
+ int i, totface;
+
+ int totmaterial = dm->totmat;
+ MTFace **mtface_base;
+ MTFace *stencil_base;
+ int stencil;
+ MFace *mf;
+
+ /* should have been checked for before, reassert */
+ BLI_assert(DM_get_tessface_data_layer(dm, CD_MTFACE));
+ mf = dm->getTessFaceArray(dm);
+ mtface_base = MEM_mallocN(totmaterial * sizeof(*mtface_base), "texslots");
+
+ for (i = 0; i < totmaterial; i++) {
+ mtface_base[i] = DM_paint_uvlayer_active_get(dm, i);
+ }
+
+ stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
+ stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
+
+ totface = dm->getNumTessFaces(dm);
+
+ for (i = 0; i < totface; i++, mf++) {
+ int mat_i = mf->mat_nr;
+ start = index[mat_orig_to_new[mat_i]];
+
+ /* v1 v2 v3 */
+ copy_v2_v2(&varray[start], mtface_base[mat_i][i].uv[0]);
+ copy_v2_v2(&varray[start + 2], stencil_base[i].uv[0]);
+ copy_v2_v2(&varray[start + 4], mtface_base[mat_i][i].uv[1]);
+ copy_v2_v2(&varray[start + 6], stencil_base[i].uv[1]);
+ copy_v2_v2(&varray[start + 8], mtface_base[mat_i][i].uv[2]);
+ copy_v2_v2(&varray[start + 10], stencil_base[i].uv[2]);
+ index[mat_orig_to_new[mat_i]] += 12;
+
+ if (mf->v4) {
+ /* v3 v4 v1 */
+ copy_v2_v2(&varray[start + 12], mtface_base[mat_i][i].uv[2]);
+ copy_v2_v2(&varray[start + 14], stencil_base[i].uv[2]);
+ copy_v2_v2(&varray[start + 16], mtface_base[mat_i][i].uv[3]);
+ copy_v2_v2(&varray[start + 18], stencil_base[i].uv[3]);
+ copy_v2_v2(&varray[start + 20], mtface_base[mat_i][i].uv[0]);
+ copy_v2_v2(&varray[start + 22], stencil_base[i].uv[0]);
+ index[mat_orig_to_new[mat_i]] += 12;
+ }
+ }
+
+ MEM_freeN(mtface_base);
+}
+
+
static void copy_mcol_uc3(unsigned char *v, unsigned char *col)
{
v[0] = col[3];
@@ -932,6 +999,7 @@ typedef enum {
GPU_BUFFER_NORMAL,
GPU_BUFFER_COLOR,
GPU_BUFFER_UV,
+ GPU_BUFFER_UV_TEXPAINT,
GPU_BUFFER_EDGE,
GPU_BUFFER_UVEDGE,
} GPUBufferType;
@@ -943,12 +1011,13 @@ typedef struct {
} GPUBufferTypeSettings;
const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
- {GPU_buffer_copy_vertex, GL_ARRAY_BUFFER, 3},
- {GPU_buffer_copy_normal, GL_ARRAY_BUFFER, 3},
- {GPU_buffer_copy_mcol, GL_ARRAY_BUFFER, 3},
- {GPU_buffer_copy_uv, GL_ARRAY_BUFFER, 2},
- {GPU_buffer_copy_edge, GL_ELEMENT_ARRAY_BUFFER, 2},
- {GPU_buffer_copy_uvedge, GL_ELEMENT_ARRAY_BUFFER, 4},
+ {GPU_buffer_copy_vertex, GL_ARRAY_BUFFER, 3},
+ {GPU_buffer_copy_normal, GL_ARRAY_BUFFER, 3},
+ {GPU_buffer_copy_mcol, GL_ARRAY_BUFFER, 3},
+ {GPU_buffer_copy_uv, GL_ARRAY_BUFFER, 2},
+ {GPU_buffer_copy_uv_texpaint, GL_ARRAY_BUFFER, 4},
+ {GPU_buffer_copy_edge, GL_ELEMENT_ARRAY_BUFFER, 2},
+ {GPU_buffer_copy_uvedge, GL_ELEMENT_ARRAY_BUFFER, 4},
};
/* get the GPUDrawObject buffer associated with a type */
@@ -963,6 +1032,8 @@ static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBuffer
return &gdo->colors;
case GPU_BUFFER_UV:
return &gdo->uv;
+ case GPU_BUFFER_UV_TEXPAINT:
+ return &gdo->uv;
case GPU_BUFFER_EDGE:
return &gdo->edges;
case GPU_BUFFER_UVEDGE:
@@ -984,6 +1055,8 @@ static int gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
return sizeof(char) * 3 * dm->drawObject->tot_triangle_point;
case GPU_BUFFER_UV:
return sizeof(float) * 2 * dm->drawObject->tot_triangle_point;
+ case GPU_BUFFER_UV_TEXPAINT:
+ return sizeof(float) * 4 * dm->drawObject->tot_triangle_point;
case GPU_BUFFER_EDGE:
return sizeof(int) * 2 * dm->drawObject->totedge;
case GPU_BUFFER_UVEDGE:
@@ -1012,7 +1085,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType)))
return NULL;
}
- else if (type == GPU_BUFFER_UV) {
+ else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
if (!DM_get_tessface_data_layer(dm, CD_MTFACE))
return NULL;
}
@@ -1088,9 +1161,35 @@ void GPU_uv_setup(DerivedMesh *dm)
glTexCoordPointer(2, GL_FLOAT, 0, dm->drawObject->uv->pointer);
}
- GLStates |= GPU_BUFFER_TEXCOORD_STATE;
+ GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE;
+}
+
+void GPU_texpaint_uv_setup(DerivedMesh *dm)
+{
+ if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT))
+ return;
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ if (useVBOs) {
+ gpu_glBindBuffer(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id);
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
+ glClientActiveTexture(GL_TEXTURE2);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float)));
+ glClientActiveTexture(GL_TEXTURE0);
+ }
+ else {
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer);
+ glClientActiveTexture(GL_TEXTURE2);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float));
+ glClientActiveTexture(GL_TEXTURE0);
+ }
+
+ GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE;
}
+
void GPU_color_setup(DerivedMesh *dm, int colType)
{
if (!dm->drawObject) {
@@ -1248,8 +1347,13 @@ void GPU_buffer_unbind(void)
glDisableClientState(GL_VERTEX_ARRAY);
if (GLStates & GPU_BUFFER_NORMAL_STATE)
glDisableClientState(GL_NORMAL_ARRAY);
- if (GLStates & GPU_BUFFER_TEXCOORD_STATE)
+ if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE)
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) {
+ glClientActiveTexture(GL_TEXTURE2);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTexture(GL_TEXTURE0);
+ }
if (GLStates & GPU_BUFFER_COLOR_STATE)
glDisableClientState(GL_COLOR_ARRAY);
if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
@@ -1258,8 +1362,8 @@ void GPU_buffer_unbind(void)
}
}
GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
- GPU_BUFFER_TEXCOORD_STATE | GPU_BUFFER_COLOR_STATE |
- GPU_BUFFER_ELEMENT_STATE);
+ GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
+ GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
if (attribData[i].index != -1) {
@@ -2584,11 +2688,17 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
}
else if (buffers->use_bmesh) {
/* due to dynamc nature of dyntopo, only get first material */
- GSetIterator gs_iter;
- BMFace *f;
- BLI_gsetIterator_init(&gs_iter, bm_faces);
- f = BLI_gsetIterator_getKey(&gs_iter);
- GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ if (BLI_gset_size(bm_faces) > 0) {
+ GSetIterator gs_iter;
+ BMFace *f;
+
+ BLI_gsetIterator_init(&gs_iter, bm_faces);
+ f = BLI_gsetIterator_getKey(&gs_iter);
+ GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ }
+ else {
+ return false;
+ }
}
else {
const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
@@ -2596,9 +2706,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
}
- return diffuse_color[0] != buffers->diffuse_color[0] ||
- diffuse_color[1] != buffers->diffuse_color[1] ||
- diffuse_color[2] != buffers->diffuse_color[2];
+ return !equals_v3v3(diffuse_color, buffers->diffuse_color);
}
/* release a GPU_PBVH_Buffers id;