MonoGame - Android SamplerState.LinearWrap
-
24-06-2021 - |
سؤال
We use SamplerState.LinearWrap
to tile alot of things in our game. Our game shares a single SpriteBatch
object, and calls Begin()
like this:
_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, _rasterState);
This works great for XNA on Windows as well as MonoGame on iOS.
Problem is, on Android, if LinearWrap is turned on, any non-power of two sized texture render as a black rectangle, even if it is drawn in a way where it would not need to be wrapped. If we switch to SamplerState.LinearClamp
(the default), these textures no longer render black on Android. Normally non-power of two textures leave empty space up to the next largest power of two if you try to tile them (on other platforms).
Is this a limitation of OpenGL on Android, or is an issue in MonoGame? I would hate to resize every texture to be a power of two, but we would do it if it is the only option (or there is a very good reason to).
المحلول
Digging through MonoGame, I found this in ESTexture2D.cs:
_width = imageSource.Width;
_height = imageSource.Height;
// There are rules for npot textures that we must abide by (wrap = ClampToEdge and filter = Nearest or Linear)
if (!MathHelper.IsPowerOfTwo(_width) || !MathHelper.IsPowerOfTwo(_height))
{
//filter = ALL11.Linear;
//wrap = ALL11.ClampToEdge;
_width = (int)Math.Pow(2, Math.Min(10, Math.Ceiling(Math.Log10(imageSource.Width) / Math.Log10(2))));
_height = (int)Math.Pow(2, Math.Min(10, Math.Ceiling(Math.Log10(imageSource.Height) / Math.Log10(2))));
}
I commented out the changes to filter
and wrap
, and adjusted the size to be a power of two.
This resolved my issue, but I'm not sure if is a valid fix for MonoGame. I don't know what effect it would have if you were using SamplerState.LinearClamp
.
نصائح أخرى
I believe this has been fixed in the develop3d branch.
D.