Monitor Elektronenstrahl Position?



  • Statt dem InvalidateRect-Aufruf kannst du das Bild auch gleich in WM_TIMER zeichnen!

    Keine gute Idee. Er macht das schon richtig so. Begründung hab ich aber auch nicht. :p



  • Erstmal Danke für eure Antworten 🙂

    Also, ich hab jetzt, nur um es mal zu testen, die WM_ERASEBKGND message eingefügt, aus der WM_TIMER das InvalidateRect() rausgenommen und zeichne das Bild jetzt mit BitBlt(hdc,...) also direkt auf den Bildschirm. Aber das flackert immer noch an den Rändern.

    Wie gesagt, es flackert nicht ständig, es kann gut mal sein, dass es 2-3 Bewegungszyklen (also von einem Bildschirmrand zum anderen und zurück) durchläuft ohne zu flackern, und dann flackerts, und zwar sieht mans an den Rändern und es flackert von oben nach unten. Das muss doch was mit dem Bildaufbau des Monitors zu tun haben, oder?

    Hat denn niemand hier schonmal sowas gesehen, der sich schnell bewegende Bitmaps auf den Screen programmiert hat? Wenn nicht, was mache ich dann nur falsch?



  • benutzt du irgendwo in deinem code CS_HREDRAW oder CS_VREDRAW? vielleicht mal rausnehmen 🙄



  • ja, in der Windowclass... rausnehmen hat aber auch nichts bewirkt



  • Hier mal was zum lesen, ist jedoch englisch:
    http://www.compuphase.com/vretrace.htm#VRETRACE_WHY

    und in Assembler würde man den vertical retrace so abfragen (aus dem Artikel):

    mov     dx, 3dah        ; VGA input status register
    vretrace_loop:
                    in      al, dx
                    test    al, 8           ; bit 3 set?
                    jz      vretrace_loop   ; no, continue waiting
    

    Jemand ne Idee, wie man das in C hinbekommt als Teil eines WinAPI-Programms?



  • quatsch sowas brauchst du nicht



  • @TimTaylor
    Bitte lies Dir doch mal ein Tutorial durch. Da steht überall (und ausserdem wurde es hier im Forum schon häufig behandelt), dass jede Selektierung in einen DC mit einer Deselektierung abgeschlossen werden muss.

    Richtiger und verbesserter Code:

    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HDC hdc,hdcMem,hdcBackbuffer;
    PAINTSTRUCT ps;
    
    static HBITMAP Bild;
    HBITMAP Backbuffer;
    BITMAP bitmap;
    static ufo_xpos,ufo_ypos=0;
    static float i,j=0;
    static RECT rect;
    HGDIOBJ hBmpOld, hBmpOld2;
    
    switch (message)
    {
    case WM_CREATE:
        SetTimer( hwnd,1,40,NULL);
        Bild = LoadImage (hInst,"testbild.bmp",IMAGE_BITMAP, 100,100, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
        GetObject(Bild, sizeof (BITMAP), &bitmap);
    
        hdc=GetDC(hwnd);
        hdcBackbuffer=CreateCompatibleDC(hdc);
        Backbuffer=CreateCompatibleBitmap(hdc,1024,768);
    
        hBmpOld = SelectObject( hdcBackbuffer,Backbuffer);
        SetRect (&rect,0,0,1024,768);
        FillRect(hdcBackbuffer, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
        // !!! WICHTIG !!!
        SelectObject( hdcBackbuffer, hBmpOld);
    
        DeleteDC(hdcBackbuffer);
        ReleaseDC(hdc,hwnd);
        break;
    case WM_PAINT:
        hdc=BeginPaint (hwnd, &ps);
        hdcBackbuffer=CreateCompatibleDC(hdc);
        hdcMem = CreateCompatibleDC(hdc);
    
        hBmpOld = SelectObject (hdcBackbuffer,Backbuffer);
        hBmpOld2 = SelectObject (hdcMem, Bild);
        FillRect(hdcBackbuffer, &rect, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
        BitBlt (hdcBackbuffer,ufo_xpos,ufo_ypos,100,100,hdcMem,0,0,SRCCOPY);
        BitBlt (hdc,0,0,1024,768,hdcBackbuffer,0,0,SRCCOPY);
        // !!! WICHTIG !!!
        SelectObject( hdcMem, hBmpOld2);
        SelectObject( hdcBackbuffer, hBmpOld);
        DeleteDC (hdcBackbuffer);
        DeleteDC (hdcMem);
        EndPaint (hwnd, &ps);
        break;
    case WM_TIMER:
            switch (wParam)
            {
            case 1:
            if(i>6.27) i=i-6.28;
            ufo_xpos = (sin (i)*300)+450;i=i+0.04;
            if(j>=3.13) j=j-3.14;
            ufo_ypos = (sin (j)*200);j=j+0.02;
            InvalidateRect (hwnd,&rect,FALSE);
            // Manchmal besser, um flüssigeren Bewegungsablauf zu garantieren
            UpdateWindow( hwnd);
            break;
            }
            break;
    
    case WM_DESTROY:
    
        DeleteObject (Bild);
        DeleteObject(Backbuffer);
    
        PostQuitMessage (0);
    
        break;
    }
    


  • Wenn ich deinen verbesserten Code benutze wird, das bitmap gar nicht mehr gezeichnet, der screen bleibt schwarz. naja, wenigstens flackert es nicht mehr 😃

    Trotzdem Danke für deinen Tipp, mal sehen ob ich es nicht doch noch ans Laufen bringe...



  • Nagut, ein static vor HBITMAP Backbuffer hat gefehlt... hast du es aus einem bestimmten Grund weggelassen?

    Ansonsten läufts genauso wie vorher, es flackert manchmal... naja, was solls, wenn es denn nicht besser zu realisieren ist, muss ich wohl die Flinte ins Korn werfen. Oder mich mit DirectX befassen, denn da gibts Befehle, um ein Programm mit dem vertikalen Bildaufbau zu synchronisieren.

    Danke nochmal an alle, die hier mitgeschrieben haben.



  • Hallo,

    biste schon mal auf die Idee gekommen, dass der Monitor kaputt sein könnte?



  • Nagut, ein static vor HBITMAP Backbuffer hat gefehlt... hast du es aus einem bestimmten Grund weggelassen?

    Nein, hab ich nur übersehen.

    P.S. Das flackern geht im normalen DC nie ganz weg.


Anmelden zum Antworten