Some Triangles are Disapearing with IndexBuffer

Started by
2 comments, last by Bacterius 11 years, 10 months ago
Hello Everybody!

I had a bug few hours ago and I solved it without knowing how to smile.png .


88866365.jpg

I am using VertexBuffer and IndexBuffer, it's not the first time that I am using them, but this time I was forced to use DynamicIndexBuffer with some frustrating trial & error.

It stays about 1 second right then everything goes wrong.

With DrawUserIndexedPrimitives it works nice (but slower), DynamicIndexBuffer works nice and just with IndexBuffer it's what happens in the picture.

I know that using DynamicIndexBuffer is slower, but do have any choice? What is happening?

It seems like gpu memory corruption.

Thanks ;-)
Advertisement
this is the effect file:


struct VertexToPixel
{
float4 Position : POSITION;
float2 TextureCoords : TEXCOORD1;
float4 Position3D : TEXCOORD2;
float4 Normal3D : TEXCOORD3;
float Texture[3] : TEXCOORD4;
};
//------- Constants --------
float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;
float3 xLightDirection;
float xAmbient;
float3 xCameraPosition;
float xFogStart;
float xFogEnd;
float xFogEnabled;
float4 xFogColor;
float2 xWaterPosition;
//------- Texture Samplers --------
Texture xTexture0,xNormal0; // WATER
Texture xTexture1,xNormal1; // SAND
Texture xTexture2,xNormal2; // GRASS
sampler TextureSampler[3]{
{ texture = <xTexture0>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;},
{ texture = <xTexture1>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;},
{ texture = <xTexture2>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;}
};
sampler NormalSampler[3]{
{ texture = <xNormal0>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;},
{ texture = <xNormal1>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;},
{ texture = <xNormal2>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;}
};
//-----------------------------------------------------------------------------
// Compute fog factor
//-----------------------------------------------------------------------------
float ComputeFogFactor(float d){
return clamp((d - xFogStart) / (xFogEnd - xFogStart), 0, 1) * xFogEnabled;
}

//------- Technique: Terrain --------
VertexToPixel MultiTextureVS( float4 inPos : POSITION, float3 inNormal: NORMAL, float2 coord : TEXCOORD,short tex : COLOR){
VertexToPixel Output = (VertexToPixel)0;

// === USE THIS FOR PHONG ===
Output.Normal3D = mul(inNormal, xWorld);
Output.Position3D = mul(inPos, xWorld);
// === MATRIX AND TRANSFORMS ===
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
Output.Position = mul(inPos, preWorldViewProjection);
// === TEXTURE COORDINATES ===
Output.TextureCoords = coord;
// === TEXTURED VERTEX ===
if(tex==0) Output.Texture[0] = 1;
if(tex==1) Output.Texture[1] = 1;
if(tex==2) Output.Texture[2] = 1;
return Output;
}
//------- Technique: Water --------
VertexToPixel WaterVS( float4 inPos : POSITION, float3 inNormal: NORMAL,float2 coord : TEXCOORD){
VertexToPixel Output = (VertexToPixel)0;
// === USE THIS FOR PHONG ===
Output.Normal3D = mul(inNormal, xWorld);
Output.Position3D = mul(inPos, xWorld);
// aldrabating
inPos.y = 0;
// === MATRIX AND TRANSFORMS ===
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
Output.Position = mul(inPos, preWorldViewProjection);
// === TEXTURE COORDINATES ===
Output.TextureCoords = coord + xWaterPosition;
Output.Texture[0] = 1;
return Output;
}

float4 MultiTexturePS(VertexToPixel Input) : COLOR {
float4 Color = (float4)0;
float3 tex2DNormal= (float3) 0;
float NdotL, rotH, rotV;
float3 normalVector;
// === MULTI-TEXTURE SPLATING ===
if(Input.Texture[0]){ Color += tex2D(TextureSampler[0], Input.TextureCoords)*Input.Texture[0]; tex2DNormal += tex2D(NormalSampler[0], Input.TextureCoords)*Input.Texture[0]; }
if(Input.Texture[1]){ Color += tex2D(TextureSampler[1], Input.TextureCoords)*Input.Texture[1]; tex2DNormal += tex2D(NormalSampler[1], Input.TextureCoords)*Input.Texture[1]; }
if(Input.Texture[2]){ Color += tex2D(TextureSampler[2], Input.TextureCoords)*Input.Texture[2]; tex2DNormal += tex2D(NormalSampler[2], Input.TextureCoords)*Input.Texture[2]; }
// === READ NORMAL MAP ===
tex2DNormal = tex2DNormal*2.0-1.0;
normalVector = normalize(float3(tex2DNormal.x, tex2DNormal.z,tex2DNormal.y));
normalVector = normalize(normalVector + Input.Normal3D);
// === DO DIRTY JOB ===
Color.rgb *= saturate(dot(normalVector, -xLightDirection)) + xAmbient;
float fogFactor = ComputeFogFactor(length(xCameraPosition - Input.Position3D));
float3 eyeVector = normalize(xCameraPosition - Input.Position3D);
float3 reflectionVector = reflect(-xLightDirection ,normalVector);
NdotL = dot(normalize(reflectionVector), normalize(eyeVector));
if(NdotL<0){
float specular = pow(NdotL, 16);
Color.rgb += specular*0.2;
}
Color.rgba = lerp(Color.rgba, xFogColor, fogFactor);
return Color;
}


technique ERATech
{
pass Pass0
{
VertexShader = compile vs_3_0 MultiTextureVS();
PixelShader = compile ps_3_0 MultiTexturePS();
}
pass Pass1
{
VertexShader = compile vs_3_0 WaterVS();
PixelShader = compile ps_3_0 MultiTexturePS();
}
}


this is my vertex declaration:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ERA_XNA.Core
{
public struct VertexMultiTexture : IVertexType
{
public Vector3 Position, Normal, Tangent, Binormal;
public Vector2 TextureCoordinate;
public short TextureID;

public static readonly Random _rand = new Random();
VertexDeclaration IVertexType.VertexDeclaration
{
get { return VertexDeclaration; }
}
public VertexMultiTexture(Vector3 position, Vector3 normal, Vector2 coordinates, short tex, Vector3 tangent, Vector3 binormal)
{
TextureID = tex;
Position = position;
Normal = normal;
TextureCoordinate = coordinates;
Tangent = tangent;
Binormal = binormal;
}
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration(
new VertexElement(sizeof(float) * 0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementUsage.Normal,0),
new VertexElement(sizeof(float) * 6, VertexElementFormat.Vector3, VertexElementUsage.Tangent,0),
new VertexElement(sizeof(float) * 9, VertexElementFormat.Vector3, VertexElementUsage.Binormal,0),
new VertexElement(sizeof(float) * 12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate,0),
new VertexElement(sizeof(float) * 14, VertexElementFormat.Short2, VertexElementUsage.Color,0)
);
}
}


and where I create Buffers:


// INIT BUFFER
_vertexBuffer = new VertexBuffer(graphics,VertexMultiTexture.VertexDeclaration, _vertices.Length, BufferUsage.WriteOnly);
// SEND VERTEXS TO BUFFER
_vertexBuffer.SetData<VertexMultiTexture>(_vertices);
// INIT BUFFER

// if _indexBuffer = new DynamicIndexBuffer(...) it works, why?

_indexBuffer = new IndexBuffer(graphics,IndexElementSize.ThirtyTwoBits, pos, BufferUsage.WriteOnly);
// SEND INDEXS TO BUFFER
_indexBuffer.SetData<int>(_indices);


btw, the "normalVector = normalize(normalVector + Input.Normal3D);" in my Pixel Shader is wrong, given Binormal and Tangent what should I do now do have normal map working correctly?
Good news! I solved the problem!


"public short TextureID ;" && "new VertexElement(sizeof (float)*14,VertexElementFormat.Short2,VertexElementUsage.Color,0)"



I changed short to int and there is no problem now!
But I think int is too big for a textureID

But I think int is too big for a textureID

GPU's have a hard time dealing with odd types like short/bool and prefer when data is aligned properly, especially in highly regular structures like vertex arrays, so unless you have a really good reason to optimize this I wouldn't worry about it too much. Remember that premature optimization isn't a good habit to have - just make it work first, make it work fast later.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement