DirectX in a Window(need help)

Started by
17 comments, last by Dave Hunt 18 years, 7 months ago
So my program starts but it looks like weird random Graphic Errors O.o im linking to ddraw.lib dxguid.lib FreeImage.lib my files are: -bouncy_main.cpp -bouncy_classes.h -bouncy_functions.h -bouncy_resource.h -bouncy_resource.rc bouncy_main.cpp:

#include <windows.h>
#include <FreeImage.h>
#include <ddraw.h>
#include "bouncy_resource.h"
#include "bouncy_functions.h"
#include "bouncy_classes.h"

BitMapObject bmoBall;
BitMapObject bmoBackground;
HBITMAP hBall;
HWND hWnd;
CBouncyBall BallClass;

LPDIRECTDRAW7 lpDD;
LPDIRECTDRAWSURFACE7 lpDDSPrimary;
LPDIRECTDRAWSURFACE7 lpDDSBack;
LPDIRECTDRAWCLIPPER  lpDDClipper;

int Bouncy_Points;
bool done;
bool bRunGame;

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
	switch(message){
		case WM_SIZE:
		{
			SetWindowPos(hWnd,0,0,0,400,500,SWP_NOMOVE | SWP_NOZORDER);
			return(0);
		}break;
		case WM_COMMAND:
		{
			switch(LOWORD(wParam)){
				case MENUID_CLOSE:
				{
                    PostMessage(hWnd,WM_DESTROY,0,0);
					return(0);
				}break;
			}
		}break;
		case WM_KEYDOWN:
		{
		switch(wParam){
			case VK_ESCAPE:
			{
				PostMessage(hWnd,WM_DESTROY,0,0);
				return(0);
			}break;
		}
		}break;
		case WM_DESTROY:
		{
			done=true;
			return(0);
		}break;
		case WM_ACTIVATE:
		{
			if( LOWORD( wParam ) == WA_INACTIVE )
{
    
    bRunGame = false;
}
else
{
    
    bRunGame = true;
}
		}break;
		default:break;
	}
	return(DefWindowProc(hWnd,message,wParam,lParam));
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow){
	MSG message;
	WNDCLASSEX bouncyMain;
	bouncyMain.cbSize=sizeof(WNDCLASSEX);
	bouncyMain.style=CS_HREDRAW|CS_VREDRAW;
	bouncyMain.lpfnWndProc=WindowProc;
	bouncyMain.cbClsExtra=0;
	bouncyMain.cbWndExtra=0;
	bouncyMain.hInstance=hinst;
	bouncyMain.hIcon=LoadIcon(NULL,IDI_WINLOGO);
	bouncyMain.hCursor=LoadCursor(NULL,IDC_ARROW);
	bouncyMain.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	bouncyMain.lpszMenuName=MAKEINTRESOURCE(MAIN_MENU);
	bouncyMain.lpszClassName="BouncyMainClass";
	bouncyMain.hIconSm=LoadIcon(NULL,IDI_WINLOGO);
	if(!RegisterClassEx(&bouncyMain))return(0);
	if(!(hWnd=CreateWindowEx(NULL,
                             "BouncyMainClass",
                             "Bouncy Ball",
                             WS_BORDER | WS_SYSMENU | WS_VISIBLE,
                             200, 200,
                             400, 500,
                             NULL,
                             NULL,
                             hinst,
                             NULL)))return(0);
    ShowWindow(hWnd,SW_SHOWNORMAL);
    UpdateWindow(hWnd);
    if(!Bouncy_Init())return(0);
    FreeImage_Initialise(false);
    done=false;
    while(!done){
    	while(PeekMessage(&message,hWnd,0,0,PM_REMOVE)){
    		TranslateMessage(&message);
    		DispatchMessage(&message);
    	}
    	GameLoop();
    }
    Bouncy_EndDDraw();
    PostQuitMessage(0);
	return(0);
}
bool Bouncy_Init(void){
    if(!Bouncy_InitDDraw())return(false);
    return(true);
}
bool Bouncy_InitDDraw(void){
	HRESULT ddrval;
	ddrval=DirectDrawCreateEx(NULL,(LPVOID *)&lpDD,IID_IDirectDraw7,NULL);
	if(ddrval!=DD_OK){
		return(false);
	}
	ddrval=lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL);
	if(ddrval!=DD_OK){
		lpDD->Release();
		return(false);
	}
	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	ddsd.dwFlags=DDSD_CAPS;
	ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
	ddrval=lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL);
	if(ddrval!=DD_OK){
		lpDD->Release();
		return(false);
	}
ZeroMemory(&ddsd, sizeof(ddsd));

ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 400; 
ddsd.dwHeight = 500; 
ddrval=lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL);
if(ddrval!=DD_OK){
	lpDD->Release();
	lpDDSPrimary->Release();
	return(false);
}
ddrval=lpDD->CreateClipper(0,&lpDDClipper,NULL);
if(ddrval!=DD_OK){
	lpDD->Release();
	lpDDSPrimary->Release();
	lpDDSBack->Release();
	return(false);
}
ddrval=lpDDClipper->SetHWnd(0,hWnd);
if(ddrval!=DD_OK){
	lpDDClipper->Release();
	lpDDSPrimary->Release();
	lpDDSBack->Release();
	lpDD->Release();
	return(false);
}
ddrval=lpDDSPrimary->SetClipper(lpDDClipper);
if(ddrval!=DD_OK){
		lpDDClipper->Release();
	lpDDSPrimary->Release();
	lpDDSBack->Release();
	lpDD->Release();
	return(false);
}
	return(true);
}
bool Bouncy_EndDDraw(void){
	if(lpDDSBack){
		lpDDSBack->Release();
		lpDDSBack=NULL;
	}
	if(lpDDSPrimary){
		lpDDSPrimary->SetClipper(NULL);
		lpDDClipper=NULL;
		lpDDSPrimary->Release();
		lpDDSPrimary=NULL;
	}
	if(lpDD){
		lpDD->Release();
		lpDD=NULL;
	}
	return(true);
}
bool GameLoop(){
    if(bRunGame){
    	DrawAll();
    }
	return(true);
}
bool DrawAll(){
    DDSURFACEDESC2 ddsd;
    UCHAR *VRam;
    int Linewidth;
    int x,y;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    lpDDSBack->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
    Linewidth=ddsd.lPitch;
    VRam=(UCHAR *)ddsd.lpSurface;
    for(y=0;y<200;y++){
    for(x=0;x<200;x++){
    	VRam[x+y*Linewidth]=245;
    }
    }
    lpDDSBack->Unlock(NULL);
    Bouncy_Flip();
	return(true);
}
bool Bouncy_Flip(void){
	RECT rect;
	ZeroMemory(&rect,sizeof(rect));
	GetClientRect(hWnd,&rect);
	POINT p1;
	POINT p2;
	p1.x=rect.left;
	p1.y=rect.top;
	p2.x=rect.right;
	p2.y=rect.bottom;
	ClientToScreen(hWnd,&p1);
	ClientToScreen(hWnd,&p2);
	rect.left=p1.x;
	rect.top=p1.y;
	rect.right=p2.x;
	rect.bottom=p2.y;
	lpDDSPrimary->Blt(&rect,lpDDSBack,NULL,DDBLT_WAIT,NULL);
	return(true);
}

bouncy_functions.h:

bool Bouncy_Init(void);
bool GameLoop();
bool DrawAll();
bool Bouncy_InitDDraw(void);
bool Bouncy_EndDDraw(void);
bool Bouncy_Flip(void);


bouncy_classes.h:

#include <windows.h>
class BitMapObject
{
	private:
	  HDC hdcMemory;
	  HBITMAP hbmNewBitMap;
	  HBITMAP hbmOldBitMap;
	  int iWidth, iHeight;
    public:
      BitMapObject();
      ~BitMapObject();
      void Load(HDC hdcCompatible, HBITMAP hLoad);
      void Create(HDC hdcCompatible, int width, int height);
      void Destroy();
      int GetWidth();
      int GetHeight();
      operator HDC();
};

BitMapObject::BitMapObject()
{
	hdcMemory=NULL;
	hbmOldBitMap=NULL;
	hbmNewBitMap=NULL;
	iWidth=0;
	iHeight=0;
}
BitMapObject::~BitMapObject(){
	if(hdcMemory)Destroy();
}
void BitMapObject::Load(HDC hdcCompatible, HBITMAP hLoad){
	if(hdcMemory)Destroy();
	hdcMemory=CreateCompatibleDC(hdcCompatible);
	hbmNewBitMap=hLoad;
	hbmOldBitMap=(HBITMAP)SelectObject(hdcMemory,hbmNewBitMap);
	BITMAP bmp;
	GetObject(hbmNewBitMap,sizeof(BITMAP),(LPVOID)&bmp);
	iWidth=bmp.bmWidth;
	iHeight=bmp.bmHeight;
}
void BitMapObject::Create(HDC hdcCompatible, int width, int height){
	if(hdcMemory)Destroy();
	hdcMemory=CreateCompatibleDC(hdcCompatible);
	hbmNewBitMap=CreateCompatibleBitmap(hdcCompatible,width,height);
	hbmOldBitMap=(HBITMAP)SelectObject(hdcMemory,hbmNewBitMap);
	iWidth=width;
	iHeight=height;
}
void BitMapObject::-)estroy(){
	SelectObject(hdcMemory,hbmOldBitMap);
	DeleteObject(hbmNewBitMap);
	DeleteDC(hdcMemory);
	hdcMemory=NULL;
	hbmOldBitMap=NULL;
	hbmNewBitMap=NULL;
	iWidth=0;
	iHeight=0;
}
BitMapObject::operator HDC(){
	return(hdcMemory);
}
int BitMapObject::GetWidth(){
	return(iWidth);
}
int BitMapObject::GetHeight(){
	return(iHeight);
}

class CBouncyBall
{
	private:
	float x,y;
	float vx,vy;
	public:
	CBouncyBall();
	~CBouncyBall();
	bool SetX(float nx);
	bool SetY(float ny);
	float GetX();
	float GetY();
	float GetVX();
    float GetVY();
	bool SetVX(float nvx);
	bool SetVY(float nvy);
};
CBouncyBall::CBouncyBall(){
	x=y=0;
	vx=vy=0;
}
CBouncyBall::~CBouncyBall(){
	x=y=0;
	vx=vy=0;
}
float CBouncyBall::GetX(){
	return(x);
}
float CBouncyBall::GetY(){
	return(y);
}
bool CBouncyBall::SetX(float nx){
	x=nx;
	return(true);
}
bool CBouncyBall::SetY(float ny){
	y=ny;
	return(true);
}
bool CBouncyBall::SetVX(float nvx){
	vx=nvx;
	return(true);
}
bool CBouncyBall::SetVY(float nvy){
	vy=nvy;
	return(true);
}
float CBouncyBall::GetVX(){
	return(vx);
}
float CBouncyBall::GetVY(){
	return(vy);
}

bouncy_resource.rc:

#include "bouncy_resource.h"

MAIN_MENU MENU
{
    MENUITEM "&Close" MENUID_CLOSE
}

bouncy_resource.h:

#define MENUID_CLOSE 1001
#define MAIN_MENU 1000


[Edited by - Coder on September 1, 2005 6:26:26 PM]
Advertisement
Hey,

First, you should change those 'quote' tags to 'source' tags; makes things much easier to read.

Second, can you clarrify what the 'weird random graphic errors' are? A screen shot would be awesome. From what you've said, it sounds like you may just not be clearing your back buffer.

Matt Hughson
__________________________________[ Website ] [ Résumé ] [ [email=contact[at]matthughson[dot]com]Contact[/email] ][ Have I been Helpful? Hook me up! ]
Sure ;)
theres a screenshot:
http://graalatlantis.gr.funpic.de/graphicerror.html
no directlinks...
*bump* O.o
I suggest you use a IDirectDrawSurface7::Blt, it's faster and less work.
lpDDSPrimary->Blt(&rect,lpDDSBack,NULL,DDBLT_WAIT,NULL);

ehr?
If I remember correctly, you should blit to back buffer to the front. I found a source code example of a windowed DirectDraw 7 app for you on the net (www.codeguru.com). It should show you how to use the Blt correctly in windowed mode. It's written in C++ so I hope that the classes and stuff don't confuse you.

// DDrawSystem.h: interface for the CDDrawSystem class.//////////////////////////////////////////////////////////////////#if !defined(AFX_DDRAWSYSTEM_H__1E152EB4_ED1D_4079_BDD4_773383DD98C8    __INCLUDED_)#define AFX_DDRAWSYSTEM_H__1E152EB4_ED1D_4079_BDD4_773383DD98C8    __INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include <ddraw.h>#define _CHARACTORBUILDER_#include "../GameLib/Image.h"class CDDrawSystem{public:  CDDrawSystem();  virtual ~CDDrawSystem();  BOOL Init(HWND hWnd);  void Terminate();  void Clear();  void TestDraw(int x, int y);  void Display();protected:  LPDIRECTDRAW7 m_pDD;  LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer;  LPDIRECTDRAWSURFACE7 m_pddsStoreBuffer;  LPDIRECTDRAWCLIPPER pcClipper;  HWND hWnd;};#endif//!defined(AFX_DDRAWSYSTEM_H__1E152EB4_ED1D_4079_BDD4_773383DD98C8__INCLUDED_)// DDrawSystem.cpp: implementation of the CDDrawSystem class.//////////////////////////////////////////////////////////////////#include "stdafx.h"#include "DDrawSystem.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif////////////////////////////////////////////////////////////////// Construction/Destruction////////////////////////////////////////////////////////////////CDDrawSystem::CDDrawSystem(){  m_pDD = NULL;  m_pddsFrontBuffer = NULL;  m_pddsStoreBuffer = NULL;  pcClipper = NULL;}CDDrawSystem::~CDDrawSystem(){  Terminate();}// old DirectDraw Initialization stuff.// Set a window mode DirectDraw Display.BOOL CDDrawSystem::Init(HWND hWnd){  HRESULT hRet;  this->hWnd = hWnd;  hRet = DirectDrawCreateEx(NULL, (VOID**)&m_pDD,    IID_IDirectDraw7, NULL);  if(hRet != DD_OK)  {    AfxMessageBox("Failed to create directdraw object.");    return FALSE;  }  hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);  if(hRet != DD_OK)  {    AfxMessageBox("Failed to set directdraw display behavior.");    return FALSE;  }  HRESULT hr;  DDSURFACEDESC2 ddsd;  ZeroMemory( &ddsd, sizeof( ddsd ) );  ddsd.dwSize = sizeof( ddsd );  ddsd.dwFlags = DDSD_CAPS;  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  if(FAILED(hr = m_pDD->CreateSurface(&ddsd,    &m_pddsFrontBuffer, NULL)))  {    AfxMessageBox("Failed to create primary surface.");    return FALSE;    }  // Create the backbuffer surface  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |    DDSCAPS_3DDEVICE;  ddsd.dwWidth = 800;  ddsd.dwHeight = 600;  if(FAILED(hr = m_pDD->CreateSurface(&ddsd,    &m_pddsStoreBuffer, NULL)))  {    AfxMessageBox("Failed to create back buffer surface.");    return FALSE;  }  if(FAILED(hr = m_pDD->CreateClipper(0, &pcClipper, NULL)))  {    AfxMessageBox("Failed to create clipper.");    return FALSE;  }  if(FAILED(hr = pcClipper->SetHWnd(0, hWnd)))  {    pcClipper->Release();    AfxMessageBox("Failed to create primary surface.");    return FALSE;  }  if(FAILED(hr = m_pddsFrontBuffer->SetClipper(pcClipper)))  {    pcClipper->Release();     AfxMessageBox("Failed to create primary surface.");    return FALSE;  }  return TRUE;}// make sure all things are terminated and set to NULL// when application ends.void CDDrawSystem::Terminate(){  if (m_pDD != NULL)  {    if (m_pddsFrontBuffer != NULL)    {      if (m_pddsStoreBuffer != NULL)      {        m_pddsStoreBuffer->Release();        m_pddsStoreBuffer = NULL;      }      if (pcClipper != NULL)      {        pcClipper->Release();        pcClipper = NULL;      }        m_pddsFrontBuffer->Release();        m_pddsFrontBuffer = NULL;        }      m_pDD->Release();      m_pDD = NULL;  }}// clear both off csreen buffer and primary buffer.void CDDrawSystem::Clear(){  HRESULT hRet;  DDBLTFX fx;  fx.dwSize = sizeof(fx);  fx.dwFillColor = 0x000000;  while (1)  {    hRet = m_pddsFrontBuffer->Blt(NULL, NULL, NULL,      DDBLT_COLORFILL, &fx);    if (hRet == DD_OK)      break;    else if (hRet == DDERR_SURFACELOST)      {        m_pddsFrontBuffer->Restore();      }     else if (hRet != DDERR_WASSTILLDRAWING)       break;    }  while (1)  {    hRet = m_pddsStoreBuffer->Blt(NULL, NULL, NULL,      DDBLT_COLORFILL, &fx);    if (hRet == DD_OK)      break;    else if (hRet == DDERR_SURFACELOST)      {        m_pddsStoreBuffer->Restore();      }    else if (hRet != DDERR_WASSTILLDRAWING)      break;  }}// a test:// The conclusion is: Under no circumstance, draw directly to// primary Surface!// It doesn't work that way.// ...// ...// This is just a simple test function. It has shit use in this//  project.void CDDrawSystem::TestDraw(int x, int y){  HRESULT hRet;  HDC dc;  hRet = m_pddsStoreBuffer->GetDC(&dc);  if (hRet != DD_OK)    return;  POINT p = {0 + x, 0 + y};  ClientToScreen(hWnd, &p);  SetTextColor(dc, RGB(255, 0, 0));  TextOut(dc, 20, 20, "This is a stinky App", lstrlen("This is    a stinky App"));   Ellipse(dc, x-50, y-50, x+50,y+50);  m_pddsStoreBuffer->ReleaseDC(dc);}// Load images from offscteen buffer to primary buffer// and for display.void CDDrawSystem::Display(){  HRESULT hRet;  RECT rt;  POINT p = {0, 0};  ClientToScreen(hWnd, &p);  rt.left = 0 + p.x;  rt.top = 0 + p.y;  rt.right = 800 + p.x; rt.bottom = 600 + p.y;  while(1)  {    hRet = m_pddsFrontBuffer->Blt(&rt, m_pddsStoreBuffer,      NULL, DDBLT_WAIT, NULL);    if (hRet == DD_OK)      break;    else if(hRet == DDERR_SURFACELOST)      {        m_pddsFrontBuffer->Restore();        m_pddsStoreBuffer->Restore();      }    else if(hRet != DDERR_WASSTILLDRAWING)      return;   }}
You just need to clear the backbuffer (using a Blt with DDBLT_COLORFILL) before drawing to it.
Oh works now, thanks
ehm i got another problem
bool DrawAll(){    if(!Bouncy_ClearBack())return(false);    int x,y,Linewidth;    UCHAR *VRam;    DDSURFACEDESC2 ddsd;    HRESULT ddrval;    ZeroMemory(&ddsd,sizeof(ddsd));    ddsd.dwSize=sizeof(ddsd);    lpDDSBack->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);    Linewidth=ddsd.lPitch;    VRam=(UCHAR *)ddsd.lpSurface;        for(x=0;x<500;x++){    	for(y=0;y<10;y++){    		VRam[x+(y*Linewidth)]=234;    	}    }    lpDDSBack->Unlock(NULL);    Bouncy_Flip();	return(true);}

thats my ne drawall

and thats my new clearback:
bool Bouncy_ClearBack(void){    HRESULT ddrval;	DDBLTFX fx;	fx.dwSize=sizeof(fx);	fx.dwFillColor=0xFFFFFF;	ddrval=lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);	if(ddrval==DD_OK)return(true);	else{		if(ddrval==DDERR_SURFACELOST){			lpDDSBack->Restore();				ddrval=lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);				if(ddrval==DD_OK)return(true);else return(false);		}	}	return(true);}


why it dont fills the entire window with the color
i mean its 500 x , the window is only 400 width
O.o it wont work with 400 or 300 either
Because your code assumes there is one byte per pixel. If your screen color resolution is 32-bits, then there are actually 4 bytes per pixel. In 16-bits, there would be 2 bytes per pixel.

This topic is closed to new replies.

Advertisement