Question

I didn't get the blob.

I successfully rendered the rectangle without glEnable(GL_BLEND).

But I get nothing with that.

I found this: https://github.com/daw42/glslcookbook/blob/master/chapter01/scenebasic_uniformblock.cpp

I think my codes are very similar to him...

Following is my codes clip:

auto block_index = glGetUniformBlockIndex(basic_program.program_, "BlobSettings");
GLint block_size;
glGetActiveUniformBlockiv(basic_program.program_, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_size);
auto block_buffer = new GLubyte[block_size / sizeof(GLubyte)];
const GLchar *names[] = {"InnerColor", "OuterColor", "RadiusInner", "RadiusOuter"};
GLuint indices[4];
glGetUniformIndices(basic_program.program_, 4, names, indices);
GLint offsets[4];
glGetActiveUniformsiv(basic_program.program_, 4, indices, GL_UNIFORM_OFFSET, offsets);
GLfloat outer_color[] = {0, 0, 0, 0};
GLfloat inner_color[] = {1, 1, .75, 0};
GLfloat inner_radius = .25;
GLfloat outer_radius = .45;
memcpy(block_buffer + offsets[0], inner_color, 4 * sizeof(GLfloat));
memcpy(block_buffer + offsets[1], outer_color, 4 * sizeof(GLfloat));
memcpy(block_buffer + offsets[2], &inner_radius, sizeof(GLfloat));
memcpy(block_buffer + offsets[3], &outer_radius, sizeof(GLfloat));
GLuint ubo;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, block_size, block_buffer, GL_DYNAMIC_DRAW);
//                delete []blockBuffer;
glBindBufferBase(GL_UNIFORM_BUFFER, block_index, ubo);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLfloat position[] = {
    -.8, -.8, 0,
    .8, -.8, 0,
    .8, .8, 0,
    -.8, -.8, 0,
    .8, .8, 0,
    -.8, .8, 0
};
GLfloat texture_position[] = {
    0, 0,
    1, 0,
    1, 1,
    0, 0,
    1, 1,
    0, 1
};
GLuint position_buffer;
glGenBuffers(1, &position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, static_cast<GLubyte *>(nullptr));
GLuint texture_position_buffer;
glGenBuffers(1, &texture_position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, texture_position_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(texture_position), texture_position, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texture_position_buffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, static_cast<GLubyte *>(nullptr));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(.5, .5, .5, 0);
while (!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    glfwSwapBuffers(window);
    glfwPollEvents();
}

Following is my fragment shader:

#version 400

in vec3 TexCoord;
out vec4 FragColor;

uniform BlobSettings {
    vec4 InnerColor;
    vec4 OuterColor;
    float RadiusInner;
    float RadiusOuter;
};

void main() {
    float dx = TexCoord.x - 0.5;
    float dy = TexCoord.y + 0.5;
    float dist = sqrt(dx * dx + dy * dy);
    FragColor = mix(InnerColor, OuterColor,
                    smoothstep(RadiusInner, RadiusOuter, dist));
}
Was it helpful?

Solution

Your InnerColor and OuterColor are producing an alpha value of 0.0. When you mix (...) two vectors both with alpha = 0.0, the result will have alpha = 0.0 no matter what value you use for the a coefficient.

That is fine when you don't use blending, but the second you enable blending you run into trouble.

Your current blend function:

GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

Effectively does the following:

FragColor.a * FragColor.rgba  +  (1.0 - FragColor.a) * FrameBufferColor.rgba

To put this another way, you are using blending to discard the result of your fragment shading. You should use a non-zero alpha value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top