22
Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Embed Size (px)

Citation preview

Page 1: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Balance V01

Der Windows-Rahmen

S. 207 - 210

Vortrag von Lisa Rau

Page 2: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

- Elementares Windows-Framework schon vorhanden- Rahmen ist mit dem Ultris-Rahmen fast identisch

Erforderliche Includes:

# include <stdio.h># include <stdarg.h># include <windows.h># include <commctrl.h># include <d3dx9.h># include <dinput.h># include "d3dfont.h"

# include "resource.h„

HINSTANCE balance_instance; // Instanz-HandlerHWND balance_window; // Handler für Hauptfenster der Applikation

Page 3: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

- Neuer Name des Eventhandlers- WM_GETMINMAXINFO Message wird nicht behandelt, da Fenstergröße frei

veränderbar sein soll

LRESULT CALLBACK balance_windowhandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{switch( msg)

{case WM_COMMAND:

switch( LOWORD(wParam)) {

case IDM_EXIT:PostMessage( hWnd, WM_CLOSE, 0, 0);return 0;}

break;case WM_DESTROY:

PostQuitMessage( 0);return 0;}

return DefWindowProc(hWnd, msg, wParam, lParam);}

Page 4: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Hauptprogramm

- nur Unterschiede in Benennung der Handles, Ressourcensymbole und des Windows-Handlers

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){

...//Anlegen des Fenstersbalance_window = CreateWindowEx(0, TEXT( "Balance"),

TEXT( "Balance"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,

CW_USEDEFAULT, // System-Defaults in der Fenstergröße

0, NULL, NULL, hInst, NULL);...}

- Keine Stelle, um aus der Hauptverarbeitungsschleife heraus das Spiel regelmäßig zu aktualisieren

Page 5: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Spiel starten / testen:

- Leeres Fenster, das in der Größe veränderbar ist

- Warnungen beim Start können ignoriert werden

- stammen von inkludierten Libraries, die momentan noch nicht verwendet werden

Page 6: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Balance V02

Initialisieren und Darstellen des Spielfeldes

S. 211 - 222

Page 7: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Die Klasse directX

class directx{public:

LPDIRECT3D9 d3d;LPDIRECT3DDEVICE9 device;D3DPRESENT_PARAMETERS d3dpp;

int init(); //wird als nächstes genauer betrachtetvoid adjust(int breite, int hoehe);

};

int directx::init(){

D3DDISPLAYMODE d3ddm;D3DDEVTYPE devtype;D3DCAPS9 caps;

d3d = Direct3DCreate9( D3D_SDK_VERSION); // Zeiger d3d erlaubt Zugriff auf grundlegende DirectX – Funktionen// Initialisierung des Zeigers mit der Funktion Direct3DCreate9

Page 8: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

- Schnittstelle, die durch d3d zur Verfügung steht

- Überwiegend technische Details des Grafik-Adapters

- Für Balance werden nur Standard-möglichkeiten genutzt, um das Spiel möglichst schnell zum Laufen zu bringen

Page 9: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Weiter in init-Funktion ...if( !d3d) return 0;

if( d3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm) < 0)// Display-Modus wird in Variable d3ddm ausgelesen return 0;

ZeroMemory( &d3dpp, sizeof(d3dpp)); //Präsentationsparameter d3dpp wird gesetzt//ZeroMemory: Parameter, die nicht im Folgenden explizit erwähnt werden, erhalten den

Wert 0

d3dpp.Windowed = TRUE; //Umstellung auf Windowed-Mode (Darstellung des Spiels in einem Fenster)

d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

d3dpp.BackBufferFormat = d3ddm.Format; //bestehendes Display-Format für den Backbuffer übernehmen

Page 10: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Graphic Device Interface (GDI):

-Von klassischen Windows-Anwendungen (z.B. Word, Explorer) verwendet

-erlaubt Darstellung von Text und Zeichnungen auf dem Bildschirm

Direct3D-API (Application Programming Interface):

- Von 3D Spielen verwendet

- Erlaubt Rendern dreidimensionaler Objekte

-> benutzt HAL

Hintergrundinformationen:

HAL (Hardware Abstraction Layer)

-versucht alle Operationen möglichst direkt auf der Hardware auszuführen

-nur wenn Grafikkarte eine Operation nicht unterstütz, wird sie in der HAL-Software nachgebildet (langsamer)

- alternativ Reference Device: Emulation der Direct3D Funktionen in Software

Page 11: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Weiter in init-Funktion:

//Prüfung, ob HAL verfügbar ist

if( d3d->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps) < 0)

{MessageBox( balance_window, "Kein HAL-Device - das wird langsam!",

"Balance-Meldung", MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);devtype = D3DDEVTYPE_REF; //Speicherung in devtype: kein HAL}

elsedevtype = D3DDEVTYPE_HAL; //Speicherung in devtype: HAL verfügbar

// Anlegen des Devices, das im Folgenden benutzt wird

if( d3d->CreateDevice( D3DADAPTER_DEFAULT, devtype, balance_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &device) < 0)

return 0; // Initialisierung gescheitert return 1; // Initialisierung hat vollständig funktioniert

}

Page 12: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

adjust-Funktion

- Wird aufgerufen, wenn sich die Größe des Fensters ändert- DirectX-Einstellungen müssen dann an neue Fenstergröße (breite, höhe) angepasst

werden

void directx::adjust( int breite, int hoehe){

D3DXMATRIX proj;

d3dpp.BackBufferWidth = breite; // Anpassen des Backbuffers d3dpp.BackBufferHeight = hoehe;

device->Reset( &d3dpp); // Reset des Devices

- Ganz am Anfang setzt System in der Funktion CreateDevice bei gewähltem Windowed-Mode die Koordinaten des aktiven Fensters zu Bestimmung der Backbuffergröße heran

- Änderung des Render-State des Devices:device->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE); // z-Buffering

aktivierendevice->SetRenderState( D3DRS_AMBIENT, 0xffffff); //Umgebungsbeleuchtung

einschalten

Page 13: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Z-Buffering:

- Wichtig für Tiefe (z-Achse)- Vorne liegende Objekte verdecken andere,

die weiter hinten liegen- Kostet Rechenzeit

-> lässt sich abstellen, wenn es nicht benötigt wird (wenn man jederzeit weiß, was vorne und hinten ist)

Beleuchtung:

- Farbe Weiß: 0xffffff

- Auch andere Farbwerte möglich, z.B.: 0xff0000, 0x00ff00, 0x0000ff

- Umgebungslicht ist ungerichtetes, gleichmäßiges Licht ohne Schatten

Fehler bei ausgeschaltetem z-Buffer

Page 14: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Weiter in adjust Funktion:- Projektionsmatrix proj wird erzeugt und mit SetTransform festgelegt

D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI/4,

((float)breite)/hoehe, 1.0f, 500.0f);

device->SetTransform( D3DTS_PROJECTION, &proj); //Projektion zur Darstellung der Szene festlegen

}

Parameter:

Page 15: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Blickfeldwinkel:

Kleiner Winkel (z.B. Teleobjektiv)

-> entfernte Dinge rücken nah heran

-> alles rückt in der Tiefe nah zusammen

Großer Winkel (z.B. Weitwinkelobjektiv)-> Dinge rücken auseinander-> Landschaft wirkt flacher/ niedriger

Der menschlichen Sehweise entspricht etwa ein Winkel von 45° im Bogenmaß, also etwa π/4.

Begrenzungsebenen:

- Beschränken Blickfeld in der Tiefe

- Bereich davor/dahinter wird abgeschnitten

-Sichtbarer Teil mit Pyramidenstumpf vergleichbar

-aber: normalerweise werden nahe liegende Dinge perspektivisch vergrößert

-> Blickfeld wird am Blickpunkt auseinander gezogen, um dies zu erreichen

-> perspektivische Transformation durch Projektionsmatrix

Page 16: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Ansichtsverhältnis- Quotient aus Breite und Höhe des Blickfeldes- Parameter sorgt dafür, dass bei der perspektivischen Transformation keine

Verzerrungen auftreten

-> Alle Parameter-Funktionen anschaulich im Demoprogramm Projektion.

Schließlich Instanziierung eines Objekts der Klasse directx:

directx mein_directx;

Page 17: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Die Klasse objekt- Dient zur Aufnahme der Drahtmodelle- Kapselung der Daten eines Drahtmodells:

class objekt

{

private:

LPD3DXMESH mesh; // Mesh mit Vertices und Faces

D3DMATERIAL9 *materialien;

DWORD anz_mat; // gewisse Anzahl der Materialien

LPDIRECT3DTEXTURE9 *texturen; //zu jedem Material eine Textur

public:

objekt(); // Konstruktor

void load( char *xfile); // Objekt aus x-Datei laden

void draw(); // auf dem Bildschirm darstellen

~objekt(); // Destruktor

};

Page 18: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Konstruktor

- Vorbesetzung der Member-Variablen mit 0:

objekt::objekt()

{

mesh = NULL;

materialien = NULL;

anz_mat = 0;

texturen = NULL;

}

Page 19: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Funktion load

void objekt::load( char *xfile){

LPD3DXBUFFER buf;D3DXMATERIAL* mat; DWORD i;

// Mesh wird aus der Datei geladen D3DXLoadMeshFromX( xfile, D3DXMESH_SYSTEMMEM, mein_directx.device, NULL,

&buf, // Buffer mit Material- und Texturinformationen

NULL, &anz_mat, // Information über Anzahl der

Materialien&mesh); // Mesh wird in eine interne Struktur

geladen

mat = (D3DXMATERIAL*)buf->GetBufferPointer(); // Zeiger mat wird initialisiert, um auf Materialdaten im Buffer zugreifen zu

können //Arrays für Material- und Texturdaten, werden angelegt: materialien = new D3DMATERIAL9[anz_mat]; texturen = new LPDIRECT3DTEXTURE9[anz_mat];

Page 20: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

for( i=0; i<anz_mat; i++) // Schleife durch die Materialien Texturen aus den Textur{

materialien[i] = mat[i].MatD3D; // Materialdaten werden in Array übertragen

// Materialen werden auf volle Reflexion (1.0) gesetzt, damit Licht reflektiert wirdmaterialien[i].Ambient.r = 1.0f;materialien[i].Ambient.g = 1.0f;materialien[i].Ambient.b = 1.0f;

// Texturen aus Dateien laden:if( D3DXCreateTextureFromFile( mein_directx.device,

mat[i].pTextureFilename, &texturen[i]) < 0)

texturen[i] = NULL;}

buf->Release(); // Buffer wird wieder frei gegeben }

Page 21: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Destruktor- Ressourcen zur Speicherung des Objekts sind dynamisch allokiert-> müssen beim Abbau des Objekts wieder freigegeben werden

objekt::~objekt(){unsigned int i;

if( materialien) delete[] materialien;

if( texturen){

for( i = 0; i < anz_mat; i++ ){

if( texturen[i]) texturen[i]->Release();

} delete[] texturen;

} if( mesh) mesh->Release();

}

Page 22: Balance V01 Der Windows-Rahmen S. 207 - 210 Vortrag von Lisa Rau

Methode draw

void objekt::draw(){unsigned int i;

for( i=0; i < anz_mat; i++ ) // Schleife durch alle Materialien{

// Material und zugehörige Textur in das Device laden:mein_directx.device->SetMaterial( &materialien[i]);

mein_directx.device->SetTexture( 0, texturen[i]);

mesh->DrawSubset( i); // Teilgitternetz zeichnen, das mit Material und Textur belegt wurde

}}

Zu beachten:- Device kann zu einem Zeitpunkt immer nur ein Material + Textur aufnehmen- kann aber ein ganzesTeilgitternetz, das damit belegt ist, rendern