Другое > Программирование (любое)

Каким яп можно быстро манипулировать пикселями? (выбор яп)

(1/7) > >>

m.A:
Привет. Вот приспичило мне обрабатывать некими алгоритмами массив точек(пикселей) области экрана. Чтобы была анимация неких генерируемых процессов в реальном(хотелось бы быстро чтобы наглядно) времени. Встал вопрос выбора подходящего инструмента - языка программирования. Подходящего для задачи и подходящего такому программисту, как я(в коде ниже возможна куча ошибок).
Для теста скорости отрисовки конкретным языком(библиотекой) решил просто рисовать массив точек черного или белого цвета. Как белый шум на экране аналогового тв, когда нет сигнала. И посмотреть сколько кадров в секунду вообще возможно рисовать. Ведь я еще даже не буду обрабатывать массив точек по нужному мне алгоритму, просто рандом(белый ИЛИ черный).
Попробовал Free Pascal(Lazarus). Если в лоб, то очень медленно. С разрешением поля 800х600 всего 3.5 к/с(кадров в секунду).
Рисую 60 циклов и считаю за какое время отрисовалось:

--- Код ---
begin
  myBitmap := TBitmap.Create;
  myBitmap.SetSize(800, 600);

  M1 := Now;
  for Count := 0 to 60 do
  begin
    for x := 0 to 800 do
      for y := 0 to 600 do
      begin
        if Random > 0.5 then
          myBitmap.Canvas.DrawPixel(x, y, TColorToFPColor(clWhite))
        else
          myBitmap.Canvas.DrawPixel(x, y, TColorToFPColor(clBlack));
      end;
    PaintBox1.Canvas.Draw(0, 0, myBitmap);
    //myBitmap.Free;
  end;
  M2 := Now;
  fps := 60 / (MilliSecondsBetween(M1, M2) / 1000);
  labCap := FloatToStr(fps);
  Label1.Caption := labCap;
end;
--- Конец кода ---

Медленно. Погуглил. Есть у Free Pascal быстрые библиотеки для манипуляции пикселями. Немного замороченные, не осилил. Да и как-то не понравилось в целом.

======================================
Ну, наверное, чистый С с какой-нибудь графической библиотекой покажет скорость? Наткнулся как раз на интересный фреймворк raylib. Код на С:

--- Код ---
#include "raylib.h"

int main(void)
{
    const int screenWidth = 1600;
    const int screenHeight = 900;
   
    InitWindow(screenWidth, screenHeight, "WhiteNoise window");

    while (!WindowShouldClose())
    {
        int x, y, rnd;
        BeginDrawing();
            for (x = 0; x < screenWidth; x++) {
                for (y = 0; y < screenHeight; y++) {
                    rnd = GetRandomValue(0, 1);
                    if(rnd==1) DrawPixel(x, y, RAYWHITE);
                    if(rnd==0) DrawPixel(x, y, BLACK);
                }
            }
            DrawFPS(0, 0); 
        EndDrawing();
    }
    CloseWindow();
    return 0;
}
--- Конец кода ---
С, при большем разрешении поля 1600х900 даёт всего-то 10 к/с. Интересно, что ГСЧ там не очень хороший, изображение(картинка1) как бы смещается вправо-вверх. Но это претензии не к скорости. Язык С дает всего 10 кадров? Наверное не правильную библиотеку выбрал. Или не умею его готовить.

======================================
Посмотрел, что может FreeBasic. Старый Демон плохого не посоветует же? Код:

--- Код ---
Dim As Integer screenWidth, screenHeight
screenWidth = 1600
screenHeight = 900
Screenres screenWidth, screenHeight, 32

Dim As Integer x, y, rand

Do
    If Inkey = Chr$(27) Then Exit Do 
    For x = 0 To screenWidth
        For y = 0 To screenHeight
            rand = Rnd
            If rand = 1 Then
                Pset (x, y), Rgb(255,255,255)
            Else
                Pset (x, y), Rgb(0,0,0)
            End If
        Next y
    Next x
Loop
End
--- Конец кода ---
Как подсчитывать в FreeBasic к/с не нашел. Но визуально около 10 к/с. И еще синхронизация с монитором не совпадает, плывет. Почитал документацию. Использовал буфер, чтобы синхронизация не плыла. Рисую 600 циклов и просто засекаю отдельным секундомером:

--- Код ---
Dim As Integer screenWidth, screenHeight
screenWidth = 1600
screenHeight = 900
ScreenRes screenWidth, screenHeight, 32

Dim As Integer x, y, rand, count

Dim image As Any Ptr = ImageCreate( screenWidth, screenHeight, RGB(0, 0, 0) )

For count = 1 To 600
   For x = 0 To screenWidth
      For y = 0 To screenHeight
         rand = Rnd
         If rand = 1 Then
            PSet image, (x, y), RGB(255, 255, 255)
         Else
            PSet image,  (x, y), RGB(0, 0, 0)
         End If
      Next y
   Next x
   
   Put (0, 0), image, PSet
   
Next count
End
--- Конец кода ---

FreeBasic: 600 циклов за ~45 секунд. ~13 к/с. FreeBasic медленный.

======================================
Что там далее? Попробовал язык Processing (Java):

--- Код ---
void setup() {
  size(1600, 900);
  frameRate(60);
  background(0);
}

void draw() {
  if (keyCode == ESC) exit();
  int rnd;
  for (int x = 0; x < width; x++)
  {
    for (int y = 0; y < height; y++)
    {
      rnd = (int)random(2);
      if(rnd==1) set(x, y, color(255,255,255));
      else set(x, y, color(0,0,0));
    }
  }
  String txt = String.format("Window 1   %6.2fps", frameRate);
  windowTitle(txt);
  println(frameRate);
  text(frameRate,0,0);
}
--- Конец кода ---

Processing: 32 к/с! Это рекорд, Java быстрее всех. А если еще переписать так:


--- Код ---
void setup() {
  size(1600, 900);
  frameRate(60);
  background(0);
}

void draw() {
  if (keyCode == ESC) exit();
  loadPixels();

  for (int i = 0; i < pixels.length; i++) {
    float rand = random(255);
    color c = color(rand);
    pixels[i] = c;
  }

  updatePixels();
  println(frameRate);
  text(frameRate, 0, 0);
}
--- Конец кода ---

То здесь получаем 53 к/с. Выбираю Processing.

Может кто-то перепишет примеры кода правильнее, чтобы быстрее было? Я где-то ошибся? Может кто-то напишет код на другом языке/фреймворке? Алгоритм я думаю понятен. Еще напишу, что хочется писать алгоритм обработки массива(вместо rand), а не  длиннющие портянки кода инициализации и работы с OpenGl напрямую.

Samovar:

--- Цитировать ---Посмотрел, что может FreeBasic. Старый Демон плохого не посоветует же?
FreeBasic: 600 циклов за ~45 секунд. ~13 к/с. FreeBasic медленный.
--- Конец цитаты ---
Считай так... не вопрос :) Java все равно проиграет :) хотя, х.з. ... у всякого ЯП есть подводные камни...
Даже на конструкторе  GameEditor  мне попадался пример с симуляцией жидкости попиксельно (но там виртуальная машина Cи стоит, даже,а не Си)... и это работает быстро, т.к.
 OpenGL...
-------
Пока я не буду с тобой спорить... но как будет время разобраться и проверить, обязательно вернусь к этому вопросу.

Anchoret:
Когда все это дело делалось на слабых машинах, то имитировалась через строчная развертка - чтобы более плавно все это дело появлялось на экране. Например на древнем ZX Spectrum кроме того, что все писалось на ассемблере, была некая экранная память - диапазон адресов экранного адресного пространства. Вот в эту "экранку" все напрямую и выгружалось строками байтов. Но это седая древность, тогда еще не было различных разрешений экрана и пр.. Как это все сейчас возможно реализовать в самом понятном для компе языке мне не ведомо)

Samovar:
Anchoret, на Freebasic и так, и этак и через укакзатель на видобуфер... и прямой к нему доступ через poke()...или ассемблер...
Просто у меня нет времени с этим ковыряться сейчас... я ж не программист, а любитель  :)

LanuHum:
Как дилетант могу предложить C++ openGL . Можно поковыряться в  projectM Visualizer
An open-source library for music visualization using Milkdrop-style presets and shaders
https://github.com/projectM-visualizer

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии