ofImage draw anti-aliasing

I am trying to draw some ofImage’s of PNGs with transparency, and the anti-aliasing isn’t quite right. I’m not sure it matters, but I’m trying to do this on iOS. There’s not much going on regarding drawing outside of the sort of setup and draw methods as are implemented in the imageLoaderExample app. What’s different is my PNG assets. They are a couple of cloud images with full transparency around the edges. I’ve done some experimentation with Apple’s SpriteKit using these same images and there is no issue there.

SpriteKit:

openFrameworks:

Notice the outline around the inner cloud profile.

I have this in my main:

ofiOSWindowSettings settings;
settings.enableRetina = true; // enables retina resolution if the device supports it.
settings.enableDepth = false; // enables depth buffer for 3d drawing.
settings.enableAntiAliasing = true; // enables anti-aliasing which smooths out graphics on the screen.
settings.numOfAntiAliasingSamples = 4; // number of samples used for anti-aliasing.
settings.enableHardwareOrientation = false; // enables native view orientation.
settings.enableHardwareOrientationAnimation = true; // enables native orientation changes to be animated.
settings.glesVersion = OFXIOS_RENDERER_ES2; // type of renderer to use, ES1, ES2, etc.

ofAppiOSWindow* window = (ofAppiOSWindow*)(ofCreateWindow(settings).get());

Experimenting with ES1 makes no difference. Using a number greater than 4 for numOfAntiAliasingSamples yeilds “Failed to make complete framebuffer object” in debug output.

I also noticed that even though “enableAntiAliasing = true”, that ofGLProgrammableRenderer::enableAntiAliasing() was not being called. So I added ofEnableAntiAliasing() in my draw method, confirmed that ofGLProgrammableRenderer::enableAntiAliasing()was being called, but it made no difference in the result.

Any assistance would be greatly appreciated.

Thanks,
-Todd

enabling antializasing won’t make any difference for this. antialiasing is actually jus tused for drawing geometry not for textures.

There’s a couple of things that i would try, first there’s a hack that OF uses to fix an issue with some texture sizes that might be the problem. try calling: ofDisableTextureEdgeHack() in your setup method.

also check you are not drawing your images with a different size

Thanks for the reply!

I tried ofDisableTextureEdgeHack(), but there is no difference. I’m not sure what you mean about drawing my images with a different size. If you are asking if I’m calling one of the draw methods which take a width and height, the answer is no. I am using this method:

void draw(float x, float y) const;

Any other thoughts?

btw, I’ve tried all sorts of things like the following, but none help.

ofClearAlpha();
ofEnableAntiAliasing();
ofEnableDepthTest();
ofEnableBlendMode(ofBlendMode::OF_BLENDMODE_ALPHA);
ofEnableAlphaBlending();

Thanks,
-Todd

It really looks like there was some small scaling of the images that’s breaking the antialiasing, can you post the images you are using?

Hi Arturo,

Thanks again for the reply! Very much appreciate your help.

I am certain there is no scaling of the images. I can attempt to upload the files to this post - not sure if there’s a better way…

As you can see above (assuming your forum background is white) that there is no aliasing baked into the images. I.e. they have pure white edges with alpha for anti-aliasing. Importing into Photoshop or even Apple’s Preview app shows that the edges of the cloud profiles are clean white with alpha.

I confirmed that adding these to the imageLoaderExample project shows the same issue.

Thanks,
-Todd

btw, if your forum background is indeed white, you won’t actually see the images. I assume you can right-click each one to “Save Image As…” to get the files.

You can try this test in the imageLoaderExample project:

  1. add the cloud PNGs to the /bin/data/Images folder.

  2. replace everything in the setup method with:

     	transparency.load("images/clouds1.png");
    
  3. replace everything in the draw method with:

    ofSetHexColor(0xFFFFFF);
    ofEnableAlphaBlending();
    transparency.draw(sin(ofGetElapsedTimeMillis()/5000.0f) * 100 + 300, cos(ofGetElapsedTimeMillis()/5000.0f) * 100 + 300);
    ofDisableAlphaBlending();

You will see that while the image is moving around the screen, its aliasing problem changes depending upon the X and Y position! At some positions, it disappears completely along parts of the cloud’s edge.

I’m still looking for ideas! :slight_smile: I also tried forcing the compression to none, and forcing the PNGs to a power of 2 size, but neither of these help.

-Todd

Hi -

I work with Todd and have also been looking at this problem, and I have a solution which is working locally. The problem is that on iOS all of the OS image functions have premultiplied alpha. OF_BLENDMODE_ALPHA sets a glBlendFunc which works only for straight alpha data (which is really hard to come by on iOS).

My solution is to add another blend mode to OF to support premul data, which I call OF_BLENDMODE_PREMULALPHA. I only had to change the two implementations of setBlendMode (ofGLRenderer and ofProgrammableGLRenderer) to have one more entry in the switch statement:

    case OF_BLENDMODE_PREMULALPHA:{
        glEnable(GL_BLEND);
        #ifndef TARGET_OPENGLES
            glBlendEquation(GL_FUNC_ADD);
        #endif
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
        break;
    }

This sets the correct glBlendFunc for premul data.

This fixes our problem locally, and I’m happy to get my change back into the OF code if you want it (I’m new here, and don’t know that process at all). It should not affect anyone who isn’t using the new mode. This will certainly help anyone working on iOS with alpha-bearing images.

@MikeBerry
Thanks for posting this - I have run into this issues a few times before.
It would be great if you could open an issue on github and ping the @openframeworks/ios group

Thanks!
Theo

Indeed- is there an issue about this so I can follow up on what have been going on?

i have similar issues. i am drawing a 3d model with very fine lines and i do not know how to make them more smooth.
i tried unsuccessfully the double FBO things as suggested here: Problem with video transparency / alpha channel

thanks for any advice.

I face the same problem. I solved it by using ofImage.resize(); however, I’d like to do the same thing when I’m using textures or VBOs. Those setting do not really help

imgSrc.getTexture().enableMipmap();
imgSrc.getTexture().setTextureMinMagFilter(GL_LINEAR, GL_LINEAR);
imgSrc.getTexture().generateMipmap();

Any help ?