# Four (4) color channel png has black "background"

I am experimenting with C++ code to load a png file, using libpng. When I get to the color data in the file, I load it into a std::vector. I have found that the interface between the C code libpng and my C++ code is straightforward.

I then draw the image using OpenGL.

When the image file is opened in GIMP, it displays as,

When I display the image with my OpenGL code it displays as,

The file I am using is an RGBA image without a backround, i.e., no kBKG chunk.

In looking at the pixel data in my std::vector, it appears that the OpenGL data for the lower right is all RGBA = (0, 0, 0, 0).

I was expecting that the png IDAT chunk would carry and display the transparency information.

In OpenGL I am setting the background to RGBA = (1, 1, 1, 1), i.e., in 8-bit RGBA terms (255, 255, 255, 255), white.

I am obviously missing something, but cannot see what it might be.

• Have you taken a look at https://stackoverflow.com/questions/24399431/opengl-texture-with-transparency-alpha ? Nov 15 '19 at 15:12
• Can you show us the code you're using to draw the image and manage your alpha blending? Nov 15 '19 at 15:12
• I think that is the problem. The VBO data is simply (x, y, z, R, G, B, A) data per pixel and I am drawing it with glDrawArrays(GL_POINTS, 0, numPoints);. I have used the alpha blending when using Sean Barrett's stb_image.h routines. Here I am just accepting the raw data and trying to display it for my own edification. Nov 15 '19 at 15:29
• How have you configured your rendering state prior to calling glDrawArrays ? Nov 15 '19 at 18:14
• @DMGregory - you reminded me of something I had learned a while back from "Learn OpenGL" by Joey de Vries link, viz., the blending formula. I applied it and it worked perfectly. The formula for each color is, e.g., redFinal = redInitial * alpha + (1.0 - alpha) for blending with a while background. I'd like to show the result, though I can't see how to post an image in this comment. I will do it in a couple of days when I "answer my own question", which is not, of course, accurate, though a way to get the image posted. Thanks for the pointer! Nov 15 '19 at 22:13

## 1 Answer

DMGregory's comment of two days ago put me onto the solution by reminding me of something I had read in Learn OpenGL some time ago.

In Learn OpenGL, by Joey de Vries, Learn OpenGL - Introduction, and specifically his page on blending, Blending, he discusses the combining of two images each with 4-channels of RGBA color data. The formula,

shows how to blend a solid green area, which has an A, alpha, value of 0.6 (OpenGL uses 0.0 to 1.0 to represent 8-bit colors from 0 to 255), and a solid red background with an A value of 1.0.

Since my software was reading an image pixel by pixel, I applied this formula to each pixel and blended it with a solid white, (1.0, 1.0, 1.0, 1.0), background. It seems that without specifying a background image for blending, which could be anything, OpenGL will default to solid black background. This produced the following image:

You can see the shadow detail is now present when it wasn't when I simply used OpenGL's glDrawArrays() to render the png image without blending. The new image is still being rendered with glDrawArrays(), though it is the modified, blended image.

This is calculation intensive and I know there are better ways of doing this "in production". However, this project was for my own edification.

• You can probably set the blending state in OpenGL to do this computation for you as it outputs each fragment. Your graphics card has dedicated hardware for that. Usually it involves setting a few flags to enable alpha blending and setting the blend operation and weights to your desired blending formula, before issuing your draw command. Nov 18 '19 at 14:26