我的环境是win7+Qt5.1
之前在网上找了一些例子, 怎么调试都不出来. 原来是窗口属性的问题.
解决方法:
网上的例子: setAttribute(Qt::WA_PaintOnScreen, true);
Note: This flag is only supported on X11 and it disables double buffering.
看文档发现这个属性只能用于X11环境.
修改为:
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground, true);
具体代码如下:
D3DWidget.h
#ifndef QD3DWIDGET_H
#define QD3DWIDGET_H
#include <QWidget>
#include <d3d9.h>
#include <d3dx9.h>
extern LPDIRECT3D9 g_pD3D;
extern LPDIRECT3DDEVICE9 g_pDevice;
extern LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer;
extern LPDIRECT3DINDEXBUFFER9 g_pIndexBuffer;
HRESULT Init3D(HWND hWnd);
struct CUSTOMVERTEX
{
	float x,y,z;
	DWORD color;
};
#define D3DFVF_CUSTOMVERTEXT (D3DFVF_XYZ|D3DFVF_DIFFUSE)
class QD3DWidget : public QWidget
{
	Q_OBJECT
public:
	QD3DWidget(QWidget *parent = NULL);
	~QD3DWidget();
	//reimplement paintEngine 
	QPaintEngine *paintEngine()const;
protected:
	void paintEvent(QPaintEvent *ev);
	virtual void initialize3D();
	virtual void paintD3D();
	virtual bool initGemetry();
	virtual void d3dInit();
	virtual void d3dDraw();
	virtual void render();
public:
	bool initialized()const{
		return fInit;
	}
public slots:
	void rotateTriangle();
private:
	void setupMatrices();
private:
	bool fInit;
	int fRotateY;
};
#endif // QD3DWIDGET_H
 
D3DWidget.cpp
#include "QD3DWidget.h"
#include "D3D9.h"
#include <QTimer>
#include <QMessageBox>
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;
LPDIRECT3DINDEXBUFFER9 g_pIndexBuffeer = NULL;
HRESULT Init3D(HWND hWnd)
{
	//create d3d object 
	if(NULL ==(g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
		return E_FAIL;
	//set up the structure used to create the D3DDevice 
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp , sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;//
	//create the d3ddevice 
	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pDevice)))
		return E_FAIL;
	//turn off culling , so we can see the front and back of the triangle 
	g_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
	//turn off d3d lighting , since we are prodving our own vertex colors 
	g_pDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
	g_pDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE,TRUE);
	g_pDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);
	return S_OK;
}
QD3DWidget::QD3DWidget(QWidget *parent)
	: QWidget(parent)
	, fInit(false)
	, fRotateY(0)
{
	setFixedSize(400,400);
	setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
	setAttribute(Qt::WA_TranslucentBackground, true);
}
QD3DWidget::~QD3DWidget()
{
	g_pIndexBuffeer->Release();
	g_pVertexBuffer->Release();
	g_pDevice->Release();
	g_pD3D->Release();
}
QPaintEngine * QD3DWidget::paintEngine()const
{
	return NULL;
}
void QD3DWidget::initialize3D()
{
	Init3D((HWND)winId());
	initGemetry();
	fInit = true;
}
void QD3DWidget::paintD3D()
{
	render();
}
void QD3DWidget::paintEvent(QPaintEvent *ev)
{
	if(updatesEnabled()){
		d3dDraw();
	}
}
void QD3DWidget::d3dInit()
{
	initialize3D();
}
void QD3DWidget::d3dDraw()
{
	if(!initialized()){
		d3dInit();
	}
	paintD3D();
}
void QD3DWidget::render()
{
	g_pDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(255,0,255),1.0f,0);
	g_pDevice->BeginScene();
	setupMatrices();
	//set fvf 
	g_pDevice->SetFVF(D3DFVF_CUSTOMVERTEXT);
	//bind vertex buffer data to device source data 
	g_pDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX));
	//draw 
	//g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
	g_pDevice->SetIndices(g_pIndexBuffeer);
	g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,4);
	g_pDevice->EndScene();
	g_pDevice->Present(NULL,NULL,NULL,NULL);
}
bool QD3DWidget::initGemetry()
{
	// 平面三角形原形
	//CUSTOMVERTEX vertices[] = {
	//    {
	//        -1.0f,-1.0f,0.0f,D3DCOLOR_XRGB(255,0,0)//red 
	//    },
	//    {
	//        0.0f,1.0f,0.0f,D3DCOLOR_XRGB(0,255,0)//green
	//    },
	//    {
	//        1.0f,-1.0f,0.0f,D3DCOLOR_XRGB(0,0,255)//blue
	//    }
	//};
	// 立体三角形原形
	CUSTOMVERTEX vertices[] = {
		{0.0f,1.0f,0.0f,D3DCOLOR_XRGB(0,255,0)},
		{-1.0f,-1.0f,-0.577f,D3DCOLOR_XRGB(255,0,0)},
		{1.0f,-1.0f,-0.577f,D3DCOLOR_XRGB(0,255,255)},
		{0.0f,-1.0f,1.155f,D3DCOLOR_XRGB(0,0,255)}
	};
	WORD indices[] ={0,2,1,0,3,2,0,1,3,1,2,3};
	//create vertex buffer 
	if(FAILED(g_pDevice->CreateVertexBuffer(sizeof(vertices),0,D3DFVF_CUSTOMVERTEXT,D3DPOOL_DEFAULT,&g_pVertexBuffer,NULL)))
		return false;
	//store the vertex data into buffer 
	void *pVertices;
	g_pVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0);
	memcpy(pVertices,vertices,sizeof(vertices));
	g_pVertexBuffer->Unlock();
	//create index buffer 
	g_pDevice->CreateIndexBuffer(sizeof(indices),0,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&g_pIndexBuffeer,NULL);
	//store the index data 
	void *pIndices;
	g_pIndexBuffeer->Lock(0,sizeof(indices),(void**)&pIndices,0);
	memcpy(pIndices,indices,sizeof(indices));
	g_pIndexBuffeer->Unlock();
	return true;
}
void QD3DWidget::setupMatrices()
{
	float angle = fRotateY *D3DX_PI/180;
	D3DXMATRIX matWorld;
	D3DXMatrixRotationY(&matWorld,angle);
	//set the world matrix 
	g_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
	D3DXVECTOR3 eye(0.0f,3.0f,-5.0f);
	D3DXVECTOR3 lookat(0.0f,0.0f,0.0f);
	D3DXVECTOR3 up(0.0f,1.0f,0.0f);
	D3DXMATRIX matView;
	//calculate the view matrix 
	D3DXMatrixLookAtLH(&matView,&eye,&lookat,&up);
	g_pDevice->SetTransform(D3DTS_VIEW,&matView);
	//perspective matrix 
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
	g_pDevice->SetTransform(D3DTS_PROJECTION,&matProj);
}
void QD3DWidget::rotateTriangle()
{
	fRotateY+=2;
	if(fRotateY>360)
		fRotateY=0;
	update();
}
 
QTestWidget.h
#ifndef QTESTWIDGET_H
#define QTESTWIDGET_H
#include <QWidget>
#include <QtCore>
#include "qd3dwidget.h"
class QTestWidget : public QWidget
{
	Q_OBJECT
public:
	QTestWidget(QWidget *parent=NULL);
	~QTestWidget();
	public slots:
		void startRotate();
		void endRotate();
private:
	QD3DWidget * fD3DWidget;
	QTimer fTimer;
};
#endif // QTESTWIDGET_H
 
QTestWidget.cpp
#include "QTestWidget.h"
#include <QPushButton>
#include <QGridLayout>
QTestWidget::QTestWidget(QWidget *parent)
	: QWidget(parent)
	,fTimer(this)
{
	fD3DWidget = new QD3DWidget(this);
	QGridLayout *layout = new QGridLayout(this);
	layout->addWidget(fD3DWidget,0,0,1,2);
	QPushButton *rotateBt = new QPushButton("start rotate");
	QPushButton *endBt = new QPushButton("end rotate");
	layout->addWidget(rotateBt,1,0);
	layout->addWidget(endBt,1,1);
	connect(rotateBt,SIGNAL(clicked()),this,SLOT(startRotate()));
	connect(endBt,SIGNAL(clicked()),this,SLOT(endRotate()));
	connect(&fTimer,SIGNAL(timeout()),fD3DWidget,SLOT(rotateTriangle()));
	layout->setContentsMargins(0,0,0,0);
	layout->setSpacing(0);
}
QTestWidget::~QTestWidget()
{
}
void QTestWidget::startRotate()
{
	fTimer.start(10);
}
void QTestWidget::endRotate()
{
	fTimer.stop();
}
 
main.cpp
#include "testqq.h"
#include <QtWidgets/QApplication>
#include "QTestWidget.h"
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	QTestWidget w;
	w.show();
	return a.exec();
}
 
Link的时候, 添加这几个库:
d3d9.lib
d3dx9.lib
winmm.lib
                  
                  
                  
                  
                            
本文介绍了在使用Qt5.1和D3DWidget进行3D图形渲染时遇到窗口属性问题的解决方法。通过将窗口属性设置为Qt::WindowStaysOnTopHint和Qt::FramelessWindowHint,并启用透明背景,成功解决了在非X11环境下的渲染问题。
          
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
					1221
					
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            