Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ID3DXFont::DrawText после сброса устройства, Ошибка доступа на запись в память 
V
    Опции темы
EgoBrain
Дата 21.5.2013, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



Здравствуйте. Собственно требуется предпринять какие-то действия к объекту ID3DXFont после сброса устройства, так как метод DrawText вызывает исключение. Что нужно делать и почему я не знаю..
Код

...
ID3DXFont* g_font = NULL;
RECT font_rect;

...
D3DXCreateFont(iDevice, 22, 7, FW_NORMAL, 1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Arial", &g_font);
SetRect(&font_rect, 0, 0, 1024, 300);

...
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
iDevice->BeginScene();

if(g_font) //--После сброса устройства, условие истино--
 g_font->DrawText(NULL,  "tro lo lo", -1, &font_rect, DT_LEFT|DT_NOCLIP,  0xFF000000); //--Студия указывает на эту строку--

iDevice->EndScene();
iDevice->Present(0, 0, 0, 0);


На всякий случай тект ошибки (хотя что он даст...):
Цитата

Unhandled exception at 0x0f8cb1fc in program.exe: 0xC0000005: Access violation writing location 0x0000f420.


Это сообщение отредактировал(а) EgoBrain - 21.5.2013, 08:40
PM MAIL ICQ Skype   Вверх
Bitter
Дата 23.5.2013, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 1
Всего: 27



Уф давно уже не мучал директ, но если мне не изменяет память, то после сброса нужно пересоздать вообще все объекты, в том числе и iDevice, а следом за ним и g_font. Вы так и делаете?
Access violation всего лишь означает что вы обратились к объекту, который больше не существует или существует уже в другом месте. Так что нужно заново создать и проинициализировать все объекты после сброса.
PM MAIL ICQ Skype   Вверх
EgoBrain
Дата 24.5.2013, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



Дело в том что я плохо знаком с членами ID3DXFont, но вроде как многие интерфейсы Direct3D включают в себя автоматизированные средства (или просто стандартные обработчики событий) для штатных ситуаций типа сброса/потери устройства. Устройство пересоздавать не нужно после сброса (IDirect3DDevice9::Reset).
Пересоздание - решение в лоб, но не вижу в нём ничего плохого, нужно попробовать..

Добавлено через 6 минут и 34 секунды
Цитата(Bitter @  23.5.2013,  09:21 Найти цитируемый пост)
Access violation всего лишь означает что вы обратились к объекту, который больше не существует или существует уже в другом месте.

Как проверить доступность этого объекта?
PM MAIL ICQ Skype   Вверх
EgoBrain
Дата 24.5.2013, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



Немного доработал код, и вроде помогло, но почему то чайник перестал отображаться. Все равно непокидает чувство что что-то не так, не доведено до ума..
Код

...
D3DPRESENT_PARAMETERS d3dpp;
ID3DXFont* g_font = NULL;
RECT font_rect;
...
void Setup()
{
   D3DXCreateFont(iDevice, 22, 7, FW_NORMAL, 1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Arial", &g_font);
   SetRect(&font_rect, 0, 0, 1024, 300);
}
...
//--Сброс устройства при нажатии клавиши--
g_font->Release(); //--Удалить объект--
g_font = NULL;  //--Занулить указатель--
iDevice->Reset(&d3dpp);  //--Сбросить устройство--        

Setup();  //--Создать объект--
//---------------------------------------------------------
...
//--в цикле обрабтки сообщения окна -------------------------------------------------------------
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
iDevice->BeginScene();
if(g_font) //--После сброса устройства, условие истино--
 g_font->DrawText(NULL,  "tro lo lo", -1, &font_rect, DT_LEFT|DT_NOCLIP,  0xFF000000);
iDevice->EndScene();
iDevice->Present(0, 0, 0, 0);
//--------------------------------------------------------------------------------------------------------------
...


Есть статья msdn касательно потери устройства (Reset() инициирует потерю), есть перевод.
Но все же не понятно что за методы OnLostDevice и OnResetDevice, когда их вызывать.. 
PM MAIL ICQ Skype   Вверх
Bitter
Дата 24.5.2013, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 1
Всего: 27



Цитата(EgoBrain @  24.5.2013,  01:10 Найти цитируемый пост)
Как проверить доступность этого объекта?

К сожалению никак, разве что отлавливать исключение типа try...catch и по нему судить, но это костыль.

В 9м директе потеря устройства происходит, например, при переключении разрешения экрана. В этом случае пересоздавать устройство ОБЯЗАТЕЛЬНО. Кроме того при использовании Reset, точнее перед его использованием, вы ОБЯЗАНЫ удалить все буферы вершин, цепочки состояний, и тд и создать все это заново. Это обязательно, потому что при выполнении Reset, происходит утрата всех текстур, всех данных о вершинах в видеопамяти, а так же всех настроек рендера. 

Я не вижу этого у вас в коде, отсюда и ваши ошибки
PM MAIL ICQ Skype   Вверх
kurlyak
Дата 11.6.2013, 00:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 7.11.2007

Репутация: 1
Всего: 3



От шо мне нравиться- все по- облому разобраться в проблеме. Лишь бы вставить свои 5 копеек.

Процедура рендеринга:

Код

void CMyApp::RenderScene()
{

    if( isDeviceLost() ) return;
.....


Код

bool CMyApp::isDeviceLost()
{
    
    HRESULT hr = p_d3d_Device->TestCooperativeLevel();

    if( hr == D3DERR_DEVICELOST )
    {
        Sleep(20);
        return true;
    }
    
    else if( hr == D3DERR_DRIVERINTERNALERROR )
    {
        MessageBox(0, "Internal Driver Error...Exiting", 0, 0);
        PostQuitMessage(0);
        return true;
    }
    
    else if( hr == D3DERR_DEVICENOTRESET )
    {
        onLostDevice();
        if(FAILED(p_d3d_Device->Reset(&d3dpp))) return false;
        onResetDevice();
        return false;
    }
    else
        return false;
}




Код

void CMyApp::onLostDevice()
{
    if(FAILED(pFont->OnLostDevice())) return;
}

void CMyApp::onResetDevice()
{
    if(FAILED(pFont->OnResetDevice())) return;

....


А при переключении- из Lost или Reset Device:

Код

void CMyApp::enableFullScreenMode(bool enable)
{
....
onLostDevice();
p_d3d_Device->Reset(&d3dpp);
onResetDevice();
....

PM MAIL   Вверх
EgoBrain
Дата 11.6.2013, 04:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



kurlyak, то есть пересоздавать ресурсы не нужно?

Цитата

if( hr == D3DERR_DEVICELOST )
    {
        Sleep(20);
        return true;
    }

Зачем тормозить поток? оО

onLostDevice и onResetDevice до и после ресета устройства вызывать только при переключении в фулскрин, а если я сглаживание или разрешение хочу поменять?
З.Ы. Просто из приведенного кода все равно не понятно как он поможет не терять ресурс pFont... Может я просто pFont->OnLostDevice()/OnResetDevice() не в том месте и не в то время вызывал...

Добавлено @ 04:45
А, и еще вопрос, хорошо ли постить сообщения окну для выхода в функции проверки устройства, может лучше ее результат получить из вызывающего блока и вдругом месте принимать решение...?

Добавлено позже
Кроме ID3DXFont у меня еще ID3DXMesh объект есть, он почему то после сброса не рисуется, даже после пересоздания (использовал тот же самый указатель).

Это сообщение отредактировал(а) EgoBrain - 11.6.2013, 07:59
PM MAIL ICQ Skype   Вверх
EgoBrain
Дата 13.6.2013, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

Репутация: нет
Всего: 2



Mesh пересоздавать не требуется. Моя ошибка был в том, что я матрицу проекции не переустанавливал из-за чего не видно было сетку.
Устройство сброшено, значит сбросились все рендерстейты.
Но все равно некоторые вопросы и непонятки остаются. Хотелось бы полноценной статьи по вопросу сброса/потери smile
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.0481 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.