GLuint uniform_diff_flow_tex;
GLuint uniform_equation_red_tex, uniform_equation_black_tex;
GLuint uniform_diffusivity_tex;
- GLuint uniform_phase, uniform_zero_diff_flow;
+ GLuint uniform_phase, uniform_num_nonzero_phases;
};
SOR::SOR()
uniform_equation_black_tex = glGetUniformLocation(sor_program, "equation_black_tex");
uniform_diffusivity_tex = glGetUniformLocation(sor_program, "diffusivity_tex");
uniform_phase = glGetUniformLocation(sor_program, "phase");
- uniform_zero_diff_flow = glGetUniformLocation(sor_program, "zero_diff_flow");
+ uniform_num_nonzero_phases = glGetUniformLocation(sor_program, "num_nonzero_phases");
}
void SOR::exec(GLuint diff_flow_tex, GLuint equation_red_tex, GLuint equation_black_tex, GLuint diffusivity_tex, int level_width, int level_height, int num_iterations, bool zero_diff_flow, ScopedTimer *sor_timer)
bind_sampler(sor_program, uniform_equation_red_tex, 2, equation_red_tex, nearest_sampler);
bind_sampler(sor_program, uniform_equation_black_tex, 3, equation_black_tex, nearest_sampler);
- glProgramUniform1i(sor_program, uniform_zero_diff_flow, zero_diff_flow);
+ if (!zero_diff_flow) {
+ glProgramUniform1i(sor_program, uniform_num_nonzero_phases, 2);
+ }
// NOTE: We bind to the texture we are rendering from, but we never write any value
// that we read in the same shader pass (we call discard for red values when we compute
for (int i = 0; i < num_iterations; ++i) {
{
ScopedTimer timer("Red pass", sor_timer);
+ if (zero_diff_flow && i == 0) {
+ glProgramUniform1i(sor_program, uniform_num_nonzero_phases, 0);
+ }
glProgramUniform1i(sor_program, uniform_phase, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glTextureBarrier();
{
ScopedTimer timer("Black pass", sor_timer);
if (zero_diff_flow && i == 0) {
- // Not zero anymore.
- glProgramUniform1i(sor_program, uniform_zero_diff_flow, 0);
+ glProgramUniform1i(sor_program, uniform_num_nonzero_phases, 1);
}
glProgramUniform1i(sor_program, uniform_phase, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ if (zero_diff_flow && i == 0) {
+ glProgramUniform1i(sor_program, uniform_num_nonzero_phases, 2);
+ }
if (i != num_iterations - 1) {
glTextureBarrier();
}
uniform usampler2D equation_red_tex, equation_black_tex;
uniform int phase;
-uniform bool zero_diff_flow;
+uniform int num_nonzero_phases;
// See pack_floats_shared() in equations.frag.
vec2 unpack_floats_shared(uint c)
const float omega = 1.8; // Marginally better than 1.6, it seems.
- if (zero_diff_flow) {
+ if (num_nonzero_phases == 0) {
// Simplified version of the code below, assuming diff_flow == 0.0f everywhere.
diff_flow.x = omega * b.x * inv_A11;
diff_flow.y = omega * b.y * inv_A22;
b += smooth_r * textureOffset(diff_flow_tex, tc, ivec2( 1, 0)).xy;
b += smooth_d * textureOffset(diff_flow_tex, tc, ivec2( 0, -1)).xy;
b += smooth_u * textureOffset(diff_flow_tex, tc, ivec2( 0, 1)).xy;
- diff_flow = texture(diff_flow_tex, tc).xy;
+
+ if (num_nonzero_phases == 1) {
+ diff_flow = vec2(0.0f);
+ } else {
+ diff_flow = texture(diff_flow_tex, tc).xy;
+ }
// From https://en.wikipedia.org/wiki/Successive_over-relaxation.
float sigma_u = A12 * diff_flow.y;