Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вращение вокруг заданной точки

3.9K
29 октября 2007 года
АКМ
49 / / 07.06.2005
В руководствах по DirectX9 часто приводятся в качестве примера вращение какой-либо фигуры вокруг оси координат. а как сделать вращение вокруг заданной точки, используя Direct3D, на основе этого кода?

Код:
//-----------------------------------------------------------------------------------
// 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;
}
255
29 октября 2007 года
Dart Bobr
1.4K / / 09.04.2004
алгоритм поворота вокруг точки (x,y,z):
1. Перенос системы координат на (-x,-y,-z)
2. поворот на заданый угол
3. Перенос назад на (x,y,z)
Как это писать на основе вышеприведенного кода - думай сам. И по ходу дела ненмого помогает гуглить .. хоть иногда..
391
29 октября 2007 года
Archie
562 / / 03.02.2005
http://en.wikipedia.org/wiki/Rotation_matrix
3.9K
31 октября 2007 года
АКМ
49 / / 07.06.2005
с теорией понятно. вот как прикрутить это к директ3д - вопрос.
534
01 ноября 2007 года
HarryAxe
448 / / 19.01.2006
А что, по-твоему, происходит при вызове pDirect3DDevice->SetTransform( D3DTS_WORLD, &MatrixWorld )?
3.9K
01 ноября 2007 года
АКМ
49 / / 07.06.2005
Цитата: HarryAxe
А что, по-твоему, происходит при вызове pDirect3DDevice->SetTransform( D3DTS_WORLD, &MatrixWorld )?



помоему это устанавливает преобразования для мировой матрицы??

534
02 ноября 2007 года
HarryAxe
448 / / 19.01.2006
Ну а смысл этих махинаций каков?
Ладно, объясняю популярно. Изменяя мировую матрицу, мы трансформируем все объекты, отрисовка которых происходит после такого изменения. Пример: есть квадрат [(-1, 1); (1, -1)], z1 = z2 = 0. Проводим вызов D3DXMatrixTranslation(&MatrixWorld, 2., 2., 0.) - при отрисовке квадрат будет иметь координаты [(1, 3); (3, 1)]. Мы могли бы сделать всё то же самое, тупо умножив каждую вершину объекта как вектор на мировую матрицу, но никакого понта от наличия графического ускорителя мы бы не получили.
Аналогично со вращением D3DXMatrixRotationX/Y/Z() и масштабированием D3DXMatrixScaling(). Порядок трансформаций играет существенную роль, объединить их можно с помощью умножения.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог