Ich fange gerade an, mich mit DirectX zu befassen. Dafür habe ich ein wenig gegoogelt und folgende Website gefunden:
http://www.anmabagima.de/DXCpp/tutstart.html
Ich habe das Ganze in meinen lcc-Win32 übernommen und bekomme nun Fehler.
Die Mehrzahl konnte ich beseitigen. Aber ein kleiner Rest ist übrig geblieben.
Und ich verstehe (noch) nicht, wo der letzte Abschnitt hingehört.
Die Source:
/*
* TestDDraw.c
*/
#include <windows.h>
#define INITGUID // <- nur für lcc-win32 Compiler
#include "ddraw.h"
/*<---------------------------------------------------------------------->*/
LPDIRECTDRAW7 lpDDraw7 = NULL;//Zeiger a. die Schnittstelle des DD-Obj. der Version 7
LPDIRECTDRAWSURFACE7 lpDSurf7 = NULL;//unser Bildschirmsurface
DDSURFACEDESC2 DDSurfDesc2; //die Beschreibung unserer Bildschirmzeichenfläche
LPDIRECTDRAWSURFACE7 lpDPaint7 = NULL;//die Arbeitsfläche
DDSURFACEDESC2 DDPaintDesc2; //und deren Beschreibung
BOOL IsDDraw = FALSE;//ist TRUE wenn DirectDraw initialisiert wurde
BOOL InitDirectDraw(HWND hwnd);
void ExitDirectDraw(void);
void ManipulatePaintSurface(void);
/*<---------------------------------------------------------------------->*/
LRESULT WINAPI WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;
wc.lpszClassName = "TestDDraw";
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_BACKGROUND + 1);
wc.lpszMenuName = NULL;
RegisterClass(&wc);
hwnd = CreateWindow ("TestDDraw", "Test DirectDraw Fenster", WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow (hwnd, SW_SHOW);
IsDDraw = InitDirectDraw(hwnd); //DirectDraw initailisieren
UpdateWindow(hwnd); //erzwingen einer WM_PAINT-Message
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ExitDirectDraw(); //DirectDraw wieder abbauen
return msg.wParam;
}
/*<---------------------------------------------------------------------->*/
BOOL InitDirectDraw(HWND hwnd)
{
LPDIRECTDRAW lpDDraw = NULL;
// anlegen des Objektes: lpDDraw zeigt danach auf die Schnittstelle zu diesem Objekt
if (DirectDrawCreate(NULL, &lpDDraw, NULL)!= DD_OK)
{
MessageBox(hwnd, "Konnte DirectDraw-Objekt nicht erzeugen.", NULL, MB_OK);
return FALSE;
}
//das "Ur"-DD-Objekt nach einer Schnittstelle zu einem DD-Objekt der Version 7 fragen
//wenn diese Schnittstelle existiert, dann wird ein Objekt der Version 7 angelegt
//und ein Zeiger auf die Schnittstelle zu diesem Objekt in lpDDraw7 gespeichert
if (lpDDraw->lpVtbl->QueryInterface(lpDDraw, &IID_IDirectDraw7, (void **)&lpDDraw7)!=DD_OK)
{
MessageBox(hwnd, "Keine Schnittstelle zu DirectDraw7 vorhanden", NULL, MB_OK);
return FALSE;
}
//das "Ur"-Objekt wieder freigeben, da wir es nicht länger brauchen
lpDDraw->lpVtbl->Release(lpDDraw);
/*<---------------------------------------------------------------------->*/
if (lpDDraw7->lpVtbl->SetCooperativeLevel(lpDDraw7, hwnd, DDSCL_NORMAL) != DD_OK)
{
MessageBox(hwnd, "Konnte Kooperationslevel nicht setzen", NULL, MB_OK);
return FALSE;
}
/*<---------------------------------------------------------------------->*/
//zum Anlegen einer Zeichenfläche die Beschreibung erstmal mit 0 initialisieren
memset(&DDSurfDesc2, 0, sizeof(DDSURFACEDESC2));
//DirectX erwartet in solchen Strukturen grundsätzlich eine Grössenangabe der Struktur
DDSurfDesc2.dwSize = sizeof(DDSURFACEDESC2);
//dieses Flag steuert welche Daten für die Anlage der Zeichenfläche genutzt werden sollen
DDSurfDesc2.dwFlags = DDSD_CAPS;
//Struktur ddsCaps füllen
DDSurfDesc2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |//primäre Zeichenfläche (sichtbar)
DDSCAPS_VIDEOMEMORY;//Surface im Grafikkartenspeicher anlegen
DDSurfDesc2.ddsCaps.dwCaps2 = 0;
//erzeugen der Zeichenfläche, lpDSurf ist dann der Zeiger auf die Schnittstelle
if (lpDDraw7->lpVtbl->CreateSurface(lpDDraw7, &DDSurfDesc2, &lpDSurf7, NULL) != DD_OK)
{
MessageBox(hwnd, "Konnte primäre Zeichenfläche nicht anlegen", NULL, MB_OK);
return FALSE;
}
//es folgt unsere "Arbeitsfläche"
memset(&DDPaintDesc2, 0, sizeof(DDSURFACEDESC2));
DDPaintDesc2.dwSize = sizeof(DDSURFACEDESC2);
DDPaintDesc2.dwFlags = DDSD_CAPS | DDSCAPS_HEIGHT | DDSCAPS_WIDTH;
DDPaintDesc2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |//normale Zeichenfl.("unsichtbar")
DDSCAPS_SYSTEMMEMORY;//Surface im Hauptspeicher anlegen
DDPaintDesc2.ddsCaps.dwCaps2 = 0;
DDPaintDesc2.dwHeight = 200; //die Zeichenfläche ist 200 Bildpunkte hoch
DDPaintDesc2.dwWidth = 200; //und 200 Bildpunkte breit
if (lpDDraw7->lpVtbl->CreateSurface(lpDDraw7, &DDPaintDesc2, &lpDPaint7, NULL) != DD_OK)
{
MessageBox(hwnd, "Konnte normale Zeichenfläche nicht anlegen", NULL, MB_OK);
return FALSE;
}
return TRUE;
}
/*<---------------------------------------------------------------------->*/
void ExitDirectDraw(void)
{
if (lpDPaint7 != NULL) lpDSurf7->lpVtbl->Release(lpDPaint7);
if (lpDSurf7 != NULL) lpDSurf7->lpVtbl->Release(lpDSurf7);
if (lpDDraw7 != NULL) lpDDraw7->lpVtbl->Release(lpDDraw7);
}
/*<---------------------------------------------------------------------->*/
void ManipulatePaintSurface(void)
{
BYTE *lpByteScreen;
int i;
if (lpDPaint7->lpVtbl->Lock(lpDPaint7, NULL, &DDPaintDesc2, DDLOCK_WAIT, NULL) == DD_OK)
{
//hier niemals einen Breakpoint platzieren oder mit dem Debugger hinein springen
//einen byte-Pointer auf die Adresse der Bilddaten setzen
lpByteScreen = DDPaintDesc2.lpSurface;
//die ersten 50 Byte im Screen mit 255 belegen:
for (i=0;i<50;i++)
{
*lpByteScreen = 255;
lpByteScreen++;
}
//Surface entsperren
lpDPaint7->lpVtbl->Unlock(lpDPaint7, NULL);
}
else MessageBox(NULL, "Konnte Zeichenfläche nicht sperren", NULL, MB_OK);
}
/*<---------------------------------------------------------------------->*/
LRESULT WINAPI WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch (msg)
{
case WM_PAINT:
//das sollte ja bekannt sein
BeginPaint(hwnd, &ps);
//hier wird dann die DX-Zeichenfläche geswitcht
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return FALSE;
}
/*<---------------------------------------------------------------------->*/
Hier die Liste der Fehler:
Wedit output window build: Sat May 28 16:13:56 2005
Error f:\c\york\p-testdraw.c: 107 undeclared identifier 'DDSCAPS_HEIGHT'
Error f:\c\york\p-testdraw.c: 107 undeclared identifier 'DDSCAPS_WIDTH'
Warning f:\c\york\p-testdraw.c: 107 possible usage of DDSCAPS_WIDTH before definition
Warning f:\c\york\p-testdraw.c: 107 possible usage of DDSCAPS_HEIGHT before definition
Compilation + link time:0.3 sec, Return code: 1
/* Wo Gehört dieser Code hin ???
//nur wenn DirectDraw erfolgreich initialisiert wurde
if (IsDDraw == TRUE)
{
//die Quelle soll ja die gesamte Arbeits-Zeichenfläche sein
//diese haben wir mit einer Höhe und Breite von 200 erstellt!!
SRect.top = 0;
SRect.left = 0;
SRect.right = 199;
SRect.bottom = 199;
//das Zielrechteck soll die selben Maße haben.
//dadurch kommt es zu keiner Verzerrung.
DRect = SRect;
//die DRect-Koordinaten beziehen sich auf unser Anwendungsfenster
//sie werden auf Bildschirmkoordinaten umgerechnet
//der letzte Parameter 2 gibt an wieviele Punkte in DRect zu ändern sind
MapWindowPoints(hwnd, NULL, (LPPOINT)&DRect, 2);
//Der Blitter kopiert die Bilddaten
//das Flag DDBLT_WAIT gibt an, dass dieser Vorgang wartet bis der Blitter
//frei ist um ihn auszuführen
lpDSurf7->lpVtbl->Blt(lpDSurf7, &DRect, lpDPaint7, &SRect, DDBLT_WAIT, NULL);
};