This project is read-only.

Gras Renderer

Jun 28, 2010 at 11:13 AM

Hey there .. I try to bring up a small gras renderer to render gras on my terrain.

i got this classes for now:

 

GEOMETRY:

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 Xen;
using Xen.Ex;
using Xen.Threading;
using Xen.Graphics;
using Xen.Camera;
using Xen.Input;
using Xen.Ex.Material;
using Xen.Ex.Geometry;
using DalesLibrary.Environment.BaseTerrain.TerrainShader;
using DalesLibrary.Shader.TerrainMultiTextureShader;

namespace DalesLibrary.Environment
{
    class GrasGeometrie:IDraw
    {
        IVertices _vertices;
        IIndices _indices;
        struct GrasVertex
        {
            Vector3 Position;
            Vector3 Normal;
            Vector2 TexCoord;
            public GrasVertex(Vector3 pos, Vector3 nor, Vector2 tex)
            {
                Position = pos;
                Normal = nor;
                TexCoord = tex;
            }

        }

        public GrasGeometrie(Vector2 size)
        {
            GrasVertex[] gVertex = new GrasVertex[(int)(size.X * size.Y*8)];
            Random r = new Random();
            int counter = 0;
            for (int x = 0; x < size.X; x++)
            {
                for (int y = 0; y < size.Y; y++)
                {
                    gVertex[counter] = new GrasVertex(new Vector3(x-0.5f,y,0),Vector3.UnitZ,new Vector2(0,1));
                    gVertex[counter+1] = new GrasVertex(new Vector3(x-0.5f,y,1),Vector3.UnitZ,new Vector2(0,0));
                    gVertex[counter+2] =new GrasVertex(new Vector3(x+0.5f,y,1),Vector3.UnitZ,new Vector2(1,0));
                    gVertex[counter+3] = new GrasVertex(new Vector3(x+0.5f,y,0),Vector3.UnitZ,new Vector2(1,1));
                    gVertex[counter+4] = new GrasVertex(new Vector3(x,y-0.5f,0),Vector3.UnitZ,new Vector2(0,1));
                    gVertex[counter+5] = new GrasVertex(new Vector3(x,y-0.5f,1),Vector3.UnitZ,new Vector2(0,0));
                    gVertex[counter + 6] = new GrasVertex(new Vector3(x,y+0.5f,1),Vector3.UnitZ,new Vector2(1,0));
                    gVertex[counter + 7] = new GrasVertex(new Vector3(x,y+0.5f,0),Vector3.UnitZ,new Vector2(1,1));
                    counter += 8;
            
                }
            }
            _vertices = new Vertices<GrasVertex>(gVertex);
            ushort[] ind = new ushort[(int)(size.X * size.Y * 4)];
            for (ushort i = 0; i < size.X * size.Y * 4; i++)
            {
                ind[i] = i;
            }
            _indices = new Indices<ushort>(ind);

        }
        #region IDraw Member

        public void Draw(DrawState state)
        {
            this._vertices.Draw(state, _indices, PrimitiveType.TriangleList);
            
        }

        #endregion

        #region ICullable Member

        public bool CullTest(ICuller culler)
        {
            return true;
        }

        #endregion
    }
}

-------------------------------------------------------

MAINCLASS:
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 Xen;
using Xen.Ex;
using Xen.Threading;
using Xen.Graphics;
using Xen.Camera;
using Xen.Input;
using Xen.Ex.Material;
using Xen.Ex.Geometry;
using DalesLibrary.Environment.BaseTerrain.TerrainShader;
using DalesLibrary.Shader.Gras;

namespace DalesLibrary.Environment
{
    public class SimpleGrasRenderer :IDraw
    {

        private GrasGeometrie _geometry;
        private IShader _shader;
        private Texture2D _attributeMap;
        private Texture2D _terrainTex;
        private Texture2D _grasTex;
        private Matrix worldMatrix;
        #region IDraw Member

        public SimpleGrasRenderer(Texture2D grasTex,Texture2D terrainTex,Texture2D attrMap)
        {
            _geometry = new GrasGeometrie(new Vector2(30, 30));
            _attributeMap = attrMap;
            _terrainTex = terrainTex;
            _grasTex = grasTex;

            GrasShader gShader = new GrasShader();
            gShader.GrasTex = _grasTex;
            _shader = gShader;

        }

        public void Draw(DrawState state)
        {
            state.PushWorldMatrixMultiply(ref worldMatrix);
            Vector3 vecEye=new Vector3();
            state.Camera.GetCameraPosition(out vecEye);
            state.PushRenderState();
            state.RenderState.DepthColourCull.CullMode = CullMode.None;

           // _shader.SetAttribute(state, 4,ref vecEye);

			if (_geometry.CullTest(state))
			{
				//bind the shader
				_shader.Bind(state);

				//draw the custom geometry
				_geometry.Draw(state);
			}

			//always pop the matrix afterwards
            state.PopRenderState();
			state.PopWorldMatrix();
		}

        

        #endregion

        #region ICullable Member

        public bool CullTest(ICuller culler)
        {
            return true;
        }

        #endregion
    }
}

-------------------

SHADER:

float4x4 matWorldViewProj:WORLDVIEWPROJECTION;   
float4x4 matWorld:WORLD; 
float4 vCameraPos;  

texture GrasTex;
texture TerrainTex;
texture AttrTex;

sampler GrasSampler = sampler_state{Texture = ;	MinFilter = Linear;	MagFilter = Linear;	MipFilter = Linear;	AddressU  = Wrap;	AddressV  = Wrap;};
sampler TexSampler = sampler_state{Texture = ;	MinFilter = Linear;	MagFilter = Linear;	MipFilter = Linear;	AddressU  = Wrap;	AddressV  = Wrap;};
sampler AttrSampler = sampler_state{Texture = ;	MinFilter = Linear;	MagFilter = Linear;	MipFilter = Linear;	AddressU  = Wrap;	AddressV  = Wrap;};
struct OUT
{
    float4 Pos	 : POSITION;
    float2 Tex	 : TEXCOORD0;
    float3 Nor : TEXCOORD1;
};
 

OUT VS(float4 Pos : POSITION,float3 N : NORMAL, float2 Tex : TEXCOORD)
{
      OUT Out = (OUT)0; 
     // Pos.xy+=vCameraPos.xy;
      Out.Pos = mul(Pos, matWorldViewProj); // transform Position
      Out.Nor=mul(N,matWorldViewProj);
      Out.Tex = Tex;
      return Out;
}

float4 PS(OUT input) : COLOR
{
float4 Color=tex2D(GrasSampler,input.Tex);
return Color+(1,1,1,1);

}

technique GrasShader
{
    pass P0
    {
        Sampler[0] = (GrasSampler);       
        Sampler[1] = (TexSampler);       
        Sampler[2] = (AttrSampler);      
   
        VertexShader = compile vs_1_1 VS();
        PixelShader  = compile ps_2_0 PS();
    }
}

somehow i cant get it to display something -.-

Its not complete now, later I will add heighmap and stuff to set it at terrains surface and groudn type will influence the grass type.

 

But for now i just want it to display a test gras field :-)

and its refusing to do so ^^

anyone a suggestion ?

Regards floAr

Jun 29, 2010 at 10:42 PM

I'd suggest you do a PIX capture and look at how the geometry is being transformed, etc.

I don't imagine it's a runtime issue, but to be sure, I'd also suggest enable the DX Debug runtime.

You will probably find that it's something fairly simple like the geometry being the same colour as the background, but I can't really see too much in that code that could be causing the geometry to not be visible.