Blt und For



  • Ich hab da mal ne Fräge:

    wird beim Blitten:

    lpDDSurface->Blt(&rcRectBlit , // Wo hinblitten
                     lpDDSurface2, // In welches Surface
                     &rcRectBild , // Wie groß das Stück von dem Bild ist
                     DDBLT_WAIT  , // Solange warten bis er blitten kann
                     NULL);        // Irgendwie nurwas für Farben blitten :D
    

    wird das lpDDSurface dann bei jeden blitten gelöscht und neu gemalt?

    und was ist wenn man das in eine for scheleife reinschreibt, gibt es da probleme?

    THX for anwers 😃



  • nein, es wird nichts gelöscht. Es wird einfach draufgeklatscht. Und bei ner for-Schleife eben 20 Milliarden mal.



  • Thx, jetzt hab ich nun folgendes Problem:

    Ich lasse erst 2 Bilder anzeigen, das was ganz unten sein soll, natürlich ganz zuerst, dann kommt ein transparentes Bild, und dann wird eine Reihe lang ausgeschnittene Grafiken aus einem Tilebild.... Naja, hier der Code:

    struct BMP
    {
    	LPDIRECTDRAWSURFACE7 Surface; //in welcher Surface gespeichert?
    	RECT rcSrc;     //Quelle des Bildes
    	short Breite;   //Die Breite des Bildes
    	short Hoehe;	//Die Hoehe des Bildes
    	short Timer;
    };
    
    LPDIRECTDRAW7			lpDirectDraw;	// DirectDraw-Objekt
    HRESULT					ddrval;
    LPDIRECTDRAWSURFACE7	lpddsPrimary;
    LPDIRECTDRAWSURFACE7	lpddsBack;
    LPDIRECTDRAWSURFACE7	lpddsBitmap;
    LPDIRECTDRAWSURFACE7	lpddsBg;
    LPDIRECTDRAWSURFACE7	lpddsTiles;
    DDSURFACEDESC2		ddsd;
    DDSCAPS2			ddscaps; 
    DDBLTFX			ddbltfx;
    LPDIRECTDRAWCLIPPER	lpddClipper;
    RECT			rcRectBild,rcRectBlit,rectbitmap,fill_area;
    HINSTANCE			g_hInst;
    HWND			hwnd;
    bool			running;
    BMP			Bmp[BILDANZ];
    int			px,py = 0;
    short			sx,sy,x,y = 0;
    LIST                       ErrorList[DDERR_ALL];
    
    bool ddInit (HWND hwnd)
    {
    	hwnd = hwnd;
    	if (ddrval = DirectDrawCreateEx(NULL, (VOID**)&lpDirectDraw, IID_IDirectDraw7, NULL) != DD_OK)
    	{
    
    		return (0);
    	}    
    
    	ddrval = lpDirectDraw->SetCooperativeLevel (hwnd, DDSCL_EXCLUSIVE |	DDSCL_FULLSCREEN);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return (0);
    	}
    
    	ddrval = lpDirectDraw->SetDisplayMode (800, 600, 16, 0, 0);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return (0);
    	}
    
    	ZeroMemory(&ddsd, sizeof(ddsd));
    	ddsd.dwSize = sizeof(ddsd);
    	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
    	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
    	ddsd.dwBackBufferCount = 1; 
    	ddrval = lpDirectDraw->CreateSurface (&ddsd, &lpddsPrimary, NULL);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return (0);
    	}
    	ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    	ddrval = lpddsPrimary->GetAttachedSurface(&ddscaps, &lpddsBack); 
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return (0);
    	}
    
    	ddrval = lpDirectDraw->CreateClipper(0, &lpddClipper, NULL);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return false;
    	}
    
    	struct 
    	{
    		RGNDATAHEADER rdh;
    		RECT   rgndata[1];
    	} cliplist;
    
    	cliplist.rdh.dwSize   = sizeof (RGNDATAHEADER);
    	cliplist.rdh.iType   = RDH_RECTANGLES;
    	cliplist.rdh.nCount   = 1;
    	cliplist.rdh.nRgnSize  = 0;
    	cliplist.rdh.rcBound.left = 0;
    	cliplist.rdh.rcBound.top = 0;
    	cliplist.rdh.rcBound.right = 800;
    	cliplist.rdh.rcBound.bottom = 600;
    	cliplist.rgndata[0].left = 0;
    	cliplist.rgndata[0].top  = 0;
    	cliplist.rgndata[0].right = 800;
    	cliplist.rgndata[0].bottom = 600;
    
    	ddrval = lpddClipper->SetClipList ((LPRGNDATA) &cliplist, 0);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return false;
    	}
    
    	ddrval = lpddsBack->SetClipper(lpddClipper);
    	if (ddrval != DD_OK)
    	{
    		ddRelease ();
    		return false;
    	}
    
    	return true;
    }
    
    void ddRelease ()
    {
    	if (lpddClipper != NULL)
    	{
    		lpddClipper->Release();
    		lpddClipper = NULL;
    	} 
    
    	if (lpddsBack != NULL)
    	{
    		lpddsBack->Release();
    		lpddsBack = NULL;
    	} 
    
    	if (lpddsPrimary != NULL)
    	{
    		lpddsPrimary->Release();
    		lpddsPrimary = NULL;
    	}
    
    	if (lpDirectDraw != NULL)
    	{
    		lpDirectDraw->Release();
    		lpDirectDraw = NULL;
    	}
    }
    
    void ddLastInits ()
    {
    	ddbltfx.dwSize = sizeof(DDBLTFX);
    	ddbltfx.dwFillColor = RGB(255, 0, 255); 
    
    	SetRect(&fill_area, 0, 0, 800, 600);
    	//lpDirectDraw->CreateSurface(
    	lpDirectDraw->CreateSurface( &ddsd, &lpddsTiles, NULL ); 
    	lpddsTiles = DDLoadBitmap(lpDirectDraw, "tiles.bmp", 150, 200);
    	DDSetColorKey(lpddsTiles,RGB(255,0,255));
    
    	lpDirectDraw->CreateSurface( &ddsd, &lpddsBitmap, NULL ); 
    	lpddsBitmap = DDLoadBitmap(lpDirectDraw, "Test.bmp", 200, 150);
    	DDSetColorKey(lpddsBitmap,RGB(0,0,0));
    
    	lpDirectDraw->CreateSurface( &ddsd, &lpddsBg, NULL ); 
    	lpddsBg = DDLoadBitmap(lpDirectDraw, "sky.bmp", 640, 480);
    	DDSetColorKey(lpddsBg,RGB(255,0,255));
    
    	ddStructInits();
    	//AddColorKey(lpddsBitmap, 0, 0);
    }
    
    void ddStructInits()
    {
    
    	Bmp[BILD].Breite = 200;
    	Bmp[BILD].Hoehe = 150;
    	SetRect(&Bmp[BILD].rcSrc,0,0,200,150);
    	Bmp[BILD].Surface = lpddsBitmap;
    	Bmp[BILD].Timer = 0;
    
    	Bmp[HIMMEL].Breite = 640;
    	Bmp[HIMMEL].Hoehe = 480;
    	SetRect(&Bmp[HIMMEL].rcSrc,0,0,640,480);
    	Bmp[HIMMEL].Surface = lpddsBg;
    	Bmp[HIMMEL].Timer = 0;
    
    	Bmp[GRAS].Breite = 0;
    	Bmp[GRAS].Hoehe = 0;
    	SetRect(&Bmp[GRAS].rcSrc,0,0,8,8);
    	Bmp[GRAS].Surface = lpddsTiles;
    	Bmp[GRAS].Timer = 0;
    
    }
    
    BOOL SetRect(LPRECT lprc,LPRECT lprc2) 
    {
    	lprc->bottom = lprc2->bottom;
    	lprc->left = lprc2->left;
    	lprc->right = lprc2->right;
    	lprc->top = lprc2->top;
    	return true;
    }
    
    void Generate()
    {
    
    }
    
    LPRECT CalcMiddle(LPRECT lprc,LPRECT lprc2)
    {
    	// Diese Funkton Rechnet die Mitte des Bildschirmes für das Bild an
    	// lprc ist die vollständige Berechnung
    	// lprc2 ist das Bild das in den Bildschirm eingebettet werden soll
    	// Das LPRECT kann man auch als return empfangen
    	lprc->left = MAXX/2-lprc2->right/2;
    	lprc->top = MAXY/2-lprc2->bottom/2;
    	lprc->right = lprc->left+200;
    	lprc->bottom = lprc->top+150;
    	return lprc;
    
    }
    void ddDraw ()
    {
    	sy = MAXY-200;
    
    	SetRect(&rcRectBild,0,0,640,480);
    	SetRect(&rcRectBlit,0,0,800,600);
    	Blitten(lpddsBg,lpddsBack,false);
    
    	if(px > 799) px = -200;
    	SetRect(&rcRectBild,0,0,200,150);
    	SetRect(&rcRectBlit,px,py,px+200,py+150);
    	Blitten(lpddsBitmap,lpddsBack,true);
    	//-----------------------------//
             //   HIER IST DER FEHLER...    //
             //-----------------------------//
    	for(x=0;x<MAXX/8;x++,sx+=8)
    	{
    		SetRect(&rcRectBild,0,8,8,16);
    		SetRect(&rcRectBlit,sx,sy,(sx+8),(sy+8));
    		Blitten(lpddsTiles,lpddsBack,true);
    
    	}	
    
    	lpddsPrimary->Flip(NULL, DDFLIP_WAIT);  
    }
    //....
    
    void Blitten(LPDIRECTDRAWSURFACE7 lpDDSVon,LPDIRECTDRAWSURFACE7 lpDDSNach,bool Transp)
    {
    	if (Transp)
    	{
    		lpDDSNach->Blt(&rcRectBlit,lpDDSVon,&rcRectBild,DDBLT_KEYSRC | DDBLT_WAIT,NULL);
    	}
    	else
    	{
    		lpDDSNach->Blt(&rcRectBlit,lpDDSVon,&rcRectBild,DDBLT_WAIT,NULL);
    	}
    
    }
    
    //....
    


  • Thx, jetzt hab ich nun folgendes Problem:

    Ich lasse erst 2 Bilder anzeigen, das was ganz unten sein soll, natürlich ganz zuerst, dann kommt ein transparentes Bild, und dann wird eine Reihe lang ausgeschnittene Grafiken aus einem Tilebild.... Naja, hier der Code:

    Ja und wo ist jetzt dein Problem? Und außerdem wäre es wesentlich angenehmer, wenn du dich auf den Codeabschnitt beschränkst, der nicht so funktioniert, wie er soll.



  • Das Problem liegt in den Zeilen:

    for(x=0;x<MAXX/8;x++,sx+=8)
    {
    SetRect(&rcRectBild,0,8,8,16);
    SetRect(&rcRectBlit,sx,sy,(sx+8),(sy+8));
    Blitten(lpddsTiles,lpddsBack,true);
    }
    

    Die Funktion Blitten steht oben...
    Man sieht von dem was ich geblittet habe nur kurz was, es flackert jede sek einmal auf und verschwindet dann wieder...



  • Nach den flippen wird der Inhalt vom BackBuffer nicht gelöscht. Du solltest vor jedem Zeichnen den BackBuffer erstmal freimachen oder mit einem Bild komplett bedecken.

    Mach erst mal ein Programm, dass in einer Endlosschleife läuft (meinetwegen mit Framebremse) und immer wieder den Backbuffer cleared und ein Bild blittet (und anschließend flippt).

    Zu sehen sein sollte dann ein unbewegliches, nicht flimmerndes Bild, dass (für das Auge verborgen) in Wirklichkeit immer wieder neu gezeichnet wird.

    Generell möchte ich noch anmerken, dass DDraw ausstirbt und du besser gleich DirectX Graphics lernen solltest.


Anmelden zum Antworten