📄 qpaintengine_d3d.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qdebug.h>#include "qpaintengine_d3d_p.h"#include "private/qdrawhelper_p.h"#include "private/qfont_p.h"#include "private/qfontengine_p.h"#include "private/qmath_p.h"#include "private/qpaintengine_p.h"#include "private/qtessellator_p.h"#include <private/qbezier_p.h>#include <private/qpainter_p.h>#include <private/qpixmap_p.h>#include <private/qpolygonclipper_p.h>#include <qbuffer.h>#include <qcache.h>#include <qdir.h>#include <qfileinfo.h>#include <qlibrary.h>#include <qlibraryinfo.h>#include <qpaintdevice.h>#include <qpixmapcache.h>#include <d3d9.h>#include <d3dx9.h>#include <mmintrin.h>#include <xmmintrin.h>#ifndef M_PI #define M_PI 3.14159265358979323846#endif#define QD3D_MASK_MARGIN 1#define QD3D_BATCH_SIZE 256// for the ClearType detection stuff..#ifndef SPI_GETFONTSMOOTHINGTYPE#define SPI_GETFONTSMOOTHINGTYPE 0x200A#endif#ifndef FE_FONTSMOOTHINGCLEARTYPE#define FE_FONTSMOOTHINGCLEARTYPE 0x0002#endif//#include <performance.h>#define PM_INIT#define PM_MEASURE(A)#define PM_DISPLAY//debugging//#define QT_DEBUG_VERTEXBUFFER_ACCESS//#define QT_DEBUG_D3D//#define QT_DEBUG_D3D_CALLS#define QD3D_SET_MARK(output) \ D3DPERF_SetMarker(0, QString(output).utf16());#define QT_VERTEX_RESET_LIMIT 24576#define QT_VERTEX_BUF_SIZE 32768#define QD3DFVF_CSVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEXCOORDSIZE4(1))// this is a different usage of the effect framework than intended,// but it's convinient for us to use (See effect file)#define PASS_STENCIL_ODDEVEN 0#define PASS_STENCIL_WINDING 1#define PASS_STENCIL_DRAW 2#define PASS_STENCIL_DRAW_DIRECT 3#define PASS_STENCIL_CLIP 4#define PASS_STENCIL_NOSTENCILCHECK 5#define PASS_STENCIL_NOSTENCILCHECK_DIRECT 6#define PASS_TEXT 7#define PASS_CLEARTYPE_TEXT 8#define PASS_ALIASED_LINES 9#define PASS_ALIASED_LINES_DIRECT 10#define PASS_AA_CREATEMASK 0#define PASS_AA_DRAW 1#define PASS_AA_DRAW_DIRECT 2#define D3D_STAGE_COUNT 2#define D3D_RENDER_STATES 210#define D3D_TEXTURE_STATES 33#define D3D_SAMPLE_STATES 14typedef HRESULT (APIENTRY *PFND3DXCREATEBUFFER)(DWORD, LPD3DXBUFFER *);typedef HRESULT (APIENTRY *PFND3DXCREATEEFFECT)(LPDIRECT3DDEVICE9, LPCVOID, UINT, CONST D3DXMACRO *, LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL, LPD3DXEFFECT *, LPD3DXBUFFER *);typedef D3DXMATRIX *(APIENTRY *PFND3DXMATRIXORTHOOFFCENTERLH)(D3DMATRIX *, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT);typedef IDirect3D9 *(APIENTRY *PFNDIRECT3DCREATE9)(uint);static PFNDIRECT3DCREATE9 pDirect3DCreate9 = 0;static PFND3DXCREATEBUFFER pD3DXCreateBuffer = 0;static PFND3DXCREATEEFFECT pD3DXCreateEffect = 0;static PFND3DXMATRIXORTHOOFFCENTERLH pD3DXMatrixOrthoOffCenterLH = 0;class QD3DSurfaceManager : public QObject { Q_OBJECTpublic: enum QD3DSurfaceManagerStatus { NoStatus = 0, NeedsResetting = 0x01, MaxSizeChanged = 0x02 }; QD3DSurfaceManager(); ~QD3DSurfaceManager(); void init(LPDIRECT3D9 object); void setPaintDevice(QPaintDevice *pd); int status() const; void reset(); LPDIRECT3DSURFACE9 renderTarget(); LPDIRECT3DSURFACE9 surface(QPaintDevice *pd); LPDIRECT3DSWAPCHAIN9 swapChain(QPaintDevice *pd); void releasePaintDevice(QPaintDevice *pd); LPDIRECT3DDEVICE9 device(); void cleanup(); QSize maxSize() const;private: struct D3DSwapChain { QSize size; LPDIRECT3DSWAPCHAIN9 swapchain; LPDIRECT3DSURFACE9 surface; }; void updateMaxSize(); void initPresentParameters(D3DPRESENT_PARAMETERS *params); D3DSwapChain *createSwapChain(QWidget *w); QSize m_max_size; int m_status; QMap<QPaintDevice *, D3DSwapChain *> m_swapchains; LPDIRECT3DDEVICE9 m_device; QPaintDevice *m_pd; HWND m_dummy; D3DSwapChain *m_current;private Q_SLOTS: void cleanupPaintDevice(QObject *);};struct vertex { D3DVECTOR pos; DWORD color; FLOAT s0, t0, r0, q0; FLOAT s1, t1, r1, q1;};struct QD3DMaskPosition { int x, y, channel;};struct QD3DBatchItem { enum QD3DBatchInfo { BI_WINDING = 0x0001, BI_AA = 0x0002, BI_BRECT = 0x0004, BI_MASKFULL = 0x0008, BI_TEXT = 0x0010, BI_MASK = 0x0020, BI_CLIP = 0x0040, BI_SCISSOR = 0x0080, BI_PIXMAP = 0x0100, BI_IMAGE = 0x0200, BI_COMPLEXBRUSH = 0x0400, BI_CLEARCLIP = 0x0800, // clip nothing (filling the clip mask with 0) BI_TRANSFORM = 0x1000, BI_MASKSCISSOR = 0x2000, BI_FASTLINE = 0x4000, BI_COSMETICPEN = 0x8000 }; int m_info; int m_count; int m_offset; QD3DMaskPosition m_maskpos; qreal m_xoffset; qreal m_yoffset; qreal m_opacity; QPixmap m_pixmap; QRectF m_brect; QBrush m_brush; IDirect3DTexture9 *m_texture; qreal m_width; qreal m_distance; QTransform m_matrix; QPainter::CompositionMode m_cmode; QVector<int> m_pointstops;};struct QD3DBatch { int m_item_index; QD3DBatchItem items[QD3D_BATCH_SIZE];};class QD3DStateManager;class QD3DFontCache;class QD3DDrawHelper;class QD3DGradientCache;class QDirect3DPaintEnginePrivate : public QPaintEnginePrivate{ Q_DECLARE_PUBLIC(QDirect3DPaintEngine)public: enum RenderTechnique { RT_NoTechnique, RT_Antialiased, RT_Aliased, }; QDirect3DPaintEnginePrivate() : m_d3d_object(0) , m_d3d_device(0) , m_txop(QTransform::TxNone) , m_effect(0) , m_flush_on_end(0) { init(); } ~QDirect3DPaintEnginePrivate(); bool init(); void initDevice(); inline QD3DBatchItem *nextBatchItem(); QPolygonF brushCoordinates(const QRectF &r, bool stroke, qreal *fp) const; void fillAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform); void fillAntialiasedPath(const QPainterPath &path, const QRectF &brect, const QTransform &txform, bool stroke); void fillPath(const QPainterPath &path, QRectF brect); void strokePath(const QPainterPath &path, QRectF brect, bool simple = false); QPainterPath strokePathFastPen(const QPainterPath &path); void strokeAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform); void flushBatch(); int flushAntialiased(int offset); void flushAliased(QD3DBatchItem *item, int offset); void flushText(QD3DBatchItem *item, int offset); void flushLines(QD3DBatchItem *item, int offset); void updateTransform(const QTransform &matrix); void updatePen(const QPen &pen); void updateBrush(const QBrush &pen); void updateClipRegion(const QRegion &clipregion, Qt::ClipOperation op = Qt::ReplaceClip); void updateClipPath(const QPainterPath &clipregion, Qt::ClipOperation op = Qt::ReplaceClip); void updateFont(const QFont &font); void setRenderTechnique(RenderTechnique technique); QPointF transformPoint(const QPointF &p, qreal *w) const; bool prepareBatch(QD3DBatchItem *item, int offset); void prepareItem(QD3DBatchItem *item); void cleanupItem(QD3DBatchItem *item); void setCompositionMode(QPainter::CompositionMode mode); void verifyTexture(const QPixmap &pixmap); bool isFastRect(const QRectF &rect); void releaseDC(); void cleanup(); bool testCaps(); QPixmap getPattern(Qt::BrushStyle style) const; // clipping QPainterPath m_sysclip_path; QPainterPath m_clip_path; QRegion m_sysclip_region; QRegion m_clip_region; qreal m_opacity; D3DCOLOR m_opacity_color; int m_current_state; ID3DXEffect* m_effect; RenderTechnique m_current_technique; QTransform m_matrix; qreal m_inv_scale; QPen m_pen; Qt::BrushStyle m_pen_brush_style; QTransform m_inv_pen_matrix; D3DCOLOR m_pen_color; qreal m_pen_width; QBrush m_brush; Qt::BrushStyle m_brush_style; QTransform m_inv_brush_matrix; D3DCOLOR m_brush_color; QTransform m_brush_origin; uint m_clipping_enabled : 1; uint m_has_complex_clipping : 1; uint m_cleartype_text: 1; uint m_has_pen : 1; uint m_has_cosmetic_pen : 1; uint m_has_brush : 1; uint m_has_fast_pen : 1; uint m_has_aa_fast_pen : 1; uint m_flush_on_end : 1; uint m_supports_d3d : 1; QTransform::TransformationType m_txop; QPainter::CompositionMode m_cmode; QD3DSurfaceManager m_surface_manager; QSize m_surface_size; LPDIRECT3D9 m_d3d_object; LPDIRECT3DDEVICE9 m_d3d_device; IDirect3DSurface9 *m_current_surface; bool m_in_scene; QD3DGradientCache *m_gradient_cache; QD3DDrawHelper *m_draw_helper; QD3DBatch m_batch; QD3DStateManager *m_statemanager; HDC m_dc; IDirect3DSurface9 *m_dcsurface; QMap<Qt::BrushStyle, QPixmap> m_patterns;};class QD3DStateManager : public ID3DXEffectStateManager {public: QD3DStateManager(LPDIRECT3DDEVICE9 pDevice, ID3DXEffect *effect); void reset(); inline void startStateBlock(); inline void endStateBlock(); inline void setCosmeticPen(bool enabled); inline void setBrushMode(int mode); inline void setTexture(LPDIRECT3DBASETEXTURE9 pTexture); inline void setTexture(LPDIRECT3DBASETEXTURE9 pTexture, QGradient::Spread spread); inline void setTransformation(const QTransform *matrix = 0); inline void setProjection(const D3DXMATRIX *pMatrix); inline void setMaskChannel(int channel); inline void setMaskOffset(qreal x, qreal y); inline void setFocalDistance(const qreal &fd); inline void beginPass(int pass); inline void endPass(); STDMETHOD(QueryInterface)(REFIID iid, LPVOID *ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); STDMETHOD(SetTransform)(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix); STDMETHOD(SetMaterial)(CONST D3DMATERIAL9 *pMaterial); STDMETHOD(SetLight)(DWORD Index, CONST D3DLIGHT9 *pLight); STDMETHOD(LightEnable)(DWORD Index, BOOL Enable); STDMETHOD(SetRenderState)(D3DRENDERSTATETYPE State, DWORD Value); STDMETHOD(SetTexture)(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture); STDMETHOD(SetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value); STDMETHOD(SetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value); STDMETHOD(SetNPatchMode)(FLOAT NumSegments);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -