Android - 如何在 android studio 中更快地逐像素绘制帧(用于 NES 仿真)?

问题描述 投票:0回答:1

这是我正在做的一个 NES 模拟器项目。每秒我需要绘制大约 60 次屏幕才能获得准确的仿真,这意味着我每秒至少要绘制 256 * 240 * 60 像素。对于绘图,我使用的是画布。在每一帧上,我都会浏览 256 * 240 像素的数据并将它们绘制在屏幕上。不出所料,这太可怕了。我的模拟器每秒绘制不到一帧

public class GameCanvas extends View{
public void drawSprite(int x, int y, Olc2C02A.Sprite sprite, Canvas canvas){
        for (int ir = 0; ir < sprite.height; ir++){
            for (int ic = 0; ic < sprite.width; ic++){
                Olc2C02A.Pixel p = sprite.getPixel(ic, ir);
                if (p.a != 0){
                    int pr = p.r, pg = p.g, pb = p.b, pa = p.a;
                    painter.setColor(Color.argb(pa, pr, pg, pb));
                    canvas.drawPoint((x + ic), (y + ir), painter);
                }
            }
        }
    }

@Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.parseColor("#000000"));
        drawSprite(0, 0, this.gameScreen, canvas);
    }

}

上面的代码是我的代码的一个稍微简化的版本。在这段代码中,我只是逐个像素地绘制,而忽略了每个像素的实际大小,如果我考虑根据运行此应用程序的屏幕大小调整框架大小,则需要这些像素。 精灵是一个 256x240 大小的像素对象数组。这是我为存储每个像素的颜色值而制作的自定义类。 因此,不幸的是,仅仅轻微的性能提升对于模拟器来说是不够的。如果我想让我的模拟器正常运行,我需要每秒至少绘制 30 帧。 对于适合我的 android studio 项目的任务,我还可以使用哪些其他替代方法。

android image emulation
1个回答
0
投票

没有人绘制像素。所有游戏都使用 OpenGL。

甚至 Android 应用程序的 GUI(按钮/编辑/图片/...)也是使用 OpenGL 绘制的。

当你逐像素绘制时,你正在使用 CPU 来渲染图形。您根本没有使用 GPU(显卡)。所以这永远行不通。

你必须使用 GLSurfaceView。您必须使用 GLES20, GLES30, ...

中定义的 OpenGL 函数

参见 Android OpenGL 指南

NES 图形基于二次条纹(纹理)。这些条纹被加载到 NES 显卡中,然后可以由 GPU 内部的 CPU 调整大小、旋转和变换。所以CPU可以向GPU发送命令:“请将stripe旋转90度”(举例)。所以 CPU 从不绘制像素,而是向 GPU 发送命令。

在 Android 上,您使用 OpenGL 将此类命令发送到 GPU。这使得速度很快,因为图形计算外包给了 GPU。

另请注意,DirectX 是 Microsoft 的 OpenGL 等价物。

我还想补充一点,在执行 CPU 密集型任务时,最好使用 C/C++/Rust 而不是 Java/Kotlin。因为前者直接在 CPU 上运行而后者则没有。这样可以节省电池并且速度更快。请参阅JNI 技巧

© www.soinside.com 2019 - 2024. All rights reserved.