|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 12:25 Titel: Mehrere Sprite instanzen |
|
|
Hallo!
ich habe ein problem mit meiner sprite klasse.
wenn ich mehrere instanzen dieser klasse anlege, wird kein sprite mehr angezeigt, und der bildschirm bekommt die farbe des sprites was zuletzt angezeigt werden sollte! |
|
Nach oben |
|
|
Robrunner Mini JLI'ler
Alter: 32 Anmeldedatum: 08.07.2007 Beiträge: 44 Wohnort: Passau Medaillen: Keine
|
Verfasst am: 25.07.2007, 12:50 Titel: |
|
|
Etwas Quellcode bitte! |
|
Nach oben |
|
|
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 13:05 Titel: |
|
|
hier die wichtigsten methoden der CSprite klasse
CPP: | void CSprite::Create(LPDIRECT3DDEVICE9 lpDevice)
{
m_lpDevice = lpDevice;
// Sprite anlegen
D3DXCreateSprite(m_lpDevice, &m_lpSprite);
// Skalierung und Schrittweise setzen
m_vScale = D3DXVECTOR2(1.0f, 1.0f);
// Schrittweise des Sprites bei Bewegung
m_StepX = 10.0f;
m_StepY = 10.0f;
}
void CSprite::AddTexture(LPDIRECT3DTEXTURE9 lpTexture)
{
// Informationen über die Textur holen
D3DSURFACE_DESC desc;
lpTexture->GetLevelDesc(0, &desc);
// Breite und Höhe speichern
m_Width = desc.Width;
m_Height = desc.Height;
m_vCenter =
D3DXVECTOR3(static_cast<float>(m_Width) / 2.0f,
static_cast<float>(m_Height) / 2.0f,
0.0f);
// Zeiger auf die Textur speichern
m_AnimationVec.push_back(lpTexture);
}
void CSprite::Draw()
{
D3DXMATRIX Matrix;
D3DXMatrixTransformation2D(
&Matrix,
reinterpret_cast<D3DXVECTOR2*>(&m_vCenter),
0.0f,
&m_vScale,
reinterpret_cast<D3DXVECTOR2*>(&m_vCenter),
m_Rotation,
reinterpret_cast<D3DXVECTOR2*>(&m_vPosition));
// Transformations-Matrix setzen
m_lpSprite->SetTransform(&Matrix);
m_lpSprite->Begin(D3DXSPRITE_ALPHABLEND);
DWORD ModulateColor = 0xFFFFFFFF;
// Sprite zeichnen
m_lpSprite->Draw(m_AnimationVec[static_cast<size_t>(m_CurrentImage)],
NULL,
NULL,
NULL,
ModulateColor);
m_lpSprite->End();
} |
und hier die addtexture Methoden des resourcemanagers
CPP: | LPDIRECT3DTEXTURE9 CResourceManager::AddTexture(LPCSTR lpFileName)
{
LPDIRECT3DTEXTURE9 lpTexture = NULL;
// Wenn die Textur bereits existiert
if(lpTexture = m_MapTextures[lpFileName])
{
return lpTexture;
}
else
{
D3DXIMAGE_INFO ImageInfo;
D3DXGetImageInfoFromFile(lpFileName, &ImageInfo);
D3DXCreateTextureFromFileEx(m_lpD3DDevice,
lpFileName,
ImageInfo.Width,
ImageInfo.Height,
1, 0,
D3DFMT_UNKNOWN,
D3DPOOL_MANAGED,
D3DX_FILTER_NONE,
D3DX_FILTER_NONE,
0, 0, 0,
&lpTexture);
// und in die Map unter ihren Namen eingefügt
m_MapTextures[lpFileName] = lpTexture;
return lpTexture;
}
} |
wenn ich jetzt ca 3 oder 4 instanzen der sprite klasse anlege
(und immer den zeiger auf die selbe resource klasse)
werden nicht alle sprites angezeigt, einige werden tansparent oder der gesamte bildschirm bekommt die farbe eines sprites.
die draw methode wird immer zwischen dem aufruf der beiden methoden beginscene und endscene, der klasse cdirect3d, aufgerufen.
das selbe problem hatte ich als ich ein beispiel programm (ein asteroidenfeld) aus meinem buch nachprogrammiert hatte (spieleprogrammierung mit directx)
der autor hat die instanzen der sprite klasse global definiert.
und so gibt es auch keine probleme. wenn ich die instanzen in der main funtion definiere habe ich wieder das oben beschriebene problem!
<edit TLoP>
Bitte in Zukunft statt [ code ] die [ cpp ]-Tags verwenden. Danke
</edit TLoP> |
|
Nach oben |
|
|
Robrunner Mini JLI'ler
Alter: 32 Anmeldedatum: 08.07.2007 Beiträge: 44 Wohnort: Passau Medaillen: Keine
|
Verfasst am: 25.07.2007, 13:43 Titel: |
|
|
Ich weiß nicht, ob es das ist, aber in der AddTexture Methode muss es heißen: CPP: | if(lpTexture == m_MapTextures[lpFileName]) | also zwei = und nicht nur eines. |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 25.07.2007, 13:43 Titel: |
|
|
-=|BLACK|=- hat Folgendes geschrieben: | CPP: | // Wenn die Textur bereits existiert
if(lpTexture = m_MapTextures[lpFileName])
{
return lpTexture;
} |
|
Hmm...ich kann mir nicht vorstellen, dass das irgendwas Sinnvolles bringt
1. Vergleichsoperator verwenden
2. Der []-Operator der std::map(ist m_MapTextures eine solche?) legt automatisch ein Element an, sofern verhanden. Falls du nach einem Element suchen willst, nutze die Methode find(). Ist m_MapTextures ein normales Array, wärs hilfreich, davon noch mehr zu sehen.
PS: Thema Verschoben. In Grafik&Sound keine DirectX und OpenGL bezogene Codes. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 13:48 Titel: |
|
|
nee daran liegt es nicht!
das habe ich schon kontrolliert!
es werden keine doppelten grafiken angelegt!
denn wenn ich ein element in der map hinzufügen will, geht dass nur wenn das element noch nicht vorhanden ist! wenn es vorhanden ist, gibt der aufruft false zurück!
wenn nicht true! |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 25.07.2007, 15:50 Titel: |
|
|
@TLOP & Robrunner:
Nein daran liegt es nicht, der Test ist schon korrekt (wenn auch etwas komplex zusammengefasst, aber im Grunde nicht schlecht ;) ) Das wird deutlich wenn man sich das so vorstellt: CPP: | if( m_MapTextures[lpFileName] != 0 )
{
return m_MapTextures[lpFileName];
} | Im Grunde hat er nur das != 0 weggelassen, was in einer if-Abfrage sowieso möglich ist, und dann diesen Wert einer Variablen zugewiesen. maps legen zwar die Werte noch nicht vorhandener Keys im op[] automatisch an, und initialisieren sie aber mit dem Standardkonstruktor. Und ein explizit aufegrufener Konstruktor eines Zeigers (wie das im Template der Map durch T() gemacht wird) initialisiert diesen mit NULL.
Gruß DXer |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 25.07.2007, 19:52 Titel: |
|
|
das hier ist falsch
CPP: | void CSprite::Draw()
{
// ...
m_lpSprite->Begin(D3DXSPRITE_ALPHABLEND);
// ...
m_lpSprite->End();
// ...
}
|
Das heißt du löschst bei jedem Zeichenvorgang den gesammten Bildschirm und gibst die Anweisung, den Backbuffer mit dem Frontbuffer zu tauschen.
Pack das "Begin" und "End" in separate Funktionen und ruf es nur einmal pro Schleifendurchlauf auf. |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 25.07.2007, 21:15 Titel: |
|
|
@Chris: Der Codeausschnitt den du grade gezeigt hast tut aber nichts dergleichen oO sicher das du nicht den falschen erwischst hast? Auch der Orignalcode zeigt keine Present oder Clear Anweisung.
Begin und End seperat aufzurufen bei jedem Rendercall mag zwar von der OPerformance her nicht die beste Lösung zu sein, aber vom Renderergebniss durchaus vertretbar.
@-=|BLACK|=-:
Bitte poste mal den ganzen relevanten Code oder wenn möglich eine eine lauffähige Version des gesammten Projektes, so das man es "Hautnah" nachvollziehen kann. (aus diversen chemischen Gründen kann ich den Code sowieso nicht 100% nachprüfen, sry) _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 21:52 Titel: |
|
|
CPP: | bool CDirect3D::Init(HWND hWnd, BOOL bWindowed)
{
// Direct3D-Objekt erzeugen
m_lpD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(NULL == m_lpD3D)
{
// Fehler, D3D-Objekt wurde nicht erzeugt
return false;
}
// Parameter für den Modus festlegen
D3DPRESENT_PARAMETERS PParams;
ZeroMemory(&PParams, sizeof(PParams));
PParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
PParams.hDeviceWindow = hWnd;
PParams.Windowed = bWindowed;
PParams.BackBufferWidth = 1024;
PParams.BackBufferHeight = 768;
PParams.BackBufferFormat = D3DFMT_A8R8G8B8;
HRESULT hr;
// Direct3D-Gerät anlegen
if(FAILED(hr = m_lpD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PParams,
&m_lpD3DDevice)))
{
// Fehler, kann Gerät nicht anlegen
LPCSTR err = DXGetErrorDescription9(hr);
DXTRACE_MSG(err);
MessageBox(NULL, err, "Fehler", MB_OK);
return false;
}
return true;
}
void CDirect3D::BeginScene()
{
// Backbuffer füllen
m_lpD3DDevice->Clear(0, 0,
D3DCLEAR_TARGET,
m_ClearColor,
0, 0);
// D3D mitteilen, dass eine Szene beginnt
m_lpD3DDevice->BeginScene();
}
void CDirect3D::EndScene()
{
// D3D mitteilen, dass eine Szene endet
m_lpD3DDevice->EndScene();
// Backbuffer anzeigen
m_lpD3DDevice->Present(0, 0, 0, 0);
}
void CGameManager::DrawScene()
{
m_D3DDevice->BeginScene();
// Hier werden die Draw Methoden der Sprite Objekte aufgerufen
m_D3DDevice->EndScene();
}
|
so hier noch die wichtigestn methoden der direct3d-klasse (hiervon wird nur eine instanz erzeugt und die adresse an die sprite objekte übergeben! |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 25.07.2007, 22:01 Titel: |
|
|
rufst du um CGameManager::DrawScene() auch CDirect3D::BeginScene() und CDirect3D::EndScene() auf? Wenn ja liegt dort der Fehler, da du jeweils 2x IDirect3DDevice::BeginScene() bzw. End- aufrufst.
Gruß DXer
Zuletzt bearbeitet von DirectXer am 25.07.2007, 23:14, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 22:13 Titel: |
|
|
nein! beginscene und endscene der direct3d klasse wird nur einmal aufgerufen!
kann es irgendwie daran liegen, dass man nicht so viele sprite objekte erzeugen sollte? |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 25.07.2007, 22:37 Titel: |
|
|
hmm eigentlich nicht... Ich sehe keinen Grund warum die Anzahl Sprites softwäremäßig begrenzt sein sollte, und hardwäremäßig ist das bei heutigen Leistungen nicht denkbar. Kanns vllt sein dass deine Grafikkarte nur bestimmte Texturen unterstützt? (so 2^ oder squared) Was hast du denn für eine? Oder hast du mal probiert ob es Windowed / Fullscreen läuft?
Gruß DXer |
|
Nach oben |
|
|
-=|BLACK|=- Mini JLI'ler
Alter: 41 Anmeldedatum: 25.07.2007 Beiträge: 18
Medaillen: Keine
|
Verfasst am: 25.07.2007, 22:51 Titel: |
|
|
aso eine gute grafikkarte ist das nich.. is die auf meinem notebook das is eine von sis.
naja un im fullscreen modus lass ich dass immer laufen!
ich bin gerade den resource manager so am umbauen, dass jede textur oder animation einen namen bekommt!
die csprite klasse soll dann den namen übergeben bekommen und sich die textur beim resource manager holen.
dann brauch ich insgesamt nur 1 sprite objekt, dass ich dann den klassen die eins brauchen kann über einen pointer übergeben kann.
ma gucken ob das klappt! |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 25.07.2007, 23:15 Titel: |
|
|
Ja also wenn du immer fullscreen machst kannst du ja ma gucken ob sich im windowed was ändert...
btw: Du sagst, das Problem kommt nur wenn du die Sprites lokal in der main definierst? Dann zeig die doch mal her
Gruß DXer |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|