Russian Qt Forum
Ноябрь 25, 2024, 07:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Direct3D widget  (Прочитано 13812 раз)
ixSci
Гость
« : Март 31, 2009, 11:03 »

Всем привет,

Мне нужно сделать виджет внутри которога можно будет рисоват с помощью Direct3D
делаю так:
.h
Код
C++ (Qt)
class Direct3DWidget : public QWidget
{
Q_OBJECT
 
public:
Direct3DWidget(QWidget *parent = 0);
~Direct3DWidget();
 
bool InitDirect3D();
public slots:
bool Rendering();
private:
 
void paintEvent(QPaintEvent *p)
{
Rendering();
}
QPaintEngine* paintEngine()
{
return NULL;
}
 
LPDIRECT3D9 m_pD3D;
LPDIRECT3DDEVICE9 m_pd3dDevice;
};
.cpp
Код
C++ (Qt)
Direct3DWidget::Direct3DWidget(QWidget *parent /* = 0 */)
{
setFixedSize(200, 200);
setAutoFillBackground(false);
setAttribute(Qt::WA_PaintOnScreen, true);
}
Direct3DWidget::~Direct3DWidget()
{
if( m_pd3dDevice != NULL)
m_pd3dDevice->Release();
 
if( m_pD3D != NULL)
m_pD3D->Release();
}
bool Direct3DWidget::InitDirect3D()
{
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION);
if( !m_pD3D)
return false;
 
D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
HRESULT hr = m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winId(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &m_pd3dDevice );
if( FAILED(hr) || !m_pd3dDevice)
return false;
}
bool Direct3DWidget::Rendering()
{
if(m_pd3dDevice == NULL)
return false;
m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 0), 1.0f, 0);
if(SUCCEEDED(m_pd3dDevice->BeginScene()))
{
m_pd3dDevice->EndScene();
}
m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
return true;
}
 
main
Код
C++ (Qt)
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
 
QMainWindow window;
Direct3DWidget* widget = new Direct3DWidget(&window);
 
window.show();
widget->InitDirect3D();
return a.exec();
}

В результате ничего не рисуется  Злой
Кто нибудь может сказать, что не так в моем коде?
Принимаются любые советы по скрещиванию QT+Direct3D, если у кого нибудь есть готовые примеры был бы очень благодарен.
Записан
Sergeich
Гость
« Ответ #1 : Март 31, 2009, 14:49 »

Попробуй добавить аттрибут Qt::WA_MSWindowsUseDirect3D
Записан
ixSci
Гость
« Ответ #2 : Март 31, 2009, 15:26 »

не помогло
Записан
Sergeich
Гость
« Ответ #3 : Март 31, 2009, 21:50 »

Гмм... даже не знаю че сказать, я всю жисть на OpenGL всю трехмерку делал. То, что оно с кутей скрещивается - это точно. По крайней мере их PaintEngine на этом говне точно работает. Как вариант попробуй создать виджет с direct3d атрибутом и в пайнт ивенте какие-нить его команды заюзать. И лучше всего в отладчике глянь на каком движке QPainter рисует, там у пайнтера свойство engine будет. Если QRaster... - то direct3d оно не юзает. А какая кутиха, кстати?
Записан
ixSci
Гость
« Ответ #4 : Март 31, 2009, 21:55 »

Цитировать
Как вариант попробуй создать виджет с direct3d атрибутом и в пайнт ивенте какие-нить его команды заюзать
команды кого?, если директа, то я так и делаю.
Цитировать
И лучше всего в отладчике глянь на каком движке QPainter рисует, там у пайнтера свойство engine будет. Если QRaster... - то direct3d оно не юзает
попробую, спасибо
Цитировать
А какая кутиха, кстати?
4.5
Записан
ixSci
Гость
« Ответ #5 : Апрель 01, 2009, 10:35 »

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

Немного изменил код
юр
Код
C++ (Qt)
class Direct3DWidget : public QWidget
{
Q_OBJECT
public:
Direct3DWidget(QWidget *parent = 0);
~Direct3DWidget();
public slots:
bool Rendering();
public:
 
void InitDirect3D();
void paintEvent(QPaintEvent *p)
{
Rendering();
}
QPaintEngine* paintEngine()
{
return 0;
}
private:
CComPtr<IDirect3D9> m_pD3D;
CComPtr<IDirect3DDevice9> m_pd3dDevice;
};
 
.cpp
Код
C++ (Qt)
Direct3DWidget::Direct3DWidget(QWidget *parent /* = 0 */)
{
/*
setFixedSize(200, 200);
setAutoFillBackground(false);
setAttribute(Qt::WA_PaintOnScreen, true);
setAttribute(Qt::WA_MSWindowsUseDirect3D, true);
setAttribute(Qt::WA_NoSystemBackground, true);*/

 
//InitDirect3D();
}
Direct3DWidget::~Direct3DWidget()
{
}
void Direct3DWidget::InitDirect3D()
{
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION);
 
D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winId(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &m_pd3dDevice );
}
bool Direct3DWidget::Rendering()
{
if(m_pd3dDevice == 0)
return false;
m_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 0), 1.0f, 0);
if(SUCCEEDED(m_pd3dDevice->BeginScene()))
{
m_pd3dDevice->EndScene();
}
m_pd3dDevice->Present( 0, 0, 0, 0 );
return true;
}
main
Код
C++ (Qt)
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow window;
Direct3DWidget* widget = new Direct3DWidget(&window);
//widget->setMinimumSize(20, 20);
window.setAttribute(Qt::WA_PaintOnScreen);
   window.setAttribute(Qt::WA_NoSystemBackground);
window.setCentralWidget(widget);
widget->InitDirect3D();
window.show();
QTimer *timer = new QTimer();
QObject::connect(timer, SIGNAL( timeout() ), widget, SLOT( Rendering() ) );
timer->start();
 
return a.exec();
}
при таком коде отрисовка происходит нормально(экран заливает желтым цветом).
Если я убираю либо таймер, либо setCentralWidget отрисовка пропадает.
В связи с этим два вопроса:
1. Почему нет отрисовки через paintEvent, но есть вне его. В чем может быть разница?
2. Почему не отрисовывает если не является центральным виджетом? Мне бы хотелось совмещать различные виджеты, не просто иметь окно куда я могу рисовать..
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Апрель 01, 2009, 10:50 »

2. Почему не отрисовывает если не является центральным виджетом? Мне бы хотелось совмещать различные виджеты, не просто иметь окно куда я могу рисовать..

Вот примечание из ассистанта:

Цитировать
Note: Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.



Так что во всех случаях, central widget ДОЛЖЕН быть установлен
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
spirit
Гость
« Ответ #7 : Апрель 01, 2009, 10:54 »

ага, возьми, для примера, помести в лэйаут свой виджет для рендеринга при помощи direct3d и помести еще несколько других виджетов.
а вот с таймером непонятно.
Записан
ixSci
Гость
« Ответ #8 : Апрель 01, 2009, 11:45 »

так дело сдвинулось с мертвой точки Улыбающийся
Заменил основное окно с QMainWindow на Qwidget. Убрал все аттрибуты(они не влияют никак). И убрал таймер, при ресайзе происходит отрисовка виджета, но потом заливается фоном, т.е при ресайзе получается мерцание. Как можно это побороть?Улыбающийся
вот что я пробовал выставлять
Код
C++ (Qt)
/*
window.setAttribute(Qt::WA_PaintOnScreen);
window.setAttribute(Qt::WA_NoSystemBackground);
window.setAttribute(Qt::WA_MSWindowsUseDirect3D, true);
window.setAutoFillBackground(false);*/

 
Записан
spirit
Гость
« Ответ #9 : Апрель 01, 2009, 11:46 »

почитай про "Double Buffered Graphics Driver Example" в ассистанте.
Записан
ixSci
Гость
« Ответ #10 : Апрель 01, 2009, 12:05 »

у меня не просто мерцание, изображения на экране не остается. Если принцип double buffer'а в QT не отличается от других либ, то проблема не в этом.
Записан
ixSci
Гость
« Ответ #11 : Апрель 01, 2009, 13:07 »

почитал про двойную буферизацию в QT, к моей проблеме она отношения не имеет(к тому же двойная буферизация это нативная часть Direct3D). У меня получается, что после отрбаотки paintevent происходит заливка цветом фона виджета, как ее можно убрать?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #12 : Апрель 01, 2009, 13:52 »

Установка аттрибута Qt::WA_NoSystemBackground не помогает?

Цитировать
Indicates that the widget has no background, i.e. when the widget receives paint events, the background is not automatically repainted. Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled with the background (e.g., after showing a window for the first time the user can see "through" it until the application processes the paint events). This flag is set or cleared by the widget's author.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
ixSci
Гость
« Ответ #13 : Апрель 01, 2009, 14:03 »

не помогает
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #14 : Апрель 02, 2009, 10:45 »

А такой вопросец, Qt сконфигурирована с флагом -direct3d?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.181 секунд. Запросов: 23.