Gibt es hier jemanden der mithilfe von DierctX 9.0 (D3D9) erfolgreich ein einfaches 2D Spiel erstellt hat?



  • Im Buch geht es NUR um 3D.


  • Mod

    und wieso steht in der themenbeschriebung das eben zitierte über einen 2d arkanoid clone (mit 2D-Grafik arbeiten (obwohl DirectDraw gestorben ist)?)

    ?

    ich hab es nicht gelesen also kann ich mich dazu nicht äußern, aber den index entnahm ich das

    rapso->greets();



  • in d9 kann man immernoch directdraw von 8 verwenden,
    für 2d war halt einfach nix mehr zu verbessern.


  • Mod

    von 7
    zu verbessern war/ist vieles, aber es wäre eh alles mit der 3d hardware emuliert worden, also können das die entwickler auch selber machen.

    rapso->greets();



  • > ja ich hab mehrere kleine games so gemacht

    kannst du vielleicht mal Sourcecode von einem dieser games zum downloaden anbieten? wäre sehr nett - ich habe nämlich so meine Probleme - auf meiner TNT2 sieht alles normal aus nur bei manchen Leuten gibt es grüne Striche und ich weiß nicht warum...

    es würde schon reichen wenn du zeigst wie man ein einziges Sprite aus einer BMP Datei darstellen kann... verwendest du vielleicht eine selbstgeschrieben Texturlade funktion - hab festgestellt das die D3DXCreateTextureFromFileEx auch D3D_OK zurückliefert wenn der Texturbuffer nicht richtig erstellt werden konnte z. B. die von der Grafikkarte unterstützte maximale Texturgröße übersteigert wurde - das führ bei meinem "Code" zu unschönen Grafikfehlern

    so sieht mein programmcode der sprite.h aus - ist quick & dirty

    #include <d3d9.h>
    #include <d3dx9.h>
    #include <stdio.h>
    #include "timer.h"
    #include "log.h"
    
    Engine_Log Log;
    bool schalter = 0;
    
    // Our custom FVF, which describes our custom vertex structure
    #define D3DFVF_SPRITE_VERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
    
    class CSprite
    {
    private:
    	// A structure for our custom vertex type
    	struct SPRITE_VERTEX
    	{
    		FLOAT x, y, z, rhw; // The transformed position for the vertex
    		DWORD color;        // The vertex color
    		FLOAT tu, tv;		// Texturkoordinaten
    	};
    
    	LPDIRECT3DVERTEXBUFFER9 g_pVB;			// Buffer to hold vertices
    	LPDIRECT3DTEXTURE9		g_pTexture;		// Buffer to hold the texture
    
    	HRESULT InitVB(LPDIRECT3DDEVICE9  g_pd3dDevice)		// Create the vertexbuffer
    	{
    		// Create the vertex buffer
    		if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(SPRITE_VERTEX),
    													  D3DUSAGE_DYNAMIC, D3DFVF_SPRITE_VERTEX,
    													  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    		{
    			return E_FAIL;
    		}
    
    		return S_OK;
    	}
    
    	HRESULT Modify_VertexBufferEx(float x, float y, float frame)
    	{
    		int frames_per_zeile = frames_per_row;
    
    		// Texturkoordinaten
    		float frame_borders_in_texel_left = 0;
    		float frame_borders_in_texel_right = 0;
    		float frame_borders_in_texel_top = 0;
    		float frame_borders_in_texel_bottom = 0;
    
    		if(frame < (frames_per_zeile-1) || frame == (frames_per_zeile-1))
    		{
    
    		// Texturkoordinaten berechnen
    		 frame_borders_in_texel_left =  (frame*frame_width+frame*Cell_Space_Width) / picture_width;
    		 frame_borders_in_texel_right = (frame*frame_width+frame*Cell_Space_Width+frame_width) / picture_width;
    		 frame_borders_in_texel_top = 0;
    		 frame_borders_in_texel_bottom = frame_height / picture_height;
    		}
    		else 
    		{
    			// In welcher Zeile befinden wir uns - wir fangen mit der 0ten Zeile an
    			int zeilen_nummer = frame / frames_per_zeile;
    			float fzeilen_nummer = zeilen_nummer;
    
    			frame = frame - zeilen_nummer * frames_per_zeile;
    
    			// Texturkoordinaten berechnen
    			frame_borders_in_texel_left =  (frame*frame_width+frame*Cell_Space_Width) / picture_width;
    			frame_borders_in_texel_right = (frame*frame_width+frame*Cell_Space_Width+frame_width) / picture_width;
    			frame_borders_in_texel_top = (fzeilen_nummer*frame_height+fzeilen_nummer*Cell_Space_Height) / picture_height;
    			frame_borders_in_texel_bottom = (frame_height + fzeilen_nummer*frame_height+fzeilen_nummer*Cell_Space_Height) / picture_height;
    		}
    
    		// Initialize four vertices for rendering a sprite
    		SPRITE_VERTEX vertices[] =
    		{
    			{ x+0.0f,		 y+0.0f, 0.0f, 1.0f, 0xffffffff,                 frame_borders_in_texel_left,  frame_borders_in_texel_top}, 
    			{ x+frame_width, y+0.0f, 0.0f, 1.0f, 0xffffffff,          frame_borders_in_texel_right, frame_borders_in_texel_top},
    			{ x+0,			 y+frame_height, 0.0f, 1.0f, 0xffffffff,            frame_borders_in_texel_left,  frame_borders_in_texel_bottom},
    			{ x+frame_width, y+frame_height, 0.0f, 1.0f, 0xffffffff,  frame_borders_in_texel_right,	frame_borders_in_texel_bottom}, 
    		};
    
    		VOID* pVertices;
    		if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
    			return E_FAIL;
    		memcpy( pVertices, vertices, sizeof(vertices) );
    		g_pVB->Unlock();
    
    		return S_OK;
    	}
    
    	Timer time;
    	bool timer_init;
    	float actual_frame;
    
    	char filename[200];
    	float frame_width;
    	float frame_height;
    	float picture_width;
    	float picture_height;
    	float position_x;
    	float position_y;
    	float Cell_Space_Width;
    	float Cell_Space_Height;
    	float frames_per_row;
    	float start_frame;
    	float end_frame;
    	float animation_speed;
    public:
    
    	void Init(char *cfilename, LPDIRECT3DDEVICE9  g_pd3dDevice)
    	{
    		timer_init = false;
    		actual_frame = 0;
    
    		g_pVB = NULL;
    		g_pTexture = NULL;
    
    		FILE *player;
    		player = fopen(cfilename, "r");
    
    		// Einlesen
    		fscanf(player, "filename %s\n", filename);
    		fscanf(player, "frame_width %f\n", &frame_width); 
    		fscanf(player, "frame_height %f\n", &frame_height);
    		fscanf(player, "picture_width %f\n", &picture_width);
    		fscanf(player, "picture_height %f\n", &picture_height);
    		fscanf(player, "position_x %f\n", &position_x);
    		fscanf(player, "position_y %f\n", &position_y);
    		fscanf(player, "Cell_Space_Width %f\n", &Cell_Space_Width);
    		fscanf(player, "Cell_Space_Height %f\n", &Cell_Space_Height);
    		fscanf(player, "frames_per_row %f\n", &frames_per_row);
    		fscanf(player, "start_frame %f\n", &start_frame);
    		fscanf(player, "end_frame %f\n", &end_frame);
    		fscanf(player, "animation_speed %f\n", &animation_speed);
    		fclose(player);
    
    		InitVB(g_pd3dDevice);
    
    		if(schalter==false)
    		{
    			Log.SetFilename("Log.txt");
    			Log.Reset();
    			schalter = true;
    		}
    
    		// Textur laden
    		//	D3DXCreateTextureFromFile(g_pd3dDevice, "TIE_burnout.bmp", &g_pTexture);
    		HRESULT Result;
    
    		Result = D3DXCreateTextureFromFileEx(g_pd3dDevice, filename,
    									picture_width, picture_height,
    									0, 0, D3DFMT_UNKNOWN,
    									D3DPOOL_DEFAULT , D3DX_FILTER_NONE, 
    									D3DX_FILTER_NONE, D3DCOLOR_ARGB(0, 255, 0, 255), 
    									NULL, NULL, &g_pTexture);
    
    		if(Result==D3D_OK)
    		{
    			char Buffer[300];
    			sprintf(Buffer, "%s konnte erfolgreich geladen werden\n", filename);
    			Log.InsertStatement(Buffer);
    		}
    		else
    		{
    			char Buffer[300];
    			sprintf(Buffer, "Error: %s konnte erfolgreich geladen werden\n", filename);
    			Log.InsertStatement(Buffer);
    
    			// Warum nicht?
    			if(Result==D3DERR_NOTAVAILABLE)
    			{
    				Log.InsertStatement("This device does not support the queried technique.\n");
    			}
    
    			if(Result==D3DERR_OUTOFVIDEOMEMORY)
    			{
    				Log.InsertStatement("Microsoft® Direct3D® does not have enough display memory to perform the operation.\n");
    			}
    
    			if(Result==D3DERR_INVALIDCALL)
    			{
    				Log.InsertStatement("The method call is invalid. For example, a method's parameter may have an invalid value.\n");
    			}
    
    			if(Result==D3DXERR_INVALIDDATA)
    			{
    				Log.InsertStatement("The data is invalid.\n");
    			}
    
    			if(Result==E_OUTOFMEMORY)
    			{
    				Log.InsertStatement("Direct3D could not allocate sufficient memory to complete the call.\n");
    			}
    		}
    
    		// Alphablending
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    		g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    		g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHAREF, 0x00000000);
    		g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
    
    	}
    
    	void Draw(LPDIRECT3DDEVICE9  g_pd3dDevice)
    	{
    		if(timer_init==false)
    		{
    			time.reset();
    			timer_init = true;
    			actual_frame = 0;
    		}
    
    		if(time.get_time() > animation_speed)
    		{
    			actual_frame++;
    
    			if(actual_frame > end_frame)
    				actual_frame = start_frame;
    
    			time.reset();
    		}
    
    		Modify_VertexBufferEx(position_x, position_y, actual_frame);
    
    		// Begin the scene
    		if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    		{
    			// Textur setzen
    			g_pd3dDevice->SetTexture( 0, g_pTexture );
    			g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTA_TEXTURE);
    			g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTA_TEXTURE);
    			// Draw the triangles in the vertex buffer. This is broken into a few
    			// steps. We are passing the vertices down a "stream", so first we need
    			// to specify the source of that stream, which is our vertex buffer. Then
    			// we need to let D3D know what vertex shader to use. Full, custom vertex
    			// shaders are an advanced topic, but in most cases the vertex shader is
    			// just the FVF, so that D3D knows what type of vertices we are dealing
    			// with. Finally, we call DrawPrimitive() which does the actual rendering
    			// of our geometry (in this case, just one triangle).
    			g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(SPRITE_VERTEX) );
    			g_pd3dDevice->SetFVF( D3DFVF_SPRITE_VERTEX );
    			g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
    
    			// End the scene
    			g_pd3dDevice->EndScene();
    		}
    	}
    
    	void DrawEx(LPDIRECT3DDEVICE9 g_pd3dDevice, dword delta_time)
    	{
    		int i_actual_frame = delta_time / animation_speed;
    		actual_frame = i_actual_frame;
    
    		if(actual_frame < start_frame || actual_frame > end_frame)
    			actual_frame = start_frame;
    
    		Modify_VertexBufferEx(position_x, position_y, actual_frame);
    
    		// Begin the scene
    		if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    		{
    			// Textur setzen
    			g_pd3dDevice->SetTexture( 0, g_pTexture );
    			g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTA_TEXTURE);
    			g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTA_TEXTURE);
    			// Draw the triangles in the vertex buffer. This is broken into a few
    			// steps. We are passing the vertices down a "stream", so first we need
    			// to specify the source of that stream, which is our vertex buffer. Then
    			// we need to let D3D know what vertex shader to use. Full, custom vertex
    			// shaders are an advanced topic, but in most cases the vertex shader is
    			// just the FVF, so that D3D knows what type of vertices we are dealing
    			// with. Finally, we call DrawPrimitive() which does the actual rendering
    			// of our geometry (in this case, just one triangle).
    			g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(SPRITE_VERTEX) );
    			g_pd3dDevice->SetFVF( D3DFVF_SPRITE_VERTEX );
    			g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
    
    			// End the scene
    			g_pd3dDevice->EndScene();
    		}	
    	}
    
    	void Shutdown(void)
    	{
    		if(g_pTexture != NULL)
    			g_pTexture->Release();
    
    		if(g_pVB != NULL)        
    			g_pVB->Release();
    	}
    
    	void SetPositon(float x, float y)
    	{
    		position_x = x;
    		position_y = y;
    	}
    
    	float GetFrameWidth(void)
    	{
    		return frame_width;
    	}
    
    	float GetFrameHeight(void)
    	{
    		return frame_height;
    	}
    
    	void SetAnimationSpeed(float s)
    	{
    		animation_speed = s;
    	}
    
    	void SetFrame(int frame)
    	{
    		start_frame = frame;
    		end_frame = frame;
    		actual_frame = frame;
    	};
    
    	float GetEndFrame(void)
    	{
    		return end_frame;
    	}
    
    	float GetStartFrame(void)
    	{
    		return start_frame;
    	}
    
    	float GetAnimationSpeed(void)
    	{
    		return animation_speed;
    	}
    
    };
    

  • Mod

    ich lade alles selbst ein und zeichne das auch alles mittels triangles (mit vertices und indices). hab das problem also irgendwie noch nie.
    vielleicht ist die größe deines bildes nicht schön quadratisch, was noch sein könnte wäre, dass du D3DFMT_A8R8G8B8 versuchen könntest, denn default kann auch dxt1 verwendet werden falls die graka das unterstützt (macht deine ja nicht) und deswegen mit konvertierungen falsch aussehen.

    falls nicht, schau ich mir den code noch mehr an :).. kannst dich aber auch im chat melden, hast ja den irc server und sogar icq von mir 😉

    rapso->greets();


  • Mod

    beim berechnen der texturcoordinaten scheint es mir, als würdest du dich nicht an die dx9 doku halten für korrecktes uv-mapping... 😃

    rapso->greets();



  • Ich bin auch gerade bei Überlegungen wegen 2D. Geht es denn auch ohne die Transformierten Vertrizen indem man einfach die Projektionsmatrix auf die Identitätsmatrix stellt oder irgendwas anderes? Dann hat man kein Problem wegen Rotation usw.

    Edit: Habe was gefunden. Es gibt eine Orthogonal ProjektionsMatrix. Die passt genau da rein bei dem was ich machen wollte.



  • Da mir anscheinend niemand mit meinem SDL-Problem helfen kann, suche ich ein Tutorial für 2D-Spiele in DirectX 9. Da es da DDraw ja offiziell nicht mehr gibt, muss das irgendwie anders gehen. (Oder muss ich da einfach die alte DDraw Version nutzen?)

    Naja bis den.



  • Hab ich was verpasst ? 😕
    Warum gibt es kein DirectDraw mehr ?
    Ich nehme an es wird nicht mehr weiterentwickelt oder ? Schade eigentlich,
    ich hatte immer den Eindruck 2D sei bei DX langsamer als 3D. Woran liegt das ?`
    Ich schweife vom Thema ab 😃
    Also: Was ist mit DirectDraw ?


  • Mod

    du kannst ddraw nutzen, du kannst d3d9 nutzen oder du nutzt eine 2d-engine (gibt bei google unmengen von), natürlich geht das auch alles mit openGL, sdl...

    rapso->greets();



  • Nein, es wurde höchstens DirectX 9.0 benutzt. 😉 Aber Libs sind für 95% des Codes ehh egal.



  • Entschuldigung, aber ich blicke noch nicht durch. Bin eben noch neu in der Materie.

    Was muss ich machen, wenn ich mit DirectX 9 ein 2D Game basteln will? (Nix SDL, OpenGL, ...)


  • Mod

    http://www.gamasutra.com/features/20010629/geczy_01.htm

    eventuell mußt du dir da ein login besorgen, aber oft lohnt sich das 😃

    rapso->greets();



  • Gibts das auch in Deutsch? Nein scherz 😃 😃

    danke für den link


Anmelden zum Antworten