Problems with windowed mode

Started by
23 comments, last by ELFanatic 16 years, 10 months ago
Allways when dealing with sprites, even if you would like to draw just one picture, you need 2 sprites. One with the picture which you acctualy want to display and one with the target surface where to draw to.

Try following: everytime WM_SIZE or WM_MOVE is called, destroy and recreate the second sprite (SURFACE). And then draw normaly. I think, it should work like this.

I believe it is because when your second surface sprite was created, it didn't know where your window might be positioned or clipped. It happens only on create time. So when you re-create it after WM_MOVE or WM_SIZE it should work. You do not need to recreate the picture sprite.
Advertisement
thanks for all the replies. UriKiller thank you greatly for your knowledge, I couldn't understand for the life of me why everything happened the way it did, seemed inconsistent but after your explanation, it all makes sense why it screws up the way it does.

Still, I'm not sure why it screws up to begin with. I was thinking, maybe someone could make a very simple DirectX9 program with D3DXSPRITE. bear essentials. And I could look over it and see where my code deviates.

Just an idea.
Quote:Original post by Samurai Jack
Allways when dealing with sprites, even if you would like to draw just one picture, you need 2 sprites. One with the picture which you acctualy want to display and one with the target surface where to draw to.

Try following: everytime WM_SIZE or WM_MOVE is called, destroy and recreate the second sprite (SURFACE). And then draw normaly. I think, it should work like this.

I believe it is because when your second surface sprite was created, it didn't know where your window might be positioned or clipped. It happens only on create time. So when you re-create it after WM_MOVE or WM_SIZE it should work. You do not need to recreate the picture sprite.


oh man, I think I see what you're saying. Because I am creating and destroying inside the render it assumes that pos(0,0,0) is the same as the screen's pos(0,0,0). I swear it screwed up like that before I put all my create and destroy texture code inside the render ...unless! I accidently created and destoryed always in the render without knowing it. I wonder. I wanna check that out now.
Quote:Original post by ELFanatic
Quote:Original post by Samurai Jack
Allways when dealing with sprites, even if you would like to draw just one picture, you need 2 sprites. One with the picture which you acctualy want to display and one with the target surface where to draw to.

Try following: everytime WM_SIZE or WM_MOVE is called, destroy and recreate the second sprite (SURFACE). And then draw normaly. I think, it should work like this.

I believe it is because when your second surface sprite was created, it didn't know where your window might be positioned or clipped. It happens only on create time. So when you re-create it after WM_MOVE or WM_SIZE it should work. You do not need to recreate the picture sprite.


oh man, I think I see what you're saying. Because I am creating and destroying inside the render it assumes that pos(0,0,0) is the same as the screen's pos(0,0,0). I swear it screwed up like that before I put all my create and destroy texture code inside the render ...unless! I accidently created and destoryed always in the render without knowing it. I wonder. I wanna check that out now.



No, I'm creating and destroying the texture outside of render, on initialization and I still have this weird clipping problem. I'd like to look at some code that doesn't have this issue just to kinda see where I might be going wrong.
And you are constantly calling render function, or just when wm_paint occurs?
Quote:Original post by streamer
And you are constantly calling render function, or just when wm_paint occurs?


constantly.

this is my render loop.

    // Main loop    MSG msg;    while ( bRunning )     {        // Only render when there are no messages        if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )         {            if ( msg.message == WM_QUIT )            {                break;            }            TranslateMessage( &msg );            DispatchMessage ( &msg );        }         else         {			DX.updateScene();        }     }	return 0;}


What does it do if you create a REF device instead of a HAL device?
why don't you paste a whole code? It will be easier to follow.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Title : DEngine.cppAuthor : Joseph P. Selah, Jr.URL : Description : DirectX 9 engineCreated :  09/01/2006Modified : * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "stdafx.h"#include "DEngine.h"#include "WinMain.h"#include "SpriteNode.h"#include <string>#include "Cutscenes.h"#include "Textures.h"#include "GUI.h"#include <d3d9.h>#include <atldebugapi.h>#include <atlcoll.h> #include <atlsync.h> DEngine::DEngine(){	hWnd = NULL;	D3D9 = NULL; 	D3DDevice = NULL; 	D3DSprite = NULL;	oCutscene = new Cutscenes;	oCutscene->initCutscenes(spriteList);	oCutscene->initiateCutscene();	//oGui = new Gui(*this);	filename = "C:\\Documents and Settings\\Joey Selah\\My Documents\\Visual Studio Projects\\Game\\images/nadia_3_800.bmp";	box.right = 1024;	box.left = 0;	box.top = 0;	box.bottom = 768;}DEngine::~DEngine(){    // Give back resources	SAFE_RELEASE( D3DSprite );    SAFE_RELEASE( D3DDevice );    SAFE_RELEASE( D3D9 );	delete oCutscene;	oCutscene = NULL;	SAFE_RELEASE(tex);	}bool DEngine::DInitDirectX(std::string errReport){	 // Initialize DirectX    D3D9 = Direct3DCreate9( D3D_SDK_VERSION );    if ( !D3D9 )	{		errReport = "DInitDirectX() - Failed";        return false;	}else if (!DBuildPresentationParameters()){		errReport = "DBuildPresentationParameters() - Failed";		return false;	}else if (!DCreateDevice()){		errReport = "DCreateDevice() - Failed";		return false;	}else if(!DCreateSpriteInterface(errReport)){		return false;	}else{		D3DXCreateTextureFromFile(D3DDevice, filename.c_str(), &tex);		return true;  //success it is created!	}}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: Builds the D3DPRESENT_PARAMETERS structure using the current window size. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool DEngine::DBuildPresentationParameters() { 	bool success = true;	// Clean out the presentation parameters	ZeroMemory( &D3Dpp, sizeof(D3Dpp) ); 	// Get display mode 	D3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &displayMode); 	if ( SUCCEEDED( D3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) ) 		D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 	else if ( SUCCEEDED( D3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) ) 		D3Dpp.AutoDepthStencilFormat = D3DFMT_D24X8;  	else if ( SUCCEEDED( D3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) 		D3Dpp.AutoDepthStencilFormat = D3DFMT_D16; 	else 	{		success = false; 	}	//obtain handler to window.	hWnd = getHWND();	//Fill the presentation parameters	D3Dpp.BackBufferWidth            = WINDOW_WIDTH;	D3Dpp.BackBufferHeight           = WINDOW_HEIGHT; 	D3Dpp.BackBufferFormat           = D3DFMT_X8R8G8B8;	D3Dpp.BackBufferCount            = 1; 	D3Dpp.MultiSampleType            = D3DMULTISAMPLE_NONE; 	D3Dpp.MultiSampleQuality         = 0; 	D3Dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 	D3Dpp.hDeviceWindow              = hWnd;	D3Dpp.Windowed                   = true; 	D3Dpp.EnableAutoDepthStencil     = true; 	D3Dpp.FullScreen_RefreshRateInHz = 0; //displayMode.RefreshRate; <- is for fullscreen, 0 for windowed	D3Dpp.PresentationInterval       = D3DPRESENT_INTERVAL_ONE; 		return success;} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: Creates the device for directxReturns: true if successful.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool DEngine::DCreateDevice(){	// Check for hardware T&L 	D3DCAPS9 D3DCaps; 	D3D9->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps ); 	DWORD vertexProcessing = 0; 	if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) 	{ 		vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING; 		//**********************************************		//Do this when the application is finished for best		//performance.  Not meant for debugging		//*******************************************		//// Check for pure device 		//if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE ) 		//{ 		//	vertexProcessing |= D3DCREATE_PUREDEVICE; 		//} 	} 	else 	{ 		vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 	} 	 // Create the device    if ( FAILED( D3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vertexProcessing, &D3Dpp, &D3DDevice ) ) )    {	        return false;	}else{		Textures::setDevice(D3DDevice);		oGui = new Gui(this);		return true;	}}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: Creates a sprite interface.  it stes the device to FVF and turns of lightingReturns: true if successful.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool DEngine::DCreateSpriteInterface(std::string errReport){	bool success = false;	if ( !FAILED( D3DDevice->SetFVF(D3DFVF_XYZRHW) ) )		{success = true;}	else{errReport = "SetFVF() - Failed";}	if ( !FAILED( D3DDevice->SetRenderState(D3DRS_LIGHTING, false)))		{success = true;}	else{errReport = "SetRenderState() - Failed";}	if ( !FAILED ( D3DXCreateSprite(D3DDevice, &D3DSprite)))		{success = true;}	else{errReport = "D3DXCreateSprite() - Failed";}	return success;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: This is the render loop.  All drawing to the screen happens here.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */void DEngine::updateScene(){	render();}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: This is the render loop.  All drawing to the screen happens here.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */void DEngine::render(){		if (SpriteNode::zChanged)	{		spriteList.sort(SpriteNode::sortSpriteByZ);		SpriteNode::zChanged = false;	}	D3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );     D3DDevice->BeginScene();	    //RENDER STARTS!	D3DSprite->Begin( D3DXSPRITE_DONOTSAVESTATE );	D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);    D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);    D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);	//try{	//	std::list<SpriteNode>::iterator iter = spriteList.begin();	//	while (iter != spriteList.end())	//	{			//D3DSprite->Draw(iter->getTex(), &iter->getSrcRect(), &iter->getCenter(), &iter->getScreenPoint(), iter->getColor());	//		iter++;	//	}	//}	//catch(...)	//{	//}	D3DSprite->Draw(tex, &box, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,0,0), 0xFFFFFFFF);	D3DSprite->End();        D3DDevice->EndScene();    D3DDevice->Present( NULL, NULL, NULL, NULL );}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Purpose: This is incase windows wishes to paint to the window.We need to tell it that the device is a DirectX device and should call render.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */bool DEngine::DeviceNotLost(){	if (D3DDevice)		return true;	else		return false;}
Here is one program I wrote that do same thing you need. It works perfectly.
Anyway, maybe it is not so important, but you have one or two monitors?

This topic is closed to new replies.

Advertisement