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.

My application has multiple screens with different tasks. Once I set a geometry shader to the device context for my custom terrain, it works and I get the desired results.

But then when I get back to the main menu, all sprites and text disappear. These sprites don't dissappear when I use pixel and vertex shaders.

The sprites are being drawn through D3D11, of course, with specified view and projection matrices as well an input layout, vertex, and pixel shader. I'm trying DeviceContext->ClearState() but it does not help. Any ideas?

    void gGeometry::DrawIndexedWithCustomEffect(gVertexShader*vs,gPixelShader* ps,gGeometryShader* gs=nullptr)
{
    unsigned int offset = 0;
    auto context = mp_D3D->mp_Context;

    //set topology
    context->IASetPrimitiveTopology(m_Topology);

    //set input layout
    context->IASetInputLayout(mp_inputLayout);

    //set vertex and index buffers
    context->IASetVertexBuffers(0,1,&mp_VertexBuffer->mp_Buffer,&m_VertexStride,&offset);
    context->IASetIndexBuffer(mp_IndexBuffer->mp_Buffer,mp_IndexBuffer->m_DXGIFormat,0);

    //send constant buffers to shaders
    context->VSSetConstantBuffers(0,vs->m_CBufferCount,vs->m_CRawBuffers.data()); 
    context->PSSetConstantBuffers(0,ps->m_CBufferCount,ps->m_CRawBuffers.data());
    if(gs!=nullptr) 
    {

        context->GSSetConstantBuffers(0,gs->m_CBufferCount,gs->m_CRawBuffers.data());
        context->GSSetShader(gs->mp_D3DGeomShader,0,0);//after this call all sprites disappear
    }

    //set shaders
    context->VSSetShader( vs->mp_D3DVertexShader, 0, 0 );
    context->PSSetShader( ps->mp_D3DPixelShader, 0, 0 );    


    //draw
    context->DrawIndexed(m_indexCount,0,0);
}

//sprites
    void gSpriteDrawer::Draw(gTexture2D* texture,const RECT& dest,const RECT& source, const Matrix& spriteMatrix,const float& rotation,Vector2d& position,const Vector2d& origin,const Color& color)
{

    VertexPositionColorTexture* verticesPtr;
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    unsigned int TriangleVertexStride = sizeof(VertexPositionColorTexture);
    unsigned int offset = 0;

    float halfWidth = ( float )dest.right / 2.0f;
    float halfHeight = ( float )dest.bottom / 2.0f;

    float z = 0.1f;       

    int w = texture->Width();
    int h = texture->Height();

    float tu = (float)source.right/(w); 
    float tv = (float)source.bottom/(h);
    float hu = (float)source.left/(w);
    float hv = (float)source.top/(h);

    Vector2d t0 = Vector2d( hu+tu, hv);
    Vector2d t1 = Vector2d( hu+tu, hv+tv);
    Vector2d t2 = Vector2d( hu, hv+tv);
    Vector2d t3 = Vector2d( hu, hv+tv);
    Vector2d t4 = Vector2d( hu, hv);
    Vector2d t5 = Vector2d( hu+tu, hv);        

    float ex=(dest.right/2)+(origin.x);
    float ey=(dest.bottom/2)+(origin.y);  

    Vector4d v4Color = Vector4d(color.r,color.g,color.b,color.a);

    VertexPositionColorTexture vertices[] =
    {
        { Vector3d( dest.right-ex,  -ey,              z),v4Color, t0},
        { Vector3d( dest.right-ex,  dest.bottom-ey ,  z),v4Color, t1},
        { Vector3d( -ex,             dest.bottom-ey ,  z),v4Color, t2},
        { Vector3d( -ex,             dest.bottom-ey ,  z),v4Color, t3},
        { Vector3d( -ex,             -ey ,              z),v4Color, t4},
        { Vector3d( dest.right-ex,  -ey ,              z),v4Color, t5},
    }; 

    auto mp_context = mp_D3D->mp_Context;

    // Lock the vertex buffer so it can be written to.
    mp_context->Map(mp_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

    // Get a pointer to the data in the vertex buffer.
    verticesPtr = (VertexPositionColorTexture*)mappedResource.pData;

    // Copy the data into the vertex buffer.
    memcpy(verticesPtr, (void*)vertices, (sizeof(VertexPositionColorTexture) * 6));

    // Unlock the vertex buffer.
    mp_context->Unmap(mp_vertexBuffer, 0);

    //set vertex shader
    mp_context->IASetVertexBuffers( 0, 1, &mp_vertexBuffer, &TriangleVertexStride, &offset);

    //set texture
    mp_context->PSSetShaderResources( 0, 1, &texture->mp_SRV);

    //set matrix to shader
    mp_context->UpdateSubresource(mp_matrixBuffer, 0, 0, &spriteMatrix, 0, 0 );
    mp_context->VSSetConstantBuffers( 0, 1, &mp_matrixBuffer); 

    //draw sprite
    mp_context->Draw( 6, 0 );
}   
share|improve this question
    
ClearState will clear all your state, including all shaders. You don't mention which state you restore afterwards. You might want to post some code because as it stands we can only speculate (and relatively wildly) what might be wrong -- it could be anything. –  Josh Petrie Jun 15 '12 at 15:39
    
^^ Post updated. –  ChaosDev Jun 15 '12 at 15:45
    
Is DrawIndexedWithCustomEffect used to draw both the sprites/text and the terrain? –  Josh Petrie Jun 15 '12 at 15:49
    
Josh Petrie, No, I update post again. They are in different classes. DrawIndexedWithCustomEffect used only for things like terrain. Anyway, they must using different instances of geometry class. –  ChaosDev Jun 15 '12 at 15:52
add comment

1 Answer 1

up vote 3 down vote accepted

Once you call DrawIndexedWithCustomEffect with a non-null geometry shader, that shader is bound to the device and it remains bound until you either bind another one or until you unbind it (by calling GSSetShader with a null pointer).

Consequently, if you call DrawIndexedWithCustomEffect and pass it a non-null geometry shader, and then you call your sprite Draw method, the sprites will still be rendered with the geometry shader active, which will likely do unexpected things to their geometry, causing them to be unrenderable or to render way off screen or something.

You have a separate method for rendering sprites, and that method is currently assuming that no geometry shader is present, but that's no longer the case.

You should solve this problem by ensuring you set all state that is relevant in your draw methods. In this case you probably want to ensure the geometry shader is unbound in your gSpriteDrawer::Draw method by calling GSSetShader with a null pointer prior to issuing a draw call.

share|improve this answer
    
You right ! Its my fault. When Im trying call mp_Context->GSSetShader(nullptr,0,0); before, its strangely throw me error. Now its ok. –  ChaosDev Jun 15 '12 at 16:03
add comment

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.