Sign in to follow this  

Small Experimental Program - BIG PROBLEMS [FIXED]

This topic is 4690 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I started out making an experimental program comparing relationships between size of drawn objects in windowed vs fullscreen mode. However, at this point, I would be delighted to at least get either to work, much less draw anything. The effect of the program is the screen flashes odd colors, but doesn't draw anything. I'll provide you the code with explanations, and you please tell me what I'm doing wrong. Off we go: Firstly, I include files and link the libraries, then set up a few globals to be used in the program:
#include <windows.h>
#include <d3d8.h>
#include <d3dx8tex.h>
#include <dxerr8.h>

#pragma comment( lib, "d3d8.lib" )
#pragma comment( lib, "d3dx8.lib" )
#pragma comment( lib, "dxerr8.lib" )

// Globals
HWND g_hWnd;
IDirect3D8* g_pDirect3D = NULL;
IDirect3DDevice8* g_pDevice = NULL;

// Windows prototypes
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
void RegisterWindowClass( HINSTANCE hInstance );
void CreateAppWindow( HINSTANCE hInstance );
WPARAM StartMessageLoop();

// Prototypes
BOOL InitApp();
BOOL InitWindowed( D3DPRESENT_PARAMETERS* D3DPresentParams );
void InitFullscreen( D3DPRESENT_PARAMETERS* D3DPresentParams );
BOOL InitDirect3D( BOOL bWindowed );
BOOL Setup();
void Render();
void CleanUp();

// Direct3D stuff
struct CUSTOMVERTEX
{
	float x, y, z, rhw;
	DWORD color;
};

CUSTOMVERTEX triangle[] =
{
	{ 320.0f, 120.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0 ) ,},
	{ 420.0f, 320.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 0, 255, 0 ) ,},
	{ 220.0f, 320.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255 ) ,},
};
DWORD MyFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

IDirect3DVertexBuffer8* pVertexBuffer = NULL;




Then, I do all the standard Windows type stuff (i.e., setting up the actual application window). Then, in the "tail" of WinMain(), I prompt the user to choose either windowed or fullscreen mode, initialize Direct3D appropriately, and finally, enter the message loop:
////////////////////////////////
// WinMain()
////////////////////////////////
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, INT )
{
	RegisterWindowClass( hInstance );
	CreateAppWindow( hInstance );
	ShowWindow( g_hWnd, SW_SHOWDEFAULT );
	UpdateWindow( g_hWnd );

	BOOL bWindowed = InitApp();
	if( InitDirect3D( bWindowed ) && Setup() )
	{
		WPARAM result = StartMessageLoop();
	}
	
	CleanUp();
	return 0;
}

////////////////////////////////
// WndProc()
////////////////////////////////
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_CREATE:
			return 0;

		case WM_DESTROY:
			PostQuitMessage( 0 );
			return 0;

		case WM_PAINT:
			ValidateRect( g_hWnd, NULL );
			return 0;

		case WM_KEYDOWN:
			switch( wParam )
			{
				case VK_ESCAPE:
					{
						PostQuitMessage( 1 );
						break;
					}
			}
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}

////////////////////////////////
// RegisterWindowClass()
////////////////////////////////
void RegisterWindowClass( HINSTANCE hInstance )
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof( WNDCLASSEX );
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = (HCURSOR)LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "D3D";
	wc.hIconSm = NULL;

	RegisterClassEx( &wc );
}

////////////////////////////////
// CreateAppWindow()
////////////////////////////////
void CreateAppWindow( HINSTANCE hInstance )
{
	g_hWnd = CreateWindowEx(
		NULL, "D3D", "D3D Windowed VS Full Test",
		WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, GetDesktopWindow(),
		NULL, hInstance, NULL );
	if( g_hWnd == NULL )
	{
		DWORD Error = GetLastError();
		char ErrorBuffer[ 1024 ];
		wsprintf( ErrorBuffer, "Error creating window. Error code, decimal %d, hexadecimal %X.", Error, Error );
		MessageBox( NULL, ErrorBuffer, "Error", MB_ICONHAND );
	}
}

////////////////////////////////
// StartMessageLoop()
////////////////////////////////
WPARAM StartMessageLoop()
{
	MSG msg;
	while( 1 )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if( msg.message == WM_QUIT )
				break;
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			Render();
		}
	}

	return msg.wParam;
}




As you can see, I Render() when there's nothing to do. Finally, I get to initialization. First, I ask the user what mode he wants, windowed or fullscreen:
////////////////////////////////
// InitApp()
////////////////////////////////
BOOL InitApp()
{
	// return TRUE for WINDOWED
	int FullOrWindowed = MessageBox( g_hWnd,
		"Would you like to run this application full-screen?",
		NULL, MB_YESNO | MB_ICONQUESTION );
	
	return ( FullOrWindowed == IDYES ) ? FALSE : TRUE;
}




The return value is retrieved back in WinMain(), and sent to InitDirect3D(). This calls the appropriate function to fill out the present parameters function, based on the bWindowed flag. Finish up by creating the device:
////////////////////////////////
// InitDirect3D()
////////////////////////////////
BOOL InitDirect3D( BOOL bWindowed )
{
	g_pDirect3D = Direct3DCreate8( D3D_SDK_VERSION );
	if( g_pDirect3D == NULL )
		return FALSE;	

	D3DPRESENT_PARAMETERS D3DPresentParams;
	ZeroMemory( &D3DPresentParams, sizeof( D3DPRESENT_PARAMETERS ) );
	if( bWindowed )
	{
		if( !InitWindowed( &D3DPresentParams ) )
			return FALSE;
	}
	else
		InitFullscreen( &D3DPresentParams );

	HRESULT hResult = g_pDirect3D->CreateDevice(
		D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&D3DPresentParams, &g_pDevice );
	if( FAILED( hResult ) )
		return FALSE;

	return TRUE;
}

////////////////////////////////
// InitWindowed()
////////////////////////////////
BOOL InitWindowed( D3DPRESENT_PARAMETERS* D3DPresentParams )
{
	D3DDISPLAYMODE display;
	HRESULT hResult = g_pDirect3D->GetAdapterDisplayMode(
		D3DADAPTER_DEFAULT, &display );
	if( hResult != D3D_OK )
		return FALSE;

	D3DPresentParams->Windowed = TRUE;
	D3DPresentParams->BackBufferFormat = display.Format;
	D3DPresentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
	D3DPresentParams->hDeviceWindow = g_hWnd;

	return TRUE;
}

////////////////////////////////
// InitFullscreen()
////////////////////////////////
void InitFullscreen( D3DPRESENT_PARAMETERS* D3DPresentParams )
{
	D3DPresentParams->Windowed = FALSE;
	D3DPresentParams->BackBufferCount = 1;
	D3DPresentParams->BackBufferWidth = 800;
	D3DPresentParams->BackBufferHeight = 600;
	D3DPresentParams->BackBufferFormat = D3DFMT_X8R8G8B8;
	D3DPresentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
	D3DPresentParams->hDeviceWindow = g_hWnd;
}




So far, so good. Here's where I think the trouble begins. Recall this segment from WinMain(): if( InitDirect3D( bWindowed ) && Setup() ) { WPARAM result = StartMessageLoop(); } After Direct3D has been initialized, the Setup() function is called. This sets up the proper vertices and sets the stream source, so it wouldn't have to be reset every frame (i.e. minimize the workload of Render() since it's called every frame):
////////////////////////////////
// Setup()
////////////////////////////////
BOOL Setup()
{
	HRESULT hResult = g_pDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
		0, MyFVF, D3DPOOL_DEFAULT, &pVertexBuffer );
	if( FAILED( hResult ) )
	{
		DXTRACE_ERR( "Error creating vertex buffer", hResult );
		return FALSE;
	}

	VOID* pVertices;
	hResult = pVertexBuffer->Lock( 0, 0, (BYTE**)&pVertices, 0 );
	if( FAILED( hResult ) )
	{
		DXTRACE_ERR( "Error locking vertex buffer", hResult );
		return FALSE;
	}
	memcpy( pVertices, triangle, sizeof( triangle ) );
	pVertexBuffer->Unlock();

	g_pDevice->SetStreamSource( 0, pVertexBuffer, sizeof( CUSTOMVERTEX ) );
	g_pDevice->SetVertexShader( MyFVF );

	return TRUE;
}




And finally, the Render():
////////////////////////////////
// Render()
////////////////////////////////
void Render()
{
	g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0,0,0 ), 1.0f, 0 );
	g_pDevice->BeginScene();
	g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
	g_pDevice->EndScene();
	g_pDevice->Present( NULL, NULL, NULL, NULL );
}




The effect is the screen flashes odd colors, but doesn't draw what I want. Can anyone spot the problem? EDIT: Here's the full source in one block, in case it's more handy that way to anyone:
// Comparing windowed and full-screen direct3d apps
// More precisely, if the objects appear larger or not.

#include <windows.h>
#include <d3d8.h>
#include <d3dx8tex.h>
#include <dxerr8.h>

#pragma comment( lib, "d3d8.lib" )
#pragma comment( lib, "d3dx8.lib" )
#pragma comment( lib, "dxerr8.lib" )

// Globals
HWND g_hWnd;
IDirect3D8* g_pDirect3D = NULL;
IDirect3DDevice8* g_pDevice = NULL;

// Windows prototypes
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
void RegisterWindowClass( HINSTANCE hInstance );
void CreateAppWindow( HINSTANCE hInstance );
WPARAM StartMessageLoop();

// Prototypes
BOOL InitApp();
BOOL InitWindowed( D3DPRESENT_PARAMETERS* D3DPresentParams );
void InitFullscreen( D3DPRESENT_PARAMETERS* D3DPresentParams );
BOOL InitDirect3D( BOOL bWindowed );
BOOL Setup();
void Render();
void CleanUp();

// Direct3D stuff
struct CUSTOMVERTEX
{
	float x, y, z, rhw;
	DWORD color;
};

CUSTOMVERTEX triangle[] =
{
	{ 320.0f, 120.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0 ) ,},
	{ 420.0f, 320.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 0, 255, 0 ) ,},
	{ 220.0f, 320.0f, 0.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255 ) ,},
};
DWORD MyFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

IDirect3DVertexBuffer8* pVertexBuffer = NULL;

////////////////////////////////
// WinMain()
////////////////////////////////
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, INT )
{
	RegisterWindowClass( hInstance );
	CreateAppWindow( hInstance );
	ShowWindow( g_hWnd, SW_SHOWDEFAULT );
	UpdateWindow( g_hWnd );

	BOOL bWindowed = InitApp();
	if( InitDirect3D( bWindowed ) && Setup() )
	{
		WPARAM result = StartMessageLoop();
	}
	
	CleanUp();
	return 0;
}

////////////////////////////////
// WndProc()
////////////////////////////////
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
		case WM_CREATE:
			return 0;

		case WM_DESTROY:
			PostQuitMessage( 0 );
			return 0;

		case WM_PAINT:
			ValidateRect( g_hWnd, NULL );
			return 0;

		case WM_KEYDOWN:
			switch( wParam )
			{
				case VK_ESCAPE:
					{
						PostQuitMessage( 1 );
						break;
					}
			}
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}

////////////////////////////////
// RegisterWindowClass()
////////////////////////////////
void RegisterWindowClass( HINSTANCE hInstance )
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof( WNDCLASSEX );
	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = (HCURSOR)LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "D3D";
	wc.hIconSm = NULL;

	RegisterClassEx( &wc );
}

////////////////////////////////
// CreateAppWindow()
////////////////////////////////
void CreateAppWindow( HINSTANCE hInstance )
{
	g_hWnd = CreateWindowEx(
		NULL, "D3D", "D3D Windowed VS Full Test",
		WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, GetDesktopWindow(),
		NULL, hInstance, NULL );
	if( g_hWnd == NULL )
	{
		DWORD Error = GetLastError();
		char ErrorBuffer[ 1024 ];
		wsprintf( ErrorBuffer, "Error creating window. Error code, decimal %d, hexadecimal %X.", Error, Error );
		MessageBox( NULL, ErrorBuffer, "Error", MB_ICONHAND );
	}
}

////////////////////////////////
// StartMessageLoop()
////////////////////////////////
WPARAM StartMessageLoop()
{
	MSG msg;
	while( 1 )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if( msg.message == WM_QUIT )
				break;
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			Render();
		}
	}

	return msg.wParam;
}

////////////////////////////////
// InitApp()
////////////////////////////////
BOOL InitApp()
{
	// return TRUE for WINDOWED
	int FullOrWindowed = MessageBox( g_hWnd,
		"Would you like to run this application full-screen?",
		NULL, MB_YESNO | MB_ICONQUESTION );
	
	return ( FullOrWindowed == IDYES ) ? FALSE : TRUE;
}

////////////////////////////////
// InitDirect3D()
////////////////////////////////
BOOL InitDirect3D( BOOL bWindowed )
{
	g_pDirect3D = Direct3DCreate8( D3D_SDK_VERSION );
	if( g_pDirect3D == NULL )
		return FALSE;	

	D3DPRESENT_PARAMETERS D3DPresentParams;
	ZeroMemory( &D3DPresentParams, sizeof( D3DPRESENT_PARAMETERS ) );
	if( bWindowed )
	{
		if( !InitWindowed( &D3DPresentParams ) )
			return FALSE;
	}
	else
		InitFullscreen( &D3DPresentParams );

	HRESULT hResult = g_pDirect3D->CreateDevice(
		D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&D3DPresentParams, &g_pDevice );
	if( FAILED( hResult ) )
		return FALSE;

	return TRUE;
}

////////////////////////////////
// CleanUp()
////////////////////////////////
void CleanUp( void )
{
	if( pVertexBuffer )
		pVertexBuffer->Release();

	if( g_pDevice )
		g_pDevice->Release();
	
	if( g_pDirect3D )
		g_pDirect3D->Release();
}

////////////////////////////////
// Setup()
////////////////////////////////
BOOL Setup()
{
	HRESULT hResult = g_pDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
		0, MyFVF, D3DPOOL_DEFAULT, &pVertexBuffer );
	if( FAILED( hResult ) )
	{
		DXTRACE_ERR( "Error creating vertex buffer", hResult );
		return FALSE;
	}

	VOID* pVertices;
	hResult = pVertexBuffer->Lock( 0, 0, (BYTE**)&pVertices, 0 );
	if( FAILED( hResult ) )
	{
		DXTRACE_ERR( "Error locking vertex buffer", hResult );
		return FALSE;
	}
	memcpy( pVertices, triangle, sizeof( triangle ) );
	pVertexBuffer->Unlock();

	g_pDevice->SetStreamSource( 0, pVertexBuffer, sizeof( CUSTOMVERTEX ) );
	g_pDevice->SetVertexShader( MyFVF );

	return TRUE;
}

////////////////////////////////
// Render()
////////////////////////////////
void Render()
{
	g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0,0,0 ), 1.0f, 0 );
	g_pDevice->BeginScene();
	g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
	g_pDevice->EndScene();
	g_pDevice->Present( NULL, NULL, NULL, NULL );
}

////////////////////////////////
// InitWindowed()
////////////////////////////////
BOOL InitWindowed( D3DPRESENT_PARAMETERS* D3DPresentParams )
{
	D3DDISPLAYMODE display;
	HRESULT hResult = g_pDirect3D->GetAdapterDisplayMode(
		D3DADAPTER_DEFAULT, &display );
	if( hResult != D3D_OK )
		return FALSE;

	D3DPresentParams->Windowed = TRUE;
	D3DPresentParams->BackBufferFormat = display.Format;
	D3DPresentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
	D3DPresentParams->hDeviceWindow = g_hWnd;

	return TRUE;
}

////////////////////////////////
// InitFullscreen()
////////////////////////////////
void InitFullscreen( D3DPRESENT_PARAMETERS* D3DPresentParams )
{
	D3DPresentParams->Windowed = FALSE;
	D3DPresentParams->BackBufferCount = 1;
	D3DPresentParams->BackBufferWidth = 800;
	D3DPresentParams->BackBufferHeight = 600;
	D3DPresentParams->BackBufferFormat = D3DFMT_X8R8G8B8;
	D3DPresentParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
	D3DPresentParams->hDeviceWindow = g_hWnd;
}


[Edited by - v0dKA on February 12, 2005 10:03:08 AM]

Share this post


Link to post
Share on other sites
I am no DX programmer, but in terms of logic, I would say go ahead and try calling
"Setup()" in the render function and see if that fixes the problem. I do not know how the interal DX workings go, but it seems like that could be a potential problem if it was not called by some chance previously.

- Drew

Share this post


Link to post
Share on other sites
would your problem have to do with this?

D3DPresentParams->BackBufferWidth = 800;
D3DPresentParams->BackBufferHeight = 600;

unless your desktop resolution is set to 800 x 600, wouldn't you be drawing on the 800 x 600 back buffer and then trying to render it to a different resolution in full screen mode which might screw up the drawing? I'm probably wrong, but just thought I would give my two cents.

[Edited by - cyberninjaru on February 12, 2005 6:48:46 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
If the odd colors is pink and green the flags in clear are wrong. Turn on DirectX debugging (in the control panel) and look in the output window.


I turned them on higher output, and found the problem. Looks like DWORD MyFVF did not actually match the flexible vertex format (D3D_XYZ should have been D3D_XYZRHW).

Share this post


Link to post
Share on other sites

This topic is 4690 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this