diff options
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_basic_shader.h | 6 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_basic_shader.c | 65 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_basic_frag.glsl | 14 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_basic_geom.glsl | 100 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_basic_vert.glsl | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_gesture.c | 44 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_subwindow.c | 1 |
9 files changed, 210 insertions, 31 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 3b228c18f5e..cfa083116f2 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -73,6 +73,7 @@ set(SRC shaders/gpu_shader_sep_gaussian_blur_vert.glsl shaders/gpu_shader_basic_frag.glsl shaders/gpu_shader_basic_vert.glsl + shaders/gpu_shader_basic_geom.glsl shaders/gpu_shader_vertex.glsl shaders/gpu_shader_vsm_store_frag.glsl shaders/gpu_shader_vsm_store_vert.glsl @@ -105,6 +106,7 @@ data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_basic_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_basic_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_basic_geom.glsl SRC) data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC) data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC) data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_basic_shader.h b/source/blender/gpu/GPU_basic_shader.h index f376850a8f9..df2da971845 100644 --- a/source/blender/gpu/GPU_basic_shader.h +++ b/source/blender/gpu/GPU_basic_shader.h @@ -33,6 +33,7 @@ #define __GPU_BASIC_SHADER_H__ #include "BLI_utildefines.h" +#include "GPU_glew.h" #ifdef __cplusplus extern "C" { @@ -48,7 +49,8 @@ typedef enum GPUBasicShaderOption { GPU_SHADER_SOLID_LIGHTING = (1 << 4), /* use faster lighting (set automatically) */ GPU_SHADER_STIPPLE = (1 << 5), /* use stipple */ - GPU_SHADER_OPTIONS_NUM = 6, + GPU_SHADER_LINE = (1 << 6), /* draw lines */ + GPU_SHADER_OPTIONS_NUM = 7, GPU_SHADER_OPTION_COMBINATIONS = (1 << GPU_SHADER_OPTIONS_NUM) } GPUBasicShaderOption; @@ -105,6 +107,8 @@ typedef struct GPULightData { void GPU_basic_shader_light_set(int light_num, GPULightData *light); void GPU_basic_shader_light_set_viewer(bool local); void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id); +void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern); +void GPU_basic_shader_line_width(float line_width); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c index 4a27965aee1..abaf1944302 100644 --- a/source/blender/gpu/intern/gpu_basic_shader.c +++ b/source/blender/gpu/intern/gpu_basic_shader.c @@ -61,6 +61,8 @@ static struct { int lights_enabled; int lights_directional; + float line_width; + GLint viewport[4]; } GPU_MATERIAL_STATE; @@ -325,6 +327,8 @@ static GPUShader *gpu_basic_shader(int options) /* glsl code */ extern char datatoc_gpu_shader_basic_vert_glsl[]; extern char datatoc_gpu_shader_basic_frag_glsl[]; + extern char datatoc_gpu_shader_basic_geom_glsl[]; + char *geom_glsl = NULL; GPUShader *shader; /* detect if we can do faster lighting for solid draw mode */ @@ -347,7 +351,10 @@ static GPUShader *gpu_basic_shader(int options) strcat(defines, "#define USE_TEXTURE\n"); if (options & GPU_SHADER_STIPPLE) strcat(defines, "#define USE_STIPPLE\n"); - + if (options & GPU_SHADER_LINE) { + strcat(defines, "#define DRAW_LINE\n"); + geom_glsl = datatoc_gpu_shader_basic_geom_glsl; + } if (options & GPU_SHADER_SOLID_LIGHTING) strcat(defines, "#define USE_SOLID_LIGHTING\n"); else if (options & GPU_SHADER_LIGHTING) @@ -356,7 +363,7 @@ static GPUShader *gpu_basic_shader(int options) shader = GPU_shader_create( datatoc_gpu_shader_basic_vert_glsl, datatoc_gpu_shader_basic_frag_glsl, - NULL, + geom_glsl, NULL, defines, 0, 0, 0); @@ -377,6 +384,15 @@ static GPUShader *gpu_basic_shader(int options) return shader; } +static void GPU_basic_shader_uniform_autoset(GPUShader *shader, int options) +{ + if (options & GPU_SHADER_LINE) { + glGetIntegerv(GL_VIEWPORT, &GPU_MATERIAL_STATE.viewport[0]); + glUniform4iv(GPU_shader_get_uniform(shader, "viewport"), 1, &GPU_MATERIAL_STATE.viewport[0]); + glUniform1f(GPU_shader_get_uniform(shader, "line_width"), GPU_MATERIAL_STATE.line_width); + } +} + /* Bind / unbind */ void GPU_basic_shader_bind(int options) @@ -385,8 +401,10 @@ void GPU_basic_shader_bind(int options) if (options) { GPUShader *shader = gpu_basic_shader(options); - if (shader) + if (shader) { GPU_shader_bind(shader); + GPU_basic_shader_uniform_autoset(shader, options); + } } else { GPU_shader_unbind(); @@ -424,10 +442,19 @@ void GPU_basic_shader_bind(int options) glDisable(GL_TEXTURE_2D); } - if (options & GPU_SHADER_STIPPLE) - glEnable(GL_POLYGON_STIPPLE); - else if (bound_options & GPU_SHADER_STIPPLE) - glDisable(GL_POLYGON_STIPPLE); + if (options & GPU_SHADER_LINE) { + if (options & GPU_SHADER_STIPPLE) + glEnable(GL_LINE_STIPPLE); + else if (bound_options & GPU_SHADER_STIPPLE) + glDisable(GL_LINE_STIPPLE); + } + else { + if (options & GPU_SHADER_STIPPLE) + glEnable(GL_POLYGON_STIPPLE); + else if (bound_options & GPU_SHADER_STIPPLE) + glDisable(GL_POLYGON_STIPPLE); + } + } GPU_MATERIAL_STATE.bound_options = options; @@ -592,3 +619,27 @@ void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id) } } } + +void GPU_basic_shader_line_width(float line_width) +{ + if (USE_GLSL) { + GPU_MATERIAL_STATE.line_width = line_width; + if (GPU_MATERIAL_STATE.bound_options & GPU_SHADER_LINE) { + glUniform1f(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "line_width"), line_width); + } + } + else { + glLineWidth(line_width); + } +} + +void GPU_basic_shader_line_stipple(GLint stipple_factor, GLushort stipple_pattern) +{ + if (USE_GLSL) { + glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_factor"), stipple_factor); + glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_pattern"), stipple_pattern); + } + else { + glLineStipple(stipple_factor, stipple_pattern); + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl index 7b4df51c12d..c7b29ee5707 100644 --- a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl @@ -45,11 +45,20 @@ uniform sampler2D texture_map; #ifdef USE_STIPPLE uniform int stipple_id; +#if defined(DRAW_LINE) +varying in float t; +uniform int stipple_pattern; +#endif #endif void main() { #if defined(USE_STIPPLE) +#if defined(DRAW_LINE) + /* GLSL 1.3 */ + if (!bool((1 << int(mod(t, 16))) & stipple_pattern)) + discard; +#else /* We have to use mod function and integer casting. * This can be optimized further with the bitwise operations * when GLSL 1.3 is supported. */ @@ -123,9 +132,8 @@ void main() discard; } } - - -#endif +#endif /* !DRAW_LINE */ +#endif /* USE_STIPPLE */ #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) /* compute normal */ diff --git a/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl new file mode 100644 index 00000000000..ffd747ab1eb --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl @@ -0,0 +1,100 @@ +/* +* Used the implementation of wide lines of Timo Suoranta (http://neure.dy.fi/wideline.html) +*/ + +#define PASSTHROUGH 0 + +layout(lines) in; + +#if defined(DRAW_LINE) + +#if PASSTHROUGH +layout(line_strip, max_vertices = 10) out; +#else +layout(triangle_strip, max_vertices = 6) out; +#endif + +varying out float t; +varying in vec4 varying_vertex_color_line[]; +varying out vec4 varying_vertex_color; + +uniform ivec4 viewport; +uniform float line_width; +uniform int stipple_factor; + +void main(void) +{ + vec2 window_size = viewport.zw; + vec4 start = gl_in[0].gl_Position; + vec4 end = gl_in[1].gl_Position; +#if PASSTHROUGH + gl_Position = start; EmitVertex(); + gl_Position = end; EmitVertex(); + EndPrimitive(); + return; +#endif + +/* t = 0 t = ~(len(end - start) + 2*line_width) + * A-------------------------------------B + * | | | | + * | side | | + * | | | | + * |--axis--*start--------------*end-----| + * | | | | + * | | | | + * | | | | + * D-------------------------------------C + */ + + /* Clip the line before homogenization. + * Compute line start and end distances to nearplane in clipspace + * Distances are t0 = dot(start, plane) and t1 = dot(end, plane) + */ + float t0 = start.z + start.w; + float t1 = end.z + end.w; + if(t0 < 0.0) { + if(t1 < 0.0) { + return; + } + start = mix(start, end, (0 - t0) / (t1 - t0)); + } + if(t1 < 0.0) { + end = mix(start, end, (0 - t0) / (t1 - t0)); + } + + /* Compute line axis and side vector in screen space */ + vec2 startInNDC = start.xy / start.w; /* clip to NDC: homogenize and drop z */ + vec2 endInNDC = end.xy / end.w; + vec2 lineInNDC = endInNDC - startInNDC; + vec2 lineInScreen = lineInNDC * window_size; /* ndc to screen (direction vector) */ + + vec2 axisInScreen = normalize(lineInScreen); + vec2 sideInScreen = vec2(-axisInScreen.y, axisInScreen.x); /* rotate */ + vec2 axisInNDC = axisInScreen / window_size; /* screen to NDC */ + vec2 sideInNDC = sideInScreen / window_size; + vec4 axis = vec4(axisInNDC, 0.0, 0.0) * line_width; /* NDC to clip (delta vector) */ + vec4 side = vec4(sideInNDC, 0.0, 0.0) * line_width; + + vec4 A = (start + (side - axis) * start.w); + vec4 B = (end + (side + axis) * end.w); + vec4 C = (end - (side - axis) * end.w); + vec4 D = (start - (side + axis) * start.w); + + /* There is no relation between lines yet */ + /* TODO Pass here t0 to make continuous pattern. */ + t0 = 0; + t1 = (length(lineInScreen) + 2*line_width)/ (2*line_width * stipple_factor); + + gl_Position = A; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex(); + gl_Position = D; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex(); + gl_Position = B; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex(); + gl_Position = C; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex(); + EndPrimitive(); +} + +#else +void main(void) +{ + +} +#endif diff --git a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl index 8ccd0feb5e2..04900001998 100644 --- a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl @@ -8,8 +8,12 @@ varying vec3 varying_position; #endif #ifdef USE_COLOR +#ifdef DRAW_LINE +varying vec4 varying_vertex_color_line; +#else varying vec4 varying_vertex_color; #endif +#endif #ifdef USE_TEXTURE varying vec2 varying_texture_coord; @@ -44,8 +48,12 @@ void main() #endif #ifdef USE_COLOR +#ifdef DRAW_LINE + varying_vertex_color_line = gl_Color; +#else varying_vertex_color = gl_Color; #endif +#endif #ifdef USE_TEXTURE varying_texture_coord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index d20cffe9382..f8a879d0485 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -59,6 +59,7 @@ #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_glew.h" +#include "GPU_basic_shader.h" #include "RE_engine.h" diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 92c9b81cdef..26d1d4c3266 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -51,6 +51,7 @@ #include "wm.h" #include "wm_subwindow.h" #include "wm_draw.h" +#include "GPU_basic_shader.h" #include "BIF_glutil.h" @@ -180,29 +181,29 @@ static void wm_gesture_draw_rect(wmGesture *gt) glEnd(); glDisable(GL_BLEND); - glEnable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); glColor3ub(96, 96, 96); - glLineStipple(1, 0xCCCC); + GPU_basic_shader_line_stipple(1, 0xCCCC); sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); glColor3ub(255, 255, 255); - glLineStipple(1, 0x3333); + GPU_basic_shader_line_stipple(1, 0x3333); sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); - glDisable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); } static void wm_gesture_draw_line(wmGesture *gt) { rcti *rect = (rcti *)gt->customdata; - glEnable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); glColor3ub(96, 96, 96); - glLineStipple(1, 0xAAAA); + GPU_basic_shader_line_stipple(1, 0xAAAA); sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax); glColor3ub(255, 255, 255); - glLineStipple(1, 0x5555); + GPU_basic_shader_line_stipple(1, 0x5555); sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax); - glDisable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); } @@ -217,15 +218,16 @@ static void wm_gesture_draw_circle(wmGesture *gt) glutil_draw_filled_arc(0.0, M_PI * 2.0, rect->xmax, 40); glDisable(GL_BLEND); - glEnable(GL_LINE_STIPPLE); + // for USE_GLSL works bad because of no relation between lines + GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); glColor3ub(96, 96, 96); - glLineStipple(1, 0xAAAA); + GPU_basic_shader_line_stipple(1, 0xAAAA); glutil_draw_lined_arc(0.0, M_PI * 2.0, rect->xmax, 40); glColor3ub(255, 255, 255); - glLineStipple(1, 0x5555); + GPU_basic_shader_line_stipple(1, 0x5555); glutil_draw_lined_arc(0.0, M_PI * 2.0, rect->xmax, 40); - glDisable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); glTranslatef(-rect->xmin, -rect->ymin, 0.0f); } @@ -303,9 +305,10 @@ static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled) draw_filled_lasso(win, gt); } - glEnable(GL_LINE_STIPPLE); + // for USE_GLSL can't check this yet + GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); glColor3ub(96, 96, 96); - glLineStipple(1, 0xAAAA); + GPU_basic_shader_line_stipple(1, 0xAAAA); glBegin(GL_LINE_STRIP); for (i = 0; i < gt->points; i++, lasso += 2) glVertex2sv(lasso); @@ -314,7 +317,7 @@ static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled) glEnd(); glColor3ub(255, 255, 255); - glLineStipple(1, 0x5555); + GPU_basic_shader_line_stipple(1, 0x5555); glBegin(GL_LINE_STRIP); lasso = (short *)gt->customdata; for (i = 0; i < gt->points; i++, lasso += 2) @@ -323,7 +326,7 @@ static void wm_gesture_draw_lasso(wmWindow *win, wmGesture *gt, bool filled) glVertex2sv((short *)gt->customdata); glEnd(); - glDisable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); } @@ -333,17 +336,17 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) const int winsize_x = WM_window_pixels_x(win); const int winsize_y = WM_window_pixels_y(win); - glEnable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_LINE | GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); glColor3ub(96, 96, 96); - glLineStipple(1, 0xCCCC); + GPU_basic_shader_line_stipple(1, 0xCCCC); sdrawline(rect->xmin - winsize_x, rect->ymin, rect->xmin + winsize_x, rect->ymin); sdrawline(rect->xmin, rect->ymin - winsize_y, rect->xmin, rect->ymin + winsize_y); glColor3ub(255, 255, 255); - glLineStipple(1, 0x3333); + GPU_basic_shader_line_stipple(1, 0x3333); sdrawline(rect->xmin - winsize_x, rect->ymin, rect->xmin + winsize_x, rect->ymin); sdrawline(rect->xmin, rect->ymin - winsize_y, rect->xmin, rect->ymin + winsize_y); - glDisable(GL_LINE_STIPPLE); + GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); } /* called in wm_draw.c */ @@ -351,6 +354,7 @@ void wm_gesture_draw(wmWindow *win) { wmGesture *gt = (wmGesture *)win->gesture.first; + GPU_basic_shader_line_width(1); for (; gt; gt = gt->next) { /* all in subwindow space */ wmSubWindowSet(win, gt->swinid); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 243f7467f25..6526d419914 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -48,6 +48,7 @@ #include "BIF_gl.h" #include "GPU_extensions.h" +#include "GPU_basic_shader.h" #include "WM_api.h" #include "wm_subwindow.h" |