📄 sprite.c
字号:
/*
* PSP Software Development Kit - http://www.pspdev.org
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* Copyright (c) 2005 Jesper Svennevid
*/
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <pspgu.h>
#include <pspgum.h>
#include "../common/callbacks.h"
#include "../common/vram.h"
PSP_MODULE_INFO("Sprite Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
static unsigned int __attribute__((aligned(16))) list[262144];
extern unsigned char ball_start[];
struct InputVertex
{
float x,y,z;
};
struct Vertex
{
float u, v;
unsigned int color;
float x,y,z;
};
void create_torus_billboards(struct Vertex* vertices, float* world);
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define NUM_SLICES 128
#define NUM_ROWS 128
#define RING_SIZE 2.0f
#define RING_RADIUS 1.0f
#define SPRITE_SIZE 0.025f
unsigned int colors[8] =
{
0xffff0000,
0xffff00ff,
0xff0000ff,
0xff00ffff,
0xff00ff00,
0xffffff00,
0xffffffff,
0xff101010
};
struct InputVertex torus_vertices[NUM_SLICES * NUM_ROWS];
int main(int argc, char* argv[])
{
unsigned int i,j;
setupCallbacks();
// initialize torus
for (i = 0; i < NUM_SLICES; ++i)
{
for (j = 0; j < NUM_ROWS; ++j)
{
float s = i + 0.5f, t = j;
float x,y,z;
x = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * cosf(t * ((GU_PI*2)/NUM_ROWS));
y = (RING_SIZE + RING_RADIUS * cosf(s * ((GU_PI*2)/NUM_SLICES))) * sinf(t * ((GU_PI*2)/NUM_ROWS));
z = RING_RADIUS * sinf(s * ((GU_PI*2)/NUM_SLICES));
torus_vertices[j + i * NUM_ROWS].x = x;
torus_vertices[j + i * NUM_ROWS].y = y;
torus_vertices[j + i * NUM_ROWS].z = z;
}
}
// setup GU
sceGuInit();
void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444);
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH);
sceGuDepthBuffer(zbp,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);
sceGuAlphaFunc(GU_GREATER,0,0xff);
sceGuEnable(GU_ALPHA_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
// run sample
ScePspFMatrix4 world;
float val = 0;
while(running())
{
struct Vertex* vertices;
sceGuStart(GU_DIRECT,list);
// clear screen
sceGuClearColor(0xff554433);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
// setup texture
sceGuTexMode(GU_PSM_5551,0,0,0);
sceGuTexImage(0,32,32,32,ball_start); // width, height, buffer width, tbp
sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA); // NOTE: this enables reads of the alpha-component from the texture, otherwise blend/test won't work
sceGuTexFilter(GU_NEAREST,GU_NEAREST);
sceGuTexWrap(GU_CLAMP,GU_CLAMP);
sceGuTexScale(1,1);
sceGuTexOffset(0,0);
sceGuAmbientColor(0xffffffff);
// setup transforms
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumPerspective(75.0f,16.0f/9.0f,0.5f,1000.0f);
sceGumMatrixMode(GU_VIEW);
{
ScePspFVector3 pos = {0.0f,0.0f,-3.5f};
sceGumLoadIdentity();
sceGumTranslate(&pos);
}
sceGumMatrixMode(GU_MODEL);
{
ScePspFVector3 rot = {val * 0.3f * (GU_PI/180.0f), val * 0.7f * (GU_PI/180.0f), val * 1.3f * (GU_PI/180.0f)};
sceGumLoadIdentity();
sceGumRotateXYZ(&rot);
}
sceGumStoreMatrix(&world);
// render torus
vertices = sceGuGetMemory(NUM_SLICES * NUM_ROWS * 2 * sizeof(struct Vertex));
create_torus_billboards(vertices,(float*)&world);
sceGumDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D,NUM_SLICES*NUM_ROWS*2,0,vertices);
// wait for next frame
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
val += 0.6f;
}
sceGuTerm();
sceKernelExitGame();
return 0;
}
/* this function generates the billboards rendered by sceGuDrawArray() */
void create_torus_billboards(struct Vertex* vertices, float* world)
{
unsigned int i,j;
float sx, sy, sz;
// calculate billboard world offsets
sx = SPRITE_SIZE * world[(0 << 2)+0] + SPRITE_SIZE * world[(0 << 2)+1];
sy = SPRITE_SIZE * world[(1 << 2)+0] + SPRITE_SIZE * world[(1 << 2)+1];
sz = SPRITE_SIZE * world[(2 << 2)+0] + SPRITE_SIZE * world[(2 << 2)+1];
for (i = 0; i < NUM_SLICES; ++i)
{
struct Vertex* row = &vertices[i * NUM_ROWS * 2];
struct InputVertex* inrow = &torus_vertices[i * NUM_ROWS];
for (j = 0; j < NUM_ROWS; ++j)
{
struct Vertex* curr = &row[j << 1];
struct InputVertex* incurr = &inrow[j];
float x, y, z;
x = incurr->x;
y = incurr->y;
z = incurr->z;
curr[0].u = 0;
curr[0].v = 0;
curr[0].color = colors[(i+j)&7];
curr[0].x = x - sx;
curr[0].y = y - sy;
curr[0].z = z - sz;
curr[1].u = 1;
curr[1].v = 1;
curr[1].color = colors[(i+j)&7];
curr[1].x = x + sx;
curr[1].y = y + sy;
curr[1].z = z + sz;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -