1

I am working on a particle system using OpenGL and version 460 shaders that are compiled to SPIR-V.

My particles are based on PNG textures with alpha and it's actually pretty straight forward, I have done it on earlier OpenGL versions before.

However, the particle in the output window remains to be a square, the corners are black - meaning, the alpha channel is drawn as black. I used different PNG files, one with the particle as grey on alpha or grey on black. I set in the fragment shader the forth component to 0.0 or 0.5 to see any change, but nothing changed. I tried to change the formats in the loadTexture function, but still the same.

I tried all different kinds of blending modes and changed the order of the lines. I noticed in RenderDoc, that the target blend is disabled. But no change of glEnable(GL_BLEND) to another position was helpful.

I would really appreciate your help!

particle texture1particle texture2

// init stuff
glEnable(GL_POINT_SPRITE);
initbasicShaders(); // vertex, fragment
initTexture();
...

void application::initTexture()
{
    m_ParticleTex = Texture(); // empty constructor
    m_ParticleTex.loadTexture(TEXTURE_PATH);

    GLint baseImageLoc = glGetUniformLocation(m_RenderProgramHandle, "u_Texture");
    glUseProgram(m_RenderProgramHandle);
    glUniform1i(baseImageLoc, 0); 
    glActiveTexture(GL_TEXTURE0 + 0);
    glBindTexture(GL_TEXTURE_2D, m_ParticleTex.getTextureID());
}

// using the library stb_image
void Texture::loadTexture(const char* fileName)
{
    int channels, width, height;
    unsigned char * localBuffer;
    m_FilePath = fileName;

    localBuffer = stbi_load(fileName, &width, &height, &channels, 4);

    glGenTextures(1, &m_TextureID);
    glBindTexture(GL_TEXTURE_2D, m_TextureID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localBuffer);
    glBindTexture(GL_TEXTURE_2D, 0);

    if (localBuffer) {
        stbi_image_free(localBuffer);
    }
}

...
...
...
// Now - the render loop:
void application::runOpenGLBuffer()
{
    Log::logInfoRun(m_Name, "OpenGL buffer");
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glEnable(GL_POINT_SMOOTH);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_ALPHA_TEST);

    glPointSize(PARTICLE_SIZE);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

        glUseProgram(m_RenderProgramHandle);
    this->updateTextures();
        glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
}


...
// and the fragment shader
#version 460
#extension GL_ARB_separate_shader_objects : enable

layout(std430, binding = 3) buffer density_block
{
    float density[];
};

void main()
{
// densitColor is just a variable color from density
    vec4 particleColor = vec4(texture(u_Texture, gl_PointCoord) * densityColor);
    color = particleColor;
}

And here the output in the render frame and information from RenderDoc:

enter image description here enter image description here enter image description here

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Allwo
  • 225
  • 2
  • 10

1 Answers1

1

The parameter to glEnable (like GL_BLEND or GL_POINT_SMOOTH) is a enumerator constant rather than a bits of a bit field. Different enumerator constants can't be concatenated by the | operator. Each state has to be enabled separately:

glEnable(GL_BLEND | GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);

Note, the bitwise or operation calculates a new value by performing "or" to each bit of both values. The result may have not any meaning to glEnable. This causes that neither GL_BLEND nor GL_POINT_SMOOTH is enabled in your code.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you for the hint @Rabbid76 and I changed it. It unfortunately didn't solve the problem. I will edit it here for others not to worry about. – Allwo Jan 12 '19 at 11:53
  • I also wonder about glEnable(GL_POINT_SPRITE); If I don't set it nothing is displayed. But as far as I see it is a legacy function. – Allwo Jan 14 '19 at 15:08