Using GeometricPrimitive with BasicEffect?

Feb 15, 2013 at 4:18 AM
I've attempted this using a Sphere primitive but, probably because of something I'm doing wrong, nothing appears to be getting rendered. Everything works fine however using the non-custom effect draw method.

At the moment I'm just trying to get it to work so I'm not doing anything special and trying to leave it to the defaults.

Here's some code:
   // Set up basic info for the Mars lighting
   g_MarsEffect = make_unique<BasicEffect>(g_Device);
   g_MarsEffect->SetView(g_View);
   g_MarsEffect->SetProjection(g_Projection);
   g_MarsEffect->SetTexture(g_pTextureMars);
   g_MarsEffect->SetTextureEnabled(true);
   g_MarsEffect->EnableDefaultLighting();

   ...

   // Down where I do all the rendering
   BasicEffect* MarsEffect = g_MarsEffect.get();
   ComPtr<ID3D11InputLayout> layout;

   // Mars always sits at the origin and spins in place
   XMMATRIX MarsLocal = XMMatrixTranslation(0.f, 0.f, 0.f);
   XMMATRIX spin = XMMatrixRotationY(t);
   MarsLocal *= spin;
   g_MarsEffect->SetWorld(MarsLocal);

   g_Mars->CreateInputLayout(MarsEffect, &layout);
   g_Mars->Draw(MarsEffect, layout.Get());
   /*g_Mars->Draw(MarsLocal, g_View, g_Projection, Colors::White, g_pTextureMars);*/
Using the commented out code g_Mars->Draw(MarsLocal, g_View, g_Projection, Colors::White, g_pTextureMars); everything works fine, but, again, trying to use a custom effect nothing gets drawn to the screen.

Running in the debugger and following the calls to void GeometricPrimitive::Impl::Draw(...) and checking the values for the default shared effect and mine shows that pretty much everything matches up.

Any idea what I'm doing wrong?
Coordinator
Feb 15, 2013 at 7:04 AM
Edited Feb 15, 2013 at 7:09 AM
TEXTFrom the code pasted here it does look correct basically for doing custom effect rendering with a GeoPrim. My test case looks very similar.
    auto cube = GeometricPrimitive::CreateCube(context, 1.f, rhcoords );

    ID3D11InputLayout* customIL = nullptr;
    std::unique_ptr<BasicEffect> customEffect( new BasicEffect( device ) );
    customEffect->EnableDefaultLighting();
    customEffect->SetTextureEnabled(true);
    customEffect->SetTexture(dxlogo);
    customEffect->SetDiffuseColor( g_XMOne );
    cube->CreateInputLayout( customEffect.get(), &customIL );

    customEffect->SetView( view );
    customEffect->SetProjection( projection );

    customEffect->SetWorld( ... );
    cube->Draw( customEffect.get(), customIL );
The only thing different I see is that you are not explicitly setting a diffuse color.
g_MarsEffect->SetDiffuseColor( Colors::White );
Also, does it work if you render using the non-custom version first and then the custom version second (in a different position)?

Do you get different results if you reorder the calls to set up your BasicEffect?

Do you get any output from the debug device?
Feb 15, 2013 at 10:04 AM
Edited Feb 15, 2013 at 11:39 AM
I didn't bother to set a diffuse color because that's already set when calling EnableDefaultLighting(). Figured I'd just get it showing up as normal first then tinker until I got something interesting but even after explicitly setting it myself, just in case, it still doesn't work.

Changing the call order when setting up the effect doesn't do anything, nor does calling the non-custom one first then the custom one or the other way around when using a different position for the custom effect.

Nothing useful from the debug device either. Just a ton of INFO messages about the creation and deletion of the input layout relating to my attempt to use a custom effect. Here's a small sample.

D3D11: INFO: Create InputLayout: Name="unnamed", Addr=0x027C6FEC, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097264: CREATE_INPUTLAYOUT ]
D3D11: INFO: Destroy InputLayout: Name="DirectXTK:GeometricPrimitive", Addr=0x027C5D0C [ STATE_CREATION INFO #2097266: DESTROY_INPUTLAYOUT ]
D3D11: INFO: Create InputLayout: Name="unnamed", Addr=0x027C5D0C, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097264: CREATE_INPUTLAYOUT ]
D3D11: INFO: Destroy InputLayout: Name="DirectXTK:GeometricPrimitive", Addr=0x027C6FEC [ STATE_CREATION INFO #2097266: DESTROY_INPUTLAYOUT ]
D3D11: INFO: Create InputLayout: Name="unnamed", Addr=0x027C6FEC, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #2097264: CREATE_INPUTLAYOUT ]
D3D11: INFO: Destroy InputLayout: Name="DirectXTK:GeometricPrimitive", Addr=0x027C5D0C [ STATE_CREATION INFO #2097266: DESTROY_INPUTLAYOUT ]

No errors or warnings.

I'll keep fooling around with it. Thankfully getting this working isn't critical to my needs right now, it's just annoying.
Coordinator
Feb 15, 2013 at 4:45 PM
My telepathic debugging powers suggest two things to look at:

Are you sure that g_View and g_Projection are properly initialized before you copy them into your BasicEffect instance?

Why are you creating a new input layout every frame? Make just one on startup, then hang onto and reuse it.
Coordinator
Feb 15, 2013 at 6:00 PM
Edited Feb 15, 2013 at 6:01 PM
That's a good idea. Make sure you move the matrix setup to just before the draw...
   g_MarsEffect->SetView(g_View);
   g_MarsEffect->SetProjection(g_Projection);
As Shawn notes, you shouldn't create the input layout every frame...

If you have VS 2012 Pro or higher, you can try the VS Graphics Debugging feature out on the app to see if gives you any hints.
Feb 16, 2013 at 4:59 AM
Edited Feb 16, 2013 at 5:18 AM
Umm yeah. I was just testing you...

Heh. Moving the effect initialization stuff to happen after the view/projection/world matrix setup stuff worked and I have a second sphere. I was under the impression, from the documentation, that I needed to create a new layout whenever the effect was modified so that's why I was doing so though now I realize that it's only when things such the lights or fog are changed, not the matrices.

Thanks!

Now comes the really fun part. Shadows.
Coordinator
Feb 16, 2013 at 6:37 AM
Edited Feb 16, 2013 at 6:46 AM
We should probably be more explicitly about exactly what requires a new layout :)

For the built-in effects, the trigger for needing to create a new layout would be:
  • Enabling or disabling lighting (which requires a vertex normal)
  • Enabling or disabling per vertex color (which requires a vertex color value)
  • Enabling or disabling textures (which requires vertex texture coordinates)