Sign in to follow this  

Object Rotation in Ortho Matrix

This topic is 3859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i have a little problem with my 2D code, and im really not the matrix guy :/ I built a sprite class based on a tutorial from gamedev, and everything works ... except the rotation. I want a rotating sprite, not a sprite that surrounds the center of the screen like an orbit, or a sprite that rotates around the top left pixel of the sprite. Here is the code i have 3d init code:
   //Setup an orthographic perspective
    D3DXMatrixOrthoLH (&matOrtho, (float) a_width, (float) a_height, 1.0f, 10.0f);
    D3DXMatrixIdentity (&matIdentity);
    s_d3DDevice->SetTransform (D3DTS_PROJECTION, &matOrtho);
    s_d3DDevice->SetTransform (D3DTS_VIEW, &matIdentity);
    s_d3DDevice->SetTransform (D3DTS_WORLD, &matIdentity);
    
    //Setup vertex format
    s_d3DDevice->SetVertexShader(NULL);
    s_d3DDevice->SetFVF (D3DFVF_TLVERTEX);
	s_d3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    
    //Set render states
    s_d3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    s_d3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    s_d3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    s_d3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    s_d3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

and here the render code of the sprite
IsoEngine::s_d3DDevice->SetStreamSource (0, m_vertexBuffer, 0, sizeof(TLVERTEX));

	float X;
    float Y;
    D3DXMATRIX matTranslation;
    D3DXMATRIX matScaling;
    D3DXMATRIX matTransform;
    
    //Get coordinates
	X = GetPositionX() - (float)(IsoEngine::s_enviroment.m_screenWidth) / 2;
	Y = -GetPositionY() + (float)(IsoEngine::s_enviroment.m_screenHeight) / 2; 

    //Setup translation and scaling matrices
    D3DXMatrixScaling (&matScaling, (float)m_width, (float)m_height, 1.0f);
    D3DXMatrixTranslation (&matTranslation, X, Y, 0.0f);
    matTransform = matScaling * matTranslation;
	
    //Check if quad is rotated
    if (m_rotation)
    {
        D3DXMATRIX matRotate;

        //Create rotation matrix about the z-axis
		D3DXMatrixRotationZ (&matRotate, m_rotation);

        //Multiply matrices together
        matTransform *= matRotate;
    }

    //Draw the quad
	IsoEngine::s_d3DDevice->SetTransform (D3DTS_WORLD, &matTransform);
    IsoEngine::s_d3DDevice->SetTexture (0, m_texture->GetTexture());
    IsoEngine::s_d3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);

Share this post


Link to post
Share on other sites
The problem is in hotspot of sprite. You need to define center coordinates of your sprite. Say, you have quad that has vertex on 100,100 (top left corner) and 120,120 (bottom down corner). Obviously the center of your sprite is located at 110,110 and around that point you need to rotate your sprite.
That is if you are using sprite interface.

On quads, the problem is different. Problem is in transforms.
You need FIRST to SCALE quad, then ROTATE and then MOVE;

D3DXMatrixScaling (&matScaling, (float)m_width, (float)m_height, 1.0f);
D3DXMatrixTranslation (&matTranslation, X, Y, 0.0f);


//Check if quad is rotated
if (m_rotation)
{
D3DXMATRIX matRotate;

//Create rotation matrix about the z-axis
D3DXMatrixRotationZ (&matRotate, m_rotation);

//Multiply matrices together
matTransform = matScaling *matRotate* matTranslation;


}
else
matTransform = matScaling * matTranslation;

Hope that helps

Share this post


Link to post
Share on other sites
thanks for your answer, but no it still doesnt work :(
with your code change, the sprite rotates around the top left corner.
But im using quads ... at least i think i am lol, better i post the full code
of the class


#include ".\isosprite.h"
#include "Application.h"

IsoSprite::IsoSprite(CString a_name) :
IsoObject (a_name)
{
m_texture = NULL;
m_vertexBuffer = NULL;
m_alpha = 255;
m_colorR = 255;
m_colorG = 255;
m_colorB = 255;
m_width = 0;
m_height = 0;
m_rotation = 0;
}

IsoSprite::IsoSprite() :
IsoObject ("")
{
m_texture = NULL;
m_vertexBuffer = NULL;
m_alpha = 255;
m_colorR = 255;
m_colorG = 255;
m_colorB = 255;
m_width = 0;
m_height = 0;
m_rotation = 0;
}

IsoSprite::~IsoSprite(void)
{
Shutdown ();
}

void IsoSprite::Shutdown ()
{
SafeRelease (m_vertexBuffer);

if (m_texture != NULL)
{
m_texture->DecreaseReferenceCount ();
m_texture = NULL;
}
}

int IsoSprite::Run ()
{
return TRUE;
}

int IsoSprite::Render ()
{
m_rotation += 0.005; // just to test the rotation
IsoEngine::s_d3DDevice->SetStreamSource (0, m_vertexBuffer, 0, sizeof(TLVERTEX));

float X;
float Y;
D3DXMATRIX matTranslation;
D3DXMATRIX matScaling;
D3DXMATRIX matTransform;

//Get coordinates
X = GetPositionX() - (float)(IsoEngine::s_enviroment.m_screenWidth) / 2;
Y = -GetPositionY() + (float)(IsoEngine::s_enviroment.m_screenHeight) / 2;

D3DXMatrixScaling (&matScaling, (float)m_width * 2, (float)m_height * 2, 1.0f);
D3DXMatrixTranslation (&matTranslation, X, Y, 0.0f);

//Check if quad is rotated
if (m_rotation)
{
D3DXMATRIX matRotate;

//Create rotation matrix about the z-axis
D3DXMatrixRotationZ (&matRotate, m_rotation);

//Multiply matrices together
matTransform = matScaling *matRotate* matTranslation;
}
else matTransform = matScaling * matTranslation;

//Draw the quad
IsoEngine::s_d3DDevice->SetTransform (D3DTS_WORLD, &matTransform);
IsoEngine::s_d3DDevice->SetTexture (0, m_texture->GetTexture());
IsoEngine::s_d3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);

return TRUE;
}

bool IsoSprite::CreateSprite (CString a_filename)
{
// try to load the texture
m_texture = IsoEngine::GetTexture (a_filename);
if (m_texture == NULL) return false;

// then create vertexbuffer
SafeRelease (m_vertexBuffer);

HRESULT hr;
hr = IsoEngine::s_d3DDevice->CreateVertexBuffer (
4*sizeof (TLVERTEX),
D3DUSAGE_WRITEONLY,
D3DFVF_TLVERTEX,
D3DPOOL_MANAGED,
&m_vertexBuffer, NULL);

if (FAILED(hr))
{
g_app.Log ("Couldn't create vertexbuffer for sprite %s",a_filename);

Shutdown ();
return false;
}

m_textureRect.left = 0;
m_textureRect.top = 0;
m_textureRect.right = m_texture->GetWidth();
m_textureRect.bottom = m_texture->GetHeight();
m_width = m_textureRect.right - m_textureRect.left;
m_height = m_textureRect.bottom - m_textureRect.top;

m_clipRegion.left = 0;
m_clipRegion.top = 0;
m_clipRegion.right = IsoEngine::s_enviroment.m_screenWidth;
m_clipRegion.bottom = IsoEngine::s_enviroment.m_screenHeight;

return UpdateSprite ();
}

void IsoSprite::SetTextureRect(int a_x, int a_y, int a_width, int a_height)
{
m_textureRect.left = a_x;
m_textureRect.top = a_y;
m_textureRect.right = a_x + a_width;
m_textureRect.bottom = a_y + a_height;
m_width = m_textureRect.right - m_textureRect.left;
m_height = m_textureRect.bottom - m_textureRect.top;
}

bool IsoSprite::UpdateSprite(void)
{
if (m_vertexBuffer == NULL || m_texture == NULL) return false;

float a_sx = m_textureRect.left;
float a_sy = m_textureRect.top;
float a_sx2 = m_textureRect.right;
float a_sy2 = m_textureRect.bottom;

FLOAT w = (1.0f / (float) m_texture->GetWidth());
FLOAT h = (1.0f / (float) m_texture->GetHeight());

FLOAT tu1 = a_sx * w;
FLOAT tv1 = a_sy * h;
FLOAT tu2 = a_sx2 * w;
FLOAT tv2 = a_sy2 * h;

TLVERTEX* pVertices;
m_vertexBuffer->Lock( 0, 0, (VOID**)&pVertices, 0);

pVertices [0].x = 0.0f;
pVertices [0].y = 0.0f;
pVertices [0].z = 1.0f;
pVertices [0].colour = IsoArgb ((int)m_alpha,(int)m_colorR,(int)m_colorG,(int)m_colorB);
pVertices [0].u = tu1;
pVertices [0].v = tv1;

pVertices [1].x = 1.0f;
pVertices [1].y = 0.0f;
pVertices [1].z = 1.0f;
pVertices [1].colour = IsoArgb ((int)m_alpha,(int)m_colorR,(int)m_colorG,(int)m_colorB);
pVertices [1].u = tu2;
pVertices [1].v = tv1;

pVertices [2].x = 1.0f;
pVertices [2].y = -1.0f;
pVertices [2].z = 1.0f;
pVertices [2].colour = IsoArgb ((int)m_alpha,(int)m_colorR,(int)m_colorG,(int)m_colorB);
pVertices [2].u = tu2;
pVertices [2].v = tv2;

pVertices [3].x = 0.0f;
pVertices [3].y = -1.0f;
pVertices [3].z = 1.0f;
pVertices [3].colour = IsoArgb ((int)m_alpha,(int)m_colorR,(int)m_colorG,(int)m_colorB);
pVertices [3].u = tu1;
pVertices [3].v = tv2;

m_vertexBuffer->Unlock();
return false;
}


Share this post


Link to post
Share on other sites
lol i was so stupid ^^, i found my error. The positions of the vertices were wrong, with those the center was always the top left corner, i didnt even think about that :p. KK problem solved, thanks for your help streamer, now the rotation is perfect

Share this post


Link to post
Share on other sites

This topic is 3859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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