Gibt es hier jemanden der mithilfe von DierctX 9.0 (D3D9) erfolgreich ein einfaches 2D Spiel erstellt hat?
-
> 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; } };
-
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();
-
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 ?
-
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, ...)
-
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