SHARE
TWEET

SB.cpp

Dekowta Sep 20th, 2012 204 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "MLSpriteBatch.h"
  2.  
  3. using MLRenderer::MLSpriteBatch;
  4.  
  5.  
  6. MLSpriteBatch::MLSpriteBatch(int buffersize) : m_BufferSize(buffersize), m_spriteSize((sizeof(MLBatchItem::Vertex) * 4))
  7. {
  8.         m_shader = new MLShader();
  9.         //load the default sprite batch shaders
  10.         m_shader->LoadShaderFile("shaders/SBatch.vert", GL_VERTEX_SHADER);
  11.         m_shader->LoadShaderFile("shaders/SBatch.frag", GL_FRAGMENT_SHADER);
  12.         //lock the shader in place to add the attributes and link
  13.         m_shader->lock();
  14.         {
  15.                 m_shader->bindAtt(MLRenderer::ML_ATT_VERTEXPOS, "VertexPosition");
  16.                 m_shader->bindAtt(MLRenderer::ML_ATT_TEXTURE0"TextureCoord");
  17.                 m_shader->LinkShaders();
  18.         }
  19.         m_shader->unlock(); //unlock the shader
  20.         m_beginCall = false;
  21.         MLError::ErrorHandler::ML_Printf(ML_SpriteBatch, "Creating batch with max %i sprites\n", ML_MAX_SPRITES);
  22.  
  23.         //initalise the batcher
  24.         Initalise();
  25.  
  26.         MLError::ErrorHandler::ML_Printf(ML_SpriteBatch, "Created Sprite Batch\n");
  27. }
  28.  
  29.  
  30. MLSpriteBatch::MLSpriteBatch(MLShader* inShader, int buffersize) : m_shader(inShader), m_BufferSize(buffersize), m_spriteSize((sizeof(MLBatchItem::Vertex) * 4))
  31. {
  32.         m_beginCall = false;
  33.         Initalise();
  34. }
  35.  
  36. MLSpriteBatch::~MLSpriteBatch(void)
  37. {
  38.         Release(this);
  39. }
  40.  
  41. void MLSpriteBatch::release()
  42. {
  43.  
  44. }
  45.  
  46. void MLSpriteBatch::releaseShader()
  47. {
  48.         if (m_shader)
  49.                 delete m_shader;
  50. }
  51.  
  52. void MLSpriteBatch::Initalise()
  53. {
  54.  
  55.         m_BufferOffset = 0;
  56.  
  57.         glGenBuffers(1, &m_VertBuffer);
  58.  
  59.         glBindBuffer(GL_ARRAY_BUFFER, m_VertBuffer);
  60.         glBufferData(GL_ARRAY_BUFFER, m_BufferSize, NULL,  GL_STREAM_DRAW);
  61.  
  62.         //enable the vertex attributes for the VAO in this case vertex pos and texture are needed
  63.         glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_VERTEXPOS);  // Vertex position
  64.         glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_TEXTURE0); //vertex texture coord
  65.  
  66.         //set the vertex attribute pointers
  67.         glBindBuffer(GL_ARRAY_BUFFER, m_VertBuffer);
  68.         glVertexAttribPointer(MLRenderer::ML_ATT_VERTEXPOS, 3, GL_FLOAT, GL_FALSE, sizeof(MLBatchItem::Vertex), (GLubyte *)NULL );
  69.        
  70.         //glBindBuffer(GL_ARRAY_BUFFER, m_UVBuffer);
  71.         glVertexAttribPointer(MLRenderer::ML_ATT_TEXTURE0, 2, GL_FLOAT, GL_FALSE, sizeof(MLBatchItem::Vertex), (GLubyte*)sizeof(Vector3f));
  72.        
  73.         //unbind buffers
  74.         //glBindVertexArray(0);
  75.         glBindBuffer(GL_ARRAY_BUFFER, 0);
  76.        
  77.         //set the total sprite count to 0
  78.         totalSpriteCount = 0;
  79.  
  80. }
  81.  
  82. void MLSpriteBatch::setShader(MLShader* inShader)
  83. {
  84.         m_shader = inShader;
  85. }
  86.  
  87. void MLSpriteBatch::Begin(bool Alpha)
  88. {
  89.         //simple check for alpha. This is pre-set to true
  90.         if (Alpha)
  91.         {
  92.                 glEnable (GL_BLEND);
  93.         }
  94.         else
  95.                 glDisable(GL_BLEND);
  96.  
  97.         //set the begincall to true so now end can be called without error
  98.         m_beginCall = true;
  99. }
  100.  
  101. void MLSpriteBatch::Draw(MLSprite* Sprite)
  102. {
  103.         //check to see if the sprite is enabled or not
  104.         if (!Sprite->getEnabled())
  105.                 return;
  106.  
  107.         bool NewBatch = false;
  108.  
  109.         //a pointer for a batch item
  110.         MLBatchItem::batchInfo* tmpBatch;
  111.  
  112.         //iterate through the batched items and see if the texture has been called before
  113.         BatchMap::iterator it = m_BatchItems.find(Sprite->getTexture());
  114.         if (it != m_BatchItems.end()) //if it has then set the pointer to that batch
  115.                 tmpBatch = m_BatchItems[Sprite->getTexture()];
  116.         else // otherwise create a new batch
  117.         {
  118.                 tmpBatch = new MLBatchItem::batchInfo();
  119.                 tmpBatch->spriteCount = 0;
  120.                 NewBatch = true;
  121.         }
  122.  
  123.         //create the points of the source rectangle
  124.         Vector3f topLeft                = Vector3f(Sprite->getPos().x, Sprite->getPos().y , 0.0f);
  125.         Vector3f topRight               = Vector3f((Sprite->getPos().x + Sprite->getSize().x), Sprite->getPos().y, 0.0f);
  126.         Vector3f bottmLeft              = Vector3f(Sprite->getPos().x, (Sprite->getPos().y + Sprite->getSize().y), 0.0f);
  127.         Vector3f bottomRight    = Vector3f((Sprite->getPos().x + Sprite->getSize().x), (Sprite->getPos().y + Sprite->getSize().y), 0.0f);
  128.        
  129.         //add the points to the batch
  130.         tmpBatch->addPoint(topLeft, Vector2f(0.0f, 1.0f));
  131.         tmpBatch->addPoint(topRight, Vector2f(1.0f, 1.0f));
  132.         tmpBatch->addPoint(bottomRight, Vector2f(1.0f, 0.0f));
  133.         tmpBatch->addPoint(bottmLeft, Vector2f(0.0f, 0.0f));
  134.        
  135.         //increase the batch sprite and total sprite count
  136.         tmpBatch->spriteCount++;
  137.         totalSpriteCount++;
  138.  
  139.         //if it was a new batch created add it to the map
  140.         if (NewBatch)
  141.                 m_BatchItems[Sprite->getTexture()] = tmpBatch;
  142.        
  143.         //if the max sprite count is reached then render them all out
  144.         if (tmpBatch->spriteCount >= ML_MAX_SPRITES)
  145.                 Render();
  146.  
  147. }
  148.  
  149. void MLSpriteBatch::Draw(GLuint Texture, Vector2f Pos, Vector2f Size)
  150. {
  151.        
  152.         bool NewBatch = false;
  153.  
  154.         MLBatchItem::batchInfo* tmpBatch;
  155.  
  156.         BatchMap::iterator it = m_BatchItems.find(Texture);
  157.         if (it != m_BatchItems.end())
  158.                 tmpBatch = m_BatchItems[Texture];
  159.         else
  160.         {
  161.                 tmpBatch = new MLBatchItem::batchInfo();
  162.                 tmpBatch->spriteCount = 0;
  163.                 NewBatch = true;
  164.         }
  165.  
  166.         Vector3f topLeft                = Vector3f(Pos.x, Pos.y , 0.0f);
  167.         Vector3f topRight               = Vector3f((Pos.x + Size.x), Pos.y, 0.0f);
  168.         Vector3f bottmLeft              = Vector3f(Pos.x, (Pos.y + Size.y), 0.0f);
  169.         Vector3f bottomRight    = Vector3f((Pos.x + Size.x), (Pos.y + Size.y), 0.0f);
  170.  
  171.         tmpBatch->addPoint(topLeft, Vector2f(0.0f, 1.0f));
  172.         tmpBatch->addPoint(topRight, Vector2f(1.0f, 1.0f));
  173.         tmpBatch->addPoint(bottomRight, Vector2f(1.0f, 0.0f));
  174.         tmpBatch->addPoint(bottmLeft, Vector2f(0.0f, 0.0f));
  175.  
  176.         tmpBatch->spriteCount++;
  177.  
  178.         if (NewBatch)
  179.                 m_BatchItems[Texture] = tmpBatch;
  180. }
  181.  
  182. void MLSpriteBatch::End()
  183. {
  184.         //If begin has not been called then there is an error
  185.         if (!m_beginCall)
  186.         {
  187.                 MLError::ErrorHandler::printError("Begin must be called before end");
  188.                 return;
  189.         }
  190.         //if the sprite count is greater than 0 the something will need to be rendered still
  191.         if (totalSpriteCount > 0)
  192.                 Render();
  193.  
  194.         m_BufferOffset = 0;
  195.         //clear the batch after done just in case
  196.         m_BatchItems.clear();
  197. }
  198.  
  199. void MLSpriteBatch::Render()
  200. {
  201.         //lock the shader
  202.         m_shader->lock();
  203.         //apply the uniforms
  204.         m_shader->addUniform("inMVP", (MLRenderer::MLCoreGL::getOrtho()));
  205.         m_shader->addUniform("Tex1", 0);
  206.  
  207.         glBindBuffer(GL_ARRAY_BUFFER, m_VertBuffer);
  208.         //start iterating through the batchs
  209.         BatchMap::iterator it = m_BatchItems.begin();
  210.         for(; it != m_BatchItems.end(); it++)
  211.         {
  212.                 //create a pointer to the current batch
  213.                 MLBatchItem::batchInfo* currentBatch = it->second;
  214.  
  215.                 //bind the current texture
  216.                 glBindTexture(GL_TEXTURE_2D, it->first);
  217.  
  218.                 if (m_BufferOffset +  (currentBatch->spriteCount * m_spriteSize) >= m_BufferSize)
  219.                 {
  220.                         glBufferData(GL_ARRAY_BUFFER, m_BufferSize, NULL, GL_STREAM_DRAW);
  221.                         m_BufferOffset = 0;
  222.                 }
  223.  
  224.                 GLbitfield access = (GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  225.                 void* mappedData = glMapBufferRange(GL_ARRAY_BUFFER, m_BufferOffset, m_BufferOffset +  (currentBatch->spriteCount  * m_spriteSize), access);
  226.  
  227.                 if (mappedData)
  228.                 {
  229.                         memcpy(mappedData, it->second->Verts, (currentBatch->spriteCount * m_spriteSize));
  230.                         glUnmapBuffer(GL_ARRAY_BUFFER);
  231.                         m_BufferOffset += (currentBatch->spriteCount * m_spriteSize);
  232.                         //draw using the indicies and vert count set when the batch was created
  233.                         glDrawArrays(GL_QUADS, 0, currentBatch->pointcount);
  234.                        
  235.                 }
  236.                 //unbind the texture
  237.                 glBindTexture(GL_TEXTURE_2D, 0);
  238.                 //delete the batch
  239.                 delete it->second;
  240.         }
  241.         //unbind the buffer
  242.         glBindBuffer(GL_ARRAY_BUFFER, 0);
  243.         //unlock the shader
  244.         m_shader->unlock();
  245.         //set the total sprite count to 0
  246.         totalSpriteCount = 0;
  247.         //clear the batchs
  248.         m_BatchItems.clear();
  249. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top