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;
}