Du musst IMMER die Matrizen in folgender Reihenfolge multiplizieren:
Skalierung * Rotation * Translation
Ich zeige dir hier mal den Render-Code von meinem Spriterenderer in stark verkürzter (Pseudo-)Form:
Code:
// Matrices for positioning, rotation and scaling
D3DXMATRIX matTemp, matPosition, matRotation, matScaling;
D3DXMatrixIdentity(&matTemp);
// Dimensions in Pixel space
float fWidth = csi.fWidth * cti.sSize.cx;
float fHeight = csi.fHeight * cti.sSize.cy;
x -= (fScaleX - 1.0f) * fRotationCenterX * fWidth;
y -= (fScaleY - 1.0f) * fRotationCenterY * fHeight;
D3DXMatrixScaling(&matScaling, fScaleX * fWidth / 100.0f, fScaleY * fHeight / 100.0f, 1.0f);
matTemp = matTemp * matScaling;
// Rotation (done only if wanted)
if (fRotationAngle != 0.0f)
{
D3DXMatrixRotationZ(&matRotation, fRotationAngle);
matTemp = matTemp * matRotation;
}
// Bias for texel -> pixel matching
x -= 0.5f;
y -= 0.5f;
// Translation
D3DXMatrixTranslation(&matPosition, x - m_sScreen.cx / 2 - fRotationCenterX * fWidth, m_sScreen.cy - y - m_sScreen.cy / 2 + fRotationCenterY * fHeight, 0.0f);
matTemp = matTemp * matPosition;
m_pDevice->SetTransform(D3DTS_WORLD, &matTemp);
// Set modulation color and texture if not the same as in the previous call
if (m_clLastColor != clColor)
{
m_pDevice->SetRenderState(D3DRS_TEXTUREFACTOR, clColor);
m_clLastColor = clColor;
}
if (m_nLastTextureIndex != nTextureIndex)
{
m_pDevice->SetTexture(0, m_pInfos[nTextureIndex].ppTextures[0]);
m_nLastTextureIndex = nTextureIndex;
}
// Texture Coordinate Transformation
D3DXMatrixScaling(&matScaling, csi.fWidth, csi.fHeight, 1.0f);
D3DXMatrixIdentity(&matPosition);
matPosition._31 = csi.fLeft;
matPosition._32 = csi.fTop;
matTemp = matScaling * matPosition;
m_pDevice->SetTransform(D3DTS_TEXTURE0, &matTemp);
HRESULT hr = m_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
return hr;
In Delphi kannst du übrigens, wenn ich mich nicht irre, die Matrizen nicht direkt multiplizieren, sondern musst den Umweg über D3DXMatrixMultiply etc. gehen.
Copy&Paste würde ich dir nicht empfehlen, weil zum einen eine ganze Menge fehlt, und du zum anderen so viele Variablen etc. neu definieren müsstest, dass du schneller zum Ziel kommst, wenn du alles selbst schreibst ;c) Aber vielleicht ist das ganze so etwas anschaulicher.
Klar kannst du 2D und 3D mischen. Wenn du 2D rendern willst, nimmst du halt ein orthogonales Koordinatensystem, wenn du 3D rendern willst, ein perspektivisches. Geht alles über Welt-/Ansicht-/Projektionstransformation.
Warum die Matrizen 4x4 sind, kann ich dir gar nicht so genau sagen, aber das steht, wenn ich nicht irre, im
DirectX SDK ;c)
[edit=Daniel B]Delphi-Tags korrigiert. Mfg, Daniel B[/edit]
[edit=Daniel B]Code-Tags wieder eingefügt. Sorry. Mfg, Daniel B[/edit]