/*---------------------------------------------------------------------------* Copyright (C) 2010-2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #include #include #include #include #include #define PI 3.14159f // ----- Surface Information #define RENDERTARGET_WIDTH 1280 #define RENDERTARGET_HEIGHT 720 #define SURFACE_WIDTH 1280 #define SURFACE_HEIGHT 720 //////////////////////////////////////////////////// // // Assets Data // //////////////////////////////////////////////////// // ----- Attribute Layout struct AttributeLayout { const char* shaderVarName; GX2AttribFormat attribFormat; u32 elementSize; }; // ----- Model files #define NUM_MODEL 4 static char* MODEL_FILES[NUM_MODEL][3] = { {"assets/geometries/elephantPosition.dat", "assets/geometries/elephantNormal.dat", "assets/geometries/elephantIdx.dat"}, {"assets/geometries/teapotPosition.dat", "assets/geometries/teapotNormal.dat", "assets/geometries/teapotIdx.dat"}, {"assets/geometries/torusPosition.dat", "assets/geometries/torusNormal.dat", "assets/geometries/torusIdx.dat"}, {"assets/geometries/spherePosition.dat", "assets/geometries/sphereNormal.dat", "assets/geometries/sphereIdx.dat"} }; // ----- Shader files static const char * const GSH_SHADER_FILE_DEFERRED_GEOMETRY = "assets/shaders/test_gx2/cafe/shading/deferredRenderingSetup.gsh"; static const char * const GSH_SHADER_FILE_DEFERRED_LIGHTING = "assets/shaders/test_gx2/cafe/shading/deferredRenderingLighting.gsh"; static const char * const GSH_SHADER_FILE_TEXTURE2D = "assets/shaders/test_gx2/cafe/simple/texture2D.gsh"; // ----- Struct for geometry stage attribute buffers static AttributeLayout s_modelAttributeLayout[] = { { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) }, { "a_normal", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) }, }; static const u32 MODEL_NUM_ATTRIBUTES=sizeof(s_modelAttributeLayout)/sizeof(s_modelAttributeLayout[0]); typedef struct _ModelAttribBuffer { GX2RBuffer attributeBuffer[MODEL_NUM_ATTRIBUTES]; GX2RBuffer indexBuffer; } ModelAttribBuffer; // ----- Struct for lighting stage attribute buffers static AttributeLayout s_LightingAttributeLayout[] = { { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) }, { "a_texCoord", GX2_ATTRIB_FORMAT_32_32_FLOAT, sizeof(DEMO_F32x2) }, }; static const u32 LIGHTING_NUM_ATTRIBUTES=sizeof(s_LightingAttributeLayout)/sizeof(s_LightingAttributeLayout[0]); typedef struct _LightingAttribBuffer { GX2RBuffer attributeBuffer[LIGHTING_NUM_ATTRIBUTES]; GX2RBuffer indexBuffer; } LightingAttribBuffer; // ----- Struct for gbuffer stage attribute buffers static AttributeLayout s_gBufferAttributeLayout[] = { { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) }, { "a_texCoord", GX2_ATTRIB_FORMAT_32_32_FLOAT, sizeof(DEMO_F32x2) }, }; static const u32 G_BUFFER_NUM_ATTRIBUTES=sizeof(s_gBufferAttributeLayout)/sizeof(s_gBufferAttributeLayout[0]); typedef struct _GBufferAttribBuffer { GX2RBuffer attributeBuffer[G_BUFFER_NUM_ATTRIBUTES]; GX2RBuffer indexBuffer; } GBufferAttribBuffer; static struct _GeometryPass { // -- Shaders -- // DEMOGfxShader shaders; // -- Constant Buffers -- // Mtx44 modelMtx44; Mtx44 viewprojMtx44; Qtrn color; // -- Attribute Buffers -- // ModelAttribBuffer attribs[NUM_MODEL]; // -- Texture Setting -- // GX2ColorBuffer myColorBuffer[3]; void * myColorBufferData[3]; void * myScanBufferPtr; } GeometryPass; static struct _LightingPass { // -- Shaders -- // DEMOGfxShader shaders; // -- Constant Buffers -- // Qtrn ambientColor; Qtrn lightColor; Qtrn lightPosition; Qtrn cameraPosition; // -- Attribute Buffers -- // LightingAttribBuffer attribs; // -- Texture Setting -- // GX2Texture myTextureBuffer[3]; GX2Sampler mySampler; } LightingPass; static struct _BuffersPass { // -- Shaders -- // DEMOGfxShader shaders; // -- Attribute Buffers -- // GBufferAttribBuffer attribs; // -- Texture Setting -- // GX2Texture myTextureBuffer[3]; GX2Sampler mySampler; } BuffersPass; // Globals static float s_rotateY; static BOOL s_drawBuffers; static u32 s_modelIdx; static u32 s_avgNoSwizzleTime; static u32 s_avgSwizzleTime; static u32 s_noSwizzleTime; static u32 s_swizzleTime; static u64* s_timerData; static u32 s_ticks; // Prototype static void CameraInit(Mtx44 resultViewProjMtx44); static void SceneInit(void); static void SceneUpdate(void); static void GeometryPassInit(void); static void LightingPassInit(void); static void BuffersPassInit(void); static void SceneFree(void); static void GeometryPassDraw(void); static void LightingPassDraw(void); static void BuffersPassDraw(void); static void SceneDraw(void); // Init function for setting projection matrix static void CameraInit(Mtx44 resultViewProjMtx44) { // row major matricies Mtx lookAtMtx34; Mtx44 projMtx44; Mtx44 viewMtx44; Vec up = {0.0f, 1.0f, 0.0f}; Vec objPt = {0.0f, 0.0f, 0.0f}; Vec camLoc = {0.0f, 0.0f, 300.0f}; f32 pers = 30.0f; f32 aspect = (f32)SURFACE_WIDTH / (f32)SURFACE_HEIGHT; f32 znear = 50.0f; f32 zfar = 2000.0f; // Set light position LightingPass.cameraPosition.x = camLoc.x; LightingPass.cameraPosition.y = camLoc.y; LightingPass.cameraPosition.z = camLoc.z; LightingPass.cameraPosition.w = 1.0f; // Compute perspective matrix MTXPerspective(projMtx44, pers, aspect, znear, zfar); // Compute lookAt matrix MTXLookAt(lookAtMtx34, &camLoc, &up, &objPt); MTX34To44(lookAtMtx34, viewMtx44); // return view+proj MTX44Concat(projMtx44, viewMtx44, resultViewProjMtx44); } // The init function for the rendering portions of this app static void SceneInit(void) { // Initialize globals s_rotateY = 0.0f; s_drawBuffers = TRUE; s_modelIdx = 0; s_noSwizzleTime = 0; s_swizzleTime = 0; s_avgNoSwizzleTime = 0; s_avgSwizzleTime = 0; s_timerData = (u64*)DEMOGfxAllocMEM2(sizeof(u64)*2, GX2_DEFAULT_BUFFER_ALIGNMENT); s_ticks = 0; // Initialize passes GeometryPassInit(); LightingPassInit(); BuffersPassInit(); } // rotate the model static void SceneUpdate(void) { Mtx modelWorldMtx; MTXRotRad(modelWorldMtx, 'y', s_rotateY / 4.0f); MTX34To44(modelWorldMtx, GeometryPass.modelMtx44); s_rotateY += 0.06f; if(s_rotateY > PI*8) { s_rotateY -= PI*8; s_drawBuffers = !s_drawBuffers; if(s_drawBuffers) s_modelIdx = (s_modelIdx + 1) % NUM_MODEL; } ++s_ticks; } static GX2RBuffer LoadModelBuffer(const char* modelFileName, GX2RResourceFlags resourceFlags, u32 elementSize) { // This version does it's own file reading to eliminate the extra malloc/memcpy/free // and just load straight into the buffer memory. DEMOFSFileInfo file; u32 fileLen; s32 fileRet; fileRet = DEMOFSOpenFile(modelFileName, &file); DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't open file"); fileRet = DEMOFSGetLength(&file, &fileLen); DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't get file length"); u32 elementCount = fileLen/elementSize; GX2RBuffer gx2Buffer; GX2UTCreateBuffer(&gx2Buffer, resourceFlags | GX2R_USAGE_CPU_WRITE | GX2R_USAGE_GPU_READ, elementSize, elementCount); GX2RSetBufferName(&gx2Buffer, modelFileName); // Lock the buffer and read straight into the memory with no copying void* pMem=GX2RLockBuffer(&gx2Buffer); fileRet = DEMOFSRead(&file, pMem, (s32)fileLen, 0); DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't read file"); GX2RUnlockBuffer(&gx2Buffer); fileRet = DEMOFSCloseFile(&file); if (fileRet != DEMO_FS_RESULT_OK) { DEMOAssert(!"couldn't close file"); } return gx2Buffer; } // Initialized the Geometry pass static void GeometryPassInit(void) { u32 i; u32 gshLen; void *gshBuf; // initialize uniforms CameraInit(GeometryPass.viewprojMtx44); SceneUpdate(); GeometryPass.color.x = 1.0f; GeometryPass.color.y = 0.0f; GeometryPass.color.z = 0.0f; GeometryPass.color.w = 80.0f / 255.0f; // shininess / 255.0f // DEMOFSSimpleRead sets PPC_IO_BUFFER_ALIGN alignment. // This number must fit to vertex and index buffer alignment. ASSERT(PPC_IO_BUFFER_ALIGN % GX2_VERTEX_BUFFER_ALIGNMENT == 0); ASSERT(PPC_IO_BUFFER_ALIGN % GX2_INDEX_BUFFER_ALIGNMENT == 0); // load models for(i = 0; i < NUM_MODEL; ++i) { // Load attribute buffers for (u32 attribSlot=0; attribSlot