Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Графика в Windows API (http://forum.oszone.net/showthread.php?t=103143)

Pury 18-03-2008 23:33 763345

Графика в Windows API
 
Требуется вывести в окно большой массив точек (например 800 на 600). Функцией SetPixel это выводится очень долго. Подскажите пожалуйста, есть ли способ более быстрого вывода?

pva 19-03-2008 07:53 763445

1. определись, совместимый код будет или быстрый (не на много)
2. определись как часто будешь переисовываться
3. определись с глубиной цвета (8/16/32 bpp)

дальше варианты выбора:

1. используешь функции GDI или DirectX
2. если GDI, то CreateDIBitmap (типа кэширование) либо SetDIBitsToDevice
3. подстрой свой алгоритм под глубину цвета

Код:

class DrawScreen
{
    enum {
      scr_width = 800, scr_height=600
    };

    long screen_[scr_width*scr_height];
    BITMAPINFOHEADER bmi_;

public:
    DrawScreen();
    long& pixel(int x, int y) {return screen_[max(0,min(x, scr_width)) + scr_width*max(0,min(y, scr_height))];}
    long& pixel_(int x, int y) {return screen[x + scr_width*y];}
    void show();
    static long Rgb(int r, int g, int b) {return max(0,min(255,r)) | (max(0,min(255,g))<<8)  | (max(0,min(255,g))<<16);}
}

DrawScreen::DrawScreen() : screen_(), bmi_()
{
    bmi_.biSize = sizeof(bmi_);
    bmi_.biWidth = scr_width;
    bmi_.biHeight = scr_height;
    bmi_.biPlanes = 1;
    bmi_.biBitCount = 32;
}

void DrawScreen::show()
{
    HDC dc = GetDC(0);
    SetDIBitsToDevice(dc, 0, 0, scr_width, scr_height, 0, 0, 0, scr_height, screen_, (BITMAPINFO*)&bmi_, DIB_RGB_COLORS);
    ReleaseDC(0, dc);
}

// рисуем:

DrawScreen screen;
for (int x=0; x<800; ++x) screen.pixel(x, 10) = DrawScreen::Rgb(x, 255-x, 128-x);

screen.show();


Admiral 19-03-2008 16:14 763671

pva, а возможны варианты с GDI+? Я видел, что в реальном коде, он принимался где нужна прозрачность, градиент для VB .NET.
И как насчёт OpenGL?

Pury 19-03-2008 19:10 763800

Спасибо за ответ. На самом оказалось что мне не хватало функции ReleaseDC(hWnd,DC). Ее нет в стандартном коде и это сильно запутывает понимание.

podsyp 20-03-2008 21:17 764569

Попробуйте использовать функции BitBlt и CreateCompatibleDC. Вторая создаёт виртуальный контекст устройства, на котором и можно рисовать: SetPixel, DrawLine и т.п. После чего копируйте образ из виртуального в обычный контекст с помощью функции BitBlt. Функция BitBlt очень быстрая. На виртуальном контексте тоже всё очень быстро "прорисовывается". Деталей я не помню, но идея именно такая. Удачи.

Admiral 20-03-2008 21:19 764572

podsyp, нечто похожее на DirectXкий z-буфер.

DillerInc 21-03-2008 00:01 764674

Раз мы уже начали говорить о графике в win32, то не мог бы кто-то пояснить,чем принципиально отличается GDI от OpenGL?
Например,при создании окна необходимо похоже проинициализировать пиксельный формат с помощью структуры PIXELFORMATDESCRIPTOR.Так вот в ней можно выставить флаг либо PFD_SUPPORT_GDI, либо PFD_SUPPORT_OPENGL...

pva 24-03-2008 07:28 766497

Цитата:

Цитата Admiral
возможны варианты с GDI+?

Конечно, ничего невозможного нет, но пиксели выставлять ими нет смысла, там эффективней использовать более сложные примитивы
Цитата:

Цитата podsyp
Попробуйте использовать функции BitBlt и CreateCompatibleDC

Функция putpixel работает недостаточно быстро даже с memory DC


Время: 03:20.

Время: 03:20.
© OSzone.net 2001-