Archived

This topic is now archived and is closed to further replies.

Cef

Problem blitting on DirectDraw7

Recommended Posts

Hi, If anyone could help me with this problem... Im learning from the book TOTWGPG 2ED and on the happy face clipping example, my screen looks very unsable, like "flashing" in color black. I''ve not found my error, and don''t have the source CD, so I don''t know if this is because of my code or because of my Graphics card. I''d really appreciate any help...

Share this post


Link to post
Share on other sites
I don't have that book so I'm not sure what example you're talking about, maybe you can post your blitting code?

Also, make sure to clear the backbuffer each frame to your background color (most often black) to get rid of video memory artifacts.

[edited by - BitBlt on July 8, 2003 12:39:02 PM]

Share this post


Link to post
Share on other sites
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BIT_DEPTH 8
#include <windows.h>
#include <ddraw.h>
#include <ddrawex.h>
#include <mmsystem.h>
#define WIN32_LEAN_AND_MEAN
#include "T3D.h"


bool window_closed = 0;
HWND g_hWnd = NULL;
LPDIRECTDRAW7 lpDD7 = NULL;
PALETTEENTRY palette[256];
LPDIRECTDRAWPALETTE lpDDpal = NULL;
LPDIRECTDRAWSURFACE7 lpDDSPrimary = NULL, lpDDSBack = NULL;
DDSURFACEDESC2 DDsd;
POINT happy_faces[100];
POINT happy_facesv[100];


int GameInit()
{
DDPIXELFORMAT ddpixel;
if(FAILED(DirectDrawCreateEx(NULL, (void **) &lpDD7, IID_IDirectDraw7, NULL)))
OutputDebugString("Could not initialize COM object \n");
if(FAILED(lpDD7->SetCooperativeLevel(g_hWnd,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT)))
OutputDebugString("Could not set Coop Level \n");
if(FAILED(lpDD7->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,BIT_DEPTH,0,0)))
OutputDebugString("Could not set Display Mode\n");

memset(&DDsd, 0, sizeof(DDsd));

DDsd.dwSize = sizeof(DDSURFACEDESC2);
DDsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
DDsd.dwBackBufferCount = 1;

DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX |DDSCAPS_FLIP;

if(FAILED(lpDD7->CreateSurface(&DDsd, &lpDDSPrimary, NULL)))
OutputDebugString("Could not create primary surface\n");

DDsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

if(FAILED(lpDDSPrimary->GetAttachedSurface(&DDsd.ddsCaps, &lpDDSBack)))
OutputDebugString("Could not attach secondary surface\n");

memset(&ddpixel, 0, sizeof(ddpixel));
ddpixel.dwSize = sizeof(DDPIXELFORMAT);

if(FAILED(lpDDSPrimary->GetPixelFormat(&ddpixel)))
OutputDebugString("Could not get pixel format\n");

if(ddpixel.dwFlags & DDPF_RGB)
switch(ddpixel.dwRGBBitCount)
{
case 15:
{ OutputDebugString("Pixel format 555");
}break;
case 16:
{ OutputDebugString("Pixel format 565");
}break;
case 32:
{ OutputDebugString("Pixel format 32");
}break;
default: break;
}
//else if(ddpixel.dwFlags & DDPF_PALETTEINDEXED8)
//{
OutputDebugString("Pixel format 256");
PALETTEENTRY palette[256];
LPDIRECTDRAWPALETTE lpddpal = NULL;
for (int color=1; color<255; color++)
{
palette[color].peRed = rand()%256;
palette[color].peGreen = rand()%256;
palette[color].peBlue = rand()%256;
palette[color].peFlags = PC_NOCOLLAPSE;
}

palette[0].peRed = 0;
palette[0].peGreen = 0;
palette[0].peBlue = 0;
palette[0].peFlags = PC_NOCOLLAPSE;

palette[255].peRed = 255;
palette[255].peGreen = 255;
palette[255].peBlue = 255;
palette[255].peFlags = PC_NOCOLLAPSE;

palette[1].peRed = 255;
palette[1].peGreen = 255;
palette[1].peBlue = 0;
palette[1].peFlags = PC_NOCOLLAPSE;

if(FAILED(lpDD7->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
OutputDebugString("Could not create palette");
if(FAILED(lpDDSPrimary->SetPalette(lpddpal)))
OutputDebugString("Could not set palette");


//}

for(int face = 0; face < 100; face++)
{
happy_faces[face].x = rand()%SCREEN_WIDTH;
happy_faces[face].y = rand()%SCREEN_HEIGHT;
happy_facesv[face].x = rand()%4*(-rand()%2);
happy_facesv[face].y = rand()%4*(-rand()%2);
}

return 1;
}

int GameMain()
{

UCHAR happy_bitmap[64] = {0,0,0,0,0,0,0,0,
0,0,1,1,1,1,0,0,
0,1,0,1,1,0,1,0,
0,1,1,1,1,1,1,0,
0,1,0,1,1,0,1,0,
0,1,1,0,0,1,1,0,
0,0,1,1,1,1,0,0,
0,0,0,0,0,0,0,0};

DDBLTFX ddBltFX;
//RECT dest_rect;
//UCHAR *DoubleBuffer = (UCHAR *)malloc(SCREEN_WIDTH*SCREEN_HEIGHT);
UCHAR *BackBuffer = NULL;

if(window_closed)
return 0;

if(KEYDOWN(VK_ESCAPE))
{
PostMessage(g_hWnd,WM_CLOSE, 0,0);
window_closed = 1;
}

//memset((void *)DoubleBuffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);



DDRAW_INIT_STRUCT(ddBltFX);
ddBltFX.dwFillColor = 0;
if(FAILED(lpDDSPrimary->Blt(NULL, NULL, NULL, DDBLT_COLORFILL , &ddBltFX)))
{
OutputDebugString("Could not blit\n");

return 0;
}

//BackBuffer = (UCHAR *)DDsd.lpSurface;




DDRAW_INIT_STRUCT(DDsd);
DDsd.dwSize = sizeof(DDsd);

if(FAILED(lpDDSBack->Lock(NULL,&DDsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
OutputDebugString("Could not lock surface\n");


for(int face = 0; face < 100; face++)
Blit_Clipped(happy_faces[face].x, happy_faces[face].y, 8,8, happy_bitmap, (UCHAR *) DDsd.lpSurface, DDsd.lPitch);

for(face = 0; face < 100; face++)
{
happy_faces[face].x += happy_facesv[face].x;
happy_faces[face].y += happy_facesv[face].y;

if(happy_faces[face].x > SCREEN_WIDTH)
happy_faces[face].x = -8;
if(happy_faces[face].x < 0)
happy_faces[face].x = SCREEN_WIDTH;
if(happy_faces[face].y > SCREEN_HEIGHT)
happy_faces[face].y = -8;
if(happy_faces[face].y < -8)
happy_faces[face].y = SCREEN_HEIGHT;
}

if(FAILED(lpDDSBack->Unlock(NULL)))
OutputDebugString("Could not unlock surface");


while(FAILED(lpDDSPrimary->Flip(NULL, /*DDFLIP_WAIT*/0)));


return 1;
}

int GameShutdown()
{

if(lpDDpal){
if(FAILED(lpDDpal->Release()))
OutputDebugString("Could not realease Palette object\n");
lpDDpal = NULL;
}
if(lpDDSBack){
if(FAILED(lpDDSBack->Release()))
OutputDebugString("Could not realease Back Surface object\n");
lpDDSBack = NULL;
}
if(lpDDSPrimary){
if(FAILED(lpDDSPrimary->Release()))
OutputDebugString("Could not realease Surface object\n");
lpDDSPrimary = NULL;
}
if(lpDD7){
if(FAILED(lpDD7->Release()))
OutputDebugString("Could not realease COM object\n");
lpDD7 = NULL;
}

return 1;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hDC;

switch(msg)
{
case WM_CREATE:
{
return(0);
}
break;
case WM_PAINT:
{
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return(0);
}
break;
case WM_DESTROY:
{
PostQuitMessage(20);
return(0);
}
break;

default: break;
}
return(DefWindowProc(hWnd, msg, wparam, lparam));
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
WNDCLASSEX wc;


wc.cbClsExtra = NULL;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(hInstance, "IDI_BART");
wc.hIconSm = LoadIcon(hInstance,"IDI_BART");
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "WindowClass";
wc.lpszMenuName = "Menuppal";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;

RegisterClassEx(&wc);

g_hWnd = CreateWindowEx( NULL, "WindowClass", "Parent Guindow", WS_POPUP | WS_VISIBLE, 0,CW_USEDEFAULT,640,480,NULL,NULL,hInstance,NULL);

UpdateWindow(g_hWnd);

GameInit();

while(TRUE)
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if(msg.message==WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GameMain();
}
GameShutdown();
return(msg.wParam);
}

Share this post


Link to post
Share on other sites
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code)&0x8000000) ? 1:0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code)&0x8000000) ? 0:1)

#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))
#define _RGB32BIT(a,r,g,b) ((b)+ ((g)<<8)+((r)<<16)+((a)<<24))

#define DDRAW_INIT_STRUCT(ddstruct) {memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

//typedef struct _POINT {
// int x;
// int y;
//} POINT;

inline void PlotPixel8(int x, int y, UCHAR index, UCHAR *video_buffer, int lpitch)
{
video_buffer[x+y*lpitch] = index;
}

inline void PlotPixel555(int x, int y,int red, int green, int blue, USHORT *video_buffer, int lpitch)
{
USHORT pixel = _RGB16BIT555(red,green,blue);
video_buffer[x+y*lpitch] = pixel;
}

inline void PlotPixel565(int x, int y,int red, int green, int blue, USHORT *video_buffer, int lpitch)
{
USHORT pixel = _RGB16BIT565(red,green,blue);
video_buffer[x+y*lpitch] = pixel;
}

inline void PlotPixel32(int x, int y, int red, int green, int blue, int alpha, UINT *video_buffer, int lpitch)
{
UINT pixel = _RGB32BIT(alpha, red, green, blue);
video_buffer[x+y*lpitch] = pixel;
}

//En cada modo de video cambia pitch, cambia video_buffer, cambia RGB

void Blit_Clipped(int x, int y, int width, int height, UCHAR *bitmap, UCHAR *video_buffer, int mempitch)
{
if((x>=SCREEN_WIDTH) || (y>= SCREEN_HEIGHT) || (x+width<=0) || (y+height<=0))
return;

int x1 = x;
int y1 = y;
int x2 = x+width-1;
int y2 = y+height-1;

if(x1<0)
x1=0;
if(y1<0)
y1=0;

if(x2>=SCREEN_WIDTH)
x2=SCREEN_WIDTH-1;
if(y2>=SCREEN_HEIGHT)
y2=SCREEN_HEIGHT-1;

int xoff = x1-x;
int yoff = y1-y;

int dx = x2-x1+1;
int dy = y2-y1+1;

video_buffer += (x1 + y1*mempitch);

bitmap += (xoff + yoff*width);

UCHAR pixel;

for(int index_y = 0; index_y < dy; index_y++)
{
for(int index_x = 0; index_x < dx; index_x++)
{
if(pixel = bitmap[index_x])
video_buffer[index_x] = pixel;
}
video_buffer += mempitch;
bitmap += width;
}
}

Share this post


Link to post
Share on other sites