Какой самый быстрый способ нарисовать двумерный массив цветовых триплетов на экране? - PullRequest
9 голосов
/ 02 февраля 2009

Целевым языком является C / C ++, и программа должна работать только на Linux, но независимые от платформы решения предпочтительнее. Я запускаю Xorg, XVideo и OpenGL доступны.

Сколько кадров в секунду можно ожидать в 1024x768 на Intel Core 2 Duo с графикой Intel? (ТОЛЬКО чертеж рассчитывает, считайте, что массивы готовы в ОЗУ; точный прогноз не требуется)

Ответы [ 6 ]

9 голосов
/ 02 февраля 2009

Самый быстрый способ нарисовать двумерный массив цветовых триплетов:

  1. Использовать плавающее ( не байт, не double) хранилище. Каждый триплет состоит из 3 поплавков от 0,0 до 1,0 каждый. Этот формат наиболее оптимально реализован для графических процессоров (но используйте оттенки серого GL_LUMINANCE, когда вам не нужен оттенок - намного быстрее!)
  2. Загрузить массив в текстуру с помощью glTexImage2D
  3. Убедитесь, что для параметра текстуры GL_TEXTURE_MIN_FILTER установлено значение GL_NEAREST
  4. Сопоставить текстуру с соответствующим квадом.

Этот метод немного быстрее, чем glDrawPixels (который по какой-то причине имеет тенденцию быть плохо реализованным) и намного быстрее, чем использование собственного блиттинга платформы.

Кроме того, он дает вам возможность многократно выполнять шаг 4 без шага 2, когда ваше растровое изображение не изменилось, что, конечно, намного быстрее.

Библиотеки, которые обеспечивают только медленное собственное билинг, включают:

  • Windows 'GDI
  • SDL на X11 (в Windows он обеспечивает быстрый бэкэнд opengl при использовании HW_SURFACE)
  • Qt

Что касается FPS, вы можете ожидать, рисуя текстуру 1024x768 на Intel Core 2 Duo с графикой Intel: около 60FPS, если текстура меняет каждый кадр, и> 100FPS, если нет.

Но просто сделай это сам и посмотри;)

6 голосов
/ 02 февраля 2009

Я сделал это некоторое время назад, используя 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;
}
1 голос
/ 30 апреля 2009

На вопрос «сколько кадров в секунду я могу ожидать» нельзя ответить серьезно. даже если вы назовете дедушку парня, который занимался компоновкой процессора. это зависит от слишком многих переменных.

  • сколько триплетов нужно отрендерить?
  • они меняются между кадрами?
  • с какой скоростью (вы не заметите изменение, если оно чаще, чем 30 раз в секунду)?
  • все ли пиксели постоянно меняются или только некоторые пиксели в некоторых областях?
  • Вы смотрите на пиксели без искажений перспективы?
  • Вы всегда видите все пиксели?
  • в зависимости от версии драйвера opengl вы получите разные результаты

это может продолжаться вечно, ответ полностью зависит от вашего алгоритма. если вы придерживаетесь подхода opengl, вы также можете попробовать другие расширения (например, http://www.opengl.org/registry/specs/NV/pixel_data_range.txt), чтобы посмотреть, подходит ли оно вам лучше; хотя уже упоминавшийся метод glTexSubImage () довольно быстрый.

1 голос
/ 02 февраля 2009

Другие опции, кроме SDL (как уже упоминалось)

  • Каир поверхности с блеском (в C, работает на всех платформах, но лучше всего в Linux)
  • QT Canvas (в C ++, мультиплатформенный)
  • OpenGL raw API или QT OpenGL (Вам необходимо знать openGL)
  • чистый Xlib / XCB, если вы хотите учесть плагины не-opengl

Мое предложение

  1. QT, если вы предпочитаете C ++
  2. Каир, если вы предпочитаете C
1 голос
/ 02 февраля 2009

Если вы пытаетесь выводить пиксели на экран, вы, вероятно, захотите использовать sdl's «поверхностная» возможность. Чтобы добиться максимальной производительности, постарайтесь расположить входные данные в макете, аналогичном выходной поверхности. По возможности избегайте установки пикселей на поверхности по одному.

SDL - это не аппаратный интерфейс сам по себе, а скорее слой переносимости, который хорошо работает поверх многих других слоев отображения, включая DirectX, OpenGL, DirectFB и xlib, поэтому вы получаете очень хорошую переносимость очень тонкий слой поверх этих технологий, поэтому вы платите очень мало накладных расходов на производительность.

0 голосов
/ 02 февраля 2009

Сколько FPS я могу ожидать на 1024x768?

Ответ на этот вопрос зависит от многих факторов, которые невозможно сказать.

...