GU - Grafikpower der PSP
Die GU - das ist die “Graphic Unit” der PSP. Ich habe keine wirkliche Auflösung dieses Kürzels gefunden, aber im
Grunde kann man sich die GU wie einen Teil der Grafikkarte eines PC’s vorstellen. Dieser Teil ist in der Lage 3D
Grafiken zu berechnen und darzustellen.
Der Vorteil der GU ist, dass diese eine sehr leistungsstarke Einheit ist, die quasi parallel zur CPU der PSP arbeitet
und einen optimierten Datenbus zur Grafikausgabe und zu bestimmten Hauptspeicherbereichen hat. Wer sich schon mit
verschieden 3D Spielen auf dem PC auseinander gesetzt hat weiß vielleicht, dass Hardwarebeschleunigung in einer
Grafikkarte bei der Berechnung der Grafik gegenüber der reinen CPU enorme Vorteile und Performancegewinn bietet und
uns dadurch auch auf der PSP vermutlich einige Türen öffnen wird.
Hier gibt es nun ersteinmal ein wenig Theorie zum Thema Grafik mit der GU der PSP. Die notwendige Initialisierung für unsere
Homebrews findet in den jeweiligen Basisklassen statt. Dennoch kann es nicht schaden, die Grundlegene Funktionsweise
zu kennen.
Der virtuelle Raum der PSP
Damit die Abbildung 3 dimensionaler Objekte funktionieren kann, braucht man einen virtuellen 3 dimensionalen Raum in
dem man seine Objekte platzieren kann. In eben dem selben befindet sich dann quasi eine virtuelle Kamera durch die
man die Objekte betrachten kann. Das was die Kamera sieht bringt die GU dann auf den PSP Bildschirm.
Dieser virtuelle Raum - auch oft als “World space” bezeichnet - hat bei der PSP eine Ausdehnung von 4096 Einheiten in
die X- und Y-Richtung. Die Ausdehnungsbegrenzung der Z-Achse ist mir nicht bekannt. Es wird von der GU ein
Links-Händiges Koordinatensystem verwendet. Wer wissen möchte was damit gemeint ist, wird bei Google sehr schnell fündig werden.
Arbeitsweise der GU
Die GU der PSP arbeitet Kommandos ähnlich einem Batch ab. Das heißt, dass alle Aktionen/Befehle die von der GU
verarbeitet werden sollen in einer Art Liste gesammelt werden. Anschließend wird die Liste der GU zur Bearbeitung
übergeben. Der Vorteil: Während die GU diese Liste abarbeitet kann das normale Programm fortgesetzt werden.
Virtuelle Objekte im virtuellen Raum
Jedes Objekt im virtuellen Raum wird - wie üblich - durch Dreiecke beschrieben. Jedes Dreieck wiederum wird durch 3
Punkte beschrieben. Jeder Punkt wird mittels eines Vektors beschrieben. Der Vektor enthält dabei die x, y und z -
Koordinaten des Punktes bezogen auf den Koordinatenursprung - dem Null-Punkt. Bei der Beschreibung der Objekte durch
Dreiecke ist es von Bedeutung in welcher Reihenfolge die Punkte angeordnet sind. Dadurch “weiß” die GU wo vorne und
wo hinten ist. Wir stellen uns vor dem geistigen Auge ein Dreick vor auf das man von oben drauf schaut. Wenn man nun
die Punkte im Uhrzeigersinn aufzählt, und so das Dreieck beschreibt dann ist die Seite des Dreieckes das wir sehen
vorne. Sind die Punkte dagegen gegen den Uhrzeigersinn angeordnet, dann schaut man auf die Rückseite. Dies ist
insofern wichtig, da mann der GU aus performance Gründen die Berechnung der Flächen die man nur von “hinten” sieht
verbieten kann. Schließlich muss man von einem Würfel ja nicht die Innenseite berechnen, wenn sie nie zu sehen ist.
Die virtuelle Kamera
Für die Darstellung der virtuellen Objekte des virtuellen Raumes auf dem realen Bildschirm der PSP wird dieser ebenso
im virtuellen Raum platziert. Dies wird im allgemeinen auch Viewport genannt. Dieser Viewport/virtuelle Bildschirm
hat im virtuellen Raum in der Regel “reale” Abmessungen und ist damit im Normalfall 480 Einheiten breit und 272
Einheiten hoch - genauso wie der Bildschirm.
Puffer
Für flimmerfreies darstellen der virtuellen 3D Welt arbeitet die GU mit zwei Puffern, zwischen denen nach jedem
“Zeichenvorgang” gewechselt wird/werden muss. Zusätzlich besitzt die GU noch einen Tiefenpuffer - auch als Z-Puffer
bekannt. Damit ist es für die GU möglich sicherzustellen, dass verdeckte Objekte garnicht bzw. dass sich überlappende
Objekte immer in der richtigen Reihenfolge dargestellt werden.
Ein Dreick im Raum
Für unser erstes virtual 3D Homebrew nutzen wir natürlich die PSPHBC Bibliothek. Die Homebrew Klasse wird dabei von
der Basisklasse Cl3dHomebrew abgeleitet.
/*
* HbcGuSampleApp.h
* Beispiel Implementierung der GU Homebrew Basisklasse
*/
#ifndef HBCGUSAMPLEAPP_H_
#define HBCGUSAMPLEAPP_H_
#include <3dHomebrew.h>
class ClHbcGuSampleApp : public Cl3dHomebrew {
public:
static ClHbcGuSampleApp* getInstance();
static void releaseInstance();
// Redefiniren der Render Methode um sie mit eigender Logik zu füllen
void render();
protected: ClHbcGuSampleApp();
virtual ~ClHbcGuSampleApp();
static ClHbcGuSampleApp* _instance;
};
#endif /* HBCGUSAMPLEAPP_H_ */
Das Dreick wird durch 3 Punkte im virtuellen Raum beschrieben. Diese Punkte erhalten zusätzlich zu ihrer Position
noch einen Farbwert, so dass die Fläche die von dem Dreieck umspannt wird entsprechend ausgefüllt wird. Dabei
verwenden wir hier für jeden Punkt einen anderen Farbwert um einen netten Farbverlauf zu erzeugen. Ganz nebenbei wird
verdeutlicht, dass die GU eine flexible Struktur der Vertices unterstützt.
void ClHbcGuSampleApp::render(){
// Definition einer Struktur die einen 3D-Punkt beschreibt
typedef struct Vertex {
int color;
float x, y, z;
}Vertex;
//Speicher für 3 Punkte reservieren
//dieser Speicher ist dabei nur temporär und nur innerhalb der aktuellen GU Liste gültig
Vertex* triangle = (Vertex*)sceGuGetMemory(sizeof(Vertex)*3);
//Daten für die Punkte
triangle[0].x = -4.0f;
triangle[0].y = -2.0f;
triangle[0].z = -10.0f;
triangle[0].color = 0xff0000ff;
triangle[1].x = 0.0f;
triangle[1].y = 2.0f;
triangle[1].z = -10.0f;
triangle[1].color = 0xffff0000;
triangle[2].x = 4.0f;
triangle[2].y = -2.0f;
triangle[2].z = -10.0f;
triangle[2].color = 0xff00ff00;
Als nächsten Schritt wollen wir dieses Dreieck auch zeichnen. Zuerst leeren wir den Bildschirm mit einer von schwarz
verschiedenen Farbe (schwarz macht’s die Basisklasse). Dadurch kann mann schneller erkennen ob hier was “gezeichnet”
wird oder nicht, da ggfl. schwarz auf schwarz gezeichnete Objekte nicht sichtbar wären…
Nachdem wir den Bildschirm nochmals geleert haben müssen wir die Projektion der GU festlegen. Dafür legen wir für den
aktuellen View und für das Objektmodell eine Einheitsmatrix fest. Dies bedeutet, dass weder unsere Kamera, noch unser
Objekt im Raum manipuliert werden. Sie werden so dargestellt wie wir sie im Raum platziert haben. Mit der Model-Matrix
wären wir z.Bsp. in der Lage das Objekt im Raum zu bewegen oder zu rotieren, ohne die ursprüngliche Definition der
Punkte zu verändern. Doch das beleuchten wir zu einem späteren Zeitpunkt.
Doch nun zum Rest des Codes:
//den Bildschirm mit einer eigenen Farbe leeren, anders als in 3DHomebrew
sceGuClearColor(0xff442222);
sceGuClear(GU_COLOR_BUFFER_BIT);
// Festlegen der View und Model Matrix als Einheitsmatrix
sceGumMatrixMode(GU_VIEW);
sceGumLoadIdentity();
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
//damit die Farbwerte beim Füllen des Dreiecks verlaufen “smooth” (weiche/fortlaufende) Schattierung aktivieren
sceGuShadeModel(GU_SMOOTH);
//Das Dreieck kommt ganz ohne Texturen aus…also deaktivieren
sceGuDisable(GU_TEXTURE_2D);
// hier wird das Dreieck dann tatsächlich auf den Bildschirm gebracht, oder
// besser in den Zeichenpuffer der beim nächsten wechsel zwischen Display- und Zeichenpuffer
// sichtbar wird
sceGumDrawArray(GU_TRIANGLES, GU_TRANSFORM_3D | GU_VERTEX_32BITF | GU_COLOR_8888, 3, 0, triangle);
}
Wenn nun das Erstellen des Homebrews funktioniert hat und es auf der PSP läuft sollte es so aus sehen:
|