Seite 1 von 1

Falschfarben in Textur?

Verfasst: 15.04.2013, 10:16
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

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 10:32
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 11:12
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 12:33
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 17:39
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?

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 18:02
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 :)

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 18:22
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?

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 18:27
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 18:30
von sirnoname
Feature Level 9?
Was soll ich sonst nehmen/machen, bin für Vorschläge offen?

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 18:32
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?

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 19:58
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 21:16
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.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 21:21
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

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 21:37
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();
	}

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 21:52
von Krishty
Ergänz das Format um _SRGB, wenn die GPU die Textur beim Lesen vom gammakorrigierten in den linearen Farbraum konvertieren soll.

Re: Falschfarben in Textur?

Verfasst: 15.04.2013, 22:52
von sirnoname
Danke für den Tipp.
Hab ich nun versucht, leider lässt sich die Textur weiterhin von den globalen Einstellungen beeinflussen.