|
Компелятор говорит что у StorageContainer нет свойства TotalStorage, как решить эту проблему ? |
Санкт-Петербургский государственный политехнический университет
Опубликован: 09.12.2013 | Доступ: свободный | Студентов: 2068 / 33 | Длительность: 06:23:00
Темы: Программирование, Игры, Образование
Специальности: Программист
Самостоятельная работа 8:
Шейдеры. Точечные источники света
Реализация:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Primitives3D;
namespace Lab8
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
TeapotPrimitive teapot;
Effect effect;
SpherePrimitive pointLight;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
teapot = new TeapotPrimitive(GraphicsDevice);
pointLight = new SpherePrimitive(GraphicsDevice, 0.1f, 20);
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
effect = Content.Load<Effect>("light");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
Vector3 cameraPosition = new Vector3(0, 0, 8);
Matrix world = Matrix.CreateRotationY((float)gameTime.TotalGameTime.TotalSeconds);
Matrix view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 0.1f, 20);
Vector3 lightPos0 = new Vector3(0, -1, 1);
Vector3 lightPos1 = new Vector3(1, 1, 1);
Vector3 lightPos2 = new Vector3(-2, 0, 0);
// Источники света
pointLight.Draw(Matrix.CreateTranslation(lightPos0), view, proj, Color.Blue);
pointLight.Draw(Matrix.CreateTranslation(lightPos1), view, proj, Color.Blue);
pointLight.Draw(Matrix.CreateTranslation(lightPos2), view, proj, Color.Blue);
effect.CurrentTechnique = effect.Techniques["Phong"];
effect.Parameters["LightPosition0"].SetValue(lightPos0);
effect.Parameters["LightPosition1"].SetValue(lightPos1);
effect.Parameters["LightPosition2"].SetValue(lightPos2);
effect.Parameters["AmbientColor0"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
effect.Parameters["DiffuseColor0"].SetValue(new Vector4(0.5f, 0f, 0f, 1));
effect.Parameters["SpecularColor0"].SetValue(new Vector4(1, 0, 0, 1));
effect.Parameters["AmbientColor1"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
effect.Parameters["DiffuseColor1"].SetValue(new Vector4(0, 0.5f, 0.5f, 1));
effect.Parameters["SpecularColor1"].SetValue(new Vector4(0, 1, 1, 1));
effect.Parameters["AmbientColor2"].SetValue(new Vector4(0.1f, 0.1f, 0.1f, 1));
effect.Parameters["DiffuseColor2"].SetValue(new Vector4(0.5f, 0.5f, 0.5f, 1));
effect.Parameters["SpecularColor2"].SetValue(new Vector4(1, 1, 1, 1));
effect.Parameters["Eye"].SetValue(cameraPosition);
effect.Parameters["World"].SetValue(world);
effect.Parameters["View"].SetValue(view);
effect.Parameters["Projection"].SetValue(proj);
effect.Parameters["Color"].SetValue(new Vector4(1, 1, 0, 1));
teapot.Draw(effect);
effect.Parameters["World"].SetValue(world * Matrix.CreateTranslation(0, 2, 0));
teapot.Draw(effect);
effect.Parameters["World"].SetValue(world * Matrix.CreateTranslation(-3, 0, 0));
teapot.Draw(effect);
base.Draw(gameTime);
}
}
}Шейдер light.fx:
float4x4 World;
float4x4 View;
float4x4 Projection;
float ka = 1;
float kd = 0.5;
float ks = 1;
float SpecularPower = 4;
// Собственный цвет объекта
float4 Color = float4(1, 0, 0, 1);
float4 AmbientColor0 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor0 = float4(1,1,1,1);
float4 SpecularColor0 = float4(1,1,1,1);
float4 AmbientColor1 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor1 = float4(1,1,1,1);
float4 SpecularColor1 = float4(1,1,1,1);
float4 AmbientColor2 = float4(0.1, 0.1, 0.1, 1);
float4 DiffuseColor2 = float4(1,1,1,1);
float4 SpecularColor2 = float4(1,1,1,1);
// Предполагается, что координаты источников света заданы в мировых координатах
float3 LightPosition0 = float3(0,0,2);
float3 LightPosition1 = float3(2,0,0);
float3 LightPosition2 = float3(-2,0,0);
float3 Eye;
// TODO: add effect parameters here.
struct VertexShaderInputPhong
{
float4 Position : POSITION0;
float3 Normal : NORMAL;
// TODO: add input channels such as texture
// coordinates and vertex colors here.
};
struct VertexShaderOutputPhong
{
float4 Position : POSITION0;
float3 WorldPosition : TEXCOORD0;
float3 Normal : TEXCOORD1;
// TODO: add vertex shader outputs such as colors and texture
// coordinates here. These values will automatically be interpolated
// over the triangle, and provided as input to your pixel shader.
};
VertexShaderOutputPhong VertexShaderFunctionPhong(VertexShaderInputPhong input)
{
VertexShaderOutputPhong output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
float3 worldNormal = normalize(mul(input.Normal, World));
output.Position = mul(viewPosition, Projection);
output.WorldPosition = worldPosition;
output.Normal = worldNormal;
// TODO: add your vertex shader code here.
return output;
}
float4 PointLight(float3 LightPosition, float3 worldPosition, float3 worldNormal, float4 AmbientColor, float4 DiffuseColor, float4 SpecularColor)
{
float4 Ambient = ka * AmbientColor;
float3 lightDirection = normalize(LightPosition - worldPosition);
float4 Diffuse = kd * max(0, dot(worldNormal, lightDirection)) * DiffuseColor;
float3 eyeDirection = normalize(Eye - worldPosition);
float3 reflectedLight = normalize(reflect(-lightDirection, worldNormal));
float4 Specular = ks * pow(max(0, dot(eyeDirection, reflectedLight)), SpecularPower) * SpecularColor;
// для упрощения коэффициент затухания равен 1/d^2
return (Ambient + Diffuse + Specular) / pow(length(worldPosition-LightPosition), 2);
}
float4 PixelShaderFunctionPhong(VertexShaderOutputPhong input) : COLOR0
{
// TODO: add your pixel shader code here.
float3 worldPosition = input.WorldPosition;
float3 worldNormal = normalize(input.Normal);
float4 light0 = PointLight(LightPosition0, worldPosition, worldNormal, AmbientColor0, DiffuseColor0, SpecularColor0);
float4 light1 = PointLight(LightPosition1, worldPosition, worldNormal, AmbientColor1, DiffuseColor1, SpecularColor1);
float4 light2 = PointLight(LightPosition2, worldPosition, worldNormal, AmbientColor2, DiffuseColor2, SpecularColor2);
return Color * (light0 + light1 + light2);
}
technique Phong
{
pass Pass1
{
// TODO: set renderstates here.
VertexShader = compile vs_1_1 VertexShaderFunctionPhong();
PixelShader = compile ps_3_0 PixelShaderFunctionPhong();
}
}