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

    //set input layout

    //set vertex and index buffers

    //send constant buffers to shaders

        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 );    


    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 );
  • \$\begingroup\$ 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. \$\endgroup\$
    – user1430
    Commented Jun 15, 2012 at 15:39
  • \$\begingroup\$ ^^ Post updated. \$\endgroup\$
    – ChaosDev
    Commented Jun 15, 2012 at 15:45
  • \$\begingroup\$ Is DrawIndexedWithCustomEffect used to draw both the sprites/text and the terrain? \$\endgroup\$
    – user1430
    Commented Jun 15, 2012 at 15:49
  • \$\begingroup\$ 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. \$\endgroup\$
    – ChaosDev
    Commented Jun 15, 2012 at 15:52

1 Answer 1


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.

  • \$\begingroup\$ You right ! Its my fault. When Im trying call mp_Context->GSSetShader(nullptr,0,0); before, its strangely throw me error. Now its ok. \$\endgroup\$
    – ChaosDev
    Commented Jun 15, 2012 at 16:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .