Can you provide steps on how these are setup as I am not sure how this should be done properly.
Sorry not inclined to give a full tutorial (and you definitively need one, a forum post is just not enough). A good starting point though is in the MSDN entry about
Transforms. But it essentially boils down to this: Your vertex positions get transformed (duh?) to finally be in screen space (pixel coordinates). With the so-called fixed function pipeline the individual transformation stages are set with
IDirect3DDevice9::SetTransform and
IDirect3DDevice9::SetViewport. Alernatively you use a vertex shader to perform the transformation calculation yourself. Which brings us to...
Since we are on this subject could you also go over transforms as well. I understand what they do and what they are for but I cannot get them to work. I assume this is because of my render / draw function or the way my CUSTOMFVF is setup.
Precisely. You're currently using pretransformed vertices (D3DFVF_XYZRHW). Such vertex positions won't be changed by the SetTransform (or Vertex Shader) at all, they're supposed to be in screen space already
If you do give me a tutorial how will I learn?
Anyway, I have been reading up on this all day since this is a very annoying issue. But there are somethings I'm unsure about.
Here is what I understand so far, so please correct anything if I'm wrong.
[+]--------------------------------------------------------[+]
First lets start with the transforms as everything is based on this
So we have 4 types of spaces:
Local: Literally this space is how a object is positioned and etc in its own space.
World: Where everything is in the world. A model or quad in my case is transformed here from its original local space.
View: The space that the belongs to the current view ( camera ). All items in the world space are ajusted based on this space.
Projection: How the camera functions. This space is controled by the view space and handles the Field of View (FoV) and far and near clipping planes
If we use this sampleish code:
//Somewhere at the top where the variables are
//UN-transformed vertices
DWORD CUSTFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
void initDirectX()
{
/* Create the DirectX 9 device here and etc*/
//Set the render states we use
device->SetRenderState(D3DRS_LIGHTING, FALSE);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
void render()
{
static float x = 0.0f;
static float y = 0.0f;
static float z = 0.0f;
static float w = 32.0f;
static float h = 32.0f;
vertex vertices[] =
{
{ x, y, z, D3DCOLOR_XRGB(0, 0, 255), },
{ x+w, y, z, D3DCOLOR_XRGB(0, 255, 0), },
{ x+w, y+h, z, D3DCOLOR_XRGB(255, 0, 0), },
{ x, y, z, D3DCOLOR_XRGB(0, 0, 255), },
{ x, y+h, z, D3DCOLOR_XRGB(0, 255, 0),},
{ x+w, y+h, z, D3DCOLOR_XRGB(255, 0, 0), }
};
device->CreateVertexBuffer(6 *sizeof(vertex),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&vB,
NULL);
VOID* pVoid;
vB->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
vB->Unlock();
device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
device->BeginScene();
device->SetFVF(CUSTFVF);
device->SetStreamSource(0, vB, 0, sizeof(vertex));
device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
device->EndScene();
device->Present(NULL, NULL, NULL, NULL);
}
We will see this rendered on the screen:
[attachment=18330:Capture.PNG]
Which makes sense because the camera is currently not setup; So it points at position 0,0
[attachment=18331:cam.png]
Here is where I am unsure of somethings
Things I understand:
1. Direct X uses a left hand system BUT
2. D3DFVF_XYZRHW vertices are already transformed
3. When using D3DFVF_XYZRHW everything is based at the top left 0,0
4. How transformations work at the local and world space level
5. Orthographic projections convert 3D space to 2D space
Things I don't know / don't understand:
1. How to manipulate the view space
2. How to manipulate and setup the projection space
Other questions:
1. Are these the only things I need to do for orthographic projections? The projections seem to work. The only thing that does not work is rotation, its is rotateing around the world's perspective. How can I rotate in local space?
Working code with no rotation involved
/* Clear and begin scene code */
//Sets up a orthographic projections where the origin is the center of the screen
D3DXMATRIX out;
D3DXMatrixOrthoLH(&out, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, 1.0f);
device->SetTransform(D3DTS_PROJECTION, &out);
/*Draw primative and endScene code */
Alternative Orthographic projection code (Base on Top Left as 0, 0 )
/* Clear and begin scene code */
//Sets up an orthographic projection based on the top left (0,0) using a 800 x 600 screen
D3DXMATRIX out;
D3DXMatrixOrthoOffCenterLH(&out, 0.0f, 800.0f, 600.0f, 0.0f, 0.0f, 1.0f);
device->SetTransform(D3DTS_PROJECTION, &out);
/*Draw primative and endScene code */
Code when trying to rotate (Works, but rotates around the 0,0 of the projection)
How do I get it to rotate around the local space so the object is rotated about its center
/* Clear and begin scene code */
D3DXMATRIX rot;
D3DXMatrixRotationX(&rot, D3DXToRadian(45.0f));
device->SetTransform(D3DTS_WORLD, &rot);
D3DXMATRIX out;
D3DXMatrixOrthoOffCenterLH(&out, 0.0f, 800.0f, 600.0f, 0.0f, 0.0f, 1.0f);
device->SetTransform(D3DTS_PROJECTION, &out);
/*Draw primative and endScene code */
2. In order to make a movable 2D Camera would I be moving everything based on the camera's position like this?
Is there a better way?
//Transform everything in the world based on the camera's position
D3DXMATRIX tran;
D3DXMatrixTranslation(&tran, Object.x - cam.x, Object.y - cam.y, 0.0f);
device->SetTransform(D3DTS_WORLD, &tran);
3. What would I do to rotate models or quads on a indivisual? Surely it can't be:
//Preform a rotation on the X-Axis
D3DXMATRIX rot;
D3DXMatrixRotationX(&rot, D3DXToRadian(45.0f));
device->SetTransform(D3DTS_WORLD, &rot);
This would rotate everything the transform applys to. I would think doing something like
1. If we need to rotate a quad / model use the rotation transform; the otherwise do not do the transform
2. Draw it the quad
3. Move onto the next quad to draw; check to see if it needs to be rotated or etc
Would be highly inefficient
4. The original problem is fixed with setting a -0.5 pixel offset. So now that I have an Othrographic Projection how do I set global offset? Or because I use D3DFVF_XYZ for my vertexs and I can perform transformations?
Something like this:
D3DXMATRIX tran;
D3DXMatrixTranslation(&tran, Object.x - 0.5f, Object.y - 0.5f, 0.0f);
device->SetTransform(D3DTS_WORLD, &tran);
How is this applied to multiple objects?
-------------------
I'll add more as I think of it, but for now I got to grab some food!