From 31f19438c73b207f506ba0b1187d2de75c166a5b Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 9 Apr 2020 17:39:54 +0100 Subject: [PATCH] Fix blending --- billboardfrag.glsl | 20 +++++++++++++++++++- clouds.cpp | 42 +++++++++++++++--------------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/billboardfrag.glsl b/billboardfrag.glsl index 840ec89..2349e4d 100644 --- a/billboardfrag.glsl +++ b/billboardfrag.glsl @@ -3,7 +3,25 @@ uniform vec4 color; uniform sampler2D tex; in vec2 texCoord; out vec4 FragColor; +uniform bool modulate; void main() { - FragColor = texture(tex, texCoord).r * color; + // Cf = color from fragment, Ct = color from texture + // Cc = color from texture environment(?) assume to be 0? + // Af = alpha from fragment, At = alpha from texture + // C = output color, A = output alpha + float f = texture(tex, texCoord).r; + if (modulate) { + // GL_MODULATE: C + // C = Cf * Ct + // A = Af * At + FragColor = color * f; + } else { + // GL_BLEND: + // C = Cf * (1-Ct) + Cc * Ct + // A = Af * At + vec3 C = color.rgb * (1 - f); + float A = color.a * f; + FragColor = vec4(C, A); + } } diff --git a/clouds.cpp b/clouds.cpp index 7bb51e8..96612e8 100644 --- a/clouds.cpp +++ b/clouds.cpp @@ -84,21 +84,21 @@ void calculateMetaballs() {} #define NQ 1 GLuint bbTexIds[NQ]; +// Stores attenuation ratio inside r channel +// Should be highest value at center void precalculateBillboardTextures() { float data[32 * 32]; // TODO: properly calculate this instead of whatever this is for (int j = 0; j < 32; j++) for (int i = 0; i < 32; i++) - data[i + j * 32] = fmin(1.f, 0.1f + 2.f * (distance(vec2(i, j), vec2(16, 16)) / 16)); + data[i + j * 32] = fmin(1.f, 0.3f + 2.f * (distance(vec2(i, j), vec2(16, 16)) / 16)); glGenTextures(NQ, bbTexIds); - /* GLuint captureFBO; */ - /* glGenFramebuffers(1, &captureFBO); */ for (int i = 0; i < NQ; i++) { glBindTexture(GL_TEXTURE_2D, bbTexIds[i]); - /* glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 32, 32, 0, GL_RED, */ - /* GL_FLOAT, data); */ + checkError(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 32, 32, 0, GL_RED, GL_FLOAT, data); glGenerateMipmap(GL_TEXTURE_2D); // required, otherwise texture is blank @@ -152,6 +152,7 @@ void shadeClouds() { bbColors.clear(); glDisable(GL_DEPTH_TEST); + // shaderOutput * 0 + buffer * shader alpha glBlendFunc(GL_ZERO, GL_SRC_ALPHA); glEnable(GL_BLEND); @@ -159,24 +160,11 @@ void shadeClouds() { sort(metaballs.begin(), metaballs.end(), [](Metaball &a, Metaball &b) { return distance(sunPos, a.pos) < distance(sunPos, b.pos); }); - /* GLuint fbo; */ - /* glGenFramebuffers(1, &fbo); */ - /* glBindFramebuffer(GL_FRAMEBUFFER, fbo); */ - /* glBindTexture(GL_TEXTURE_2D, attenuationTex); */ - /* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, */ - /* GL_UNSIGNED_BYTE, NULL); */ - /* glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, */ - /* attenuationTex, 0); */ - /* assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); */ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, bbTexIds[0]); glUniform1i(glGetUniformLocation(bbProg, "tex"), 0); -/* glClearColor(1, 1, 1, 1); */ -/* glClear(GL_COLOR_BUFFER_BIT); */ - - GLuint modelLoc = glGetUniformLocation(bbProg, "model"); for (auto k : metaballs) { @@ -195,8 +183,9 @@ void shadeClouds() { // Map the billboard texture with GL_MODULATE. // i.e. multiply rather than add - // TODO: FIX- this crashes with invalid operation - /* glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */ + // but glTexEnv is for the old fixed function pipeline -- + // need to just tell our fragment shader then to modulate + glUniform1i(glGetUniformLocation(bbProg, "modulate"), 1); // Render the billboard. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); @@ -215,16 +204,11 @@ void shadeClouds() { pixel *= sunColor; // Store the color into an array C[k] as the color of the billboard. - fprintf(stderr, "pixel: "); - dump(pixel); bbColors.push_back(pixel); } - /* saveFBO(); */ + saveFBO(); checkError(); - - /* glDeleteFramebuffers(1, &fbo); */ - /* glBindFramebuffer(GL_FRAMEBUFFER, 0); // render to screen */ } void renderObject() {} @@ -237,6 +221,7 @@ void renderClouds() { glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); + // shaderOutput * 1 + buffer * shader alpha glBlendFunc(GL_ONE, GL_SRC_ALPHA); for (int i = 0; i < metaballs.size(); i++) { Metaball k = metaballs[i]; @@ -253,7 +238,7 @@ void renderClouds() { // Set the billboard color as C[n]. fprintf(stderr, "bbColors[i]: "); dump(bbColors[i]); - /* bbColors[i] = {0,0,0,0.5}; */ + bbColors[i].w = 1; glUniform4fv(glGetUniformLocation(bbProg, "color"), 1, glm::value_ptr(bbColors[i])); @@ -262,6 +247,9 @@ void renderClouds() { glBindTexture(GL_TEXTURE_2D, bbTexIds[0]); glUniform1i(glGetUniformLocation(bbProg, "tex"), 0); + // Don't modulate it -- blend it + glUniform1i(glGetUniformLocation(bbProg, "modulate"), 0); + // Render the billboard with the blending function. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } -- 2.30.2