PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [D3D9] 800x600 auf verschiedene Aufösungen "strecken"


BavariaBlade
2006-07-13, 12:55:41
Hi,

ich habe hier eine kleine 2d Anwendung die ich fest für 800x600 programmieren möchte. Wenn ich sie im Fenster ausführe, dann kann man das Fenster beliebig in die Breite und in die Höhe ziehen, das gerenderte Bild passt sich jedesmal dem Fenster an.
Wie mache ich das im Vollbildmodus?
z.B von 800x600 auf 1024x768 oder auf 1920x1600??

Mein Code:


D3DPRESENT_PARAMETERS presentParameters;
presentParameters.BackBufferCount =1 ;
//presentParameters.hDeviceWindow = m_hwnd;

if (vollbild==false)
{


presentParameters.Windowed = true; //Fenstermodus
presentParameters.BackBufferFormat = displayMode.Format; /

}
else
{
presentParameters.Windowed = false; //Vollbild

presentParameters.BackBufferFormat = D3DFMT_R5G6B5; //16Bit Farbtiefe
presentParameters.BackBufferWidth = 800; //Breite+Höhe des Backbuffers
presentParameters.BackBufferHeight = 600;
}




// Create the device

m_hr=m_direct3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_hwnd, //Renderfester
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,
&presentParameters, &m_device );

Neomi
2006-07-13, 13:04:01
Im Vollbild müßtest du erst in eine passend große Textur rendern, die du dann per Fullscreen-Quad hochskalierst.

Aber mal eine Frage am Rande: wozu? Wenn deine Oberfläche schon nicht skalierbar ist, dann könntest du doch die Auflösung auf 800x600 festlegen. Durch Umskalierung verlierst du nur Bildqualität.

BavariaBlade
2006-07-13, 13:25:48
Neomi[/POST]']
.....
Aber mal eine Frage am Rande: wozu? Wenn deine Oberfläche schon nicht skalierbar ist, dann könntest du doch die Auflösung auf 800x600 festlegen. Durch Umskalierung verlierst du nur Bildqualität.

Das Problem entsteht bei 16:10 Mointoren z.B. Wenn ich 800x600 fest einprogrammiere, dann stellt der eine 1280x800 Monitor das gerenderte Bild gestretched dar, der andere übernimmt die 800x600 1:1 und lässt dafür schwarze Ränder.
Ich will das aber nicht dem jeweiligen Monitor überlassen ob er schwarze Ränder macht oder nicht, sonderm immer das komplette Vollbild nutzen können. Dafür mache ich dann Abstriche bei der Qualität, bekomme aber im gegenzug eine vorhersagbare Bildausgabe ;)

Neomi[/POST]']Im Vollbild müßtest du erst in eine passend große Textur rendern, die du dann per Fullscreen-Quad hochskalierst.
...

Bist du dir sicher, dass es nicht einfachher geht, ähnlich wie bei der Fensterausgabe die ich beschrieben habe?
Danke für die schnelle Antwort!!

Neomi
2006-07-13, 13:37:58
BavariaBlade[/POST]']Ich will das aber nicht dem jeweiligen Monitor überlassen ob er schwarze Ränder macht oder nicht, sonderm immer das komplette Vollbild nutzen können. Dafür mache ich dann Abstriche bei der Qualität, bekomme aber im gegenzug eine vorhersagbare Bildausgabe ;)

Vorhersagbar unscharf und verzerrt, da sind schwarze Ränder das weitaus kleinere Übel. Du solltest dir eher Gedanken darüber machen, auf welche Art du dein Bild berechnest. Skalierbar sollte es schon sein, ansonsten hast du ein nicht gerade kleines Konzeptproblem.

BavariaBlade[/POST]']Bist du dir sicher, dass es nicht einfachher geht, ähnlich wie bei der Fensterausgabe die ich beschrieben habe?
Danke für die schnelle Antwort!!

Das ist doch eine einfache Variante. Einfacher geht es im Vollbild wirklich nicht mehr.

Awesomo
2006-07-14, 01:43:05
wie das bild skaliert werden soll, kannst du im graka-treiber-menü einstellen. musst halt ne gute readme schreiben ^^

BavariaBlade
2006-07-14, 11:55:47
Neomi[/POST]']
...Das ist doch eine einfache Variante. Einfacher geht es im Vollbild wirklich nicht mehr.

Gut, danke. Jetzt weiß ich wenigstens in welche Richtung ich programmieren muss.
Das Problem ist jetzt, dass ich nur Ahnung von den D3dSprites habe, mit verticies hab ich noch nichts gemacht.
Wenn ich deinen Lösungsansatz richtig verstanden habe muss ich nun:
-eine 800x600 Haupttextur erzeugen
-alles dort hieneinzeichnen
-die Textur auf einen Fan legen ( heißt doch so oder)
-den Fan auf die richtige größe skalieren

Wie erstelle ich eine Textur ohne ein Bild.datei zu laden die 800x600 groß ist?
Wie zeichnne ich verschieden Sprites in eine Textur?




Ich glaube für den rest habe ich schon genug Tutorials und Beispielcode hier :) .

servus und danke BB

BavariaBlade
2006-07-14, 11:57:50
Awesomo[/POST]']wie das bild skaliert werden soll, kannst du im graka-treiber-menü einstellen. musst halt ne gute readme schreiben ^^

Danke für den Tipp. Auch wenn mein Programm durch das Skalieren nicht so toll aussehehn wird soll es doch relativ DAU sicher sein, desshalb kann ich das leider nicht so machen :( .

BTW Willkommen im 3dc, happy coding und so ;)

servus BB

Coda
2006-07-14, 12:50:28
Mal ne Frage, aber wieso renderst du nicht einfach in die native Auflösung? :|

BavariaBlade
2006-07-14, 13:35:34
Coda[/POST]']Mal ne Frage, aber wieso renderst du nicht einfach in die native Auflösung? :|

Ich kann dir jetzt nicht wirklich folgen?!

Awesomo
2006-07-14, 16:00:04
BavariaBlade[/POST]']Gut, danke. Jetzt weiß ich wenigstens in welche Richtung ich programmieren muss.
Das Problem ist jetzt, dass ich nur Ahnung von den D3dSprites habe, mit verticies hab ich noch nichts gemacht.
Wenn ich deinen Lösungsansatz richtig verstanden habe muss ich nun:
-eine 800x600 Haupttextur erzeugen
-alles dort hieneinzeichnen
-die Textur auf einen Fan legen ( heißt doch so oder)
-den Fan auf die richtige größe skalieren

Wie erstelle ich eine Textur ohne ein Bild.datei zu laden die 800x600 groß ist?
Wie zeichnne ich verschieden Sprites in eine Textur?




Ich glaube für den rest habe ich schon genug Tutorials und Beispielcode hier :) .

servus und danke BB

hi ;)


das rendern auf eine textur ist einfach. allerdings gibt es dann probleme mit filtern wie aa (die auf einer textur ja nicht funktionieren. müsste man irgendwie davor anwenden!?)

du kannst eigentlich alles normal rendern. nur anstatt es mit "present()" anzuzeigen, musst es dann halt auf die textur schreiben.

http://www.riaz.de/tutorials/d3d16/d3d16.html


aber dein eigentliches problem habe ich auch noch nicht verstanden ^^. du kannst doch einfach die dekstop auflösung auslesen und verwenden??

SCREEN_WIDTH = GetSystemMetrics(SM_CXSCREEN);
SCREEN_HEIGHT = GetSystemMetrics(SM_CYSCREEN);

daraus kennst du auch das seitenverhältnis und kannst damit die perspective anpassen: D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ),
(float) SCREEN_WIDTH / SCREEN_HEIGHT, 2.0f, 3000.0f );

du solltest von den 800x600 abkommen...

BavariaBlade
2006-07-14, 16:33:18
Awesomo[/POST]']


...aber dein eigentliches problem habe ich auch noch nicht verstanden ^^. du kannst doch einfach die dekstop auflösung auslesen und verwenden??

SCREEN_WIDTH = GetSystemMetrics(SM_CXSCREEN);
SCREEN_HEIGHT = GetSystemMetrics(SM_CYSCREEN);

daraus kennst du auch das seitenverhältnis und kannst damit die perspective anpassen: D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ),
(float) (SCREEN_WIDTH / SCREEN_HEIGHT), 2.0f, 3000.0f );

du solltest von den 800x600 abkommen...

Also Grundsatzlich muss ich auch nicht auf SVGA setzen. Das Problem das ich habe ist folgendes:
Ich erzeuge Sprites und setze die mit Hilfe von Pixelkoordinaten auf den Screen. So rendere ich mein komplettes Bild. Wenn ich nun die Auflösung verändere (z.B auf 1920 x 1600) sitzt natürlich alles oben in der linken Ecke.

Ich habe mich gerade Einigermaßen in den 2D-Teil von D3D eingearbeitet, desshalb habe ich auch keine Ahnung, und nehme jeden Vorschlag dankbar an ;).

Würde deine Lösung mit dem FOV direkt bei mir gehen? Oder muss ich meinen Sprites irgendwelche anderen Koordinaten zuweisen?
Die Idee mit dem FOV ist an sich aber schonmal super.

Bin grade nicht Arbeitsrechner, aber wenn du willst kann ich dir später mal Posten wie ich meine Sprites platziere.

servus BB

Awesomo
2006-07-14, 17:56:23
kenne mich zwar mit 2d nicht wirklich aus aber es gibt bestimmt einige möglichkeiten die koordinaten von sprites auf eine höhere auflösung umzurechnen.

nehmen wir an, du bastelst dir alles zuerst in 800x600. wenn jetzt also einer ne auflösung von 1600x1200 hat, hat das sprite, welches bei 800x600 die koordinaten (400, 300)hatte, dann (400*(1600/800), 400*(1200/600). somit ist das sprite bei beiden auflösungen in der bildschirmmitte. dann musst noch die grösse der sprites verdoppeln und es sollte wieder etwa gleich aussehen.

wie gesagt ich habe sowas noch nie gemacht, sollte aber bestimmt irgendwie in der art funktionieren....

del_4901
2006-07-14, 18:04:55
einfach mal mit float rechnen, würde vieles einfacher gestalten ^^ :)

BavariaBlade
2006-07-15, 16:38:49
So, dann will ich mal meine Erfolge posten. Ich habe euren letzten Vorschlag umgesetzt.



//Vollbild 16Bit und setze den Skalierungsfaktor
......

presentParameters.Windowed = false; //Vollbild
presentParameters.BackBufferFormat = D3DFMT_R5G6B5; //16Bit Farbtiefe

int w = 1280;
int h = 1024;

presentParameters.BackBufferWidth = w; //Breite+Höhe des Backbuffers
presentParameters.BackBufferHeight = h;

SetGlobalScale(w,h);
.....


//in dieser Funktion wird der Skalierungsfaktor errechnet
....
void SetGlobalScale(int screenWidth, int screenHeight)
{
m_globalScaleX = (float)screenWidth / 800.f;
m_globalScaleY = (float)screenHeight / 600.f;

}
.....



//erstelle Sprite mit der richtigen Skalierung
.....
//erstelle Sprite
m_hr=D3DXCreateSprite(pDevice,&m_pSprite);

//Skaliert die Sprites alle auf die gewählte Bildschirmgröße
D3DXMATRIX SpriteMatrix;
D3DXMatrixScaling(&SpriteMatrix, m_globalScaleX, m_globalScaleY, 1.0f);
m_pSprite->SetTransform(&SpriteMatrix);
.....



//zeichne Sprite
........
m_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
m_hr = m_pSprite->Draw( m_pTexture,
NULL,//&srcRect,
&m_vCenter,
&m_vPosition,
D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f) );
m_pSprite->End();
.......



-in den früheren Versionen von DirectX, konnte man mit pSprite->Draw(...) direkt den Skalierungsfaktor setzen, das geht nun nicht mehr.
Deshalb die Transformationsmatrix.

-m_vCenter und m_vPosition sind D3DXVECTOR3(x,y,z)
Bsp: m_vPosition = D3DXVECTOR3( 10.0f,10.0f, 0.0f );


-Das skalieren auf z.B 1280x1024 funktioniert wunderbar, aber auf 640x480 habe ich leichte Schatten von dem 800x600 Bild!?
Ist aber nicht weiter tragisch. Wichtig ist, dass ich upscalen kann. Die niedrigen Auflösungen benötige ich sowieso nicht.

-Und der System tray flackert ab und zu durch, kann man das abstellen?

Danke an Alle,
Gruß BB

Awesomo
2006-07-15, 19:33:13
zeig doch mal einen screenshot :D