Sign in to follow this  
ext

After resizing window cursor positioning is wrong

Recommended Posts

I've written the following small directx app, but after resizing the window the cursor position and the cursor image are no longer the same. What do I have to do to treat the resizing correctly?
//-----------------------------------------------------------------------------
// File: CreateDevice.cpp
//
// Desc: This is the first tutorial for using Direct3D. In this tutorial, all
//       we are doing is creating a Direct3D device and using it to clear the
//       window.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <d3d9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 ) 
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <atltypes.h>


//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
bool			g_isDragging = false; // signals if a dragging is in process
RECT			g_dragRect;			// the dragging rectangle


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object, which is needed to create the D3DDevice.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // Set up the structure used to create the D3DDevice. Most parameters are
    // zeroed out. We set Windowed to TRUE, since we want to do D3D in a
    // window, and then set the SwapEffect to "discard", which is the most
    // efficient method of presenting the back buffer to the display.  And 
    // we request a back buffer format that matches the current desktop display 
    // format.
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    // Create the Direct3D device. Here we are using the default adapter (most
    // systems only have one, unless they have multiple graphics hardware cards
    // installed) and requesting the HAL (which is saying we want the hardware
    // device rather than a software one). Software vertex processing is 
    // specified since we know it will work on all cards. On cards that support 
    // hardware vertex processing, though, we would see a big performance gain 
    // by specifying hardware vertex processing.
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Device state would normally be set here
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	g_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pd3dDevice != NULL) 
        g_pd3dDevice->Release();

    if( g_pD3D != NULL)
        g_pD3D->Release();
}




//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
    if( NULL == g_pd3dDevice )
        return;

    // Clear the backbuffer to a black color
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
    
    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Rendering of scene objects can happen here
		if( g_isDragging )
		{
			struct Vertex
			{
				float x,y,z,rhw;
				D3DCOLOR color;
			};

#pragma warning(disable: 4244)

			Vertex vertices[5];
			vertices[0].x = g_dragRect.left; //top left
			vertices[0].y = g_dragRect.top;
			vertices[0].z = 1.0f;
			vertices[0].rhw = 1.0f;
			vertices[0].color = D3DCOLOR_XRGB(0,255,0);
			vertices[1].x = g_dragRect.right; //top right
			vertices[1].y = g_dragRect.top;
			vertices[1].z = 1.0f;
			vertices[1].rhw = 1.0f;
			vertices[1].color = D3DCOLOR_XRGB(0,255,0);
			vertices[2].x = g_dragRect.right;//bottom right
			vertices[2].y = g_dragRect.bottom;
			vertices[2].z = 1.0f;
			vertices[2].rhw = 1.0f;
			vertices[2].color = D3DCOLOR_XRGB(0,255,0);
			vertices[3].x = g_dragRect.left;//bottom left
			vertices[3].y = g_dragRect.bottom;
			vertices[3].z = 1.0f;
			vertices[3].rhw = 1.0f;
			vertices[3].color = D3DCOLOR_XRGB(0,255,0);
			vertices[4].x = g_dragRect.left;//top left again
			vertices[4].y = g_dragRect.top;
			vertices[4].z = 1.0f;
			vertices[4].rhw = 1.0f;
			vertices[4].color = D3DCOLOR_XRGB(0,255,0);


#pragma warning(default: 4244)

			g_pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, 4, (void*) vertices, sizeof( Vertex ) ); 
		}
		
    
        // End the scene
        g_pd3dDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
	case WM_LBUTTONDOWN:
		g_isDragging = true;
		g_dragRect.right = g_dragRect.left = LOWORD( lParam );
		g_dragRect.bottom = g_dragRect.top = HIWORD( lParam );
		return 0;
	case WM_LBUTTONUP:
		if( g_isDragging )
		{
			ReleaseCapture();
			InvalidateRect( hWnd, NULL, TRUE );
		}
                g_isDragging = false;
		return 0;
	case WM_MOUSEMOVE:
		if( g_isDragging )
		{
			SetCapture( hWnd );
			POINT cp; GetCursorPos( &cp );
			ScreenToClient( hWnd, &cp );
			RECT cr; GetClientRect( hWnd, &cr );
			if( cp.x < 0 )
				cp.x = 0;
			if( cp.y < 0 )
				cp.y = 0;
			if( cp.x > cr.right )
				cp.x = cr.right - 1;
			if( cp.y > cr.bottom )
				cp.y = cr.bottom - 1;
			g_dragRect.right = cp.x;
			g_dragRect.bottom = cp.y;
			Render();
			ValidateRect( hWnd, NULL );
		}
		return 0;
    }

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




//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    // Register the window class
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC | CS_HREDRAW | CS_VREDRAW, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, LoadCursor( hInst, IDC_ARROW ), NULL, NULL,
                      "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 01: CreateDevice", 
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              NULL, NULL, wc.hInstance, NULL );

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    { 
        // Show the window
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        // Enter the message loop
        MSG msg; 
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }

    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
}




Share this post


Link to post
Share on other sites
Quote:
Original post by ext
how can I change the backbuffer's size?

After the window has been resized, you need to update your presentation parameters with the correct dimensions. At this point, you need to call IDirect3DDevice9::Reset().

Note that before Reset() you need to release all of your resources that reside in the default pool. Many D3DX interfaces require you to call a OnDeviceLost() function. Also, after Reset() has succeeded, you need to re-create these resources (or call OnDeviceReset() for D3DX interfaces).

There are tutorials online that better illustrate this process. Check any of the common D3D sites.

Share this post


Link to post
Share on other sites
Ok thank you.

I just tried

case WM_SIZE:
Cleanup();
InitD3D( hWnd );
return 0;

and it works great.
But after reading your posting I'm remembering that there's a function to change those settings :)

Share this post


Link to post
Share on other sites
I'm not expert, but shouldn't you only define the vertex struct./primitive initialization only once. I don't think it's very good to create a vertex struct. and setup the primitive using the struct., each frame.

Just happened to notice it. But I'm no expert. =)

Share this post


Link to post
Share on other sites
Yes I could setp it up once and then change only the position, but for this simple example it's not that important :-)

Share this post


Link to post
Share on other sites

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