android - Unity - 检测 Android 上的 OpenGL 是否不支持某个操作
问题描述
我正在使用在 pastebin 上找到的纹理缩放器代码(下面的代码),由于某种原因它在某些设备上不起作用,它会产生无效的纹理。我确定它不起作用的一种设备是 Nexus 7 平板电脑(2012 年),但它可能不适用于许多其他设备。但在绝大多数设备上它确实有效。
我不确定为什么它不起作用,或者它在什么操作上失败,但鉴于这个缩放器是在 GPU 上完成的,它比我发现的其他版本的缩放器快得多。
然后我想做的是以某种方式检测它不起作用,因此我可以运行较慢版本的缩放算法。关于任何一个的任何想法:
1)如何检测?我想在运行后检查纹理是否无效,但它在不同设备上的行为可能不同(在 Nexus 7 上,它总是将像素颜色变为 205,205,205)
2)为什么它不起作用?我在一些搜索中发现,如果纹理是 NPOT,Nexus 7 上的一些 GPU 操作会失败,但我不知道它是否与此有关。我还认为它可能与 Open GL ES 版本有关,但我不知道如何检查版本(也许 Nexus 7 是 GLES 2.0,而这个缩放器只适用于 GLES 3.0+?)。
谢谢
using UnityEngine;
// from: https://pastebin.com/qkkhWs2J
/// A unility class with functions to scale Texture2D Data.
///
/// Scale is performed on the GPU using RTT, so it's blazing fast.
/// Setting up and Getting back the texture data is the bottleneck.
/// But Scaling itself costs only 1 draw call and 1 RTT State setup!
/// WARNING: This script override the RTT Setup! (It sets a RTT!)
///
/// Note: This scaler does NOT support aspect ratio based scaling. You will have to do it yourself!
/// It supports Alpha, but you will have to divide by alpha in your shaders,
/// because of premultiplied alpha effect. Or you should use blend modes.
public class TextureScaler
{
/// <summary>
/// Returns a scaled copy of given texture.
/// </summary>
/// <param name="tex">Source texure to scale</param>
/// <param name="width">Destination texture width</param>
/// <param name="height">Destination texture height</param>
/// <param name="mode">Filtering mode</param>
public static Texture2D scaled(Texture2D src, int width, int height, FilterMode mode = FilterMode.Trilinear)
{
Rect texR = new Rect(0,0,width,height);
_gpu_scale(src,width,height,mode);
//Get rendered data back to a new texture
Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, true);
result.Resize(width, height);
result.ReadPixels(texR,0,0,true);
return result;
}
/// <summary>
/// Scales the texture data of the given texture.
/// </summary>
/// <param name="tex">Texure to scale</param>
/// <param name="width">New width</param>
/// <param name="height">New height</param>
/// <param name="mode">Filtering mode</param>
public static void scale(Texture2D tex, int width, int height, FilterMode mode = FilterMode.Trilinear)
{
Rect texR = new Rect(0,0,width,height);
_gpu_scale(tex,width,height,mode);
// Update new texture
tex.Resize(width, height);
tex.ReadPixels(texR,0,0,true);
tex.Apply(true); //Remove this if you hate us applying textures for you :)
}
// Internal unility that renders the source texture into the RTT - the scaling method itself.
static void _gpu_scale(Texture2D src, int width, int height, FilterMode fmode)
{
//We need the source texture in VRAM because we render with it
src.filterMode = fmode;
src.Apply(true);
//Using RTT for best quality and performance. Thanks, Unity 5
RenderTexture rtt = new RenderTexture(width, height, 32);
//Set the RTT in order to render to it
Graphics.SetRenderTarget(rtt);
//Setup 2D matrix in range 0..1, so nobody needs to care about sized
GL.LoadPixelMatrix(0,1,1,0);
//Then clear & draw the texture to fill the entire RTT.
GL.Clear(true,true,new Color(0,0,0,0));
Graphics.DrawTexture(new Rect(0,0,1,1),src);
}
}
解决方案
推荐阅读
- python - 如何部署对托管在 pythonanywhere 上的 django 项目所做的更改?
- javascript - 在前端重用后端模块
- javascript - Firebase 实时数据库安全性,仅使用时间戳读取过去 10 分钟的消息不起作用
- json - 使用 Swift 一次将多个字典写入 Firebase 实时数据库,使用 childByAutoId()
- javascript - 反应切换在初始状态更改时返回错误状态
- c# - UriFormatException:无效的 URI:无法解析主机名。MVC API C#
- r - 是否有可能在 r 中使用 dynlm 对象执行重置测试
- php - 如何在查询中绑定参数数组和值
- linux - 在 bash 脚本中获取相对简单的正则表达式以匹配的问题
- assembly - XNZVC 操作(汇编语言 Easy68K)