diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 9 | ||||
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_immediate.h | 11 | ||||
-rw-r--r-- | source/blender/gpu/GPU_select.h | 50 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 156 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 8 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 32 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_extensions.c | 58 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_immediate.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_matrix.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_raster.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_select.c | 330 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_utility.c | 4 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 54 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_simple_vert.glsl | 54 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_vertex.glsl | 12 |
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 |