Bilder dartstellen

mamarulez

Mitglied
[c++/DirectX] - DDRAW - Bilder darstellen

Hallo!

Also - meine Frage:

Auch wenn ich nciht der allerbeste Coder bin, habe ich doch mittlerweile herausgefunden (!), dass es viele Funktionen zum Zeichnen von Bildern mit Hilfe von C++ unter Windows gibt.

Ich will aber weder DirectX noch OpenGL verwenden.

Welche Funktionen benutzt ihr? Und welche sind eurer Meinung nach die besten? Bitte schreibt hier den vollständigen und korrekten Namen der Funktion, die Parameter am besten mit Kurzbeschreibung wenn erforderlich und mit der Angabe, welche Bibliotheken dafür eingebunden werden müssen!
 
Zuletzt bearbeitet:
Ähm du solltest vielleicht schon angeben, was genau du machen möchtest.
Selbst Pixel auf den Bildschirm malen, Linien, Bilder laden oder was?
Unter Windows benötigst du immer einen Device Context, auf den kannst du dann zeichnen usw.
Interessantes dazu gibt es auch in diesem Thread:
http://www.tutorials.de/tutorials146416.html

Also und doch etwas mehr Angaben. Wenn du eine Funktionsreferenz suchst, dann verweise ich dich auf die MSDN

Gruß Homer
 
Ich verwende normalerweise normale Windows MFC.

Sorry, wie gesagt bin ich nicht noch nicht so der erfahrene Coder, tut mir leid dass du mir alles aus der Nase ziehen musst.

Trotzdem: Danke für deine Mühe!
 
Also am einfachsten ist es das Bild (Bitmap) als Ressource in dein Projekt mit aufzunehmen und dann mit CBitmap::LoadBitmap() zur Luafzeit zu laden. Dann einfach in einen DeviceContext blitten.
Mehr dazu in der MSDN oder hier z.B.:
http://www.tutorials.de/tutorials131703.html
oder hier: (Is allerdings reine Windows API)
http://www.gamedev.net/community/forums/topic.asp?topic_id=203932

Viel mehr kann ich dir dazu auch nicht sagen, ich kann dir eher sagen, wie du eine Bitmap verarbeitest ohne Fenster usw. also rein an die Pixeldaten rankommst.
Denn ich mach nicht so viel mit MFC (bin da eher abgeneigt :-) )

Gruß Homer
 
OK. Soweit sogut.

Ich benutze jetzt DirectDraw und habe also ein neues Projekt gestartet. Es lässt sich kompilieren aber kein Bitmap wird anegzeigt. Was ist falsch?
Hier kommt der quelltext:

Code:
#include <ddraw.h>
#include <windows.h>

#define WIN32_LEAN_AND_MEAN

LPDIRECTDRAW lpDD; // DirectDraw object defined in DDRAW.H

bool DirectDrawInit(HWND hwnd)
{
    HRESULT ddrval;
   
    ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval != DD_OK )
    {
        return(false);
    }

   
    ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }

    ddrval = lpDD->SetDisplayMode( 640, 480, 8);
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }

    return(true);
}

LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface
LPDIRECTDRAWSURFACE lpDDSBack; // DirectDraw back surface
LPDIRECTDRAWSURFACE lpDDSOne;

bool CreatePrimarySurface()
{
    DDSURFACEDESC ddsd;
    DDSCAPS ddscaps;
    HRESULT ddrval;

    memset( &ddsd, 0, 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 = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }

    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
    if( ddrval != DD_OK )
    {
        lpDDSPrimary->Release();
        lpDD->Release();
        return(false);
    }

    return true;
}


IDirectDrawSurface * CreateOffScreenSurface(IDirectDraw *pdd, int dx, int dy)
{
    DDSURFACEDESC ddsd;
    IDirectDrawSurface *pdds;

    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd.dwWidth = dx;
    ddsd.dwHeight = dy;

    if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
    {
        return NULL;
    } else {
        return pdds;
    }
}

HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int dx, int dy)
{
    HDC hdcImage;
    HDC hdc;
    HRESULT hr;
    HBITMAP hbmOld;

    hdcImage = CreateCompatibleDC(NULL);
    hbmOld = (HBITMAP)SelectObject(hdcImage, hbm);

    if ((hr = pdds->GetDC(&hdc)) == DD_OK)
    {
        BitBlt(hdc, 0, 0, dx, dy, hdcImage, 0, 0, SRCCOPY);
        pdds->ReleaseDC(hdc);
    }

    SelectObject(hdcImage, hbmOld);
    DeleteDC(hdcImage);

    return hr;
}

IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap)
{
    HBITMAP hbm;
    BITMAP bm;
    IDirectDrawSurface *pdds;

    hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
    LR_LOADFROMFILE|LR_CREATEDIBSECTION);

    if (hbm == NULL)
        return NULL;

    GetObject(hbm, sizeof(bm), &bm); // get size of bitmap

    pdds = CreateOffScreenSurface(pdd, bm.bmWidth, bm.bmHeight);
    if (pdds) {
        DDCopyBitmap(pdds, hbm, bm.bmWidth, bm.bmHeight);
    }

    DeleteObject(hbm);

    return pdds;
}

void updateFrame( void )
{
    RECT rcRect;
    HRESULT ddrval;
   
	//IDirectDrawSurface *lpDDSMySprite;
	IDirectDraw *lpDDSBMP;
	LPDDSURFACEDESC SurfDesc;

	lpDDSBMP->CreateSurface (SurfDesc, &lpDDSOne, NULL);

	DDLoadBitmap (lpDDSBMP, "bitmap.bmp");

    SetRect(&rcRect, 0, 0, 640, 480);

    ddrval = lpDDSBack->BltFast( 0, 0, lpDDSOne, &rcRect,
    DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);

    if( ddrval != DD_OK )
    {
        return;
    }

 
    ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
} 

void finiObjects( void )
{
    if( lpDD != NULL )
    {
        if( lpDDSPrimary != NULL )
        {
            lpDDSPrimary->Release();
            lpDDSPrimary = NULL;
        }

        if( lpDDSOne != NULL )
        {
            lpDDSOne->Release();
            lpDDSOne = NULL;
        }

    lpDD->Release();
    lpDD = NULL;
} 

LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	switch	(message)
	{
		case WM_KEYDOWN:
		{
			switch (wparam)
			{
				case VK_ESCAPE:
					PostMessage (hwnd, WM_CLOSE, 0, 0);
					return (0);
				break;
			}
		}
		break;
		case WM_DESTROY: 
		{
			PostQuitMessage(0);
			return(0);
		} 
		break;
		default:

		break;
    } 

	return (DefWindowProc(hwnd, message, wparam, lparam));
}

int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hprevinst, LPSTR lpcmdline, int ncmdshow)
{
	WNDCLASSEX  winclass;
	HWND	      hwnd;
	MSG		   message;
	DWORD		loop_start_time;

	winclass.cbSize         = sizeof(WNDCLASSEX);
	winclass.style			= CS_HREDRAW | CS_VREDRAW;
	winclass.lpfnWndProc	= WindowProc;
	winclass.cbClsExtra		= 0;
	winclass.cbWndExtra		= 0;
	winclass.hInstance		= hinst;
	winclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	winclass.hCursor		= LoadCursor(NULL, IDC_CROSS); 
	winclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winclass.lpszMenuName	= NULL;
	winclass.lpszClassName	= "Class Name";
	winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassEx(&winclass))
   		return(0);

	if (!(hwnd = CreateWindowEx(NULL, "Class Name", "GROW! BMP_TEST_BUILD", WS_POPUPWINDOW | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, hinst, NULL)))
		return(0);

	ShowWindow		(hwnd, ncmdshow);
	UpdateWindow	(hwnd);				

	ShowCursor	(false);

	while(GetMessage(&message,NULL,0,0))
	{ 
		TranslateMessage(&message);
		DispatchMessage(&message);
	} 
	
	loop_start_time = GetTickCount ();

	updateFrame ();

	while ( ( GetTickCount ( ) - loop_start_time ) < 40 );

	return message.wParam;
}

Sorry dass ich den ganzen quelltexxt geposted habe aber ich weiss mir nicht mehr zu helfen....
 
Abgesehen davon, dass ich vermute, dass im DirectX-Part noch der Wurm ist, finde ich Folgendes etwas komisch:

Code:
        while(GetMessage(&message,NULL,0,0))
	{ 
		TranslateMessage(&message);
		DispatchMessage(&message);
	} 
        // obige Schleife wird erst bei Programmende verlassen
	
	loop_start_time = GetTickCount ();

	updateFrame (); // wird nur ein einziges Mal aufgerufen

	while ( ( GetTickCount ( ) - loop_start_time ) < 40 ); // leere Schleife?
Ich habe da mal ein paar Kommentare reingemacht.

Hier ist eine entsprechende Schleife, die ich mal für ein Projekt verwendet habe:
Code:
 while ( 1 )
 {
    if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
    {
      if ( !GetMessage( &msg, NULL, 0, 0 ) )
      {
        break;
      }
      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
    else
    {
      UpdateFrame();
    }
  }
Ohne DirectX, aber das sollte keinen Unterschied machen. Ausserdem läuft meine Schleife ungebremst; da müsstest du dir noch was zum Begrenzen reinsetzen.
 
Also... ich würde für einfache sachen KEIN DirectDraw verwenden, denn wenn du mit DirectDraw halbwegs schnell zeichnen willst musst du eine ungebremste schleife verwenden -> CPU last = 100%

Absolut unzureichend für Anwendungsprogramme.


Ich würde dir empfehlen GDI zu benutzen...

und zwar...

LoadBitmap()
GetDC()
CreateCompatibleDC()
SelectObject()
BitBlt()
DeleteDC()
ReleaseDC()
DeleteObject()

und fertig, das ganze kommt in die WM_DRAW rein und es passt.
 
Zuletzt bearbeitet:
Zurück