Inconsistency between XNA/DirectX and OpenGL rendering

Started by
8 comments, last by L. Spiro 10 years ago

Hi all,

I have some drawing code that is expected to work on "all systems" ... it's working okay on DirectX/XNA, but in OpenGL, I get graphical glitches.

Here's a screenshot:

http://i.imgur.com/qSm4mgR.jpg

(Top text/image in each picture is filtering on, bottom tex/image in each picture is filtering off)

Some explanation (please read before you answer that I need to offset my pixels/texels by .5 in openGL):

1. Everything you see there, including the font, are just images combined onto a texture atlas

2. The texture atlas DOES have a white, zero alpha background-- I have no idea where the darker color is blending in from.

3. There IS space around all images on the texture atlas-- they are not grabbing pixels from another, adjacent image

4. I have tried many versions of "add .5 to pixels, add .5 to texels" to try to get the OpenGL version working. I can make it look worse, but I can't make it look better.

My default render settings are these:


glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glDisable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glAlphaFunc(GL_GREATER,.01f);

I am suspecting the GL_ONE_MINUS_SRC_ALPHA, because I read that that's supposed to be for premultiplied alpha. I do not have premultiplied alpha in the images-- but what's the fix? I tried every blend mode that didn't sound crazy, and I get either white boxes for everything, or the images you see here.

Please help!

Thanks!

Advertisement

please read before you answer that I need to offset my pixels/texels by .5 in openGL

It's the opposite, D3D9/XNA have a wacky coordinate system where screen pixels are misaligned by half a pixel. D3D10+ and GL have a sensible screen coordinate system.

How do you generate your vertex positions and texture coordinates?

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); is traditional alpha blending (which should look fine if your RGB channels are white everywhere).

glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); is premultiplied alpha blending (which should look fine if your RGB channels are black in areas where the A channel is also black).

How do you get the pixel data from disk and send it to the API? Is it possible that the API is modifying your data (introducing a black background area)?

Try GL_REPLACE instead of GL_MODULATE...

If the scale isn't 1:1 also check the mip-maps so they're not all black on GL or something.

Hola,

Basically I have rectangles on the texture atlas-- so I'd say, for this image, draw with this texture rectangle.

The texture rectangle is modified on the OpenGL version-- so if I had rect=(0,0 - 10,10) on OpenGL it'll actually be rect=(.5,.5 - 9.5,9.5). I have also tried rect=(.5,.5 - 10,10) and rect=(.5,.5-10.5,10.5) with those second two making it worse. (Naturally all coordinates are converted to 0.0 - 1.0 by the width of the image itself).

So essentially it looks like:

Image rect is (0,0-10,10)
Fix it for OpenGL-- now rect is (.5f,.5f - 9.5,9.5)
Divide rect by width/height of texture to convert to 0-1

I also have tried kludging the actual draw positions onscreen, by adding .5 to them as well, with no luck. Again, I've tried lots of combinations, everything from adding .5 to all four corners of the rect, to shrinking the rect by .5, and even tried expanding the rect by .5 as I randomly started lashing about for solutions.

* * *

For loading textures, at this time they're a simple PNG that I ensured had a white (invisible) background in photoshop. For completeness, I tried drawing with no alpha and got white squares (if the background had been dark I'd have gotten the imprint of the letters over the background color). Extra note: The utility I wrote to put the images onto the texture atlas automatically bleeds the pixel's rbg outward, so even without the extra step of going into photoshop to guarantee the white background, it SHOULD work. But I did the photoshop thing for completeness.

I tried premultiplied alpha, but it didn't seem to help anything (it's easy to premultiply the alpha in my load pipeline)-- still got the rim.

Extra wrinkle: This is particularly frustrating because it worked at one point (I had this same fight a couple months ago, but it was easy to fix by simply adding the .5). It stopped working after I accepted an update to OSX Lion.

Hi Erik,

I just tried the change from modulate to replace-- I got the dark rim on the unfiltered text as well doing that.

BUT, just flailing randomly, I tried this:

glBlendFunc(GL_SRC_ALPHA,GL_ONE);

... and it seemed to work, at least for white stuff (haven't tried colored yet).

What are the implications of that? That's not a correct alpha blend, is it?... maybe that's giving me additive, I don't remember.

it is possible that some pixels on your font texture exhibit different than white color (darker, is it antialiased?) but do not exhibit enough alpha to not pass blending. You can for sure bypass this by apropriate blending function considering alpha reference. In any case, your opengl should be just perfectly the same as your xna code, and they should result in same thing, unless you have some "lucky" default in xna code.

Hi again,

In trying to diagnose this, I got it running on iPad. I get a similar problem, but a little different.

Does OpenGL blend more than one pixel distance away? If I color all RGB in my image white on load (and leave alpha alone) then it works okay. But, I have my image bundler set up to add an outline around each image of the image's own color-- so that a letter in a font, say, is surrounded by a stroke of white. On iPad, each letter and image has a perfect (thin) border around the edge-- as if the blending is reaching out another pixel's distance away.

By comparison, on the Mac, only certain areas get this blending-- as seen in that screenshot above. But on iPad, a perfect halo around the rim of each letter.

Is this filtering going further than I expect it to? I'm expecting it to go one pixel out-- as in, I have a pixel that's 255,255,255,255, and it's next to 255,255,255,0, and that's next to 0,0,0,0 ... when I draw the first one, I expect it to blend with the second one, but ignore the third. On iPad, at least (retina?) it seems to involved the third.

Do I have higher-order blending on by default, maybe?

[Edit] Oh, incidentally, I have no mipmaps-- this is all for the 2D, "sprite" portion of the interface.

you should actualy always calibrate your glyphs to sample mimap level 1, if you want it eye perfect. Do not allow magnification of texture, since, if you do, it does not have to break absolutely, but you will experience alpha weighted (curvy blend), wheather you use, alpha test, color key test, or pixel discard upon texture you sample. It does not matter much on leafes of trees you get too close to, but on font, this artefacts may get uncomfortable

Just wanted to weigh in with what the problem is/was...

Did you know XCode will take your png and modify it? As part of the modification process, it premultiplies the alpha. That's why this was happening. I don't see any real way around it but to include pnglib in my project, or stop using pngs.

I've been programming for 20 years and this is the most infuriating thing I've ever seen. The idea that they would MODIFY the data you're including in the bundle... and worse, they don't give you a way to turn it off. There's notes on the web on how to turn it off, but none of them actually work.

Infuriating.

Did you know XCode will take your png and modify it? As part of the modification process, it premultiplies the alpha. That's why this was happening. I don't see any real way around it but to include pnglib in my project, or stop using pngs.

Change the Xcode setting so that it does not premultiply (and otherwise modify) your PNG files. Premultiplied images are a historic trend of Apple’s.
http://imageoptim.com/xcode.html

Note that you are probably correct that it doesn’t work. I didn’t take the time in the past to investigate thoroughly, but it seemed not to work in my projects as well.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement