| M | D | M | D | F | S | S |
|---|---|---|---|---|---|---|
| « Dez | Feb » | |||||
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Allgemein (6)
- Einfache 3D Welten (3)
- Erste Schritte (3)
- GU (4)
- Komplexe 3D Welten (1)
- 26.1.2011: Der Blog zieht um
- 23.3.2010: Der Anstrich - aber mit Plan
- 4.3.2010: 3D Landschaft - optimiert
- 17.2.2010: Landschaft 3D mit GU
- 28.1.2010: Ein Dreieck - GU Test
- 20.1.2010: Homebrew - 3D
- 12.1.2010: GU - und nu ?
- 11.1.2010: Neustart...
- 7.1.2010: Bildschirm aufräumen
- 5.1.2010: Schwarz/Weiß war gestern
PSP Allgemein
PSP Entwicklung
Ein Dreieck - GU Test
Die GU Bibliothek zur einfachen Erstellung unser ersten 3D Homebrew ist fertig und nun wollen wir natürlich einen ersten kleinen Test durchführen um - zunächsteinmal nur ein Dreieck - im virtuellen Raum auf den realen PSP Bildschirm zu zaubern.
Die in der PspHbc Bibliothek enthaltenen Header Files entpackt ihr am besten in euer PSPSDK Verzeichnis C:\pspsdk\psp\sdk\include das Lib-File kommt dann in das Verzeichnis C:\pspsdk\psp\sdk\lib dadurch wird die Nutzung in eigenen Projekten stark vereinfacht.
Nun aber los. Wie schon bei unserer ersten “normalen” Homebrew beginnt alles mit dem erstellen einer neuen Klasse. Diese wird nun von der 3DHomebrew-Basisklasse abgeleitet. Unsere Beispiel Homebrew soll den Namen HbcGuSample tragen. Die Klasse heißt dann treffender Weise: ClHbcGuSampleApp
/*
* 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_ */
Nachdem die neue Klasse nun definiert ist, können wir diese implementieren. Dabei ist der erste Teil der Implementierung recht einfach - glaube ich - da wir nur eine singleton Instanz erzeugen und diese zurück liefern. Die GU initializeirung bleibt unverändert.
/*
* HbcGuSampleApp.cpp
*
*/
extern “C”{
#include<pspgu.h>
#include<pspgum.h>
}
#include “HbcGuSampleApp.h”
ClHbcGuSampleApp* ClHbcGuSampleApp::_instance = 0;
// liefert singleton Instaz
ClHbcGuSampleApp *ClHbcGuSampleApp::getInstance(){
if(!_instance){
_instance = new ClHbcGuSampleApp();
}
return _instance;
}
//baut die singleton Instanz wieder ab und gibt Resourcen frei
void ClHbcGuSampleApp::releaseInstance(){
if (_instance) {
delete(_instance);
_instance = 0;
}
}
Der für die Klasse generierte Constructor und Destructor bleiben unberührt bzw. leer. Der nun “spannende” Teil befindet sich in der render Methode. Hier wollen wir unser erstes Objekt im virtuellen Raum definieren.
Wichtig:Definitionen von Objekten, Bewegungen und Objektrelationen im 3 dimensionalen Raum nutzen Vektoren und Matrizen. Wer also keinerlei Grundkenntnisse auf diesem Gebiet mitbringt sollte sich diese aneignen befor er hier weiter macht. Wikipedia ist eine gute Addresse um sich diesbezüglich aufzuschlauen. Oftmals helfen einem bei der Veranschaulichung auch ein paar Bleistifte (als Vektoren) und ein Tisch aus.
Das Dreieck
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.
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 Code:
//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); }
Ganz zum Schluss - bevor wir dieses Beispiel nun erstellen können müssen wir in unserem Makefile noch einige Bibliotheken aufnehmen, damit wir die GU Funktionen auch nutzen können. Im Detail sieht dieses dann folgendermaßen aus:
TARGET = hbcGuSample OBJS = main.o HbcGuSampleApp.o INCDIR = CFLAGS = -G0 -Wall -g CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti ASFLAGS = $(CFLAGS) BUILD_PRX = 1 LIBDIR = LDFLAGS = LIBS = -lstdc++ -lpsphbc -lpspgum -lpspgu -lpng -lz -lm EXTRA_TARGETS = EBOOT.PBP PSP_EBOOT_TITLE = HBC Gu Sample PSP_LARGE_MEM=1 PSP_FW_VERSION=500 PSPSDK=$(shell psp-config --pspsdk-path) include $(PSPSDK)/lib/build.mak
Wenn nun die Erstellung dieses Beispiels glatt gelaufen ist, dann sollte das ganze auf der PSP so aussehen:

Antwort schreiben
Sie müssen als angemeldet sein, um einen Kommentar schreiben zu können.