Skip to content

Instantly share code, notes, and snippets.

@DarkMorford
Created January 22, 2017 19:58
Show Gist options
  • Select an option

  • Save DarkMorford/9bbcbfb1db19c0b98e76f8ca504921c1 to your computer and use it in GitHub Desktop.

Select an option

Save DarkMorford/9bbcbfb1db19c0b98e76f8ca504921c1 to your computer and use it in GitHub Desktop.
#include <kos.h>
#include <plx/matrix.h>
#include <plx/prim.h>
// Initialize KOS
KOS_INIT_FLAGS(INIT_DEFAULT);
// Global variables
bool exitProgram = false;
pvr_poly_hdr_t triStripHeader;
// Lighting information
float ambientLight = 0.3f;
float diffuseLight = 0.7f;
vector_t lightPosition = { 10.0f, 0.0f, 10.0f, 1.0f };
// Cube geometry
vector_t verts[8] = {
{ 1.0f, 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f }
};
vector_t normals[6] = {
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, -1.0f, 0.0f, 0.0f }
};
float calculateDiffuseIntensity(vector_t light, vector_t point, vector_t normal)
{
// Compute a valid normal vector
vec3f_normalize(normal.x, normal.y, normal.z);
// Compute the light direction vector
vector_t lightDirection;
vec3f_sub_normalize(
light.x, light.y, light.z,
point.x, point.y, point.z,
lightDirection.x, lightDirection.y, lightDirection.z
);
// Calculate the light's intensity at the point
float intensity;
vec3f_dot(
normal.x, normal.y, normal.z,
lightDirection.x, lightDirection.y, lightDirection.z,
intensity
);
if (intensity < 0.0f)
return 0.0f;
else
return intensity;
}
void submitVertex(vector_t vertex, vector_t normal, vector_t light, bool endOfStrip = false)
{
int flags = endOfStrip ? PVR_CMD_VERTEX_EOL : PVR_CMD_VERTEX;
float intensity = calculateDiffuseIntensity(light, vertex, normal);
float color = ambientLight + (intensity * diffuseLight);
plx_vert_fnp(flags, vertex.x, vertex.y, vertex.z, 1.0f, color, color, color);
}
void Setup()
{
// Initialize libraries
pvr_init_defaults();
plx_mat3d_init();
// Set the background color
pvr_set_bg_color(0.2f, 0.2f, 0.2f);
// Set up a triangle-strip header
pvr_poly_cxt_t polyContext;
pvr_poly_cxt_col(&polyContext, PVR_LIST_OP_POLY);
polyContext.gen.culling = PVR_CULLING_CW;
pvr_poly_compile(&triStripHeader, &polyContext);
// Position the "camera"
plx_mat3d_mode(PLX_MAT_PROJECTION);
plx_mat3d_identity();
plx_mat3d_perspective(60.0f, 640.0f / 480.0f, 0.1f, 100.0f);
plx_mat3d_mode(PLX_MAT_MODELVIEW);
plx_mat3d_identity();
point_t eye = { 5.0f, 0.0f, 5.0f, 1.0f };
point_t center = { 0.0f, 0.0f, 0.0f, 1.0f };
vector_t up = { 0.0f, 1.0f, 0.0f, 0.0f };
plx_mat3d_lookat(&eye, &center, &up);
}
void Loop()
{
// Transform the normal vectors into worldspace
plx_mat_identity();
plx_mat3d_apply(PLX_MAT_MODELVIEW);
vector_t transformedNormals[6];
for (int i = 0; i < 6; ++i)
{
mat_trans_normal3_nomod(
normals[i].x, normals[i].y, normals[i].z,
transformedNormals[i].x, transformedNormals[i].y, transformedNormals[i].z
);
}
// Transform the light's position
vector_t transformedLight = lightPosition;
mat_trans_single4(transformedLight.x, transformedLight.y, transformedLight.z, transformedLight.w);
// Transform the cube vertices
plx_mat_identity();
plx_mat3d_apply_all();
vector_t transformedVerts[8];
plx_mat_transform(verts, transformedVerts, 8, 4 * sizeof(float));
// Wait for the PVR to accept another frame
pvr_wait_ready();
// Begin rendering
pvr_scene_begin();
pvr_list_begin(PVR_LIST_OP_POLY);
// Send the triangle-strip header
pvr_prim(&triStripHeader, sizeof(triStripHeader));
// Front face
submitVertex(transformedVerts[0], transformedNormals[0], transformedLight);
submitVertex(transformedVerts[1], transformedNormals[0], transformedLight);
submitVertex(transformedVerts[2], transformedNormals[0], transformedLight);
submitVertex(transformedVerts[3], transformedNormals[0], transformedLight, true);
// Back face
submitVertex(transformedVerts[5], transformedNormals[1], transformedLight);
submitVertex(transformedVerts[4], transformedNormals[1], transformedLight);
submitVertex(transformedVerts[7], transformedNormals[1], transformedLight);
submitVertex(transformedVerts[6], transformedNormals[1], transformedLight, true);
// Right face
submitVertex(transformedVerts[4], transformedNormals[2], transformedLight);
submitVertex(transformedVerts[0], transformedNormals[2], transformedLight);
submitVertex(transformedVerts[6], transformedNormals[2], transformedLight);
submitVertex(transformedVerts[2], transformedNormals[2], transformedLight, true);
// Left face
submitVertex(transformedVerts[1], transformedNormals[3], transformedLight);
submitVertex(transformedVerts[5], transformedNormals[3], transformedLight);
submitVertex(transformedVerts[3], transformedNormals[3], transformedLight);
submitVertex(transformedVerts[7], transformedNormals[3], transformedLight, true);
// Top face
submitVertex(transformedVerts[4], transformedNormals[4], transformedLight);
submitVertex(transformedVerts[5], transformedNormals[4], transformedLight);
submitVertex(transformedVerts[0], transformedNormals[4], transformedLight);
submitVertex(transformedVerts[1], transformedNormals[4], transformedLight, true);
// Bottom face
submitVertex(transformedVerts[7], transformedNormals[5], transformedLight);
submitVertex(transformedVerts[6], transformedNormals[5], transformedLight);
submitVertex(transformedVerts[3], transformedNormals[5], transformedLight);
submitVertex(transformedVerts[2], transformedNormals[5], transformedLight, true);
// Finished rendering
pvr_list_finish();
pvr_scene_finish();
}
void Shutdown()
{
pvr_mem_stats();
pvr_shutdown();
}
int main(int argc, char *argv[])
{
Setup();
while (!exitProgram)
{
maple_device_t *controller = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
cont_state_t *controllerState = reinterpret_cast<cont_state_t*>(maple_dev_status(controller));
if (controllerState->buttons & CONT_START)
exitProgram = true;
Loop();
}
Shutdown();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment