Code:
void Draw::DrawImageAtPosition(Vector3 worldPos, float size, LPDIRECT3DTEXTURE9 texture, LPDIRECT3DDEVICE9 dev)
{
if (!dev) {
printf("[DrawImage] Device is null.\n");
return;
}
if (!texture) {
printf("[DrawImage] Texture is null. Skipping image draw.\n");
Draw::DrawBox(worldPos, size, D3DCOLOR_ARGB(255, 255, 0, 0), dev);
return;
}
CameraInfo* cam = (CameraInfo*)Camera::GetActiveCamera();
if (!cam) {
printf("[DrawImage] No active camera.\n");
Draw::DrawBox(worldPos, size, D3DCOLOR_ARGB(255, 255, 0, 0), dev);
return;
}
// Build camera matrices
D3DXMATRIX world, view, projection;
D3DXMatrixIdentity(&world);
D3DXVECTOR3 eye = cam->Position;
D3DXVECTOR3 at = eye + Camera::Forward();
D3DXVECTOR3 up(0, 0, 1);
D3DXMatrixLookAtRH(&view, &eye, &at, &up);
D3DXMatrixPerspectiveFovRH(&projection, cam->FieldOfView * 0.6f, cam->Aspect, cam->NearPlane, cam->FarPlane);
// Project 3D world position to 2D screen
D3DVIEWPORT9 viewport;
dev->GetViewport(&viewport);
D3DXVECTOR3 screenPos;
D3DXVECTOR3 input(worldPos.X, worldPos.Y, worldPos.Z);
if (!D3DXVec3Project(&screenPos, &input, &viewport, &projection, &view, &world)) {
printf("[DrawImage] D3DXVec3Project failed.\n");
Draw::DrawBox(worldPos, size, D3DCOLOR_ARGB(255, 255, 0, 0), dev);
return;
}
if (screenPos.z < 0.0f || screenPos.z > 1.0f) {
printf("[DrawImage] Projected Z out of view range: %.2f\n", screenPos.z);
Draw::DrawBox(worldPos, size, D3DCOLOR_ARGB(255, 255, 0, 0), dev);
return;
}
// Debug projection result
printf("[DrawImage] Projected screen X=%.2f Y=%.2f Z=%.2f\n", screenPos.x, screenPos.y, screenPos.z);
// Prepare screen-space quad
float half = size / 2.0f;
struct ScreenVertex {
float x, y, z, rhw;
float u, v;
};
ScreenVertex quad[4] = {
{ screenPos.x - half, screenPos.y - half, 0.0f, 1.0f, 0.0f, 0.0f },
{ screenPos.x + half, screenPos.y - half, 0.0f, 1.0f, 1.0f, 0.0f },
{ screenPos.x + half, screenPos.y + half, 0.0f, 1.0f, 1.0f, 1.0f },
{ screenPos.x - half, screenPos.y + half, 0.0f, 1.0f, 0.0f, 1.0f }
};
quad->rhw = 1.0f;
// Set rendering state
dev->SetTexture(0, texture);
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
dev->SetRenderState(D3DRS_ZENABLE, FALSE);
dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
HRESULT hr = dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, sizeof(ScreenVertex));
if (FAILED(hr)) {
printf("[DrawImage] DrawPrimitiveUP failed (HRESULT: 0x%08X). Drawing fallback box.\n", hr);
Draw::DrawBox(worldPos, size, D3DCOLOR_ARGB(255, 255, 0, 0), dev);
}
else {
printf("[DrawImage] Image draw completed successfully.\n");
}
}