Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Загрузка Х-файла в DirectX 9  (Прочитано 14409 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« : 23-06-2009 02:04 » 

Я сделал крутящегося тигра, но у меня при работе программы почему-то части тигра пропадает.

Поясните пожалуйста, где я ошибся?

Вот код

Код:
// в этом файле лежат все функции WinAPI
#include <windows.h>
// подключаем заголовочный файл DirectX 9 SDK
#include <d3d9.h>
#include <d3dx9.h>
// Для работы с mesh
#include <d3dx9mesh.h>
#include <math.h>

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;

// Указатель на Mesh
LPD3DXMESH pMesh = NULL;
// Указател на буфер mesh-а
LPD3DXBUFFER pMeshBuffer = NULL;
// Указатель на буфер материалов
D3DMATERIAL9 *pMeshMaterial = NULL;
// Указатель на буфер текстур
LPDIRECT3DTEXTURE9 *pMeshTexture = NULL;
// Количество материала и текстур
DWORD dwNumber = 0;

DWORD OneTick = 0;

HINSTANCE hInstance;

// Функция обработки сообщений - прототип
LRESULT CALLBACK MainWinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
// Функция инициализации Direct3D - прототип
HRESULT InitDirect3D(HWND hwnd);
// Функция рендеринга Direct3D - прототип
void RenderingDirect3D(void);
// Функция освобождения захваченных ресурсов - прототип
void DeleteDirect3D(void);
// Функция инициализации объекта (буфера и индексов вершин) - прототип
HRESULT InitMesh(void);
// Установка матриц преобоазования - прототип
void Matrix(void);
// Рисует созданную mesh - прототип
void DrawMyMesh(void);

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX windowsclass;
    HWND hwnd;
    MSG msg;
    hInstance = hInst;

    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 = hInst;
    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;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением", WS_OVERLAPPEDWINDOW|
   WS_VISIBLE, 0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    if (SUCCEEDED(InitDirect3D(hwnd)))
    {
        if (SUCCEEDED(InitMesh()))
        {
            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 (int)msg.wParam;
}
// Функция обработки сообщений
LRESULT CALLBACK MainWinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg)
    {
        // События Создания объектов
        case WM_CREATE:
        break;

        //Обработка сообщений от элементов управления
        case WM_COMMAND:
        break;

        //WM_PAINT - для рисования
        case WM_PAINT:
        break;

        // WM_DESTROY - для закрытия окна
        case WM_DESTROY:
                DeleteDirect3D();
                PostQuitMessage(0);
        break;
    }
    return (DefWindowProc(hwnd, msg, wparam, lparam));
}
// Функция инициализации Direct3D
HRESULT InitDirect3D(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 Direct3DParameter;
    ZeroMemory(&Direct3DParameter, sizeof(Direct3DParameter));
    Direct3DParameter.Windowed = true;
    Direct3DParameter.SwapEffect = D3DSWAPEFFECT_DISCARD;
    Direct3DParameter.BackBufferFormat = Display.Format;
    // Включаем z-буфер
    Direct3DParameter.EnableAutoDepthStencil = TRUE;
    // Формат поверхности z-буфера
    Direct3DParameter.AutoDepthStencilFormat = D3DFMT_D16;

    if (FAILED(pDirect3D -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
                                                               D3DCREATE_SOFTWARE_VERTEXPROCESSING, &Direct3DParameter, &pDirect3DDevice)))
        return E_FAIL;
    pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, false);
    // Включаем z-буфер
    pDirect3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    return S_OK;
}
// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
    if (pDirect3DDevice == NULL)
       return;
    // Очистка z-буфера
    pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET |  D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(172, 221, 101), 1.0f, 0);

    pDirect3DDevice->BeginScene();
 
    Matrix();
    DrawMyMesh();

    pDirect3DDevice->EndScene();

    pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
}
// Функция освобождения захваченных ресурсов
void DeleteDirect3D(void)
{
    if (pDirect3DDevice != NULL)
        pDirect3DDevice->Release();
    if (pDirect3D != NULL)
        pDirect3D->Release();
    if (pMeshMaterial != NULL)
        delete [] pMeshMaterial;
    if (pMeshTexture)
    {
        for(DWORD i = 0; i < dwNumber; i++)
        {
            if (pMeshTexture[i])
               pMeshTexture[i]->Release();
        }
        delete [] pMeshTexture;
    }
    if (pMesh != NULL)
        pMesh->Release();
}
// Функция инициализации объекта (буфера и индексов вершин)
HRESULT InitMesh(void)
{
    if (FAILED(D3DXLoadMeshFromX("Tiger.x", D3DXMESH_SYSTEMMEM, pDirect3DDevice, NULL, &pMeshBuffer, NULL, &dwNumber, &pMesh)))
  return E_FAIL;

// Извлекаем свойства материала и названия{имена} структуры
    D3DXMATERIAL *D3DXMeshMaterial = (D3DXMATERIAL *)pMeshBuffer->GetBufferPointer();
    pMeshMaterial = new D3DMATERIAL9[dwNumber];
    pMeshTexture   = new LPDIRECT3DTEXTURE9[dwNumber];
    for (DWORD i = 0; i < dwNumber; i++)
    {
        // Копируем материал
        pMeshMaterial[i] = D3DXMeshMaterial[i].MatD3D;
        // Установить окружающего свет
        pMeshMaterial[i].Ambient = pMeshMaterial[i].Diffuse;
        // Загружаем текстуру
        if ( FAILED(D3DXCreateTextureFromFile(pDirect3DDevice, D3DXMeshMaterial[i].pTextureFilename, &pMeshTexture[i])))
           pMeshTexture[i] = NULL;
    }
    // Уничтожаем буфер материала
    pMeshBuffer->Release();

    return S_OK;
}
// Рисует созданную mesh
void DrawMyMesh(void)
{
     for (DWORD i = 0; i < dwNumber; i++)
     {
         // Устанавливаем материал и текстуру
         pDirect3DDevice->SetMaterial(&pMeshMaterial[i]);
         pDirect3DDevice->SetTexture(0, pMeshTexture[i]);
         // Рисуем Меш
         pMesh->DrawSubset(i);
     }
}
// Установка матриц преобоазования
void Matrix(void)
{
    // Матрица вида
    D3DXMATRIX MatrixView;
    //матрица проекции
    D3DXMATRIX MatrixProjection;
    D3DXMATRIX MatrixWorld;
    D3DXMATRIX MatrixTranslation;
    D3DXMATRIX MatrixRotation;

    float BeginAngle;
    float rps;
    UINT iTime;
    float fAngle;

    BeginAngle = D3DX_PI/4.0f;
    rps = 0.5f;
    iTime = GetTickCount();

    if(!OneTick)
        OneTick = iTime;
    fAngle = BeginAngle + (iTime -  OneTick) * (D3DX_PI * 2.0f * rps / 1000.0f);
    
    D3DXMatrixRotationY(&MatrixRotation, fAngle);                                      // поворот тигра
    D3DXMatrixTranslation(&MatrixTranslation, 0.0f, 0.0f, 0.0f);                       // положение тигра
    D3DXMatrixMultiply(&MatrixWorld, &MatrixRotation, &MatrixTranslation);
    pDirect3DDevice->SetTransform(D3DTS_WORLD, &MatrixWorld);

    // Изменяем видовую матрицу
    D3DXMatrixLookAtLH(&MatrixView,      // полученная в итоге видовая матрица
        &D3DXVECTOR3(0.0f, 0.0f, 10.0f),   // точка, из которой смотрим
        &D3DXVECTOR3(0.0f, 0.0f, 0.0f),     // куда смотрим
        &D3DXVECTOR3(0.0f, 1.0f, 0.0f));   // направление верха
    // Устанавливаем видовую матрицу
    pDirect3DDevice->SetTransform(D3DTS_VIEW, &MatrixView);
    // Изменяем матрицу проекции
    D3DXMatrixPerspectiveFovLH(&MatrixProjection, // полученная итоговая матрица проекции
        D3DX_PI/4,                                                      // поле зрения в направлении оси Y в радианах
        1.54f,                                                               // соотношения сторон экрана 770/500=1.54
        10.0f,                                                               // передний план отсечения сцены
        200.0f);                                                           // задний план отсечения сцены
    // Устанавливаем матрицу проекции
    pDirect3DDevice->SetTransform(D3DTS_PROJECTION, &MatrixProjection);
}

Пример:


* loadxfile.rar (40.93 Кб - загружено 1089 раз.)
« Последнее редактирование: 23-06-2009 02:50 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 23-06-2009 07:44 » 

Offtopic:

центробежная сила Улыбаюсь
Поставлю в угол.


а может экран проекции слишком близко к тигру ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #2 : 23-06-2009 07:50 » new

Цитата: Алексей1153++
а может экран проекции слишком близко к тигру?

То есть Вы советуете попробавать увеличить значение точки из которой смотрим в матрицы вида?
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #3 : 23-06-2009 07:57 » 

Спасибо, большое Алексей1153++!!!

Всё заработала в матрице вида  значение точки из которой смотрим в место 10 поставил 20, тигр стал более удалён, но теперь он нормально отображается.

Пример:



Теперь буду переходить к изучению камеры.
« Последнее редактирование: 23-06-2009 08:01 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 23-06-2009 08:10 » 

zuze, не надо никаких Вы , надо на ты Ага

можно было просто отодвинуть тигру дальше, а точку зрения и экран проекции обычно не передвигают по 100 раз (разве что для создания эффекта искажённого восприятия мира)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #5 : 23-06-2009 19:34 » 

Я тебя понял Алексей1153++

В матрице вида значение точки из которой смотрим не трогую, за то изменяю это

Код:
D3DXMatrixTranslation(&MatrixTranslation, 0.0f, 0.0f, 0.0f); 


на это

Код:
D3DXMatrixTranslation(&MatrixTranslation, 0.0f, 0.0f, -5.0f); 

Всё работает, вот пример:



Хотел спросить, а если у сцены много объектов как выбирается в матрице вида значение точки из которой смотрим?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 24-06-2009 03:12 » 

я думаю, просто достаточно отъехать от сцены или покрутиться на месте - тогда увидишь всё Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #7 : 24-06-2009 07:06 » 

Понял твой совет Алексей1153++, как раз дальше я буду изучать камеру.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines