Форум для программистов - задавайте интересные вопросы - получайте квалифицированные ответы
Помогите с рисованием пикселей в WinApi
  • NoIDNoID June 2011
    Помогите разобраться с функцией рисования пикселей. Цель следующая: я хочу создать совместимый DC и рисовать в него один раз при создании окна(так как setPixel очень медленная). И, соответственно, при получении сообщения WM_PAINT просто копировать содержимое с помощью функции BitBlt, но пока что то не очень получается.
    Я привёл тут код который по идее должен рисовать красный квадрат в клиентской области, но он не работает, подскажите пожалуйста кто знает в чём проблема. Заранее спасибо

    #include"ColorPanel.h"
    #include"resource.h"

    void Init(HDC* hdc){
    for(int i = 0; i < 256; i++){
    for(int j = 0; j < 256; j++){
    SetPixel(*hdc, i, j, RGB(255, 0, 0));
    }
    }
    }

    BOOL CALLBACK ColorPanelProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
    RECT rect;
    PAINTSTRUCT ps;
    static HDC hdc;
    static HDC comHdc;

    GetClientRect(hWnd, &rect);

    switch(msg){
    case WM_INITDIALOG:
    comHdc = CreateCompatibleDC(hdc);//создаём совместимый DC
    Init(&comHdc);//и заполняем квадрат размером 256х256 красным цветом
    return true;

    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    BitBlt(//копируем содержимое заготовленного DC
    hdc,
    0,
    0,
    256,//rect.right - rect.left,
    256,//rect.bottom - rect.top,
    comHdc,
    0,
    0,
    SRCCOPY);
    EndPaint(hWnd, NULL);
    return true;

    case WM_CLOSE:
    //ReleaseDC(hWnd, hdc);
    //ReleaseDC(hWnd, comHdc);
    PostQuitMessage(0);
    return true;
    }
    return false;
    }

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
    HWND colorDlg;
    MSG msg;
    //создаём немодальный диалог
    colorDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_COLOR_PANEL), NULL, ColorPanelProc);

    //обрабатываем сообщения
    while(GetMessage(&msg, NULL, 0, 0)){
    IsDialogMessage(colorDlg, &msg);
    }

    return 0;
    }
  • WiperWiper June 2011
    Суть подхода неверная.
    В отличие от старинного подхода к графике, в современной графике ты должен либо
    - подготовить геометрию сцены со всеми параметрами и передать её одним блоком или частями на исполнение видеокарте.
    - либо самостоятельно заполнить блок памяти значениями цвета и скормить его видеокарте как текстуру, и она это должна будет нарисовать. Например SetDIBitsToDevice.

    Сам будешь попиксельно? Или как все посоны через 3D API?

  • OFFroadOFFroad June 2011
    А ты у себя для своего HDC создал битмапу в памяти?
    Ты ж его даже не инициализировал!

    Для себя я сделал такие процедуры:


    type
    TBitmap = record
    Handle: HWND;
    DC: HDC;
    Mem: PColor;
    SizeX, SizeY: integer;
    end;

    procedure CreateBitmap(var Bitmap: TBitmap; sizeX, sizeY: integer; Bits: byte);
    var
    BI: TBitmapInfo;
    ScreenDC: HDC;
    begin
    FillChar(BI, SizeOf(BI), 0);
    Bitmap.SizeX := SizeX;
    Bitmap.SizeY := SizeY;
    with BI.bmiHeader do begin
    biSize := SizeOf(BI.bmiHeader);
    biWidth := sizeX;
    biHeight := sizeY;
    biPlanes := 1;
    biBitCount := Bits;
    end;
    ScreenDC := GetDC(0);
    with Bitmap do begin
    DC := CreateCompatibleDC(ScreenDC);
    Handle := CreateDIBSection(DC, BI, DIB_RGB_COLORS, pointer(Mem), 0, 0);
    SelectObject(DC, Handle);
    SelectObject(DC, Font);
    ReleaseDC(Handle, ScreenDC);
    end;
    end;

    // фишка в том, что после CreateBitmap ты имеешь и DC, и указатель на начало блока пикселей (Mem).
    // SetPixel выкинь на помойку
    // сразу советую использовать 32битные битмапы в памяти как наиболее удобные в большинстве случаев
    // PColor(PChar(Mem) + (X + Y*SizeX) shl 2)^ - обращение к пикселу по координатам
    // а лучше перебирай пикселы так:
    // tmp := Mem;
    // for i := 0 to SizeX*SizeY-1 do begin
    // // делаем что нужно с пикселем tmp^;
    // inc(tmp);
    // end;

    procedure DeleteBitmap(var Bitmap: TBitmap);
    begin
    with Bitmap do if Handle <> 0 then begin
    ReleaseDC(Handle, DC);
    DeleteDC(DC);
    DeleteObject(Handle);
    Handle := 0;
    end;
    end;

Добро пожаловать!

Похоже, что Вы здесь впервые. Если хотите поучаствовать, нажмите на одну из этих кнопок!

Sign In with Twitter Sign In with OpenID Sign In with Google Login with Facebook

Войти Зарегистрироваться

In this Discussion

Tagged

Webparadox - разработка мобильных приложений под iOS и Android.