I've been playing with PSPSDK for a few weeks, and I tried making my own scene/models loader. I'm using ASE files I'm converting to binaries that I load with my PSP.
But I'm having troubles with lights right now. As it's hard to explain, I took some screenshots to show you.
My scene is a room, with 4 walls, a roof and a floor. On the screens, you'll see 3 green lines, these are the normals of each vertices of the selected face (shown in red). There's also a little cube where the light should be.
Screen 1:
http://www.rr4.net/screenshot1.jpg
On this screen, the light is at the center of the room, everything looks fine.
Screen 2:
http://www.rr4.net/screenshot2.jpg
I moved the light to the left (x--). Notice that the left wall is dark, and the right wall is bright. Also notice that the back wall, the roof and the floor lighting seems correct.
Screen 3:
http://www.rr4.net/screenshot3.jpg
I moved the light to the right (x++). The exact opposite of the screen 2. It seems like left wall and right wall should be inverted...
Screen 4:
http://www.rr4.net/screenshot4.jpg
This one is just to show that it's not only happening with the x axis. This time, I moved up the light (y++). Roof is getting darker, and floor is getting brighter, whereas walls lighting looks good.
Now, here are parts of my source code:
Code: Select all
typedef struct
{
float u, v;
float nx, ny, nz;
float x, y, z;
} Vertex;
typedef struct
{
Vertex a, b, c;
} Face;
typedef struct
{
int width, height;
unsigned char __attribute__((aligned(16))) *image;
} Texture;
typedef struct
{
char file[125];
int nbFaces;
Face *faces;
Texture texture;
float xpos, ypos, zpos;
float xrot, yrot, zrot;
} Model;
typedef struct
{
float xpos, ypos, zpos;
float xrot, yrot, zrot;
} Camera;
typedef struct
{
char type;
float x, y, z;
float att1, att2, att3;
} Light;
typedef struct
{
Camera camera;
int nbLights, nbModels;
Light *lights;
Model *models;
} Scene;
void drawModel(Model model) {
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
{
ScePspFVector3 pos = { model.xpos, model.ypos, model.zpos };
ScePspFVector3 rot = { model.xrot, model.yrot, model.zrot };
sceGumTranslate(&pos);
sceGumRotateXYZ(&rot);
}
if (model.texture.width!=0 && model.texture.height!=0) {
sceGuTexMode(GU_PSM_8888, 0, 0, 0);
sceGuTexImage(0, model.texture.width, model.texture.height, model.texture.width, model.texture.image);
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGB);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
}
sceGuAmbientColor(0xff808080);
sceGuColor(0xffffff);
sceGumDrawArray(GU_TRIANGLES, GU_NORMAL_32BITF|GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D, model.nbFaces*3, 0, model.faces);
}
void setLight(int index, Light light) {
ScePspFVector3 lightPosition = {light.x, light.y, light.z};
sceGuLight(index, light.type, GU_DIFFUSE, &lightPosition);
sceGuLightColor(index, GU_DIFFUSE, 0xff808080);
sceGuLightAtt(index, light.att1, light.att2, light.att3); // 0.0f, 0.001f, 0.0f in this case...
}
void drawScene(Scene scene) {
int i;
for (i=0;i<scene.nbLights;i++)
setLight(i, scene.lights[i]);
for (i=0;i<scene.nbModels;i++)
drawModel(scene.models[i]);
}
int main() {
Scene room;
pspDebugScreenInit();
SetupCallbacks();
// loading scene
// ...
sceKernelDcacheWritebackAll();
sceGuInit();
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH);
sceGuDepthBuffer((void*)0x110000,BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(0xc350,0x2710);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_CLIP_PLANES);
sceGuEnable(GU_TEXTURE_2D);
if (room.nbLights>0) {
sceGuEnable(GU_LIGHTING);
sceGuEnable(GU_LIGHT0);
}
if (room.nbLights>1)
sceGuEnable(GU_LIGHT1);
if (room.nbLights>2)
sceGuEnable(GU_LIGHT2);
if (room.nbLights>3)
sceGuEnable(GU_LIGHT3);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
for(;;) {
// Keypad stuff
// ...
sceGuStart(GU_DIRECT,list);
sceGuClearColor(0xff554433);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuAmbient(0x00222222);
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f);
sceGumMatrixMode(GU_VIEW);
sceGumLoadIdentity();
{
ScePspFVector3 pos = { room.camera.xpos, room.camera.ypos, room.camera.zpos };
ScePspFVector3 rot = { room.camera.xrot, room.camera.yrot, room.camera.zrot };
sceGumTranslate(&pos);
sceGumRotateXYZ(&rot);
}
drawScene(room);
sceGuFinish();
sceGuSync(0,0);
}
freeScene(room);
quit();
return 0;
}