Avatar billede tycho Nybegynder
05. juni 2003 - 18:20 Der er 21 kommentarer

Optegne et vindue.

Dav.
I mit program har jeg lavet en tråd der hvert halve sekund optegner vinduet.
Mit problem er at optegnelsen går enormt langsomt (ca. 1 sekund).
Jeg benytter mig af 2 for() løkker der kalder SetPixel, og på den måde udfylder hele vinduet.
eksempel:
hdc=GetDC(hwnd);
    for(u=0;u<600;u++){
        for(i=y;i<y+800;i++){
            if(color > 255)color = 255;
            SetPixelV(hdc, (X+i),(Y+u), (long)color);
        }
    }
    ReleaseDC(hwnd,hdc);

Er der en måde hvorpå jeg kan speed'e denne proces op (jeg kan ikke forestille mig at det _skal_ tage så lang tid at optegne vinduet.
På forhånd tak.
-Niels
Avatar billede soreno Praktikant
05. juni 2003 - 18:25 #1
Hvordan har du defineret din WNDCLASS ?

Og hvordan ser din WM_PAINT metode ud ?
Avatar billede tycho Nybegynder
05. juni 2003 - 18:35 #2
WNDCLASS er defineret i WinMain.
Jeg har har ikke oprettet en WM_PAINT metode (optegner den ikke kun når man starter, flytter og ændrer størrelsen på vinduet?)
Avatar billede tycho Nybegynder
05. juni 2003 - 18:35 #3
hwnd = CreateWindow (szAppName,"BMP Load",WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
        0,0,hInstance,0);
Avatar billede soreno Praktikant
05. juni 2003 - 18:41 #4
Det er CreateWindow du har postet.
Det er WNDCLASS der er interessant (plejer at være før CreateWindow).

Jeg ville i timer (eller hvad du nu bruger) udføre dette:
InvalidateRect(hwnd, NULL, TRUE);

Og putte kode der "painter" i WM_PAINT.
Avatar billede soreno Praktikant
05. juni 2003 - 19:00 #5
Hvad er det koden skal gøre ?

Hvis du vil vise en BMP er der nemmere metoder..
Avatar billede tycho Nybegynder
05. juni 2003 - 19:14 #6
Det er ikke en BMP viser (jeg bygger bare koden oven på én :) )
a.h.t WNDCLASS:

========================
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;

RegisterClass (&wc);
========================

Jeg vil egentlig bare prøve at lave en funktion der optegner et vindue, da jeg har i sinde at udvikle det til et spil (derfor skal det opdateres hver halve sekund).
Hvad er det InvalidateRect() gør?
Avatar billede soreno Praktikant
05. juni 2003 - 19:17 #7
Ok. Jeg tror jeg har misforstået dit problem.
Jeg troede at du tegnede en ensfarvet baggrund.

Jeg har ingen erfaring i at lave egne vinduer, men jeg tror ikke at du skal repainte hver ½ sekund..
Avatar billede tycho Nybegynder
05. juni 2003 - 19:31 #8
Hvis jeg skal lave et spil, bliver jeg da nødt til at optegne vinduet.
Spørgsmålet er om der er en hurtigere måde at gøre det på.
Avatar billede soreno Praktikant
05. juni 2003 - 20:20 #9
Jeg troede du mente at du ville tegne dine egne vinduer (altså knapper, menuer osv.).

Du bør i så fald kigge lidt nærmere på enten OpenGL eller Direct3D.

Jeg foretrækker OpenGL.

http://nehe.gamedev.net/
http://www.lighthouse3d.com/opengl/tutorials.shtml
http://www.gametutorials.com/
Avatar billede tycho Nybegynder
05. juni 2003 - 20:24 #10
Nu var 3D ikke lige min hensigt. Det skulle bare være et simpelt platformspil (ikke noget stort), bare for at teste og udvide mine evner inden for programmering...
Avatar billede soreno Praktikant
05. juni 2003 - 20:28 #11
Fordelen med OpenGL er at 2D er ligeså nemt som 3D (det er faktisk bare 3D med z kordinatet sat til samme værdi hele tiden).
Avatar billede soreno Praktikant
05. juni 2003 - 20:29 #12
Avatar billede tycho Nybegynder
05. juni 2003 - 20:38 #13
tjaaa, så er det vel værd at overveje. tak for links'ne :)
Avatar billede bertelbrander Novice
05. juni 2003 - 20:51 #14
Hvis du skal have det til at gå hurtigt er du nød til at bruge bitmap's. Først laver du en bitmap med CreateCompatibleBitmap(), så laver du en memory DC med CreateCompatibleDC(), så vælger du bitmappen på din memory DC vha. SelectObject(), dernæst tegner du med din memory DC, og til sidst overfører du bitmappen fra din memory DC til den rigtige DC vha BitBlt().
Avatar billede tycho Nybegynder
05. juni 2003 - 23:27 #15
Vil det svare til noget i retningen af det her:
    HDC hdc;
    HDC Mhdc;

    int y = 0;
    int i;
    int u;

    hdc=GetDC(hwnd);
    CreateCompatibleBitmap(hdc,800,600);
    CreateCompatibleDC(Mhdc);
    SelectObject(Mhdc,hdc);
    for(u=0;u<600;u++){
        for(i=y;i<y+800;i++){
            if(color > 255)color = 255;
            SetPixelV(hdc, (X+i),(Y+u), (long)color);
        }
    }
    ReleaseDC(hwnd,hdc);
?
Avatar billede bertelbrander Novice
05. juni 2003 - 23:47 #16
CreateCompatibleDC returnerer en memory DC der er kompatibel med den DC der angives som parameter, så det skal være:
Mhdc = CreateCompatibleDC(hdc);
Når du tegner med SetPixelV skal du bruge din memory DC dvs:
SetPixelV(Mhdc, ...);
Når du så er færdig skal du overføre din bitmap fra memory (Mhdc) til skærmen (hdc) vha BitBlt.
Avatar billede tycho Nybegynder
06. juni 2003 - 16:47 #17
Kunne du give et eksempel på hvordan jeg kunne få min kode til at optegne vinduet?
Med de metoder du har givet mig, kan jeg ikke få det til at virke.
Avatar billede bertelbrander Novice
06. juni 2003 - 23:50 #18
void do_draw(HWND hwnd)
{
  HDC hdc, mdc;
  HBITMAP bitmap;
  int i, j;

  hdc = GetDC(hwnd);
  mdc = CreateCompatibleDC(hdc);
  bitmap = CreateCompatibleBitmap(hdc, 256, 256);
  SelectObject(mdc, bitmap);
  for(i = 0; i < 256; i++)
    for(j = 0; j < 256; j++)
      SetPixelV(mdc, i, j, RGB(i, j, 0));
  BitBlt(hdc, 0, 0, 256, 256, mdc, 0, 0, SRCCOPY);
  DeleteDC(mdc);
  ReleaseDC(hwnd, hdc);
}
Avatar billede tycho Nybegynder
07. juni 2003 - 00:04 #19
Tusind tak. Det var lige det jeg skulle bruge.
Avatar billede tycho Nybegynder
09. juni 2003 - 21:50 #20
Jeg har nu leget lidt rundt med det, og jeg løbet ind i et problem.
Hvis jeg indsætter noget der ligner ovenstående kode i en tråd, så køre den 880 gange hvorefter SelectObject() fejler.
Hvorfor gør den det?
Avatar billede bertelbrander Novice
10. juni 2003 - 00:23 #21
Du skal måske delete din bitmap ved at kalde DeleteObject(bitmap) i slutningen af funktionen.
Det er ligeledes en god ide at restore det object man har selected med SelectObject(), inden man kalder DeleteDC()/ReleaseDC() (jeg er dog ikke sikker på at det gør nogen forskel):

void do_draw(HWND hwnd)
{
  HDC hdc, mdc;
  HBITMAP bitmap, oldbitmap;
  int i, j;

  hdc = GetDC(hwnd);
  mdc = CreateCompatibleDC(hdc);
  bitmap = CreateCompatibleBitmap(hdc, 256, 256);
  oldbitmap = (HBITMAP )SelectObject(mdc, bitmap);
  for(i = 0; i < 256; i++)
    for(j = 0; j < 256; j++)
      SetPixelV(mdc, i, j, RGB(i, j, 0));
  BitBlt(hdc, 0, 0, 256, 256, mdc, 0, 0, SRCCOPY);
  SelectObject(mdc, oldbitmap);

  DeleteDC(mdc);
  ReleaseDC(hwnd, hdc);
  DeleteObject(bitmap);
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester