From a27b54f6e29fbf37aa21f7fe7dca41804d3f4442 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 16 Sep 2016 12:25:40 +0200 Subject: [PATCH] OpenSubdiv: Split shader source files Was a bit annoying to do tweaks in a file which contained all vertex, geometry and fragment shaders. --- intern/opensubdiv/CMakeLists.txt | 4 +- ...sl => gpu_shader_opensubdiv_fragment.glsl} | 166 ------------------ .../gpu_shader_opensubdiv_geometry.glsl | 165 +++++++++++++++++ .../gpu_shader_opensubdiv_vertex.glsl | 53 ++++++ intern/opensubdiv/opensubdiv_gpu_capi.cc | 20 ++- 5 files changed, 234 insertions(+), 174 deletions(-) rename intern/opensubdiv/{gpu_shader_opensubd_display.glsl => gpu_shader_opensubdiv_fragment.glsl} (56%) create mode 100644 intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl create mode 100644 intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index f8e80de7f8f..876b5c0181f 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -64,7 +64,9 @@ OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE) -data_to_c_simple(gpu_shader_opensubd_display.glsl SRC) +data_to_c_simple(gpu_shader_opensubdiv_vertex.glsl SRC) +data_to_c_simple(gpu_shader_opensubdiv_geometry.glsl SRC) +data_to_c_simple(gpu_shader_opensubdiv_fragment.glsl SRC) add_definitions(-DGLEW_STATIC) diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl similarity index 56% rename from intern/opensubdiv/gpu_shader_opensubd_display.glsl rename to intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl index 5193d3a71dc..1e36d549360 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl @@ -29,170 +29,6 @@ struct VertexData { vec2 uv; }; -#ifdef VERTEX_SHADER // --------------------- - -in vec3 normal; -in vec4 position; - -uniform mat4 modelViewMatrix; -uniform mat3 normalMatrix; - -out block { - VertexData v; -} outpt; - -void main() -{ - outpt.v.position = modelViewMatrix * position; - outpt.v.normal = normalize(normalMatrix * normal); - -#if __VERSION__ < 140 - /* Some compilers expects gl_Position to be written. - * It's not needed once we explicitly switch to GLSL 1.40 or above. - */ - gl_Position = outpt.v.position; -#endif -} - -#elif defined GEOMETRY_SHADER // --------------------- - -#if __VERSION__ >= 150 - layout(lines_adjacency) in; - #ifdef WIREFRAME - layout(line_strip, max_vertices = 8) out; - #else - layout(triangle_strip, max_vertices = 4) out; - #endif -#else - #extension GL_EXT_geometry_shader4: require - /* application provides input/output layout info */ -#endif - -#if __VERSION__ < 140 - #extension GL_ARB_uniform_buffer_object: require - #extension GL_ARB_texture_buffer_object: enable - #extension GL_EXT_texture_buffer_object: enable -#endif - -uniform mat4 modelViewMatrix; -uniform mat4 projectionMatrix; -uniform int PrimitiveIdBase; -uniform int osd_fvar_count; -uniform int osd_active_uv_offset; - -in block { - VertexData v; -} inpt[]; - -#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \ - { \ - vec2 v[4]; \ - int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \ - for (int i = 0; i < 4; ++i) { \ - int index = (primOffset + i) * osd_fvar_count + fvarOffset; \ - v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \ - texelFetch(FVarDataBuffer, index + 1).s); \ - } \ - result = mix(mix(v[0], v[1], tessCoord.s), \ - mix(v[3], v[2], tessCoord.s), \ - tessCoord.t); \ - } - -uniform samplerBuffer FVarDataBuffer; -uniform isamplerBuffer FVarDataOffsetBuffer; - -out block { - VertexData v; -} outpt; - -#ifdef FLAT_SHADING -void emit(int index, vec3 normal) -{ - outpt.v.position = inpt[index].v.position; - outpt.v.normal = normal; - - /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); - vec2 st = quadst[index]; - - INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); - - gl_Position = projectionMatrix * inpt[index].v.position; - EmitVertex(); -} - -# ifdef WIREFRAME -void emit_edge(int v0, int v1, vec3 normal) -{ - emit(v0, normal); - emit(v1, normal); -} -# endif - -#else -void emit(int index) -{ - outpt.v.position = inpt[index].v.position; - outpt.v.normal = inpt[index].v.normal; - - /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); - vec2 st = quadst[index]; - - INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); - - gl_Position = projectionMatrix * inpt[index].v.position; - EmitVertex(); -} - -# ifdef WIREFRAME -void emit_edge(int v0, int v1) -{ - emit(v0); - emit(v1); -} -# endif - -#endif - -void main() -{ - gl_PrimitiveID = gl_PrimitiveIDIn; - -#ifdef FLAT_SHADING - vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz; - vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz; - vec3 flat_normal = normalize(cross(B, A)); -# ifndef WIREFRAME - emit(0, flat_normal); - emit(1, flat_normal); - emit(3, flat_normal); - emit(2, flat_normal); -# else - emit_edge(0, 1, flat_normal); - emit_edge(1, 2, flat_normal); - emit_edge(2, 3, flat_normal); - emit_edge(3, 0, flat_normal); -# endif -#else -# ifndef WIREFRAME - emit(0); - emit(1); - emit(3); - emit(2); -# else - emit_edge(0, 1); - emit_edge(1, 2); - emit_edge(2, 3); - emit_edge(3, 0); -# endif -#endif - - EndPrimitive(); -} - -#elif defined FRAGMENT_SHADER // --------------------- - #define MAX_LIGHTS 8 #define NUM_SOLID_LIGHTS 3 @@ -334,5 +170,3 @@ void main() gl_FragColor = vec4(L, diffuse.a); #endif } - -#endif // --------------------- diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl new file mode 100644 index 00000000000..3a83d44a8be --- /dev/null +++ b/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl @@ -0,0 +1,165 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * 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) 2014 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct VertexData { + vec4 position; + vec3 normal; + vec2 uv; +}; + +#if __VERSION__ >= 150 +layout(lines_adjacency) in; + #ifdef WIREFRAME +layout(line_strip, max_vertices = 8) out; + #else +layout(triangle_strip, max_vertices = 4) out; + #endif +#else + #extension GL_EXT_geometry_shader4: require + /* application provides input/output layout info */ +#endif + +#if __VERSION__ < 140 + #extension GL_ARB_uniform_buffer_object: require + #extension GL_ARB_texture_buffer_object: enable + #extension GL_EXT_texture_buffer_object: enable +#endif + +uniform mat4 modelViewMatrix; +uniform mat4 projectionMatrix; +uniform int PrimitiveIdBase; +uniform int osd_fvar_count; +uniform int osd_active_uv_offset; + +in block { + VertexData v; +} inpt[]; + +#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \ + { \ + vec2 v[4]; \ + int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \ + for (int i = 0; i < 4; ++i) { \ + int index = (primOffset + i) * osd_fvar_count + fvarOffset; \ + v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \ + texelFetch(FVarDataBuffer, index + 1).s); \ + } \ + result = mix(mix(v[0], v[1], tessCoord.s), \ + mix(v[3], v[2], tessCoord.s), \ + tessCoord.t); \ + } + +uniform samplerBuffer FVarDataBuffer; +uniform isamplerBuffer FVarDataOffsetBuffer; + +out block { + VertexData v; +} outpt; + +#ifdef FLAT_SHADING +void emit(int index, vec3 normal) +{ + outpt.v.position = inpt[index].v.position; + outpt.v.normal = normal; + + /* TODO(sergey): Only uniform subdivisions atm. */ + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); + vec2 st = quadst[index]; + + INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); + + gl_Position = projectionMatrix * inpt[index].v.position; + EmitVertex(); +} + +# ifdef WIREFRAME +void emit_edge(int v0, int v1, vec3 normal) +{ + emit(v0, normal); + emit(v1, normal); +} +# endif + +#else +void emit(int index) +{ + outpt.v.position = inpt[index].v.position; + outpt.v.normal = inpt[index].v.normal; + + /* TODO(sergey): Only uniform subdivisions atm. */ + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); + vec2 st = quadst[index]; + + INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); + + gl_Position = projectionMatrix * inpt[index].v.position; + EmitVertex(); +} + +# ifdef WIREFRAME +void emit_edge(int v0, int v1) +{ + emit(v0); + emit(v1); +} +# endif + +#endif + +void main() +{ + gl_PrimitiveID = gl_PrimitiveIDIn; + +#ifdef FLAT_SHADING + vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz; + vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz; + vec3 flat_normal = normalize(cross(B, A)); +# ifndef WIREFRAME + emit(0, flat_normal); + emit(1, flat_normal); + emit(3, flat_normal); + emit(2, flat_normal); +# else + emit_edge(0, 1, flat_normal); + emit_edge(1, 2, flat_normal); + emit_edge(2, 3, flat_normal); + emit_edge(3, 0, flat_normal); +# endif +#else +# ifndef WIREFRAME + emit(0); + emit(1); + emit(3); + emit(2); +# else + emit_edge(0, 1); + emit_edge(1, 2); + emit_edge(2, 3); + emit_edge(3, 0); +# endif +#endif + + EndPrimitive(); +} diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl new file mode 100644 index 00000000000..6d3c06f59c9 --- /dev/null +++ b/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl @@ -0,0 +1,53 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * 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) 2014 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct VertexData { + vec4 position; + vec3 normal; + vec2 uv; +}; + +in vec3 normal; +in vec4 position; + +uniform mat4 modelViewMatrix; +uniform mat3 normalMatrix; + +out block { + VertexData v; +} outpt; + +void main() +{ + outpt.v.position = modelViewMatrix * position; + outpt.v.normal = normalize(normalMatrix * normal); + +#if __VERSION__ < 140 + /* Some compilers expects gl_Position to be written. + * It's not needed once we explicitly switch to GLSL 1.40 or above. + */ + gl_Position = outpt.v.position; +#endif +} diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc index 05bd3728f93..da4a937540d 100644 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc @@ -49,7 +49,9 @@ using OpenSubdiv::Osd::GLMeshInterface; -extern "C" char datatoc_gpu_shader_opensubd_display_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[]; /* TODO(sergey): This is bit of bad level calls :S */ extern "C" { @@ -208,7 +210,8 @@ namespace { GLuint compileShader(GLenum shaderType, const char *section, const char *version, - const char *define) + const char *define, + const char *source) { char sdefine[64]; sprintf(sdefine, "#define %s\n", section); @@ -220,7 +223,7 @@ GLuint compileShader(GLenum shaderType, #ifdef SUPPORT_COLOR_MATERIAL "#define SUPPORT_COLOR_MATERIAL\n", #endif - datatoc_gpu_shader_opensubd_display_glsl + source, }; GLuint shader = glCreateShader(shaderType); @@ -235,7 +238,7 @@ GLuint compileShader(GLenum shaderType, fprintf(stderr, "Error compiling GLSL %s: %s\n", section, emsg); fprintf(stderr, "Version: %s\n", version); fprintf(stderr, "Defines: %s\n", define); - fprintf(stderr, "Source: %s\n", datatoc_gpu_shader_opensubd_display_glsl); + fprintf(stderr, "Source: %s\n", source); return 0; } @@ -247,21 +250,24 @@ GLuint linkProgram(const char *version, const char *define) GLuint vertexShader = compileShader(GL_VERTEX_SHADER, "VERTEX_SHADER", version, - define); + define, + datatoc_gpu_shader_opensubdiv_vertex_glsl); if (vertexShader == 0) { return 0; } GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, "GEOMETRY_SHADER", version, - define); + define, + datatoc_gpu_shader_opensubdiv_geometry_glsl); if (geometryShader == 0) { return 0; } GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, "FRAGMENT_SHADER", version, - define); + define, + datatoc_gpu_shader_opensubdiv_fragment_glsl ); if (fragmentShader == 0) { return 0; }