| 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);
- MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(4, 6, vertexDesc);
- auto vecIter = meshData->getVec3DataIter(VES_POSITION);
- vecIter.setValue(Vector3(-1.0f, 1.0, 0));
- vecIter.setValue(Vector3(1.0f, 1.0f, 0));
- vecIter.setValue(Vector3(-1.0f, -1.0f, 0));
- vecIter.setValue(Vector3(1.0f, -1.0f, 0));
- auto uvIter = meshData->getVec2DataIter(VES_TEXCOORD);
- uvIter.setValue(Vector2(0.0f, 0.0));
- uvIter.setValue(Vector2(1.0f, 0.0f));
- uvIter.setValue(Vector2(0.0f, 1.0f));
- uvIter.setValue(Vector2(1.0f, 1.0f));
- auto indices = meshData->getIndices32();
- indices[0] = 0;
- indices[1] = 1;
- indices[2] = 2;
- indices[3] = 1;
- indices[4] = 3;
- indices[5] = 2;
- mFullScreenQuadMesh = MeshCore::create(meshData);
- }
- 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)
- {
- // 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.width, 0.0f);
- Vector2 uvs[4];
- // TODO - Set UVs
- 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();
- }
- SPtr<VertexBufferCore> vb = mFullScreenQuadMesh->getVertexData()->getBuffer(0);
- vb->writeData(0, sizeof(vertices), vertices, BufferWriteType::Discard);
- draw(mFullScreenQuadMesh, mFullScreenQuadMesh->getProperties().getSubMesh());
- }
- RendererUtility& gRendererUtility()
- {
- return RendererUtility::instance();
- }
- }
|