|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 01.10.2007, 16:12 Titel: scrolling |
|
|
hallo, ich probier mich gerade am scrolling.
Ich habe folgendes Problem:
Ich erstelle ein Surface 1280 mal 1024. Klappt super.
Jetzt kopiere ich eine Grafik auf das surface. Klappt auch super.
Wenn ich allerding 1280*3 eingebe und drei Grafiken auf das Surface kopiere, zeigt er mir nur so komische Sachen an (Sieht aus wie nicht benutzter Grakaspeicher).
Hier der Teil meines Codes:
CPP: | m_lpD3DDevice->CreateOffscreenPlainSurface(
1280*3, 1024,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&m_lpSurface,
0);
RECT r = { 0, 0, 1280, 1024 };
D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r,
"bild1.bmp",
0, D3DX_DEFAULT, 0, NULL);
r.left += 1280;
r.right += 1280;
D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r,
"bild2.bmp",
0, D3DX_DEFAULT, 0, NULL);
r.left += 1280;
r.right += 1280;
D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r,
"bild3.bmp",
0, D3DX_DEFAULT, 0, NULL);
m_lpD3DDevice->GetBackBuffer(0, 0,
D3DBACKBUFFER_TYPE_MONO,
&m_lpBackBuffer);
}
|
und:
CPP: | RECT DestRect = {0, 0, 1280, 1024};
m_lpD3DDevice->StretchRect(m_lpSurface,
NULL,
m_lpBackBuffer,
&DestRect,
D3DTEXF_NONE);
|
|
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 01.10.2007, 16:31 Titel: |
|
|
Evtl. ist 3*12809 zu groß, daher kann das Surface nicht erstellt werden.
Du solltest mal alle Fehlermeldungen checken (bzw. Fehlerabfrage einbauen) _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 01.10.2007, 16:38 Titel: |
|
|
ich hab es mal mit 800*600 versucht, funktioniert auch nicht.
Wie würde die Fehlerüberprüfung den aussehen? |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 01.10.2007, 17:08 Titel: |
|
|
Die DX Funktionen geben normalerweise immer einen Wert zurück, der angibt ob alles geklappt hat, oder andernfalls was für Fehler aufgetreten sind.
Es müsste da so ein FaILED Marko geben, in etwa so:
CPP: | if(FAILED(DXFunktion(Mit, Parametern))
cout << "ICh bin eine Fehlermeldung!";
|
_________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 02.10.2007, 09:20 Titel: |
|
|
Ich versteh das jetzt nicht! Ich hab auf Fehler überprüft, bekomme aber keine Fehlermeldung! Ich bin gerade am verzweifen, deswegen poste ich mal meinen kompletten Code:
scrolling.cpp:
CPP: | #include "Direct3D.h"
HWND CreateMainWindow(HINSTANCE hInstance);
LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
HWND hWnd = 0;
MSG msg;
CDirect3D DirectX;
int WINAPI WinMain(HINSTANCE hInstance, // Handle der Programminstanz
HINSTANCE hPrevInstance, // Handle der letzten Instanz
LPSTR lpCmdLine, // Kommandozeile
int nCmdShow) // Art wie das Fenster angezeigt werden soll
{
hWnd = CreateMainWindow(hInstance);
DirectX.Init(hWnd, FALSE);
DirectX.SetClearColor(D3DCOLOR_XRGB(50, 150, 150));
DirectX.BeginScene();
DirectX.EndScene();
if(0 == hWnd)
{
MessageBox(0, "Fenster konnte nicht erzeugt werden", "Fehler", MB_OK);
return 0;
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
HWND CreateMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wndClass =
{
sizeof(WNDCLASSEX), // Groesse angeben
CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW, // Standardstile
MessageHandler, // Callback-Funktion
0, // Zusaetzliche Angaben
0, // nicht benoetigt
hInstance, // Anwendungsinstanz
LoadIcon(NULL, IDI_WINLOGO), // Windows-Logo
LoadCursor(NULL, IDC_ARROW), // Normaler Cursor
(HBRUSH)GetStockObject(WHITE_BRUSH), // Weisser Pinsel
NULL, // kein Menue
"WindowClass", // Der Name der Klasse
LoadIcon(NULL, IDI_WINLOGO) // Windows Logo
};
RegisterClassEx(&wndClass);
return CreateWindowEx(NULL, // Keine erweiterten Stile nutzen
"WindowClass", // Klassenname
"Surfaces", // Fenstertitel
WS_OVERLAPPEDWINDOW | // Fenster
WS_VISIBLE, // Eigenschaften
100, 100,
1280, 1024, // Anfangsposition und Groesse
NULL, // Handle des Elternfensters
NULL, // Handle des Menues
hInstance, // Anwendungsinstanz
NULL); // wird nicht benoetigt
}
LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
DirectX.~CDirect3D();
PostQuitMessage(0);
return 0;
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
|
Direct3D.h:
CPP: | #include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "dxguid")
#pragma comment(lib, "d3d9")
#pragma comment(lib, "d3dx9")
class CDirect3D
{
public:
CDirect3D();
virtual ~CDirect3D();
// Direct3D initialisieren
BOOL Init(HWND hWnd, BOOL bWindowed = TRUE);
// Farbe fuer den Backbuffer festlegen
void SetClearColor(D3DCOLOR Color);
// Text an Position x, y ausgeben
void DrawText(LPCSTR Text,
int x, int y,
D3DCOLOR TextColor);
// Methoden zum Start/Beenden der Szene
void BeginScene(void);
void EndScene(void);
// Erzeugen der D3D-Schrift
void CreateFont(void);
// Freigeben der Objekte
void CleanUp(void);
// Farbe fuer den Backbuffer
D3DCOLOR m_ClearColor;
// Direct3D Variablen
LPDIRECT3D9 m_lpD3D;
LPDIRECT3DDEVICE9 m_lpD3DDevice;
LPD3DXFONT m_lpD3DFont;
LPDIRECT3DSURFACE9 m_lpSurface;
LPDIRECT3DSURFACE9 m_lpBackBuffer;
};
|
Direct3D.cpp:
CPP: | #include "Direct3D.h"
#include <dxerr9.h>
CDirect3D::CDirect3D()
{
m_lpD3D = NULL;
m_lpD3DDevice = NULL;
m_lpD3DFont = NULL;
}
CDirect3D::~CDirect3D()
{
CleanUp();
}
// Direct3D initialisieren
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 fuer 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-Geraet anlegen
if(FAILED(hr = m_lpD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PParams,
&m_lpD3DDevice)))
{
// Fehler, Geraet kann nicht angelegt werden
return FALSE;
}
CreateFont();
if(FAILED(m_lpD3DDevice->CreateOffscreenPlainSurface(
1024*3, 768,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&m_lpSurface,
0)))
{
MessageBox(0, "Fehler Nr.1", "Fehler", MB_OK);
}
RECT r1 = { 0, 0, 1024, 768 };
if(FAILED(D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r1,
"bild1.bmp",
0, D3DX_DEFAULT , 0, NULL)))
{
MessageBox(0, "Fehler Nr.2", "Fehler", MB_OK);
}
RECT r2 = { 1024, 0, 2048, 768 };
D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r2,
"bild2.bmp",
0, D3DX_DEFAULT, 0, NULL);
RECT r3 = { 2048, 0, 3072, 768 };
D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r3,
"bild3.bmp",
0, D3DX_DEFAULT, 0, NULL);
m_lpD3DDevice->GetBackBuffer(0, 0,
D3DBACKBUFFER_TYPE_MONO,
&m_lpBackBuffer);
}
// Farbe fuer den Backbuffer festlegen
void CDirect3D::SetClearColor(D3DCOLOR Color)
{
m_ClearColor = Color;
}
// Text an Position x, y ausgeben
void CDirect3D::DrawText(LPCSTR Text, int x, int y, D3DCOLOR TextColor)
{
RECT r = { x, y, 0, 0 };
// Groesse des Rechtecks berechnen
m_lpD3DFont->DrawText(NULL, Text, -1, &r, DT_CALCRECT, TextColor);
// Text ausgeben
m_lpD3DFont->DrawText(NULL, Text, -1, &r, DT_CENTER, TextColor);
}
// Methoden zum Start/Beenden der Szene
void CDirect3D::BeginScene(void)
{
RECT DestRect = {0, 0, 1024, 768};
// Puffer mit blau fuellen
m_lpD3DDevice->Clear(0, 0, D3DCLEAR_TARGET, m_ClearColor, 0, 0);
m_lpD3DDevice->StretchRect(m_lpSurface,
NULL,
m_lpBackBuffer,
&DestRect,
D3DTEXF_NONE);
m_lpD3DDevice->BeginScene();
}
void CDirect3D::EndScene(void)
{
m_lpD3DDevice->EndScene();
m_lpD3DDevice->Present(0, 0, 0, 0);
}
// Erzeugen der D3D-Schrift
void CDirect3D::CreateFont(void)
{
// Struktur fuer die Beschreibung der Schriftart
// anlegen und Elemente mit 0 initialisieren
D3DXFONT_DESC FontDesc = { 0 };
// das Element FaceName muss den Namen der
// gewuenschten Schriftart enthalten
strcpy(FontDesc.FaceName, "Arial");
// nach erfolgreichem Aufruf zeigt lpD3DFont
// auf ein Objekt vom Typ D3DXFont
D3DXCreateFontIndirect(m_lpD3DDevice,
&FontDesc,
&m_lpD3DFont);
}
// Freigeben der Objekte
void CDirect3D::CleanUp(void)
{
// testen, ob die Objekt angelegt
// wurden und ggf. freigeben
if(NULL != m_lpD3DFont)
{
m_lpD3DFont->Release();
m_lpD3DFont = NULL;
}
if(NULL != m_lpD3DDevice)
{
m_lpD3DDevice->Release();
m_lpD3DDevice = NULL;
}
if(NULL != m_lpD3D)
{
m_lpD3D->Release();
m_lpD3D = NULL;
}
}
|
Ich bekomme keine Compilerfehler aber wenn ich das Programm starte, bekomme ich die Bilder nicht angezeigt! Wenn ich bei CreateOffscreenSurface das *3 weglasse, bekomme ich das erste Bild angezeit!
PS:
Falls das wichtig ist, meine Intelgrafikchip hat 64Mb Speicher. Ist nicht viel ich weiß! |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 02.10.2007, 13:03 Titel: |
|
|
Vielleicht hilft dir das weiter:
DirectX-Doku hat Folgendes geschrieben: | IDirect3DDevice9::StretchRect will fail for any of the following:
If the source and destination surface are the same.
If stretching or shrinking is involved, or if either surface is in a compressed format (see Using Compressed Textures).
If the destination surface is an off-screen plain surface but the source is not. If the destination surface is an off-screen plain surface and stretching is involved. |
Ich versteh zwar nicht ganz, wieso die Doku hier meint, dass strecken/stauchen nicht erlaubt sein sollte(dafür ist die Funktion ja eigentlich gemacht...), aber wozu brauchst du das überhaupt? So wie das hier aussiehst, versuchst du ein Surface zu erstellen, in dem der gesamte Scroll-Inhalt ist. Beim Rendern stauchst du das ganze auf Bildschirmgröße. Das hat nicht wirklich was mit scrollen zu tun. Du solltest lieber versuchen, nur einen Teil des Scroll-Inhaltes (in Originalgröße) in den Backbuffer zu bekommen _________________ 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 |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 02.10.2007, 13:11 Titel: |
|
|
ich wollte eigentlich nur das erste Bild anzeigen lassen! Ich habe StretchRect ein DestRect übergeben, was nur die Fläche des ersten Bildes auf dem Surface anzeigen soll! Ich meine, so wie der Code im Moment funktionieren soll, soll nur das erste Bild angezeigt werden, bis jetzt ohne scrolling. Die anderen beiden Bilder sollen aber auch auf dem Surface liegen nur halt außerhalb des Anzeigebereichs. Beim scrollen will ich den Bereich jetzt einfach nach rechts oder links verschieben können, wie bei einem alten Film. |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 02.10.2007, 13:18 Titel: |
|
|
Dest = Destination = Ziel = Backbuffer -> DestRect = Rechteck im Backbuffer. Fällt dir was auf?
Du übergibst nunmal (bisher) kein SourceRect. Genau das veranlasst StretchRect() dazu, die ganzen 3*1024x768 zu nehmen und zu versuchen, sie auf 1*1024x768 zu skalieren, was offenbar fehlschlägt. Für das DestRect brauchst du bisher eigentlich keines angeben, da bei NULL der gesamte Backbuffer als Zielrechteck genommen wird. Es fehlt hier aber am Quellenrechteck. _________________ 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 |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 02.10.2007, 13:20 Titel: |
|
|
dann hab ich die beiden Rechtecke wohl vertauscht. Ich dachte das DestRect würde angeben, welcher Teil des Surfaces in den BackBuffer kopiert wird.
Danke für eure Hilfe!
ich hab jetzt einfach mal folgendes geändert:
CPP: | RECT SourceRect = {0, 0, 1024, 768};
// Puffer mit blau fuellen
m_lpD3DDevice->Clear(0, 0, D3DCLEAR_TARGET, m_ClearColor, 0, 0);
m_lpD3DDevice->StretchRect(m_lpSurface,
&SourceRect,
m_lpBackBuffer,
NULL,
D3DTEXF_NONE);
|
Ich hab das DestRect zum SourceRect gemacht. Es funktioniert immernoch nicht! Woran liegt das? |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 02.10.2007, 14:03 Titel: |
|
|
Und wenn du nur die 3* wegnimmst funktioniert es wieder?
Wieso hast du eigentlich BeginScene() Am Schluss der Renderfunktion? Das sollte den Rendervorgang einleiten, nicht abschließen. Auch wenn ich mir nicht vorstellen kann, dass es daran liegt, würde ich das auf jeden Fall ändern.
PS: Es gibt auch nen Edit-Button. _________________ 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 |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 02.10.2007, 14:29 Titel: |
|
|
Wenn ich das *3 weglasse bekomme ich das erste Bild angezeigt, wie es sein sollte. Wenn ich es dazu schreibe, zeigt er mir irgendwie alle drei Bilder übernander an, aber nur das linke obere viertel. Die drei Bilder sind teilweise transparent! Das ist irgendwie alles komisch! |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 02.10.2007, 15:23 Titel: |
|
|
@newby: Warum orientierst du dich nicht am Kapitel des Buches? Dort wird die Grafik nicht in den Grafikspeicher kopiert sondern in den Arbeitsspeicher. Dann wird der angezeigte Ausschnitt in den Grafikspeicher kopiert und bei Bewegung die entsprechend neue Zeile.
Zudem hast du dann eine funktionierende Referenz die du anschließend so erweitern kannst das sie in alle Seiten funktioniert. |
|
Nach oben |
|
|
newby JLI'ler
Anmeldedatum: 17.08.2007 Beiträge: 106
Medaillen: Keine
|
Verfasst am: 02.10.2007, 15:31 Titel: |
|
|
ich orientiere mich am Buch! Ich weiß ja nicht wie du das Buch ließst, aber ich lese es von vorne nach hinten! In dem ersten Beispiel bei dem es ums scrolling ging, wurde es in den Grafikkartenspeicher geschrieben.
EDIT:
Ich hab gerade gemerkt, dass das Beispiel scrolling1 aus dem Buch den selben Fehler hat! Muss das so? |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 03.10.2007, 15:55 Titel: |
|
|
newby hat Folgendes geschrieben: | Ich weiß ja nicht wie du das Buch ließst |
Erste Seite bis zur letzten und immer von links oben bis nach rechts unten. Dabei zeilenweise und nicht spaltenweise.
@Topic: Wenn das Beispiel so aufgebaut ist dann solltest du wie bereits geschrieben das Quellrechteck ändern. Das wäre dann etwa so
CPP: | // gespeicherten Werte um die Verschiebung ändern
memberVarX += diffX;
memberVarY += diffY;
// Quellrechteck abhängig von der membervariable definieren
sourceRect.x = memberVarX;
sourceRect.y = memberVarY;
sourceRect.width = memberVarX + resolutionWidth;
sourceRect.height = memberVarY + resolutionHeight;
|
Natürlich musst du erst noch prüfen ob du innerhalb des Quellbildes bist aber das sollte ja kein Problem sein. |
|
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
|