Creating an OpenGL texture with alpha using NSBitmapImageRep - opengl

I am loading a PNG using:
theImage = [NSBitmapImageRep imageRepWithContentsOfFile:imagePath];
from which I can successfully create a gl texture and render correctly without any transparency. However, when I switch blending on using:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
The texture renders with the correct transparent background, but the image colours are incorrect.
I have tried several options in the blend function, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_DST_ALPHA, etc.
I was taught maybe I need to reorder the bits in the image data, maybe the channels have been mixed up, but I would not expect it to render correctly when blending is off in that case.
Alternatively, I could use libPNG I guess, but I would like to try using a NSBitmapImageRep if it is possible.

How about supplying a screenshot?
Anyway, your blending function is wrong either way for simple transparency channel blending. It should be either
normal alpha: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
or
premultiplied alpha: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

Related

OpenGL Blend Function To Copy RBG/Disregard Alpha?

There may be an easier way to do this, I can do it with a shader I'd imagine, but I feel like setting the blend function is simpler.
Shader would maybe be gl_FragColor = vec4(texture.rgb, 0);
For a reason, I need to have a freshly cleared FBO filled with a transparent (0) texture. That way the pixels in the FBO are visually transparent, but contain the RGB values of the texture.
It's tough to explain, but it's essentially a glClear() but with a texture rather than a solid color. Is there a combination blend src/dst function that would accomplish this?
Basically it shouldn't matter what the FBO looks like beforehand. I then want to render a texture to it, but since I'm rendering it with alpha 0, it's not overriding the existing FBO pixels.
If you really want to do this via blending, you can do this via the separate blend factors introduced originally in GL_EXT_blend_func_separate (promoted to OpenGL core functionalitiy in Version 2.0):
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
glBlendEquation(GL_ADD); // is the default anyway

Using multiple blendfunc OpenGL

I want to use
glBlendFunc(GL_ONE, GL_ONE)
and
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
at the same time. Is this possible?
You can create an offscreen Framebuffer Object with a texture attached to it. Perform the first render using glBlendFunc(GL_ONE, GL_ONE) then flip the input and output textures and perform the second render using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).

Procedure for alpha blending textured quads in OpenGL 3+?

I am attempting to put together a simple program that just displays two textured quads overlapping each other, and the textures have alpha channels.
I have successfully been able to get the quads themselves to display, and the textures look correct except for the transparency.
On this topic, the GL_BLEND flag does not seem to do anything at all, whether it is enabled or not. Is this particular flag inapplicable when shaders are being used?
I know for a fact that the alpha is being rendered in correctly, since if I set out_color = texture.aaaa, I get a nice pattern of blacks/whites/grays that match the original texture.
So, if GL_BLEND doesn't work, what are the usual methods for getting alpha blending working?
All that glEnable(GL_BLEND) does is turn blending on and off. It does not say what the blending will do; that is controlled by the various blending functions. If you want a typical alpha transparency blend, you do this:
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
If you use pre-multiplied alpha (and you probably should), you would do:
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);

glBlendFunc and alpha channel

I'm trying to render some transparent objects using:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
However, I don't get the result I want.
I draw a fully opaque square, and then i draw a semi-transparent square. The colors are just as a I would expect however, the alpha channel is NOT fully white as I want.
Basically I want the following equation:
r = old_r*(1.0-a)+r*a;
g = old_g*(1.0-a)+g*a;
b = old_b*(1.0-a)+b*a;
a = old_a + a;
Is this possible to achieve using glBlendFunc or do I have to resort to shaders and multiple FBOs for read-back?
You basically want separate blend functions for color and alpha, and this is achieved by using glBlendFuncSeparate:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
Does the blend func you want.
Just draw your opaque square, then check the alpha channel. If it's not showing up as fully white when a known-opaque square is rendered, you may have a problem with some other setting.

OpenGL - Textures - Replacing black (white) with color

I am generating a bitmap for a text display with OpenGL using Cairo/Pango. I generate the bitmap as RGBA with a transparent background and with the text in either black or white. (Let's assume black.)
If I load this bitmap as an OpenGL texture and display it, it appears as black text or white text, as expected.
I'd like to be able to color the text using only the original texture, but with OpenGL taking care of the coloring.
Preferably, I'd like to use glColor to set the color, but I'm willing to use glBlendColor or GL_TEXTURE_ENV_COLOR.
However, I can't get any of those options to work.
I've try what seem like innumerable combinations of
- white text or black text
- enabling blending or using GL_TEXTURE_ENV_MODE's GL_BLEND
- trying GL_MODULATE, GL_REPLACE, and GL_COMBINE
- trying various differnt glBlendFunc combinations
I've been searching online and reading the spec for a few hours and I'm really at the end of my rope.
Can anyone point me to the right place to get the answer to this?
The simplest way to go is to have your text bitmap with white text and transparent background.
Then, to color it, you have to make sure that TEXTURE_ENV_MODE is set to MODULATE :
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
With this, the draw color will be glColor * textureColor == glColor (as textureColor is white)
Then you have to enable blending to handle your transparent background :
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
or, if your bitmaps are in premultiplied alpha form :
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Instead of supplying a full RGBA set, let the text just determinine the non-/transparency, i.e. just supply an alpha channel. Then use the normal glColor to set the text color.
It sounds like you can create the bitmap as you see fit. If that's the case, instead of black on white, I'd draw the text into the alpha channel. Then to color the text, you draw a rectangle (or whatever) of the color you want. Then draw your texture over it. Where the texture is opaque, you'll get the texture color. Where the texture is transparent, the background color will show through.
To do that, you will have to set up glBlendFunc. The usual should be fine:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
You also have to turn on blending for texturing:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);