/*---------------------------------------------------------------------------* Project: NintendoWare File: lyt_Window.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. 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. $Revision: 26746 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include #include #include #include #include #include #include #include #include namespace nw { namespace lyt { namespace local { namespace { struct Rect { f32 x, y, w, h; const math::VEC2& Position() const { return *(const math::VEC2 *)&this->x; } const nw::lyt::Size& Size() const { return *(const nw::lyt::Size *)&this->w; } }; struct TextureFlipInfo { u8 coords[VERTEX_MAX][2]; u8 idx[2]; }; const TextureFlipInfo& GetTexutreFlipInfo(u8 textureFlip) { NW_ASSERT(textureFlip < TEXTUREFLIP_MAX); static TextureFlipInfo flipInfos[] = { { { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }, { 0, 1 } }, // TEXTUREFLIP_NONE { { { 1, 0 }, { 0, 0 }, { 1, 1 }, { 0, 1 } }, { 0, 1 } }, // TEXTUREFLIP_FLIPH { { { 0, 1 }, { 1, 1 }, { 0, 0 }, { 1, 0 } }, { 0, 1 } }, // TEXTUREFLIP_FLIPV { { { 0, 1 }, { 0, 0 }, { 1, 1 }, { 1, 0 } }, { 1, 0 } }, // TEXTUREFLIP_ROTATE90 { { { 1, 1 }, { 0, 1 }, { 1, 0 }, { 0, 0 } }, { 0, 1 } }, // TEXTUREFLIP_ROTATE180 { { { 1, 0 }, { 1, 1 }, { 0, 0 }, { 0, 1 } }, { 1, 0 } }, // TEXTUREFLIP_ROTATE270 }; return flipInfos[textureFlip]; } void GetLTFrameSize( math::VEC2* pPt, Size* pSize, const math::VEC2& basePt, const Size& winSize, const WindowFrameSize& frameSize ) { *pPt = basePt; pSize->width = winSize.width - frameSize.r; pSize->height = frameSize.t; } void GetLTTexCoord( math::VEC2 texCds[], const Size& polSize, const TexSize& texSize, u8 textureFlip ) { const TextureFlipInfo& flipInfo = GetTexutreFlipInfo(textureFlip); const int ix = flipInfo.idx[0]; const int iy = flipInfo.idx[1]; const math::VEC2 tSz(texSize.width, texSize.height); texCds[VERTEX_LT][ix] = texCds[VERTEX_LB][ix] = flipInfo.coords[VERTEX_LT][ix]; texCds[VERTEX_LT][iy] = texCds[VERTEX_RT][iy] = flipInfo.coords[VERTEX_LT][iy]; texCds[VERTEX_RB][ix] = texCds[VERTEX_RT][ix] = polSize.width / ((flipInfo.coords[VERTEX_RT][ix] - flipInfo.coords[VERTEX_LT][ix]) * tSz[ix]) + flipInfo.coords[VERTEX_LT][ix]; texCds[VERTEX_RB][iy] = texCds[VERTEX_LB][iy] = polSize.height / ((flipInfo.coords[VERTEX_LB][iy] - flipInfo.coords[VERTEX_LT][iy]) * tSz[iy]) + flipInfo.coords[VERTEX_LT][iy]; } void GetRTFrameSize( math::VEC2* pPt, Size* pSize, const math::VEC2& basePt, const Size& winSize, const WindowFrameSize& frameSize ) { using namespace nw::math; *pPt = VEC2(basePt.x + winSize.width - frameSize.r, basePt.y); pSize->width = frameSize.r; pSize->height = winSize.height - frameSize.b; } void GetRTTexCoord( math::VEC2 texCds[], const Size& polSize, const TexSize& texSize, u8 textureFlip ) { const TextureFlipInfo& flipInfo = GetTexutreFlipInfo(textureFlip); const int ix = flipInfo.idx[0]; const int iy = flipInfo.idx[1]; const math::VEC2 tSz(texSize.width, texSize.height); texCds[VERTEX_RT][ix] = texCds[VERTEX_RB][ix] = flipInfo.coords[VERTEX_RT][ix]; texCds[VERTEX_RT][iy] = texCds[VERTEX_LT][iy] = flipInfo.coords[VERTEX_RT][iy]; texCds[VERTEX_LB][ix] = texCds[VERTEX_LT][ix] = polSize.width / ((flipInfo.coords[VERTEX_LT][ix] - flipInfo.coords[VERTEX_RT][ix]) * tSz[ix]) + flipInfo.coords[VERTEX_RT][ix]; texCds[VERTEX_LB][iy] = texCds[VERTEX_RB][iy] = polSize.height / ((flipInfo.coords[VERTEX_RB][iy] - flipInfo.coords[VERTEX_RT][iy]) * tSz[iy]) + flipInfo.coords[VERTEX_RT][iy]; } void GetLBFrameSize( math::VEC2* pPt, Size* pSize, const math::VEC2& basePt, const Size& winSize, const WindowFrameSize& frameSize ) { *pPt = math::VEC2(basePt.x, basePt.y - frameSize.t); pSize->width = frameSize.l; pSize->height = winSize.height - frameSize.t; } void GetLBTexCoord( math::VEC2 texCds[], const Size& polSize, const TexSize& texSize, u8 textureFlip ) { const TextureFlipInfo& flipInfo = GetTexutreFlipInfo(textureFlip); const int ix = flipInfo.idx[0]; const int iy = flipInfo.idx[1]; const math::VEC2 tSz(texSize.width, texSize.height); texCds[VERTEX_LB][ix] = texCds[VERTEX_LT][ix] = flipInfo.coords[VERTEX_LB][ix]; texCds[VERTEX_LB][iy] = texCds[VERTEX_RB][iy] = flipInfo.coords[VERTEX_LB][iy]; texCds[VERTEX_RT][ix] = texCds[VERTEX_RB][ix] = polSize.width / ((flipInfo.coords[VERTEX_RB][ix] - flipInfo.coords[VERTEX_LB][ix]) * tSz[ix]) + flipInfo.coords[VERTEX_LB][ix]; texCds[VERTEX_RT][iy] = texCds[VERTEX_LT][iy] = polSize.height / ((flipInfo.coords[VERTEX_LT][iy] - flipInfo.coords[VERTEX_LB][iy]) * tSz[iy]) + flipInfo.coords[VERTEX_LB][iy]; } void GetRBFrameSize( math::VEC2* pPt, Size* pSize, const math::VEC2& basePt, const Size& winSize, const WindowFrameSize& frameSize ) { *pPt = math::VEC2(basePt.x + frameSize.l, basePt.y - winSize.height + frameSize.b); pSize->width = winSize.width - frameSize.l; pSize->height = frameSize.b; } void GetRBTexCoord( math::VEC2 texCds[], const Size& polSize, const TexSize& texSize, u8 textureFlip ) { const TextureFlipInfo& flipInfo = GetTexutreFlipInfo(textureFlip); const int ix = flipInfo.idx[0]; const int iy = flipInfo.idx[1]; const math::VEC2 tSz(texSize.width, texSize.height); texCds[VERTEX_RB][ix] = texCds[VERTEX_RT][ix] = flipInfo.coords[VERTEX_RB][ix]; texCds[VERTEX_RB][iy] = texCds[VERTEX_LB][iy] = flipInfo.coords[VERTEX_RB][iy]; texCds[VERTEX_LT][ix] = texCds[VERTEX_LB][ix] = polSize.width / ((flipInfo.coords[VERTEX_LB][ix] - flipInfo.coords[VERTEX_RB][ix]) * tSz[ix]) + flipInfo.coords[VERTEX_RB][ix]; texCds[VERTEX_LT][iy] = texCds[VERTEX_RT][iy] = polSize.height / ((flipInfo.coords[VERTEX_RT][iy] - flipInfo.coords[VERTEX_RB][iy]) * tSz[iy]) + flipInfo.coords[VERTEX_RB][iy]; } #ifdef NW_LYT_DMPGL_ENABLED // @brief フレームのテクスチャ座標変換を設定します。 // // @param gres グラフィックスリソースです。 // @param frame フレーム番号です。 // @param flip テクスチャフリップ番号です。 void SetupFrameTransform( const GraphicsResource& gres, WindowFrame frame, TextureFlip flip) { static const u32 frameFlag[WINDOWFRAME_MAX] = { internal::FRAMESPECFLAG_FRAME_LT, // WINDOWFRAME_LT internal::FRAMESPECFLAG_FRAME_RT, // WINDOWFRAME_RT internal::FRAMESPECFLAG_FRAME_LB, // WINDOWFRAME_LG internal::FRAMESPECFLAG_FRAME_RB, // WINDOWFRAME_RB internal::FRAMESPECFLAG_FRAME_LB, // WINDOWFRAME_L internal::FRAMESPECFLAG_FRAME_RT, // WINDOWFRAME_R internal::FRAMESPECFLAG_FRAME_LT, // WINDOWFRAME_T internal::FRAMESPECFLAG_FRAME_RB // WINDOWFRAME_B }; static const u32 flipFlag[TEXTUREFLIP_MAX] = { internal::FRAMESPECFLAG_NORMAL, // TEXTUREFLIP_NONE internal::FRAMESPECFLAG_FLIP_HFLIP, // TEXTUREFLIP_FLIPH internal::FRAMESPECFLAG_FLIP_VFLIP, // TEXTUREFLIP_FLIPV internal::FRAMESPECFLAG_FLIP_R90, // TEXTUREFLIP_ROTATE90 internal::FRAMESPECFLAG_FLIP_R180, // TEXTUREFLIP_ROTATE180 internal::FRAMESPECFLAG_FLIP_R270 // TEXTUREFLIP_ROTATE270 }; GLint loc = gres.GetUniformLocation(gres.UNIFORM_uFrameSpec); u32 flag =frameFlag[frame] | flipFlag[flip]; glUniform4f(loc, (f32)flag, 0, 0, 0); NW_GL_ASSERT(); } #endif // NW_LYT_DMPGL_ENABLED } // nw::lyt::local::{anonymous} } // nw::lyt::local NW_UT_RUNTIME_TYPEINFO_DEFINITION(Window, Window::Base); // 実行時型情報の実体を定義 Window::Frame::~Frame() { if (pMaterial && !pMaterial->IsUserAllocated()) { Layout::DeleteObj(pMaterial); } pMaterial = 0; } Window::Window( u8 contentTexNum, u8 frameTexNum ) { NW_ASSERT(contentTexNum <= TexMapMax); NW_ASSERT(frameTexNum <= TexMapMax); const u8 frameNum = 1; u8 frameTexNums[frameNum]; frameTexNums[WINDOWFRAME_LT] = frameTexNum; InitTexNum(contentTexNum, frameTexNums, frameNum); } Window::Window( u8 contentTexNum, u8 frameLTTexNum, u8 frameRTTexNum, u8 frameRBTexNum, u8 frameLBTexNum ) { NW_ASSERT(contentTexNum <= TexMapMax); NW_ASSERT(frameLTTexNum <= TexMapMax); NW_ASSERT(frameRTTexNum <= TexMapMax); NW_ASSERT(frameRBTexNum <= TexMapMax); NW_ASSERT(frameLBTexNum <= TexMapMax); const u8 frameNum = 4; u8 frameTexNums[frameNum]; frameTexNums[WINDOWFRAME_LT] = frameLTTexNum; frameTexNums[WINDOWFRAME_RT] = frameRTTexNum; frameTexNums[WINDOWFRAME_RB] = frameRBTexNum; frameTexNums[WINDOWFRAME_LB] = frameLBTexNum; InitTexNum(contentTexNum, frameTexNums, frameNum); } Window::Window( u8 contentTexNum, u8 cornerLTTexNum, u8 cornerRTTexNum, u8 cornerRBTexNum, u8 cornerLBTexNum, u8 frameLTexNum, u8 frameTTexNum, u8 frameRTexNum, u8 frameBTexNum ) { NW_ASSERT(contentTexNum <= TexMapMax); NW_ASSERT(cornerLTTexNum <= TexMapMax); NW_ASSERT(cornerRTTexNum <= TexMapMax); NW_ASSERT(cornerRBTexNum <= TexMapMax); NW_ASSERT(cornerLBTexNum <= TexMapMax); NW_ASSERT(frameLTexNum <= TexMapMax); NW_ASSERT(frameTTexNum <= TexMapMax); NW_ASSERT(frameRTexNum <= TexMapMax); NW_ASSERT(frameBTexNum <= TexMapMax); const u8 frameNum = 8; u8 frameTexNums[frameNum]; frameTexNums[WINDOWFRAME_LT] = cornerLTTexNum; frameTexNums[WINDOWFRAME_RT] = cornerRTTexNum; frameTexNums[WINDOWFRAME_RB] = cornerRBTexNum; frameTexNums[WINDOWFRAME_LB] = cornerLBTexNum; frameTexNums[WINDOWFRAME_L ] = frameLTexNum; frameTexNums[WINDOWFRAME_T ] = frameTTexNum; frameTexNums[WINDOWFRAME_R ] = frameRTexNum; frameTexNums[WINDOWFRAME_B ] = frameBTexNum; InitTexNum(contentTexNum, frameTexNums, frameNum); } Window::Window( const res::Window* pBlock, const ResBlockSet& resBlockSet ) : Base(pBlock) { const res::WindowContent *const pResContent = internal::ConvertOffsToPtr(pBlock, pBlock->contentOffset); const u8 texCoordNum = ut::Min(pResContent->texCoordNum, u8(TexMapMax)); InitContent(texCoordNum); m_ContentInflation = pBlock->inflation; NW_NULL_ASSERT(resBlockSet.pMaterialList); const u32 *const matOffsTbl = internal::ConvertOffsToPtr(resBlockSet.pMaterialList, sizeof(*resBlockSet.pMaterialList)); // content // 頂点カラー for (int i = 0; i < VERTEXCOLOR_MAX; ++i) { m_Content.vtxColors[i] = pResContent->vtxCols[i]; } // テクスチャ座標 if (texCoordNum > 0) { if (! m_Content.texCoordAry.IsEmpty()) { m_Content.texCoordAry.Copy( reinterpret_cast(pResContent) + sizeof(*pResContent), texCoordNum); } } // マテリアルの作成 { const res::Material *const pResMaterial = internal::ConvertOffsToPtr(resBlockSet.pMaterialList, matOffsTbl[pResContent->materialIdx]); m_pMaterial = Layout::NewObj(pResMaterial, resBlockSet); } // Frame m_FrameNum = 0; m_Frames = 0; if (pBlock->frameNum > 0) { InitFrame(pBlock->frameNum); const u32 *const frameOffsetTable = internal::ConvertOffsToPtr(pBlock, pBlock->frameOffsetTableOffset); for (int i = 0; i < m_FrameNum; ++i) { const res::WindowFrame *const pResWindowFrame = internal::ConvertOffsToPtr(pBlock, frameOffsetTable[i]); m_Frames[i].textureFlip = pResWindowFrame->textureFlip; // マテリアルの初期化 const res::Material *const pResMaterial = internal::ConvertOffsToPtr(resBlockSet.pMaterialList, matOffsTbl[pResWindowFrame->materialIdx]); m_Frames[i].pMaterial = Layout::NewObj(pResMaterial, resBlockSet); } } } void Window::InitTexNum( u8 contentTexNum, u8 frameTexNums[], u8 frameNum ) { InitContent(contentTexNum); m_ContentInflation.l = 0; m_ContentInflation.r = 0; m_ContentInflation.t = 0; m_ContentInflation.b = 0; // マテリアルの作成 m_pMaterial = Layout::NewObj(); if (m_pMaterial) { m_pMaterial->ReserveMem(contentTexNum, contentTexNum, contentTexNum); } // Frame InitFrame(frameNum); for (int i = 0; i < m_FrameNum; ++i) { // マテリアルの作成 m_Frames[i].pMaterial = Layout::NewObj(); if (m_Frames[i].pMaterial) { m_Frames[i].pMaterial->ReserveMem(frameTexNums[i], frameTexNums[i], frameTexNums[i]); } } } void Window::InitContent(u8 texNum) { if (texNum > 0) { ReserveTexCoord(texNum); } #ifdef NW_LYT_DRAWER_ENABLE m_IsTexCoordInited = false; #endif } void Window::InitFrame(u8 frameNum) { m_FrameNum = 0; m_Frames = Layout::NewArray(frameNum); if (m_Frames) { m_FrameNum = frameNum; } } Window::~Window() { // OSReport("Window::~Window()\n"); Layout::DeleteArray(m_Frames, m_FrameNum); if (m_pMaterial && ! m_pMaterial->IsUserAllocated()) { Layout::DeleteObj(m_pMaterial); m_pMaterial = 0; } m_Content.texCoordAry.Free(); } void Window::ReserveTexCoord(u8 num) { m_Content.texCoordAry.Reserve(num); } u8 Window::GetTexCoordNum() const { return m_Content.texCoordAry.GetSize(); } void Window::SetTexCoordNum(u8 num) { m_Content.texCoordAry.SetSize(num); } void Window::GetTexCoord( u32 idx, TexCoordQuad coords ) const { m_Content.texCoordAry.GetCoord(idx, coords); } void Window::SetTexCoord( u32 idx, const TexCoordQuad coords ) { m_Content.texCoordAry.SetCoord(idx, coords); Material* pMaterial = this->GetContentMaterial(); if (pMaterial != NULL) { pMaterial->SetTextureDirty(); } } Material* Window::FindMaterialByName( const char* findName, bool bRecursive ) { if (m_pMaterial) { if (internal::EqualsMaterialName(m_pMaterial->GetName(), findName)) { return m_pMaterial; } } for (int i = 0; i < m_FrameNum; ++i) { if (internal::EqualsMaterialName(m_Frames[i].pMaterial->GetName(), findName)) { return m_Frames[i].pMaterial; } } if (bRecursive) { // 子供に一致するものが無いか検索 for (PaneList::Iterator it = GetChildList().GetBeginIter(); it != GetChildList().GetEndIter(); ++it) { if (Material* pMat = it->FindMaterialByName(findName, bRecursive)) { return pMat; } } } return 0; } const ut::Color8 Window::GetVtxColor(u32 idx) const { NW_ASSERT(idx < VERTEXCOLOR_MAX); return m_Content.vtxColors[idx]; } void Window::SetVtxColor( u32 idx, ut::Color8 value ) { NW_ASSERT(idx < VERTEXCOLOR_MAX); m_Content.vtxColors[idx] = value; } u8 Window::GetVtxColorElement(u32 idx) const { return internal::GetVtxColorElement(m_Content.vtxColors, idx); } void Window::SetVtxColorElement(u32 idx, u8 value) { internal::SetVtxColorElement(m_Content.vtxColors, idx, value); } #ifdef NW_LYT_DMPGL_ENABLED void Window::DrawSelf(const DrawInfo& drawInfo) { NW_LYT_STOPWATCH_MEASURE(-500, "nw::lyt::Window::DrawSelf"); // 行列 LoadMtx(drawInfo); const WindowFrameSize frameSize = GetFrameSize(m_FrameNum, m_Frames); const math::VEC2 basePt = GetVtxPos(); // contentの描画 DrawContent(drawInfo, basePt, frameSize, GetGlobalAlpha()); // frameの描画 switch (m_FrameNum) { case 1: DrawFrame(drawInfo, basePt, m_Frames[WINDOWFRAME_LT], frameSize, GetGlobalAlpha()); break; case 4: DrawFrame4(drawInfo, basePt, m_Frames, frameSize, GetGlobalAlpha()); break; case 8: DrawFrame8(drawInfo, basePt, m_Frames, frameSize, GetGlobalAlpha()); break; } } void Window::DrawContent( const DrawInfo& drawInfo, const math::VEC2& basePt, const WindowFrameSize& frameSize, u8 alpha ) { m_pMaterial->SetupGraphics(drawInfo, alpha); internal::DrawQuad( drawInfo, math::VEC2(basePt.x + frameSize.l - m_ContentInflation.l, basePt.y - frameSize.t + m_ContentInflation.t), Size(GetSize().width - frameSize.l + m_ContentInflation.l - frameSize.r + m_ContentInflation.r, GetSize().height - frameSize.t + m_ContentInflation.t - frameSize.b + m_ContentInflation.b), m_Content.texCoordAry.GetSize(), m_Content.texCoordAry.GetArray(), m_Content.vtxColors); } void Window::DrawFrame( const DrawInfo& drawInfo, const math::VEC2& basePt, const Frame& frame, const WindowFrameSize& frameSize, u8 alpha ) { NW_LYT_STOPWATCH_MEASURE(-501, "nw::lyt::Window::DrawFrame"); // フレームのテクスチャがない場合は何もしない if (frame.pMaterial->GetTexMapNum() == 0) { return; } frame.pMaterial->SetupGraphics(drawInfo, alpha, false); math::VEC2 polPt; Size polSize; GraphicsResource& gres = *drawInfo.GetGraphicsResource(); local::GetLTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::SetupFrameTransform(gres, WINDOWFRAME_LT, TEXTUREFLIP_NONE); internal::DrawQuad(drawInfo, polPt, polSize); local::GetRTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::SetupFrameTransform(gres, WINDOWFRAME_RT, TEXTUREFLIP_FLIPH); internal::DrawQuad(drawInfo, polPt, polSize); local::GetRBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::SetupFrameTransform(gres, WINDOWFRAME_RB, TEXTUREFLIP_ROTATE180); internal::DrawQuad(drawInfo, polPt, polSize); local::GetLBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::SetupFrameTransform(gres, WINDOWFRAME_LB, TEXTUREFLIP_FLIPV); internal::DrawQuad(drawInfo, polPt, polSize); } void Window::DrawFrame4( const DrawInfo& drawInfo, const math::VEC2& basePt, const Frame* frames, const WindowFrameSize& frameSize, u8 alpha ) { NW_LYT_STOPWATCH_MEASURE(-502, "nw::lyt::Window::DrawFrame4"); math::VEC2 polPt[WINDOWFRAME_RB + 1]; Size polSize[WINDOWFRAME_RB + 1]; bool bRepeat = false; GraphicsResource& gres = *drawInfo.GetGraphicsResource(); local::GetLTFrameSize(&polPt[WINDOWFRAME_LT], &polSize[WINDOWFRAME_LT], basePt, GetSize(), frameSize); local::GetRTFrameSize(&polPt[WINDOWFRAME_RT], &polSize[WINDOWFRAME_RT], basePt, GetSize(), frameSize); local::GetLBFrameSize(&polPt[WINDOWFRAME_LB], &polSize[WINDOWFRAME_LB], basePt, GetSize(), frameSize); local::GetRBFrameSize(&polPt[WINDOWFRAME_RB], &polSize[WINDOWFRAME_RB], basePt, GetSize(), frameSize); for (int i = WINDOWFRAME_LT; i <= WINDOWFRAME_RB; ++i) { const Frame& frame = frames[i]; if (frame.pMaterial && frame.pMaterial->GetTexMapNum() > 0) { frame.pMaterial->SetupGraphics(drawInfo, alpha, false); local::SetupFrameTransform(gres, WindowFrame(i), frame.GetTextureFlip()); if (!bRepeat) { internal::DrawQuad(drawInfo, polPt[i], polSize[i]); bRepeat = true; } else { internal::DrawQuad_Repeat(drawInfo, polPt[i], polSize[i]); } } } } void Window::DrawFrame8( const DrawInfo& drawInfo, const math::VEC2& basePt, const Frame* frames, const WindowFrameSize& frameSize, u8 alpha ) { NW_LYT_STOPWATCH_MEASURE(-503, "nw::lyt::Window::DrawFrame8"); const f32 x0 = basePt.x; const f32 x1 = basePt.x + frameSize.l; const f32 x2 = basePt.x + this->GetSize().width - frameSize.r; const f32 y0 = basePt.y; const f32 y1 = basePt.y - frameSize.t; const f32 y2 = basePt.y - this->GetSize().height + frameSize.b; const f32 w0 = frameSize.l; const f32 w1 = this->GetSize().width - frameSize.l - frameSize.r; const f32 w2 = frameSize.r; const f32 h0 = frameSize.t; const f32 h1 = this->GetSize().height - frameSize.t - frameSize.b; const f32 h2 = frameSize.b; const local::Rect frameRect[WINDOWFRAME_MAX] = { { x0, y0, w0, h0 }, // LT { x2, y0, w2, h0 }, // RT { x0, y2, w0, h2 }, // LB { x2, y2, w2, h2 }, // RB { x0, y1, w0, h1 }, // L { x2, y1, w2, h1 }, // R { x1, y0, w1, h0 }, // T { x1, y2, w1, h2 }, // B }; GraphicsResource& gres = *drawInfo.GetGraphicsResource(); bool bRepeat = false; for (int i = 0; i < WINDOWFRAME_MAX; ++i) { const Frame& frame = frames[i]; if (frame.pMaterial->GetTexMapNum() > 0) // Corner LT { frame.pMaterial->SetupGraphics(drawInfo, alpha, false); local::SetupFrameTransform(gres, WindowFrame(i), frame.GetTextureFlip()); if (!bRepeat) { internal::DrawQuad(drawInfo, frameRect[i].Position(), frameRect[i].Size()); bRepeat = true; } else { internal::DrawQuad_Repeat(drawInfo, frameRect[i].Position(), frameRect[i].Size()); } } } } #endif // NW_LYT_DMPGL_ENABLED const WindowFrameSize Window::GetFrameSize( u8 frameNum, const Window::Frame* frames ) const { WindowFrameSize ret = { 0, 0, 0, 0 }; switch (frameNum) { case 1: { Material* pMaterial = frames[WINDOWFRAME_LT].pMaterial; if (pMaterial != NULL && pMaterial->GetTexMapNum() > 0) { TexSize texSize = pMaterial->GetTexMap(0).GetSize(); ret.l = texSize.width; ret.t = texSize.height; ret.r = texSize.width; ret.b = texSize.height; } } break; case 4: case 8: { Material* pMaterialLT = frames[WINDOWFRAME_LT].pMaterial; if (pMaterialLT != NULL && pMaterialLT->GetTexMapNum() > 0) { ret.t = pMaterialLT->GetTexMap(0).GetHeight(); } Material *pMaterialRT = frames[WINDOWFRAME_RT].pMaterial; if (pMaterialRT != NULL && pMaterialRT->GetTexMapNum() > 0) { ret.r = pMaterialRT->GetTexMap(0).GetWidth(); } Material *pMaterialRB = frames[WINDOWFRAME_RB].pMaterial; if (pMaterialRB != NULL && pMaterialRB->GetTexMapNum() > 0) { ret.b = pMaterialRB->GetTexMap(0).GetHeight(); } Material *pMaterialLB = frames[WINDOWFRAME_LB].pMaterial; if (pMaterialLB != NULL && pMaterialLB->GetTexMapNum() > 0) { ret.l = pMaterialLB->GetTexMap(0).GetWidth(); } } break; } return ret; } u8 Window::GetMaterialNum() const { return u8(1 + m_FrameNum); } Material* Window::GetMaterial(u32 idx) const { NW_WARNING(idx < GetMaterialNum(), "idx >= GetMaterialNum() : %d >= %d", idx, GetMaterialNum()); return idx == 0 ? GetContentMaterial(): GetFrameMaterial(WindowFrame(idx - 1)); } Material* Window::GetFrameMaterial(WindowFrame frameIdx) const { NW_ASSERT(frameIdx < WINDOWFRAME_MAX); if (frameIdx >= m_FrameNum) { return NULL; } return m_Frames[frameIdx].pMaterial; } void Window::SetFrameMaterial(WindowFrame frameIdx, Material* pMaterial) { NW_ASSERT(frameIdx < WINDOWFRAME_MAX); if (m_Frames[frameIdx].pMaterial == pMaterial) { return; } if (m_Frames[frameIdx].pMaterial != NULL && !m_Frames[frameIdx].pMaterial->IsUserAllocated()) { Layout::DeleteObj(m_Frames[frameIdx].pMaterial); } m_Frames[frameIdx].pMaterial = pMaterial; if (pMaterial != NULL) { pMaterial->SetTextureDirty(); } } Material* Window::GetContentMaterial() const { return m_pMaterial; } void Window::SetContentMaterial(Material* pMaterial) { if (m_pMaterial == pMaterial) { return; } if (m_pMaterial != NULL && !m_pMaterial->IsUserAllocated()) { Layout::DeleteObj(m_pMaterial); } m_pMaterial = pMaterial; if (m_pMaterial != NULL) { m_pMaterial->SetTextureDirty(); } } #ifdef NW_LYT_DRAWER_ENABLE //---------------------------------------------------------- // Window void Window::MakeUniformDataSelf( DrawInfo* pDrawInfo, Drawer* pDrawer ) const { #ifdef NW_LYT_DRAWER_DISABLE_DRAW_WINOOW return; #endif // 使わないぽい NW_UNUSED_VARIABLE( pDrawInfo ); const WindowFrameSize frameSize( GetFrameSize(m_FrameNum, m_Frames) ); const math::VEC2 basePt( GetVtxPos() ); { // Contentについての設定 { // TexEnv設定 pDrawer->SetUpTexEnv( m_pMaterial ); } { // テクスチャの設定 pDrawer->SetUpTextures( m_pMaterial ); } { // テクスチャ座標の設定 if ( !m_IsTexCoordInited || m_pMaterial->IsTextureDirty() ) { m_UniformTexCoordNum = pDrawer->CalcTextureCoords( m_pMaterial, m_Content.texCoordAry.GetArray(), m_UniformTexCoords ); m_IsTexCoordInited = true; m_pMaterial->SetTextureDirty( false ); } pDrawer->SetUpTextureCoords( m_UniformTexCoords, m_UniformTexCoordNum ); } { // 頂点座標の計算に必要な情報の設定 pDrawer->SetUpMtx( GetGlobalMtx() ); // TODO: lyt_Windowにキャッシュすることを検討 Size size( GetSize().width - frameSize.l + m_ContentInflation.l - frameSize.r + m_ContentInflation.r, GetSize().height - frameSize.t + m_ContentInflation.t - frameSize.b + m_ContentInflation.b ); nw::math::VEC2 pos( basePt.x + frameSize.l - m_ContentInflation.l, basePt.y - frameSize.t + m_ContentInflation.t ); pDrawer->SetUpQuad( size, pos ); } { // 頂点カラーの設定 pDrawer->SetUpVtxColors( m_Content.vtxColors, GetGlobalAlpha() ); } { // UniformDataの設定終了 pDrawer->SetUniformDataEnd(); } } { // 頂点カラーの設定 ut::Color8 white[ 4 ] = { 0xffffffff,0xffffffff,0xffffffff,0xffffffff }; pDrawer->SetUpVtxColors( white, GetGlobalAlpha() ); } const u8 texCoordNum = 1; int uniformTexCoordNum; nw::math::VEC4 uniformTexCoords[ TexMapMax * 2 ]; Size polSize; math::VEC2 polPt; math::VEC2 texCds[ texCoordNum ][ VERTEX_MAX ]; // Frameについての設定 switch ( m_FrameNum ) { case 1 : { const Frame& frame = m_Frames[ WINDOWFRAME_LT ]; // フレームのテクスチャがない場合は何もしない if ( frame.pMaterial->GetTexMapNum() == 0 ) return; // TexEnv設定 pDrawer->SetUpTexEnv( frame.pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( frame.pMaterial ); const TexSize texSize = frame.pMaterial->GetTexMap(0).GetSize(); local::GetLTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetLTTexCoord( texCds[0], polSize, texSize, TEXTUREFLIP_NONE ); uniformTexCoordNum = pDrawer->CalcTextureCoords( frame.pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); local::GetRTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetRTTexCoord(texCds[0], polSize, texSize, TEXTUREFLIP_FLIPH); uniformTexCoordNum = pDrawer->CalcTextureCoords( frame.pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); local::GetRBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetRBTexCoord(texCds[0], polSize, texSize, TEXTUREFLIP_ROTATE180); uniformTexCoordNum = pDrawer->CalcTextureCoords( frame.pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); local::GetLBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetLBTexCoord(texCds[0], polSize, texSize, TEXTUREFLIP_FLIPV); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( frame.pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } break; case 4 : { const Frame* pFrame = &m_Frames[ WINDOWFRAME_LT ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); local::GetLTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetLTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_RT ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); local::GetRTFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetRTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_RB ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); local::GetRBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetRBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_LB ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); local::GetLBFrameSize(&polPt, &polSize, basePt, GetSize(), frameSize); local::GetLBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } } break; case 8 : { const Frame* pFrame = &m_Frames[ WINDOWFRAME_LT ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.l, frameSize.t); polPt = basePt; local::GetLTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_T ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(GetSize().width - frameSize.l - frameSize.r, frameSize.t); polPt = math::VEC2(basePt.x + frameSize.l, basePt.y); local::GetLTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_RT ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.r, frameSize.t); polPt = math::VEC2(basePt.x + GetSize().width - frameSize.r, basePt.y); local::GetRTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_R ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.r, GetSize().height - frameSize.t - frameSize.b); polPt = math::VEC2(basePt.x + GetSize().width - frameSize.r, basePt.y - frameSize.t); local::GetRTTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_RB ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.r, frameSize.b); polPt = math::VEC2(basePt.x + GetSize().width - frameSize.r, basePt.y - GetSize().height + frameSize.b); local::GetRBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_B ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(GetSize().width - frameSize.l - frameSize.r, frameSize.b); polPt = math::VEC2(basePt.x + frameSize.l, basePt.y - GetSize().height + frameSize.b); local::GetRBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_LB ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.l, frameSize.b); polPt = math::VEC2(basePt.x, basePt.y - GetSize().height + frameSize.b); local::GetLBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } pFrame = &m_Frames[ WINDOWFRAME_L ]; if ( pFrame->pMaterial->GetTexMapNum() != 0 ) { // TexEnv設定 pDrawer->SetUpTexEnv( pFrame->pMaterial ); // テクスチャの設定 pDrawer->SetUpTextures( pFrame->pMaterial ); polSize = Size(frameSize.l, GetSize().height - frameSize.t - frameSize.b); polPt = math::VEC2(basePt.x, basePt.y - frameSize.t); local::GetLBTexCoord(texCds[0], polSize, pFrame->pMaterial->GetTexMap(0).GetSize(), pFrame->textureFlip); // TODO: uniformTexCoordsをキャッシュしたい uniformTexCoordNum = pDrawer->CalcTextureCoords( pFrame->pMaterial, texCds, uniformTexCoords ); pDrawer->SetUpTextureCoords( uniformTexCoords, uniformTexCoordNum ); pDrawer->SetUpQuad( polSize, polPt ); pDrawer->SetUniformDataEnd(); } } break; } // 同じテクスチャを使用するWindowとPictureの描画で、フレームの // 描画位置がおかしくなる不具合への対処 pDrawer->FlushBuffer(); } #endif } // namespace nw::lyt } // namespace nw