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

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

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


« Ответ #60 : 19-03-2009 11:32 » 

Может надо отдельно делать функции для создания текста, вывода текста и освобождение памяти?

А вот и кодх

* text2.cpp (15.05 Кб - загружено 1043 раз.)
Записан
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #61 : 19-03-2009 17:07 » 

Матрицы надо устанавливать. Хотя бы мировую.
Код:
	 D3DXMATRIXA16 world, tr, rotX, rotY;
D3DXMatrixRotationX(&rotX, 0);
D3DXMatrixRotationY(&rotY, 0);
D3DXMatrixTranslation(&tr, -1.0,0.0,0.0);
world = tr * rotX * rotY;
pDirect3DDevice->SetTransform(D3DTS_WORLD, &world);
Цитата
Может надо отдельно делать функции для создания текста, вывода текста и освобождение памяти?
Для создания - стоит. А про удаление пока забудь:). Оно тебе не скоро понадобится.
При выходе из программы всё прекрасно освобождается и удаляется.
Записан
zuze
Опытный

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


« Ответ #62 : 19-03-2009 23:36 » 

Я так понял текст выезжает за экран из-за того что я не задал структуру которая задаёт прямоугольник в который выводится текст.

Я ещё раз переписал функцию для создания шрифта и вывода текста на экран

Код: (C++)
void MyTextOut(char *TextString, long x1, long y1, long x2, long y2, D3DCOLOR TextColor)
{  
     // Переменная, которая будет задавать область вывода на экран
     RECT myRect;
     // Получение дескриптора контекста устройства
     HDC hdc = CreateCompatibleDC(0);
   
       
     HFONT hFont;    // Дескриптор нового шрифта
     HFONT hFontOld; // Дескриптор старого шрифта
     LPD3DXFONT pFont = NULL;

     hFont = CreateFont(0, 0, 0, 0, FW_NORMAL, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"));

     // Делаем данный шрифт текущим шрифтом
     hFontOld = (HFONT)SelectObject(hdc, hFont);

     // Указател на Меш
     LPD3DXMESH Text = NULL;
     // Создание трехмерной сетки, представляющую строку текста
     D3DXCreateText(pDirect3DDevice, hdc, TextString, 0.001f, 0.4f, &Text, NULL, NULL);

     // координаты прямоугольнка
     myRect.left   = x1;
     myRect.top    = y1;
     myRect.right  = x2;
     myRect.bottom = y2;
     // Вывод текста
     pFont->DrawText(NULL, TextString, -1, &myRect, DT_CENTER, TextColor);

     // Восстанавление бывшего до этого шрифта
     SelectObject(hdc, hFontOld);
     // Освобождение памяти указателя на шрифт
     DeleteObject(hFont);
     // Освобождение памяти дискриптора контекста устройства
     DeleteDC(hdc);
     // Освобождение памяти указателя на меш
     if (Text != NULL)
       Text->Release();
    if (pFont != NULL)
       pFont->Release();
}

Эту функцию вызываю в функции рендеринга так

Код: (C++)
MyTextOut(TEXT("Hello"), 10, 10, 800, 800, D3DCOLOR_ARGB(150,0,150,14));

Компилируется без ошибок, но при запуске программы выскакивает окно Ошибка приложения с двумя кнопками ОК и Отмена и с текстом Инструкция по адресу "0x0040140a" обратилась к памяти по адресу "0x00000000". Память не может быть "read".
"ОК" -- завершение приложения
"Отмена" -- отладка приложения


Что же я не так сделал?

Помогите пожалуйста разобраться.
Записан
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #63 : 20-03-2009 07:48 » 

Что такое "TEXT("Hello")"?
Записан
zuze
Опытный

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


« Ответ #64 : 20-03-2009 07:52 » 

"TEXT("Hello")" - это приобоазование типа, но это не нужно можно так "Hello".
Записан
zuze
Опытный

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


« Ответ #65 : 20-03-2009 07:59 » 

Мне кажется ошибка из-за того что я в функции D3DXCreateText строку в mesh-е закидываю, а не pFont, следовательно pFont равен NULL и из за этого нельзя использовать строку
Код:
pFont->DrawText(NULL, TextString, -1, &myRect, DT_CENTER, TextColor);
а можно через mesh
Код:
Text->DrawSubset(0);
но к сожалению так я сделать не могу так как мне надо выводить текст определённого цвета и в координатак описанных экземпляром структуры RECT.

Что посоветуете для такого вывода?
« Последнее редактирование: 20-03-2009 08:02 от zuze » Записан
zuze
Опытный

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


« Ответ #66 : 20-03-2009 08:04 » 

Задать цвет это легко
Код:
SetTextColor(hdc, RGB(255,0,255));

А вот функцию для задания вывода текста в координатах заданными экземпляром структуры RECT я не знаю, если бы я знал тогда можно воспользоватся функцией вывода
Код:
Text->DrawSubset(0);

Записан
zuze
Опытный

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


« Ответ #67 : 21-03-2009 15:43 » 

Я попытался сделать вывод 3D-текста с помощью Mesh.
Смотрел в пример Text3D из DirectX 9.0c нояборь 2008, но этот пример немного усложнён, но всётаки часть кода я из этого примера смог понять и взять в свой код.

Вот то, что я сделал, но почему-то 3D-текст не выводится

Код:
// Глобальная переменная
LPD3DXMESH Text3DMesh = NULL;
void RenderingDirect3D(void)
{
     ...
     ...
     ...
     // Создание шрифта
     CreateD3DXTextMesh("Hello", Text3DMesh);
     // Вывод текста
     if (Text3DMesh != NULL)
    Text3DMesh->DrawSubset(0);
     ...
     ...
     ...
}
HRESULT CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh)

     HRESULT Net3DText;
     HFONT hFont;   // Дескриптор нового шрифта
     HFONT hFontOld;    // Дескриптор старого шрифта
     HDC hdc;
     LPD3DXMESH Text3DMeshNew = NULL; // Указател на Меш

     // Получение дескриптора контекста устройства
     hdc = CreateCompatibleDC(0);
   
     // Создание шрифта     
     hFont = CreateFont(0, 0, 0, 0, FW_NORMAL, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH |
                        FF_DONTCARE, TEXT("Times New Roman"));

     // Делаем данный шрифт текущим шрифтом
     hFontOld = (HFONT)SelectObject(hdc, hFont);
     
     // Создание трехмерной сетки, представляющую строку текста
     Net3DText = D3DXCreateText(pDirect3DDevice, hdc, TextString, 0.001f, 0.4f, &Text3DMeshNew, NULL, NULL);

     // Восстанавление бывшего до этого шрифта
     SelectObject(hdc, hFontOld);
     // Освобождение памяти указателя на шрифт
     DeleteObject(hFont);
     // Освобождение памяти дискриптора контекста устройства
     DeleteDC(hdc);
 
     if (SUCCEEDED(Net3DText))
        pMesh = Text3DMeshNew;
     
     return Net3DText;
}

Помогите пожалуйста понять, где я ошибся?
Записан
zuze
Опытный

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


« Ответ #68 : 11-06-2009 03:36 » 

В коде из ответа #67 в результате работы программы выводится пустое окно.

Для лучшего понимания привиду полный код, а не урезанный как в ответе #67

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

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

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVertices = NULL;
LPDIRECT3DINDEXBUFFER9 pBufferIndexes = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVertices1 = NULL;
LPDIRECT3DINDEXBUFFER9 pBufferIndexes1 = NULL;
LPD3DXFONT pFont = NULL; // указатель на интефейс, отвечающий за работу со шрифтом
LPD3DXMESH Text3DMesh = NULL;

#define D3DFVF_TRIANGLEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

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);
// Функция создания шрифта с помощью Mesh - прототип
HRESULT CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh);

// Функция которая является входной точкой приложения
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", "Вывод 3D текста", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    if (SUCCEEDED(InitDirect3D(hwnd)))
    {
       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_CULLMODE, D3DCULL_NONE);
    pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    // Включаем z-буфер
    pDirect3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
    return S_OK;
}
// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
    if (pDirect3DDevice == NULL)
        return;

    pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET |  D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(172, 221, 101), 1.0f, 0);

    pDirect3DDevice->BeginScene();

    // Создание шрифта
    CreateD3DXTextMesh("Hello", Text3DMesh);
    // Вывод текста
    if (Text3DMesh != NULL)
       Text3DMesh->DrawSubset(0);

    pDirect3DDevice->EndScene();

    pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
}
// Функция освобождения захваченных ресурсов
void DeleteDirect3D(void)
{
    if (pFont != NULL)
        pFont->Release();
    if (pBufferVertices != NULL)
        pBufferVertices->Release();
    if (pBufferIndexes != NULL)
        pBufferIndexes->Release();
    if (pDirect3DDevice != NULL)
        pDirect3DDevice->Release();
    if (pDirect3D != NULL)
        pDirect3D->Release();
    if (Text3DMesh != NULL)
      Text3DMesh->Release();
}
// Функция создания шрифта с помощью Mesh
HRESULT CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh)

     HRESULT Net3DText;
     HFONT hFont;   // Дескриптор нового шрифта
     HFONT hFontOld;    // Дескриптор старого шрифта
     HDC hdc;
     LPD3DXMESH Text3DMeshNew = NULL; // Указател на Меш
     //D3DXMATERIAL *D3DXMeshMaterial = NULL;

     // Получение дескриптора контекста устройства
     hdc = CreateCompatibleDC(0);
   
     // Создание шрифта     
     hFont = CreateFont(0, 0, 0, 0, FW_NORMAL, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, 
                                     DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"));

     // Делаем данный шрифт текущим шрифтом
     hFontOld = (HFONT)SelectObject(hdc, hFont);
     
     // Создание трехмерной сетки, представляющую строку текста
     Net3DText = D3DXCreateText(pDirect3DDevice, hdc, TextString, 0.001f, 0.4f, &Text3DMeshNew, NULL, NULL);

     // Восстанавление бывшего до этого шрифта
     SelectObject(hdc, hFontOld);
     // Освобождение памяти указателя на шрифт
     DeleteObject(hFont);
     // Освобождение памяти дискриптора контекста устройства
     DeleteDC(hdc);
 
     if (SUCCEEDED(Net3DText))
        pMesh = Text3DMeshNew;
     
     return Net3DText;
}

Я так понял код не выводит текст так как я не задал материал для mesh.

Я попытался задать материал для Mesh вот код

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

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

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVertices = NULL;
LPDIRECT3DINDEXBUFFER9 pBufferIndexes = NULL;
LPDIRECT3DVERTEXBUFFER9 pBufferVertices1 = NULL;
LPDIRECT3DINDEXBUFFER9 pBufferIndexes1 = NULL;
LPD3DXFONT pFont = NULL; // указатель на интефейс, отвечающий за работу со шрифтом
LPD3DXMESH Text3DMesh = NULL;
LPD3DXBUFFER pMeshMaterialBuffer = NULL; // буфер для материала
D3DMATERIAL9 *pMeshMaterial = NULL;

#define D3DFVF_TRIANGLEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

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);
// Функция создания шрифта с помощью Mesh - прототип
HRESULT CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh);

// Функция которая является входной точкой приложения
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", "Вывод 3D текста", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    if (SUCCEEDED(InitDirect3D(hwnd)))
    {
       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_CULLMODE, D3DCULL_NONE);
    pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    // Включаем z-буфер
    pDirect3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
    return S_OK;
}
// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
    if (pDirect3DDevice == NULL)
        return;

    pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET |  D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(172, 221, 101), 1.0f, 0);

    pDirect3DDevice->BeginScene();

    // Создание шрифта
    CreateD3DXTextMesh("Hello", Text3DMesh);
    // Вывод текста
    if (Text3DMesh != NULL)
    {
       pDirect3DDevice->SetMaterial(&pMeshMaterial[0]);
       Text3DMesh->DrawSubset(0);
    }

    pDirect3DDevice->EndScene();

    pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
}
// Функция освобождения захваченных ресурсов
void DeleteDirect3D(void)
{
    if (pFont != NULL)
      pFont->Release();
    if (pBufferVertices != NULL)
        pBufferVertices->Release();
    if (pBufferIndexes != NULL)
        pBufferIndexes->Release();
    if (pDirect3DDevice != NULL)
        pDirect3DDevice->Release();
    if (pDirect3D != NULL)
        pDirect3D->Release();
    if (Text3DMesh != NULL)
        Text3DMesh->Release();
    if (pMeshMaterialBuffer != NULL)
        pMeshMaterialBuffer->Release();
    if (pMeshMaterial != NULL)
        pMeshMaterial = NULL;
}
// Функция создания шрифта с помощью Mesh
HRESULT CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh)

     HRESULT Net3DText;
     HFONT hFont;   // Дескриптор нового шрифта
     HFONT hFontOld;    // Дескриптор старого шрифта
     HDC hdc;
     LPD3DXMESH Text3DMeshNew = NULL; // Указател на Меш
     D3DXMATERIAL *D3DXMeshMaterial = NULL;

     // Получение дескриптора контекста устройства
     hdc = CreateCompatibleDC(0);
   
     // Создание шрифта     
     hFont = CreateFont(0, 0, 0, 0, FW_NORMAL, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
                                      DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"));

     // Делаем данный шрифт текущим шрифтом
     hFontOld = (HFONT)SelectObject(hdc, hFont);
     
     // Создание трехмерной сетки, представляющую строку текста
     Net3DText = D3DXCreateText(pDirect3DDevice, hdc, TextString, 0.001f, 0.4f, &Text3DMeshNew, NULL, NULL);

     D3DXMeshMaterial = reinterpret_cast<D3DXMATERIAL *>(pMeshMaterialBuffer->GetBufferPointer());
     pMeshMaterial = new D3DMATERIAL9[1];

     // Копируем материал
     pMeshMaterial[0] = D3DXMeshMaterial[0].MatD3D;

     // Фоновую составляющую делаем такой же, как и диффузную
     pMeshMaterial[0].Ambient = pMeshMaterial[0].Diffuse;

     // Восстанавление бывшего до этого шрифта
     SelectObject(hdc, hFontOld);
     // Освобождение памяти указателя на шрифт
     DeleteObject(hFont);
     // Освобождение памяти дискриптора контекста устройства
     DeleteDC(hdc);
 
     if (SUCCEEDED(Net3DText))
        pMesh = Text3DMeshNew;
     
     return Net3DText;
}

Но почему-то этот код компилируется без ошибок, а при запуске происходит ошибка такая



Почему эта ошибка происходит?

Помогите пожалуйста разобраться.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #69 : 11-06-2009 03:42 » 

zuze, ну так же ведь русским по серому написано - пытаешься по адресу 0 прочитать данные. Наверное, где то пустой указатель используешь ? В отладчике поймай место ошибки - это делается легко, без точек останова запусти в режиме отладки, а в момент ошибки выбери из диалога "повторить"
Записан

zuze
Опытный

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


« Ответ #70 : 11-06-2009 04:11 » 

Я сделал, как Вы сказали. Нажал "Отмена" и перешёл в режим отладки и запустил заново.

Кроме вот этого



Нет ничего, не понятно, на какую строчку информация указывает.
Записан
zuze
Опытный

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


« Ответ #71 : 12-06-2009 11:43 » 

Переправил на этот код

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

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

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPD3DXMESH pText3DMesh = NULL;

#define D3DFVF_TRIANGLEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

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);
// Функция создания шрифта с помощью Mesh - прототип
void CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh);

// Функция которая является входной точкой приложения
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", "Вывод 3D текста", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    if (SUCCEEDED(InitDirect3D(hwnd)))
    {
       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_CULLMODE, D3DCULL_NONE);
    pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    // Включаем z-буфер
    pDirect3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
    return S_OK;
}
// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
    if (pDirect3DDevice == NULL)
        return;

    pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET |  D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(172, 221, 101), 1.0f, 0);

    pDirect3DDevice->BeginScene();

    // Создание шрифта
    CreateD3DXTextMesh("Hello", pText3DMesh);
    // Вывод текста
    if (pText3DMesh)
       pText3DMesh->DrawSubset(0);

    pDirect3DDevice->EndScene();

    pDirect3DDevice->Present(NULL, NULL, NULL, NULL);
}
// Функция освобождения захваченных ресурсов
void DeleteDirect3D(void)
{
    if (pDirect3DDevice != NULL)
        pDirect3DDevice->Release();
    if (pDirect3D != NULL)
        pDirect3D->Release();
    if (pText3DMesh != NULL)
        pText3DMesh->Release();
}
// Функция создания шрифта с помощью Mesh
void CreateD3DXTextMesh(char *TextString, LPD3DXMESH pMesh)
{  
     HFONT hFont;   // Дескриптор нового шрифта
     HFONT hFontOld;    // Дескриптор старого шрифта
     HDC hdc;
  
     // Создание шрифта    
     hFont = CreateFont(0, 0, 0, 0, FW_NORMAL, 1, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
                                     DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"));

     // Получение дескриптора контекста устройства
     hdc = CreateCompatibleDC(NULL);

     // Делаем данный шрифт текущим шрифтом
     hFontOld = (HFONT)SelectObject(hdc, hFont);
    
     // Создание трехмерной сетки, представляющую строку текста
     D3DXCreateText(pDirect3DDevice, hdc, TextString, 0.01f, 0.4f, &pText3DMesh, NULL, NULL);

     // Восстанавление бывшего до этого шрифта
     SelectObject(hdc, hFontOld);
     // Освобождение памяти указателя на шрифт
     DeleteObject(hFont);
     // Освобождение памяти дискриптора контекста устройства
     DeleteDC(hdc);
}

Я пытаюсь вывести слово "Hello", но почему-то полностью видно букву 'H' и частично буква 'e' все остальные буквы выходят за правую грань окна программы включая кусочек от буквы 'e'.

Почему так происходит?

Ведь в примерах, не используются ни какие матрицы для сдвига текста, а текст у них весь влезает.

Помогите пожалуйста разобраться.
« Последнее редактирование: 13-06-2009 05:15 от zuze » Записан
zuze
Опытный

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


« Ответ #72 : 15-06-2009 07:55 » 

Оказывается я забыл установить матрицы мира, вида, проекции, так как Mesh это сетка.

Вот код функции в дополнении к прошлому коду

Код:
// Установка матриц преобоазования
void Matrix(void)
{
    // Матрица вида
    D3DXMATRIX MatrixView;
    //матрица проекции
    D3DXMATRIX MatrixProjection;
    D3DXMATRIX MatrixTranslation;

    D3DXMatrixTranslation(&MatrixTranslation, 0.0f, 0.0f, 0.0f);                       // положение текста
    pDirect3DDevice->SetTransform(D3DTS_WORLD, &MatrixTranslation);

    // Изменяем видовую матрицу
    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);
}

Только текст у меня почему-то выводится зеркально.

Почему текст выводится так и как это поправить?
Записан
zuze
Опытный

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


« Ответ #73 : 15-06-2009 09:16 » new

Исправил, теперь текст нормально выводится.

В функции

Код:
void Matrix(void)

в место строки

Код:
D3DXVECTOR3(0.0f, 0.0f, 10.0f)

надо написать

Код:
D3DXVECTOR3(0.0f, 0.0f, -10.0f)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #74 : 15-06-2009 10:09 » 

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

zuze
Опытный

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


« Ответ #75 : 15-06-2009 14:05 » 

Спасибо за поддержку Алексей1153++.

В коде надо ещё изменить

У меня было так

Код:
// Создание шрифта
CreateD3DXTextMesh("Hello", pText3DMesh);


А я исправил на это

Код:
if (pText3DMesh == NULL)
   // Создание шрифта
   CreateD3DXTextMesh("Hello", pText3DMesh);

Если не исправлять, то создаваться текст будет каждый раз в цикле отрисовки, а так он создаётся один раз.
« Последнее редактирование: 15-06-2009 14:08 от zuze » Записан
zuze
Опытный

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


« Ответ #76 : 15-06-2009 14:20 » 

Я же вывод текста задумывал делать с помощью Mesh, чтобы вращать его.

И по этому привожу пример, что нужно сделать, чтобы текст вращался, а для этого достаточно чуть-чуть изменить функцию void Matrix(void)

Код:
// Глобальная переменная
DWORD OneTick = 0;

// Установка матриц преобоазования
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);
   
    D3DXMatrixRotationX(&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);
}
Записан
zuze
Опытный

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


« Ответ #77 : 15-06-2009 15:45 » 

Ну и с последним вопросом разобрался как менять цвет у текста, также как и в коде с кубами, но что бы люди не лазили и не искали привиду сдесь код этой функции

Код:
// Функция установки освещения и материалов
void LightMaterial(void)
{
// Создаём материал
D3DMATERIAL9 Material;
// Создаём освещение
D3DLIGHT9 Light;
D3DXVECTOR3 VectorDir;

// Обнуляем память под материал
ZeroMemory(&Material, sizeof(D3DMATERIAL9));
            // Задаём цвета для диффузного и цвета подсветки
Material.Diffuse.r = Material.Ambient.r = 0.5f;
Material.Diffuse.g = Material.Ambient.g = 1.0f;
Material.Diffuse.b = Material.Ambient.b = 0.0f;
Material.Diffuse.a = Material.Ambient.a = 1.0f;
// Устанавливаем материал
pDirect3DDevice->SetMaterial(&Material);
// Обнуляем память под освещение
ZeroMemory(&Light, sizeof(D3DLIGHT9));
            // Тип света
Light.Type = D3DLIGHT_DIRECTIONAL;
// Количество красного в свете
Light.Diffuse.r = 1.0f;
Light.Diffuse.g = 1.0f;
Light.Diffuse.b = 1.0f;
// Максимальное расстояние действия источника света
Light.Range = 1000.0f;
// Вектор, задающий направление света
VectorDir = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

// Нормализуем вектор VectorDir и записываем в свойства
            // направления Light
D3DXVec3Normalize((D3DXVECTOR3*)&Light.Direction, &VectorDir);
// Устанавливаем свет
pDirect3DDevice->SetLight(0, &Light);
// Включаем свет с соответсвующим индексом
pDirect3DDevice->LightEnable(0, TRUE);
// Устанавливаем параметры рендеринга, включая освещение
pDirect3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
// Устанавливаем параметры рендеринга, включая окружающее
            // освещение
pDirect3DDevice->SetRenderState(D3DRS_AMBIENT, 0);
}

А вставляется эта функция для выполнения в код перед функцией Matrix();.

Всё я закончил с этим и перехажу текстурам и мультитекстурированию, а затем буду возращатся к загрузки формата X с помощью mesh, так как в них указываются текстуры.
Записан
zuze
Опытный

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


« Ответ #78 : 16-06-2009 06:41 » 

Так как всё равно каждый раз приходится сверять, то можно сделать ещё лучше.

Написать функцию такую.

Код:
// Функция инициализации объекта (в данном случае только создаёт текст)
HRESULT InitObject(void)
{
              CreateD3DXTextMesh("Hello", pText3DMesh);
              return S_OK;
}

А из функции void RenderingDirect3D(void) удалить строчки

Код:
 
if (pText3DMesh == NULL)
   CreateD3DXTextMesh("Hello", pText3DMesh);

И на последок модифицировать вот этот кусок кода из функции int WINAPI WinMain(HINSTANCE hInst,   HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)

Код:
...
...
...
if (SUCCEEDED(InitDirect3D(hwnd)))
{
   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();
   }
}
...
...
...

На этот

Код:
...
...
...
if (SUCCEEDED(InitDirect3D(hwnd)))
{
       if (SUCCEEDED(InitObject()))
       {
           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();
          }
      }
}
...
...
...
Записан
Страниц: 1 2 [3]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines