⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpaintengine_d3d.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        m_texturestates[Stage][Type] = Value;    }    return m_pDevice->SetTextureStageState(Stage, Type, Value);}STDMETHODIMP QD3DStateManager::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value){    if (Sampler < D3D_STAGE_COUNT && Type < D3D_SAMPLE_STATES) {        if (m_samplerstates[Sampler][Type] == Value)            return S_OK;        m_samplerstates[Sampler][Type] = Value;    }    return m_pDevice->SetSamplerState(Sampler, Type, Value);}STDMETHODIMP QD3DStateManager::SetNPatchMode(FLOAT NumSegments){    return m_pDevice->SetNPatchMode(NumSegments);}STDMETHODIMP QD3DStateManager::SetFVF(DWORD FVF){    return m_pDevice->SetFVF(FVF);}STDMETHODIMP QD3DStateManager::SetVertexShader(LPDIRECT3DVERTEXSHADER9 pShader){    if (m_vertexshader == pShader)        return S_OK;    m_vertexshader = pShader;    return m_pDevice->SetVertexShader(pShader);}STDMETHODIMP QD3DStateManager::SetVertexShaderConstantF(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount){    return m_pDevice->SetVertexShaderConstantF(RegisterIndex, pConstantData, RegisterCount);}STDMETHODIMP QD3DStateManager::SetVertexShaderConstantI(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount){    return m_pDevice->SetVertexShaderConstantI(RegisterIndex, pConstantData, RegisterCount);}STDMETHODIMP QD3DStateManager::SetVertexShaderConstantB(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount){    return m_pDevice->SetVertexShaderConstantB(RegisterIndex, pConstantData, RegisterCount);}STDMETHODIMP QD3DStateManager::SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader){    if (m_pixelshader == pShader)        return S_OK;    m_pixelshader = pShader;    return m_pDevice->SetPixelShader(pShader);}STDMETHODIMP QD3DStateManager::SetPixelShaderConstantF(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount){    return m_pDevice->SetPixelShaderConstantF(RegisterIndex, pConstantData, RegisterCount);}STDMETHODIMP QD3DStateManager::SetPixelShaderConstantI(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount){    return m_pDevice->SetPixelShaderConstantI(RegisterIndex, pConstantData, RegisterCount);}STDMETHODIMP QD3DStateManager::SetPixelShaderConstantB(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount){    return m_pDevice->SetPixelShaderConstantB(RegisterIndex, pConstantData, RegisterCount);}#define QD3D_GRADIENT_CACHE_SIZE    60#define QD3D_GRADIENT_PALETTE_SIZE  1024class QD3DGradientCache{    struct CacheInfo    {        inline CacheInfo(QGradientStops s, qreal op) :            stops(s), opacity(op) {}        IDirect3DTexture9 *texture;        QGradientStops stops;        qreal opacity;    };    typedef QMultiHash<quint64, CacheInfo> QD3DGradientColorTableHash;public:    QD3DGradientCache(LPDIRECT3DDEVICE9 device);    ~QD3DGradientCache();    inline IDirect3DTexture9 *getBuffer(const QGradientStops &stops, qreal opacity);protected:    inline void generateGradientColorTable(const QGradientStops& s,                                           uint *colorTable,                                           int size, qreal opacity) const;    IDirect3DTexture9 *addCacheElement(quint64 hash_val, const QGradientStops &stops, qreal opacity);    void cleanCache();    QD3DGradientColorTableHash cache;    LPDIRECT3DDEVICE9 m_device;};QD3DGradientCache::QD3DGradientCache(LPDIRECT3DDEVICE9 device)    : m_device(device){}QD3DGradientCache::~QD3DGradientCache(){    cleanCache();}inline IDirect3DTexture9 *QD3DGradientCache::getBuffer(const QGradientStops &stops, qreal opacity){    quint64 hash_val = 0;    for (int i = 0; i < stops.size() && i <= 2; i++)        hash_val += stops[i].second.rgba();    QD3DGradientColorTableHash::const_iterator it = cache.constFind(hash_val);    if (it == cache.constEnd())        return addCacheElement(hash_val, stops, opacity);    else {        do {            const CacheInfo &cache_info = it.value();            if (cache_info.stops == stops && cache_info.opacity == opacity) {                return cache_info.texture;            }            ++it;        } while (it != cache.constEnd() && it.key() == hash_val);        // an exact match for these stops and opacity was not found, create new cache        return addCacheElement(hash_val, stops, opacity);    }}void QD3DGradientCache::generateGradientColorTable(const QGradientStops& s, uint *colorTable, int size, qreal opacity) const{    int pos = 0;    qreal fpos = 0.0;    qreal incr = 1.0 / qreal(size);    QVector<uint> colors(s.size());    for (int i = 0; i < s.size(); ++i)        colors[i] = s[i].second.rgba();    uint alpha = qRound(opacity * 255);    while (fpos < s.first().first) {        colorTable[pos] = ARGB_COMBINE_ALPHA(colors[0], alpha);        pos++;        fpos += incr;    }    for (int i = 0; i < s.size() - 1; ++i) {        qreal delta = 1/(s[i+1].first - s[i].first);        while (fpos < s[i+1].first && pos < size) {            int dist = int(256 * ((fpos - s[i].first) * delta));            int idist = 256 - dist;            uint current_color = ARGB_COMBINE_ALPHA(colors[i], alpha);            uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN            colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);#else            uint c = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);            colorTable[pos] = ( (c << 24) & 0xff000000)                              | ((c >> 24) & 0x000000ff)                              | ((c << 8) & 0x00ff0000)                              | ((c >> 8) & 0x0000ff00);#endif // Q_BYTE_ORDER            ++pos;            fpos += incr;        }    }    for (;pos < size; ++pos)        colorTable[pos] = colors[s.size() - 1];}IDirect3DTexture9 *QD3DGradientCache::addCacheElement(quint64 hash_val, const QGradientStops &stops, qreal opacity){    if (cache.size() == QD3D_GRADIENT_CACHE_SIZE) {        int elem_to_remove = qrand() % QD3D_GRADIENT_CACHE_SIZE;        uint key = cache.keys()[elem_to_remove];        // need to call release on each removed cache entry:        QD3DGradientColorTableHash::const_iterator it = cache.constFind(key);        do {            it.value().texture->Release();        } while (++it != cache.constEnd() && it.key() == key);        cache.remove(key); // may remove more than 1, but OK    }    CacheInfo cache_entry(stops, opacity);    uint buffer[QD3D_GRADIENT_PALETTE_SIZE];    generateGradientColorTable(stops, buffer, QD3D_GRADIENT_PALETTE_SIZE, opacity);    if (FAILED(m_device->CreateTexture(QD3D_GRADIENT_PALETTE_SIZE, 1, 1, 0,                    D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cache_entry.texture, 0))) {        qWarning("QD3DGradientCache::addCacheElement(): unable to create Direct3D texture.");        return 0;    }    D3DLOCKED_RECT rect;    if (FAILED(cache_entry.texture->LockRect(0, &rect, 0, 0))) {        qDebug() << "QD3DGradientCache::addCacheElement(): unable to lock texture rect.";        return 0;    }    memcpy(rect.pBits, buffer, rect.Pitch);    cache_entry.texture->UnlockRect(0);    return cache.insert(hash_val, cache_entry).value().texture;}void QD3DGradientCache::cleanCache(){    QD3DGradientColorTableHash::const_iterator it = cache.constBegin();    for (; it != cache.constEnd(); ++it) {        const CacheInfo &cache_info = it.value();        cache_info.texture->Release();    }    cache.clear();}QD3DSurfaceManager::QD3DSurfaceManager() :    m_status(NoStatus), m_dummy(0), m_device(0), m_pd(0), m_current(0){}QD3DSurfaceManager::~QD3DSurfaceManager(){}void QD3DSurfaceManager::setPaintDevice(QPaintDevice *pd){    m_status = NoStatus;    m_pd = pd;    m_current = 0;    if (m_device->TestCooperativeLevel() != D3D_OK) {        m_status = NeedsResetting;        return;    }    m_current = m_swapchains.value(pd, 0);    QWidget *w = static_cast<QWidget*>(pd);    if (m_current) {        if (m_current->size != w->size()) {            m_swapchains.remove(pd);            m_current->surface->Release();            m_current->swapchain->Release();            delete m_current;            m_current = 0;        }    }    if (!m_current) {        m_current = createSwapChain(w);        updateMaxSize();    }}int QD3DSurfaceManager::status() const{    return m_status;}void QD3DSurfaceManager::reset(){    QList<QPaintDevice *> pds = m_swapchains.keys();    QMap<QPaintDevice *, D3DSwapChain *>::const_iterator i = m_swapchains.constBegin();    while (i != m_swapchains.constEnd()) {        i.value()->surface->Release();        i.value()->swapchain->Release();        ++i;    }    qDeleteAll(m_swapchains.values());    m_swapchains.clear();    D3DPRESENT_PARAMETERS params;    initPresentParameters(&params);    params.hDeviceWindow = m_dummy;    HRESULT res = m_device->Reset(&params);    if (FAILED(res)) {        switch (res) {            case D3DERR_DEVICELOST:                qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_DEVICELOST)");                break;            case D3DERR_DRIVERINTERNALERROR:                qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_DRIVERINTERNALERROR)");                break;            case D3DERR_OUTOFVIDEOMEMORY:                qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_OUTOFVIDEOMEMORY)");                break;            default:                qWarning("QDirect3DPaintEngine: Reset failed");        };    }    for (int i=0; i<pds.count(); ++i) {        QWidget *w = static_cast<QWidget*>(pds.at(i));        createSwapChain(w);    }    // reset the mask as well    m_status = MaxSizeChanged;    setPaintDevice(m_pd);    updateMaxSize();}LPDIRECT3DSURFACE9 QD3DSurfaceManager::renderTarget(){    return m_current ? m_current->surface : 0;}LPDIRECT3DSURFACE9 QD3DSurfaceManager::surface(QPaintDevice *pd){    D3DSwapChain *swapchain = m_swapchains.value(pd, 0);    return swapchain ? swapchain->surface : 0;}LPDIRECT3DSWAPCHAIN9 QD3DSurfaceManager::swapChain(QPaintDevice *pd){    D3DSwapChain *swapchain = m_swapchains.value(pd, 0);    return swapchain ? swapchain->swapchain : 0;}void QD3DSurfaceManager::releasePaintDevice(QPaintDevice *pd){    D3DSwapChain *swapchain = m_swapchains.take(pd);    if (swapchain) {        swapchain->surface->Release();        swapchain->swapchain->Release();        delete swapchain;        if (swapchain == m_current)            m_current = 0;    }}LPDIRECT3DDEVICE9 QD3DSurfaceManager::device(){    return m_device;}void QD3DSurfaceManager::cleanup(){    QPixmapCache::clear();    qd3d_glyph_cache()->cleanCache();    // release doomed textures    for (int k=0; k<qd3d_release_list.size(); ++k)        qd3d_release_list.at(k)->Release();    qd3d_release_list.clear();    QMap<QPaintDevice *, D3DSwapChain *>::const_iterator i = m_swapchains.constBegin();    while (i != m_swapchains.constEnd()) {        i.value()->surface->Release();        i.value()->swapchain->Release();        ++i;    }    qDeleteAll(m_swapchains.values());    if (m_device)        m_device->Release();    DestroyWindow(m_dummy);    QString cname(QLatin1String("qt_d3d_dummy"));    QT_WA({        UnregisterClass((TCHAR*)cname.utf16(), (HINSTANCE)qWinAppInst());    } , {        UnregisterClassA(cname.toLatin1(), (HINSTANCE)qWinAppInst());    });}QSize QD3DSurfaceManager::maxSize() const{    return m_max_size;}extern "C" {    LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);};void QD3DSurfaceManager::init(LPDIRECT3D9 object){    QString cname(QLatin1String("qt_d3d_dummy"));    uint style = CS_DBLCLKS | CS_SAVEBITS;    ATOM atom;    QT_WA({        WNDCLASS wc;        wc.style         = style;        wc.lpfnWndProc   = (WNDPROC)QtWndProc;        wc.cbClsExtra    = 0;        wc.cbWndExtra    = 0;        wc.hInstance     = (HINSTANCE)qWinAppInst();        wc.hIcon         = 0;        wc.hCursor       = 0;        wc.hbrBackground = 0;        wc.lpszMenuName  = 0;        wc.lpszClassName = (TCHAR*)cname.utf16();        atom = RegisterClass(&wc);    } , {        WNDCLASSA wc;        wc.style         = style;        wc.lpfnWndProc   = (WNDPROC)QtWndProc;        wc.cbClsExtra    = 0;        wc.cbWndExtra    = 0;        wc.hInstance     = (HINSTANCE)qWinAppInst();        wc.hIcon         = 0;        wc.hCursor       = 0;        wc.hbrBackground = 0;        wc.lpszMenuName  = 0;        QByteArray tempArray = cname.toLatin1();        wc.lpszClassName = tempArray;        atom = RegisterClassA(&wc);    });    QT_WA({

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -