UpdateTexture funktioniert nicht wie es soll



  • Hallo

    Ich möchte eine "normale" Texture mit Direct3D laden und gleichzeitig ein BackUp im Hauptspeicher anlegen.
    Also ich erzeuge eine Texture mit D3DPOOL_SYSTEMMEM und lade in diese meine Texture. Dann erstell ich eine Zweite mit D3DPOOL_DEFAULT und verwende Direct3DDevice9::UpdateTexture (SourceTexture, DestinationTexture)
    (die Parameterreihenfolge stehts so im SDK)

    Soweit so gut ... das funktioniert auch noch ....
    Wenn ich die D3DPOOL_DEFAULT-Texture jetzt rendere funktioniert alles wunderbar.
    Wenn ich jetzt aber die besagt Texture einmal release, neu erstelle und nochmal UpdateTexture() mach und sie dann versuche zu rendern sehen ich nur einen Pixelhaufen. Das lustige ist, wenn ich die beiden Params von UpdateTexture vertausche, dann kann ich 100 mal releasen und neu laden und es funzt trotzdem 😮 😕
    Ähm wie kann das sein ????
    Beim ersten mal UpdateTexture funktioniert es und beim zweiten mal nicht mehr ?? Params vertauschen und es funzt immer ????

    Um andere Fehler oder sonstiges auszuschließen, hab ich die Engine mal zur Seite gestellt und ein kleines CodeSample gemacht das genau diese Dilema zeigt.
    (Ich weiß 90% des Codes ist fürn Hugo aber schreiben musste ich ihn auch 🕶

    So hier mal der erste Teil des Codes.

    //Libs includieren
    #pragma comment (lib, "d3d9.lib")
    #pragma comment (lib, "d3dx9.lib")
    //Header includieren
    #include <d3d9.h>
    #include <d3dx9.h>
    
    //VertexStruct
    struct SVertex
    {
    	float X;
    	float Y;
    	float Z;
    	DWORD Diffuse;
    	float TextureU;
    	float TextureV;
    };
    
    //CallBackFunktion für das Fenster
    LRESULT CALLBACK MessageHandler (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
    
    //WinMain
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    	//////////////////////////////////////////////////////////////////////////
    	// Fenster erzeugen
    	//////////////////////////////////////////////////////////////////////////
    
    	HWND hWnd;
    	MSG Msg;
    	WNDCLASSEX wndClass;
    
    	//Struct mit Werten füllen
    	wndClass.cbSize        = sizeof (WNDCLASSEX);
    	wndClass.style         = NULL;
    	wndClass.lpfnWndProc   = MessageHandler;
    	wndClass.cbClsExtra    = 0;
    	wndClass.cbWndExtra    = 0;
    	wndClass.hInstance     = hInstance;
    	wndClass.hIcon         = LoadIcon (NULL, IDI_WINLOGO);
    	wndClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    	wndClass.hbrBackground = reinterpret_cast<HBRUSH> (GetStockObject (WHITE_BRUSH));
    	wndClass.lpszMenuName  = NULL;
    	wndClass.lpszClassName = "WindowClass";
    	wndClass.hIconSm       = LoadIcon (NULL, IDI_WINLOGO);
    
    	//Registrieren
    	RegisterClassEx (&wndClass);
    
    	//Fenster erzeugen
    	hWnd = CreateWindowEx (NULL, "WindowClass", "Test", WS_POPUP | WS_VISIBLE,
    	                       0, 0, 640, 480, NULL, NULL, hInstance, NULL);
    	//WindowsCursor verstecken
    	ShowCursor (false);
    
    	//////////////////////////////////////////////////////////////////////////
    	// Direct3D initialisieren
    	//////////////////////////////////////////////////////////////////////////
    
    	LPDIRECT3D9 d3d;
    	LPDIRECT3DDEVICE9 d3dDevice;
    	D3DPRESENT_PARAMETERS PresentParams;
    	D3DXMATRIX Matrix;
    	LPDIRECT3DTEXTURE9 d3dSysTexture;
    	LPDIRECT3DTEXTURE9 d3dTexture;
    
    	//Interface holen
    	d3d = Direct3DCreate9 (D3D_SDK_VERSION);
    
    	//PresentParams mit Werten füllen
    	PresentParams.BackBufferWidth            = 1920; //Notebook Auflösung :D
    	PresentParams.BackBufferHeight           = 1200;
    	PresentParams.BackBufferFormat           = D3DFMT_X8R8G8B8;
    	PresentParams.BackBufferCount            = 1;
    	PresentParams.MultiSampleType            = D3DMULTISAMPLE_NONE;
    	PresentParams.MultiSampleQuality         = 0;
    	PresentParams.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
    	PresentParams.hDeviceWindow              = hWnd;
    	PresentParams.Windowed                   = false;
    	PresentParams.EnableAutoDepthStencil     = false;
    	PresentParams.AutoDepthStencilFormat     = D3DFMT_UNKNOWN;
    	PresentParams.Flags                      = 0;
    	PresentParams.FullScreen_RefreshRateInHz = 0;
    	PresentParams.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    	HRESULT hr;
    
    	//Device erzeugen
    	hr = d3d->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &PresentParams, &d3dDevice);
    	//ProjectionsMatrix setzen
    	d3dDevice->SetTransform (D3DTS_PROJECTION, D3DXMatrixPerspectiveFovLH (&Matrix, 45.0f / 180.0f * D3DX_PI, 1920.0f / 1200.0f, 1, 100));
    

    Hier lade ich jetzt die Texturen .....
    Das funktioniert (also später dann die Texture anzeigen)

    //Zuerst die BackUpTexture
    	D3DXCreateTextureFromFileEx (d3dDevice, "Background.bmp", 
    	                             512, 512, //Auflösung
    								 1, //Keine MipMaps
    								 0, //Kein Usage :)
    								 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, //Im "Haupt"-Ram
    								 D3DX_DEFAULT, D3DX_DEFAULT, //Die beiden Filter
    								 0, //ColorKey brauch ich keinen
    								 NULL, NULL, &d3dSysTexture);
    
    	//Jetzt die "RenderTexture"
    	d3dDevice->CreateTexture (512, 512, 
    	                          1, //Keine MipMaps
    							  0, //Kein Usage
    							  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, //Diesmal Default
    							  &d3dTexture, NULL);
    
    	//So ... jetzt SystemTexture auf die RenderTexture kopieren
    	d3dDevice->UpdateTexture (d3dSysTexture,  //SourceTexture
    							  d3dTexture);    //DestinationTexture
    

    Das funktionierts nicht 😞

    //Zuerst die BackUpTexture
    	D3DXCreateTextureFromFileEx (d3dDevice, "Background.bmp", 
    	                             512, 512, //Auflösung
    								 1, //Keine MipMaps
    								 0, //Kein Usage :)
    								 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, //Im "Haupt"-Ram
    								 D3DX_DEFAULT, D3DX_DEFAULT, //Die beiden Filter
    								 0, //ColorKey brauch ich keinen
    								 NULL, NULL, &d3dSysTexture);
    
    	//Jetzt die "RenderTexture"
    	d3dDevice->CreateTexture (512, 512, 
    	                          1, //Keine MipMaps
    							  0, //Kein Usage
    							  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, //Diesmal Default
    							  &d3dTexture, NULL);
    
    	//So ... jetzt SystemTexture auf die RenderTexture kopieren
    	d3dDevice->UpdateTexture (d3dSysTexture,  //SourceTexture
    							  d3dTexture);    //DestinationTexture
    
    	//Texture wieder freigeben
    	d3dTexture->Release ();
    
    	//Neu erzeugen
    	d3dDevice->CreateTexture (512, 512, 
    	                          1, //Keine MipMaps
    							  0, //Kein Usage
    							  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, //Diesmal Default
    							  &d3dTexture, NULL);
    
    	//Und nochmal UpdateTexture
    	d3dDevice->UpdateTexture (d3dSysTexture,  //SourceTexture
    							  d3dTexture);    //DestinationTexture (so wie im SDK)
    

    Und das beste ... das funzt wieder 👍

    //Zuerst die BackUpTexture
    	D3DXCreateTextureFromFileEx (d3dDevice, "Background.bmp", 
    	                             512, 512, //Auflösung
    								 1, //Keine MipMaps
    								 0, //Kein Usage :)
    								 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, //Im "Haupt"-Ram
    								 D3DX_DEFAULT, D3DX_DEFAULT, //Die beiden Filter
    								 0, //ColorKey brauch ich keinen
    								 NULL, NULL, &d3dSysTexture);
    
    	//Jetzt die "RenderTexture"
    	d3dDevice->CreateTexture (512, 512, 
    	                          1, //Keine MipMaps
    							  0, //Kein Usage
    							  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, //Diesmal Default
    							  &d3dTexture, NULL);
    
    	//So ... jetzt SystemTexture auf die RenderTexture kopieren
    	d3dDevice->UpdateTexture (d3dTexture,     //DestinationTexture
    							  d3dSysTexture); //SourceTexture       (VERTAUSCHT)
    
    	for (int i = 0; i < Unendlich; ++i)
    	{
    		//Texture wieder freigeben
    		d3dTexture->Release ();
    
    		//Neu erzeugen
    		d3dDevice->CreateTexture (512, 512, 
    			                      1, //Keine MipMaps
    								  0, //Kein Usage
    								  D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, //Diesmal Default
    								  &d3dTexture, NULL);
    
    		//Und nochmal UpdateTexture
    		d3dDevice->UpdateTexture (d3dTexture,     //DestinationTexture
    								  d3dSysTexture); //SourceTexture       (VERTAUSCHT)
    	}
    

    Hier noch der restliche, wahrscheinlich uninteressante Code

    //////////////////////////////////////////////////////////////////////////
    	// Vertices initialisieren
    	//////////////////////////////////////////////////////////////////////////
    	SVertex Vertices[4];
    	Vertices[0].X = -1;
    	Vertices[0].Y = 1;
    	Vertices[0].Z = 5;
    	Vertices[0].Diffuse = 0xFFFFFFFF;
    	Vertices[0].TextureU = 0;
    	Vertices[0].TextureV = 0;
    	Vertices[1].X = 1;
    	Vertices[1].Y = 1;
    	Vertices[1].Z = 5;
    	Vertices[1].Diffuse = 0xFFFFFFFF;
    	Vertices[1].TextureU = 1;
    	Vertices[1].TextureV = 0;
    	Vertices[2].X = -1;
    	Vertices[2].Y = -1;
    	Vertices[2].Z = 5;
    	Vertices[2].Diffuse = 0xFFFFFFFF;
    	Vertices[2].TextureU = 0;
    	Vertices[2].TextureV = 1;
    	Vertices[3].X = 1;
    	Vertices[3].Y = -1;
    	Vertices[3].Z = 5;
    	Vertices[3].Diffuse = 0xFFFFFFFF;
    	Vertices[3].TextureU = 1;
    	Vertices[3].TextureV = 1;
    
    	//////////////////////////////////////////////////////////////////////////
    	// Rendern
    	//////////////////////////////////////////////////////////////////////////
    
    	d3dDevice->SetTexture (0, d3dTexture);
    	d3dDevice->SetFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
    	d3dDevice->SetRenderState (D3DRS_LIGHTING, false);
    	d3dDevice->SetRenderState (D3DRS_ZENABLE, false);
    
    	do
    	{
    		d3dDevice->Clear (0, NULL, D3DCLEAR_TARGET, 0, 1, 0);
    		d3dDevice->BeginScene ();
    		d3dDevice->DrawPrimitiveUP (D3DPT_TRIANGLESTRIP, 2, &Vertices, sizeof (SVertex));
    		d3dDevice->EndScene ();
    		d3dDevice->Present (NULL, NULL, NULL, NULL);
    
    		if (PeekMessage (&Msg, hWnd, 0, 0, PM_REMOVE))
    		{
    			TranslateMessage (&Msg);
    			DispatchMessage (&Msg);
    		}
    
    	} while (Msg.message != WM_QUIT);
    
    	//////////////////////////////////////////////////////////////////////////
    	// CleanUp
    	//////////////////////////////////////////////////////////////////////////
    
    	d3dTexture->Release ();
    	d3dSysTexture->Release ();
    	d3dDevice->Release ();
    	d3d->Release ();
    
    	UnregisterClass ("WindowClass", hInstance);
    
    	return 0;
    }
    

    Was sagt ihr dazu ????
    Ich bin echt gespannt !!! 😋

    mfg
    Xatian



  • ähm jo ...
    ich habs heute nochmal in der Schule ausprobiert .....
    keine Ahnung wieso aber jetzt gehts vertauscht garnicht mehr 😉

    UpdateTexture mit Params in der richtigen Reihenfolge geht aber trotzdem nur einmal. Wenn ich die Texture dann release, neu erstell und nochmal UpdateTexture aufrufe, seh ich nur Schrott ....
    Was ist da los ????

    mfg
    Xatian



  • Da Du offenbar nicht nur 'nen Clown, sondern 'ne ganze Karnevalsgesellschaft gefrühstückt hast, da Du ÜBERHAUPT KEINEN Fehlerparameter entgegennimmst oder gar überprüfst, kann man natürlich nur wild raten.
    Und die Debug Runtimes sollten auch was melden.

    Allerdings liegt IMHO bei Dir eher ein Verständnisproblem vor, daß durch Lesen der Dokumentation (dafür ist sie da) behoben werden könnte:

    <a href= schrieb:

    http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/directx9_c_summer_03/directx/graphics/reference/d3d/interfaces/idirect3ddevice9/updatetexture.asp">IDirect3DDevice9::UpdateTexture Method

    Updates the dirty portions of a texture.

    [...]

    Remarks

    You can dirty a portion of a texture by locking it, or by calling one of the following methods.

    * IDirect3DCubeTexture9::AddDirtyRect
    * IDirect3DTexture9::AddDirtyRect
    * IDirect3DVolumeTexture9::AddDirtyBox
    * IDirect3DDevice9::UpdateSurface



  • DANKE DANKE DANKE *FREU*

    In der Engine hab ich natürlich alle Fehlercodes getestet aber alles war immer SUCCESS. DebugRuntime hat auch nie einen Fehler gemeldet.
    Das komische war halt, dass beim ersten mal UpdateTexture es funktioniert hat. Nur wenn ich die D3DPOOL_DEFAULT Texture wieder released habe, neu erstellt hab und dann nochmal UpdateTexture aufgerufen hab, hats nicht mehr funktioniert ...also ich hab nur noch einen Pixelhaufen gesehen ... UpdateTexture hat aber so wie alle anderen Funktionen keinen Fehler zurückgeworfen.

    Jo und die Doku verwende ich regelmäßig !! Das mit dem AddDirtyRect hatte ichauch schon probiert, hat aber nix gebracht ....
    Bloß ich hab immer auf der D3DPOOL_DEFAULT Texture das AddDirtyRect() aufgerufen .... jetzt hab ichs mal bei der im SystemSpeicher probiert und jetzt funzt !! 😃
    Also du hattest recht .... war ein Verständnisproblem 🕶

    mfg
    Xatian


Anmelden zum Antworten