Войти

Показать полную графическую версию : Графика в Windows API


Pury
18-03-2008, 23:33
Требуется вывести в окно большой массив точек (например 800 на 600). Функцией SetPixel это выводится очень долго. Подскажите пожалуйста, есть ли способ более быстрого вывода?

pva
19-03-2008, 07:53
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
pva, а возможны варианты с GDI+? Я видел, что в реальном коде, он принимался где нужна прозрачность, градиент для VB .NET.
И как насчёт OpenGL?

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

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

Admiral
20-03-2008, 21:19
podsyp, нечто похожее на DirectXкий z-буфер.

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

pva
24-03-2008, 07:28
возможны варианты с GDI+?Конечно, ничего невозможного нет, но пиксели выставлять ими нет смысла, там эффективней использовать более сложные примитивы
Попробуйте использовать функции BitBlt и CreateCompatibleDC Функция putpixel работает недостаточно быстро даже с memory DC




© OSzone.net 2001-2012