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')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c289
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c38
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h6
-rw-r--r--source/blender/gpu/intern/gpu_deprecated.h5
-rw-r--r--source/blender/gpu/intern/gpu_draw.c92
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c20
-rw-r--r--source/blender/gpu/intern/gpu_material.c12
7 files changed, 278 insertions, 184 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 8b5b8f491da..1aae8ed2271 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -53,6 +53,7 @@
#include "GPU_buffers.h"
#include "GPU_compatibility.h"
+#include "GPU_draw.h"
typedef enum {
GPU_BUFFER_VERTEX_STATE = 1,
@@ -706,34 +707,6 @@ static void GPU_buffer_copy_uv(DerivedMesh *dm, float *varray, int *index, int *
}
}
-
-static void GPU_buffer_copy_color3(DerivedMesh *dm, float *varray_, int *index, int *mat_orig_to_new, void *user)
-{
- int i, totface;
- char *varray = (char *)varray_;
- char *mcol = (char *)user;
- MFace *f = dm->getTessFaceArray(dm);
-
- totface = dm->getNumTessFaces(dm);
- for (i = 0; i < totface; i++, f++) {
- int start = index[mat_orig_to_new[f->mat_nr]];
-
- /* v1 v2 v3 */
- copy_v3_v3_char(&varray[start], &mcol[i * 12]);
- copy_v3_v3_char(&varray[start + 3], &mcol[i * 12 + 3]);
- copy_v3_v3_char(&varray[start + 6], &mcol[i * 12 + 6]);
- index[mat_orig_to_new[f->mat_nr]] += 9;
-
- if (f->v4) {
- /* v3 v4 v1 */
- copy_v3_v3_char(&varray[start + 9], &mcol[i * 12 + 6]);
- copy_v3_v3_char(&varray[start + 12], &mcol[i * 12 + 9]);
- copy_v3_v3_char(&varray[start + 15], &mcol[i * 12]);
- index[mat_orig_to_new[f->mat_nr]] += 9;
- }
- }
-}
-
static void copy_mcol_uc3(unsigned char *v, unsigned char *col)
{
v[0] = col[3];
@@ -818,28 +791,6 @@ static void GPU_buffer_copy_uvedge(DerivedMesh *dm, float *varray, int *UNUSED(i
}
}
-/* get the DerivedMesh's MCols; choose (in decreasing order of
- * preference) from CD_ID_MCOL, CD_PREVIEW_MCOL, or CD_MCOL */
-static MCol *gpu_buffer_color_type(DerivedMesh *dm)
-{
- MCol *c;
- int type;
-
- type = CD_ID_MCOL;
- c = DM_get_tessface_data_layer(dm, type);
- if (!c) {
- type = CD_PREVIEW_MCOL;
- c = DM_get_tessface_data_layer(dm, type);
- if (!c) {
- type = CD_MCOL;
- c = DM_get_tessface_data_layer(dm, type);
- }
- }
-
- dm->drawObject->colType = type;
- return c;
-}
-
typedef enum {
GPU_BUFFER_VERTEX = 0,
GPU_BUFFER_NORMAL,
@@ -922,7 +873,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
/* special handling for MCol and UV buffers */
if (type == GPU_BUFFER_COLOR) {
- if (!(user_data = gpu_buffer_color_type(dm)))
+ if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType)))
return NULL;
}
else if (type == GPU_BUFFER_UV) {
@@ -942,7 +893,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type)
{
GPUBuffer **buf;
-
+
if (!dm->drawObject)
dm->drawObject = GPU_drawobject_new(dm);
@@ -1004,8 +955,28 @@ void GPU_uv_setup(DerivedMesh *dm)
GLStates |= GPU_BUFFER_TEXCOORD_STATE;
}
-void GPU_color_setup(DerivedMesh *dm)
+void GPU_color_setup(DerivedMesh *dm, int colType)
{
+ if (!dm->drawObject) {
+ /* XXX Not really nice, but we need a valid gpu draw object to set the colType...
+ * Else we would have to add a new param to gpu_buffer_setup_common. */
+ dm->drawObject = GPU_drawobject_new(dm);
+ dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
+ dm->drawObject->colType = colType;
+ }
+ /* In paint mode, dm may stay the same during stroke, however we still want to update colors!
+ * Also check in case we changed color type (i.e. which MCol cdlayer we use). */
+ else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) {
+ GPUBuffer **buf = gpu_drawobject_buffer_from_type(dm->drawObject, GPU_BUFFER_COLOR);
+ /* XXX Freeing this buffer is a bit stupid, as geometry has not changed, size should remain the same.
+ * Not sure though it would be worth defining a sort of gpu_buffer_update func - nor whether
+ * it is even possible ! */
+ GPU_buffer_free(*buf);
+ *buf = NULL;
+ dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
+ dm->drawObject->colType = colType;
+ }
+
if (!gpu_buffer_setup_common(dm, GPU_BUFFER_COLOR))
return;
@@ -1166,20 +1137,6 @@ void GPU_buffer_unbind(void)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
-/* confusion: code in cdderivedmesh calls both GPU_color_setup and
- * GPU_color3_upload; both of these set the `colors' buffer, so seems
- * like it will just needlessly overwrite? --nicholas */
-void GPU_color3_upload(DerivedMesh *dm, unsigned char *data)
-{
- if (dm->drawObject == 0)
- dm->drawObject = GPU_drawobject_new(dm);
- GPU_buffer_free(dm->drawObject->colors);
-
- dm->drawObject->colors = gpu_buffer_setup(dm, dm->drawObject, 3,
- sizeof(char) * 3 * dm->drawObject->tot_triangle_point,
- GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color3);
-}
-
void GPU_color_switch(int mode)
{
if (mode) {
@@ -1270,11 +1227,11 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start,
* drawing and doesn't interact at all with the buffer code above */
/* Return false if VBO is either unavailable or disabled by the user,
- true otherwise */
+ * true otherwise */
static int gpu_vbo_enabled(void)
{
return (GLEW_ARB_vertex_buffer_object &&
- !(U.gameflags & USER_DISABLE_VBO));
+ !(U.gameflags & USER_DISABLE_VBO));
}
/* Convenience struct for building the VBO. */
@@ -1316,6 +1273,9 @@ struct GPU_Buffers {
/* The PBVH ensures that either all faces in the node are
smooth-shaded or all faces are flat-shaded */
int smooth;
+
+ int show_diffuse_color;
+ float diffuse_color[4];
};
typedef enum {
VBO_ENABLED,
@@ -1339,23 +1299,24 @@ static void gpu_colors_disable(VBO_State vbo_state)
static float gpu_color_from_mask(float mask)
{
- return (1.0f - mask) * 0.5f + 0.25f;
+ return 1.0f - mask * 0.75f;
}
-static void gpu_color_from_mask_copy(float mask, unsigned char out[3])
+static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3])
{
- unsigned char color;
-
- color = gpu_color_from_mask(mask) * 255.0f;
+ float mask_color;
+
+ mask_color = gpu_color_from_mask(mask) * 255.0f;
- out[0] = color;
- out[1] = color;
- out[2] = color;
+ out[0] = diffuse_color[0] * mask_color;
+ out[1] = diffuse_color[1] * mask_color;
+ out[2] = diffuse_color[2] * mask_color;
}
-static void gpu_color_from_mask_set(float mask)
+static void gpu_color_from_mask_set(float mask, float diffuse_color[4])
{
- gpuGray3f(gpu_color_from_mask(mask));
+ float color = gpu_color_from_mask(mask);
+ gpuColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
}
static float gpu_color_from_mask_quad(const CCGKey *key,
@@ -1371,36 +1332,50 @@ static float gpu_color_from_mask_quad(const CCGKey *key,
static void gpu_color_from_mask_quad_copy(const CCGKey *key,
CCGElem *a, CCGElem *b,
CCGElem *c, CCGElem *d,
+ const float *diffuse_color,
unsigned char out[3])
{
- unsigned char color =
+ float mask_color =
gpu_color_from_mask((*CCG_elem_mask(key, a) +
*CCG_elem_mask(key, b) +
*CCG_elem_mask(key, c) +
*CCG_elem_mask(key, d)) * 0.25f) * 255.0f;
- out[0] = color;
- out[1] = color;
- out[2] = color;
+ out[0] = diffuse_color[0] * mask_color;
+ out[1] = diffuse_color[1] * mask_color;
+ out[2] = diffuse_color[2] * mask_color;
}
static void gpu_color_from_mask_quad_set(const CCGKey *key,
CCGElem *a, CCGElem *b,
- CCGElem *c, CCGElem *d)
+ CCGElem *c, CCGElem *d,
+ float diffuse_color[4])
{
- gpuGray3f(gpu_color_from_mask_quad(key, a, b, c, d));
+ float color = gpu_color_from_mask_quad(key, a, b, c, d);
+ gpuColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
}
void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
- int *vert_indices, int totvert, const float *vmask)
+ int *vert_indices, int totvert, const float *vmask,
+ int (*face_vert_indices)[4], int show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j, k;
buffers->vmask = vmask;
+ buffers->show_diffuse_color = show_diffuse_color;
if (buffers->vert_buf) {
int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ if (buffers->show_diffuse_color) {
+ MFace *f = buffers->mface + buffers->face_indices[0];
+
+ GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ }
+
+ copy_v4_v4(buffers->diffuse_color, diffuse_color);
/* Build VBO */
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
@@ -1421,11 +1396,27 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
copy_v3_v3(out->co, v->co);
memcpy(out->no, v->no, sizeof(short) * 3);
- if (vmask) {
- gpu_color_from_mask_copy(vmask[vert_indices[i]],
- out->color);
- }
}
+
+#define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
+ { \
+ VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
+ if (vmask) \
+ gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
+ else \
+ rgb_float_to_uchar(out->color, diffuse_color); \
+ } (void)0
+
+ for (i = 0; i < buffers->totface; i++) {
+ MFace *f = buffers->mface + buffers->face_indices[i];
+
+ UPDATE_VERTEX(i, f->v1, 0, diffuse_color);
+ UPDATE_VERTEX(i, f->v2, 1, diffuse_color);
+ UPDATE_VERTEX(i, f->v3, 2, diffuse_color);
+ if (f->v4)
+ UPDATE_VERTEX(i, f->v4, 3, diffuse_color);
+ }
+#undef UPDATE_VERTEX
}
else {
for (i = 0; i < buffers->totface; ++i) {
@@ -1437,6 +1428,9 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
float fmask;
+ if (paint_is_face_hidden(f, mvert))
+ continue;
+
/* Face normal and mask */
if (f->v4) {
normal_quad_v3(fno,
@@ -1448,7 +1442,7 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
fmask = (vmask[fv[0]] +
vmask[fv[1]] +
vmask[fv[2]] +
- vmask[fv[3]]) * 0.25;
+ vmask[fv[3]]) * 0.25f;
}
}
else {
@@ -1471,8 +1465,11 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
copy_v3_v3(out->co, v->co);
memcpy(out->no, no, sizeof(short) * 3);
+
if (vmask)
- gpu_color_from_mask_copy(fmask, out->color);
+ gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
+ else
+ rgb_float_to_uchar(out->color, diffuse_color);
vert_data++;
}
@@ -1506,6 +1503,8 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4],
buffers->index_type = GL_UNSIGNED_SHORT;
buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH;
+ buffers->show_diffuse_color = FALSE;
+
/* Count the number of visible triangles */
for (i = 0, tottri = 0; i < totface; ++i) {
const MFace *f = &mface[face_indices[i]];
@@ -1560,7 +1559,7 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4],
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
- if (buffers->index_buf || !buffers->smooth)
+ if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth))
glGenBuffersARB(1, &buffers->vert_buf);
buffers->tot_tri = tottri;
@@ -1574,16 +1573,27 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4],
void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
const DMFlagMat *grid_flag_mats, int *grid_indices,
- int totgrid, const CCGKey *key)
+ int totgrid, const CCGKey *key, int show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j, k, x, y;
+ buffers->show_diffuse_color = show_diffuse_color;
+
/* Build VBO */
if (buffers->vert_buf) {
int totvert = key->grid_area * totgrid;
int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
const int has_mask = key->has_mask;
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ if (buffers->show_diffuse_color) {
+ const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
+
+ GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
+ }
+
+ copy_v4_v4(buffers->diffuse_color, diffuse_color);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,
@@ -1601,12 +1611,11 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
copy_v3_v3(vd->co, CCG_elem_co(key, elem));
if (smooth) {
- normal_float_to_short_v3(vd->no,
- CCG_elem_no(key, elem));
+ normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
if (has_mask) {
gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
- vd->color);
+ diffuse_color, vd->color);
}
}
vd++;
@@ -1642,6 +1651,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
elems[1],
elems[2],
elems[3],
+ diffuse_color,
vd->color);
}
}
@@ -1761,7 +1771,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
/* VBO is disabled; delete the previous buffer (if it exists) and
* return an invalid handle */
- if (gpu_vbo_enabled()) {
+ if (!gpu_vbo_enabled()) {
if (buffer)
glDeleteBuffersARB(1, &buffer);
return 0;
@@ -1810,6 +1820,8 @@ GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
buffers->grid_hidden = grid_hidden;
buffers->totgrid = totgrid;
+ buffers->show_diffuse_color = FALSE;
+
/* Count the number of quads */
totquad = gpu_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
@@ -1854,6 +1866,11 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers)
const MVert *mvert = buffers->mvert;
int i, j;
const int has_mask = (buffers->vmask != NULL);
+ const MFace *face = &buffers->mface[buffers->face_indices[0]];
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ if (buffers->show_diffuse_color)
+ GPU_material_diffuse_get(face->mat_nr + 1, diffuse_color);
if (has_mask) {
gpu_colors_enable(VBO_DISABLED);
@@ -1874,7 +1891,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers)
if (buffers->smooth) {
for (j = 0; j < S; j++) {
if (has_mask) {
- gpu_color_from_mask_set(buffers->vmask[fv[j]]);
+ gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color);
}
gpuNormal3sv(mvert[fv[j]].no);
gpuVertex3fv(mvert[fv[j]].co);
@@ -1900,10 +1917,10 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers)
buffers->vmask[fv[1]] +
buffers->vmask[fv[2]]);
if (f->v4)
- fmask = (fmask + buffers->vmask[fv[3]]) * 0.25;
+ fmask = (fmask + buffers->vmask[fv[3]]) * 0.25f;
else
fmask /= 3.0f;
- gpu_color_from_mask_set(fmask);
+ gpu_color_from_mask_set(fmask, diffuse_color);
}
for (j = 0; j < S; j++)
@@ -1925,6 +1942,11 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
const CCGKey *key = &buffers->gridkey;
int i, j, x, y, gridsize = buffers->gridkey.grid_size;
const int has_mask = key->has_mask;
+ const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
+ float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
+
+ if (buffers->show_diffuse_color)
+ GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
if (has_mask) {
gpu_colors_enable(VBO_DISABLED);
@@ -1958,7 +1980,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
if (buffers->smooth) {
for (j = 0; j < 4; j++) {
if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]));
+ gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color);
}
gpuNormal3fv(CCG_elem_no(key, e[j]));
@@ -1975,7 +1997,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
gpuNormal3fv(fno);
if (has_mask) {
- gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]);
+ gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color);
}
for (j = 0; j < 4; j++)
@@ -1994,13 +2016,13 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, a));
+ gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color);
}
gpuNormal3fv(CCG_elem_no(key, a));
gpuVertex3fv(CCG_elem_co(key, a));
if (has_mask) {
- gpu_color_from_mask_set(*CCG_elem_mask(key, b));
+ gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color);
}
gpuNormal3fv(CCG_elem_no(key, b));
@@ -2029,7 +2051,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
gpuNormal3fv(fno);
if (has_mask) {
- gpu_color_from_mask_quad_set(key, a, b, c, d);
+ gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color);
}
}
@@ -2050,8 +2072,6 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
{
- const int has_mask = (buffers->vmask || buffers->gridkey.has_mask);
-
if (buffers->totface) {
const MFace *f = &buffers->mface[buffers->face_indices[0]];
if (!setMaterial(f->mat_nr + 1, NULL))
@@ -2068,13 +2088,7 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
if (buffers->vert_buf) {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
- if (has_mask) {
- gpu_colors_enable(VBO_ENABLED);
- }
- else {
- gpu_colors_enable(VBO_DISABLED);
- gpuCurrentColor4ub(0xff, 0xff, 0xff, 0xff);
- }
+ gpu_colors_enable(VBO_ENABLED);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
@@ -2091,10 +2105,8 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
offset + offsetof(VertexBufferFormat, co));
glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
offset + offsetof(VertexBufferFormat, no));
- if (has_mask) {
- glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- offset + offsetof(VertexBufferFormat, color));
- }
+ glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
+ offset + offsetof(VertexBufferFormat, color));
glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0);
@@ -2108,10 +2120,8 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
(void *)offsetof(VertexBufferFormat, co));
glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
(void *)offsetof(VertexBufferFormat, no));
- if (has_mask) {
- glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
- (void *)offsetof(VertexBufferFormat, color));
- }
+ glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
+ (void *)offsetof(VertexBufferFormat, color));
if (buffers->index_buf)
glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, 0);
@@ -2125,12 +2135,7 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
- if (has_mask) {
- gpu_colors_disable(VBO_ENABLED);
- }
- else {
- gpu_colors_disable(VBO_DISABLED);
- }
+ gpu_colors_disable(VBO_ENABLED);
}
/* fallbacks if we are out of memory or VBO is disabled */
else if (buffers->totface) {
@@ -2141,6 +2146,32 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
}
}
+int GPU_buffers_diffuse_changed(GPU_Buffers *buffers, int show_diffuse_color)
+{
+ float diffuse_color[4];
+
+ if (buffers->show_diffuse_color != show_diffuse_color)
+ return TRUE;
+
+ if (buffers->show_diffuse_color == FALSE)
+ return FALSE;
+
+ if (buffers->mface) {
+ MFace *f = buffers->mface + buffers->face_indices[0];
+
+ GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
+ }
+ else {
+ const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
+
+ 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];
+}
+
void GPU_free_buffers(GPU_Buffers *buffers)
{
if (buffers) {
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 235bb74a65c..cfac515e306 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -794,7 +794,7 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
/* now bind the textures */
for (input=inputs->first; input; input=input->next) {
if (input->ima)
- input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->imagencd, time, mipmap);
+ input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
if (input->tex && input->bindtex) {
GPU_texture_bind(input->tex, input->texid);
@@ -950,7 +950,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->ima = link->ptr1;
input->iuser = link->ptr2;
- input->imagencd = link->imagencd;
+ input->image_isdata = link->image_isdata;
input->textarget = GL_TEXTURE_2D;
input->textype = GPU_TEX2D;
MEM_freeN(link);
@@ -1079,17 +1079,20 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a
}
}
- if (a == attribs->totlayer && a < GPU_MAX_ATTRIB) {
- input->attribid = attribs->totlayer++;
- input->attribfirst = 1;
+ if (a < GPU_MAX_ATTRIB) {
+ if (a == attribs->totlayer) {
+ input->attribid = attribs->totlayer++;
+ input->attribfirst = 1;
- attribs->layer[a].type = input->attribtype;
- attribs->layer[a].attribid = input->attribid;
- BLI_strncpy(attribs->layer[a].name, input->attribname,
- sizeof(attribs->layer[a].name));
+ attribs->layer[a].type = input->attribtype;
+ attribs->layer[a].attribid = input->attribid;
+ BLI_strncpy(attribs->layer[a].name, input->attribname,
+ sizeof(attribs->layer[a].name));
+ }
+ else {
+ input->attribid = attribs->layer[a].attribid;
+ }
}
- else
- input->attribid = attribs->layer[a].attribid;
}
}
}
@@ -1143,14 +1146,14 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
return link;
}
-GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int ncd)
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
{
GPUNodeLink *link = GPU_node_link_create(0);
link->image= 1;
link->ptr1= ima;
link->ptr2= iuser;
- link->imagencd= ncd;
+ link->image_isdata= isdata;
return link;
}
@@ -1178,15 +1181,6 @@ GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
return link;
}
-GPUNodeLink *GPU_socket(GPUNodeStack *sock)
-{
- GPUNodeLink *link = GPU_node_link_create(0);
-
- link->socket= sock;
-
- return link;
-}
-
GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
{
GPUNodeLink *link = GPU_node_link_create(0);
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index b4e9f6d996c..a412d0eb4c6 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -92,7 +92,7 @@ struct GPUNodeLink {
const char *attribname;
int image;
- int imagencd;
+ int image_isdata;
int texture;
int texturesize;
@@ -100,7 +100,7 @@ struct GPUNodeLink {
void *ptr1, *ptr2;
int dynamic;
- int dynamictype;
+ int dynamictype;
int type;
int users;
@@ -139,7 +139,7 @@ typedef struct GPUInput {
struct Image *ima; /* image */
struct ImageUser *iuser;/* image user */
- int imagencd; /* image does not contain color data */
+ int image_isdata; /* image does not contain color data */
float *dynamicvec; /* vector data in case it is dynamic */
int dynamictype; /* origin of the dynamic uniform (GPUDynamicType) */
void *dynamicdata; /* data source of the dynamic uniform */
diff --git a/source/blender/gpu/intern/gpu_deprecated.h b/source/blender/gpu/intern/gpu_deprecated.h
index 403e0ec87c9..016cb3d10e4 100644
--- a/source/blender/gpu/intern/gpu_deprecated.h
+++ b/source/blender/gpu/intern/gpu_deprecated.h
@@ -536,6 +536,9 @@
#undef glNewList
#define glNewList DO_NOT_USE_glNewList
-/* GLU Quadrics */
+/* GLU */
+#undef gluUnProject
+#define gluUnProject DO_NOT_USE_gluUnProject
+
#endif /* _GPU_DEPRECATED_H_ */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index ab8a7389887..53a51c9c9fd 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -529,7 +529,7 @@ static void GenerateMipmapRGBA(int high_bit, int w, int h, void * data)
}
#endif
-int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap, int ncd)
+int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap, int is_data)
{
ImBuf *ibuf = NULL;
unsigned int *bind = NULL;
@@ -599,7 +599,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
}
/* TODO unneeded when float images are correctly treated as linear always */
- if (!ncd)
+ if (!is_data)
do_color_management = TRUE;
if (ibuf->rect==NULL)
@@ -719,12 +719,21 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
rect= tilerect;
}
}
+
#ifdef WITH_DDS
if (ibuf->ftype & DDS)
GPU_create_gl_tex_compressed(bind, rect, rectw, recth, mipmap, ima, ibuf);
else
#endif
GPU_create_gl_tex(bind, rect, frect, rectw, recth, mipmap, use_high_bit_depth, ima);
+
+ /* mark as non-color data texture */
+ if (*bind) {
+ if (is_data)
+ ima->tpageflag |= IMA_GLBIND_IS_DATA;
+ else
+ ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
+ }
/* clean up */
if (tilerect)
@@ -831,12 +840,17 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
return FALSE;
}
+ if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) {
+ printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
+ return FALSE;
+ }
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- blocksize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
+ blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
for (i=0; i<ibuf->dds_data.nummipmaps && (width||height); ++i) {
if (width == 0)
width = 1;
@@ -999,7 +1013,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
/* if color correction is needed, we must update the part that needs updating. */
if (ibuf->rect_float) {
float *buffer = MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
- IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+ int is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA);
+ IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
@@ -1030,12 +1045,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
if (y != 0)
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
- if (ibuf->rect_float)
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
- GL_FLOAT, ibuf->rect_float);
- else
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
- GL_UNSIGNED_BYTE, ibuf->rect);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ GL_UNSIGNED_BYTE, ibuf->rect);
if (ibuf->x != 0)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); /* restore default value */
@@ -1127,21 +1138,53 @@ void GPU_free_smoke(SmokeModifierData *smd)
if (smd->domain->tex_shadow)
GPU_texture_free(smd->domain->tex_shadow);
smd->domain->tex_shadow = NULL;
+
+ if (smd->domain->tex_flame)
+ GPU_texture_free(smd->domain->tex_flame);
+ smd->domain->tex_flame = NULL;
}
}
void GPU_create_smoke(SmokeModifierData *smd, int highres)
{
#ifdef WITH_SMOKE
- if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && !highres)
- smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid));
- else if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && highres)
- smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt));
+ if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
+ SmokeDomainSettings *sds = smd->domain;
+ if (!sds->tex && !highres) {
+ /* rgba texture for color + density */
+ if (smoke_has_colors(sds->fluid)) {
+ float *data = MEM_callocN(sizeof(float)*sds->total_cells*4, "smokeColorTexture");
+ smoke_get_rgba(sds->fluid, data, 0);
+ sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 4, data);
+ MEM_freeN(data);
+ }
+ /* density only */
+ else {
+ sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_density(sds->fluid));
+ }
+ sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_flame(sds->fluid)) : NULL;
+ }
+ else if (!sds->tex && highres) {
+ /* rgba texture for color + density */
+ if (smoke_turbulence_has_colors(sds->wt)) {
+ float *data = MEM_callocN(sizeof(float)*smoke_turbulence_get_cells(sds->wt)*4, "smokeColorTexture");
+ smoke_turbulence_get_rgba(sds->wt, data, 0);
+ sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 4, data);
+ MEM_freeN(data);
+ }
+ /* density only */
+ else {
+ sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_density(sds->wt));
+ }
+ sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_flame(sds->wt)) : NULL;
+ }
- smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow);
+ sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, sds->shadow);
+ }
#else // WITH_SMOKE
(void)highres;
smd->domain->tex= NULL;
+ smd->domain->tex_flame= NULL;
smd->domain->tex_shadow= NULL;
#endif // WITH_SMOKE
}
@@ -1206,7 +1249,7 @@ void GPU_free_image(Image *ima)
ima->repbind= NULL;
}
- ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ ima->tpageflag &= ~(IMA_MIPMAP_COMPLETE|IMA_GLBIND_IS_DATA);
}
void GPU_free_images(void)
@@ -1392,7 +1435,7 @@ static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat,
if (gamma) {
linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
linearrgb_to_srgb_v3_v3(smat->spec, smat->spec);
- }
+ }
}
}
@@ -1656,6 +1699,21 @@ void GPU_disable_material(void)
reset_default_alphablend_state();
}
+void GPU_material_diffuse_get(int nr, float diff[4])
+{
+ /* prevent index to use un-initialized array items */
+ if (nr >= GMS.totmat)
+ nr = 0;
+
+ /* no GPU_begin_object_materials, use default material */
+ if (!GMS.matbuf) {
+ mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit);
+ }
+ else {
+ copy_v4_v4(diff, GMS.matbuf[nr].diff);
+ }
+}
+
void GPU_end_object_materials(void)
{
GPU_disable_material();
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 7de3729f9b5..57a35eac3e2 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -474,7 +474,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
}
-GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
+GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels)
{
GPUTexture *tex;
GLenum type, format, internalformat;
@@ -512,9 +512,15 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
GPU_print_error("3D glBindTexture");
- type = GL_FLOAT; // GL_UNSIGNED_BYTE
- format = GL_RED;
- internalformat = GL_INTENSITY;
+ type = GL_FLOAT;
+ if (channels == 4) {
+ format = GL_RGBA;
+ internalformat = GL_RGBA;
+ }
+ else {
+ format = GL_RED;
+ internalformat = GL_INTENSITY;
+ }
//if (fpixels)
// pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
@@ -554,7 +560,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
return tex;
}
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int ncd, double time, int mipmap)
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, double time, int mipmap)
{
GPUTexture *tex;
GLint w, h, border, lastbindcode, bindcode;
@@ -562,7 +568,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int ncd, doub
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
GPU_update_image_time(ima, time);
- bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, ncd);
+ bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, isdata);
if (ima->gputexture) {
ima->gputexture->bindcode = bindcode;
@@ -1319,7 +1325,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
return retval;
}
-void GPU_shader_free_builtin_shaders()
+void GPU_shader_free_builtin_shaders(void)
{
if (GG.shaders.vsm_store) {
MEM_freeN(GG.shaders.vsm_store);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index b60c178cf3c..1005a60d8b1 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -802,7 +802,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
}
}
- if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS);
+ if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) {
+ /* pass */
+ }
else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
(GPU_link_changed(shi->spec) || ma->spec != 0.0f))
{
@@ -1149,7 +1151,7 @@ static void do_material_tex(GPUShadeInput *shi)
newnor = tnor;
}
- norfac = minf(fabsf(mtex->norfac), 1.0f);
+ norfac = min_ff(fabsf(mtex->norfac), 1.0f);
if (norfac == 1.0f && !GPU_link_changed(stencil)) {
shi->vn = newnor;
@@ -1609,8 +1611,8 @@ void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float a
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend)
{
- lamp->spotsi= cos(M_PI*spotsize/360.0);
- lamp->spotbl= (1.0f - lamp->spotsi)*spotblend;
+ lamp->spotsi= cosf((float)M_PI * spotsize / 360.0f);
+ lamp->spotbl= (1.0f - lamp->spotsi) * spotblend;
}
static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
@@ -1901,7 +1903,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
GPUBuiltin gputype;
GPUDynamicType dynamictype;
GPUDataType datatype;
- } builtins[] = {
+ } builtins[] = {
{ GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F },
{ GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA_16F },
{ GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F },