//-----------------------------------------------------------------------------------
// MatrixKvadrat.CPP
// Рисуем квадрат
//-----------------------------------------------------------------------------------
#include <windows.h> // Подключаем заголовочный файл Windows
#include <d3d9.h> // Подключаем заголовочный файл DirectX 9 SDK
#include <d3dx9.h> // Подключаем из D3DX утилит для работы с матрицами
#include <mmsystem.h> // Подключаем системную библеотеку
//-----------------------------------------------------------------------------------
// Глобальные переменные
//-----------------------------------------------------------------------------------
LPDIRECT3D9 pDirect3D = NULL; // Главный Direct3D обьект
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL; // Устройство
LPDIRECT3DVERTEXBUFFER9 pBufferVershin = NULL; // Буфер вершин
struct CUSTOMVERTEX
{
FLOAT x, y, z; //кординаты
DWORD color; //цвет вершин
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE) // Формат вершин
//-----------------------------------------------------------------------------------
// Функция
// InitialDirect3D()
// Инициализация Direct3D
//-----------------------------------------------------------------------------------
HRESULT InitialDirect3D( HWND hwnd )
{
if( NULL == ( pDirect3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
D3DDISPLAYMODE Display;
if( FAILED( pDirect3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &Display ) ) )
return E_FAIL;
D3DPRESENT_PARAMETERS Direct3DParametr;
ZeroMemory( &Direct3DParametr, sizeof(Direct3DParametr) );
Direct3DParametr.Windowed = TRUE;
Direct3DParametr.SwapEffect = D3DSWAPEFFECT_DISCARD;
Direct3DParametr.BackBufferFormat = Display.Format;
if( FAILED( pDirect3D -> CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&Direct3DParametr, &pDirect3DDevice ) ) )
{
return E_FAIL;
}
pDirect3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Отключить освещенние Direct3D
pDirect3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
return S_OK;
}
//---------------------------------------------------------------------------------------
// Функция
// InitialBufferVershin()
// Иннициализирует вершины
//---------------------------------------------------------------------------------------
HRESULT InitialBufferVershin()
{
CUSTOMVERTEX Vershin[] =
{
{ 1.0f,-1.0f, 0.0f, 0x00000fff, }, //А
{ -1.0f,-1.0f, 0.0f, 0xff000fff, }, //В
{ -1.0f, 1.0f, 0.0f, 0x00000fff, }, //С
{ -1.0f, 1.0f, 0.0f, 0x00000fff, }, //C
{ 1.0f, 1.0f, 0.0f, 0xff000fff, }, //D
{ 1.0f,-1.0f, 0.0f, 0x00000fff, }, //A
// x y z color
};
if( FAILED( pDirect3DDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &pBufferVershin, NULL ) ) )
{
return E_FAIL;
}
VOID* pBV;
if( FAILED( pBufferVershin->Lock( 0, sizeof(Vershin), (void**)&pBV, 0 ) ) ) //Блокируем
return E_FAIL;
memcpy( pBV, Vershin, sizeof(Vershin) ); //Копируем
pBufferVershin->Unlock(); // Разблокируем
return S_OK;
}
//-----------------------------------------------------------------------------
// Функция
// Matrix()
// Мировая матрица, матрица вида, матрица проекции
//-----------------------------------------------------------------------------
VOID Matrix()
{
D3DXMATRIX MatrixWorld; // Мировая матрица (MatrixWorld)
D3DXMATRIX MatrixView; // Матрица вида (MatrixView)
D3DXMATRIX MatrixProjection; // Матрица проекции (MatrixProjection)
// MatrixWorld
UINT Time = timeGetTime() % 5000;
FLOAT Angel = Time * (2.0f * D3DX_PI) / 5000.0f;
D3DXMatrixRotationY( &MatrixWorld, Angel );
pDirect3DDevice->SetTransform( D3DTS_WORLD, &MatrixWorld );
// MatrixView
D3DXMatrixLookAtLH( &MatrixView, &D3DXVECTOR3 ( 0.0f, 0.0f,-8.0f ),
&D3DXVECTOR3 ( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3 ( 0.0f, 1.0f, 0.0f ) );
pDirect3DDevice->SetTransform( D3DTS_VIEW, &MatrixView );
// MatrixProjection
D3DXMatrixPerspectiveFovLH( &MatrixProjection, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
pDirect3DDevice->SetTransform( D3DTS_PROJECTION, &MatrixProjection );
}
//-----------------------------------------------------------------------------------
// Функция
// RenderingDirect3D()
// Рисуем
//-----------------------------------------------------------------------------------
VOID RenderingDirect3D()
{
if(pDirect3DDevice == NULL) // Проверяем ошибки
return;
pDirect3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,0), 1.0f, 0 );
pDirect3DDevice->BeginScene(); // Начало сцены
Matrix();
// Здесь происходит прорисовка сцены
pDirect3DDevice->SetStreamSource( 0, pBufferVershin, 0, sizeof(CUSTOMVERTEX) );
pDirect3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
pDirect3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
pDirect3DDevice->EndScene(); //Конец сцены
pDirect3DDevice->Present( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------------
// Функция
// DeleteDirect3D()
// Освобождает захваченные ресурсы
//-----------------------------------------------------------------------------------
VOID DeleteDirect3D()
{
if( pBufferVershin != NULL)
pBufferVershin->Release();
if( pDirect3DDevice != NULL)
pDirect3DDevice->Release();
if( pDirect3D != NULL)
pDirect3D->Release();
}
//-----------------------------------------------------------------------------------
// Функция
// MainWinProc()
// Здесь происходит обработка сообщений
//-----------------------------------------------------------------------------------
LRESULT CALLBACK MainWinProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
{
DeleteDirect3D();
PostQuitMessage(0);
return(0);
}
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
//-----------------------------------------------------------------------------------
// Функция
// WinMain
// Входная точка приложения
//-----------------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX windowsclass; // Создаем класс
HWND hwnd; // Создаем дескриптор окна
MSG msg; // Идентификатор сообщения
// Определим класс окна WNDCLASSEX
windowsclass.cbSize = sizeof(WNDCLASSEX);
windowsclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
windowsclass.lpfnWndProc = MainWinProc;
windowsclass.cbClsExtra = 0;
windowsclass.cbWndExtra = 0;
windowsclass.hInstance = hinstance;
windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
windowsclass.lpszMenuName = NULL;
windowsclass.lpszClassName = "WINDOWSCLASS";
windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Зарегистрируем класс
if (!RegisterClassEx(&windowsclass))
return(0);
// Теперь когда класс зарегестрирован можно создать окно
if (!(hwnd = CreateWindowEx(NULL, // стиль окна
"WINDOWSCLASS", // класс
"Вращаем Квадрат ", // название окна
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
300,150, // левый верхний угол
500,400, // ширина и высота
NULL, // дескриптор родительского окна
NULL, // дескриптор меню
hinstance, // дескриптор экземпляра приложения
NULL))) // указатель на данные окна
return 0;
if( SUCCEEDED( InitialDirect3D( hwnd ) ) )
{
if( SUCCEEDED( InitialBufferVershin( ) ) )
{
ShowWindow( hwnd, SW_SHOWDEFAULT );
UpdateWindow( hwnd );
ZeroMemory( &msg, sizeof(msg));
while( msg.message!=WM_QUIT)
{
if(PeekMessage( &msg, NULL,0,0,PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
RenderingDirect3D();
}
}
}
return 0;
}
Вращение вокруг заданной точки
В руководствах по DirectX9 часто приводятся в качестве примера вращение какой-либо фигуры вокруг оси координат. а как сделать вращение вокруг заданной точки, используя Direct3D, на основе этого кода?
1. Перенос системы координат на (-x,-y,-z)
2. поворот на заданый угол
3. Перенос назад на (x,y,z)
Как это писать на основе вышеприведенного кода - думай сам. И по ходу дела ненмого помогает гуглить .. хоть иногда..
с теорией понятно. вот как прикрутить это к директ3д - вопрос.
А что, по-твоему, происходит при вызове pDirect3DDevice->SetTransform( D3DTS_WORLD, &MatrixWorld )?
Цитата: HarryAxe
А что, по-твоему, происходит при вызове pDirect3DDevice->SetTransform( D3DTS_WORLD, &MatrixWorld )?
помоему это устанавливает преобразования для мировой матрицы??
Ладно, объясняю популярно. Изменяя мировую матрицу, мы трансформируем все объекты, отрисовка которых происходит после такого изменения. Пример: есть квадрат [(-1, 1); (1, -1)], z1 = z2 = 0. Проводим вызов D3DXMatrixTranslation(&MatrixWorld, 2., 2., 0.) - при отрисовке квадрат будет иметь координаты [(1, 3); (3, 1)]. Мы могли бы сделать всё то же самое, тупо умножив каждую вершину объекта как вектор на мировую матрицу, но никакого понта от наличия графического ускорителя мы бы не получили.
Аналогично со вращением D3DXMatrixRotationX/Y/Z() и масштабированием D3DXMatrixScaling(). Порядок трансформаций играет существенную роль, объединить их можно с помощью умножения.