Jump to content
  • Advertisement
Sign in to follow this  
Meai

Questions on world/view/projection stuff

This topic is 3411 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

I have read so many tutorials and explanations on this stuff, and never found anything understandable. Sorry for the long post! I'd be so glad if anyone could clarify these questions for me (I'm stuck on these for over a week now): Here it comes.. 1, What exactly does this do?
device->SetTransform(D3DTS_WORLD/VIEW/PROJECTION, matrix) 
Do -all- my future vertices/sprites/everything get transformed by the "matrix"? Every frame? Do I need to call them every frame? Is this comparable to setting a virtual origin in case of D3DTS_WORLD? 2, In my understanding, world space starts at the top left corner of the starting screen, and goes on infinitely in all directions. Is this correct? Does the world space origin change if I change the starting camera position? Meaning: does my world space origin always start at the top left corner of the cameras view volume? 3,If I want to place something (a sprite for example) at screen position 100/100 and another one at world space 100/100, how would those two be any different when my camera decides to move around? Would in this case screen space be equal to world space? 4, Im moving my camera by changing the lookat and eye vector in D3DXMatrixLookAtLH. How does the movement of my camera affect the aforementioned sprites positioned at 100/100 screen and world space? This is actually my problem at the moment: I tried it, and the sprites stay where they are, but If I want to reposition them through a mouseclick, the topleft corner has moved in response to the camera movement. Only the top left position though! The sprite gets drawn at the mouse position + camera movement delta, but I want it exactly at the mouse cursor. Currently I call device->SetTranform(D3DTS_WORLD,&matrixWithTheFirstCameraPos) once at initialization. And SetTransform(D3DTS_VIEW) and SetTransform(D3TS_PROJECTION) every frame. This is how my sprite is positioned every frame:
D3DXVECTOR2 spriteCentre=D3DXVECTOR2(center.x,center.y);
D3DXVECTOR2 trans=D3DXVECTOR2(posOnScreen.x,posOnScreen.y);
D3DXVECTOR2 scaling=D3DXVECTOR2(scaleX,scaleY);

D3DXMatrixTransformation2D(&m_worldMatrix,&spriteCentre,
0.0,&scaling,&spriteCentre,rotation,&trans);

m_d3dspt->SetTransform(&m_worldMatrix);
m_d3dspt->Draw(texture,NULL,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));


ANY help is greatly needed :) (also links to more tutorials, maybe I overlooked one)

Share this post


Link to post
Share on other sites
Advertisement
So you are using D3D9 to do some 2D sprite drawing, right? If so, then I'll try to help out:

1. SetTransform sets a matrix which is one of three matrices: the world matrix, the view matrix, and the projection matrix. These matrices are 'applied' in the order I just mentioned by multiplying them together, and then multiplying each vertex by the resulting matrix. So SetTransform is your way to affect the output from the vertex transformation stage. The values set in this way are retained from frame to frame or until a device is lost.

You could think of it as a virtual origin when setting the WORLD matrix, but there is more to it than that. Depending on the contents of your matrix, you can do much more than moving the origin around (i.e. rotation, stretching, skewing, etc...)

2. This one is not generally correct. World space is defined by your world matrix. So it can have an origin pretty much anywhere. What you are referring to that starts at the top left are normalized device coordinates, where the values range from 0-1 starting in the upper left hand corner. So 1,1 is the bottom right of the screen.

3. To place an object at world space 100,100 then you would set a translation matrix for those coordinates. The screen space coordinates 100,100 are a little trickier, requiring you to translate by a world space amount that puts the object there.

4. The camera affects where objects in the entire scene show up. If you move the camera 4 units to the right in world space, then the whole scene should appear to move to the left by the same amount.

I'm not really clear about the problem you are having, but you should be setting the view and projection matrices once per frame if they have changed, and set the world matrix right before rendering each object. I hope that helps - but you may want to spend some time with the DX documentation, which covers this topic as well.

Share this post


Link to post
Share on other sites
Thx for the reply!
Quote:

3. To place an object at world space 100,100 then you would set a translation matrix for those coordinates. The screen space coordinates 100,100 are a little trickier, requiring you to translate by a world space amount that puts the object there.

In my case, every sprite has its own matrix which defines position, rotation and scaling. I don't have to multiply those individual sprite matrices with the device world matrix right? Because that one is getting applied automatically, once I SetTransform() it at startup?
Essentially I want my sprite to appear whereever I click. Currently I transform my sprite by the posted code snipped, and replace "posOnScreen" with the client mouseclick position. The behaviour that happens is: the sprite appears correctly on the mouseclick as long as I dont move the camera. When I move it, the sprite is drawn XYZ units away from the mouse pointer, and XYZ being the distance the camera was moved.

Are the camera and the world space connected somehow? Otherwise all of this wouldnt make much sense.

Share this post


Link to post
Share on other sites
Quote:
Original post by Meai
Thx for the reply!
Quote:

3. To place an object at world space 100,100 then you would set a translation matrix for those coordinates. The screen space coordinates 100,100 are a little trickier, requiring you to translate by a world space amount that puts the object there.

In my case, every sprite has its own matrix which defines position, rotation and scaling. I don't have to multiply those individual sprite matrices with the device world matrix right? Because that one is getting applied automatically, once I SetTransform() it at startup?
Essentially I want my sprite to appear whereever I click. Currently I transform my sprite by the posted code snipped, and replace "posOnScreen" with the client mouseclick position. The behaviour that happens is: the sprite appears correctly on the mouseclick as long as I dont move the camera. When I move it, the sprite is drawn XYZ units away from the mouse pointer, and XYZ being the distance the camera was moved.
You should call the SetTransform method once per object to set it's world matrix, right before you draw it. Is this what you are doing?
Quote:
Are the camera and the world space connected somehow? Otherwise all of this wouldnt make much sense.
The world space transform changes your input vertices to 'World' space, and then the view matrix transforms your world space vertices to 'View' space. Finally your projection matrix will transform your view space vertices into homogenous clip space. Then they are converted to NDC coords (like mentioned above) and rasterized according to the resolution of the current render target.

Share this post


Link to post
Share on other sites
Quote:

You should call the SetTransform method once per object to set it's world matrix, right before you draw it. Is this what you are doing?

You don't mean the world matrix applied to the device right? Because I currently only call that once in the camera constructor. (which is called before anything gets rendered)
The first posted code is all I do with my objects ->every frame. It consists of constructing a new matrix for the object from position, scale and rotation member variables, applying that new matrix with sprite->SetTransform() and finally calling sprite->Draw();

It's frustrating because I already dumbed down my code so much, but even at such a basic level, I cannot find the mistake.

This is the relevant camera code, maybe that helps, although pretty standard:

//called once at start up
void OrthoCamera::init(float x, float y)
{
setPosition(D3DXVECTOR2(x,y)); // sets the position of the camera
D3DXMATRIX mat;
D3DXMatrixTranslation(&mat,x,y,0);
d3dManager.m_pDevice->SetTransform(D3DTS_WORLD, &mat);
}

void OrthoCamera::update() // called every frame after input is handled
{

//Setup orthographic projection matrix
float halfWidth = float(p_rectWidth/2.0);
float halfHeight = float(p_rectHeight/2.0);

D3DXMatrixOrthoOffCenterLH(&this->p_matrixProj,
-halfWidth / (float)p_zoom , halfWidth / (float)p_zoom,
halfHeight / (float)p_zoom, -halfHeight / (float)p_zoom,
(float)p_maxZoom, (float)p_minZoom);

d3dManager.m_pDevice->SetTransform(D3DTS_PROJECTION, &this->p_matrixProj);

//set the camera's view matrix
D3DXVECTOR3 eye(this->p_virtualPosition.x, this->p_virtualPosition.y, (float)-p_zoom);
D3DXVECTOR3 at(eye.x, eye.y, (float)p_maxZoom);
D3DXMatrixLookAtLH(&this->p_matrixView, &eye, &at, &D3DXVECTOR3(0.0f,1.0f,0.0f));
d3dManager.m_pDevice->SetTransform(D3DTS_VIEW, &this->p_matrixView);
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!