2013-05-23 5 views
0

У меня есть среда direct3d в окне MFC, и я хотел бы нарисовать оси координатной системы в углу экрана, как и любое 3D-программное обеспечение. Я думал, что это не проблема, но проблемы возникли, когда я начал перемещать камеру. Мне нужно, чтобы объект находился в одном и том же месте, независимо от того, как я панорамирую, масштабирую или поворачиваю камеру.рисование координат оси системы в углу экрана в direct3d

Но кажется, что я делаю что-то неправильно, и я надеялся, что кто-то может указать мне в правильном направлении, поскольку объект, который я рисую, не масштабируется соответственно, когда я увеличиваю масштаб, но он отлично работает при панорамировании или вращение.

Я также мириться Видеосервис YouTube, чтобы показать вам симптомы: http://www.youtube.com/watch?v=gwM0m8nbLts&feature=youtu.be

Это мой код для рисования объекта:

void CDEMView::DrawSomeBox() 
{ 
// Define the needed matrices - object world, view and project 
D3DXMATRIX matObjectWorld; 
    D3DXMatrixIdentity (&matObjectWorld); // object world matrix 
D3DXMATRIX matView;    
    D3DXMatrixIdentity (&matView);  // view matrix 
D3DXMATRIX matProjection; 
    D3DXMatrixIdentity (&matProjection); // projection matrix 

// Get the needed matrices 
_device->GetTransform(D3DTS_VIEW, &matView); 
_device->GetTransform(D3DTS_PROJECTION, &matProjection); 

// Get the viewport 
D3DVIEWPORT9 viewport; 
_device->GetViewport(&viewport); 

// Get the center point of the object  
D3DXVECTOR3* p_centerPoint = BoxCenterVector; // this is from an external variable 

// Get the point on the creen that is the screen projection of the object 
D3DXVECTOR3 projectPoint; 
D3DXVec3Project(&projectPoint, p_centerPoint ,&viewport, &matProjection, &matView, &matObjectWorld); 

// choose the screen point where the object is to be drawn, relative to the Viewport's dimensions 
D3DXVECTOR3 screenPoint; 
screenPoint.x = 0.1*viewport.Width; // x position (horizontal) is 10% of the width of the screen (0% is left, 100% is right) 
screenPoint.y = 0.9*viewport.Height; // y position (vertical) is 90% of the height of the screen (0% is top, 100% is bottom) 
screenPoint.z = projectPoint.z;  // 1-projectPoint.z*60/(-zoom); 

//transform the screen position to a world position 
D3DXVECTOR3 worldPoint; 
D3DXVec3Unproject(&worldPoint, &screenPoint, &viewport, &matProjection, &matView, &matObjectWorld); 

// now define how much to translate the box in order to get it to the point we want it to be (WorldPoint) 
float transX, transY, transZ; 
transX = worldPoint.x; 
transY = worldPoint.y; 
transZ = worldPoint.z; 

// define a mesh to store the object into and create the object 
ID3DXMesh* _SomeBox; 
float boxSize = 2.0f; 
D3DXCreateBox(_device,boxSize,boxSize,boxSize,&_SomeBox,NULL); 

// define a material and set its color 
D3DMATERIAL9 mat; 

// Set the RGBA for diffuse reflection. 
mat.Diffuse.r = 255; 
mat.Diffuse.g = 0; 
mat.Diffuse.b = 0; 
mat.Diffuse.a = 0.5; 

_device->SetMaterial(&mat); 
_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); // D3DFILL_SOLID 

// apply the translation matrix 
D3DXMatrixTranslation(&matObjectWorld, transX, transY, transZ); 
_device->SetTransform(D3DTS_WORLD, &matObjectWorld); 

// draw the object 
_SomeBox->DrawSubset(0); 
// release the mesh 
_SomeBox->Release(); 
} 

ответ

0

Я внимательно не смотрел на свой код, чтобы попробовать и найти проблему, но я бы посоветовал вам выбрать несколько иной подход, который позволит избежать необходимости компенсировать движение камеры. Вместо того, чтобы позиционировать координатные оси как объект, расположенный в том же пространстве мира, что и ваша сцена, измените свой видовой экран на область, где вы хотите отображать координатные оси и визуализировать их в виртуальной сцене с фиксированной камерой и мировой матрицей это ваша матрица просмотра вашей основной сцены без компонента перевода.

Таким образом, вам даже не нужно беспокоиться о масштабировании вашей камеры, вы просто показываете, как вращение вашей матрицы просмотра влияет на мировые оси. Этот подход также имеет то преимущество, что вы можете избежать любых проблем с вашими осями, взаимодействующими с вашей сценой. Вы можете очистить z-буфер окна просмотра, где вы делаете свои оси перед их рисованием, и они будут похожи на отдельный слой, который не взаимодействует с вашей основной сценой. Вы также можете добиться такого же эффекта, визуализируя оси на экране вне контекста рендеринга целевой текстуры и отображая это как квадрат в вашей основной сцене, но для этого случая это будет больше работы без значительной выгоды.

+0

привет! Спасибо за ответ. У меня мало знаний о программировании вообще и directx в частности. поэтому я не понимаю, что такое «виртуальная сцена» и как это можно сделать. У меня тоже возникла идея создать еще меньший видовой экран и нарисовать топоры там, но у меня было много проблем с этим, и я отказался от этой идеи. вы могли бы указать мне место, где я мог бы изучить несколько видов видовых экранов в одном окне (я использую MFC). Еще раз спасибо! – user2415320

+0

Виртуальная сцена не является официальным термином, это был просто мой термин для описанного подхода. Не так много, чтобы использовать меньший видовой экран, вам просто нужно вызвать SetViewport с координатами, которые вы хотите отобразить, и тогда вы, вероятно, захотите вызвать Clear, чтобы очистить буфер z перед рендерингом. Любой рендеринг, который вы делаете сейчас, вы установили, что окно просмотра будет происходить с этим субрегионом экрана. – mattnewport

+0

Отлично! Я отдам его. Я также пробовал это несколько дней назад, но теперь я понимаю, что пошло не так. Я буду держать вас в курсе. – user2415320

0

Одна вещь, которую вы могли бы сделать, хотя и немного перебор, состоит в том, чтобы сначала нарисовать вращающийся объект без перевода, но только вращение ортогонально в текстуру. См. this link.

Этот способ, независимо от того, насколько далеко объект, он будет такого же размера. После того, как у вас есть текстура, просто выполните одну из двух вещей: выделите квадрат на экран в верхнем левом углу без 3D-преобразований или используйте интерфейс спрайтов, поставляемый с DirectX для рендеринга текстуры. Использование интерфейса спрайта будет по сути делать то же самое, что использовать 2D-квадрант, но это может быть немного проще, и, по моему опыту, он довольно быстро. Удачи!