-
-
Save OptimisticPeach/353b04699a1df134356cfbb16a03f635 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Content; | |
using Microsoft.Xna.Framework.Input; | |
using Microsoft.Xna.Framework.Graphics; | |
using System.IO; | |
using Microsoft.Xna.Framework.Audio; | |
using Microsoft.Xna.Framework.Media; | |
namespace Testing_Project | |
{ | |
//A primitive effect manager. | |
public class PrimitiveEffect | |
{ | |
Effect internalEffect; | |
public Effect InternalEffect | |
{ | |
get | |
{ | |
if (!SetParams) | |
{ | |
internalEffect.Parameters["World"].SetValue(World); | |
internalEffect.Parameters["WorldViewProj"].SetValue(World * View * Projection); | |
internalEffect.Parameters["WorldInverseTranspose"].SetValueTranspose(Matrix.Invert(World)); | |
internalEffect.Parameters["EyePosition"].SetValue(Matrix.Invert(View).Translation); | |
internalEffect.Parameters["DiffuseColor"].SetValue(DiffuseColor); | |
internalEffect.Parameters["EmissiveColor"].SetValue(EmissiveColor); | |
internalEffect.Parameters["SpecularColor"].SetValue(SpecularColor); | |
internalEffect.Parameters["SpecularPower"].SetValue(SpecularPower); | |
internalEffect.Parameters["LightDirection"].SetValue(LightDirection); | |
internalEffect.Parameters["LightDiffuseColor"].SetValue(LightDiffuseColor); | |
internalEffect.Parameters["LightSpecularColor"].SetValue(LightSpecularColor); | |
internalEffect.Parameters["Time"].SetValue((float)DateTime.Now.TimeOfDay.TotalSeconds); | |
SetParams = true; | |
} | |
return internalEffect; | |
} | |
set | |
{ | |
internalEffect = value; | |
SetParams = false; | |
} | |
} | |
private bool SetParams = false; | |
private Vector3 _lightSpecularColor = new Vector3(1); | |
private Vector3 _lightDiffuseColor = new Vector3(1); | |
private Vector3 _lightDirection = new Vector3(1); | |
private float _specularPower = 1; | |
private Vector3 _specularColor = new Vector3(1); | |
private Vector3 _emissiveColor = new Vector3(1); | |
private Vector4 _diffuseColor = new Vector4(1); | |
private Matrix _projection = Matrix.Identity; | |
private Matrix _view = Matrix.Identity; | |
private Matrix _world = Matrix.Identity; | |
public Vector4 DiffuseColor | |
{ | |
get => _diffuseColor; set | |
{ | |
_diffuseColor = value; | |
SetParams = false; | |
} | |
} | |
public Vector3 EmissiveColor | |
{ | |
get => _emissiveColor; set | |
{ | |
_emissiveColor = value; | |
SetParams = false; | |
} | |
} | |
public Vector3 SpecularColor | |
{ | |
get => _specularColor; set | |
{ | |
_specularColor = value; | |
SetParams = false; | |
} | |
} | |
public float SpecularPower | |
{ | |
get => _specularPower; set | |
{ | |
_specularPower = value; | |
SetParams = false; | |
} | |
} | |
public Vector3 LightDirection | |
{ | |
get => _lightDirection; set | |
{ | |
_lightDirection = value; | |
SetParams = false; | |
} | |
} | |
public Vector3 LightDiffuseColor | |
{ | |
get => _lightDiffuseColor; set | |
{ | |
_lightDiffuseColor = value; | |
SetParams = false; | |
} | |
} | |
public Vector3 LightSpecularColor | |
{ | |
get => _lightSpecularColor; set | |
{ | |
_lightSpecularColor = value; | |
SetParams = false; | |
} | |
} | |
public Matrix Projection | |
{ | |
get => _projection; set | |
{ | |
_projection = value; | |
SetParams = false; | |
} | |
} | |
public Matrix View | |
{ | |
get => _view; set | |
{ | |
_view = value; | |
SetParams = false; | |
} | |
} | |
public Matrix World | |
{ | |
get => _world; set | |
{ | |
_world = value; | |
SetParams = false; | |
} | |
} | |
public static explicit operator Effect(PrimitiveEffect source) | |
{ | |
return source.InternalEffect; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Input; | |
using System; | |
using System.Reflection; | |
using System.Runtime; | |
using System.Runtime.InteropServices; | |
using System.IO; | |
using System.Collections.Generic; | |
using System.Linq; | |
using SharpDX; | |
using SharpDX.D3DCompiler; | |
using SharpDX.Direct3D11; | |
using Buffer = SharpDX.Direct3D11.Buffer; | |
using SharpDX.Direct3D; | |
using SharpDX.DXGI; | |
using Device = SharpDX.Direct3D11.Device; | |
using Utils = GardeningGame.Engine.Scenes.Common.Utils; | |
using GardeningGame.Engine.Scenes.Game.Terrain; | |
namespace Testing_Project | |
{ | |
public static class Ext | |
{ | |
public static void DrawWithGeom(this Water W, GraphicsDevice GD, Vector3 Position, bool UseID, PrimitiveEffect PEffect, GardeningGame.Engine.Scenes.Common.Camera Cam, GeometryShader GS) | |
{ | |
PEffect.World = Cam.worldMatrix * Matrix.CreateTranslation(Position); | |
PEffect.View = Cam.viewMatrix; | |
PEffect.Projection = Cam.projectionMatrix; | |
if (UseID) | |
{ | |
PEffect.InternalEffect.CurrentTechnique = PEffect.InternalEffect.Techniques["Plain"]; | |
PEffect.DiffuseColor = W.ID.ToVector4(); //1, 1, 1 by default | |
} | |
else | |
{ | |
PEffect.InternalEffect.CurrentTechnique = PEffect.InternalEffect.Techniques["Colored"]; | |
//PEffect.DiffuseColor = new Vector4(0.35f, 0.35f, 0.35f, 1); //1, 1, 1 by default | |
PEffect.DiffuseColor = new Vector4(0.192f, 0.192f, 0.192f, 1); //1, 1, 1 by default | |
PEffect.LightSpecularColor = new Vector3(0f); | |
PEffect.SpecularColor = new Vector3(1f); | |
PEffect.SpecularPower = 0.14f; | |
PEffect.LightDirection = new Vector3(1, .71f, 1); | |
PEffect.EmissiveColor = new Vector3(0.125f); | |
} | |
//Utils.PrimitivesEffect.AmbientLightColor = new Vector3(0, .25f, .75f); | |
//Utils.PrimitivesEffect.EmissiveColor = new Vector3(0, 0, 1); | |
//Utils.PrimitivesEffect.SpecularColor = new Vector3(0, .9f, 0.25f); | |
GD.SetVertexBuffer(W.VertexBuffer); | |
PEffect.InternalEffect.CurrentTechnique = PEffect.InternalEffect.Techniques[0]; | |
foreach (EffectPass pass in PEffect.InternalEffect.CurrentTechnique.Passes) | |
{ | |
pass.Apply(); | |
((Device)GD.Handle).ImmediateContext.GeometryShader.Set(GS); | |
((Device)GD.Handle).ImmediateContext.PixelShader.Set(pass._pixelShader._pixelShader); | |
((Device)GD.Handle).ImmediateContext.VertexShader.Set(pass._vertexShader._vertexShader); | |
// assume low-spec DX10 8 regs | |
// Requires enforcement that GS uses same CBuffers at the same registers as the VS, CBuffers the GS doesn't use are A-Okay, shader doesn't care | |
//Buffer[] vsBuffers = ((Device)GD.Handle).ImmediateContext.VertexShader.GetConstantBuffers(0, 8); | |
Buffer[] vsBuffers = PEffect.InternalEffect.ConstantBuffers.Select((a)=>a._cbuffer).ToArray(); | |
if (vsBuffers != null) | |
{ | |
for (int i = 0; i < vsBuffers.Length; ++i) | |
((Device)GD.Handle).ImmediateContext.GeometryShader.SetConstantBuffer(i, vsBuffers[i]); | |
} | |
if (vsBuffers != null) | |
{ | |
for (int i = 0; i < vsBuffers.Length; ++i) | |
((Device)GD.Handle).ImmediateContext.VertexShader.SetConstantBuffer(i, vsBuffers[i]); | |
} | |
if (vsBuffers != null) | |
{ | |
for (int i = 0; i < vsBuffers.Length; ++i) | |
((Device)GD.Handle).ImmediateContext.PixelShader.SetConstantBuffer(i, vsBuffers[i]); | |
} | |
GD.DrawPrimitives(PrimitiveType.TriangleList, 0, W.VertexBuffer.VertexCount / 3); | |
} | |
GD.SetVertexBuffer(null); | |
GD.Indices = null; | |
} | |
} | |
/// <summary> | |
/// This is the main type for your game. | |
/// </summary> | |
public class Game1 : Game | |
{ | |
GardeningGame.Engine.Scenes.Game.GameSceneVariables GSV = new GardeningGame.Engine.Scenes.Game.GameSceneVariables() | |
{ | |
WaterSize = 10 | |
}; | |
GardeningGame.Engine.Scenes.Game.Terrain.Water W = new GardeningGame.Engine.Scenes.Game.Terrain.Water(); | |
GraphicsDeviceManager graphics; | |
SpriteBatch spriteBatch; | |
GardeningGame.Engine.Scenes.Game.GameCam GC = new GardeningGame.Engine.Scenes.Game.GameCam(); | |
public Game1() | |
{ | |
//GraphicsAdapter.UseDebugLayers = true; | |
graphics = new GraphicsDeviceManager(this); | |
graphics.GraphicsProfile = GraphicsProfile.HiDef; | |
Content.RootDirectory = @".\Content"; | |
} | |
GeometryShader GS; | |
PrimitiveEffect peffect = new PrimitiveEffect(); | |
/// <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 | |
IsMouseVisible = true; | |
W.Generate(10, 10, 100, GraphicsDevice); | |
GC.Initialize(GraphicsDevice, 1000, 100, false, 1400); | |
peffect.InternalEffect = Content.Load<Effect>("WaterShader"); | |
var CompiledGS = ShaderBytecode.CompileFromFile(@"Effects\Water\WaterShader.fx", "GeometryShader_", "gs_4_0"); | |
GS = new GeometryShader((Device)GraphicsDevice.Handle, CompiledGS.Bytecode); | |
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); | |
return; | |
} | |
/// <summary> | |
/// UnloadContent will be called once per game and is the place to unload | |
/// game-specific 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) | |
{ | |
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) | |
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.CornflowerBlue); | |
// TODO: Add your drawing code here | |
W.DrawWithGeom(GraphicsDevice, new Vector3(0), false, peffect, GC, GS); | |
base.Draw(gameTime); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//float4 FogVector; | |
//float3 FogColor; | |
cbuffer Data : register(b0) | |
{ | |
float4x4 World; | |
float4x4 WorldViewProj; | |
float3 EyePosition; | |
float3x3 WorldInverseTranspose; | |
float3 LightDirection; | |
float3 LightDiffuseColor; | |
float3 LightSpecularColor; | |
float4 DiffuseColor; | |
float3 EmissiveColor; | |
float3 SpecularColor; | |
float SpecularPower; | |
float Time; | |
float WaveFactor; | |
float WaveLength; | |
}; | |
// Vertex shader output structures. | |
struct VSOutput | |
{ | |
float4 Position : S_POSITION; | |
float4 Color : COLOR; | |
float4 PositionPS : SV_Position; | |
}; | |
struct CommonVSOutput | |
{ | |
float4 Pos_ps; | |
float4 Diffuse; | |
float3 Specular; | |
}; | |
struct LightColorPair | |
{ | |
float3 Diffuse; | |
float3 Specular; | |
}; | |
struct ColorPair | |
{ | |
float4 Diffuse; | |
float3 Specular; | |
}; | |
struct VSInput | |
{ | |
float4 Position : POSITION; | |
float4 Color : COLOR; | |
}; | |
struct GSInput | |
{ | |
float4 Position : S_POSITION; | |
float4 Color : COLOR; | |
}; | |
struct GSOutput | |
{ | |
float4 PositionPS : SV_Position; | |
float4 Diffuse : COLOR0; | |
float3 Specular : COLOR1; | |
}; | |
struct PSInput | |
{ | |
float4 PositionPS : SV_Position; | |
float4 Diffuse : COLOR0; | |
float3 Specular : COLOR1; | |
}; | |
LightColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights) | |
{ | |
// float3x3 lightDirections = 0; | |
// float3x3 lightDiffuse = 0; | |
// float3x3 lightSpecular = 0; | |
// float3x3 halfVectors = 0; | |
// lightDirections[0] = float3x3(LightDirection, DirLight1Direction, DirLight2Direction)[0]; | |
// lightDiffuse[0] = float3x3(DirLight1DiffuseColor, DirLight1DiffuseColor, DirLight2DiffuseColor)[0]; | |
// lightSpecular[0] = float3x3(DirLight0SpecularColor, DirLight1SpecularColor, DirLight2SpecularColor)[0]; | |
// halfVectors[0] = normalize(eyeVector - lightDirections[0]); | |
float3 lightDirection = LightDirection; | |
float3 lightDiffuse = LightDiffuseColor; | |
float3 lightSpecular = LightSpecularColor; | |
float3 halfVectors = 0; | |
halfVectors = normalize(eyeVector - lightDirection); | |
float3 dotL = mul(-lightDirection, worldNormal); | |
float3 dotH = mul(halfVectors, worldNormal); | |
float3 zeroL = step(float3(0, 0, 0), dotL); | |
float3 diffuse = zeroL * dotL; | |
float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower); | |
LightColorPair result; | |
result.Diffuse = mul(diffuse, lightDiffuse) * DiffuseColor.rgb + EmissiveColor; | |
result.Specular = mul(specular, lightSpecular) * SpecularColor; | |
return result; | |
} | |
//float ComputeFogFactor(float4 position) | |
//{ | |
// return saturate(dot(position, FogVector)); | |
//} | |
void AddSpecular(inout float4 color, float3 specular) | |
{ | |
color.rgb += specular * color.a; | |
} | |
CommonVSOutput ComputeCommonVSOutputWithLighting(float4 position, float3 normal, uniform int numLights) | |
{ | |
CommonVSOutput vout; | |
float4 pos_ws = mul(position, World); | |
float3 eyeVector = normalize(EyePosition - pos_ws.xyz); | |
float3 worldNormal = normalize(mul(normal, WorldInverseTranspose)); | |
LightColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights); | |
vout.Pos_ps = mul(position, WorldViewProj); | |
vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a); | |
vout.Specular = lightResult.Specular; | |
return vout; | |
} | |
float generateOffset(float x, float z, float val1, float val2) | |
{ | |
float radiansX = ((((x + z * x * val1) % WaveLength) / WaveLength) + Time * ((x * 0.8f + z) % 1.5f)) * 6.283185307179586476925286766559f; | |
float radiansZ = (((val2 * (z * x + x * z) % WaveLength) / WaveLength) + Time * 2.0f * (x % 2.0f)) * 6.283185307179586476925286766559f; | |
return WaveFactor * 50 * (float) (sin(radiansZ) + cos(radiansX)); | |
} | |
float3 applyDistortion(float3 vertex) | |
{ | |
float xDistortion = generateOffset(vertex.x, vertex.z, 0.2f, 0.1f); | |
float yDistortion = generateOffset(vertex.x, vertex.z, 0.8f, 0.95f); | |
float zDistortion = generateOffset(vertex.x, vertex.z, 0.15f, 0.2f); | |
return vertex + float3(xDistortion * 1.5f, yDistortion * 1.5f, zDistortion * 1.5f); | |
} | |
[maxvertexcount(3)] | |
void GeometryShader_(triangle GSInput input[3], inout TriangleStream<GSOutput> outstream) | |
{ | |
float3 v1 = input[1].Position.xyz - input[0].Position.xyz; | |
float3 v2 = input[2].Position.xyz - input[0].Position.xyz; | |
float3 normal = cross(v1, v2); | |
normalize(normal); | |
GSOutput output; | |
CommonVSOutput cout = ComputeCommonVSOutputWithLighting(input[0].Position, normal, 1); | |
output.PositionPS = cout.Pos_ps; | |
output.Diffuse = cout.Diffuse; | |
output.Specular = cout.Specular; | |
output.Diffuse *= input[0].Color; | |
outstream.Append(output); | |
cout = ComputeCommonVSOutputWithLighting(input[1].Position, normal, 1); | |
output.PositionPS = cout.Pos_ps; | |
output.Diffuse = cout.Diffuse; | |
output.Specular = cout.Specular; | |
output.Diffuse *= input[1].Color; | |
outstream.Append(output); | |
cout = ComputeCommonVSOutputWithLighting(input[2].Position, normal, 1); | |
output.PositionPS = cout.Pos_ps; | |
output.Diffuse = cout.Diffuse; | |
output.Specular = cout.Specular; | |
output.Diffuse *= input[2].Color; | |
outstream.Append(output); | |
} | |
VSOutput VertexShader_(VSInput input) | |
{ | |
VSOutput r; | |
r.Position = float4(applyDistortion(input.Position.xyz), input.Position.w); | |
r.Color = input.Color; | |
r.PositionPS = mul(input.Position, World); | |
return r; | |
} | |
float4 PixelShader_(PSInput pin) : SV_Target | |
{ | |
float4 color = pin.Diffuse; | |
AddSpecular(color, pin.Specular.rgb); | |
return color; | |
} | |
technique T | |
{ | |
pass | |
{ | |
VertexShader = compile vs_4_0 VertexShader_(); | |
PixelShader = compile ps_4_0 PixelShader_(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment