2015-02-02 3 views
2

До сих пор я использовал SDL 2.0, скопировал свой пиксельный массив в текстуру, которая затем отображается на экране. Мой метод визуализации выглядит следующим образом:Как визуализировать пиксельный массив наиболее эффективно для окна в C++?

for (int i = 0; i < WIDTH*HEIGHT; i++){ 
     pixels[i] = 0xFFFF0000; 
     //pixel Format: AARRGGBB 
    } 
    SDL_UpdateTexture(sdlTexture, NULL, pixels, 800 * sizeof(Uint32)); 

    SDL_RenderClear(renderer); 
    SDL_RenderCopy(renderer, sdlTexture, NULL, NULL); 
    SDL_RenderPresent(renderer); 

Затем я измерил время, необходимое, чтобы сделать это один раз в наносекунд (через хроно) и сравнил его с аналогичным образом рендеринга пикселей в Java: (массив пикселей сохраняет пиксели «displayImage»)

BufferStrategy bs = getBufferStrategy(); 
    if (bs == null){ 
     createBufferStrategy(3); 
     return; 
    } 
    screen.clear() 
    for (int i = 0; i < WIDTH*HEIGHT; i++){ 
     pixels[i] = 0xFF0000; 
     //pixel Format: RRGGBB 
    } 
    Graphics2D g = (Graphics2D) bs.getDrawGraphics(); 
    g.drawImage(displayImage,0,0,getWidth(),getHeight(),null); 



    g.dispose(); 
    bs.show(); 

Удивительно я тогда увидел, что она занимает около 600,000 наносекунд, чтобы сделать это в Java и около 2.000.000 наносекунд, чтобы сделать это в C++.

Итак, мой вопрос в том, является ли более эффективный способ рисовать пиксельный массив, как я получил на экране с тех пор (я предполагаю) C++ должен отображать его быстрее, чем Java.

Кроме того, это, как я измерил время: C++:

auto start = std::chrono::steady_clock::now(); 

//render function 

auto end = std::chrono::steady_clock::now(); 
auto result = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count(); 
std::cout << result << std::endl; 

Java:

long start = System.nanoTime(); 

//render function 

long end = System.nanoTime(); 
long result = end - start; 
System.out.println(result); 
+0

Сколько текстур вы рисуете? С включенным vsync 2.000.000 наносекунд все еще меньше, чем один кадр. – Lanting

+0

Я только инициализирую одну текстуру, на которой я рисую. Что я написал, это в основном моя функция рендеринга, так как я просто использую ее для проверки производительности прямо сейчас. –

+0

Во-первых, на C++ вы очищаете экран, но в java вы этого не делаете. – ElderBug

ответ

1

Во-первых, следует отметить, что измерение времени настолько коротки, не всегда надежны, поэтому значения следует принимать с помощью соли. Даже если Java и C++ используют один и тот же системный таймер, могут быть несвязанные различия.

Что касается кода, SDL_UpdateTexture выдаст копию во внутренний буфер и, следовательно, немного медленнее. Вместо этого вы должны использовать SDL_LockTexture и SDL_UnlockTexture. Это позволит получить прямой доступ к внутреннему буферу.

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

Если вам нужно заполнить экран только одной строкой, вы можете использовать инструкцию по сборке rep stos, которая намного быстрее, чем цикл. С Visual C++ вы можете испустить rep stos для uint32, используя __stosd. Это работает как memset, но для uint32 (у вас также есть версия uint16 с __stosw и uint64 с __stosq, x64). Существует эквивалент __movsd, чтобы сделать копию, но хорошо реализована memcpy может быть еще быстрее.

Смежные вопросы