Try to make a Version with "Actor" and "View" of your RotationCube-Example

Aug 23, 2013 at 10:38 PM
Edited Aug 23, 2013 at 11:13 PM
I try to make your simple "RotationCube"-Example as an Version with Actor and a View.

But it shows nothing on screen. Can you help me and see what is wrong?
TestActor* testActor= new TestActor();
m_pScene->AddActor( testActor );
TestActor::TestActor()
{
    initialize();
}
//--------------------------------------------------------------------------------
TerrainActor::~TerrainActor()
{
}
//--------------------------------------------------------------------------------

void TestActor::initialize() {
    RendererDX11* pRenderer = RendererDX11::Get();

    // Create the material for use by the entity.
    m_pMaterial = MaterialPtr( new MaterialDX11() );

    // Create and fill the effect that will be used for this view type
    RenderEffectDX11* pEffect = new RenderEffectDX11();

    pEffect->SetVertexShader( pRenderer->LoadShader( VERTEX_SHADER,
        std::wstring( L"RotatingCube.hlsl" ),
        std::wstring( L"VSMain" ),
        std::wstring( L"vs_4_0" ),
        true ) );

    pEffect->SetGeometryShader( pRenderer->LoadShader( GEOMETRY_SHADER,
        std::wstring( L"RotatingCube.hlsl" ),
        std::wstring( L"GSMain" ),
        std::wstring( L"gs_4_0" ),
        true ) );

    pEffect->SetPixelShader( pRenderer->LoadShader( PIXEL_SHADER,
        std::wstring( L"RotatingCube.hlsl" ),
        std::wstring( L"PSMain" ),
        std::wstring( L"ps_4_0" ),
        true ) );

    DepthStencilStateConfigDX11 dsConfig;
    int iDepthStencilState = pRenderer->CreateDepthStencilState( &dsConfig );
    if ( iDepthStencilState == -1 ) {
        Log::Get().Write( L"Failed to create light depth stencil state" );
        assert(false);
    }

    BlendStateConfigDX11 blendConfig;
    int iBlendState = pRenderer->CreateBlendState( &blendConfig );
    if ( iBlendState == -1 ) {
        Log::Get().Write( L"Failed to create light blend state" );
        assert(false);
    }

    RasterizerStateConfigDX11 rsConfig;
    rsConfig.CullMode = D3D11_CULL_BACK;
    //rsConfig.FillMode = D3D11_FILL_WIREFRAME;
    int iRasterizerState = pRenderer->CreateRasterizerState( &rsConfig );
    if ( iRasterizerState == -1 ) {
        Log::Get().Write( L"Failed to create light rasterizer state" );
        assert(false);
    }

    pEffect->m_iBlendState = iBlendState;
    pEffect->m_iDepthStencilState = iDepthStencilState;
    pEffect->m_iRasterizerState = iRasterizerState;
    pEffect->m_uStencilRef = iDepthStencilState;

    // Create the render view that will run the simulation.  The size should be
    // selected accordingly for the maximum number of particles.
    m_pSimulation = new TestView( *pRenderer, pEffect);

    // Enable the material to render the given view type, and set its effect.
    m_pMaterial->Params[VT_PERSPECTIVE].bRender = true;
    m_pMaterial->Params[VT_PERSPECTIVE].pEffect = pEffect;
    m_pMaterial->Params[VT_PERSPECTIVE].Tasks.push_back( m_pSimulation );

    GetBody()->SetMaterial( m_pMaterial );
}
struct Vertex
{
    DirectX::XMFLOAT3 Pos;
    DirectX::XMFLOAT4 Color;
};
TestView::TestView( RendererDX11& Renderer, RenderEffectDX11* pEffect )
{
    m_pEffect = pEffect;

    D3D11_INPUT_ELEMENT_DESC desc[] =
    {
        { "SV_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
    layout.push_back(desc[0]);
    layout.push_back(desc[1]);
    m_VertexLayout = Renderer.CreateInputLayout(layout, pEffect->GetVertexShader());
    if (m_VertexLayout == -1) {
        Log::Get().Write( L"Failed to create vertex layout" );
        assert(false);
    }

    {
        Vertex vertices[] =
        {
            { DirectX::XMFLOAT3( -1.0f, 1.0f, -1.0f ), DirectX::XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
            { DirectX::XMFLOAT3( 1.0f, 1.0f, -1.0f ), DirectX::XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ) },
            { DirectX::XMFLOAT3( 1.0f, 1.0f, 1.0f ), DirectX::XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
            { DirectX::XMFLOAT3( -1.0f, 1.0f, 1.0f ), DirectX::XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ) },
            { DirectX::XMFLOAT3( -1.0f, -1.0f, -1.0f ), DirectX::XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ) },
            { DirectX::XMFLOAT3( 1.0f, -1.0f, -1.0f ), DirectX::XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ) },
            { DirectX::XMFLOAT3( 1.0f, -1.0f, 1.0f ), DirectX::XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
            { DirectX::XMFLOAT3( -1.0f, -1.0f, 1.0f ), DirectX::XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) },
        };
        D3D11_SUBRESOURCE_DATA data;
        data.pSysMem = vertices;
        data.SysMemPitch = 0;
        data.SysMemSlicePitch = 0;

        BufferConfigDX11 vbConfig;
        vbConfig.SetDefaultVertexBuffer(8 * sizeof(Vertex), false);
        m_pVertexBuffer = Renderer.CreateVertexBuffer( &vbConfig, &data );
        if( m_pVertexBuffer->m_iResource == -1 ) {
            Log::Get().Write( L"Failed to create vertex buffer" );   
            assert(false);
        }
    }

    // create the index buffer resource (this is usually done by GeometryDX11)
    {
        UINT indices[] =
        {
            3,1,0,
            2,1,3,

            0,5,4,
            1,5,0,

            3,4,7,
            0,4,3,

            1,6,5,
            2,6,1,

            2,7,6,
            3,7,2,

            6,4,5,
            7,4,6,
        };
        D3D11_SUBRESOURCE_DATA data;
        data.pSysMem = indices;
        data.SysMemPitch = 0;
        data.SysMemSlicePitch = 0;

        BufferConfigDX11 vbConfig;
        vbConfig.SetDefaultIndexBuffer(sizeof(UINT) * 36, false);
        m_pIndexBuffer = Renderer.CreateIndexBuffer(&vbConfig, &data);
        if( m_pIndexBuffer->m_iResource == -1 ) {
            Log::Get().Write( L"Failed to create index buffer" );   
            assert(false);
        }
    }
}
//--------------------------------------------------------------------------------
TestView::~TestView()
{
}
//--------------------------------------------------------------------------------
void TestView::QueuePreTasks( RendererDX11* pRenderer )
{
    pRenderer->QueueTask( this );
}

//--------------------------------------------------------------------------------
void TestView::ExecuteTask( PipelineManagerDX11* pPipelineManager, IParameterManager* pParamManager )
{
    UINT stride = sizeof(Vertex);
    pPipelineManager->Draw(*m_pEffect, m_pVertexBuffer, m_pIndexBuffer, m_VertexLayout, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, stride, 36, pParamManager);
}
Coordinator
Aug 24, 2013 at 2:22 AM
Does the ExecuteTask method ever get called? Normally I would put the geometry for the cube into the Body() of the Actor, and then draw that. Even so, this way should also be able to work. You have a material set for the body, so any views that are bound to that entity should be queued up and then rendered.

So in theory it should get executed. Can you check if that TestView::ExecuteTask method is ever being called? Also, have you taken care to position the actor in a place that the camera can see it? Those are the two likely suspects...
Aug 24, 2013 at 9:23 AM
Edited Aug 24, 2013 at 4:32 PM
Yes the ExecuteTask is called and there is no error on creating VertexBuffer, IndexBuffer or VertexLayout. So the draw method is called success. The camera should see the entity too.

I dont want to set geometry into the actor like GetBody()->SetGeometry( m_pExecutor ); because i will make more than one draw call later in the view. So i have a for-loop that makes more than one draw call with different textures. With setting an geometry executor inside the the body() i think i cant manage it.

My purpose is to render terrain tiles. Each tile has a different Texture. The terrain is streamed and i get all tiles in a list. So i have to iterate through all tiles and the diffenent textures and draw them.
Coordinator
Aug 24, 2013 at 11:22 PM
Did you check with PIX or the Graphics Debugger in VS2012 to see why the geometry doesn't end up in the viewport? I would assume that since you aren't using a geometry object (Executor actually...) that there is no world matrix being set before you do the rendering. That might cause the issue - can you double check what world matrix is being used at the time of the call?
Aug 25, 2013 at 1:29 AM
Edited Aug 25, 2013 at 12:19 PM
Never used a Graphic Debugger before.

Perhaps you can help me.
I started over Debug->Graphics->Start Diagnostics the Debugger and with "Print" Key i can capture the current image.

But i have to go into the shader... i think i need something like a HLSL Debugger or not? Should i have to use something like NSight from Nvidia for this? Pix is not working under VS2012 i think. And i think NSight is not working under VS2012 too. Thats hard.

Have i bind my shaders with my project somehow, so that i can set breakpoints on a hlsl-file?, because visual studio (project) doesnt know about the shaders i use, only over the url that points to the file on the hard drive.

I will give it a closer look tomorrow. My daytime is over ... a lot of over ^^

Edit: I see that the method:
void ParameterManagerDX11::SetWorldMatrixParameter( Matrix4f* pMatrix ) 
is never been called. So no parameters are set to the shader.

I dont get it where my failure is.

ExecuteTask makes now this, but there is no output on the screen:

The most code is the out written method PipelineManagerDX11::Draw( RenderEffectDX11& effect, ResourcePtr vb, ResourcePtr ib, int inputLayout, D3D11_PRIMITIVE_TOPOLOGY primType, UINT vertexStride, UINT numIndices, IParameterManager* pParamManager )
,so i can perhaps better see why it doesnt work)
void TestView::ExecuteTask( PipelineManagerDX11* pPipelineManager, IParameterManager* pParamManager )
{
       _entity->SetRenderParams(pParamManager);
    
    UINT vertexStride = sizeof(Vertex);
    
    pPipelineManager->InputAssemblerStage.ClearDesiredState();

    // Use the effect to load all of the pipeline stages here.
    pPipelineManager->ClearPipelineResources();
    m_pEffect->ConfigurePipeline( pPipelineManager, pParamManager );
    pPipelineManager->ApplyPipelineResources();

    pPipelineManager->InputAssemblerStage.DesiredState.PrimitiveTopology.SetState( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
    
    // Bind the vertex and index buffers.
    if ( m_pVertexBuffer != NULL ) {
        pPipelineManager->InputAssemblerStage.DesiredState.VertexBuffers.SetState( 0, m_pVertexBuffer->m_iResource );
        pPipelineManager->InputAssemblerStage.DesiredState.VertexBufferStrides.SetState( 0, vertexStride );
        pPipelineManager->InputAssemblerStage.DesiredState.VertexBufferOffsets.SetState( 0, 0 );
    }

    if ( m_pIndexBuffer != NULL ) {
        pPipelineManager->InputAssemblerStage.DesiredState.IndexBuffer.SetState( m_pIndexBuffer->m_iResource );
        pPipelineManager->InputAssemblerStage.DesiredState.IndexBufferFormat.SetState( DXGI_FORMAT_R32_UINT );
    }

    // Bind the input layout.
    if ( m_pVertexBuffer != NULL ) {
        pPipelineManager->InputAssemblerStage.DesiredState.InputLayout.SetState( m_VertexLayout );
    }

    // Set and apply the state in this pipeline manager's input assembler.
    pPipelineManager->InputAssemblerStage.ApplyDesiredState( pPipelineManager->m_pContext );
    
    pPipelineManager->m_pContext->DrawIndexed( 36, 0, 0 );
}