2011-05-12 9 views
6

Ho bisogno di aiuto per disegnare un testo su una trama con GDI e D3D11. Ho provato a usare D2D/DirectWrite, ma supporta solo D3D10 e non D3D11 di cui ho bisogno. Tutto ciò che ho provato finora non è riuscito ... Ora voglio usare i metodi GDI per scrivere nella trama. così ho creato una texture con questo params:D3D11: come disegnare il testo GDI su una superficie GXDI? (Senza D2D)

Usage = D3D11_USAGE_DEFAULT; 
Format = DXGI_FORMAT_B8G8R8A8_UNORM; 
BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 
CPUAccessFlags = 0; 
MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE 

Poi ho creato una RenderTargetView normale da questa texture come Microsoft sais qui: http://msdn.microsoft.com/en-us/library/ff476203%28v=vs.85%29.aspx

prossimo passo: ottenere l'interfaccia DXGI:

m_pTexFSText->QueryInterface(__uuidof(IDXGISurface1), (void **)(&m_pDXGISurface)); 

Sulla funzione Render faccio solo questo:

m_pDeviceContext->OMSetRenderTargets(1,&m_pTextRenderTarget,NULL); 

HDC hDc = NULL; 
if(FAILED(m_pDXGISurface->GetDC(TRUE,&hDc))) 
    return E_FAIL; 

COLORREF bla = SetPixel(hDc,1,1,RGB(255,255,255)); 
bool hmm = TextOutA(hDc, 10, 10, "LALALA!", 7); 

if(FAILED(m_pDXGISurface->ReleaseDC(NULL))) 
    return E_FAIL; 

Il problema è che la texture è ancora vuota dopo il disegno GDI (testato anche con PIX). Tutto funziona e non ci sono messaggi di errore.

Spero che qualcuno possa spiegare come funziona.

Grazie, Stefan

EDIT: Provato anche con GetDC(FALSE,&hDc) (in base alla documentazione): stessi risultati -> niente.

+0

hai provato un formato di 'DXGI_FORMAT_R8G8B8A8_UINT'? – Necrolis

+0

secondo il docu sul link qui sopra una texture compatibili gdi bisogno formati speciali "è necessario impostare il formato di texture per uno dei seguenti tipi: DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_TYPELESS, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB" – sandicz

risposta

3

Forse stai facendo tutto bene, è solo che il disegno del testo non fa quello che ti aspetti?

COLORREF bla = SetPixel(hDc,1,1,RGB(255,255,255)); 
bool hmm = TextOutA(hDc, 10, 10, "LALALA!", 7); 

Non capisco da questo come si aspetta che TextOutA indovinerà che bla dovrebbe essere usato come il colore del testo. AFAIK il colore del testo predefinito utilizzato nella CC appena creata/ottenuta è nero. Non sei sicuro della modalità di riempimento in background, ma se è impostata su TRANSPARENT per impostazione predefinita, questo spiega pienamente perché non si sta disegnando nulla.

che vorrei cambiare il codice per il seguente:

COLORREF bla = SetPixel(hDc,1,1,RGB(255,255,255)); 
VERIFY(SetTextColor(hDc, bla) != CLR_INVALID); 

CREct rc(0, 0, 30, 20); // put relevant coordinates 
VERIFY(ExtTextOut(hDc, rc.left, rc.top, ETO_CLIPPED, &rc, "LALALA!", 7)); 
+0

hi, queste righe sono solo test. imposta il pixel a 1,1 in bianco e in secondo luogo scrivi un testo dimostrativo. Proverò la tua versione. grazie :) – sandicz

+0

Ho appena notato che sto ricevendo un messaggio di errore sulla funzione GetDC(): "Microsoft C++ - Eccezione: _com_error nella posizione di memoria 0x0018f760" (tradotto in inglese). Non riesco davvero a immaginare perché questo accada. Forse questo è il problema principale e non GDI. Sembra che ho bisogno di aspettare fino a DirectWrite supporta D3D11 ... – sandicz

+0

Sì, controllare il valore restituito/eccezioni è una buona idea, soprattutto se qualcosa non va :) – valdo

4

realtà ho combattuto questo problema molto durante la scorsa settimana - ma ce l'ho tutto il funzionamento! Ecco un elenco di cose che dovreste sapere/fare per far funzionare il tutto:

Tenere presente quanto segue quando utilizzando questo metodo:

• È necessario creare la superficie utilizzando il flag D3D11_RESOURCE_MISC_GDI_COMPATIBLE per una superficie o utilizzando il flag DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE per le catene di scambio, altrimenti questo metodo non riesce.

• È necessario rilasciare il dispositivo e chiamare il metodo IDXGISurface1 :: ReleaseDC prima di emettere nuovi comandi Direct3D.

• Questo metodo ha esito negativo se è già stato creato un DC in sospeso con questo metodo.

• Il formato per la catena di superficie o di scambio deve essere DXGI_FORMAT_B8G8R8A8_UNORM_SRGB o DXGI_FORMAT_B8G8R8A8_UNORM.

• Su GetDC, il target di rendering nella fusione di output della pipeline Direct3D non è associato alla superficie. È necessario chiamare il metodo ID3D11DeviceContext :: OMSetRenderTargets sul dispositivo prima del rendering di Direct3D dopo il rendering GDI.

• Prima di ridimensionare i buffer, è necessario rilasciare tutti i controller di dominio in sospeso.

  • Se avete intenzione di usarlo nel buffer di nuovo, ricordatevi di ri-bind rendono bersaglio dopo avete chiamato ReleaseDC. Non è necessario separare manualmente RT prima di chiamare GetDC come questo metodo fa per te.

  • Non è possibile utilizzare qualsiasi disegno Direct3D tra GetDC() e ReleaseDC() chiama come la superficie è excusively bloccato da DXGI per GDI. Tuttavia è possibile combinare il rendering GDI e D3D purché si chiami GetDC()/ReleaseDC() ogni volta che è necessario utilizzare GDI, prima di passare a D3D.

  • Questo ultimo pezzo può sembra facile, ma si sarebbe sorpreso di come molti sviluppatori rientrano in questa edizione - quando si disegna con GDI sul back buffer, ricordate che questo è il posteriore tampone, non un framebuffer, quindi, per vedere effettivamente ciò che hai disegnato, devi re-legare RT a OM e chiamare il metodo swapChain-> Present() in modo che il backbuffer diventi un framebuffer e il suo contenuto verrà visualizzato sullo schermo.

+0

hey, grazie per la risposta. sembra davvero utile e forse so dove si trova il problema nel mio codice (rilasciando DC e reindirizzando Rendertarget). Purtroppo non ho tempo per provare la tua solita ora, ma lo farò in futuro ... – sandicz

Problemi correlati