Falschfarben in Textur?

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Falschfarben in Textur?

Beitrag von sirnoname »

Hallo,

ich steige gerade mit meinem Code von DX9 auf DX10 um.
Dadurch wude der HUD Code (eine simple Textur) von:

Code: Alles auswählen

D3DXCreateTextureFromResourceEx(mydev,hSrcModule,MAKEINTRESOURCE(IDB_OVERLAY),texinfo.Width,texinfo.Height,1,D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,D3DX_FILTER_NONE,D3DX_FILTER_NONE,0xff000000,NULL,NULL,&texTexture);
zu:

Code: Alles auswählen

	D3DX10_IMAGE_LOAD_INFO loadinfo;
	loadinfo.Width			=texinfo.Width;
	loadinfo.Height			=texinfo.Height;
	loadinfo.FirstMipLevel	=0;
	loadinfo.MipLevels		=texinfo.MipLevels;
	loadinfo.Usage			=D3D10_USAGE_DYNAMIC;
	loadinfo.Format			=DXGI_FORMAT_R8G8B8A8_UNORM;
	loadinfo.Depth			=texinfo.Depth;
	loadinfo.Filter			=D3DX10_FILTER_NONE;
	loadinfo.MipFilter		=D3DX10_FILTER_NONE;				   
	loadinfo.MiscFlags		=texinfo.MiscFlags;
	loadinfo.CpuAccessFlags	=D3D10_CPU_ACCESS_WRITE;
	loadinfo.BindFlags		=D3D10_BIND_SHADER_RESOURCE;
	loadinfo.pSrcInfo		=&texinfo;
	D3DX10CreateTextureFromResource(mydev,hSrcModule, MAKEINTRESOURCE(IDR_OSDMENU_RCDATA), &loadinfo, NULL, (ID3D10Resource**)&pTexture,NULL);
zuerst hatte ich mit dem Problem von RCDATA zu kämpfen, da der Load nun nicht mehr aus BMP Resourcen funktioniert.
Nach MSDN sind D3DFMT_A8R8G8B8 und DXGI_FORMAT_R8G8B8A8_UNORM identisch, trotzdem ist in DX10 alles blaue nun gelb. Ich habe die Variationen vom Format der load information schon ausprobiert, keine Änderungen.
Wie passt man die Farbe, evtl. automatisch, dem erzeugten Device an?

Grüße,
sirnoname
Zuletzt geändert von sirnoname am 15.04.2013, 17:48, insgesamt 1-mal geändert.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Falschfarben in Textur?

Beitrag von Niki »

EDIT: Sorry, ich hatte Tomaten auf den Augen als ich in der DirectX Doku nachschaute. Ich dachte D3DX10GetImageInfoFromResource gibt die Load-Info zurück, dem ist aber nicht so.
Zuletzt geändert von Niki am 15.04.2013, 12:18, insgesamt 2-mal geändert.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von Schrompf »

Aber A8R8G8B8 und R8G8B8A8 sind nunmal nicht identisch. Auch nicht, wenn man einen Endian Swap unterstellt. Es sind halt einfach verschiedene Kanalzuordnungen. Ein Blau (0xff0000ff) würde im DX10-Format wohl als Rot interpretiert werden. Du wirst wohl vor dem Hochladen die Kanäle von Hand vertauschen müssen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von CodingCat »

sirnoname hat geschrieben:Nach MSDN sind D3DFMT_A8R8G8B8 und DXGI_FORMAT_R8G8B8A8_UNORM identisch
Nein, D3DFMT_A8R8G8B8 == DXGI_FORMAT_B8G8R8A8_UNORM, siehe Mapping texture formats.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

D3DFMT_A8R8G8B8 == DXGI_FORMAT_B8G8R8A8_UNORM
Ups, sorry, ich habe wie geschrieben einige andere Formate ausprobiert, daher ist es oben falsch eingetragen.
Wiederspricht das nicht nun auch noch Schrompf?
Leider führt keiner der Formate in 8 bit zu einem andersfarbigen Bild, bleibt immer im falschen gelb. (DXGI_FORMAT_B8G8R8A8_UNORM oder DXGI_FORMAT_R8G8B8A8_UNORM)
Würde es trotzdem gerne verstehen warum das Format in 8 Bit ignoriert wird. (UINT Formate werden gar nicht geladen, daher ist der Format Eintrag nicht ganz tot)
Beim DX9 Befehl gebe ich einen ColorKey an 0xff000000, beim DX10 nicht. Liegt es daran?
Oder dürfen die RCDATA Texturen keine BMP Header mehr haben (Habe die BMP einfach umbenannt in .bin)?
Mit was für einem Programm würdet ihr die Kanäle tauschen?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Falschfarben in Textur?

Beitrag von Niki »

Also, ich komm mir dabei jetzt zwar ein wenig doof vor, aber vielleicht solltest du tatsächlich mal D3DX10GetImageInfoFromResource benutzen und mit dem Debugger nachsehen, was dir die Method in D3DX10_IMAGE_INFO zurückgibt. Muss nicht unbedingt was bringen, aber mit etwas Glück könnte es aufschlussreich sein. Nicht das in deiner texInfo.Depth eine Farbtiefe a la 8 oder 32 steht, aber ich denke mal so schlau bist du selbst :)
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

Also ich habe jetzt folgendes durchprobiert:
Da ich eine RGB BMP habe ohne A (geht ja bei DX9) habe ich mit GIMP daraus eine ARGB gemacht (mehr ging dort nicht als Export).
Der Erfolg: Resourcen Editor kann das RCDATA nicht mehr als BMP erkennen, gleiche falschfarbene Textur.

Dann habe ich bei loadinfo die texinfo als Format eingefügt, um das Format gleich dem erkannten zu setzen, die ich zuvor bei der Info Abfrage erhalte (texinfo).
Der Erfolg: wieder falsche Farben.

Depth ist 1! Ein erzwungenes 8 führt zum Absturz.

Zugegeben, ich kann nur ARGB liefern, aber DX9 passte dies ja und die MSDN sagt das obige.
Mit was erzeugt ihr denn solche Texturen?
Zuletzt geändert von sirnoname am 15.04.2013, 18:32, insgesamt 1-mal geändert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8316
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von Krishty »

sirnoname hat geschrieben:
D3DFMT_A8R8G8B8 == DXGI_FORMAT_B8G8R8A8_UNORM
Ups, sorry, ich habe wie geschrieben einige andere Formate ausprobiert, daher ist es oben falsch eingetragen.
Sicher? DXGI_FORMAT_B8G8R8A8_UNORM steht unter Direct3D 10 nämlich nur im Feature Level 9 zur Verfügung.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

Feature Level 9?
Was soll ich sonst nehmen/machen, bin für Vorschläge offen?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: Falschfarben in Textur?

Beitrag von Niki »

Ich kenne mich mit RCDATA nicht so prima aus. Aber kann man da nicht auch eine DDS Textur reintun? Oder haut das nicht hin?
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von Schrompf »

sirnoname hat geschrieben:
D3DFMT_A8R8G8B8 == DXGI_FORMAT_B8G8R8A8_UNORM
Ups, sorry, ich habe wie geschrieben einige andere Formate ausprobiert, daher ist es oben falsch eingetragen.
Wiederspricht das nicht nun auch noch Schrompf?
Nein, das widerspricht nicht. Achtung: Spekulation folgt.

Anscheinend benutzen die Grafikkarten intern auch LittleEndian-Speicherlayout. Die x86-Architektur tut das ja auch. Little Endian bedeutet, dass die einzelnen Bytes von Multi-Byte-Werten von hinten nach vorn in den Speicher geschrieben werden. Wenn Du also einen uint32_t mit dem Inhalt 0xaabbccdd in den Speicher schreibst, steht im Speicher 0xdd 0xcc 0xbb 0xaa.

Ich interpretiere die Doku jetzt also so, dass DX9 bisher das Format nach der Repräsentation im Register benannt hat, ein A8R8G8B8 wäre im Register also ein uint32_t( 0xAARRGGBB) und im Speicher ein (0xBB 0xGG 0xRR 0xAA). DXGI orientiert sich in der Benamung der Konstanten also eher nach dem Aufbau im Speicher und benennt das Format dann folgerichtig B8G8R8A8.

Du dagegen wolltest DXGI_FORMAT_R8G8B8A8_UNORM benutzen, was nach obiger Logik im Speicher als (0xRR 0xGG 0xBB 0xAA) liegt und im Register wie (0xAABBGGRR) aussieht.
Leider führt keiner der Formate in 8 bit zu einem andersfarbigen Bild, bleibt immer im falschen gelb. (DXGI_FORMAT_B8G8R8A8_UNORM oder DXGI_FORMAT_R8G8B8A8_UNORM)
Würde es trotzdem gerne verstehen warum das Format in 8 Bit ignoriert wird. (UINT Formate werden gar nicht geladen, daher ist der Format Eintrag nicht ganz tot)
Was heißt "nicht geladen"? UINT-Formate dürften im Shader genauso gelesen werden wie andere Texturen auch. Die unterscheiden sich nur in der Nachbearbeitung, die die Grafikkarte für Dich tut. UINT-Formate werden direkt so geladen, Du bekommst also bei 8Bit-Formaten pro Kanal Werte zwischen 0 und 255. Die UNORM-Formate dividieren für Dich durch den Maximalwerte, Du bekommst die Werte also normiert vom 0.0 bis 1.0 aus der Textur. Daher auch der Name.
Beim DX9 Befehl gebe ich einen ColorKey an 0xff000000, beim DX10 nicht. Liegt es daran?
ColorKey ist doch eh tot, schon seit Ewigkeiten, oder? Lade ein Bild mit richtiger Transparenz, z.B. aus einem TGA oder PNG.
Oder dürfen die RCDATA Texturen keine BMP Header mehr haben (Habe die BMP einfach umbenannt in .bin)?
Mit was für einem Programm würdet ihr die Kanäle tauschen?
Spätestens die Frage finde ich schon sehr seltsam. Du bist doch Programmierer? Schreib doch einfach mal kurz die paar Zeilen, um nach dem Laden der Bilddaten die Kanäle zu vertauschen und lad das Ergebnis erst dann hoch.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

Naja, übetreiben muss ich es nicht, mit Paintshop Pro geht das recht fix.
Die Farben passen nun bei BGR.

Leider passt das Malen der Textur nicht mehr und sie wird durch scalen unscharf:

Code: Alles auswählen

float w = static_cast<float>(uiWidth);
	float h = static_cast<float>(uiHeight);
	float left   = static_cast<float>(uiLeft) - 0.5f;
	float top    = static_cast<float>(uiTop) - 0.5f;
	float right  = static_cast<float>(uiRight) + 0.5f;
	float bottom = static_cast<float>(uiBottom) + 0.5f;
	float texl = (left) / w;
	float text = (top) / h;
	float texr = (right + 1.0f) / w;
	float texb = (bottom + 1.0f) / h;
	left = 2.0f * (left / vp.Width) - 1.0f;
	right = 2.0f * (right / vp.Width) - 1.0f;
	top = -2.0f * (top / vp.Height) + 1.0f;
	bottom = -2.0f * (bottom / vp.Height) + 1.0f;
	// Create vertex buffer
	SimpleVertex vertices[] = 
	{
		{ D3DXVECTOR3(left, top, 0.5f), D3DXVECTOR2(texl, text) },
		{ D3DXVECTOR3(right, top, 0.5f), D3DXVECTOR2(texr, text) },
		{ D3DXVECTOR3(right, bottom, 0.5f), D3DXVECTOR2(texr, texb) },
		{ D3DXVECTOR3(left, bottom, 0.5f), D3DXVECTOR2(texl, texb) },
	};
Ich habe dort keine 1:1 pixelgenaue Ausgabe und finde den Fehler nicht. vp ist der viewport.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5047
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von Schrompf »

Nimm das -0.5f und +0.5f weg. Bis D3D9 war nur das -0.5f notwendig, allerdings für linksoben UND rechtsunten. Ab D3D10 sind die Rasterizer-Regeln saubergemacht worden, ab da braucht es gar kein Halb-Pixel-Offset mehr
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

Treffer, alle 4 und die +1.0f bei texr und texb.

Nun bin ich fast glücklich, allerdings möchte ich die Textur nun unabhängig von der Gamma Korrektur haben.
Sie verändert die Helligkeit bei den globalen Einstellungen.

Kann man das irgendwie einbauen beim Übergeben?

Code: Alles auswählen

HRESULT hr = pDevice->CreateShaderResourceView(pTexture, &srvDesc, &pSRView);
	dwMyThread = GetCurrentThreadId();
	if (pSRView && (uiLeft != uiRight)) 
	{
		HRESULT hr;
		pOrigStateBlock->Capture();
		pMyStateBlock->Apply();
		D3D10_TECHNIQUE_DESC techDesc;
		pTechnique->GetDesc(&techDesc);
		// Set vertex buffer
		UINT stride = sizeof(SimpleVertex);
		UINT offset = 0;
		pDevice->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
		hr = pDiffuseTexture->SetResource(pSRView);
		for (UINT p = 0; p < techDesc.Passes; ++p) 
		{
			pTechnique->GetPassByIndex(p)->Apply(0);
			pDevice->DrawIndexed(6, 0, 0);
		}
		pOrigStateBlock->Apply();
	}
Benutzeravatar
Krishty
Establishment
Beiträge: 8316
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Falschfarben in Textur?

Beitrag von Krishty »

Ergänz das Format um _SRGB, wenn die GPU die Textur beim Lesen vom gammakorrigierten in den linearen Farbraum konvertieren soll.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
sirnoname
Beiträge: 67
Registriert: 20.06.2010, 11:04

Re: Falschfarben in Textur?

Beitrag von sirnoname »

Danke für den Tipp.
Hab ich nun versucht, leider lässt sich die Textur weiterhin von den globalen Einstellungen beeinflussen.
Antworten