Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: DirectDraw esimerkki

HtH [04.09.2002 16:08:02]

#

Tässä pieni esimerkki DirectDrawin käytöstä. Esimerkissä käytetään DirectDrawin 4:ttä versiota, joka on ollut muistaakseni 4. versio DirectX:n 6. versiosta lähtien. Anyway muista lisätä projektiin ddraw.lib ja dxguid.lib, jotta ohjelma suostuu kääntymään. Koodi kääntyy ainakin VC++ 6.0:lla, mutta voi kääntyä Borlandilla, tai jopa Dev-C++:ssa. Joo, mutta tässäpä pitemmittä löpinöittää koodi. Olen kommentoinut liki jokaisen rivin, mikä vain on selittämisen arvoinen.

/* Pieni DirectDraw esimerkki by HtH
 * Pieni esimerkki, kuinka käytetään DirectDraw4
 * Resoluution voit helposti vaihtaa muuttamalla alempana olevia vakioita.
 * Muista sisällyttää projektiin ddraw.lib ja dxguid.lib, muuten koodi ei käänny!
 */


#define WIN32_LEAN_AND_MEAN // Ei MFC:tä

#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>

#include <ddraw.h> // DirectDraw mukaan

//Makro, joka ei ole omatekemäni; katsoo näppäimenpainallukset
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define resox 640 //Näitä vakioita muuttamalla saat vaihdettua resoluutiota
#define resoy 480



//Tapahtuma käsittelijä; hoitaa windowsin lähettämät viestit
LRESULT CALLBACK WindowProc(HWND hwnd,
							UINT msg,
							WPARAM wparam,
							LPARAM lparam) {
	switch(msg) {
	case WM_DESTROY: { // Kun ikkunaa ollaan tuhoamassa...
			PostQuitMessage(0); // Lähetetään WM_QUIT viesti
			return(0); //Palautetaan operaation onnistuminen Windowsille
		} break;
	default:break;
	}
	//Annetaan Windowsin hoitaa tehtävät, joista emme huolehtineet
	return(DefWindowProc(hwnd, msg, wparam, lparam));
} //Tapahtumien käsittelijäin loppu

// DirectDraw rajapinta; vanha versio mukana että saamme käyttöön DirectDrawin uudemman version
LPDIRECTDRAW		lpdd			= NULL;
// DirectDraw rajapinta versio 4
LPDIRECTDRAW4		lpdd4			= NULL;
// Pinta, jolla piiretään
LPDIRECTDRAWSURFACE4 lpddsprimary	= NULL;

DDSURFACEDESC2		ddsd;
// Paletin kuvaus
LPDIRECTDRAWPALETTE lpddpal			= NULL;
// Paletin arvot
PALETTEENTRY		palette[256];

int Game_Init(HWND hwnd) { // Aliohjelma, joka hoitaa alustuksen.
	// Luodaan aluksi Direct Draw rajapinta
	DirectDrawCreate(NULL, &lpdd, NULL);
	// Vaihdetaan uudempaan versioon
	lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4);
	// Luovutaan vanhasta
	lpdd->Release();
	lpdd=NULL;
	// Asetetaan yhteistyötaso Windowsin kanssa
	lpdd4->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
	// Vaihdetaan näyttötila
	lpdd4->SetDisplayMode(resox, resoy, 8, 0, 0);
	// Tyhjennetään ddsd
	memset(&ddsd, 0, sizeof(lpdd));
	// Ilmoitetaan ddsd:lle oma kokonsa
	ddsd.dwSize = sizeof(ddsd);
	// Kerromme ddsd:lle, että dwCaps on käytössä
	ddsd.dwFlags = DDSD_CAPS;
	// Asetetaan opioita
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	// Luodaan pinta
	lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL);
	// Tehdään paletti
	unsigned char r=0, g=0, b=0;
	int jutska= 0;
	for(int i = 0; i < 256; i++) {
		jutska++;
		r++;
		if(jutska>=2) {g++; jutska=0;}
		b++;
		palette[i].peRed = r;
		palette[i].peGreen = g;
		palette[i].peBlue = b;
		palette[i].peFlags = PC_NOCOLLAPSE;
	}
	palette[0].peRed = 0;
	palette[0].peGreen = 0;
	palette[0].peBlue = 0;
	palette[0].peFlags = PC_NOCOLLAPSE;

	// Luodaan palettirajapintaan tiedot paletista.
	lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,
					 palette, &lpddpal, NULL);
	// Asetetaan paletti käyttöön pintaan.
	lpddsprimary->SetPalette(lpddpal);
	return(0);
}

int Game_Main(HWND hwnd) { // Tässä aliohjelmassa tapahtuu kaikki ohjelman päätapahtumat
	// Escistä poistutaan ohjelmasta...
	if (KEYDOWN(VK_ESCAPE))
	   SendMessage(hwnd,WM_CLOSE,0,0);
	// Tyhjennetään ddsd
	memset(&ddsd, 0, sizeof(ddsd));
	// Ilmoitetaan koko
	ddsd.dwSize = sizeof(ddsd);
	// Lukitaan pinta, jotta voimme piirtää siihen
	lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
	// Tehdään asiat vähän helpommaksi, ettemme tarvitse käyttää tyyppimuunnoksia alempana
	int pitch = (int)ddsd.lPitch;
	unsigned char *buffer = (unsigned char*)ddsd.lpSurface;
	//Piirretään tuhat pikseliä näytölle sattumanvaraisiin kohtiin.
	for(int i = 0; i < 1000; i++) {
		int x = rand()%resox;
		int y = rand()%resoy;
		if(buffer) buffer[x+y*pitch] = rand()%256;
	}
	// Avataan pinta.
	lpddsprimary->Unlock(NULL);
	return(0);
}

int Game_Exit(HWND hwnd) { // Tätä kutsutaan poistuttaessa.
	// Siivotaan vain käytetyt rajapinnat.
	if(lpddpal) {lpddpal->Release();
	lpddpal = NULL;}
	if(lpddsprimary){lpddsprimary->Release();
	lpddsprimary = NULL;}
	if(lpdd4){lpdd4->Release();
	lpdd4 = NULL;}
	return(0);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine, int nShowCmd) {


	//Luodaan luokka
	WNDCLASSEX winclass;
		winclass.cbSize = sizeof(WNDCLASSEX);
		winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
		winclass.lpfnWndProc = WindowProc;
		winclass.cbClsExtra = 0;
		winclass.cbWndExtra = 0;
		winclass.hInstance = hInstance;
		winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		winclass.hCursor = LoadCursor(NULL, IDC_CROSS);
		winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
		winclass.lpszMenuName = "MainMenu";
		winclass.lpszClassName = "WINCLASS1";
		winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	// Kerrotaan siitä Windowsille
	RegisterClassEx(&winclass);

	HWND hwnd;
	MSG msg;
	int t=0;
	// Luodaan ikkuna
	if(!(hwnd = CreateWindowEx(NULL,
		"WINCLASS1",
		"Ikkuna",
		WS_POPUP | WS_VISIBLE,
		0, 0, resox, resoy,
		NULL,
		LoadMenu(hInstance, "MainMenu"),
		hInstance, NULL))) return(0);

	// Kutsutaan alustusfunktiota
	Game_Init(hwnd);
	// Pääluuppi
	while(TRUE) {
		if(!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			if(msg.message == WM_QUIT) {break;} // Jos löytyy WM_QUIT viesti, rikotaan looppi
		}
		// Hoidetaan viestit
		TranslateMessage(&msg);
		// Kutsutaan Game_Main funktiota, joka hoitaa päätapahtumat.
		Game_Main(hwnd);
		DispatchMessage(&msg);
	}
	// Siivotaan jäljet
	Game_Exit(hwnd);
	// Kerrotaan Windowsille onnistuminen

	return(msg.wParam);
}

HtH [05.09.2002 21:20:06]

#

Jeps, taas unohtu ilmoittaa, että valmiiksi käännetty versio löytyypi osoitteesta http://koti.mbnet.fi/~haraa/files/ddraw.exe

Tatu Peltola [06.09.2002 17:49:30]

#

HtH pyysit IRCissä kommentoimaan tätä.

Tatu Peltola [06.09.2002 17:53:13]

#

Ainaski EXEks käännetty on hieno!

Lord Juha [02.10.2002 16:36:42]

#

Kiitti Kiitti Kiitti tosi tarpeeseen

progo [04.12.2002 08:27:53]

#

Todella loistava esimerkki!!

aWW [04.04.2005 14:39:46]

#

Ei mitenkään erikoinen, melkein suora kopio LaMothen kirjasta "Inside Peliohjelmointi"

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta