1
\$\begingroup\$

I created a 3D scene and now I wanted to draw a 2D overlay with the SpriteBatch class.

That is my rendering code:

public void Draw(GameTime gametime)
{
        SceneFactory.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        // Earth
        Matrix[] transforms = new Matrix[earth.Model.Bones.Count];
        earth.Model.CopyAbsoluteBoneTransformsTo(transforms);

        sceneShader.CurrentTechnique = sceneShader.Techniques["Earth"];

        view = viewcam.GetViewMatrix();


        foreach (ModelMesh mesh in earth.Model.Meshes)
        {
            Matrix rotation = Matrix.CreateRotationY(earth.Rotation_Y) * Matrix.CreateRotationX(earth.Rotation_X);
            Matrix model = transforms[mesh.ParentBone.Index] * rotation * Matrix.CreateTranslation(earth.Position);
            Matrix modelview = model * view;

            lightposParam.SetValue(lightpos);

            ambientlightParam.SetValue(ambientLight.ToVector4());
            diffuselightParam.SetValue(diffuseLight.ToVector4());
            specularlightParam.SetValue(specularLight.ToVector4());
            shininessParam.SetValue(shininess);

            diffusetexParam.SetValue(earthDiffuse);
            spectexParam.SetValue(earthSpec);
            normaltexParam.SetValue(earthNormals);
            cloudtexParam.SetValue(earthClouds);
            nightmaptexParam.SetValue(earthNightmap);

            modelviewParam.SetValue(modelview);
            modelviewprojectionParam.SetValue(modelview * projection);
            normalParam.SetValue(Matrix.Invert(Matrix.Transpose(model)));

            mesh.Draw();
        }


        // Skybox
        sceneShader.CurrentTechnique = sceneShader.Techniques["Skybox"];

        transforms = new Matrix[skybox.Model.Bones.Count];

        skybox.Model.CopyAbsoluteBoneTransformsTo(transforms);

        foreach (ModelMesh mesh in skybox.Model.Meshes)
        {
            Matrix model = Matrix.CreateScale(10.0f) * transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(skybox.Rotation_Y) * Matrix.CreateTranslation(skybox.Position);
            Matrix modelview = model * view;

            modelviewParam.SetValue(modelview);
            modelviewprojectionParam.SetValue(modelview * projection);

            skyboxtexParam.SetValue(skyboxCubemap);

            mesh.Draw();
        }


        spritebatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.AnisotropicWrap, DepthStencilState.None, RasterizerState.CullCounterClockwise);

        spritebatch.DrawString(arial, currentInstance.GetType().Name, new Vector2(80, 150), Color.Green);
        spritebatch.DrawString(arial, currentInstance.getSceneDescription(), new Vector2(80, 200), Color.Green);

        spritebatch.Draw(previousScene, new Rectangle(80, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 110, 50, 50), previousSceneColor);
        spritebatch.DrawString(arial, "Previous Scene", new Vector2(135, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 95), Color.Green);
        spritebatch.Draw(nextScene, new Rectangle(280, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 110, 50, 50), nextSceneColor);
        spritebatch.DrawString(arial, "Next Scene", new Vector2(335, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 95), Color.Green);
        spritebatch.Draw(selectScene, new Rectangle(480, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 110, 50, 50), Color.LightGray);
        spritebatch.DrawString(arial, "Select Scene", new Vector2(535, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 95), Color.Green);
        spritebatch.Draw(terminateScene, new Rectangle(SceneFactory.Graphics.GraphicsDevice.Viewport.Width - 205, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 110, 50, 50), Color.LightGray);
        spritebatch.DrawString(arial, "Exit Application", new Vector2(SceneFactory.Graphics.GraphicsDevice.Viewport.Width - 150, SceneFactory.Graphics.GraphicsDevice.Viewport.Height - 95), Color.Green);

        spritebatch.End();

        SceneFactory.Graphics.GraphicsDevice.BlendState = BlendState.Opaque;
        SceneFactory.Graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        SceneFactory.Graphics.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
}

The problem is, that I either get a blueish skybox and transparent 2D overlays (images and text) or a proper skybox but the 2D overlay isn't transparent anymore (depending on BlendState.AlphaBlend / Opaque). Here you can see some screenshots of the problem. I've found this post that references pretty much the same problem, but I already tried to switch the rendering order without any effect. And I'm pretty sure that I did the rendering in the right order (3D -> 2D, right?).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ It could be that you are clearing the scene on the first line of your code with a blue tint ? SceneFactory.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue); Try changing the colour to white and see if that helps as a first quick step. \$\endgroup\$
    – David K
    Dec 27, 2012 at 15:54
  • \$\begingroup\$ Yes. Now the Scene appears "whitish"... i changed it to black and now the Scene is displayed correctly. Thank you! It´s a very strange behavior of the clear function. \$\endgroup\$
    – markus
    Dec 27, 2012 at 16:37

1 Answer 1

1
\$\begingroup\$

Just to confirm the comment as an answer then, and so it might help anyone else who has the problem.

Double check the SceneFactory.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue); line of your code as this is what is responsible, when you alphablend, for your scene to have that blueish tint.

Changing it to SceneFactory.Graphics.GraphicsDevice.Clear(Color.Black); as you have done, will resolve this for you.

\$\endgroup\$

You must log in to answer this question.

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