7 Replies - 1459 Views - Last Post: 11 May 2012 - 05:14 PM Rate Topic: -----

#1 Spazmatic08   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 04-May 12

DirectX9: Background will not appear

Posted 04 May 2012 - 12:29 PM

Hey! New member here. I've just started trying to program a basic game from a textbook using Visual Studio 2005, but I've already hit a major snag. The book I'm using wasn't designed for DirectX9, and part of the code I've had to build from scratch or alter in order to work. However, after trying multiple configurations and tinkering with the code several times, I still can't get the background to display; I'm simply getting the same completely black background. I realize I may be making a mistake in posting the entire program's code, but it's relatively simple at the moment; I just want a white rectangle moving around the screen by using the arrow keys, and the background displayed properly. I've tried replacing portions of the Render() function with BeginScene() and EndScene(), which only got me a blank white screen. I can't figure out where I've gone wrong. Any ideas?

Assume that the resource files for the project include the necessary menu resources. The bitmap resource is in the proper place in the file for it to be loaded by LoadTextureFromFile(), though I only know that because I copied/pasted it all over the place to make SURE that wasn't the issue.

/* Zong Driver File
   3/13/12, by --------- */

//header files to include
#include <d3d9.h>
#include <d3dx9.h>
#include <mmsystem.h>
#include <assert.h>
#include <windows.h>
#include "resource.h"

//application title
#define APPTITLE L"Zong"

//function prototypes (forward declarations)
BOOL InitInstance(HINSTANCE,int);
ATOM MyRegisterClass(HINSTANCE);
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
HRESULT InitDirect3DDevice(HWND,int,int,BOOL,D3DFORMAT,LPDIRECT3D9,LPDIRECT3DDEVICE9*);
void CopyTexture(LPDIRECT3DSURFACE9,LPDIRECT3DSURFACE9);
void LoadTexture(LPDIRECT3DSURFACE9,LPCWSTR);
void Render();
void Rectangle32Fast(D3DRECT*,DWORD,LPDIRECT3DDEVICE9);
void GameLoop();
void GameInit();
void GameShutDown();


//global variables
HWND g_hWndMain;
int g_DeviceWidth = 640;
int g_DeviceHeight = 480;
D3DRECT g_ControlRect;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pDevice = NULL;
LPDIRECT3DSURFACE9 g_pBGSurf = NULL;

//---------------------------------------------------------------------------------------------------------
//the window event callback function; IMPORTANT
LRESULT CALLBACK WinProc(HWND hWnd,  //window handle
						 UINT message,  //message sent to the callback procedure, only occasionally even needed.
						 WPARAM wParam,  //high bit value parameter
						 LPARAM lParam)  //low bit value parameter
{
	switch(message)  //essentially a huge nested 'if' statement; an easy way
	{                //to handle multiple messages without using nested 'if's
		case WM_PAINT:  //handles window updates
			//start drawing on device context
			ValidateRect(hWnd, NULL);
			break;

		case WM_COMMAND:  //handles use of the menu
			switch(LOWORD(wParam))
			{
				case ID_HELP_about:
					MessageBox( NULL,
						        L"I love Menus!",
								L"Menu-Induced Message Box",
								MB_OK);
					break;
				
				case ID_FILE_EXIT:
					PostQuitMessage(2);
					break;

				default:
					break;
			}

		case WM_DESTROY:  //tells the window that it is time to shut down
			PostQuitMessage(0);
			break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}
//-----------------------------------------------------------------------------------------------------------
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	//create the window class structure
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);

	//fill the struct with info
	wc.style           = CS_HREDRAW | CS_VREDRAW;  //redraws the window to compensate for changes in dimensions
	wc.lpfnWndProc     = (WNDPROC)WinProc;  //long pointer to a callback function; may be named anything, but parameters MUST be accurate
	wc.cbClsExtra      = 0;  //Add extra bytes of memory to a window
	wc.cbWndExtra      = 0;  //procedure; should typically be set to 0
	wc.hInstance       = hInstance;  //so the main window knows which instance it's using
	wc.hIcon           = NULL;  //self-explanatory; typically only used for windowed games
	wc.hCursor         = LoadCursor(NULL, IDC_ARROW);  // ^   ^    ^    ^    ^    ^    ^
	wc.hbrBackground   = (HBRUSH)GetStockObject(WHITE_BRUSH);  //sets the handle for a brush to paint the background
	wc.lpszMenuName    = MAKEINTRESOURCE(IDR_MENU1);  //set to the name of the program menu; not covered in the samples provided
	wc.lpszClassName   = APPTITLE;  //gives the window a specific class name
	wc.hIconSm         = NULL;  //unexplained

	//set up the window with the class info
	return RegisterClassEx(&wc);  //RegisterClassEx is passed wc, registering the window with Windows
}
//-----------------------------------------------------------------------------------------------------------
//helper function to create the window and refresh it
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	//create a new window
	g_hWndMain = CreateWindow(
		APPTITLE,                //window class
		APPTITLE,                //title bar
		WS_OVERLAPPEDWINDOW,     //window style
		CW_USEDEFAULT,           //xposition of the window
		CW_USEDEFAULT,           //yposition of the window
		500,                     //width of the window
		400,                     //height of the window
		NULL,                    //parent window
		NULL,                    //menu
		hInstance,               //application instance
		NULL);                   //window parameters

	//was there an error creating the window?
	if (!g_hWndMain)
		return FALSE;

	//display the window
	ShowWindow(g_hWndMain, nCmdShow);
	UpdateWindow(g_hWndMain);

	return TRUE;
}
//-----------------------------------------------------------------------------------------------------------
//helper function to initialize the Direct3D device for fullscreen format
HRESULT InitDirect3DDevice(HWND hWndTarget, 
					   int Width, 
					   int Height, 
					   BOOL bWindowed, 
					   D3DFORMAT FullScreenFormat, 
					   LPDIRECT3D9 pD3D,
					   LPDIRECT3DDEVICE9* ppDevice)
{
	//Create the variable for tracking the results of functions
	HRESULT r;

	//Structure to hold information about the rendering method
	D3DPRESENT_PARAMETERS d3dpp;
	//Structure to hold information about the current display mode
	D3DDISPLAYMODE d3ddm;

	//Verify that the contents of ppDevice are empty
	if(*ppDevice != NULL)
		(*ppDevice)->Release();

	//Initialize d3dpp to 0
	ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
	//Get the settings for the current display mode
	r = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
	assert(SUCCEEDED(r));       //Fails if GetAdapterDisplayMode failed\

	//Set specific present parameters
	d3dpp.BackBufferWidth = Width;
	d3dpp.BackBufferHeight = Height;
	d3dpp.BackBufferFormat = bWindowed ? d3ddm.Format : FullScreenFormat;
	d3dpp.BackBufferCount = 1;
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.hDeviceWindow = hWndTarget;
	d3dpp.Windowed = bWindowed;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.FullScreen_RefreshRateInHz = 0;
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

	//Create the Direct3D device
	r = pD3D->CreateDevice(D3DADAPTER_DEFAULT,
						   D3DDEVTYPE_HAL,
						   hWndTarget,
						   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
						   &d3dpp,
						   ppDevice);
	assert(SUCCEEDED(r));     //Fails if the D3D device wasn't properly created

	return(S_OK);
}
//-----------------------------------------------------------------------------------------------------------
void CopyTexture(LPDIRECT3DSURFACE9 pBaseSurface, LPDIRECT3DSURFACE9 pDestSurface)
//Copies a texture from the base surface to a target surface
{
	g_pDevice->StretchRect(pBaseSurface,
				NULL,
				pDestSurface,
				NULL,
				D3DTEXF_NONE);
}
//-----------------------------------------------------------------------------------------------------------
void LoadTexture(LPDIRECT3DSURFACE9 pBaseSurface, LPCWSTR PathName)
//Loads a texture to the given surface
{
	HRESULT r;

	// Create a surface to hold the loaded texture in pBaseSurface
	r = g_pDevice->CreateOffscreenPlainSurface(
		g_DeviceWidth,
		g_DeviceHeight,
		D3DFMT_X8R8G8B8,
		D3DPOOL_DEFAULT,
		&pBaseSurface,
		NULL);
	assert(SUCCEEDED(r));  // Fails if the surface wasn't created

	// Load a texture from file to the surface
	r = D3DXLoadSurfaceFromFile(
		pBaseSurface,
		NULL,
		NULL,
		PathName,
		NULL,
		D3DX_DEFAULT,
		0,
		NULL);
	assert(SUCCEEDED(r));   //Fails if the surface didn't load using the texture
}
//-----------------------------------------------------------------------------------------------------------
//Used in GameLoop() to render
void Render()
/* Seven-step process:
	1. Clear the back buffer
	2. Acquire a pointer to the back buffer surface
	3. Lock the back buffer surface
	4. Draw into the back buffer memory
	5. Unlock the memory so that Direct3D can proceed to render
	6. Release the pointer to the back buffer
	7. Present the back buffer to the primary surface           */
{
	//Create the variable to track function results
	HRESULT r;

	//Create pointer to back buffer surface
	LPDIRECT3DSURFACE9 pBackSurf = NULL;
	//Create a base surface for loading textures
	LPDIRECT3DSURFACE9 pBaseSurf = NULL;
	//Create the locked rectangle variable
	D3DLOCKED_RECT LockedRect;

	//Confirm that the device exists
	assert(g_pDevice != NULL);
	
	//Phase 1
	r = g_pDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0.0f, 0);
	assert(SUCCEEDED(r));    //Fails if the back buffer didn't clear

	//Phase 2
	r = g_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackSurf);
	assert(SUCCEEDED(r));    //Fails if the pointer to the back buffer surface wasn't initialized properly

	//Phase 3
	r = pBackSurf->LockRect(&LockedRect, NULL, 0);
	assert(SUCCEEDED(r));     //Fails if the back buffer didn't lock

	//Phase 4
	//---------------------------- Do drawing here ------------------------------------

	//Draw the background
	CopyTexture(g_pBGSurf,pBackSurf);

	//Draw the controlled rectangle
	Rectangle32Fast(&g_ControlRect,
					D3DCOLOR_XRGB(254,254,254),
					g_pDevice);

	//Phase 5
	pBackSurf->UnlockRect();

	//Phase 6
	pBackSurf->Release();
	pBackSurf = NULL;

	//Phase 7
	g_pDevice->Present(NULL, NULL, NULL, NULL);
}
//----------------------------------------------------------------------------------------------------------
//Draws a solid rectangle by setting a block of pixels to a specific color
//Only works on the back buffer
void Rectangle32Fast(D3DRECT *pRect, DWORD Color, LPDIRECT3DDEVICE9 g_pDevice)
{
	g_pDevice->Clear(1,
					 pRect,
					 D3DCLEAR_TARGET,
					 Color,
					 0.0f,
					 0);
}
//----------------------------------------------------------------------------------------------------------
void GameLoop()
// Idle code for the game
{
	//get a DC for this window
	HDC hdc = GetDC(g_hWndMain);

	//idle code
	Render();

	//change the position of the controllable rectangle according to user input
	if((GetAsyncKeyState(VK_LEFT))&&(g_ControlRect.x1-1 > 0))
	{
		g_ControlRect.x1--;
		g_ControlRect.x2--;
	}
	if((GetAsyncKeyState(VK_RIGHT))&&(g_ControlRect.x2+1 < 640))
	{
		g_ControlRect.x1++;
		g_ControlRect.x2++;
	}
	if((GetAsyncKeyState(VK_UP))&&(g_ControlRect.y1-1 > 0))
	{
		g_ControlRect.y1--;
		g_ControlRect.y2--;
	}
	if((GetAsyncKeyState(VK_DOWN))&&(g_ControlRect.y2+1 < 480))
	{
		g_ControlRect.y1++;
		g_ControlRect.y2++;
	}

	if(GetAsyncKeyState(VK_ESCAPE))
		PostQuitMessage(0);   //closes the window by pressing Escape

	//return the DC to Windows
	ReleaseDC(g_hWndMain,hdc);
}
//-----------------------------------------------------------------------------------------------------------
void GameInit()
// Used to initialize the necessary components for the game, like the resources
{
	//Create the variable for tracking the results of functions
	HRESULT r;

	//Create the user-controlled rectangle object
	g_ControlRect.x1 = 300;
	g_ControlRect.x2 = 340;
	g_ControlRect.y1 = 200;
	g_ControlRect.y2 = 280;

	//Create the DirectX interface object
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	assert(g_pD3D != NULL);    //Fails if the DirectX interface object wasn't created

	//Create the Direct3D device
	r = InitDirect3DDevice(g_hWndMain, g_DeviceWidth, g_DeviceHeight, FALSE, D3DFMT_X8R8G8B8, g_pD3D, &g_pDevice);
	assert(SUCCEEDED(r));     //Fails if the Direct3D device wasn't properly created

	//Load the background texture
	LoadTexture(g_pBGSurf, L"legotron.bmp");
}
//-----------------------------------------------------------------------------------------------------------
void GameShutDown()
// Used to shut down the game when done; delete pointers, release DC, etc.
// Remember to delete in reverse order of initialization!
{
	//delete g_BGSurf;

	if(g_pBGSurf != NULL)
		g_pBGSurf->Release();

	//delete g_pDevice;

	if(g_pDevice != NULL)
		g_pDevice->Release();

	//delete g_pD3D;
	
	if(g_pD3D != NULL)
		g_pD3D->Release();

}
//==============================================================================================================
//entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow)
{
	//declare variables
	MSG msg;

	//register the class
	MyRegisterClass(hInstance);

	//initialize application
	if(!InitInstance(hInstance, nCmdShow))
		return FALSE;

	GameInit();

	//main message loop
	while (TRUE)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			//check if the message is to quit the application
			if(msg.message == WM_QUIT)
				//exit the message loop
				break;
			//change the format of certain messages
			TranslateMessage(&msg);
			//pass the message for processing
			DispatchMessage(&msg);
		}
		else
		{
			GameLoop();
		}
	}

	//delete pointers, perform shutdown routines
	GameShutDown();

	return(msg.wParam);
}



P.S.: I apologize if I shouldn't be posting massive pieces of code, but again, I'm new to programming forums in general and the code I've brought together is part me, part old textbook, and part semi-modern textbook, so it's a little convoluted. I was worried that posting just part of the code wouldn't provide the necessary information, so I just went and pasted the whole thing hoping that the moderately copious comments would help clarify it. I'd also love some general code tips, as I'm new to game programming in general. Thanks in advance for your patience!

Is This A Good Question/Topic? 0
  • +

Replies To: DirectX9: Background will not appear

#2 anonymous26   User is offline

  • D.I.C Lover

Reputation: 2
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: DirectX9: Background will not appear

Posted 04 May 2012 - 01:55 PM

1. Have you placed a breakpoint in the code that draws?
2. Are any assert being fired?
Was This Post Helpful? 0
  • +
  • -

#3 Spazmatic08   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 04-May 12

Re: DirectX9: Background will not appear

Posted 08 May 2012 - 09:52 AM

I'm not 100% sure as to what you mean by a breakpoint that draws. I have all the drawing done in the Render() function, which is called in GameLoop(). The drawing for the background starts by loading the texture from the file to a global surface, which is done in GameInit(). I then use StretchRect() to copy the contents of that global surface to the back buffer, then draw the user-controlled rectangle on top of it, all in the Render() function. The user-controlled rectangle works fine, but the background doesn't display; I just get the standard black screen behind the rectangle.

None of the asserts are firing. The code runs fine except for the background problem.

Since I posted the code, I've made a couple of updates. The unreferenced pBaseSurf in Render() has been removed (it was leftover from prior attempts without a global variable) and I've changed the first parameter in LoadTexture() and the second parameter in CopyTexture() to reference parameters, which they probably should have been to begin with, but hasn't fixed the problem.
Was This Post Helpful? 0
  • +
  • -

#4 anonymous26   User is offline

  • D.I.C Lover

Reputation: 2
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: DirectX9: Background will not appear

Posted 08 May 2012 - 01:23 PM

View PostSpazmatic08, on 08 May 2012 - 05:52 PM, said:

I'm not 100% sure as to what you mean by a breakpoint that draws.

I didn't say that. Do you know what a breakpoint is?
Was This Post Helpful? 0
  • +
  • -

#5 Spazmatic08   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 04-May 12

Re: DirectX9: Background will not appear

Posted 10 May 2012 - 02:06 PM

View PostButchDean, on 04 May 2012 - 01:55 PM, said:

1. Have you placed a breakpoint in the code that draws?
2. Are any assert being fired?



View PostButchDean, on 08 May 2012 - 01:23 PM, said:

View PostSpazmatic08, on 08 May 2012 - 05:52 PM, said:

I'm not 100% sure as to what you mean by a breakpoint that draws.

I didn't say that. Do you know what a breakpoint is?


A breakpoint is a point in the code that pauses the execution of the program so it can be examined in stages. I usually use MessageBox() so I can tell what's supposed to be happening as well. Right now, there are none in the code.

*Adds a few and tests it*

After plonking a few in at seemingly relevant stages, here's what I get:

1: Clearing buffer in the Render() function, before; completely white background, window borders can be seen
2: Clearing buffer in the Render() function, after; completely white background, window borders can be seen
3: Copying texture in the CopyTexture() function, called from Render(), before; completely white background, window borders can be seen
4: Copying texture in the CopyTexture() function, called from Render(), after; completely white background, window borders can be seen
5: Presenting back buffer to display in the Render() function, before; completely white background, window borders can be seen

After closing the fifth breakpoint, the rectangle and a solid black background appear. I can't control it, but clicking 6 times brings me to the sixth breakpoint while giving the little MessageBox() appearance ding each time. I can control the movements of the rectangle when I haven't included the breakpoints (seems using MessageBox() is a little sloppy).

6: Presenting back buffer to display in the Render() function, after; completely white background, window borders can be seen

After the sixth breakpoint, the whole process repeats.

I apologize for the late responses, by the way.
Was This Post Helpful? 0
  • +
  • -

#6 anonymous26   User is offline

  • D.I.C Lover

Reputation: 2
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: DirectX9: Background will not appear

Posted 10 May 2012 - 02:16 PM

Don't use message boxes to debug your code, it is awkward and renders breakpoint redundant. Also your test methodology is frankly nonsense. All it is telling you is that your setup is wrong, but not the 'why'.

Also look into using OutputDebugString().
Was This Post Helpful? 0
  • +
  • -

#7 Spazmatic08   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 04-May 12

Re: DirectX9: Background will not appear

Posted 11 May 2012 - 03:05 PM

View PostButchDean, on 10 May 2012 - 02:16 PM, said:

Don't use message boxes to debug your code, it is awkward and renders breakpoint redundant. Also your test methodology is frankly nonsense. All it is telling you is that your setup is wrong, but not the 'why'.

Also look into using OutputDebugString().


Wish I'd known about the OutputDebugString() sooner. It sounds fantastically useful. Also, I just figured out how to use REAL breakpoints, not the pseudo-breakpoints I've been using thus far. The little red dots you create by clicking to the left of the line of code you want to insert a breakpoint on? First time I've used it. I didn't know that functionality even existed in VS 2005. With those two things and assert(), though, I should be able to figure out what's going on MUCH more efficiently. You've probably saved me huge amounts of time in the future.

Guess that also means that no, I had no flipping idea what a breakpoint was. Learn something new every day, I guess.

Thanks again for being this patient; it's clear to me now that thus far I've been frustratingly obtuse. I'll start debugging properly and post another reply if I figure out what was going on.
Was This Post Helpful? 0
  • +
  • -

#8 anonymous26   User is offline

  • D.I.C Lover

Reputation: 2
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: DirectX9: Background will not appear

Posted 11 May 2012 - 05:14 PM

No problem. Also look into conditional and non-conditional breakpoint. :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1