Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Batcher.h
- #pragma once
- #include "glew.h"
- #include "Shader.h"
- #include "VertexArray.h"
- /*
- Stores basic information about an batch.
- */
- struct SBatchItem
- {
- // Stores the draw primitive to use.
- GLenum m_Primitive;
- /*
- Every child struct should implement it's own compartion method,
- as this defines if a new item fits an existing batch or if it
- needs a new one.
- */
- bool operator ==(SBatchItem other)
- {
- return m_Primitive == other.m_Primitive;
- }
- };
- /*
- Base class for batcher classes that batch a bunch
- of draw calls to one or more draw calls.
- */
- template<typename T> class CBatcher
- {
- public:
- CBatcher();
- ~CBatcher();
- // Prepares the batcher for batching.
- void BeginBatch();
- // Ends the batching process. This will automatically call RenderBatch() on all batches.
- void EndBatch();
- // Renders the batch with the given key (batch set description).
- void RenderBatch(T batchKey);
- protected:
- // Called before rendering happens, allows shader manipulation etc.
- virtual void PreRender(CVertexArray* vertexArray, T batchSet);
- // Called after rendering happens, allows unbinding data etc.
- virtual void PostRender(CVertexArray* vertexArray, T batchSet);
- // Adds an item to the batch.
- virtual T AddBatchItem(CVertex* vertices[], size_t vertexCount, T batchItemDescription, bool connectorVertices = true, bool disableBatch = false);
- private:
- // Creates a new pair to m_BatchData with the vertices given.
- void CreateNewBatchSet(CVertex* vertices[], size_t vertexCount, T batchItemDescription);
- // Stores the batch data.
- std::map<T, CVertexArray*> m_BatchData;
- };
- #include "BatcherDef.h"
- // BatcherDef.h
- template<typename T> CBatcher<T>::CBatcher()
- {
- }
- template<typename T> CBatcher<T>::~CBatcher()
- {
- for (auto pair : m_BatchData)
- {
- // TODO: This doesn't work on non-pointers either.
- delete pair.first;
- delete pair.second;
- }
- m_BatchData.clear();
- }
- /*
- Prepares the batch for batching.
- */
- template<typename T> void CBatcher<T>::BeginBatch()
- {
- }
- /*
- Ends the batching process. This will actually render the batch data.
- */
- template<typename T> void CBatcher<T>::EndBatch()
- {
- // Loops over the different batches.
- for (auto batchItem : m_BatchData)
- {
- RenderBatch(batchItem.first);
- }
- }
- /*
- Renders the batch with the given key.
- */
- template<typename T> void CBatcher<T>::RenderBatch(T batchKey)
- {
- CVertexArray* batchArray = m_BatchData[batchKey];
- if (batchArray->GetVertexData().size() == 0) return;
- // Updates the batch data; passes the vertex data to GPU.
- batchArray->UpdateVertexData();
- // Prepares the rendering.
- PreRender(batchArray, batchKey);
- // Renders the vertex array.
- batchArray->BindVertexArray();
- batchArray->DrawVertexArray(batchKey->m_Primitive);
- batchArray->UnBindVertexArray();
- // Finishes the rendering.
- PostRender(batchArray, batchKey);
- // Clears the vertex array.
- batchArray->ClearVertexArray();
- }
- /*
- Called before rendering happens, allows shader manipulation etc.
- */
- template<typename T> void CBatcher<T>::PreRender(CVertexArray* vertexArray, T batchSet)
- {
- }
- /*
- Called after rendering happens, allows unbinding data etc.
- */
- template<typename T> void CBatcher<T>::PostRender(CVertexArray* vertexArray, T batchSet)
- {
- }
- /*
- Adds an item to the batch.
- */
- template<typename T> T CBatcher<T>::AddBatchItem(CVertex* vertices[], size_t vertexCount, T batchItemDescription, bool connectorVertices, bool disableBatch)
- {
- // Checks if there is nothing in the batch, and it needs a new batch data set.
- if (m_BatchData.size() == 0 || disableBatch)
- {
- CreateNewBatchSet(vertices, vertexCount, batchItemDescription);
- }
- // There is already batch sets available, check if they meet the requirements.
- else
- {
- bool batchFound = false;
- // Checks if there is a batch that matches the data.
- for (auto item : m_BatchData)
- {
- // TODO: Doesn't work on non-pointer data. Doesn't probably need though.
- if (*item.first == *batchItemDescription)
- {
- batchFound = true;
- // Gets the vertex array of the set.
- CVertexArray* batchArray = item.second;
- // Adds connector vertices between the batch items.
- std::vector<CVertex*>& vertexData = batchArray->GetVertexData();
- if (vertexData.size() > 0 && connectorVertices)
- {
- batchArray->AddVertex(new CVertex(vertexData[vertexData.size() - 1]));
- batchArray->AddVertex(new CVertex(vertices[0]));
- }
- // Adds the vertices to the batch array.
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- batchArray->AddVertex(vertices[i]);
- }
- delete batchItemDescription;
- batchItemDescription = item.first;
- break;
- }
- }
- // A batch wasn't found, a new one needs to be created.
- if (!batchFound)
- {
- CreateNewBatchSet(vertices, vertexCount, batchItemDescription);
- }
- }
- return batchItemDescription;
- }
- /*
- Creates a new pair to m_BatchData with the vertices given.
- */
- template<typename T> void CBatcher<T>::CreateNewBatchSet(CVertex* vertices[], size_t vertexCount, T batchItemDescription)
- {
- // Creates a new vertex array.
- CVertexArray* batchArray = new CVertexArray();
- // Passes the vertices to the vertex array.
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- batchArray->AddVertex(vertices[i]);
- }
- // Adds the set to the batch data.
- m_BatchData[batchItemDescription] = batchArray;
- }
- // cpp files, a hack like this is needed. This file is then included
- // in Batcher.h to move the definitions in that file.
- template<typename T> CBatcher<T>::CBatcher()
- {
- }
- template<typename T> CBatcher<T>::~CBatcher()
- {
- for (auto pair : m_BatchData)
- {
- // TODO: This doesn't work on non-pointers either.
- delete pair.first;
- delete pair.second;
- }
- m_BatchData.clear();
- }
- /*
- Prepares the batch for batching.
- */
- template<typename T> void CBatcher<T>::BeginBatch()
- {
- }
- /*
- Ends the batching process. This will actually render the batch data.
- */
- template<typename T> void CBatcher<T>::EndBatch()
- {
- // Loops over the different batches.
- for (auto batchItem : m_BatchData)
- {
- RenderBatch(batchItem.first);
- }
- }
- /*
- Renders the batch with the given key.
- */
- template<typename T> void CBatcher<T>::RenderBatch(T batchKey)
- {
- CVertexArray* batchArray = m_BatchData[batchKey];
- if (batchArray->GetVertexData().size() == 0) return;
- // Updates the batch data; passes the vertex data to GPU.
- batchArray->UpdateVertexData();
- // Prepares the rendering.
- PreRender(batchArray, batchKey);
- // Renders the vertex array.
- batchArray->BindVertexArray();
- batchArray->DrawVertexArray(batchKey->m_Primitive);
- batchArray->UnBindVertexArray();
- // Finishes the rendering.
- PostRender(batchArray, batchKey);
- // Clears the vertex array.
- batchArray->ClearVertexArray();
- }
- /*
- Called before rendering happens, allows shader manipulation etc.
- */
- template<typename T> void CBatcher<T>::PreRender(CVertexArray* vertexArray, T batchSet)
- {
- }
- /*
- Called after rendering happens, allows unbinding data etc.
- */
- template<typename T> void CBatcher<T>::PostRender(CVertexArray* vertexArray, T batchSet)
- {
- }
- /*
- Adds an item to the batch.
- */
- template<typename T> T CBatcher<T>::AddBatchItem(CVertex* vertices[], size_t vertexCount, T batchItemDescription, bool connectorVertices, bool disableBatch)
- {
- // Checks if there is nothing in the batch, and it needs a new batch data set.
- if (m_BatchData.size() == 0 || disableBatch)
- {
- CreateNewBatchSet(vertices, vertexCount, batchItemDescription);
- }
- // There is already batch sets available, check if they meet the requirements.
- else
- {
- bool batchFound = false;
- // Checks if there is a batch that matches the data.
- for (auto item : m_BatchData)
- {
- // TODO: Doesn't work on non-pointer data. Doesn't probably need though.
- if (*item.first == *batchItemDescription)
- {
- batchFound = true;
- // Gets the vertex array of the set.
- CVertexArray* batchArray = item.second;
- // Adds connector vertices between the batch items.
- std::vector<CVertex*>& vertexData = batchArray->GetVertexData();
- if (vertexData.size() > 0 && connectorVertices)
- {
- batchArray->AddVertex(new CVertex(vertexData[vertexData.size() - 1]));
- batchArray->AddVertex(new CVertex(vertices[0]));
- }
- // Adds the vertices to the batch array.
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- batchArray->AddVertex(vertices[i]);
- }
- delete batchItemDescription;
- batchItemDescription = item.first;
- break;
- }
- }
- // A batch wasn't found, a new one needs to be created.
- if (!batchFound)
- {
- CreateNewBatchSet(vertices, vertexCount, batchItemDescription);
- }
- }
- return batchItemDescription;
- }
- /*
- Creates a new pair to m_BatchData with the vertices given.
- */
- template<typename T> void CBatcher<T>::CreateNewBatchSet(CVertex* vertices[], size_t vertexCount, T batchItemDescription)
- {
- // Creates a new vertex array.
- CVertexArray* batchArray = new CVertexArray();
- // Passes the vertices to the vertex array.
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- batchArray->AddVertex(vertices[i]);
- }
- // Adds the set to the batch data.
- m_BatchData[batchItemDescription] = batchArray;
- }
- // SpriteBatcher.h
- #pragma once
- #include "glew.h"
- #include "Batcher.h"
- #include "Color.h"
- #include "Vector2.h"
- #include "Shader.h"
- #include "Vertex.h"
- #include "VertexArray.h"
- #include <vector>
- /*
- Stores information about the batched sprites, used for
- determing if a sprite fits into an existing batch or
- if it needs a new one.
- */
- struct SBatchItemSprite : public SBatchItem
- {
- // Stores the main texture of the sprite.
- CTexture* m_SpriteTexture;
- // Stores the normal map of the sprite.
- CTexture* m_NormalTexture;
- /*
- Implements equals checking.
- */
- bool operator==(SBatchItemSprite other)
- {
- return other.m_SpriteTexture == m_SpriteTexture && other.m_NormalTexture == m_NormalTexture && other.m_Primitive == m_Primitive;
- }
- };
- /*
- Batching for sprites that can be rendered in one (or more depending on
- the texture usage) render call.
- */
- class CSpriteBatcher : public CBatcher<SBatchItemSprite*>
- {
- public:
- CSpriteBatcher();
- ~CSpriteBatcher();
- // Adds a sprite to the batch.
- SBatchItemSprite* RenderSprite(CVertex* vertices[], size_t vertexCount, GLenum mode, CTexture* spriteTexture, CTexture* normalTexture);
- protected:
- // Called before rendering happens, allows shader manipulation etc.
- void PreRender(CVertexArray* vertexArray, SBatchItemSprite* batchSet);
- // Called after rendering happens, allows unbinding data etc.
- void PostRender(CVertexArray* vertexArray, SBatchItemSprite* batchSet);
- private:
- // Stores the sprite shader.
- CShader* m_SpriteShader;
- };
- // SpriteBatcher.cpp
- #include "SpriteBatcher.h"
- #include "Renderer.h"
- CSpriteBatcher::CSpriteBatcher() : CBatcher<SBatchItemSprite*>()
- {
- m_SpriteShader = new CShader("Resource/SpriteShader");
- SGameWindowViewport* viewPort = CGameWindow::GetWindowViewport();
- m_SpriteShader->SetUniform("u_Projection", TMatrix4::OrthoProjection(0.0f, 0.0f, (float)viewPort->H, (float)viewPort->W));
- }
- CSpriteBatcher::~CSpriteBatcher()
- {
- }
- /*
- Called before rendering happens, allows shader manipulation etc.
- */
- void CSpriteBatcher::PreRender(CVertexArray* vertexArray, SBatchItemSprite* batchSet)
- {
- // Binds the shader.
- m_SpriteShader->SetUniform("u_Texture", batchSet->m_SpriteTexture);
- m_SpriteShader->SetUniform("u_NormalTexture", batchSet->m_NormalTexture);
- m_SpriteShader->SetUniform("u_LightPos", TVector2(1.0f, 1.0f));
- m_SpriteShader->SetUniform("u_ResolutionScale", CRenderer::GetResolutionScale());
- m_SpriteShader->BindShader();
- }
- /*
- Called after rendering happens, allows unbinding data etc.
- */
- void CSpriteBatcher::PostRender(CVertexArray* vertexArray, SBatchItemSprite* batchSet)
- {
- glUseProgram(0);
- }
- /*
- Renders a box (adds it to the batch).
- */
- SBatchItemSprite* CSpriteBatcher::RenderSprite(CVertex* vertices[], size_t vertexCount, GLenum mode, CTexture* spriteTexture, CTexture* normalTexture)
- {
- // Creates the item description for the batch item.
- SBatchItemSprite* itemDescription = new SBatchItemSprite();
- itemDescription->m_SpriteTexture = spriteTexture;
- itemDescription->m_NormalTexture = normalTexture;
- itemDescription->m_Primitive = mode;
- /*
- for (unsigned int i = 0; i < vertexCount; i++)
- {
- TVector2 position = vertices[i]->GetVertexPosition(); position.Z = -9.0f;
- vertices[i]->SetVertexPosition(position);
- }
- */
- // Adds the item.
- return AddBatchItem(vertices, vertexCount, itemDescription);
- }
Advertisement
Add Comment
Please, Sign In to add comment