Bitmap in DirectDraw
-
P schrieb:
wenn ich die 3 Funktionen in mein versuchsprojekt kopiere, wird das Programm schon nach 2-3 Sekunden wieder geschlossen.
Da du keinerlei Informationen über dein "Versuchsprojekt" gegeben hast, kann dir niemand helfen.
-
okay, dann schick ich einfach mal den kompletten Text(ohne die oben erwähnten Funktionen):
#include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <iostream> #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 <C:\DXSDK\Include\ddraw.h> #pragma comment(lib, "user32") #pragma comment(lib, "gdi32") #pragma comment(lib, "ddraw") #pragma comment(lib, "dxguid") #define WINDOW_CLASS_NAME "WINXCLASS" #define WINDOW_WIDTH 320 #define WINDOW_HEIGHT 200 #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 #define SCREEN_BPP 16 #define BITMAP_ID 0x4D42 #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10)) #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11)) typedef struct BITMAP_FILE_TAG { BITMAPFILEHEADER bitmapfileheader; BITMAPINFOHEADER bitmapinfoheader; PALETTEENTRY palette[256]; UCHAR *buffer; } BITMAP_FILE, *BITMAP_FILE_PTR; #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) int Game_Init(void *parms=NULL); int Game_Shutdown(void *parms=NULL); int Game_Main(void *parms=NULL); int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename); int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap); int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height); HWND main_window_handle = NULL; HINSTANCE main_instance = NULL; char buffer[80]; LPDIRECTDRAW7 lpdd; DDSURFACEDESC2 ddsd; LPDIRECTDRAWSURFACE7 lpddsprimary; UCHAR *primary_buffer = NULL; BITMAP_FILE bitmap16bit; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { WNDCLASS wc; HWND hWnd; MSG msg; wc.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = WINDOW_CLASS_NAME; if(!RegisterClass(&wc)) { return 0; } if(!(hWnd = CreateWindow(WINDOW_CLASS_NAME, "WinX", WS_POPUP | WS_VISIBLE, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL))) { return 0; } main_window_handle = hWnd; main_instance = hInstance; Game_Init(); while(1) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message == WM_QUIT) { break; } TranslateMessage(&msg); DispatchMessage(&msg); } Game_Main(); } Game_Shutdown(); return msg.wParam; } int Game_Init(void *parms) { if(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL) != DD_OK) { MessageBox(NULL, "Fehler Code 0001", "Fehler!", MB_OK); return 0; } if(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK) { MessageBox(NULL, "Fehler Code 0002", "Fehler!", MB_OK); return 0; } if(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0) != DD_OK) { MessageBox(NULL, "Fehler Code 0003", "Fehler!", MB_OK); return 0; } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL) != DD_OK) { MessageBox(NULL, "Fehler Code 0004", "Fehler!", MB_OK); return 0; } Load_Bitmap_File(&bitmap16bit, "ANDRE16.BMP"); return 1; } int Game_Shutdown(void *parms) { if(lpddsprimary != NULL){lpddsprimary->Release();} if(lpdd != NULL){lpdd->Release();} Unload_Bitmap_File(&bitmap16bit); return 1; } int Game_Main(void *parms) { if(KEY_DOWN(VK_ESCAPE)){SendMessage(main_window_handle, WM_DESTROY, 0, 0);} memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); primary_buffer = (UCHAR *)ddsd.lpSurface; for(int y=0; y < SCREEN_HEIGHT; y++) { memcpy(&primary_buffer[y*ddsd.lPitch], &bitmap16bit.buffer[y*SCREEN_WIDTH*2], SCREEN_WIDTH*2); } lpddsprimary->Unlock(NULL); return 1; }
-
Hi...
Der Quelltext ist so gut wie der gleiche wie er auch im Buch "Tricks of the Windows Game Programming Gurus" zu finden ist.
Deshalb würde ich bei deinem Problem spontan sagen, dass etwas beim Schreiben in den Speicher falsch läuft. Hast du den Code komplett von den Beispielen genommen oder selbst geschrieben?
Ich hatte auch oft das Problem, dass mein Programm sich sofort wieder beendete, wenn ich z.B. zu viel in den Speicher geschrieben habe.
Damit mein ich vor allem diese Zeile:for(int y=0; y < SCREEN_HEIGHT; y++) { memcpy(&primary_buffer[y*ddsd.lPitch], &bitmap16bit.buffer[y*SCREEN_WIDTH*2], SCREEN_WIDTH*2); }
-
Die 3 Funktionen die Speziel für das Bitmap sind, hab ich komplett kopiert.
den rest hab ich selbst geschrieben. Wobei mir aber kein unterschied zum Beispiel auffällt. und wenn ich das komplette Beispiel kopiere, hängt sich das Programm auf.Was könnte den beim Schreib in den Speicher falsch laufen?
-
Hi...
ich hab das ganze jetzt nicht komplett durchgesehen. Was mir aber so spontan einfällt weil ich es auch oft falsch gemacht hab ist dass irgendwo in deinem Code ein Fehler steckt wegen den verschiedenen Farbtiefen.
Du gehst ja davon aus, dass das Bitmap 16 Bit hat (was es hoffentlich als Datei dann auch hat). Dann frage ich mich warum du bei deiner Bitmap_File Struktur den Buffer nur als Array von UCHAR Variablem deklarierst. Außerdem gibt es bei 16-Bit Bitmaps keine Palette...typedef struct BITMAP_FILE_TAG { BITMAPFILEHEADER bitmapfileheader; BITMAPINFOHEADER bitmapinfoheader; PALETTEENTRY palette[256]; //<--- UCHAR *buffer; //<-- } BITMAP_FILE, *BITMAP_FILE_PTR;Das sind so die Sachen die mir beim drübergucken aufgefallen sind. Falls ich mich irre, korrigiert mich bitte. Ob es noch andere Ecken gibt, an denen etwas falsch läuft weiß ich gerade nicht. Aber du kannst es ja erstmal damit probieren...
-
Ja, die datei ist schon ein 16 Bit Bild _
Das mit UCHAR verwirrt mich irgendwie. Im Buch stand erst, das UCHAR für 8 Bit verwendet wird und für alles darüber USHORT. und bei dem beispiel....hmm...
Und jetzt wo du das mit der Palette erwähnst...hmm...hab den Text noch mal durchgeguckt. könnte es sein, das die Funktion die 16 Bit Bilder in 8 Bit Bilder umwandelt? Irgendwie werde ich da gar nicht draus schlau.Wüsstest du vielleicht ein gutes Tutorial, das ich mir Parallel zum Buch angucken könnte? An dieser Stelle steht da nähmlich gar nichts hilfreiches.
mfg P
-
mhh hab jetzt nochmal in meinem Buch geguckt (ich frag mich immernoch warum die Quelltexte so gut wie identisch sind. Wer hat dein Buch geschrieben?). Die Bitmap_File Struktur wird hier genauso angegeben und auch die Funktionen scheinen im Großen und Ganzen die selben zu sein.
Dass UCHAR verwendet wird scheint nicht das Problem zu sein und auch die Palette wird nur bei 8 Bit Bildern geladen.
Von daher kann ich momentan leider auch nicht sagen, woran es liegt. Vielleicht kann dir noch jemand anders helfen...
Edit: Ok die Bücher haben den selben Autor (Andre LaMothe)...
-
Der Code sieht aus als könnte er 8Bit Bitmaps mit Palette und 16 Bit Bitmaps lesen.
Ist das was du lädst ne 16bit Bitmap? Standardformat der Grafikprogramme ist ja eigentlich eher 24Bit oder nich?
-
@geeky:
hab mich noch mal vergewissert, und es ist tatsächlich ein 24 Bit Bitmap...dabei ist es die Selbe datei, die der Autor in seinem Beispiel verwendet. Und ich konnte auch kein Prog finden, dases in 16 Bit Convertiert. Immer nur 24 Bit, 8 Bit oder noch tiefer. habs dann mal mit nem 8 Bit Bitmap versucht, bringt aber den selben effekt, wie zuvor.@Amateur:
Ist in deinem Buch der Quelltext denn beschrieben? Dann könnt ich ja mal sehen, ob mir das weiter hilft.
-
Ich glaub ich irre

16bit scheint der source in 16bit umzuwandeln, oder?
-
geeky schrieb:
Ich glaub ich irre

16bit scheint der source in 16bit umzuwandeln, oder?
hmm...ich weis jetzt nicht was du meinst.
Hast du dich vielleicht vertippt und meinst, das 24 Bit Bilder in 16 Bit umgewandelt werden?
-
jo, genau

Im Prinzip scheint der Source in Ordnung zu sein.
Prüf mal noch beim Aufruf den Rückgabewert von Load_Bitmap_File() und
macht aus dem "#if 0" mal nen "#if 1"Muss man bei der DDSURFACEDESC2-Struktur das Pixelformat gar nicht angeben?
-
Den Rückgabe Wert ausgeben? Ehrlich gesagt wüsste ich jetzt nicht wie ich daran gehen muss _'
Habs aber mal in "#if 1" geändert. War aber das selbe wie vorher.
Meinst du mit Pixelformat die Bittiefe?...Ich nehme an, das die Funktion diese Information aus den File Header der datei liest.
-
memset(&ddsd, 0, sizeof(ddsd)); // Hier wunderts mich das hier nirgends das Pixelformat angegeben // werden muss - Ich meine woher weiss DirectX dass das Surface mit // 16bit-Grafik gefüllt wird? - Aber ich bin kein DXler ;D ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL) != DD_OK) { MessageBox(NULL, "Fehler Code 0004", "Fehler!", MB_OK); return 0; } // Quasi so zum Bleistift: if (Load_Bitmap_File(&bitmap16bit, "ANDRE16.BMP")==0) { MessageBox(NULL,"Load_Bitmap_File() ist fehlgeschlagen!","Fehler!",0); }
-
Ach mehr is das gar nich mit dem Rückgabe wert XD...
okay, hab ich gemacht und daran scheint es nicht zu liegen.
Hab jetzt auch einwenig weiter mit dem Quelltext rumgespielt.
mal das aus kommentiert und mal das...Und ich schätze, das der Fehler hierfor(int y=0; y < SCREEN_HEIGHT; y++) { memcpy(&primary_buffer[y*ddsd.lPitch], &bitmap16bit.buffer[y*SCREEN_WIDTH*2], SCREEN_WIDTH*2); }liegen muss, denn wenn ich einfach nur diese Zeilen auskommentiere, funktioniert alles...naja...jedenfalls vom eindruck her...das Bitmap wird natürlich nicht angezeigt...