/*---------------------------------------------------------------------------* Project: NintendoWare File: GrRenderer.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. 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. The content herein is highly confidential and should be handled accordingly. $Revision: $ *---------------------------------------------------------------------------*/ #define NW_DEBUG_CHECK_MEMORY_LEAK #include "GrRenderer.h" //---------------------------------------------------------- void PrimitiveBox::Initialize(const nn::math::VEC3& halfEdges) { // 頂点ストリーム(Position) static const f32 s_BoxVtxStreamPosition[PrimitiveBox::VERTEX_NUM * 3] = { -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, }; // 頂点ストリーム (Normal) static const f32 s_BoxVtxStreamNormal[PrimitiveBox::VERTEX_NUM * 3] = { -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, }; // 頂点ストリーム(Color) static const f32 s_BoxVtxStreamColor[PrimitiveBox::VERTEX_NUM * 4] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.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, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f } ; // 6 面体の頂点インデックス static const u16 s_BoxVtxStreamIndex[PrimitiveBox::VERTEX_NUM * 1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 }; std::memcpy(m_StreamPosition, s_BoxVtxStreamPosition, sizeof(s_BoxVtxStreamPosition)); for (u32 index = 0; index < PrimitiveBox::VERTEX_NUM; index++) { m_StreamPosition[3 * index ] *= halfEdges.x; m_StreamPosition[3 * index + 1] *= halfEdges.y; m_StreamPosition[3 * index + 2] *= halfEdges.z; } std::memcpy(m_StreamNormal, s_BoxVtxStreamNormal, sizeof(s_BoxVtxStreamNormal)); std::memcpy(m_StreamColor, s_BoxVtxStreamColor, sizeof(s_BoxVtxStreamColor)); std::memcpy(m_StreamIndex, s_BoxVtxStreamIndex, sizeof(s_BoxVtxStreamIndex)); nngxUpdateBuffer(this, sizeof(PrimitiveBox)); } //---------------------------------------------------------- void GrPrimitiveRenderer::Initialize( nw::demo::DemoAllocator* deviceAllocator, const wchar_t* shaderFilePath ) { NW_NULL_ASSERT(deviceAllocator); m_DeviceAllocator = deviceAllocator; InitializeShader(shaderFilePath); InitializePrimitive(); InitializeEnvironments(); } //---------------------------------------------------------- void GrPrimitiveRenderer::Finalize() { m_VertexBox.DisableAll(); m_DeviceAllocator->Free(m_PrimitiveBox); m_DeviceAllocator->Free(m_ShaderBinary); } //---------------------------------------------------------- void GrPrimitiveRenderer::InitializeShader(const wchar_t* shaderFilePath) { bool isSuccess = false; NW_UNUSED_VARIABLE(isSuccess); // シェーダーの初期化 nw::ut::MoveArray shaderFile = nw::demo::Utility::LoadFile(m_DeviceAllocator, shaderFilePath ); m_ShaderBinary = shaderFile.release(); // シェーダーバイナリを指定して初期化 // 0番目の実行イメージを頂点シェーダーとして有効化 m_Shader.SetupBinary(m_ShaderBinary, 0, -1); // 文字列で、Uniform を検索 isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolWorldMtx, "world"); NW_ASSERT(isSuccess); isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolProjMtx, "proj"); NW_ASSERT(isSuccess); isSuccess = m_Shader.SearchBindSymbol(&m_BindSymbolViewMtx, "view"); NW_ASSERT(isSuccess); } //---------------------------------------------------------- void GrPrimitiveRenderer::InitializePrimitive() { bool isSuccess = false; NW_UNUSED_VARIABLE(isSuccess); uptr physicalAddr = 0; nn::gr::CTR::BindSymbolVSInput symbolPosition; nn::gr::CTR::BindSymbolVSInput symbolColor; nn::gr::CTR::BindSymbolVSInput symbolNormal; m_PrimitiveBox = static_cast(m_DeviceAllocator->Alloc(sizeof(PrimitiveBox), 128)); NW_ASSERT(m_PrimitiveBox); const nn::math::VEC3 halfEdges(10.0f, 10.0f, 10.0f); m_PrimitiveBox->Initialize(halfEdges); // 文字列による location の検索 isSuccess = m_Shader.SearchBindSymbol(&symbolPosition, "Position"); NW_ASSERT(isSuccess); isSuccess = m_Shader.SearchBindSymbol(&symbolColor, "Color"); NW_ASSERT(isSuccess); isSuccess = m_Shader.SearchBindSymbol(&symbolNormal, "Normal"); NW_ASSERT(isSuccess); // 頂点ストリーム(Position)の設定 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast(m_PrimitiveBox->m_StreamPosition)); m_VertexBox.EnableAttrAsArray(symbolPosition, physicalAddr, PICA_DATA_SIZE_3_FLOAT); // 頂点ストリーム(Color)の設定 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast(m_PrimitiveBox->m_StreamColor)); m_VertexBox.EnableAttrAsArray(symbolColor, physicalAddr, PICA_DATA_SIZE_4_FLOAT); // 頂点ストリーム(Normal)の設定 physicalAddr = nngxGetPhysicalAddr(reinterpret_cast(m_PrimitiveBox->m_StreamNormal)); m_VertexBox.EnableAttrAsArray(symbolNormal, physicalAddr, PICA_DATA_SIZE_3_FLOAT); // インデックスの設定 m_IndexStreamBox.physicalAddr = nngxGetPhysicalAddr(reinterpret_cast(m_PrimitiveBox->m_StreamIndex)); m_IndexStreamBox.drawVtxNum = m_PrimitiveBox->VERTEX_NUM; // インデックスを u16 で定義している m_IndexStreamBox.isUnsignedByte = false; } //---------------------------------------------------------- void GrPrimitiveRenderer::InitializeEnvironments() { m_Viewport.Set(0, 0, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT); m_Scissor.Set(0, 0, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT); } //---------------------------------------------------------- bit32* GrPrimitiveRenderer::MakeSceneBeginCommand(bit32* command) { command = nn::gr::CTR::MakeDisableAllCommand(command); // ビューポート設定. command = m_Viewport.MakeCommand(command); // シザー設定. command = m_Scissor.MakeCommand(command); // シェーダバイナリの設定 ( glUseProgram() ) command = m_Shader.MakeFullCommand(command); // レンダーステートの設定 // Cull, Depth, Stencil, AlphaTest, Blend, etc. nn::gr::RenderState render_state; command = render_state.MakeCommand(command); // テクスチャの設定 nn::gr::Texture texture; texture.unit0.texType = PICA_DATA_TEXTURE0_SAMPLER_TYPE_FALSE; texture.unit1.texType = PICA_DATA_TEXTURE1_SAMPLER_TYPE_FALSE; texture.unit2.texType = PICA_DATA_TEXTURE2_SAMPLER_TYPE_FALSE; texture.unit3.texType = PICA_DATA_TEXTURE3_SAMPLER_TYPE_FALSE; command = texture.MakeCommand(command); //テクスチャコンバイナの設定 nn::gr::Combiner combiner; // テクスチャコンバイナの設定の変更 // プライマリカラーで置換 combiner.stage[0].rgb.combine = PICA_DATA_TEX_ENV_COMBINE_REPLACE; combiner.stage[0].rgb.source[0] = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR; combiner.stage[0].rgb.source[1] = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_SECONDARY_COLOR_DMP; command = combiner.MakeCommand(command); // 頂点を使用し始める前に、全ての頂点属性を無効化 command = nn::gr::Vertex::MakeDisableCommand(command); return command; } //---------------------------------------------------------- bit32* GrPrimitiveRenderer::MakeDrawBoxCommand(bit32* command, const nn::math::MTX34& worldMatrix) { nn::gr::Vertex* pVertex = &m_VertexBox; nn::gr::Vertex::IndexStream* pIndexStream = &m_IndexStreamBox; // モデル行列の設定 command = m_BindSymbolWorldMtx.MakeUniformCommand(command, worldMatrix); // Box プリミティブを描画 // glBindBuffer( GL_ARRAY_BUFFER ) command = pVertex->MakeEnableAttrCommand(command); // glBindBuffer( GL_ELEMENT_ARRAY_BUFFER ) + glDrawElements() command = pVertex->MakeDrawCommand(command, *pIndexStream); return command; }