diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl index 110898ad917..e343c952944 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl @@ -215,8 +215,6 @@ uniform vec4 specular; uniform float shininess; uniform sampler2D texture_buffer; -uniform bool use_color_material; -uniform bool use_texture_2d; in block { VertexData v; @@ -236,99 +234,89 @@ void main() vec3 L_diffuse = vec3(0.0); vec3 L_specular = vec3(0.0); - if (use_color_material == false) { - /* Assume NUM_SOLID_LIGHTS directional lights. */ - for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { - vec3 light_direction = lightSource[i].position.xyz; - - /* Diffuse light. */ - vec3 light_diffuse = lightSource[i].diffuse.rgb; - float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse * diffuse_bsdf; - - /* Specular light. */ - vec4 Plight = lightSource[i].position; - vec3 l = (Plight.w == 0.0) - ? normalize(Plight.xyz) : normalize(Plight.xyz - - inpt.v.position.xyz); - vec3 light_specular = lightSource[i].specular.rgb; - vec3 H = normalize(l + vec3(0,0,1)); - float specular_bsdf = pow(max(dot(N, H), 0.0), - shininess); - L_specular += light_specular * specular_bsdf; - } +#ifndef USE_COLOR_MATERIAL + /* Assume NUM_SOLID_LIGHTS directional lights. */ + for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { + vec4 Plight = lightSource[i].position; +#ifdef USE_DIRECTIONAL_LIGHT + vec3 l = (Plight.w == 0.0) + ? normalize(Plight.xyz) + : normalize(inpt.v.position.xyz); +#else /* USE_DIRECTIONAL_LIGHT */ + /* TODO(sergey): We can normalize it outside of the shader. */ + vec3 l = normalize(Plight.xyz); +#endif /* USE_DIRECTIONAL_LIGHT */ + vec3 h = normalize(l + vec3(0, 0, 1)); + float d = max(0.0, dot(N, l)); + float s = pow(max(0.0, dot(N, h)), 500.0f); + L_diffuse += d * lightSource[i].diffuse; + L_specular += s * lightSource[i].specular; } - else { - vec3 varying_position = inpt.v.position.xyz; - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? - normalize(varying_position): vec3(0.0, 0.0, -1.0); - for (int i = 0; i < num_enabled_lights; i++) { - /* todo: this is a slow check for disabled lights */ - if (lightSource[i].specular.a == 0.0) - continue; +#else /* USE_COLOR_MATERIAL */ + vec3 varying_position = inpt.v.position.xyz; + vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? + normalize(varying_position): vec3(0.0, 0.0, -1.0); + for (int i = 0; i < num_enabled_lights; i++) { + /* todo: this is a slow check for disabled lights */ + if (lightSource[i].specular.a == 0.0) + continue; - float intensity = 1.0; - vec3 light_direction; + float intensity = 1.0; + vec3 light_direction; - if (lightSource[i].position.w == 0.0) { - /* directional light */ - light_direction = lightSource[i].position.xyz; - } - else { - /* point light */ - vec3 d = lightSource[i].position.xyz - varying_position; - light_direction = normalize(d); + if (lightSource[i].position.w == 0.0) { + /* directional light */ + light_direction = lightSource[i].position.xyz; + } + else { + /* point light */ + vec3 d = lightSource[i].position.xyz - varying_position; + light_direction = normalize(d); - /* spot light cone */ - if (lightSource[i].spotCutoff < 90.0) { - float cosine = max(dot(light_direction, - -lightSource[i].spotDirection.xyz), - 0.0); - intensity = pow(cosine, lightSource[i].spotExponent); - intensity *= step(lightSource[i].spotCosCutoff, cosine); - } - - /* falloff */ - float distance = length(d); - - intensity /= lightSource[i].constantAttenuation + - lightSource[i].linearAttenuation * distance + - lightSource[i].quadraticAttenuation * distance * distance; + /* spot light cone */ + if (lightSource[i].spotCutoff < 90.0) { + float cosine = max(dot(light_direction, + -lightSource[i].spotDirection.xyz), + 0.0); + intensity = pow(cosine, lightSource[i].spotExponent); + intensity *= step(lightSource[i].spotCosCutoff, cosine); } - /* diffuse light */ - vec3 light_diffuse = lightSource[i].diffuse.rgb; - float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse*diffuse_bsdf*intensity; + /* falloff */ + float distance = length(d); - /* specular light */ - vec3 light_specular = lightSource[i].specular.rgb; - vec3 H = normalize(light_direction - V); - - float specular_bsdf = pow(max(dot(N, H), 0.0), - gl_FrontMaterial.shininess); - L_specular += light_specular*specular_bsdf * intensity; + intensity /= lightSource[i].constantAttenuation + + lightSource[i].linearAttenuation * distance + + lightSource[i].quadraticAttenuation * distance * distance; } + + /* diffuse light */ + vec3 light_diffuse = lightSource[i].diffuse.rgb; + float diffuse_bsdf = max(dot(N, light_direction), 0.0); + L_diffuse += light_diffuse*diffuse_bsdf*intensity; + + /* specular light */ + vec3 light_specular = lightSource[i].specular.rgb; + vec3 H = normalize(light_direction - V); + + float specular_bsdf = pow(max(dot(N, H), 0.0), + gl_FrontMaterial.shininess); + L_specular += light_specular*specular_bsdf * intensity; } +#endif /* USE_COLOR_MATERIAL */ /* Compute diffuse color. */ - float alpha; - if (use_texture_2d) { - L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; - } - else { - L_diffuse *= diffuse.rgb; - } - alpha = diffuse.a; +#ifdef USE_TEXTURE_2D + L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; +#else + L_diffuse *= diffuse.rgb; +#endif /* Sum lighting. */ - vec3 L = /*gl_FrontLightModelProduct.sceneColor.rgb +*/ L_diffuse; - if (shininess != 0.0f) { - L += L_specular * specular.rgb; - } + vec3 L = L_diffuse + L_specular * specular.rgb; /* Write out fragment color. */ - gl_FragColor = vec4(L, alpha); + gl_FragColor = vec4(L, diffuse.a); #endif } diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc index d46211f3668..9498f936b6b 100644 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc @@ -86,8 +86,10 @@ typedef struct Transform { static bool g_use_osd_glsl = false; static int g_active_uv_index = -1; -static GLuint g_flat_fill_program = 0; -static GLuint g_smooth_fill_program = 0; +static GLuint g_flat_fill_solid_program = 0; +static GLuint g_flat_fill_texture2d_program = 0; +static GLuint g_smooth_fill_solid_program = 0; +static GLuint g_smooth_fill_texture2d_program = 0; static GLuint g_wireframe_program = 0; static GLuint g_lighting_ub = 0; @@ -324,15 +326,8 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/, glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); /* Color */ - GLboolean use_lighting, use_color_material, use_texture_2d; + GLboolean use_lighting; glGetBooleanv(GL_LIGHTING, &use_lighting); - glGetBooleanv(GL_COLOR_MATERIAL, &use_color_material); - glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); - - glUniform1i(glGetUniformLocation(program, "use_color_material"), - use_color_material); - glUniform1i(glGetUniformLocation(program, "use_texture_2d"), - use_texture_2d); if (use_lighting) { float color[4]; @@ -376,8 +371,10 @@ void openSubdiv_osdGLDisplayInit(void) { static bool need_init = true; if (need_init) { - g_flat_fill_program = linkProgram("#define FLAT_SHADING\n"); - g_smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n"); + g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n"); + g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n"); + g_smooth_fill_solid_program = linkProgram("#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define SMOOTH_SHADING\n"); g_wireframe_program = linkProgram("#define WIREFRAME\n"); glGenBuffers(1, &g_lighting_ub); @@ -394,11 +391,17 @@ void openSubdiv_osdGLDisplayDeinit(void) if (g_lighting_ub != 0) { glDeleteBuffers(1, &g_lighting_ub); } - if (g_flat_fill_program) { - glDeleteProgram(g_flat_fill_program); + if (g_flat_fill_solid_program) { + glDeleteProgram(g_flat_fill_solid_program); } - if (g_smooth_fill_program) { - glDeleteProgram(g_flat_fill_program); + if (g_flat_fill_texture2d_program) { + glDeleteProgram(g_flat_fill_texture2d_program); + } + if (g_smooth_fill_solid_program) { + glDeleteProgram(g_flat_fill_solid_program); + } + if (g_smooth_fill_texture2d_program) { + glDeleteProgram(g_smooth_fill_texture2d_program); } if (g_wireframe_program) { glDeleteProgram(g_wireframe_program); @@ -505,12 +508,26 @@ static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh, return program; } - program = g_smooth_fill_program; if (fill_quads) { int model; + GLboolean use_texture_2d; glGetIntegerv(GL_SHADE_MODEL, &model); + glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); if (model == GL_FLAT) { - program = g_flat_fill_program; + if (use_texture_2d) { + program = g_flat_fill_texture2d_program; + } + else { + program = g_flat_fill_solid_program; + } + } + else { + if (use_texture_2d) { + program = g_smooth_fill_texture2d_program; + } + else { + program = g_smooth_fill_solid_program; + } } } else {