@willmotil wrote:
Im using vs2017 on win7 i have created the same project for the crossplatform template gl and windows dx
So i have a example Instanced DX shader that i have trimmed down to simplify it so i can understand it better. this works under the Dx 4_0 profile with hi def set under the windows template.
However
The same shader under GL 3_0 on hi-def, while it does show a window and it doesn't error or crash ect... Nothing is drawn all i get is a black screen.
Im at a loss as to why ?...
Here is the shader followed by the full code you need a texture to run the example.
,,, the shader ,,
#if OPENGL //#define SV_POSITION POSITION #define VS_SHADERMODEL vs_3_0 #define PS_SHADERMODEL ps_3_0 #else #define VS_SHADERMODEL vs_4_0 #define PS_SHADERMODEL ps_4_0 #endif static const float PI = 3.14159265359; static const float EIGHT_PI = 25.1327412287; float Life; float TotalTime; //int MaxNumOfParticles; //float2 RadiusRange; matrix WorldViewProjection; Texture2D ParticleTexture : register(t0); sampler TexSampler : register(s0); //__________________________________________________________ //__________________________________________________________ struct VSVertexInputSimple { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; //uint InstanceId : SV_InstanceId; }; struct VSInstanceInputSimple { float3 RandomIntervals : POSITION1; float ParticleTime : BLENDWEIGHT0; }; struct VSOutputSimple { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; VSOutputSimple MainVSSimple(in VSVertexInputSimple vertexInput, VSInstanceInputSimple instanceInput) { //VSOutput output = (VSOutput)0; VSOutputSimple output; //= (VSOutput)0; float3 randomIntervals = instanceInput.RandomIntervals; float particleTime = instanceInput.ParticleTime; float timeFraction = fmod((particleTime + TotalTime) / (float)Life, 1.0f); output.Position = vertexInput.Position; output.Position.xy += randomIntervals; output.Position.y += timeFraction * 100; output.Position.z = 0;//vertexInput.InstanceId * 10 / (float)MaxNumOfParticles; output.Position = mul(output.Position, WorldViewProjection); // Set colour of particle using the other two passed-in random intervals float4 endColor = lerp(float4(0.0, 0.5, 1.0, 0.8), float4(1.0, 1.0, 1.0, 0.8), randomIntervals.y); float4 startColor = lerp(float4(1.0, 0.0, 0.0, 0.8), float4(0.3, 0.0, 1.0, 1.0), randomIntervals.z); output.Color = lerp(startColor, endColor, timeFraction); output.Color *= (-4 * pow(timeFraction - 0.5, 2) + 1); output.TexCoord = vertexInput.TexCoord; return output; } float4 MainPSSimple(VSOutputSimple input) : COLOR0 { return input.Color * ParticleTexture.Sample(TexSampler, input.TexCoord); } technique ParticleDrawingSimple { pass P0 { VertexShader = compile VS_SHADERMODEL MainVSSimple(); PixelShader = compile PS_SHADERMODEL MainPSSimple(); } };
,,, the code ,, All the classes and structs have been placed in one cs file for simplicity...
using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.Runtime.InteropServices; namespace Game1 { [StructLayout(LayoutKind.Sequential)] public struct InstanceData : IVertexType { public static readonly VertexDeclaration VertexDeclaration; public Vector3 RandomIntervals; public float Time; VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } } static InstanceData() { var elements = new VertexElement[] { new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), new VertexElement(12, VertexElementFormat.Single, VertexElementUsage.BlendWeight, 0) }; VertexDeclaration = new VertexDeclaration(elements); } } [StructLayout(LayoutKind.Sequential)] public struct VertexData : IVertexType { public static readonly VertexDeclaration VertexDeclaration; public Vector3 Position; public Vector2 TexCoords; VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } } static VertexData() { var elements = new VertexElement[] { new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), }; VertexDeclaration = new VertexDeclaration(elements); } } public class Game1 : Game { GraphicsDeviceManager graphics; ParticleSystem02 particleSystem; Matrix worldViewProj; public Game1() { graphics = new GraphicsDeviceManager(this); graphics.GraphicsProfile = GraphicsProfile.HiDef; graphics.PreferMultiSampling = false; Window.AllowUserResizing = true; // Set the default resolution to be 1024x768 graphics.PreferredBackBufferWidth = 1024; graphics.PreferredBackBufferHeight = 768; Content.RootDirectory = "Content"; } protected override void Initialize() { base.Initialize(); // Setup the worldViewProj matrix float width = GraphicsDevice.PresentationParameters.BackBufferWidth; float height = GraphicsDevice.PresentationParameters.BackBufferHeight; float aspect = width / height; // Create our camera that's looking straight at the center Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 5.0f), Vector3.Zero, Vector3.Up); // Create a projection matrix so that the world dimensions have the same aspect ratio as our window size Matrix projMatrix = Matrix.CreateOrthographic(aspect * 300, 300, 0.1f, 10000); worldViewProj = viewMatrix * projMatrix; } protected override void LoadContent() { Effect particlesEffect = Content.Load<Effect>("ParticleFx02"); Texture2D particleTexture = Content.Load<Texture2D>("particle"); particleSystem = new ParticleSystem02(particlesEffect) { ParticleSize = new Vector2(3.0f, 3.0f), ParticleTexture = particleTexture, Life = 20.0f, EmitRate = 12500, Radius = 180.0f, RadiusDeviation = new Vector2(40.0f, 100.0f), }; particleSystem.RefreshParticleSystemBuffers(GraphicsDevice); } protected override void UnloadContent() { Content.Unload(); } protected override void Update(GameTime gameTime) { base.Update(gameTime); particleSystem.UpdateParticleTime((float)gameTime.ElapsedGameTime.TotalSeconds); if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); } protected override void Draw(GameTime gameTime) { base.Draw(gameTime); GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.Black, 1.0f, 0); GraphicsDevice.BlendState = BlendState.Additive; GraphicsDevice.DepthStencilState = DepthStencilState.Default; particleSystem.DrawParticles(ref worldViewProj, GraphicsDevice); } } class ParticleSystem02 { // Vertex data VertexBuffer vertexBuffer; IndexBuffer indexBuffer; VertexBufferBinding vertexBufferBinding; // Instance data int numInstancesToDraw; InstanceData[] instanceData; VertexBuffer instanceBuffer; VertexBufferBinding instanceBufferBinding; Effect particlesEffect; Vector2 radiusRange; float totalTime = 0; #region Properties public Vector2 ParticleSize { get; set; } public Texture2D ParticleTexture { get; set; } public float Life { get; set; } public uint EmitRate { get; set; } public float Radius { get; set; } public Vector2 RadiusDeviation { get; set; } public int MaxVisibleParticles { get; private set; } #endregion Properties #region Initilisation public ParticleSystem02(Effect effect) { particlesEffect = effect; } public void RefreshParticleSystemBuffers(GraphicsDevice graphicsDevice) { // Create a single quad centered at the origin float halfWidth = ParticleSize.X / 2; float halfHeight = ParticleSize.Y / 2; VertexData[] vertices = new VertexData[4]; vertices[0].Position = new Vector3(-halfWidth, -halfHeight, 0); vertices[1].Position = new Vector3(halfWidth, -halfHeight, 0); vertices[2].Position = new Vector3(-halfWidth, halfHeight, 0); vertices[3].Position = new Vector3(halfWidth, halfHeight, 0); vertices[0].TexCoords = new Vector2(0.0f, 0.0f); vertices[1].TexCoords = new Vector2(1.0f, 0.0f); vertices[2].TexCoords = new Vector2(0.0f, 1.0f); vertices[3].TexCoords = new Vector2(1.0f, 1.0f); vertexBuffer = new VertexBuffer(graphicsDevice, VertexData.VertexDeclaration, 4, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); vertexBufferBinding = new VertexBufferBinding(vertexBuffer); int[] indices = new int[6]; indices[0] = 1; indices[1] = 0; indices[2] = 2; indices[3] = 3; indices[4] = 1; indices[5] = 2; indexBuffer = new IndexBuffer(graphicsDevice, typeof(int), 6, BufferUsage.WriteOnly); indexBuffer.SetData(indices); MaxVisibleParticles = (int)Math.Max(Math.Ceiling(Life * EmitRate), 1); instanceData = new InstanceData[MaxVisibleParticles]; instanceBuffer = new VertexBuffer(graphicsDevice, InstanceData.VertexDeclaration, MaxVisibleParticles, BufferUsage.WriteOnly); instanceBufferBinding = new VertexBufferBinding(instanceBuffer, 0, 1); Random rnd = new Random(); // Initialise our instance buffer for (int i = 0; i < MaxVisibleParticles; ++i) { // instance data float time instanceData[i].Time = -(i + 1) / (float)EmitRate; // instance data float position instanceData[i].RandomIntervals = new Vector3 ( (rnd.Next(0, 300) - 150), -.001f, rnd.Next(0, MaxVisibleParticles + 1) / (float)MaxVisibleParticles ); } instanceBuffer.SetData(instanceData); radiusRange = new Vector2(Radius + RadiusDeviation.X, Radius + RadiusDeviation.Y); } #endregion Initilisation public void UpdateParticleTime(float seconds) { // Potentially, you could adjust the number of // particles rendered based on the time // However, here we're simply using the maximal number numInstancesToDraw = MaxVisibleParticles; // Update the total running time totalTime += seconds; } public void DrawParticles(ref Matrix worldViewProj, GraphicsDevice graphicsDevice) { particlesEffect.CurrentTechnique = particlesEffect.Techniques["ParticleDrawingSimple"]; // Initialise our shader constants particlesEffect.Parameters["WorldViewProjection"].SetValue(worldViewProj); particlesEffect.Parameters["Life"].SetValue(Life); //particlesEffect.Parameters["RadiusRange"].SetValue(radiusRange); //particlesEffect.Parameters["MaxNumOfParticles"].SetValue(MaxVisibleParticles); particlesEffect.Parameters["TotalTime"].SetValue((float)totalTime); particlesEffect.CurrentTechnique.Passes[0].Apply(); // Set textures and buffers graphicsDevice.Textures[0] = ParticleTexture; graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; graphicsDevice.SetVertexBuffers(vertexBufferBinding, instanceBufferBinding); graphicsDevice.Indices = indexBuffer; graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 6, 0, 2, numInstancesToDraw); } } }
Posts: 4
Participants: 2