Какой самый быстрый способ нарисовать 2D массив цветовых тройняшек на экране?

StackOverflow https://stackoverflow.com/questions/503816

  •  20-08-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Самый быстрый способ нарисовать 2D массив цветовых тройняшек:

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

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

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

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

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

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

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

Другие советы

Я сделал это некоторое время назад, используя C и OpenGL, и получил очень хорошую производительность, создав четырехъядерный формат во весь экран, а затем используя texture mapping для переноса растрового изображения на лицевую сторону четырехъядерного формата.

Вот несколько примеров кода, надеюсь, вы сможете им воспользоваться.

#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;
}

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

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

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

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

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

  1. QT, если вы предпочитаете C ++
  2. Каир, если вы предпочитаете C

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

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

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

Сколько кадров в секунду я могу ожидать на 1024х768?

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top