Sign in to follow this  
ELFanatic

Problems with windowed mode

Recommended Posts

I have an issue with clipping in windowed mode. I think pictures would explain best. Okay, so this is what the picture looks like in the middle of the screen. The picture itself is irrevelent. Now I move it to the right (or bottom) and it looks normal. It's what you'd expect, the right side is clipped off. but when I move it to the left, the left side of the window is clipped like it should be but the right side of the picture is clipped off again. I'd like to fix it so that the side that is off screen is the side that is clipped from the picture. I'm not sure if it's relevent but I'm using the ID3DXSprite helper class. I'm not sure where the problem is. Oh, something weird that I've noticed. As I drag it to the left it's okay but when I release the mouse button it redraws with this weird clipping. BUT the entire time I'm moving the window back onto screen from the left it acts weird like this. Some reason it's normal when dragging it out of screen to the left until I let go. Any help would be appreciated.

Share this post


Link to post
Share on other sites
It seems to me like you're accidentally setting the x-position of the background sprite to the leftmost clipping edge. In other words, I think when you're calculating your clipping bounds, somewhere you're trying to realign the sprite's position. If you're calculating a visible window rectangle, for example, and persistently moving the sprite around, seems something like that would be giving you the effect you're seeing.

On a side note, that wallpaper image looks kind of cool. Fushigi no umi no Nadia. Any good?

Share this post


Link to post
Share on other sites
Quote:
Original post by Omega147
It seems to me like you're accidentally setting the x-position of the background sprite to the leftmost clipping edge. In other words, I think when you're calculating your clipping bounds, somewhere you're trying to realign the sprite's position. If you're calculating a visible window rectangle, for example, and persistently moving the sprite around, seems something like that would be giving you the effect you're seeing.

On a side note, that wallpaper image looks kind of cool. Fushigi no umi no Nadia. Any good?


I thought about that but when you do ID3DXSprite->Draw and you send it a RECT with the coord to draw to, it's the coord of the window, not the screen correct? so I would figure that if I put top=0 and left=0 that it should always start drawing from the top-left corner of the window and it would ignore if the pixel is on screen or not. Tell me if I'm understanding this right or not. thanks.

Oh thanks. I found that pic a long time ago. I used to be in anime but only during the 90's. I'm not into modern anime. Something about it. Yeah, it's nadia. I'm not too sure what you're japanese says, I learned some japanese a couple years ago but I don't remember any of it now.

Share this post


Link to post
Share on other sites
I just don't get it, I mean, it acts so weird too. why doesn't it clip like that when I drag it off, why is it only like that when I set the window off to the left and when I drag it back. that's weird.

Share this post


Link to post
Share on other sites
Here's my render. There are a few bad programming practices here, such as creating the texture and destroying it within the render. It's just because I'm trying to cut out complication to figure out what's wrong.


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);


std::string filename = "C:\\Documents and Settings\\Joey Selah\\My Documents\\Visual Studio Projects\\Game\\images/nadia_3_800.bmp";
IDirect3DTexture9 * tex;
RECT box;
box.right = 1024;
box.left = 0;
box.top = 0;
box.bottom = 768;
D3DXCreateTextureFromFile(D3DDevice, filename.c_str(), &tex);
D3DSprite->Draw(tex, &box, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,0,0), 0xFFFFFFFF);

SAFE_RELEASE(tex);

D3DSprite->End();

D3DDevice->EndScene();
D3DDevice->Present( NULL, NULL, NULL, NULL );
}


Share this post


Link to post
Share on other sites
Why you load texture every time you call render? You need to do it just once when you initialize your application.
Also, you don't need this:
D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

try this:

IDirect3DTexture9 * tex = 0;
void DEngine::init()
{
std::string filename = "C:\\Documents and Settings\\Joey Selah\\My Documents\\Visual Studio Projects\\Game\\images/nadia_3_800.bmp";


D3DXCreateTextureFromFile(D3DDevice, filename.c_str(), &tex);
}
void DEngine::exit()
{
if(tex) tex->Release();
}
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();

RECT box;
box.right = 1024;
box.left = 0;
box.top = 0;
box.bottom = 768;
//RENDER STARTS!
D3DSprite->Begin( D3DXSPRITE_ALPHABLEND );
D3DSprite->Draw(tex, &box, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,0,0), 0xFFFFFFFF);
D3DSprite->End();

D3DDevice->EndScene();
D3DDevice->Present( NULL, NULL, NULL, NULL );
}


Share this post


Link to post
Share on other sites
Quote:
Original post by streamer
Why you load texture every time you call render? You need to do it just once when you initialize your application.
Also, you don't need this:
D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

try this:
*** Source Snippet Removed ***


I mentioned that why I load it and destroy it everytime. It's not the issue, I did that just to simplify my code to see where things went wrong, I've contained what I believe to be the issue and can't find where it's going wrong. I have the set render state for an alphablendable pic. I don't think that's causing the issue but I can check.

Share this post


Link to post
Share on other sites
I really have no clue meanwhile why this happens, but I can guess why while dragging the window it appears fine: While you drag a window by its title bar, your message loop is completely stuck thanks to DispatchMessage () which won't return till you release the left mouse mouse, and thus no rendering is done. So while you drag the window off the screen, the area that is not visible within the window will just be not drawn and no redrawing of the window will be done, and it will appear fine. At the exact moment that you release the left mouse button from dragging the window, the message loop will start working again and will immediately draw the scene, which will cause the other problem.

BTW: WM_PAINT messages will still be receieved, because they aren't passed through the message loop anyway (they are sent immediately), but since you drag the window off the screen, no painting is required so no message will be generated. However, when you start dragging the window back, WM_PAINT message will be constantly generated, so assuming your WindowProc calls the Engine::Render () on response to WM_PAINT messages, the weird problem WILL happen during the dragging of the window back.

[Edited by - UriKiller on May 29, 2007 7:06:30 PM]

Share this post


Link to post
Share on other sites
Hi ,guys,I encounter the same problem too.
See this:
http://www.gamedev.net/community/forums/topic.asp?topic_id=449821
I did not use D3DXSPRITE,just use D3DPT_TRIANGLELIST,but the same bug appears too.
How to post image here?
Thanks.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}



Share this post


Link to post
Share on other sites

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Title : DEngine.cpp
Author : Joseph P. Selah, Jr.
URL :

Description : DirectX 9 engine

Created : 09/01/2006
Modified :

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#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 directx
Returns: 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 lighting
Returns: 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;
}


Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Quote:
Original post by streamer
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?


it does indeed clip correctly. some reason though, when I move it off screen and then drag it back, the clipped portion is black until I release the mouse button. Still, thank you greatly. This will hopefully help me figure out what I'm doing wrong. Thank you again.

Share this post


Link to post
Share on other sites
That is because of window messages. When you click and drag on non-client area program doesn't have time to render. That is why is there "black screen". It is not rendered. But as soon as you release the mouse button render starts again.

Share this post


Link to post
Share on other sites
I figured out the problem. For the presentation parameters I put

D3Dpp.BackBufferWidth = WINDOW_WIDTH;
D3Dpp.BackBufferHeight = WINDOW_HEIGHT;

Rather than assigning them to 0. Took me a little while to figure it out. Does anyone know why this makes such a difference?

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