Multiple Sprites Overlapping Issue

Started by
8 comments, last by LancerSolurus 15 years, 3 months ago
Ok I've made a game with DirectX but did it the hard way without any classes and now I'm trying to redo all the code to make it more effcien and understandable. However I've already came across an issue with sprites. I'm using a sprite as my UI which makes sense to me at least. But I also need to use a sprite as a background image. If I try to lead both, the background image sprite will just overlap my UI sprite. Currently my work around is putting the background image on a ".x" file and import that file and render it in the distance. But I would like to do it correctly if at all possible. I hope its just a simple flag that I need to set. I will be happy to send the files to anyone who can help. Thanks! Heres my "HUD" class code. I have another class "DirectX" that calls the "HUD" class. /////////////////////////////////////////////////// HUD.h File /////////////////////////////////////////////////// #pragma once #include <d3d9.h> #include <d3dx9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") class CHud { //Sprite Variables ID3DXSprite *m_pD3DSprite; IDirect3DTexture9 *m_pD3DTexturePic; D3DXIMAGE_INFO imageInfo; //Transform Variables D3DXMATRIX trans, rot, scale, worldMat; int directionRand; //Sprite 1 int transX, transY, a, r, g, b; float scaleX, scaleY, rotZ; public: CHud(void); ~CHud(void); bool Init(IDirect3DDevice9* m_pD3DDevice); void Render(IDirect3DDevice9* m_pD3DDevice, int nWidth, int nHeight); void Shutdown(void); }; /////////////////////////////////////////////////////////////////// Here's the HUD.CPP File /////////////////////////////////////////////////////////////////// #include "Hud.h" CHud::CHud(void) { } CHud::~CHud(void) { } bool CHud::Init(IDirect3DDevice9* m_pD3DDevice) { //Create the Sprite Object D3DXCreateSprite(m_pD3DDevice, &m_pD3DSprite); //Menu's PNG/HUD.png D3DXCreateTextureFromFileEx(m_pD3DDevice, "Menu's PNG/HUD.png", 0, 0, 0 , 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, D3DCOLOR_XRGB(255, 0, 255), &imageInfo, 0, &m_pD3DTexturePic); return true; } void CHud::Render(IDirect3DDevice9* m_pD3DDevice, int nWidth, int nHeight) { if(!m_pD3DDevice) return; //Draw everything here if( SUCCEEDED(m_pD3DDevice->BeginScene())) { if(SUCCEEDED(m_pD3DSprite->Begin(D3DXSPRITE_SORT_TEXTURE))) { D3DXMatrixTranslation(&trans, (nWidth/2.0f), (nHeight/2.0f) - 95, 0.0f); D3DXMatrixScaling(&scale, 1.0f, 0.75f, 0.0f); D3DXMatrixRotationZ(&rot, 0); D3DXMatrixMultiply(&rot, &rot, &scale); D3DXMatrixMultiply(&worldMat, &rot, &trans); m_pD3DSprite->SetTransform(&worldMat); m_pD3DSprite->Draw( m_pD3DTexturePic, //image to draw NULL, //source rectangle from image &D3DXVECTOR3((float) imageInfo.Width/2, (float) imageInfo.Height/2, 0.0f), //center 0, //pos D3DCOLOR_ARGB(255, 255, 255, 255)); //color modulation m_pD3DSprite->End(); } //reset sprite com object D3DXMatrixIdentity(&worldMat); m_pD3DSprite->SetTransform(&worldMat); m_pD3DDevice->EndScene(); } } void CHud::Shutdown() { //Shutdown m_pD3DTexture if(m_pD3DTexturePic) { m_pD3DTexturePic->Release(); m_pD3DTexturePic = NULL; } if(m_pD3DSprite) { m_pD3DSprite->Release(); m_pD3DSprite = NULL; } } ////////////////////////////////////////////////////////////// DirectX.h File ////////////////////////////////////////////////////////////// #pragma once #include <d3d9.h> #include <d3dx9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") class CDirectX { //store win32 variable HWND m_hWnd; bool m_bWindowed; int m_nWidth, m_nHeight; public: //D3D Base variables IDirect3D9* m_pD3DObject; IDirect3DDevice9* m_pD3DDevice; D3DPRESENT_PARAMETERS m_D3Dpp; CDirectX(void); ~CDirectX(void); bool Init(HWND hWnd, bool bWindowed, int nWidth, int nHeight); void Update(void); void Render(void); void Shutdown(void); }; ////////////////////////////////////////////////////////// DirectX.cpp File: Calls the HUD file to render ///////////////////////////////////////////////////////// #include "DirectX.h" #include "Hud.h" #include "Levels.h" CHud g_Hud; CLevels g_Levels; CDirectX::CDirectX(void) { } CDirectX::~CDirectX(void) { } bool CDirectX::Init(HWND hWnd, bool bWindowed, int nWidth, int nHeight) { //store these window variable in our DirectX class m_hWnd = hWnd; m_bWindowed = bWindowed; m_nWidth = nWidth; m_nHeight = nHeight; //create our D3DObject m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION); //ZeroMem our Presentation Prarmeters ZeroMemory(&m_D3Dpp, sizeof(m_D3Dpp)); //fill out the presentation parameters m_D3Dpp.BackBufferWidth = m_bWindowed ? 0 : m_nWidth; m_D3Dpp.BackBufferHeight = m_bWindowed ? 0 : m_nHeight; m_D3Dpp.BackBufferCount = 1; m_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; m_D3Dpp.hDeviceWindow = m_hWnd; m_D3Dpp.Windowed = m_bWindowed; m_D3Dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; //create our D3D Device m_pD3DObject->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_D3Dpp, &m_pD3DDevice); g_Hud.Init(m_pD3DDevice); g_Levels.Init(m_pD3DDevice, 1); return true; } void CDirectX::Update(void) { } void CDirectX::Render(void) { if(!m_pD3DDevice) return; //clear the back buffer m_pD3DDevice->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 200, 255), 1.0f, 0); //draw everthing here... g_Hud.Render(m_pD3DDevice, m_nWidth, m_nHeight); g_Levels.Render(m_pD3DDevice, m_nWidth, m_nHeight, 1); //Present the Back Buffer m_pD3DDevice->Present(0, 0, 0, 0); } void CDirectX::Shutdown(void) { g_Hud.Shutdown(); if(m_pD3DDevice) { m_pD3DDevice->Release(); m_pD3DDevice = NULL; } if(m_pD3DObject) { m_pD3DObject->Release(); m_pD3DObject = NULL; } } ////////////////////////////////////////// End //////////////////////////////////////////
Advertisement
Sorry dude I wasn't bothered to read everything. I just scanned over and I'm guessing that your problem might be with a certain depth value, because that's the only reason I see possible if you believe you done everything right. Do a little check on your (Sprite)->Draw call. Hmm, I checked it again and don't see any. I'm assuming you're not showing all the code... please upload/post another samlple that shows you sprite draw calles. I'm expecting to see a background sprite that has a depth value higher than or the same as the other sprite(s).

Fissure.
Oops Sorry about that. Yea that was my first thought also on the depth. If I leave both of them with the same translation (x,y,z) values the level sprites overlaps the HUD. So I change the "z" value to "-1" and then the level sprites disappears. So I thought maybe I'm crazy and tried "1" for "z" but still no luck.

Here's the Levels.cpp file:

#include "Levels.h"

CLevels::CLevels(void)
{
}

CLevels::~CLevels(void)
{
}

bool CLevels::Init(IDirect3DDevice9* m_pD3DDevice, int level)
{
//Create the Sprite Object
D3DXCreateSprite(
m_pD3DDevice, // D3D Device
&m_pD3DSprite); // returned COM pointer

if(1 == level)
{
//Create the texture
D3DXCreateTextureFromFileEx(
m_pD3DDevice, // device
"Levels/BlackHole.png", // filename
0, 0, // width and height
0, 0, // mitmaps
D3DFMT_UNKNOWN, // format
D3DPOOL_MANAGED, // memory pool
D3DX_DEFAULT, D3DX_DEFAULT, // filters
D3DCOLOR_XRGB(255, 0, 255), // key color
&imageInfo, // returned image info
NULL, // pallate info
&m_pD3DTexturePic);
}

return true;
}
void CLevels::Render(IDirect3DDevice9* m_pD3DDevice, int nWidth, int nHeight, int level)
{
if(!m_pD3DDevice)
return;

//Draw everything here
if( SUCCEEDED(m_pD3DDevice->BeginScene()))
{
if(SUCCEEDED(m_pD3DSprite->Begin(D3DXSPRITE_SORT_TEXTURE)))
{

D3DXMatrixTranslation(&trans, (nWidth/2.0f), (nHeight/2.0f) -95, 0.0f);
D3DXMatrixScaling(&scale, 1.0f, 0.75f, 0.0f);
D3DXMatrixRotationZ(&rot, 0);

D3DXMatrixMultiply(&rot, &rot, &scale);
D3DXMatrixMultiply(&worldMat, &rot, &trans);
m_pD3DSprite->SetTransform(&worldMat);

m_pD3DSprite->Draw(
m_pD3DTexturePic, //image to draw
NULL, //source rectangle from image
&D3DXVECTOR3((float) imageInfo.Width/2, (float) imageInfo.Height/2, 0.0f), //center
0, //pos
D3DCOLOR_ARGB(255, 255, 255, 255)); //color modulation
}

//reset sprite com object
D3DXMatrixIdentity(&worldMat);
m_pD3DSprite->SetTransform(&worldMat);

m_pD3DSprite->End();


}

m_pD3DDevice->EndScene();

}
void CLevels::Shutdown()
{
//Shutdown m_pD3DTexture
if(m_pD3DTexturePic)
{
m_pD3DTexturePic->Release();
m_pD3DTexturePic = NULL;
}
if(m_pD3DSprite)
{
m_pD3DSprite->Release();
m_pD3DSprite = NULL;
}
}
Well, I'm sorry but again I rushed through it :), mainly because I'm going to sleep... its already 7AM here. Anyways the reason -1 made your level sprite disappear is likely due to the fact that the depth value should only be between 0.0 to 1.0(eg 0.53 or 0.92). As for the code posted above... well thank you but it only shows the (Sprite)->Draw call for one sprite :), please show the one for your background to.

Other optional notes/questions:
1) Is there any need to make the m_pD3DObject variable NULL? I'm asking because I always thought that the DirectX interfaces automatically did something like that after having their Release functions called.
2) Do you like tea or coffee?

Oh the memories, LOL, I used to be so infamous here... haha.

Fissure.
Ha! Def. a Coffee for me, maybe with a shot of Crown Royal at this point.

I call both of these classes in the render function of DirectX.

g_Hud.Render(m_pD3DDevice, m_nWidth, m_nHeight);
g_Levels.Render(m_pD3DDevice, m_nWidth, m_nHeight, 1);

Sorry that I'm so confusing, but maybe I can explain my issue a little better.

I render two sprites, one as a background, one as the HUD. When rendering they just render on top of each other. Is there a way to translate the sprites? I can move them in the 'x' and 'y' directions. But when I try to move the level sprite further into the screen (more depth 'z' in my case), it seems to disapear or do nothing. Perhaps I can't do that with a sprite? I'll need room to render 3D objects between the camera and the background level sprite...

Thanks!


I noticed one thing you did - D3DXSPRITE_SORT_TEXTURE - that is for non-overlapping textures. I would suggest sorting back to front or front to back as well to help (which one depends on if you use transparency or not). Also, if all of them are the same depth, you will need to render your background sprite first then render any other sprites that go on top of it after that point.

To do 3D sprites add in D3DXSPRITE_OBJECTSPACE to your sprite->Begin() part.

[Edited by - LancerSolurus on January 11, 2009 10:42:44 PM]

******************************************************************************************
Youtube Channel

Hey, thanks you two for givin me some clues. I think I have it worked out. Yea I was rendering them in the wrong order, and had to set a couple flags. Now off to try and find a Frame Rate class... Not lookin forward to this :( I guess I'll just have to remember to render the background level sprite first! I'm kind of curios though. No matter what I seem to do the application uses atleast 30 mb of RAM. I've got two sprites and one 3D object rendered. If I add up the file sizes of all the assets, its now wheres close to 30mb. Anyone ?
@ VIM06 - I would suspect the DX core is the culprit here, simply create your device and screen for DX and check the mem usage, then release both

@ GF - a simple way to test it would be

if(m_pD3DObject!=NULL) TRACE("D3D Object not released\r\n");

after you used DX to release it

******************************************************************************************
Youtube Channel

Hey!

Ok, if I go back to just my template build. Which just renders a window with a blank screen, its about 5 megs of RAM. Is that good or is that still bad? It seems a little high still...

Sorry but I'm a little confused on how to use your:

if(m_pD3DObject!=NULL) TRACE("D3D Object not released\r\n");

Thanks!
The second part was directed at GameFissure (GF) as for testing as to whether or not the device is deleted.

As to the amount of ram used, each object will eat up a certain amount, to keep this to a minimum a tree based mesh handler would be the optimal solution. Use a hash based nickname for the meshes to keep them separate.

******************************************************************************************
Youtube Channel

This topic is closed to new replies.

Advertisement