Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a class which "collects" line mesh transformations throughout the update and then draws them in one place by drawing one line over and over again. I'll post the code below. I'm just wondering if this is instanced or if the idea is to join them all into one mega-mesh and send that through?

Or if I'm missing some key-part altogether....

void BatchLineRenderer::RenderLines(D3DXMATRIX matView, D3DXMATRIX matProjection)
{
    device->IASetInputLayout(pVertexLayout);

    device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);

    // select which vertex buffer and index buffer to display
    UINT stride = sizeof(LINE);
    UINT offset = 0;
    device->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
    device->IASetIndexBuffer(iBuffer, DXGI_FORMAT_R32_UINT, 0);

    std::vector<LINE>::size_type allLines = permanentLines.size();

    for(int i = 0; i < allLines; i++)
    {
        pColour->SetFloatVector(permanentLines[i].colour); // in the line loop too?

        // combine the matrices and render
        D3DXMATRIX matFinal = 
        permanentLines[i].scale     * 
        permanentLines[i].rotation  * 
        permanentLines[i].position  * 
        matView * matProjection;

        pTransform->SetMatrix(&matFinal._11); 
        pRotation->SetMatrix(&permanentLines[i].rotation._11);    // set the rotation matrix in the effect

        pPass->Apply(0);

        device->DrawIndexed(2, 0, 0);
    }

    allLines = temporaryLines.size();

    for(int i = 0; i < allLines; i++)
    {
        pColour->SetFloatVector(temporaryLines[i].colour); // in the line loop too?

        // combine the matrices and render
        D3DXMATRIX matFinal = 
        temporaryLines[i].scale * 
        temporaryLines[i].rotation * 
        temporaryLines[i].position * 
        matView * matProjection;

        pTransform->SetMatrix(&matFinal._11); 
        pRotation->SetMatrix(&temporaryLines[i].rotation._11);    // set the rotation matrix in the effect

        pPass->Apply(0);

        device->DrawIndexed(2, 0, 0);
    }

    temporaryLines.clear();
}
share|improve this question

2 Answers 2

up vote 5 down vote accepted

The purpose of "instanced" rendering is to make one draw call to draw all of the instances. You are making allLines number of draw calls. So no, that's not instancing.

Since each instance is completely separate from the other, sharing absolutely no data at all (the matrix is basically just a bulky way to encode the two endpoints of each line), you would gain nothing from instancing. Instead, you should build a vertex buffer that contains all of the lines (and their colors). If lines change, you change the buffer.

This way, you draw all of them at once.

share|improve this answer
    
and how would I do that? also, is there a name for that technique? –  Asher Einhorn Jan 4 '12 at 9:54
    
It's called, "Drawing a lot of lines." ;) And you do it by putting your position and color attributes in the buffer. Then you just make a DrawPrimitive call, only with many vertices instead of just two. If the lines change, you have to change the data in the buffer to match. –  Nicol Bolas Jan 4 '12 at 10:05
    
what if I just stored one set of data in a buffer representing one line, then drew that line many times with a list of transforms? –  Asher Einhorn Jan 4 '12 at 14:50
    
do you mean a DrawIndex() call? –  Asher Einhorn Jan 4 '12 at 15:15
    
the lines share the same index and vertex buffer. does that count for anything? –  Asher Einhorn Jan 4 '12 at 15:39

I would consider instanced rendering to either be a single Draw call of some sort, where the geometry itself is either duplicated in the buffer N times, or the drawing API renders the mesh N times for you with some per-instance vertex buffer data, or multiple Draw calls with no other API calls in between them (i.e. only changing the starting index or vertex and number of primitives, which you would need to do if you wish to draw less than a whole mesh, but in parts).

Any other API to change textures, rendertargets, shader constants, render state, and shaders calls can incur quite a lot of overhead.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.