Something like that, yes. If you are going to store the actual vertex data in your draw list, you can just memcpy a block of it, be a little easier. Also need to remember that you if are locking the buffer with the no-overwrite option the pointer you get back will be the pointer to the same buffer you filled last time. So you need to write data into it past the point where you put data last time.
vertex* vertices;
vBuffer->Lock(0, 0, (void**)&vertices, NULL);
for (auto& item : m_drawList)
{
memcpy(vertices + m_countWritten, item.verts, sizeof(vertex) * 4);
m_countWritten += 4;
}
I have started to implement everything, but I am still a little stuck on the texture swap portion of the code.
Currently my code for the SpriteBatcher::endBatch is basing everything off of using one texture and only using the DISCARD flag
Here is my current code:
void SpriteBatcher::endBatch()
{
//std::cout<<"RENDER"<<std::endl;
//Lock the buffer based on the bufferLockFlag; Set to DISCARD for now
vBuffer->Lock(0, 0, (void**) &vertices, bufferLockFlag);
iBuffer->Lock(0, 0, (void**) &indices, bufferLockFlag);
//Loop through all of our quads and get there data
for(std::vector<quad>::iterator i = drawData.begin(); i != drawData.end(); i++)
{
//Check for texture change
if(currentTexture != (*i).texture)
{
std::cout<<"Set texture: "<<(*i).texture<<std::endl;
currentTexture = (*i).texture;
}
//Copy the verts into the buffer
memcpy(vertices + vertCount, (*i).verts, sizeof((*i).verts));
//Get all the indices
indices[indexCount] = currentIndex;
indices[indexCount + 1] = currentIndex + 1;
indices[indexCount + 2] = currentIndex + 2;
indices[indexCount + 3] = currentIndex + 3;
indices[indexCount + 4] = currentIndex;
indices[indexCount + 5] = currentIndex + 2;
//Increase the counts
indexCount += 6;
currentIndex += 4;
vertCount += 4;
numShapes += 2;
}
//Unlock the buffers
vBuffer->Unlock();
iBuffer->Unlock();
//Set the texture and draw everything; The Stream Source and Index buffer are set in an init method
batDevice->SetTexture(0, currentTexture);
batDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertCount, 0, numShapes);
//Clear the vector and reset all the counts
drawData.clear();
vertCount = 0;
indexCount = 0;
currentIndex = 0;
numShapes = 0;
}
This is currently working great, but I'm a little confused about the texture swap check portion. I understand I should unlock the buffers, set the texture to use / draw everything, and then reclaim the lock with the right flag, but my confusion comes from the drawing part.
When I draw everything inside of the texture check, do I need to reset my counts since I drew everything? Does calling the batDevice->DrawIndexedPrimitive method clear out the buffer? Meaning that I have to set the vertCount and numShapes to the right values in the final batDevice->DrawIndexedPrimitive call (the one outside the check texture swap area)?
EG:
void vBatcher::endBatch()
{
//std::cout<<"RENDER"<<std::endl;
//Lock the buffer based on the bufferLockFlag; Set to DISCARD for now
vBuffer->Lock(0, 0, (void**) &vertices, bufferLockFlag);
iBuffer->Lock(0, 0, (void**) &indices, bufferLockFlag);
//Loop through all of our quads and get there data
for(std::vector<quad>::iterator i = drawData.begin(); i != drawData.end(); i++)
{
//Check for texture change
if(currentTexture != (*i).texture)
{
//Unlock the buffers because we need to swap textures
vBuffer->Unlock();
iBuffer->Unlock();
//Confusion Part
//Set the texture and draw everything; The Stream Source and Index buffer are set in an init method;
//Draw everything because of the texture swap
batDevice->SetTexture(0, currentTexture);
batDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertCount, 0, numShapes);
//Reset the counts on everything because we did a texture swap
vertCount = 0;
indexCount = 0;
currentIndex = 0;
numShapes = 0;
//Set the new texture
std::cout<<"Set texture: "<<(*i).texture<<std::endl;
currentTexture = (*i).texture;
//{!} This is where the flag check would go to determine which flag to use
//Not sure how to handle this part because of confusion
//Relock the buffer based on the bufferLockFlag;
vBuffer->Lock(0, 0, (void**) &vertices, bufferLockFlag);
iBuffer->Lock(0, 0, (void**) &indices, bufferLockFlag);
}
//Cop the verts into the buffer
memcpy(vertices + vertCount, (*i).verts, sizeof((*i).verts));
//Get all the indices
indices[indexCount] = currentIndex;
indices[indexCount + 1] = currentIndex + 1;
indices[indexCount + 2] = currentIndex + 2;
indices[indexCount + 3] = currentIndex + 3;
indices[indexCount + 4] = currentIndex;
indices[indexCount + 5] = currentIndex + 2;
//Increase the counts
indexCount += 6;
currentIndex += 4;
vertCount += 4;
numShapes += 2;
}
//Unlock the buffers
vBuffer->Unlock();
iBuffer->Unlock();
//The final draw call in the endBatch
//Set the texture and draw everything; The Stream Source and Index buffer are set in an init method
batDevice->SetTexture(0, currentTexture);
batDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertCount, 0, numShapes);
//Clear the vector and reset all the counts
drawData.clear();
vertCount = 0;
indexCount = 0;
currentIndex = 0;
numShapes = 0;
}
If this is correct then I think I would only need to create a new variable to determine how close I am to filling the buffer. And then I would use that to base what lock I need to grab in textureswap. Correct?