diff options
| author | skidau <skidau@gmail.com> | 2014-10-13 15:57:11 +1100 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2014-10-13 15:57:11 +1100 |
| commit | 9551650c42d8e256043a5783ba3b7b3aa18e350d (patch) | |
| tree | f30a28dd869b18a02b01e6b5a59d2ecb07fe9a04 /Source/Core/VideoCommon/BoundingBox.cpp | |
| parent | 01f1768c5560bae74f5a3f527a591b17bf60a9cf (diff) | |
| parent | 1e3b9ecdc143ec9a45fb6a4df3f26578e88ec371 (diff) | |
Merge pull request #1095 from crudelios/sw-bbox
Reimplement Bounding Box calculation using the software renderer.
Diffstat (limited to 'Source/Core/VideoCommon/BoundingBox.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/BoundingBox.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/BoundingBox.cpp b/Source/Core/VideoCommon/BoundingBox.cpp new file mode 100644 index 0000000000..6a4af2aca6 --- /dev/null +++ b/Source/Core/VideoCommon/BoundingBox.cpp @@ -0,0 +1,150 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + + +#include "VideoBackends/Software/Clipper.h" +#include "VideoBackends/Software/Rasterizer.h" +#include "VideoBackends/Software/SetupUnit.h" +#include "VideoBackends/Software/TransformUnit.h" +#include "VideoCommon/BoundingBox.h" +#include "VideoCommon/PixelShaderManager.h" + + +namespace BoundingBox +{ + +// External vars +bool active = false; +u16 coords[4] = { 0x80, 0xA0, 0x80, 0xA0 }; +u8 posMtxIdx; +u8 texMtxIdx[8]; + + +// Internal vars +SetupUnit vtxUnit; +VAT myVat; +u8 * bufferPos; +TVtxDesc vertexDesc; +PortableVertexDeclaration vertexDecl; + +// Gets the pointer to the current buffer position +void LOADERDECL SetVertexBufferPosition() +{ + bufferPos = VertexManager::s_pCurBufferPointer; +} + +// Prepares the bounding box for new primitive data +void Prepare(const VAT & vat, int primitive, const TVtxDesc & vtxDesc, const PortableVertexDeclaration & vtxDecl) +{ + if (!active) + return; + + myVat = vat; + vertexDesc = vtxDesc; + vertexDecl = vtxDecl; + + vtxUnit.Init(primitive); + + // Initialize the SW renderer + static bool SWinit = false; + + if (!SWinit) + { + Clipper::Init(); + Rasterizer::Init(); + SWinit = true; + } + + // Update SW renderer values + Clipper::SetViewOffset(); + Rasterizer::SetScissor(); + + for (u8 i = 0; i < 4; ++i) + { + Rasterizer::SetTevReg(i, 0, true, (s16)PixelShaderManager::constants.kcolors[i][0]); + Rasterizer::SetTevReg(i, 1, true, (s16)PixelShaderManager::constants.kcolors[i][1]); + Rasterizer::SetTevReg(i, 2, true, (s16)PixelShaderManager::constants.kcolors[i][2]); + Rasterizer::SetTevReg(i, 3, true, (s16)PixelShaderManager::constants.kcolors[i][3]); + + Rasterizer::SetTevReg(i, 0, false, (s16)PixelShaderManager::constants.colors[i][0]); + Rasterizer::SetTevReg(i, 1, false, (s16)PixelShaderManager::constants.colors[i][1]); + Rasterizer::SetTevReg(i, 2, false, (s16)PixelShaderManager::constants.colors[i][2]); + Rasterizer::SetTevReg(i, 3, false, (s16)PixelShaderManager::constants.colors[i][3]); + } +} + +// Updates the bounding box +void LOADERDECL Update() +{ + if (!active) + return; + + // Grab vertex input data and transform to output vertex + InputVertexData myVertex; + OutputVertexData * outVertex = vtxUnit.GetVertex(); + + // Feed vertex position and matrix + myVertex.position = Vec3((const float *)bufferPos); + myVertex.posMtx = vertexDesc.PosMatIdx ? posMtxIdx : g_main_cp_state.matrix_index_a.PosNormalMtxIdx; + + // Transform position + TransformUnit::TransformPosition(&myVertex, outVertex); + + if (g_main_cp_state.vtx_desc.Normal != NOT_PRESENT) + { + // Feed normal input data and transform + memcpy((u8 *)myVertex.normal, bufferPos + vertexDecl.normals[0].offset, sizeof(float) * 3 * ((myVat.g0.NormalElements) ? 3 : 1)); + + TransformUnit::TransformNormal(&myVertex, myVat.g0.NormalElements, outVertex); + } + + // Feed color input data + for (int i = 0; i < 2; ++i) + { + if (vertexDecl.colors[i].enable) + { + u32 color; + memcpy((u8 *)&color, bufferPos + vertexDecl.colors[i].offset, sizeof(u32)); + *(u32*)myVertex.color[i] = Common::swap32(color); + } + } + + // Transform color + TransformUnit::TransformColor(&myVertex, outVertex); + + // Feed texture matrices + int idx = 0; + + myVertex.texMtx[0] = (vertexDesc.Tex0MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_a.Tex0MtxIdx; + myVertex.texMtx[1] = (vertexDesc.Tex1MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_a.Tex1MtxIdx; + myVertex.texMtx[2] = (vertexDesc.Tex2MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_a.Tex2MtxIdx; + myVertex.texMtx[3] = (vertexDesc.Tex3MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_a.Tex3MtxIdx; + myVertex.texMtx[4] = (vertexDesc.Tex4MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_b.Tex4MtxIdx; + myVertex.texMtx[5] = (vertexDesc.Tex5MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_b.Tex5MtxIdx; + myVertex.texMtx[6] = (vertexDesc.Tex6MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_b.Tex6MtxIdx; + myVertex.texMtx[7] = (vertexDesc.Tex7MatIdx) ? texMtxIdx[idx++] : g_main_cp_state.matrix_index_b.Tex7MtxIdx; + + // Feed texture coordinate data + for (int i = 0; i < 8; ++i) + { + if (vertexDecl.texcoords[i].enable) + memcpy((u8 *)&myVertex.texCoords[i], bufferPos + vertexDecl.texcoords[i].offset, sizeof(float) * 2); + } + + // Transform texture coordinate + TransformUnit::TransformTexCoord(&myVertex, outVertex, false); + + // Render the vertex in SW to calculate bbox + vtxUnit.SetupVertex(); +} + +// Save state +void DoState(PointerWrap &p) +{ + p.Do(active); + p.Do(coords); +} + +} // namespace BoundingBox |
