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')
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_buffers.h9
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/GPU_immediate.h11
-rw-r--r--source/blender/gpu/GPU_select.h50
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c156
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c8
-rw-r--r--source/blender/gpu/intern/gpu_draw.c32
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c58
-rw-r--r--source/blender/gpu/intern/gpu_immediate.c2
-rw-r--r--source/blender/gpu/intern/gpu_material.c6
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c2
-rw-r--r--source/blender/gpu/intern/gpu_raster.c2
-rw-r--r--source/blender/gpu/intern/gpu_select.c330
-rw-r--r--source/blender/gpu/intern/gpu_utility.c4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl54
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_vert.glsl54
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl12
18 files changed, 548 insertions, 246 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index f59dd44f169..7d34c4e3829 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -140,7 +140,7 @@ set(SRC
GPU_primitives.h
GPU_raster.h
GPU_safety.h
- GPU_select.h
+ GPU_select.h
GPU_sprite.h
GPU_state_latch.h
GPU_utility.h
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 55325f91c05..ee20919dde3 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -38,11 +38,11 @@
extern "C" {
#endif
-#ifdef _DEBUG
-/*#define DEBUG_VBO(X) printf(X)*/
-#define DEBUG_VBO(X)
+#ifdef DEBUG
+/* #define DEBUG_VBO(X) printf(X)*/
+# define DEBUG_VBO(X)
#else
-#define DEBUG_VBO(X)
+# define DEBUG_VBO(X)
#endif
struct BMesh;
@@ -138,6 +138,7 @@ void GPU_drawobject_free(struct DerivedMesh *dm);
void GPU_vertex_setup(struct DerivedMesh *dm);
void GPU_normal_setup(struct DerivedMesh *dm);
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_edge_setup(struct DerivedMesh *dm); /* does not mix with other data */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index df707685a35..a4ac8424fbc 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -98,7 +98,7 @@ int GPU_get_material_alpha_blend(void);
* - passing NULL clears the state again */
int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp);
-
+void GPU_clear_tpage(bool force);
/* Lights
* - returns how many lights were enabled
* - this affects fixed functions materials and texface, not glsl */
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index ddf2601800d..dcb64628f24 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -939,23 +939,12 @@ BLI_INLINE void gpuDrawElements(GLenum mode)
}
-
-
-void gpu_draw_elements_gl(void);
-
-
-
BLI_INLINE void gpuRepeatElements(void)
{
gpu_draw_elements_gl();
}
-
-void gpu_draw_range_elements_gl(void);
-
-
-
BLI_INLINE void gpuDrawRangeElements(GLenum mode)
{
GPU_IMMEDIATE->mode = mode;
diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h
index 6b81ce7b248..9fe1b413a3c 100644
--- a/source/blender/gpu/GPU_select.h
+++ b/source/blender/gpu/GPU_select.h
@@ -1,6 +1,3 @@
-#ifndef _GPU_SELECT_H_
-#define _GPU_SELECT_H_
-
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -18,12 +15,10 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): Jason Wilkins.
+ * Contributor(s): Antony Riakiotakis.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -32,30 +27,37 @@
* \ingroup gpu
*/
-#include "GPU_glew.h"
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef __GPU_SELECT__
+#define __GPU_SELECT__
+#include "GPU_glew.h"
+#include "DNA_vec_types.h" /* rcft */
+#include "BLI_sys_types.h"
+/* flags for mode of operation */
+enum {
+ GPU_SELECT_ALL = 1,
+ GPU_SELECT_NEAREST_FIRST_PASS = 2,
+ GPU_SELECT_NEAREST_SECOND_PASS = 3,
+};
-void GPU_select_buffer(GLsizei size, GLuint* buffer); /* replaces glSelectBuffer(size, buffer) */
+/* initialize and provide buffer for results */
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, char mode, int oldhits);
-void GPU_select_begin (void); /* replaces glRenderMode(GL_SELECT) */
-GLsizei GPU_select_end (void); /* replaces glRenderMode(GL_RENDER) */
+/* loads a new selection id and ends previous query, if any. In second pass of selection it also returns
+ * if id has been hit on the first pass already. Thus we can skip drawing un-hit objects IMPORTANT: We rely on the order of object rendering on passes to be
+ * the same for this to work */
+bool GPU_select_load_id(unsigned int id);
-void GPU_select_clear (void); /* replaces glInitNames() */
-void GPU_select_pop (void); /* replaces glPopName() */
-void GPU_select_push (GLuint name); /* replaces glPushName(name) */
-void GPU_select_load (GLuint name); /* replaces glLoadName(name) */
+/* cleanup and flush selection results to buffer. Return number of hits and hits in buffer.
+ * if dopass is true, we will do a second pass with occlusion queries to get the closest hit */
+unsigned int GPU_select_end(void);
+/* does the GPU support occlusion queries? */
+bool GPU_select_query_check_support(void);
+/* is occlusion query supported and user activated? */
+bool GPU_select_query_check_active(void);
-#ifdef __cplusplus
-}
#endif
-#endif /* _GPU_SELECT_H_ */
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;
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 0440215c774..c9109b96424 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -105,7 +105,7 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
/* skip a variable/function name */
while (*str) {
- if (ELEM7(*str, ' ', '(', ')', ',', '\t', '\n', '\r'))
+ if (ELEM(*str, ' ', '(', ')', ',', '\t', '\n', '\r'))
break;
else {
if (token && len < max-1) {
@@ -123,7 +123,7 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
/* skip the next special characters:
* note the missing ')' */
while (*str) {
- if (ELEM6(*str, ' ', '(', ',', '\t', '\n', '\r'))
+ if (ELEM(*str, ' ', '(', ',', '\t', '\n', '\r'))
str++;
else
break;
@@ -1417,6 +1417,10 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
/* failed? */
if (!shader) {
+ if (fragmentcode)
+ MEM_freeN(fragmentcode);
+ if (vertexcode)
+ MEM_freeN(vertexcode);
memset(attribs, 0, sizeof(*attribs));
memset(builtins, 0, sizeof(*builtins));
GPU_nodes_free(nodes);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index dd495657ea1..729146e065b 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -378,9 +378,9 @@ static void blend_func_state_init(void)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
-static void gpu_clear_tpage(void)
+void GPU_clear_tpage(bool force)
{
- if (GTS.lasttface==NULL)
+ if (GTS.lasttface==NULL && !force)
return;
GTS.lasttface= NULL;
@@ -540,12 +540,16 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
* a high precision format only if it is available */
use_high_bit_depth = true;
}
+ /* we may skip this in high precision, but if not, we need to have a valid buffer here */
+ else if (ibuf->userflags & IB_RECT_INVALID) {
+ IMB_rect_from_float(ibuf);
+ }
/* TODO unneeded when float images are correctly treated as linear always */
if (!is_data)
do_color_management = true;
- if (ibuf->rect==NULL)
+ if (ibuf->rect == NULL)
IMB_rect_from_float(ibuf);
}
@@ -876,7 +880,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap, int alphablend)
/* check if we need to clear the state */
if (tface==NULL) {
- gpu_clear_tpage();
+ GPU_clear_tpage(false);
return 0;
}
@@ -1045,21 +1049,14 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
* which is much quicker for painting */
GLint row_length, skip_pixels, skip_rows;
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
-
/* 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");
+ float *buffer = MEM_mallocN(w * h * sizeof(float) * 4, "temp_texpaint_float_buf");
bool is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA) != 0;
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
-
+
if (GPU_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
MEM_freeN(buffer);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
@@ -1084,15 +1081,16 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
}
if (GPU_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
+ glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
+ glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
+
glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
@@ -1558,7 +1556,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* setting 'do_alpha_after = true' indicates this object needs to be
* drawn in a second alpha pass for improved blending */
if (do_alpha_after && !GMS.is_alpha_pass)
- if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
+ if (ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
*do_alpha_after = true;
GMS.alphablend[a]= alphablend;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 6c4d1018272..310b46266d3 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -79,6 +79,8 @@
#include <string.h>
+#define MAX_DEFINE_LENGTH 72
+
/* Extensions support */
/* extensions used:
@@ -992,6 +994,9 @@ bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char er
gpu_glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
GG.currentfb = fb->object;
+ /* Clean glError buffer. */
+ while (glGetError() != GL_NO_ERROR) {}
+
gpu_glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
tex->target, tex->bindcode, 0);
@@ -1378,35 +1383,51 @@ static bool print_status(GLuint object, GLboolean is_program, const char* nickna
return status;
}
+static const char *gpu_shader_version(void)
+{
+ /* turn on glsl 1.30 for bicubic bump mapping and ATI clipping support */
+ if (GLEW_VERSION_3_0 &&
+ (GPU_bicubic_bump_support() || GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)))
+ {
+ return "#version 130\n";
+ }
+
+ return "";
+}
+
+
static const char *gpu_shader_standard_extensions(void)
{
/* need this extensions for high quality bump mapping */
- if (GPU_bicubic_bump_support()) {
- return "#version 130\n"
- "#extension GL_ARB_texture_query_lod: enable\n"
- "#define BUMP_BICUBIC\n";
- }
+ if (GPU_bicubic_bump_support())
+ return "#extension GL_ARB_texture_query_lod: enable\n";
return "";
}
-static const char *gpu_shader_standard_defines(void)
+static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
{
/* some useful defines to detect GPU type */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY))
- return "#define GPU_ATI\n";
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_ATI\n");
+ if (GLEW_VERSION_3_0)
+ strcat(defines, "#define CLIP_WORKAROUND\n");
+ }
else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
- return "#define GPU_NVIDIA\n";
+ strcat(defines, "#define GPU_NVIDIA\n");
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
- return "#define GPU_INTEL\n";
-
- return "";
+ strcat(defines, "#define GPU_INTEL\n");
+
+ if (GPU_bicubic_bump_support())
+ strcat(defines, "#define BUMP_BICUBIC\n");
+ return;
}
GPUShader *GPU_shader_create(const char* nickname, const char *vertexcode, const char *fragcode, const char *libcode, const char *defines)
{
GLint status;
GPUShader *shader;
+ char standard_defines[MAX_DEFINE_LENGTH] = "";
#if 0
int i;
@@ -1460,12 +1481,16 @@ GPUShader *GPU_shader_create(const char* nickname, const char *vertexcode, const
return NULL;
}
+ gpu_shader_standard_defines(standard_defines);
+
if (vertexcode) {
- const char *source[4];
+ const char *source[5];
+ /* custom limit, may be too small, beware */
int num_source = 0;
+ source[num_source++] = gpu_shader_version();
source[num_source++] = gpu_shader_standard_extensions();
- source[num_source++] = gpu_shader_standard_defines();
+ source[num_source++] = standard_defines;
if (defines) source[num_source++] = defines;
if (vertexcode) source[num_source++] = vertexcode;
@@ -1482,11 +1507,12 @@ GPUShader *GPU_shader_create(const char* nickname, const char *vertexcode, const
}
if (fragcode) {
- const char *source[5];
+ const char *source[6];
int num_source = 0;
+ source[num_source++] = gpu_shader_version();
source[num_source++] = gpu_shader_standard_extensions();
- source[num_source++] = gpu_shader_standard_defines();
+ source[num_source++] = standard_defines;
if (defines) source[num_source++] = defines;
if (libcode) source[num_source++] = libcode;
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c
index dbe480993cb..7f5127408aa 100644
--- a/source/blender/gpu/intern/gpu_immediate.c
+++ b/source/blender/gpu/intern/gpu_immediate.c
@@ -483,7 +483,7 @@ static GLboolean end_begin(void)
GPU_IMMEDIATE->hasOverflowed = GL_TRUE;
#endif
- if (!ELEM6(
+ if (!ELEM(
GPU_IMMEDIATE->mode,
GL_NOOP,
GL_LINE_LOOP,
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 9e89f6afd24..4f8ae3ebde8 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -951,6 +951,12 @@ static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *o
case MTEX_BLEND_COLOR:
GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
break;
+ case MTEX_SOFT_LIGHT:
+ GPU_link(mat, "mtex_rgb_soft", out, tex, fact, facg, in);
+ break;
+ case MTEX_LIN_LIGHT:
+ GPU_link(mat, "mtex_rgb_linear", out, tex, fact, facg, in);
+ break;
default:
GPU_link(mat, "set_rgb_zero", &in);
break;
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index 583e378c32f..dab468e6733 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -79,7 +79,7 @@ static GLenum ms_current_mode;
/* Check if we have a good matrix */
-#if WITH_GPU_SAFETY
+#ifdef WITH_GPU_SAFETY
static void checkmat(GLfloat *m)
{
diff --git a/source/blender/gpu/intern/gpu_raster.c b/source/blender/gpu/intern/gpu_raster.c
index 81a733a54a0..cbda490f980 100644
--- a/source/blender/gpu/intern/gpu_raster.c
+++ b/source/blender/gpu/intern/gpu_raster.c
@@ -502,7 +502,7 @@ static GLboolean end_begin(void)
GPU_IMMEDIATE->hasOverflowed = GL_TRUE;
#endif
- if (!ELEM6(
+ if (!ELEM(
GPU_IMMEDIATE->mode,
GL_NOOP,
GL_LINE_LOOP,
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 2ae5bc8a742..17fd584a340 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -15,177 +15,237 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
- * The Original Code is: all of this file.
- *
- * Contributor(s): Jason Wilkins.
+ * Contributor(s): Antony Riakiotakis, Jason Wilkins.
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file source/blender/gpu/intern/gpu_select.c
+/** \file blender/gpu/intern/gpu_select.c
* \ingroup gpu
+ *
+ * Interface for accessing gpu-related methods for selection. The semantics will be
+ * similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility.
*/
#if WITH_GL_PROFILE_COMPAT
#define GPU_MANGLE_DEPRECATED 0 /* Allow use of deprecated OpenGL functions in this file */
#endif
-/* my interface */
-#include "intern/gpu_select_intern.h"
-
-/* my library */
-#include "GPU_safety.h"
+#include "GPU_select.h"
+#include "GPU_extensions.h"
-/* internal */
-#include "intern/gpu_matrix_intern.h"
-#include "intern/gpu_aspect_intern.h"
-
-/* external */
#include "BLI_utildefines.h"
-
-
-static bool IS_SELECT_MODE = false;
-
-
-
-void gpu_select_init(void)
-{
- IS_SELECT_MODE = false;
-}
-
-
-
-void gpu_select_exit(void)
-{
-}
-
-
-
-bool gpu_default_select_begin(const void* UNUSED(object), void* UNUSED(param))
+#include "MEM_guardedalloc.h"
+
+#include "DNA_userdef_types.h"
+
+#include <GL/glew.h>
+
+/* Ad hoc number of queries to allocate to skip doing many glGenQueries */
+#define ALLOC_QUERIES 200
+
+typedef struct GPUQueryState {
+ /* To ignore selection id calls when not initialized */
+ bool select_is_active;
+ /* Tracks whether a query has been issued so that gpu_load_id can end the previous one */
+ bool query_issued;
+ /* array holding the OpenGL query identifiers */
+ unsigned int *queries;
+ /* array holding the id corresponding to each query */
+ unsigned int *id;
+ /* number of queries in *queries and *id */
+ unsigned int num_of_queries;
+ /* index to the next query to start */
+ unsigned int active_query;
+ /* flag to cache user preference for occlusion based selection */
+ bool use_gpu_select;
+ /* cache on initialization */
+ unsigned int *buffer;
+ unsigned int bufsize;
+ /* mode of operation */
+ char mode;
+ unsigned int index;
+ int oldhits;
+} GPUQueryState;
+
+static GPUQueryState g_query_state = {0};
+
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, char mode, int oldhits)
{
-#if defined(WITH_GPU_PROFILE_COMPAT)
- return true; /* nothing to do, allow this pass to start */
-#else
- return false; /* not implemented, so cancel this pass before it starts if possible */
-#endif
+ g_query_state.select_is_active = true;
+ g_query_state.query_issued = false;
+ g_query_state.active_query = 0;
+ g_query_state.use_gpu_select = GPU_select_query_check_active();
+ g_query_state.num_of_queries = 0;
+ g_query_state.bufsize = bufsize;
+ g_query_state.buffer = buffer;
+ g_query_state.mode = mode;
+ g_query_state.index = 0;
+ g_query_state.oldhits = oldhits;
+
+ if (!g_query_state.use_gpu_select) {
+ glSelectBuffer( bufsize, (GLuint *)buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+ glPushName(-1);
+ }
+ else {
+ float viewport[4];
+
+ g_query_state.num_of_queries = ALLOC_QUERIES;
+
+ g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries) , "gpu selection queries");
+ g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id) , "gpu selection ids");
+ glGenQueriesARB(g_query_state.num_of_queries, g_query_state.queries);
+
+ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
+ /* disable writing to the framebuffer */
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ /* In order to save some fill rate we minimize the viewport using rect.
+ * We need to get the region of the scissor so that our geometry doesn't
+ * get rejected before the depth test. Should probably cull rect against
+ * scissor for viewport but this is a rare case I think */
+ glGetFloatv(GL_SCISSOR_BOX, viewport);
+ if (!input || input->xmin == input->xmax) {
+ glViewport(viewport[0], viewport[1], 24, 24);
+ }
+ else {
+ glViewport(viewport[0], viewport[1], (int)(input->xmax - input->xmin), (int)(input->ymax - input->ymin));
+ }
+
+ /* occlusion queries operates on fragments that pass tests and since we are interested on all
+ * objects in the view frustum independently of their order, we need to disable the depth test */
+ if (mode == GPU_SELECT_ALL) {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+ else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_LEQUAL);
+ }
+ else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_EQUAL);
+ }
+ }
}
-
-
-bool gpu_default_select_end(const void* UNUSED(object), void* UNUSED(param))
+bool GPU_select_load_id(unsigned int id)
{
- return true; /* only one pass, 'true' means 'done' */
-}
-
-
+ /* if no selection mode active, ignore */
+ if(!g_query_state.select_is_active)
+ return true;
-bool gpu_default_select_commit(const void* UNUSED(object))
-{
-#if defined(WITH_GPU_PROFILE_COMPAT)
- gpu_set_common(NULL);
- gpu_glUseProgram(0);
- gpu_commit_matrix();
+ if (!g_query_state.use_gpu_select) {
+ glLoadName(id);
+ }
+ else {
+ if (g_query_state.query_issued) {
+ glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ }
+ /* if required, allocate extra queries */
+ if (g_query_state.active_query == g_query_state.num_of_queries) {
+ g_query_state.num_of_queries += ALLOC_QUERIES;
+ g_query_state.queries = MEM_reallocN(g_query_state.queries, g_query_state.num_of_queries * sizeof(*g_query_state.queries));
+ g_query_state.id = MEM_reallocN(g_query_state.id, g_query_state.num_of_queries * sizeof(*g_query_state.id));
+ glGenQueriesARB(ALLOC_QUERIES, &g_query_state.queries[g_query_state.active_query]);
+ }
+
+ glBeginQueryARB(GL_SAMPLES_PASSED_ARB, g_query_state.queries[g_query_state.active_query]);
+ g_query_state.id[g_query_state.active_query] = id;
+ g_query_state.active_query++;
+ g_query_state.query_issued = true;
+
+ if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ if (g_query_state.buffer[g_query_state.index * 4 + 3] == id) {
+ g_query_state.index++;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ }
return true;
-#else
- return false; /* cancel drawing, since select mode isn't implemented */
-#endif
}
-
-
-bool gpu_is_select_mode(void)
-{
- return IS_SELECT_MODE;
-}
-
-
-
-void GPU_select_buffer(GLsizei size, GLuint* buffer)
+unsigned int GPU_select_end(void)
{
- GPU_ASSERT(!IS_SELECT_MODE);
-
- if (!IS_SELECT_MODE) {
-#if defined(WITH_GL_PROFILE_COMPAT)
- glSelectBuffer(size, buffer);
-#endif
+ unsigned int hits = 0;
+ if (!g_query_state.use_gpu_select) {
+ glPopName();
+ hits = glRenderMode(GL_RENDER);
}
-}
-
-
-
-void GPU_select_begin(void)
-{
- GPU_ASSERT(!gpu_aspect_active());
- GPU_ASSERT(!IS_SELECT_MODE);
-
- IS_SELECT_MODE = true;
-
-#if defined(WITH_GL_PROFILE_COMPAT)
- glRenderMode(GL_SELECT);
-#endif
-}
-
-
-
-GLsizei GPU_select_end(void)
-{
- GPU_ASSERT(!gpu_aspect_active());
- GPU_ASSERT(IS_SELECT_MODE);
-
- IS_SELECT_MODE = false;
-
-#if defined(WITH_GL_PROFILE_COMPAT)
- return glRenderMode(GL_RENDER);
-#else
- return 0;
-#endif
-}
-
-
-
-void GPU_select_clear(void)
-{
- if (IS_SELECT_MODE) {
-#if defined(WITH_GL_PROFILE_COMPAT)
- glInitNames();
-#endif
+ else {
+ int i;
+
+ if (g_query_state.query_issued) {
+ glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ }
+
+ for (i = 0; i < g_query_state.active_query; i++) {
+ unsigned int result;
+ glGetQueryObjectuivARB(g_query_state.queries[i], GL_QUERY_RESULT_ARB, &result);
+ if (result > 0) {
+ if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) {
+ if(hits < g_query_state.bufsize) {
+ g_query_state.buffer[hits * 4] = 1;
+ g_query_state.buffer[hits * 4 + 1] = 0xFFFF;
+ g_query_state.buffer[hits * 4 + 2] = 0xFFFF;
+ g_query_state.buffer[hits * 4 + 3] = g_query_state.id[i];
+
+ hits++;
+ }
+ else {
+ hits = -1;
+ break;
+ }
+ }
+ else {
+ int j;
+ /* search in buffer and make selected object first */
+ for (j = 0; j < g_query_state.oldhits; j++) {
+ if (g_query_state.buffer[j * 4 + 3] == g_query_state.id[i]) {
+ g_query_state.buffer[j * 4 + 1] = 0;
+ g_query_state.buffer[j * 4 + 2] = 0;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ glDeleteQueriesARB(g_query_state.num_of_queries, g_query_state.queries);
+ MEM_freeN(g_query_state.queries);
+ MEM_freeN(g_query_state.id);
+ glPopAttrib();
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
-}
+ g_query_state.select_is_active = false;
-
-void GPU_select_pop(void)
-{
- if (IS_SELECT_MODE) {
-#if defined(WITH_GL_PROFILE_COMPAT)
- glPopName();
-#endif
- }
+ return hits;
}
-
-void GPU_select_push(GLuint name)
+bool GPU_select_query_check_support(void)
{
- if (IS_SELECT_MODE) {
-#if defined(WITH_GL_PROFILE_COMPAT)
- glPushName(name);
-#endif
- }
+ return GLEW_ARB_occlusion_query;
}
-
-void GPU_select_load(GLuint name)
+bool GPU_select_query_check_active(void)
{
- if (IS_SELECT_MODE) {
-#if defined(WITH_GL_PROFILE_COMPAT)
- glLoadName(name);
-#endif
- }
+ return GLEW_ARB_occlusion_query &&
+ ((U.gpu_select_method == USER_SELECT_USE_OCCLUSION_QUERY) ||
+ ((U.gpu_select_method == USER_SELECT_AUTO) && GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)));
}
diff --git a/source/blender/gpu/intern/gpu_utility.c b/source/blender/gpu/intern/gpu_utility.c
index 999a44a91c1..285701af1aa 100644
--- a/source/blender/gpu/intern/gpu_utility.c
+++ b/source/blender/gpu/intern/gpu_utility.c
@@ -57,7 +57,7 @@ const char* gpuErrorString(GLenum err)
case GL_OUT_OF_MEMORY:
return "Out of Memory";
-#if GL_ARB_imagining
+#ifdef GL_ARB_imagining
case GL_TABLE_TOO_LARGE:
return "Table Too Large";
#endif
@@ -102,7 +102,7 @@ const char* gpuErrorSymbol(GLenum err)
case GL_OUT_OF_MEMORY:
return "GL_OUT_OF_MEMORY";
-#if GL_ARB_imagining
+#ifdef GL_ARB_imagining
case GL_TABLE_TOO_LARGE:
return "GL_TABLE_TOO_LARGE";
#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index d5d0c7ef454..3ba36c11311 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1012,6 +1012,38 @@ void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 i
incol.rgb = col.rgb;
}
+void mtex_rgb_soft(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ vec3 one = vec3(1.0);
+ vec3 scr = one - (one - texcol)*(one - outcol);
+ incol = facm*outcol + fact*((one - texcol)*outcol*texcol + outcol*scr);
+}
+
+void mtex_rgb_linear(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ fact *= facg;
+
+ if(texcol.r > 0.5)
+ incol.r = outcol.r + fact*(2.0*(texcol.r - 0.5));
+ else
+ incol.r = outcol.r + fact*(2.0*(texcol.r) - 1.0);
+
+ if(texcol.g > 0.5)
+ incol.g = outcol.g + fact*(2.0*(texcol.g - 0.5));
+ else
+ incol.g = outcol.g + fact*(2.0*(texcol.g) - 1.0);
+
+ if(texcol.b > 0.5)
+ incol.b = outcol.b + fact*(2.0*(texcol.b - 0.5));
+ else
+ incol.b = outcol.b + fact*(2.0*(texcol.b) - 1.0);
+}
+
void mtex_value_vars(inout float fact, float facg, out float facm)
{
fact *= abs(facg);
@@ -1179,7 +1211,12 @@ void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
void mtex_2d_mapping(vec3 vec, out vec3 outvec)
{
- outvec = vec3(vec.xy*0.5 + vec2(0.5, 0.5), vec.z);
+ outvec = vec3(vec.xy*0.5 + vec2(0.5), vec.z);
+}
+
+vec3 mtex_2d_mapping(vec3 vec)
+{
+ return vec3(vec.xy*0.5 + vec2(0.5), vec.z);
}
void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
@@ -2257,6 +2294,11 @@ void node_attribute(vec3 attr_uv, out vec4 outcol, out vec3 outvec, out float ou
outf = (attr_uv.x + attr_uv.y + attr_uv.z)/3.0;
}
+void node_uvmap(vec3 attr_uv, out vec3 outvec)
+{
+ outvec = attr_uv;
+}
+
void node_geometry(vec3 I, vec3 N, mat4 toworld,
out vec3 position, out vec3 normal, out vec3 tangent,
out vec3 true_normal, out vec3 incoming, out vec3 parametric,
@@ -2280,14 +2322,18 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- generated = attr_orco;
+ generated = mtex_2d_mapping(attr_orco);
normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz);
uv = attr_uv;
object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz;
camera = I;
- window = gl_FragCoord.xyz;
- reflection = reflect(N, I);
+ vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
+ window = mtex_2d_mapping(projvec.xyz/projvec.w);
+ vec3 shade_I;
+ shade_view(I, shade_I);
+ vec3 view_reflection = reflect(shade_I, normalize(N));
+ reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
}
/* textures */
diff --git a/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
new file mode 100644
index 00000000000..8ccd0feb5e2
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
@@ -0,0 +1,54 @@
+
+#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
+varying vec3 varying_normal;
+
+#ifndef USE_SOLID_LIGHTING
+varying vec3 varying_position;
+#endif
+#endif
+
+#ifdef USE_COLOR
+varying vec4 varying_vertex_color;
+#endif
+
+#ifdef USE_TEXTURE
+varying vec2 varying_texture_coord;
+#endif
+
+#ifdef CLIP_WORKAROUND
+varying float gl_ClipDistance[6];
+#endif
+
+void main()
+{
+ vec4 co = gl_ModelViewMatrix * gl_Vertex;
+
+#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
+ varying_normal = normalize(gl_NormalMatrix * gl_Normal);
+
+#ifndef USE_SOLID_LIGHTING
+ varying_position = co.xyz;
+#endif
+#endif
+
+ gl_Position = gl_ProjectionMatrix * co;
+
+#ifdef CLIP_WORKAROUND
+ int i;
+ for(i = 0; i < 6; i++)
+ gl_ClipDistance[i] = dot(co, gl_ClipPlane[i]);
+#elif !defined(GPU_ATI)
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
+ // graphic cards, while on ATI it can cause a software fallback.
+ gl_ClipVertex = co;
+#endif
+
+#ifdef USE_COLOR
+ varying_vertex_color = gl_Color;
+#endif
+
+#ifdef USE_TEXTURE
+ varying_texture_coord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st;
+#endif
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index 159e531eb44..b5d8dcc0f35 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -2,6 +2,10 @@
varying vec3 varposition;
varying vec3 varnormal;
+#ifdef CLIP_WORKAROUND
+varying float gl_ClipDistance[6];
+#endif
+
void main()
{
vec4 co = gl_ModelViewMatrix * gl_Vertex;
@@ -10,9 +14,13 @@ void main()
varnormal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ProjectionMatrix * co;
-#ifndef GPU_ATI
+#ifdef CLIP_WORKAROUND
+ int i;
+ for(i = 0; i < 6; i++)
+ gl_ClipDistance[i] = dot(co, gl_ClipPlane[i]);
+#elif !defined(GPU_ATI)
// Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
// graphic cards, while on ATI it can cause a software fallback.
- gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
+ gl_ClipVertex = co;
#endif