#define INITGUID
#define WIN32_LEAN_AND_MEAN //No MFC
#include <stdio.h>
#include <windows.h>
#include <ddraw.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BPP 8
#define WND_CLASS_NAME "WINCLASS"
#define BMP_WIDTH 20
#define BMP_HEIGHT 20
#define RECT_NUM 5
typedef struct HAPPY_FACE_SU {
int x,y;
int x_vel, y_vel;
}HAPPY_FACE;
#define KEYPRESSED(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define RGB32(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
LPDIRECTDRAW7 lpdd;
LPDIRECTDRAWSURFACE7 primary_surface = NULL;
LPDIRECTDRAWSURFACE7 back_buffer = NULL;
LPDIRECTDRAWCLIPPER teh_clip;
LPDIRECTDRAWPALETTE pal;
DDSURFACEDESC2 surf_desc;
DDSCAPS2 ddscaps;
DDBLTFX ddbltfx;
DDBLTFX ddbltfx_black;
UCHAR *video_buffer;
UCHAR *bmp_buffer;
UCHAR pixel;
HINSTANCE app_hinst;
HWND glob_hwnd;
RECT rect_list[RECT_NUM] = { {20,20,50,50},
{67,67,200,200},
{100,100,300,300},
{49,49,89,89},
{50,50,500,500} };
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
PAINTSTRUCT ps;
HDC hdc;
switch(msg) {
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
LPDIRECTDRAWCLIPPER createDdClipper(LPDIRECTDRAWSURFACE7 lpdd7, int rect_num, LPRECT clip_list) {
LPDIRECTDRAWCLIPPER clipper;
LPRGNDATA surf_rgn_data;
lpdd->CreateClipper(NULL, &clipper, NULL);
surf_rgn_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + rect_num*sizeof(RECT));
memcpy(surf_rgn_data->Buffer, clip_list,sizeof(RECT)*rect_num);
surf_rgn_data->rdh.dwSize = sizeof(RGNDATAHEADER);
surf_rgn_data->rdh.iType = RDH_RECTANGLES;
surf_rgn_data->rdh.nCount = RECT_NUM;
surf_rgn_data->rdh.nRgnSize = RECT_NUM * sizeof(RECT);
surf_rgn_data->rdh.rcBound.left = 64000;
surf_rgn_data->rdh.rcBound.top = 64000;
surf_rgn_data->rdh.rcBound.right = -64000;
surf_rgn_data->rdh.rcBound.bottom = -64000;
for(int n = 0; n < rect_num;n++) {
if(clip_list[n].left < surf_rgn_data->rdh.rcBound.left ) surf_rgn_data->rdh.rcBound.left = clip_list[n].left;
if(clip_list[n].top < surf_rgn_data->rdh.rcBound.top ) surf_rgn_data->rdh.rcBound.top = clip_list[n].top;
if(clip_list[n].right < surf_rgn_data->rdh.rcBound.right ) surf_rgn_data->rdh.rcBound.right = clip_list[n].right;
if(clip_list[n].bottom< surf_rgn_data->rdh.rcBound.bottom) surf_rgn_data->rdh.rcBound.bottom = clip_list[n].bottom;
}
clipper->SetClipList(surf_rgn_data, NULL);
back_buffer->SetClipper(clipper);
return clipper;
}
void gameInit(void) {
DirectDrawCreateEx(NULL,(LPVOID*)&lpdd, IID_IDirectDraw7, NULL);
lpdd->SetCooperativeLevel(glob_hwnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT|DDSCL_ALLOWMODEX);
lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,BPP,0,0);
memset(&surf_desc,0,sizeof(surf_desc));
surf_desc.dwSize = sizeof(DDSURFACEDESC2);
surf_desc.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
surf_desc.dwBackBufferCount = 1;
surf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
lpdd->CreateSurface(&surf_desc,&primary_surface,NULL);
memset(&ddbltfx_black,0,sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwFillColor = 0;
primary_surface->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx_black);
surf_desc.dwFlags = DDSD_CAPS;
surf_desc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
primary_surface->GetAttachedSurface(&surf_desc.ddsCaps, &back_buffer);
back_buffer->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx_black);
memset(&ddbltfx,0,sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwFillColor = 200;
teh_clip = createDdClipper(back_buffer, RECT_NUM, rect_list);
}
int gameMain(void) {
if(KEYPRESSED(VK_ESCAPE)) {
SendMessage(glob_hwnd, WM_CLOSE,0,0);
return (0);
}
back_buffer->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddbltfx);
primary_surface->Flip(NULL,DDFLIP_WAIT);
Sleep(1000);
}
void wndInit(WNDCLASSEX *wnd_class, HWND *hwnd) {
wnd_class->cbSize = sizeof(WNDCLASSEX);
wnd_class->style = CS_HREDRAW|CS_VREDRAW;
wnd_class->lpfnWndProc = wndProc;
wnd_class->cbWndExtra = NULL;
wnd_class->cbClsExtra = NULL;
wnd_class->hInstance = app_hinst;
wnd_class->hIcon = LoadIcon(app_hinst, IDI_APPLICATION);
wnd_class->hCursor = LoadCursor(app_hinst, IDC_ARROW);
wnd_class->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wnd_class->lpszClassName= WND_CLASS_NAME;
wnd_class->lpszMenuName = NULL;
wnd_class->hIconSm = LoadIcon(app_hinst, IDI_APPLICATION);
RegisterClassEx(wnd_class);
*hwnd = CreateWindowEx(NULL, WND_CLASS_NAME,
"DirectDraw manual image blitting",
WS_POPUP|WS_VISIBLE, 0,0,
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
app_hinst,
NULL);
}
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE previnstance, LPSTR ncmdline, int ncmdshow) {
WNDCLASSEX wnd;
MSG msg;
bool _L00P_ = true;
app_hinst = hinstance;
wndInit(&wnd, &glob_hwnd);
gameInit();
while(_L00P_) {
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if(msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
gameMain();
}
return msg.wParam;
}
Distorted desktop image when flipping ?
I'm having a weird problem.When I flip my back buffer I see a distorted image of my desktop.I made the program sleep 1000 ms so you guys can see it.Why is this happening ?
full code: It is a bit long , most of it is just initialization.have a look at where you think I might be wrong.I clear the back buffer before I attach it to the primary surface, I have no idea why this is happening.The purpose of the program is to attach a DD clipper to the back buffer, fill the back buffer with one color, then flip but since it goes through the clipper you should only see some rectangles on the screen.Please help me
Your backbuffer contains corrupt, old data from when that memory space was used to render the desktop. For some reason your rendering code isn't properly targeting that buffer when it draws, so when that buffer is flipped to the front, you see garbage. Unfortunately at the moment I don't have time to look through your code to see where this may be going wrong, but in general you should be able to find the problem fairly easily by ensuring that the render logic targets the correct memory space.
Also you may want to try a massive ZeroMemory() on the backbuffer before you flip it (just as a debug) to see if you're flipping the right surface. If this works your backbuffer should render as solid black.
Also you may want to try a massive ZeroMemory() on the backbuffer before you flip it (just as a debug) to see if you're flipping the right surface. If this works your backbuffer should render as solid black.
I still get it even if I fill the backbuffer with black after I attach it to the primary surface.This is annoying me, I can't get further if I don't fix it.Can you please help me?
This means you are not setting up and/or flipping the correct buffer to the front, or you're doing it at the wrong time. If you can find some sample code that does that type of flipping you should be able to compare and find where the problem is.
You don't need to specify DDSCAPS_COMPLEX and DDSCAPS_FLIP for backbuffer. Remove those flags from back buffer initialization.
Use DDSURFACEDESC for primary buffer, but use DDSCAPS for backbuffer. ZeroMemory() first before you use them, and don't forget to set the dwSize.
You don't need to fill backbuffer with black. Since you will be drawing in it anyway. You may want to comment out your clipping initialization first, there might be something wrong with it. I never trusted DDBLTFX (because I never got it working [lol]), I used a blank bitmap instead.
Here's my DirectDraw initialization code (8-bit, there is an extra palette initialization at the end):
Disclaimer: old code.
Use DDSURFACEDESC for primary buffer, but use DDSCAPS for backbuffer. ZeroMemory() first before you use them, and don't forget to set the dwSize.
You don't need to fill backbuffer with black. Since you will be drawing in it anyway. You may want to comment out your clipping initialization first, there might be something wrong with it. I never trusted DDBLTFX (because I never got it working [lol]), I used a blank bitmap instead.
Here's my DirectDraw initialization code (8-bit, there is an extra palette initialization at the end):
void InitDirectDraw( HWND hwnd, int screen_width, int screen_height, int bpp ){ gmHWindow = hwnd; // Init DirectDraw HRESULT retval = E_FAIL; retval = DirectDrawCreate( NULL, &gmDirectDraw, NULL ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to create DirectDraw object." ); // Set cooperative level retval = gmDirectDraw->SetCooperativeLevel( gmHWindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to set exclusive cooperative level." ); // Set display mode retval = gmDirectDraw->SetDisplayMode( screen_width, screen_height, bpp ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to set display mode to 640x480x8." ); // Create surfaces DDSURFACEDESC ddsd; 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; retval = gmDirectDraw->CreateSurface( &ddsd, &gmPrimarySurface, NULL ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to create the primary surface." ); gmPrimarySurface->Restore(); DDSCAPS ddcaps; memset( &ddcaps, 0, sizeof(ddcaps) ); ddcaps.dwCaps = DDSCAPS_BACKBUFFER; retval = gmPrimarySurface->GetAttachedSurface( &ddcaps, &gmSecondarySurface ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to create the secondary surface." ); gmSecondarySurface->Restore(); // Create clipper retval = gmDirectDraw->CreateClipper( NULL, &gmClipper, NULL ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to create DirectDraw clipper object." ); retval = gmClipper->SetHWnd( 0, gmHWindow ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to set window handle to clipper object." ); gmSecondarySurface->SetClipper( gmClipper ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to set clipper object to back buffer." ); // Create Palette PALETTEENTRY pe[COLOR_COUNT]; for ( int i = 0; i < COLOR_COUNT; ++i ) { pe.peRed = (unsigned char)i; pe.peGreen = (unsigned char)i; pe.peBlue = (unsigned char)i; } retval = gmDirectDraw->CreatePalette( DDPCAPS_8BIT , pe, &gmPalette, NULL ); if ( FAILED(retval) ) throw Exception( __FILE__, __LINE__, "Unable to create a palette." );}
Disclaimer: old code.
Fixed.I attached the clipper to the primary surface instead of the back buffer and it solved it.
I think it's because the created primary surface contained garbage data, like what has been said.I am sure I had tried to fill it with black earlier but it didn't help at all, before the app puts something on the screen.I'm not sure.
I think it's because the created primary surface contained garbage data, like what has been said.I am sure I had tried to fill it with black earlier but it didn't help at all, before the app puts something on the screen.I'm not sure.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement