Advertisement
Dekowta

SpriteBatchMod2.cpp

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