It looks sort of normal, but a few vertices here and there are at the origin. Here is what I mean:
http://img297.imageshack.us/my.php?image=image019iv.png
And here is the code:
structures from the header:
Code: Select all
struct Vertex
{
	float nx,ny,nz;
	float x,y,z;
};
struct SphereObj
{
	Vertex *mesh;
	int slices, stacks;
	float radius;
};Code: Select all
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspgu.h>
#include <pspgum.h>
#include <png.h>
#include <math.h>
#include <stdlib.h>
#include "graphics.h"
#include "main.h"
PSP_MODULE_INFO("Light Demo", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
///// Global Variables ////////////////
static unsigned int __attribute__((aligned(16))) list[262144];
extern Vertex vertices[];
SphereObj obj;
///// Function Prototypes /////////////
int Setup();
int Render();
void Shutdown();
void DrawCube(float x, float y, float z, float scale);
void CreateSphere(SphereObj *obj, int slices, int stacks, float radius);
void RenderSphere(SphereObj *obj);
void DeleteSphere(SphereObj *obj);
int IsJoyInDeadZone(SceCtrlData *pad);
int SetupCallbacks();
int exit_callback(int arg1, int arg2, void *common);
int CallbackThread(SceSize args, void *argp);
int SetupCallbacks(void);
int main(int argc, char* argv[])
{
	Setup();
	while(true)
	{
		if(!Render())
			break;
	}
	Shutdown();
	return 0;
}
int Setup()
{
	SetupCallbacks();
	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_LIGHTING);
	sceGuEnable(GU_LIGHT0);
	sceGuEnable(GU_LIGHT1);
	sceGuEnable(GU_LIGHT2);
	sceGuFinish();
	sceGuSync(0,0);
	sceDisplayWaitVblankStart();
	sceGuDisplay(GU_TRUE);
	sceCtrlSetSamplingCycle(0);
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
	CreateSphere(&obj,20,10,2.0f);
	return 1;
}
int Render()
{
	static float fRotateX = 0.0f, fRotateY = 0.0f, fRotateZ = 0.0f;
	static float fLightRot[4] = {0.0f,0.0f,0.0f,0.0f};
	SceCtrlData pad;
	sceCtrlReadBufferPositive(&pad,1);
	if(pad.Buttons == PSP_CTRL_TRIANGLE)
	{
		return 0;
	}
	if(!IsJoyInDeadZone(&pad))
	{
		fRotateX += ((float)(pad.Ly - 128) / 64.0f);
		fRotateY += ((float)(pad.Lx - 128) / 64.0f);
	}
	sceGuStart(GU_DIRECT,list);
	sceGuClearColor(0xFF000000);
	sceGuClearDepth(0);
	sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
	
	unsigned int color[3] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
	ScePspFVector3 lpos[3] = { {cosf(DegToRad(fLightRot[0])) * 5.0f, sinf(DegToRad(fLightRot[0])) * 5.0f, 0},
							   {0, sinf(DegToRad(fLightRot[1])) * 5.0f, cosf(DegToRad(fLightRot[1])) * 5.0f},
							   {sinf(DegToRad(fLightRot[2])) * 5.0f,cosf(DegToRad(fLightRot[2])) * 5.0f,  0} };
	sceGuLight(0,GU_POINTLIGHT,GU_DIFFUSE,&lpos[0]);
	sceGuLightColor(0,GU_DIFFUSE,color[0]);
	sceGuLight(1,GU_POINTLIGHT,GU_DIFFUSE,&lpos[1]);
	sceGuLightColor(1,GU_DIFFUSE,color[1]);
	sceGuLight(2,GU_POINTLIGHT,GU_DIFFUSE,&lpos[2]);
	sceGuLightColor(2,GU_DIFFUSE,color[2]);
	sceGuAmbient(0x00222222);
	sceGumMatrixMode(GU_PROJECTION);
	sceGumLoadIdentity();
	sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f);
	sceGumMatrixMode(GU_VIEW);
	sceGumLoadIdentity();
	ScePspFVector3 pos = { 0, 0, -8.5f };
	sceGumTranslate(&pos);
	sceGumMatrixMode(GU_MODEL);
	sceGumLoadIdentity();
	ScePspFVector3 rot = { DegToRad(fRotateX), DegToRad(fRotateY), DegToRad(fRotateZ) };
	sceGumRotateXYZ(&rot);
	sceGuColor(0xFFFFFFFF);
	RenderSphere(&obj);
	// Draw light sources - disable lighting temporarily
	sceGuDisable(GU_LIGHTING);
	sceGumLoadIdentity();
	for(int i = 0; i < 3; i++)
	{
		sceGuColor(color[i]);
		DrawCube(lpos[i].x,lpos[i].y,lpos[i].z,0.075f);
	}
	sceGuEnable(GU_LIGHTING);
	sceGuFinish();
	sceGuSync(0,0);
	sceDisplayWaitVblankStart();
	sceGuSwapBuffers();
	fLightRot[0] += 0.5f;
	fLightRot[1] += 1.0f;
	fLightRot[2] += 1.5f;
	return 1;
}
void Shutdown()
{
	DeleteSphere(&obj);
	sceGuTerm();
	sceKernelExitGame();
}
void DrawCube(float x, float y, float z, float scale)
{
	ScePspFVector3 pos = { x, y, z };
	ScePspFVector3 scl = { scale, scale, scale };
	sceGumPushMatrix();
		sceGumTranslate(&pos);
		sceGumScale(&scl);
		sceGumDrawArray(GU_TRIANGLES,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D,12*3,0,vertices);
	sceGumPopMatrix();
}
void CreateSphere(SphereObj *obj, int slices, int stacks, float radius)
{
	float fTheta1, fTheta2, fTheta3;
	if(radius <= 0)													// Is radius valid?
		return;
	if(slices <= 0 || stacks <= 0)									// Is precision valid?
		return;
	if(obj->mesh)													// Does mesh already exist?
		free(obj->mesh);											// Deallocate existing mesh
	obj->slices = slices;											// Calculate slices
	obj->stacks = stacks;											// Calculate stacks
	obj->radius	= radius;
	obj->mesh = (Vertex *)malloc((obj->slices + 1) * obj->stacks * 2 * sizeof(Vertex));
	Vertex *meshptr = obj->mesh;									// Pointer to mesh data
	for(int j = 0; j < obj->stacks; j++)							// Loop through stacks
	{
		fTheta1 = j * PI / obj->stacks - PIDIV2;
		fTheta2 = (j + 1) * PI / obj->stacks - PIDIV2;
		for(int i = 0; i <= obj->slices; i++)						// Loop through slices
		{
			fTheta3 = i * TWOPI / slices;
			meshptr->nx = cosf(fTheta2) * cosf(fTheta3);
			meshptr->ny = sinf(fTheta2);
			meshptr->nz = cosf(fTheta2) * sinf(fTheta3);
			meshptr->x	= meshptr->nx * radius;
			meshptr->y	= meshptr->ny * radius;
			meshptr->z	= meshptr->nz * radius;
			meshptr++;
			meshptr->nx = cosf(fTheta1) * cosf(fTheta3);
			meshptr->ny = sinf(fTheta1);
			meshptr->nz = cosf(fTheta1) * sinf(fTheta3);
			meshptr->x	= meshptr->nx * radius;
			meshptr->y	= meshptr->ny * radius;
			meshptr->z	= meshptr->nz * radius;
			meshptr++;
		}
	}
}
void RenderSphere(SphereObj *obj)
{
	Vertex *meshptr = obj->mesh;
	for(int j = 0; j < obj->stacks; j++)
	{
		sceGumDrawArray(GU_TRIANGLE_STRIP,GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D,(obj->slices + 1) * 2,0,meshptr);
		meshptr += ((obj->slices + 1) * 2);
	}
}
void DeleteSphere(SphereObj *obj)
{
	if(obj->mesh)
	{
		free(obj->mesh);
		obj->mesh = NULL;
	}
}
int exit_callback(int arg1, int arg2, void *common)
{
	sceKernelExitGame();
	return 0;
}
int CallbackThread(SceSize args, void *argp)
{
	int cbid;
	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
	sceKernelRegisterExitCallback(cbid);
	sceKernelSleepThreadCB();
	return 0;
}
int SetupCallbacks(void)
{
	int thid = 0;
	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
	if(thid >= 0)
	{
		sceKernelStartThread(thid, 0, 0);
	}
	return thid;
}
int IsJoyInDeadZone(SceCtrlData *pad)
{
	if(pad->Lx < 110 || pad->Lx > 146)
		return 0;
	if(pad->Ly < 110 || pad->Ly > 146)
		return 0;
	return 1;
}