How to stop OpenGL background bleed on transparent textures - opengl-es-2.0

I have an iOS OpenGL ES 2.0 3D game and am working to get transparent textures working nicely, in this particular example for a fence.
I'll start with the final result. The bits of green background/clear color are coming through around the edges of the fence - note how it isn't ALL edges and some of it is ok:
The reason for the lack of bleed in the top right is order of operations. As you can see from the following shots, the order of draw includes some buildings that get drawn BEFORE the fence. But most of it is after the fence:
So one solution is to always draw my transparent textured objects last. I would like to explore other solutions, as my pipeline might not always allow this. I'm looking for other suggestions to solve this problem without sorting my draws.
This is likely a depth or blend function, but i've tried a ton of stuff and nothing seems to work (different blend functions, different discard alpha levels, different background colors, different texture settings).
Here are some specifics of my implementation.
In my frag shader I'm throwing out fragments that have transparency - this way they won't render to depth:
lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.5)
discard;
I'm using one giant PVR texture atlas with mipmapping - the texture itself SHOULD just have 0 or 1 for alpha, but something with the blending could be causing this:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
I'm using the following blending when rendering:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Any suggestions to fix this bleed would be great!
EDIT - tried a different min filter for the texture as suggested in the comments, LINEAR/NEAREST, but same result. Note I have also tried NEAREST/NEAREST and no luck:

try increasing the alpha filter limit,
lowp vec4 texVal = texture2D(sTexture, texCoord);
if(texVal.w < 0.9)
discard;

I know this is an old question but I came across it several times whilst trying to find an answer to my very similar OpenGL issue. Thought I'd share my findings here for anyone with similar. The culprit in my code looked like this:
glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
I used a pink transparent colour for ease of visual reference whilst debugging. Despite the fact it was transparent when it was blending between background and the colour of the subject it would bleed in much like the symptoms in the screenshot of the question. What fixed it for me was wrapping this code to mask the glClear step. It looked like this:
glColorMask(false, false, false, true);
glClearColor(1, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(true, true, true, true);
To my knowledge, this means when the clear process kicks in it only operates on the alpha channel. After this is was all re-enabled to continue the process as intended. If someone with a more solid knowledge of OpenGL can explain it better I'd love to hear!

Related

Imgui text appears as white rectangles on my custom Vulkan renderer

I am following Sascha Willems example on how to integrate imgui with a Vulkan renderer.
Trying to render this simple window:
ImGui::NewFrame();
ImGui::SetNextWindowSize(ImVec2(128, 64), ImGuiCond_FirstUseEver);
ImGui::Begin("Test Window", nullptr);
ImGui::Text("Test Text");
ImGui::End();
ImGui::Render();
Yields the following:
Unfortunately text appears as white rectangles.
I examined the rendering process against Sascha Willem code using Renderdoc but haven't yet found what went wrong.
Here is a link to the renderdoc file and relevant code files.
From my examination, it seems that vertex data and textures are loaded correctly. but the two samples have a slightly different font texture and as a result, slightly different uv coordinates per vertex. But nothing to explain why the textured text quads appear completely white. I guess the difference in the font texture emanate from the fact that I use a different imgui version (latest docking branch from vcpkg).
Does anyone have an idea what could lead to such result?
I would be happy to share more info if you think it is relevant (code, renderdoc files) but I wish to avoid clutter this post with too much code.
The issue was caused due to disabled blending.
Apparently, the imgui font texture has the value (1.0f, 1.0f, 1.0f, 0.0f) where the text quad should be blank (and not (0.0f, 0.0f, 0.0f, 0.0f). If blending is not enabled, then the alpha channel will be ignored which will cause the text quad to appear white.

Motion Blur Emplementation on OpenGL ES

I'm a novice in OpenGL ES 1.1(for IOS) texturing and I have a problem with making the effect of motion blur. During googling, I found that I should render my scene in different time moments to several textures and then draw all these textures on the screen with different alpha values. But the problem is that I don't know how to implement all this!So,my questions are:
How to draw a 2D texture on the screen? Should I make a square and put my texture on it?Or may be, there is a way to draw a texture on the screen directly?
How to draw several textures(one upon another) on the screen with different alpha values?
I've already come up with some ideas, but I'm not sure if they are correct or not.
Thanks in advance!
Well, of course the first advice is, understand the basics before trying to do advanced stuff. Other than that:
Yes indeed, to draw a full-screen texture you just draw a textured screen-sized quad. An orthographic projection would be a good idea in this case, making the screen-alignment of the quad and its proper sizing easier. For getting the textures in the first place (by rendering into them), FBOs might be of help, but I'm not sure they are supported on ES 1 devices, otherwise the good old glCopyTexSubImage2D will do, too, albeit requiring a copy operation.
Well, you just draw multiple textured quads (see 1) one over the other. You might configure the texture environment to scale the texture's color with the quad's base color (glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)) and give your quads a color of (1, 1, 1, alpha) (of course lighting should be disabled). Additionally you have to enable alpha blending (glEnable(GL_BLEND)) and use an appropriate blending function (glBlendFunc(GL_SRC_ALPHA, GL_ONE) should do).
But if all these terms don't tell you anything, you should rather first learn the basics using a good learning resource before delving into more advanced effects.

ID3DXLine strange behavior when line width is 1.0, on certain machines

I've had this problem on a couple of machines now - almost always laptops and I think usually those with Intel graphics chipsets, when using ID3DXLine.
I have some code that vaguely looks like this:
MyLine->SetWidth(MyLineThickness);
MyLine->SetPattern(MyLinePattern);
MyLine->Begin();
{
... Draw some lines with ->MyLine->Draw
}
MyLine->End();
With MyLine being a CComPtr (ID3DXLine). When MyLineThickness is 1.0, these machines draw thick lines (looking as if they're drawn with a felt-tip pen!). When I change MyLineThickness to 1.1, or 1.5, I then get nice thin lines. Obviously increasing that to around 8.f will give me thick lines again.
So ID3DXLine on these machines seems to do something really odd when thickness is 1.0. At < 1.f and > 1.f it seems to behave as you would expect!
Has anyone else experienced any strangeness in ID3DXLine? I'm using D3D 9.0c btw, alongside the Feb 2010 SDK.
According to DX9 documentation lines of thickness 1.0f are drawn using native hardware line drawing support if one exists. All other sizes are drawn by producing a pair of triangles and, hence, rendered via vertex shader. Try checking D3DCAPS9::LineCaps for supported capabilities.
After some playing with ID3DXLine I decided to use DrawPrimitives for drawing lines - it's probably a bit slower but at least you get same result on any system.

CGContextShowTextAtPoint renders upside down

I am trying to draw some text via Quartz onto an NSView via CGContextShowTextAtPoint(). This worked well until I overrode (BOOL)isFlipped to return YES in my NSView subclass in order to position the origin in the upper-left for drawing. The text draws in the expected area but the letters are all inverted. I also tried the (theoretically, at least) equivalent of flipping my CGContext and translating by the context's height.
e.x.
// drawRect:
CGContextScaleCTM(theContext, 1, -1);
CGContextTranslateCTM(theContext, 0, -dirtyRect.size.height);
This yields the same result.
Many suggestions to similar problems have pointed to modifying the text matrix. I've set the text matrix to the identity matrix, performed an additional inversion on it, and done both, respectively. All these solutions have lead to even stranger rendering of the text (often just a fragment shows up.)
Another suggestion I saw was to simply steer clear of this function in favor of other means of drawing text (e.x. NSString's drawing methods.) However, this is being done amongst mostly C++ / C and I'd like to stay at those levels if possible.
Any suggestions are much appreciated and I'd be happy to post more code if needed.
Thanks,
Sam
This question has been answered here.
Basically it's because the coordinate system on iOS core graphics is fliped (x:0, y:0 in the top left) opposed to the one on the Mac (where x:0, y:0 is bottom left). The solution for this is setting the text transform matrix like this:
CGContextSetTextMatrix(context, CGAffineTransformMake(1.0,0.0, 0.0, -1.0, 0.0, 0.0));
You need to use the view's bounds rather than the dirtyRect and perform the translation before the scale:
CGContextTranslateCTM(theContext, 0, -NSHeight(self.bounds));
CGContextScaleCTM(theContext, 1, -1);
Turns out the answer was to modify the text matrix. The weird "fragments" that were showing up instead of the text was because the font size (set via CGContextSelectFont()) was too small when the "default" text matrix was replaced. The initial matrix had, for some reason, a large scale transform so smaller text sizes looked fine when the matrix was unmodified; when replaced with a inverse scale (1, -1) or an identity matrix, however, they would become unreadably small.

Strange thin line or dots at the bottom of my opengl texture

I have made an app similar to this one: http://www.youtube.com/watch?v=U2uH-jrsSxs (the sound is a bit loud and bad). The problem is there is a very thin line/dots/whatever appearing at the bottom of every texture. It is almost unnoticeable but it is there and I have no idea why. My texture size is 256x256. I tested earliear with a texture size 128x128 I THINK there was nothing there but not sure. It's not such a big deal as it is very thin but I find it annoying. Here is a screenshot. I have selected with RED those lines. I'm a noob at OpenGL(ES) so probably I did something wrong. Any help is appreciated.
This will be due to OpenGL tiling the texture to fill the specified area. So the thin line you are seeing will be the very top of that texture just starting to repeat again.
To avoid it, tell the texture to CLAMP, rather than REPEAT (repeat being synonymous with tiling). Textures repeat by default, so you will want a line something like this:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
If you're this way inclined, there is also a no-code-involved bodge way around it. Simply edit your source graphics so that no pixels are present in the top or left edges. So move the whole lot down one pixel and right one pixel inside its canvas. But then of course you will need to adjust your coordinates if you want the images to appear in exactly the same place.