| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- #include "BsRendererUtility.h"
- #include "BsRenderAPI.h"
- #include "BsMesh.h"
- #include "BsVertexDataDesc.h"
- #include "BsMaterial.h"
- #include "BsPass.h"
- #include "BsBlendState.h"
- #include "BsDepthStencilState.h"
- #include "BsRasterizerState.h"
- namespace BansheeEngine
- {
- RendererUtility::RendererUtility()
- {
- VertexDataDescPtr vertexDesc = bs_shared_ptr_new<VertexDataDesc>();
- vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION);
- vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD);
- mFullScreenQuadMesh = MeshCore::create(4, 6, vertexDesc);
- }
- RendererUtility::~RendererUtility()
- {
-
- }
- void RendererUtility::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
- {
- RenderAPICore& rs = RenderAPICore::instance();
- SPtr<PassCore> pass = material->getPass(passIdx);
- SPtr<PassParametersCore> passParams = material->getPassParameters(passIdx);
- struct StageData
- {
- GpuProgramType type;
- bool enable;
- SPtr<GpuParamsCore> params;
- SPtr<GpuProgramCore> program;
- };
- const UINT32 numStages = 6;
- StageData stages[numStages] =
- {
- {
- GPT_VERTEX_PROGRAM, pass->hasVertexProgram(),
- passParams->mVertParams, pass->getVertexProgram()
- },
- {
- GPT_FRAGMENT_PROGRAM, pass->hasFragmentProgram(),
- passParams->mFragParams, pass->getFragmentProgram()
- },
- {
- GPT_GEOMETRY_PROGRAM, pass->hasGeometryProgram(),
- passParams->mGeomParams, pass->getGeometryProgram()
- },
- {
- GPT_HULL_PROGRAM, pass->hasHullProgram(),
- passParams->mHullParams, pass->getHullProgram()
- },
- {
- GPT_DOMAIN_PROGRAM, pass->hasDomainProgram(),
- passParams->mDomainParams, pass->getDomainProgram()
- },
- {
- GPT_COMPUTE_PROGRAM, pass->hasComputeProgram(),
- passParams->mComputeParams, pass->getComputeProgram()
- }
- };
- for (UINT32 i = 0; i < numStages; i++)
- {
- const StageData& stage = stages[i];
- if (stage.enable)
- {
- rs.bindGpuProgram(stage.program);
- rs.setGpuParams(stage.type, stage.params);
- }
- else
- rs.unbindGpuProgram(stage.type);
- }
- // Set up non-texture related pass settings
- if (pass->getBlendState() != nullptr)
- rs.setBlendState(pass->getBlendState());
- else
- rs.setBlendState(BlendStateCore::getDefault());
- if (pass->getDepthStencilState() != nullptr)
- rs.setDepthStencilState(pass->getDepthStencilState(), pass->getStencilRefValue());
- else
- rs.setDepthStencilState(DepthStencilStateCore::getDefault(), pass->getStencilRefValue());
- if (pass->getRasterizerState() != nullptr)
- rs.setRasterizerState(pass->getRasterizerState());
- else
- rs.setRasterizerState(RasterizerStateCore::getDefault());
- }
- void RendererUtility::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh)
- {
- RenderAPICore& rs = RenderAPICore::instance();
- const MeshProperties& meshProps = mesh->getProperties();
- std::shared_ptr<VertexData> vertexData = mesh->getVertexData();
- rs.setVertexDeclaration(vertexData->vertexDeclaration);
- auto& vertexBuffers = vertexData->getBuffers();
- if (vertexBuffers.size() > 0)
- {
- SPtr<VertexBufferCore> buffers[MAX_BOUND_VERTEX_BUFFERS];
- UINT32 endSlot = 0;
- UINT32 startSlot = MAX_BOUND_VERTEX_BUFFERS;
- for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
- {
- if (iter->first >= MAX_BOUND_VERTEX_BUFFERS)
- BS_EXCEPT(InvalidParametersException, "Buffer index out of range");
- startSlot = std::min(iter->first, startSlot);
- endSlot = std::max(iter->first, endSlot);
- }
- for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
- {
- buffers[iter->first - startSlot] = iter->second;
- }
- rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
- }
- rs.setDrawOperation(subMesh.drawOp);
- SPtr<IndexBufferCore> indexBuffer = mesh->getIndexBuffer();
- UINT32 indexCount = subMesh.indexCount;
- rs.setIndexBuffer(indexBuffer);
- rs.drawIndexed(subMesh.indexOffset + mesh->getIndexOffset(), indexCount, mesh->getVertexOffset(), vertexData->vertexCount);
- mesh->_notifyUsedOnGPU();
- }
- void RendererUtility::drawScreenQuad(const ViewportCore& viewport, const Rect2& uv, const Vector2I& textureSize)
- {
- // Note: Consider drawing the quad using a single large triangle for possibly better performance
- Rect2I viewArea = viewport.getArea();
- Vector3 vertices[4];
- vertices[0] = Vector3((float)viewArea.x, (float)viewArea.y, 0.0f);
- vertices[1] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y, 0.0f);
- vertices[2] = Vector3((float)viewArea.x, (float)viewArea.y + (float)viewArea.height, 0.0f);
- vertices[3] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y + (float)viewArea.height, 0.0f);
- Vector2 uvs[4];
- uvs[0] = Vector2(uv.x, uv.y);
- uvs[1] = Vector2(uv.x + uv.width, uv.y);
- uvs[2] = Vector2(uv.x, uv.y + uv.height);
- uvs[3] = Vector2(uv.x + uv.width, uv.y + uv.height);
- auto targetProps = viewport.getTarget()->getProperties();;
- RenderAPICore& rapi = RenderAPICore::instance();
- for (int i = 0; i < 4; i++)
- {
- vertices[i].x = -1.0f + 2.0f * (vertices[i].x + rapi.getHorizontalTexelOffset()) / targetProps.getWidth();
- vertices[i].y = 1.0f - 2.0f * (vertices[i].y + rapi.getVerticalTexelOffset()) / targetProps.getHeight();
- uvs[i].x /= (float)textureSize.x;
- uvs[i].y /= (float)textureSize.y;
- }
- SPtr<VertexDataDesc> vertexDesc = mFullScreenQuadMesh->getVertexDesc();
- MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
- auto vecIter = meshData->getVec3DataIter(VES_POSITION);
- for (UINT32 i = 0; i < 4; i++)
- vecIter.addValue(vertices[i]);
- auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
- for (UINT32 i = 0; i < 4; i++)
- uvIter.addValue(uvs[i]);
- auto indices = meshData->getIndices32();
- indices[0] = 0;
- indices[1] = 1;
- indices[2] = 2;
- indices[3] = 1;
- indices[4] = 3;
- indices[5] = 2;
- mFullScreenQuadMesh->writeSubresource(0, *meshData, true, false);
- draw(mFullScreenQuadMesh, mFullScreenQuadMesh->getProperties().getSubMesh());
- }
- RendererUtility& gRendererUtility()
- {
- return RendererUtility::instance();
- }
- }
|