代码之家  ›  专栏  ›  技术社区  ›  Johannes Weiss

在屏幕上绘制一个二维颜色三元组数组的最快方法是什么?

  •  9
  • Johannes Weiss  · 技术社区  · 16 年前

    目标语言是C/C++,程序只在Linux上工作,但平台无关的解决方案是明显的。我运行xorg、xvideo和opengl。

    我能在1024x768的英特尔酷睿2与英特尔图形的二人组上期望多少帧?(仅绘制计数,考虑阵列在RAM中准备就绪;无需精确预测)

    6 回复  |  直到 9 年前
        1
  •  9
  •   Iraimbilanja    16 年前

    绘制二维颜色三元组数组的最快方法:

    1. 使用浮标(浮标) 字节, 双重)储存。每个三元组由3个从0.0到1.0的浮点组成。这是GPU最理想地实现的格式(但使用灰度 GL_LUMINANCE 当你不需要色调的时候存储-快得多!)
    2. 将数组上载到纹理 glTexImage2D
    3. 确保 GL_TEXTURE_MIN_FILTER 纹理参数设置为 GL_NEAREST
    4. 将纹理映射到适当的四边形。

    这个方法比 glDrawPixels (由于某种原因,这种做法往往实施得不好)和 很多 比使用平台的本地Blitting更快。

    此外,它还允许您在PixMap未更改时重复执行步骤4而不执行步骤2,这当然要快得多。

    仅提供慢速本地Blitting的库包括:

    • Windows的GDI
    • x11上的SDL(在Windows上,它在使用HW_Surface时提供了一个快速的OpenGL后端)
    • QT

    对于您可以期待的fps,在Intel Core 2 Duo上绘制1024x768纹理,并带有Intel图形:如果纹理改变了每帧,则约为60fps;如果没有,则约为100fps。

    但你自己动手看看;)

        2
  •  6
  •   jandersson    16 年前

    我用C和OpenGL做了一段时间,通过创建一个全屏幕大小的四边形获得了非常好的性能,然后使用纹理映射将位图传输到四边形的表面上。

    下面是一些示例代码,希望您可以利用它。

    #include <GL/glut.h>
    #include <GL/glut.h>
    
    #define WIDTH 1024
    #define HEIGHT 768
    
    unsigned char texture[WIDTH][HEIGHT][3];             
    
    void renderScene() {    
    
        // render the texture here
    
        glEnable (GL_TEXTURE_2D);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
        glTexImage2D (
            GL_TEXTURE_2D,
            0,
            GL_RGB,
            WIDTH,
            HEIGHT,
            0,
            GL_RGB,
            GL_UNSIGNED_BYTE,
            &texture[0][0][0]
        );
    
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0, -1.0);
            glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0, -1.0);
            glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0,  1.0);
            glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0,  1.0);
        glEnd();
    
        glFlush();
        glutSwapBuffers();
    }
    
    int main(int argc, char **argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(WIDTH, HEIGHT);
        glutCreateWindow(" ");
    
        glutDisplayFunc(renderScene);
    
        glutMainLoop();
    
        return 0;
    }
    
        3
  •  1
  •   TokenMacGuy    16 年前

    如果你试图将像素转储到屏幕上,你可能会想利用 sdl's “表面”功能。为了获得最佳性能,请尝试将输入数据安排在与输出图面类似的布局中。如果可能的话,不要一次设置一个表面上的像素。

    SDL本身并不是一个硬件接口,而是一个可移植性层,它在许多其他显示层(包括DirectX、OpenGL、DirectFB和XLIB)之上都能很好地工作,因此您可以获得非常好的可移植性,而且在这些技术之上它是一个非常薄的层,因此在这些技术之上您只需支付很少的性能开销。

        4
  •  1
  •   kazanaki    16 年前

    除SDL以外的其他选项(如前所述)

    • Cairo 带glitz的曲面(在C中,适用于所有plaform,但在Linux中效果最好)
    • QT Canvas (C++中,多重形式)
    • OpenGL原始API或 QT OpenGL (您需要了解OpenGL)
    • 如果要考虑非OpenGL Plaforms,则使用纯XLIB/XCB

    我的建议

    1. 如果你喜欢C++
    2. 开罗如果你喜欢C
        5
  •  1
  •   akira    15 年前

    “我能期望多少帧”的问题不能认真回答。即使你说出了那个做处理器布局的人的祖父的名字也不行。它依赖于太多的变量。

    • 你需要渲染多少个三胞胎?
    • 它们在帧之间变化吗?
    • 以哪种速度(如果变化频率超过每秒30次,您不会注意到变化)?
    • 所有的像素都会随时改变,还是只是某些区域的一些像素?
    • 你看像素时没有任何透视失真吗?
    • 你总是能看到所有的像素吗?
    • 根据OpenGL驱动程序的版本,您将得到不同的结果

    这可能会一直持续下去,答案完全取决于你的算法。如果坚持使用OpenGL方法,还可以尝试不同的扩展( http://www.opengl.org/registry/specs/NV/pixel_data_range.txt 例如,我们会想到),看看它是否更适合您的需要;尽管前面提到的gltexSubImage()方法非常快。

        6
  •  0
  •   Bombe    16 年前

    在1024x768上我能期望多少帧?

    这个问题的答案取决于太多的因素,以至于无法分辨。