|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
marvin12345 Mini JLI'ler
Anmeldedatum: 26.02.2006 Beiträge: 1
Medaillen: Keine
|
Verfasst am: 26.02.2006, 22:15 Titel: DirectX Draw() 9b -> 9c |
|
|
Was mache ich falsch?
Das eingelesene Sprite wird nicht dargestellt!
Es gibt offensichtlich Probleme mit der Draw-Function.
Das Programm läuft im Visual-C++-Debugger fehlerfrei.
Wäre für jeden Tipp dankbar!
Vielen Dank im voraus!
Marvin
CPP: | #include<d3d9.h>
#include<d3dx9.h>
#include<d3dx9tex.h>
#include<d3dx9math.h>
#include<stdio.h>
#include<stdlib.h>
// Anwendungsfenster erzeugen
HWND CreateMainWindow(HINSTANCE hInstance);
// Callback-Funktion zur Nachrichtenbehandlung
BOOL Init(HWND hWnd, BOOL bWindowed = TRUE);
LPDIRECT3D9 lpD3D = NULL;
LPD3DXSPRITE lpSprite = NULL;
LPDIRECT3DDEVICE9 lpD3DDevice = NULL;
LPDIRECT3DSURFACE9 lpBackBuffer = NULL;
LPDIRECT3DTEXTURE9 lpSpriteTexture = NULL;
LPD3DXFONT lpD3DFont = NULL;
HWND hWnd = 0;
void CreateD3DFont(void);
void LadeSprite(void);
class CDirect3D
{
public:
// CDirect3D();
// virtual ~CDirect3D();
// Farbe für den Backbuffer festlegen
void SetClearColor(void);
// Methoden zum Starten/Beenden der Scene
void BeginScene(void);
void EndScene(void);
protected:
// Farbe für den Backpuffer
D3DCOLOR m_ClearColor;
};
void CDirect3D::BeginScene(void)
{
// Backpuffer füllen
lpD3DDevice->Clear(0,0,
D3DCLEAR_TARGET,
m_ClearColor,
0,0);
// D3D mitteilen, dass eine Szene beginnt
lpD3DDevice->BeginScene();
}
void CDirect3D::EndScene(void)
{
// Sprite soll nicht skaliert werden
D3DCOLOR TextColor = D3DCOLOR_XRGB(0xFF,0,0);
D3DXVECTOR2 vScaling(1.0f,1.0f);
// Punkt, um den das Sprite gedreht werden soll
D3DXVECTOR3 vRotationCenter(0.0f,10.0f,0.0f);
// Sprite soll nicht rotiert werden
float Rotation = 4.0f;
// Spite an Position 250, 250 zeichnen
D3DXVECTOR3 vPosition(0.0f,10.0f,20.0f);
// Farben der Textur sollen nicht verändert werden
D3DCOLOR ModulateColor = 0xFFFFFFFF;
// lpSprite->Draw(lpSpriteTexture,
// NULL,
// &vRotationCenter,
// &vPosition,
// ModulateColor);
lpSprite->Draw(lpSpriteTexture,
NULL,
NULL,
NULL,
ModulateColor);
// D3D mitteilen, dass eine Szene endet
lpD3DDevice->EndScene();
lpD3DDevice->Present(0,0,0,0);
}
void CDirect3D::SetClearColor(void)
{
m_ClearColor = D3DCOLOR_XRGB(0,0,0xFF);
}
// Gibt alle Direct3D-Objekte wieder frei
void CleanUpD3D(void)
{
// testen, ob die Objekte angelegt wurden
// und gebenenenfalls freigeben
if(NULL != lpSprite)
{
lpSprite->Release();
lpSprite = NULL;
}
if(NULL != lpBackBuffer)
{
lpBackBuffer->Release();
lpBackBuffer = NULL;
}
if(NULL != lpSpriteTexture)
{
lpSpriteTexture->Release();
lpSpriteTexture = NULL;
}
if(NULL != lpD3DDevice)
{
lpD3DDevice->Release();
lpD3DDevice = NULL;
}
if(NULL != lpD3D)
{
lpD3D->Release();
lpD3D = NULL;
}
}
// Windows Main-Programm
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
CDirect3D Direct3D;
// Fenster erzeugen und Handle speichern
hWnd = CreateMainWindow(hInstance);
// Wenn Rückgabewert 0, ist ein Fehler aufgetreten
if(0 == hWnd)
{
// Fehler, Fenster konnte nicht erzeugt werden
return -1;
}
BOOL bWindowed=TRUE;
if(!Init(hWnd, bWindowed))
{
// Fehler beim Initialisieren von D3D
return -1;
}
// Struktur, mit Informationen zur Nachricht
MSG msg= {0};
// Alle Grafiken in Surface laden
LadeSprite();
// Schleife läuft bis WM_QUIT empfangen wird
while(msg.message != WM_QUIT)
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Direct3D.SetClearColor();
Direct3D.BeginScene();
Direct3D.EndScene();
}
// Direct3D-Objekte wieder freigeben
CleanUpD3D();
// Rückgabewert an Windows
return 0;
}
// Direct3D Initialisieren
BOOL Init(HWND hWnd, BOOL bWindowed)
{
// Direct3D-Objekt erzeugen
lpD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(NULL == 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.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
PParams.hDeviceWindow = hWnd;
PParams.Windowed = bWindowed;
PParams.BackBufferWidth = 512;
PParams.BackBufferHeight = 512;
PParams.BackBufferFormat = D3DFMT_A8R8G8B8;
//Direct3D-Gerät anlegen
if(FAILED(lpD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PParams,
&lpD3DDevice)))
{
// Fehler, kann Gerät nicht anlegen
return FALSE;
}
lpD3DDevice->GetBackBuffer(0,0,
D3DBACKBUFFER_TYPE_MONO,
&lpBackBuffer);
return TRUE;
}
// Diese Funktion wird von Windows aufgerufen, wenn
// eine Nachricht für Ihr Programm vorliegt
LRESULT CALLBACK MessageHandler(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
CDirect3D Direct3D;
// testen, um welche Nachricht es sich handelt
switch(msg)
{
// Programm beenden, wenn das Fenster geschlossen wird
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYDOWN:
switch(wParam)
{
// Wenn ESC gedrückt, Anwendung beenden
case VK_ESCAPE:
DestroyWindow(hWnd);
break;
}
case WM_PAINT:
Direct3D.SetClearColor();
Direct3D.BeginScene();
Direct3D.EndScene();
break;
}
// Standardnachrichtenverarbeitung von Windows
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
HWND CreateMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wndClass =
{
sizeof(WNDCLASSEX),
CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW,
MessageHandler,
0,
0,
hInstance,
LoadIcon(NULL, IDI_WINLOGO),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH),
NULL,
"WindowClass",
LoadIcon(NULL, IDI_WINLOGO)
};
// Fensterklasse registrieren, damit sie von
// CreateWindowEx(&wndClass);
RegisterClassEx(&wndClass);
// Der Rückgabewert von CreateEWindowWx() ist auch der
// Rückgabewert der Funktion
return CreateWindowEx
(
NULL,
"WindowClass",
"FirstSprite by MWsoft, Abbruch mit Escape-Taste",
WS_OVERLAPPEDWINDOW |
WS_VISIBLE,
0, 0,
512, 512,
NULL,
NULL,
hInstance,
NULL);
}
LPDIRECT3DDEVICE9 GetDevice(void)
{
return lpD3DDevice;
}
void LadeSprite(void)
{
// Textur laden aus der Datei Sila.png
lpD3DDevice = GetDevice();
D3DXCreateTextureFromFile(lpD3DDevice,
"Exam.png",
&lpSpriteTexture);
// Sprite kreiern
D3DXCreateSprite(lpD3DDevice,&lpSprite);
}
void CreateD3DFont(void)
{
// Struktur für die Beschreibung der Schriftart
// anlegen und Elemente mit 0 initialisieren
D3DXFONT_DESC LogFont = { 0 };
// Das Element lfFaceName muss den Namen der
// gewünschen Schriftarten enthalten
strcpy(LogFont.FaceName, "Arial");
LogFont.Height=80;
// nach erfolgreichem Aufruf zeigt lpD3DFont
// auf ein Objekt vom Typ D3DXFont
D3DXCreateFontIndirect(lpD3DDevice,
&LogFont,
&lpD3DFont);
}
|
Kampfhund: Bitte cpp-Tags verwenden. |
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 27.02.2006, 08:28 Titel: |
|
|
Zitat: |
Es gibt offensichtlich Probleme mit der Draw-Function.
Das Programm läuft im Visual-C++-Debugger fehlerfrei.
|
Und wo läuft es nicht fehlerfrei? Wie startest du das Programm? Ist der Pfad zu Exam.png korrekt (exe + png im gleichen VZ)?.
Meiner Meinung nach fehlt da noch ein
CPP: | lpSprite->Begin(0); // oder Mode
...
lpSprite->End();
|
wenn es DX9c ist. Es sollte dann aber auch in VC nicht laufen.
Christian
Zuletzt bearbeitet von Christian Rousselle am 27.02.2006, 19:51, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 27.02.2006, 12:12 Titel: |
|
|
Patrick hat Folgendes geschrieben: | 1. Finger weg von Direct3D Extensions, die braucht 1. kein guter Coder und 2. sind die Dinger sowieso nicht abwärtskompatibel!
2. Benutz Vertexbuffer und werd ein guter Coder. |
Äh, hallo? Das ist ein Anfänger. Der hat gerade das Buch gelesen und versucht jetzt sein erstes Sprite anzuzeigen. Ist doch ganz schön frech jeamdne der n Fehler geamcht hat, weil er noch nicht so gut ist zu sagen, er solle einfach besser werden, dann würde er auch keine Fehler mehr machen. Sehr motivierend. Wenn du ein Problem damit hast, das diese heir ein Forum von einem Buch ist, welches D3DX benutzt um Anfängern den Einstieg in die Spieleprogrammierung einfacher zu machen bist du offensichtlich fehl am Platze.
VertexBuffer mögen ne feine Sache sein, aber bestimmt nix für Anfänger. Man muss ja nicht ganz unten Anfangen, und 4 Monate brauchen, um einfach mal EIN Bild anzuzeigen man kann für den Anfang doch genausogut D3DX benutzen, ist vielelicht nicht so superoptimal aber sicherlich nicht schlecht.
[edit]Zu dem Problem:
Der ganze Code scheint mir sehr merkwüridg zu sein. Wieso hat die Direct3D Klasse nicht das Device und D3DObjekt als Member? Man sollte die an dieser Stelle wirklcih nicht global machen. Ebenso sollte Init eine Methode von Direct3D sein, und keine Funktion. Es scheint zwar so einigermaßen zu funktionieren, aber ist nciht sehr übersichtlich. Was aber definitv falsch sit, ist folgendes:
CPP: | Direct3D.SetClearColor();
Direct3D.BeginScene();
Direct3D.EndScene(); |
Zwischen BeginScene() und EndScene() musst du noch die Zeichenmethode des Sprites aufrufen, den so zeichnest du gar nichts. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 02.03.2006, 16:23 Titel: |
|
|
Der Aufruf von Sprite-Draw sieht serhr seltsam aus. Normalerweise dürfte das doch von den Parametern gar nciht passen, in der Doku stehen viel mehr Parameter... _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Nomis_Simon Mini JLI'ler
Alter: 35 Anmeldedatum: 18.08.2006 Beiträge: 12
Medaillen: Keine
|
Verfasst am: 25.09.2006, 12:41 Titel: |
|
|
Hallo bin selber Anfänger und Hab auch ein Problem mit der Draw Methode von DX9.0c. Ich hab nämlich keinen blassen Schimmer wie ich die Textur skaliert oder verdreht ausgeben kann. |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 25.09.2006, 15:47 Titel: |
|
|
Normalerweise Dreht und Skaliert DirectDrwaws die Texturen auch nicht.
90 ger Schritte mag gehen, wird aber nciht ubedignt von vielen Grafikkarten unterstützt.
Mit skalieren gabs auch mal irgnedwas, aber wenn du vorhast sowas zu benutzen, solltest du lieber Direct3D nehemn, bzw. D3DXSprites (welche D3D benutzen). Ich denke das sollte schneller sein, und noch viel mehr Möglichkeiten bieten. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Nomis_Simon Mini JLI'ler
Alter: 35 Anmeldedatum: 18.08.2006 Beiträge: 12
Medaillen: Keine
|
Verfasst am: 27.09.2006, 11:18 Titel: |
|
|
Bei der Version 9.0 sah die
Draw Methode so aus
HRESULT Draw( LPDIRECT3DTEXTURE9 pSrcTexture,
CONST RECT *pSrcRect,
CONST D3DXVECTOR2 *pScaling,
CONST D3DXVECTOR2 *pRotationCenter,
FLOAT Rotation,
CONST D3DVECTOR2 *pTranslation,
D3DCOLOR Color
);
Ich hätt gedacht Das War auch schon Direct 3d.
mit 9.0c sieht die Methode So aus:
HRESULT Draw( LPDIRECT3DTEXTURE9 pTexture,
CONST RECT *pSrcRect,
CONST D3DXVECTOR3 *pCenter,
CONST D3DXVECTOR3 *pPosition,
D3DCOLOR Color
);
Wie kann ich jetzt Rotieren und Skalieren? |
|
Nach oben |
|
|
Loigie Junior JLI'ler
Anmeldedatum: 29.06.2004 Beiträge: 52 Wohnort: NRW Medaillen: Keine
|
Verfasst am: 27.09.2006, 14:57 Titel: |
|
|
Über Matrizen und der Funktion SetTransform.
So:
Code: |
D3DXMATRIXA16 matCombo, matRot, matScale, matTrans;
D3DXMatrixRotationZ(&matRot,m_Rotation);
D3DXMatrixScaling(&matScale, m_vScale.x, m_vScale.y, 1.0f);
D3DXMatrixTranslation(&matTrans, m_vPosition.x+m_vCenter.x, m_vPosition.y+m_vCenter.y,0.0f);
D3DXMatrixMultiply(&matCombo, &matRot, &matScale);
D3DXMatrixMultiply(&matCombo, &matCombo, &matTrans);
m_Sprite->Begin(D3DXSPRITE_DONOTSAVESTATE | D3DXSPRITE_ALPHABLEND);
{
m_Sprite->SetTransform(&matCombo);
m_Sprite->Draw(CIResManager.Texture(File),NULL,&VEC2TOVEC3(m_vCenter),NULL,0xFFFFFFFF);
}
m_Sprite->End();
|
|
|
Nach oben |
|
|
Nomis_Simon Mini JLI'ler
Alter: 35 Anmeldedatum: 18.08.2006 Beiträge: 12
Medaillen: Keine
|
Verfasst am: 28.09.2006, 16:37 Titel: |
|
|
Boah!
Das sieht aber sehr kompliziert aus. |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 29.09.2006, 15:05 Titel: |
|
|
Nomis_Simon hat Folgendes geschrieben: | Boah!
Das sieht aber sehr kompliziert aus. |
sieht komplizierter aus als es ist; Vorteil: es erlaubt dir mehr Flexibilität. Du hast z.B. die komplette Ausrichtung deines Objekts in dieser einen Matrix gespeichert.
@Loigie:
Wieso setzt du einen eigenen Gültigkeitsbereich zwischen Begin() und End() ?
Gruß DXer |
|
Nach oben |
|
|
Loigie Junior JLI'ler
Anmeldedatum: 29.06.2004 Beiträge: 52 Wohnort: NRW Medaillen: Keine
|
Verfasst am: 30.09.2006, 07:01 Titel: |
|
|
Zitat: | Wieso setzt du einen eigenen Gültigkeitsbereich zwischen Begin() und End() ? |
Eigentlich nur damit man direkt sieht das ID3DXSprite::Draw zwischen Begin() und End() aufgerufen wird. |
|
Nach oben |
|
|
Leycarno Mini JLI'ler
Anmeldedatum: 27.06.2006 Beiträge: 16
Medaillen: Keine
|
Verfasst am: 25.10.2006, 14:04 Titel: |
|
|
In dem Zusammenhang, Draw von Sprites, Übergang 9b->9c scheint
es außerdem einen Fehler mit dem ColorKey zu geben.
Ich habe meinen Code dank dieses Beitrags "wieder" zum Laufen gebracht, aber der ColorKey der Texture funzt nicht mehr.
Ich habe dann mal versucht die betreffende Farbe mit 0x00FFFFFF zu überschreiben (irgendwo ein Beitrag aus diesem Forum, das ich bei mir angepasst habe), bekomme aber nur Fehlermeldungen, sobald die Funktion beginnt einen Pixel zu manipulieren(Texture ist geRecLocked).
Dachte dann, das ich vielleicht über die Grenze Pixeln würde, doch er beginnt bereits beim allerersten Pixel zu meckern - habe dann mal den 2, 3, 4 versucht - gleiches Ergebnis...
nun - aussagekräftiger ist sicher Code:
(ursprünglich von "unsigned long", für meinen Code abgeändert
und nun zur besseren Leserlichkeit nochmals verändert
Das Problem müste allerdings herausgelesen werden können
-> Laufzeitfehler)
Code: |
D3DLOCKED_RECT rect;
texture->LockRect (0, &rect, NULL, 0);
for (unsigned long y=0; y<this->textureSize.y); ++y)
{
for (unsigned long x=0; x<this->textureSize.x; ++x)
{
if (rect.pBits)[this->textureSize.x*y+x] == 0xFF000000)
(rect.pBits)[this->textureSize.x*y+x] = 0x00FFFFFF; // HIER kommts immer/sofort zum Laufzeitfehler...
}
}
texture->UnlockRect (0);
|
Weiß jemand zufällig was ich machen könnte (außer auf das 'X' zu verzichten und einfach nochmal von Anfang anzufangen und alles zu FUss zu machen ) |
|
Nach oben |
|
|
Leycarno Mini JLI'ler
Anmeldedatum: 27.06.2006 Beiträge: 16
Medaillen: Keine
|
Verfasst am: 25.10.2006, 14:57 Titel: |
|
|
hab den Fehler in der Funktion gefunden... und habe nun eine SICHTBARE Alpha-Pixelelung....
Ich nutze PNG-Grafiken, denen man eh einen AlphaKanal mitgeben kann, daher neue Frage: Wie schmeiße ich für ein DXSprite den Alphakanal auf transparent???? |
|
Nach oben |
|
|
Leycarno Mini JLI'ler
Anmeldedatum: 27.06.2006 Beiträge: 16
Medaillen: Keine
|
Verfasst am: 25.10.2006, 15:04 Titel: |
|
|
HAR HAR !
Nachdem, das Device erstell wurde:
// Alphakanal anschalten, um Sprites nicht mehr als Quadrate zu sehen!
pDXDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pDXDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pDXDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
Vorraussetzung ist eie Grafik-Datei mit AlphaKey
Dadurch ist die Funktion oben nicht nötig und Colorkey kann 0 sein...
Aber vielleicht sollte ich doch langsam von d3dx9 runterkommen... |
|
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
|