XNA - Skydome

xna_logo

Skydome, is a simple sphere that representating virtual sky. Skydome have better realistic looking than skybox but it need advanced texturing. In this article, i'm using simple .x model file (full sphere) and a sky texture to creating skydome.

First, we need these fields :


GraphicsDevice device; // our graphics device
ContentManager content; // content manager for load texture and model
TextureMaterial textureMaterial; // texture material object
Matrix worldMatrix; // world matrix for skydome
float rotationY; // for rotating shere model
Vector3 position
Model skydomeModel; // model of full sphere

CullMode cullMode; // variable that save CullMode value for graphics device
bool depthBufferEnable; // variable that save depthBufferEnable value for graphics device
bool depthBufferWriteEnable; // variable that save depthBufferWriteEnable value for graphics device

SetEffectMaterial method that called in Draw() Method



private void SetEffectMaterial(BasicEffect basicEffect, Matrix viewMatrix, Matrix projectionMatrix)
{
basicEffect.DiffuseColor = Color.White.ToVector3();

// Texture Material
basicEffect.Texture = textureMaterial.Texture;
basicEffect.TextureEnabled = true;

// Transformation
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
}
 

In Update() Method, we set all transformation effect and rotation effect. Oh yeah,  if you decide the skybox center is following camera position, always update position variable.

[sourcecode language="csharp"]
rotationY += (float)gameTime.ElapsedGameTime.TotalSeconds * 0.05f;

worldMatrix =
Matrix.CreateScale(80) *
//Matrix.CreateRotationX(-MathHelper.PiOver2) *
Matrix.CreateRotationY(rotationY)*
Matrix.CreateTranslation(position.X, position.Y, position.Y);
 

Here's the full code :


using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace GameEngine
{
public class Skydome
{
GraphicsDevice device;
ContentManager content;
TextureMaterial textureMaterial;
Matrix worldMatrix;
float rotationY;
Vector3 Position
Model skydomeModel;

CullMode cullMode;
bool depthBufferEnable;
bool depthBufferWriteEnable;

public Vector3 Position { get { return position; } set { position = value; } }

public Skydome(GraphicsDevice device, ContentManager content)
{
this.device = device;
this.content = content;
}

public void LoadContent()
{
skydomeModel = content.Load<Model>(content.RootDirectory + "/" + GameAssetsPath.MODELS + "sphere");
GetTextureMaterial("sky_dome2", Vector2.One);
}

public void LoadContent(string sphereModel, string texture)
{
skydomeModel = content.Load<Model>(content.RootDirectory + "/" + GameAssetsPath.MODELS + sphereModel);
GetTextureMaterial(texture, Vector2.One);
}

private void GetTextureMaterial(string textureFilename, Vector2 tile)
{
Texture2D texture = content.Load<Texture2D>(content.RootDirectory +
"/" + GameAssetsPath.TEXTURES +
textureFilename);
textureMaterial = new TextureMaterial(texture, tile);
}

private void SetEffectMaterial(BasicEffect basicEffect, Matrix viewMatrix, Matrix projectionMatrix)
{

basicEffect.DiffuseColor = Color.White.ToVector3();

// Texture Material
basicEffect.Texture = textureMaterial.Texture;
basicEffect.TextureEnabled = true;

// Transformation
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
}

public void Update(GameTime gameTime, Vector3 camPosition)
{
rotationY += (float)gameTime.ElapsedGameTime.TotalSeconds * 0.05f;

worldMatrix =
Matrix.CreateScale(80) *
//Matrix.CreateRotationX(-MathHelper.PiOver2) *
Matrix.CreateRotationY(rotationY)*
Matrix.CreateTranslation(position.X, position.Y, position.Z);
}

private void SaveGraphicsDeviceState()
{

cullMode = device.RenderState.CullMode;
depthBufferEnable = device.RenderState.DepthBufferEnable;
depthBufferWriteEnable = device.RenderState.DepthBufferWriteEnable;

}

private void RestoreGraphicsDeviceState()
{

device.RenderState.CullMode = cullMode;
device.RenderState.DepthBufferEnable = depthBufferEnable;
device.RenderState.DepthBufferWriteEnable = depthBufferWriteEnable;
//device.RenderState.AlphaTestEnable = alphaTestEnable;

}

public void Draw(Matrix viewMatrix, Matrix projectionMatrix)
{
SaveGraphicsDeviceState();

device.RenderState.CullMode = CullMode.CullClockwiseFace;
device.RenderState.DepthBufferEnable = true;
device.RenderState.DepthBufferWriteEnable = true;

foreach (ModelMesh modelMesh in skydomeModel.Meshes)
{
// We are only rendering models with BasicEffect
foreach (BasicEffect basicEffect in modelMesh.Effects)
SetEffectMaterial(basicEffect, viewMatrix, projectionMatrix);

modelMesh.Draw();
}

device.RenderState.FillMode = FillMode.Solid;
RestoreGraphicsDeviceState();

}

}

public class TextureMaterial
{

Texture2D texture;
Vector2 uvTile;

#region Properties
public Texture2D Texture { get { return texture; } set { texture = value;} }

public Vector2 UVTile { get { return uvTile; } set { uvTile = value; } }
#endregion

public TextureMaterial() { }

public TextureMaterial(Texture2D texture, Vector2 uvTile)
{
this.texture = texture;
this.uvTile = uvTile;
}
}
}
 

To render skydome in wireframe simply add this line in Draw() method :


device.RenderState.FillMode = FillMode.WireFrame;
 

 

Published Thursday, December 2, 2010 5:38 AM by azer89
Filed under:

Comments

# re: XNA - Skydome

ini XNA versi berapa ya?

seingat saya GraphicsDevice.RenderState udah ga ada di XNA 4.0 (diganti rasterizer state dll kalo ga salah)

Thursday, December 2, 2010 6:05 AM by m.ridhwan.ramdhani

# Twitter Trackbacks for XNA - Skydome - azer89 [netindonesia.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 XNA - Skydome - azer89         [netindonesia.net]        on Topsy.com