iPhone 6s / RoboVM(?)GLTexImage2D渲染问题

路易吉尼

我们最终在App Store上发布了我们的独立游戏,只是发现我们在iPhone 6s上存在重大渲染问题。

该游戏是使用LibGDX和RoboVM(v.1.12)开发的

我们正在使用iOS本机图形库将unicode文本呈现为纹理,以将其传递给LibGDX以显示为图像。为此,我们首先创建要打印的字符串,然后调用其draw()方法:

    final String tmp = text.substring(0, text.length() >= MAX_NAME_LEN ? MAX_NAME_LEN : text.length());

    final NSMutableString string = new NSMutableString(tmp.length());
    //Allocate space for the bitmap to draw on
    int w = (int) width;
    int h = (int) height;
    final int bufferLen = w * h;
    final CGBitmapContext context = new CGBitmapContext(
        w, h, 8, 0, CGColorSpace.deviceRGB(), CGImageAlphaInfo.PremultipliedLast
    );

    final CGColor bgColor = UIColor.clear().getCGColor();

    final CGRect rect = new CGRect(0, 0, width, height);

    string.setString(tmp);

    final UIColor textColor = new UIColor(color.r, color.g, color.b, color.a);
    final UIFont font = UIFont.getBoldSystemFont(size);

    final NSString tester = new NSString("a");
    final CGSize textSize = tester.getSize(font);
    int strLen = string.toString().length();

    /**
     * Computes the optimal length of the string and removes characters beyound the
     * screen bounduaries.
     * If the string has been reduced, appends an ellipsis at the end
     */
    final NSRange range = new NSRange();
    boolean removed = false;
    while (strLen > 0 && textSize.getWidth() * strLen > width - textSize.getWidth() * 2) {
        range.setLocation(strLen - 1);
        range.setLength(1);
        string.deleteCharacters(range);

        strLen = string.toString().length();
        removed = true;
    }
    //append ellipsis at the end if we removed a char
    if (removed) {
        string.append("\u2026");
    }

    context.setFillColor(bgColor);
    context.fillRect(rect);
    //set up drawing attributes
    final NSAttributedStringAttributes attributes = new NSAttributedStringAttributes();
    attributes.set(NSAttributedStringAttribute.Font, font);
    attributes.set(NSAttributedStringAttribute.ForegroundColor, textColor);
    final NSMutableParagraphStyle paragraphStyle = new NSMutableParagraphStyle();
    paragraphStyle.setParagraphStyle(NSParagraphStyle.getDefaultParagraphStyle());
    paragraphStyle.setLineBreakMode(NSLineBreakMode.TruncatingTail);
    attributes.set(NSAttributedStringAttribute.ParagraphStyle, paragraphStyle);

    final NSAttributedString finalStr = new NSAttributedString(string.toString(), attributes);

    UIGraphics.pushContext(context);
    context.setTextMatrix(CGAffineTransform.Identity());
    context.translateCTM(0f, h);
    context.scaleCTM(1, -1);
    finalStr.draw(new CGPoint(rect.getX(), (rect.getY() + textSize.getHeight()) / 2));
    UIGraphics.popContext();


    return new BufferTextureData((int)context.getWidth(), (int)context.getHeight(), 0, GL20.GL_RGBA, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, context.getData().asIntBuffer(bufferLen));

然后,TextureBufferData通过以下方式将Buffer绑定到纹理:

private Buffer data;

public BufferTextureData(int width, int height, int mipMapLevel, int internalFormat, int format, int type, Buffer data) {
    this.width = width;
    this.height = height;
    this.mipLevel = mipMapLevel;
    this.internalFormat = internalFormat;
    this.format = format;
    this.type = type;
    this.data = data;
}

[...]

@Override
public void consumeCustomData(final int target) {
    Gdx.app.debug("BufferTextureData", "consuming data for target: " + target);
    Gdx.gl20.glTexImage2D(target, mipLevel, internalFormat, width, height, 0, format, type, data);
    data = null;
}

我们在以下设备上测试了此代码,没有任何问题:-iPhone 6-iPad Air 2-iPhone 5s以及iPhone 6s模拟器。

问题是,在iPhone 6s的实际设备上,我们得到以下信息:

在此处输入图片说明

如您所见,文本完全失真。似乎在绘图调用期间写入了保存绘图数据的缓冲区,但是我们确保在绘图线程上调用该方法以避免GL上下文切换。

我们真的不知道在哪里寻找。该代码可在iPhone6s模拟器(x64 CPU)和所有其他设备上无缝运行的事实使我认为问题可能是硬件相关的还是由RoboVM处理内存的方式引起的,但这只是一个猜测。

是否有人遇到过同样的问题,或者是否有可能导致这种现象的想法?

提前致谢

路易吉尼

感谢@datenwolf为我们指出正确的方向。

问题是由于iPhone 6s的“已知错误”造成的:

http://ios9news.net/fix-ios-9-apps-zoomed-in-on-iphone-6s/

也就是说,在给定与iPhone 6相同的分辨率和ppi的情况下,6s认为他宽一些。因此,我们制作为POT倍数的游戏单位在6s设备中的长度是奇数个(例如,iphone 6上480px的宽度在iphone 6s上为561px)。

在创建图形上下文时,CGContextCreate我们没有指定要考虑的每行多少字节,而是让设备为我们决定。事实证明,操作系统正在向每一行添加填充,使所有跨度和对齐方式混乱。

解决方法是更改​​:

final CGBitmapContext context = new CGBitmapContext(
        w, h, 8, 0, CGColorSpace.deviceRGB(), CGImageAlphaInfo.PremultipliedLast
    );

至:

final CGBitmapContext context = new CGBitmapContext(
        w, h, 8, 4 * w, CGColorSpace.deviceRGB(), CGImageAlphaInfo.PremultipliedLast
    );

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

流式传输时iPhone 6S音频问题

在iPhone 6S或iPhone 6S Plus模拟器上模拟强制触摸/ 3D触摸

iPhone 6s plus设备中的UIPickerView UI和功能问题

3d Touch在iPhone 6s +上不可用

Angular2动画(变换)在iPhone 6s上无法使用

iPhone 6S和iPhone 6S Plus的平台字符串是什么?

iPhone 6s plus上的字体大小

原始/未经编辑的iPhone 6S / 6S Plus照片的图像长度/宽度(以像素为单位)是多少?

iPhone 6s Plus尺寸屏幕在iPhone 6 Plus上被切断

为iPhone 4S缩放文本输入-iPhone 6S Plus

Swift 2.0 Popover视图无法在iPhone 6s plus上获得正确的位置,但在iPhone 6s上可以正常工作

Xcode 10.3 无法在 iOS 13 iPhone 6s 上运行 - 此 iPhone 6s 运行的是 iOS 13.1,此版本的 Xcode 10.3 可能不支持

XCODE iphone 6 plus和6s plus在显示UIAlertViewController时显示警告

如何处理iPhone 6S Plus的字体大小?

像peek和pop一样手动振动iPhone 6S?

iOS 10 iPhone 6S Play Haptic feedback or vibrate using taptic engine

错误:找不到与“iPhone 6s”匹配的模拟器

touchesMoved在iPhone 6s及更高版本上通过一次Tap调用

如何在Macbook的iPhone 6s Simulator上找到SQLite数据库?

自动布局在 iPhone 6s Plus 中没有按预期工作

iOS 9 Spritekit双击无法在iPhone 6S上运行

iPhone 6S / iOS 9.1:找不到代码为0xdeadfa11的崩溃日志

Xcode自动调整大小的XIB在iPhone 6s Plus上不正确

iOS 10 iPhone 6S使用Taptic引擎播放触觉反馈或振动

在HTML模式下为iPhone 6s Plus在HTML模式下创建整页图像

背景图像不会显示在移动设备上 (iPhone 6s)

应用程序在iPhone 5c的主线程上冻结,但在iPhone 6s上不冻结

UIImageview上的CAGradient层在iphone 6s plus中向上移动,同时在iphone 5中正确设置

iPhone 6S vs 7+ vs X X vs iPad Pro的FaceTime相机的FPS是多少?