Sign in to follow this  
VitaliBR

ID3DXSprite and SetTransform

Recommended Posts

I'm trying to apply a sprite as background (Menu).

I have the window size:
#define WIDTH 800
#define HEIGHT 600

and I'm trying this way:

	D3DXMATRIX m;
D3DXMatrixScaling(&m, WIDTH / (float)1024, HEIGHT / (float)768, 1);
m_Sprite->SetTransform(&m);
m_Sprite->Draw(m_Texture, NULL, NULL, &position, D3DCOLOR_XRGB(255,255,255));




My sprite is the size 1024x768 and window 800x600
but the sprite is not getting the exact size of the screen :(

Look:

The sprite:



The screen with sprite:



I searched on the forum, but have not found the solution
Thanks

[Edited by - VitaliBR on September 28, 2010 8:15:58 PM]

Share this post


Link to post
Share on other sites
In your image the background is correctly scaled on the X-axis, but doesn't seem scaled at all on the Y-axis. Double-check that your parameters are correct.

Also, you should use AdjustWindowRectEx to calculate the window-size when creating your window. If you create the window with size 800x600, then the actual draw-area is smaller, since the window's title-bar and borders are included in the size. However I don't think this is your current problem, as the sprite doesn't seem scaled at all on the Y-axis.

Share this post


Link to post
Share on other sites
Hi,

I'm workin' on D3DX Sprite too :D

You must use D3DXMatrixTransformation2D() instead of D3DXMatrixScaling(). That's the trick ;)

First;
* Create your texture from file via D3DXCreateTextureFromFile().
* Get it's level-0 description: IDirect3DTexture9::GetLevelDesc(). And get width and height data from it.
* Get your window size. With this and the data came from the previous step, get scaling factor via
D3DXVECTOR2 scalingFactor ((float)windowW / (float)textureW, (float)windowH / (float)textureH);


Second;
* Call D3DXMatrixTransformation2D:
D3DXMATRIX spriteMatrix;
D3DXMatrixTransformation2D (&spriteMatrix, NULL, 0, &scalingFactor, NULL, 0, NULL);

* Call ID3DXSprite::SetTransform:
yourD3DXSprite->SetTransform (&spriteMatrix);


Third, and the last;
* Draw it:
yourD3DXSprite->Draw (yourSpriteTexture, NULL, NULL, NULL, D3DXCOLOR (1, 1, 1, 1));


Excellent bg image, btw ;)

hth.
-R

Share this post


Link to post
Share on other sites
Look this friend :D



Thanks for help!
What filters can I use to make better the quality of the sprite?

Quote:
Original post by programci_84

Excellent bg image, btw ;)



Thanks, I'm not a designer :( I tried to do my best!


My blog of Project:
mateusvitali.wordpress.com

Share this post


Link to post
Share on other sites
You can use linear filtering:


yourD3DDevice->SetSamplerState (0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
yourD3DDevice->SetSamplerState (0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
yourD3DDevice->SetSamplerState (0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);


I've heard that anisotropic filtering (i.e. D3DTEXF_ANISOTROPIC) is better but you've to check the max. anisotropy level that driver/gpu work with.

Share this post


Link to post
Share on other sites
Quote:
Original post by programci_84
You can use linear filtering:


yourD3DDevice->SetSamplerState (0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
yourD3DDevice->SetSamplerState (0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
yourD3DDevice->SetSamplerState (0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);


I've heard that anisotropic filtering (i.e. D3DTEXF_ANISOTROPIC) is better but you've to check the max. anisotropy level that driver/gpu work with.
ID3DXSprite will already use bilinear filtering, or anistropic if it's available. Trilinear (linear mip filter) is redundant since sprites shouldn't have more than one mip level.

Share this post


Link to post
Share on other sites
Quote:
ID3DXSprite will already use bilinear filtering, or anistropic if it's available.


I belive it can be true, but I'm working with D3DX Sprite in 3D Space (e.g. flame, smoke, explosion effects etc.). If I don't use any of filtering operations before calling ID3DXSprite::Draw(), it looks like an image built by colored little squares.

I don't know the results in screen space like Vitali's example.

I'm using ATi HD4890, btw.

Quote:
Trilinear (linear mip filter) is redundant since sprites shouldn't have more than one mip level.

Ah yes, I missed it. You're right.

Thanks for correcting me, Steve.

Share this post


Link to post
Share on other sites
Quote:
Original post by programci_84
I belive it can be true, but I'm working with D3DX Sprite in 3D Space (e.g. flame, smoke, explosion effects etc.). If I don't use any of filtering operations before calling ID3DXSprite::Draw(), it looks like an image built by colored little squares.
If you pass the D3DXSPRITE_DONOTMODIFY_RENDERSTATE flag to ID3DXSprite::Begin(), it won't set change the sampler state (Among other things), which would mean it'll be using whatever the device has set, which is point (nearest neighbour) by default.

As for making it look better - so long as you have scaling going on, there's always going to be some blurring or jagged edges. How about not scaling the background, but splitting it into multiple pieces (I.e. title, gun logo and each menu option), and then positioning them based on the resolution, but not scaling them?

Share this post


Link to post
Share on other sites
I'm using a ScreenManager :D
but my class of menu, this is:

class MenuState : public IGameScreen
{
public:
MenuState() { }
~MenuState();

void Initialize(IDirect3DDevice9 *pDevice);
void Unload();

void Update();
void Draw();

private:
Sprite2D* background;
Sprite2D* cursor;
Sprite2D* options;
Font* text;

POINT absCursor; //Position of Mouse in Screen

// Pointer to the internal device
IDirect3DDevice9* m_pDevice;
};


The Sprite2D and Font are classes created by me for ease of use :)

//adjusts the coordinates of X, according to the new screen resolution
float posX(float x_old)
{
float new_x;
new_x = ( x_old * WIDTH ) / 1024;
return new_x;
}

//adjusts the coordinates of Y, according to the new screen resolution
float posY(float y_old)
{
float new_y;
new_y = ( y_old * HEIGHT ) / 768;
return new_y;
}

RECT option_online = { 0, 0, 290.0f, 50.0f},
option_offline = { 0, 135.0f, 290.0f, 50.0f},
option_tutorial = { 550.0f, 0, 290.0f, 50.0f},
option_options = { 550.0f, 135.0f, 290.0f, 50.0f},
option_exit = { 550.0f, 185.0f, 290.0f, 120.0f},
change_option = { 0.0f, 0.0f, 0.0f, 0.0f},
rect_void = { 0.0f, 0.0f, 0.0f, 0.0f};

MenuState::~MenuState()
{
Unload();
}

void MenuState::Initialize(IDirect3DDevice9 *pDevice)
{
m_pDevice = pDevice;

//Background of Menu
background = new Sprite2D();
background->load(m_pDevice, "Data\\Screens\\menu.png",D3DCOLOR_XRGB(255,0,255));
background->setPosition(0,0);

//Crosshair (Sprite of MouseCursor)
cursor = new Sprite2D();
cursor->load(m_pDevice, "Data\\Sprites\\crosshair.png",D3DCOLOR_XRGB(255,0,255));

//Rect of options
options = new Sprite2D();
options->load(m_pDevice, "Data\\Screens\\menu_.png",D3DCOLOR_XRGB(255,0,255));

//Text
text = new Font();
text->init(m_pDevice, 15, "Arial");
}

void MenuState::Unload()
{
//Destroy the sprites
if( background != NULL)
{
delete background;
background = NULL;
}
if( cursor != NULL)
{
delete cursor;
cursor = NULL;
}
if( options != NULL)
{
delete options;
options = NULL;
}

//Destroy the text manager
if( text != NULL)
{
delete text;
text = NULL;
}
}

void MenuState::Update()
{
GetCursorPos(&absCursor);
cursor->setPosition(absCursor.x, absCursor.y);

//If choice Online Game
if(absCursor.x >= posX(60.0f) && absCursor.x <= posX(280.0f)
&& absCursor.y >= posY(355.0f) && absCursor.y <= posY(380.0f))
{
change_option = option_online;
options->setPosition(posX(72.0f), posY(354.0f));
}
//If choice Offline Game
else if(absCursor.x >= posX(60.0f) && absCursor.x <= posX(290.0f)
&& absCursor.y >= posY(427.0f) && absCursor.y <= posY(453.0f))
{
change_option = option_offline;
options->setPosition(posX(72.0f), posY(489.0f));
}
//If choice Tutorial
else if(absCursor.x >= posX(60.0f) && absCursor.x <= posX(215.0f)
&& absCursor.y >= posY(500.0f) && absCursor.y <= posY(525.0f))
{
change_option = option_tutorial;
options->setPosition(posX(324.0f), posY(498.0f));
}
//If choice Options
else if(absCursor.x >= posX(60.0f) && absCursor.x <= posX(195.0f)
&& absCursor.y >= posY(572.0f) && absCursor.y <= posY(597.0f))
{
change_option = option_options;
options->setPosition(posX(324.0f), posY(633.0f));
}
//If choice Exit
else if(absCursor.x >= posX(60.0f) && absCursor.x <= posX(134.0f)
&& absCursor.y >= posY(644.0f) && absCursor.y <= posY(669.0f))
{
change_option = option_exit;
options->setPosition(posX(324.0f), posY(683.0f));
}
else
change_option = rect_void;
}

void MenuState::Draw()
{
//Render the background
background->render(true, m_pDevice, D3DCOLOR_ARGB(255,255,255,255));
//Render the options
options->render2(m_pDevice, change_option, D3DCOLOR_ARGB(255,255,255,255));
//Render the cursor
cursor->render(false, m_pDevice, D3DCOLOR_ARGB(255,255,255,255));


//Show the position of Cursor
std::stringstream caption_;
float x = posX(60);
float y = posY(60);
caption_ << "X: " << absCursor.x << " Y: " << absCursor.y << std::endl;
text->draw(caption_.str().c_str(), 3, 3, D3DCOLOR_ARGB(255,50,205,50));
}

Share this post


Link to post
Share on other sites
Can someone help me with the transition from screen?
alpha was increasing and then decreasing (fade-in and fade-out)

I tried it, most did not work:
void IntroState::Update()
{
float seg = GameTime->get_ticks()/1000;

//Transition of QI_logo (alpha)
if(seg >= 0.0f && seg <= 3.0f)
alpha += 4;
else if(seg > 3.0f && seg < 4.0f)
alpha = 255;
else if(seg > 4.0f && seg <= 9.0f)
alpha -= 2;

//Transition of Background_Intro
if(seg > 9.0f && seg <= 12.0f)
alpha += 5;
else if(seg > 12.0f)
alpha = 255;
}




void IntroState::Draw()
{
if(seg <= 9.0f)
qi_logo->render(true, m_pDevice, D3DCOLOR_ARGB(alpha,255,255,255));
else
{
background->render(true, m_pDevice, D3DCOLOR_ARGB(alpha,255,255,255));
intro_text->draw("Press ENTER to continue", posX(400), posY(580), D3DCOLOR_ARGB(255,255,255,255));
}

}



Function of GameTime:
int GameTime::get_ticks(void)
{
return GetTickCount() - m_start; //m_start => the start time of the game
}



[Edited by - VitaliBR on September 30, 2010 12:33:21 PM]

Share this post


Link to post
Share on other sites
I'm using a similar approach and works perfectly.

Details:
Declare an increment value:
float dA = 0.05f;


Declare fading technique:
#define FADE_IN (+1)
#define FADE_OUT (+2)
#define FADE_TECHNIQUE FADE_IN


Declare a float variable for fading start value:
static float alphaVal = FADE_TECHNIQUE - 1;


Add or subtract alphaVal_xx value according to technique (fade-in or out) on each frame:
alphaVal -= pow (-1.0f, FADE_TECHNIQUE) * dA;


Then use that alpha value as a color multiplier:
D3DXCOLOR alphaMultiplier (alphaVal, alphaVal, alphaVal, alphaVal);
yourD3DXSprite->Draw (yourSpriteTexture, NULL, NULL, NULL, alphaMultiplier);


Don't forget:
alphaVal can go under zero.
alphaVal can go over one.
You must control'em.

hth.
-R

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