Jump to content

  • Log In with Google      Sign In   
  • Create Account

Dawoodoz

Member Since 16 Aug 2010
Offline Last Active Nov 11 2014 07:22 AM

Topics I've Started

Particle force shader destroyed by optimization

31 October 2014 - 09:21 AM

I am trying to make 2D particles with full GPU accelleration for both physics and rendering. I have problems when compiling the force shader because the compiler don't recognize adding to a variable that is returned at the end as an output.

 

If I insert a debug line like "if (ParticleIndex.b > 0 || ParticleIndex.a > 0) { return float4(-3.0f, 0.0f, 3.0f, 0.0f); }" to throw the particle spinning to the left if a particle in the back layer is seen then everything works well until the condition is satisfied and throwing the particle spinning to the left. Adding 0 to a variable also changes the behaviour of the compilation so debugging feels like quantum physics where observing changes the behaviour.

 

If I remove the line then all the code that just executed fine and added the result to the Force variable are not even seen in the assembler code.

 

Writing [loop] and [branch] everywhere did not solve the problem. I use HLSL Shader Compiler 9.27.952.3022.


#define ParticleMap_Type tex_0
#define ParticleMap_Pos tex_1
#define ParticleMap_Vel tex_2
#define TileMap tex_3
#define GridMap_Indices tex_4

// TileTypes
#define TT_AIR 0
#define TT_EARTH 1
#define TT_STONE 2
#define TT_WOOD 3

// Collision types
#define CT_NONE 0
#define CT_CENTER 1
#define CT_BACK 2
#define CT_ALL 3

#define MapSize Arg[0].xy

// Constant properties
#define Bounce 0.5f

#define LoopForward(min,var,max) for((var)=(min);(var)<=(max);(var)++)
#define LoopBackward(min,var,max) for((var)=(max);(var)>=(min);(var)--)

#define ScanSize_FixedTile 1

#define ScanSize_Particles 4

// This must be evaluated equally for both particles to give equal and opposite reaction
// 	Collide(A,B) = -Collide(B,A)
void CollideWithParticle(inout float3 Force, in int4 TypeA, in float3 PosA, in float3 VelA, in int2 IndexB) {
	// Get ParticleB's type
	int4 TypeB = round(ParticleMap_Type.Load(int3(IndexB.x, IndexB.y, 0)));
	
	// Check if any layer is in common using bitwise and
	if ((TypeA.g & TypeB.g) != 0) {
		// Get the other data
		float3 PosB = ParticleMap_Pos.Load(int3(IndexB.x, IndexB.y, 0)).xyz;
		float3 VelB = ParticleMap_Vel.Load(int3(IndexB.x, IndexB.y, 0)).xyz;
		
		// Measure the distance
		float Dist = length(PosA - PosB);
		
		// Assume circles of radius 0.5
		//float TotalRadius = 0.5f + 0.5f;
		float TotalRadius = 1.2f; // ¤¤¤¤¤¤¤¤ Pressure test
		
		// Check if the circles are colliding
		if (Dist < TotalRadius) {
			// Measure the pressure
			float Pressure = (TotalRadius - Dist) * 300.0f;
			
			// Calculate the direction of the force
			float2 Direction = normalize(PosA.xy - PosB.xy);
			
			// Add a force
			Force.xy += Direction * Pressure;
		}
	}
}

float4 PS( VS_to_PS input) : SV_Target {
	int PX = int(PixelPos.x);
	int PY = int(PixelPos.y);
	int4 TypeA = round(ParticleMap_Type.Load(int3(PX, PY, 0)));
	
	// Reset force
	float3 Force = float3(0.0f, 0.0f, 0.0f);
	
	if (TypeA.x != TT_AIR) {
		int X;
		int Y;
		
		// Get the particle
		float4 PosA = ParticleMap_Pos.Load(int3(PX, PY, 0));
		float4 VelA = ParticleMap_Vel.Load(int3(PX, PY, 0));
		
		// Get the coordinate of the tile to collide from
		int2 ParticleTile = floor(PosA.xy);
		
		// Get nearby tiles to collide with
		LoopForward(max(0, ParticleTile.x - ScanSize_FixedTile), X, min(MapSize.x - 1, ParticleTile.x + ScanSize_FixedTile)) {
			LoopForward(max(0, ParticleTile.y - ScanSize_FixedTile), Y, min(MapSize.y - 1, ParticleTile.y + ScanSize_FixedTile)) {
				int TileColType = round(TileMap.Load(int3(X, Y, 0)).g);
				if ((TypeA.g & TileColType) != 0) {
					// Start with the most basic collision without intersecting the shapes
					Force.xy += normalize(PosA.xy - float2(X + 0.5f, Y + 0.5f)) * 100.0f;
				}
			}
		}
		
		// Get the location in the grid to search from
		int2 Center = floor((PosA.xy * 2.0f) + 0.5f);
		
		// Get nearby particles to collide with
		int MinX = max(0, Center.x - ScanSize_Particles);
		int MinY = max(0, Center.y - ScanSize_Particles);
		int MaxX = min(MapSize.x * 2, Center.x + ScanSize_Particles);
		int MaxY = min(MapSize.y * 2, Center.y + ScanSize_Particles);
		LoopForward(MinX, X, MaxX) {
			LoopForward(MinY, Y, MaxY) {
				// Get particles from the grid position
				int4 ParticleIndex = GridMap_Indices.Load(int3(X, Y, 0));
				
				// Colliding with front layer particles only works when this line is preventing the compiler from optimizing
				if (ParticleIndex.b > 0 || ParticleIndex.a > 0) { return float4(-3.0f, 0.0f, 3.0f, 0.0f); } // ¤¤¤¤¤¤¤¤
				
				// Find something in the front layer
				if (ParticleIndex.x >= 0) {
					// Do not collide with yourself
					if (ParticleIndex.x != PX || ParticleIndex.y != PY) {
						CollideWithParticle(Force, TypeA, PosA.xyz, VelA.xyz, ParticleIndex.rg);
					}
				}
				
				// Find something in the back layer
				if (ParticleIndex.z >= 0) {
					// Do not bother to read data from the back layer for a center particle
					if (TypeA.g != CT_CENTER) {
						// Do not collide with yourself
						if (ParticleIndex.z != PX || ParticleIndex.w != PY) {
							CollideWithParticle(Force, TypeA, PosA.xyz, VelA.xyz, ParticleIndex.ba);
						}
					}
				}
			}
		}
	}
	
	// Return the new force
	return float4(Force, 0.0f);
}


Displaying an ActiveX component using C99

17 October 2014 - 02:11 PM

I have made a graphics engine that is an MFC ActiveX component and a programming language that is compiling to C99.
Now I want to make a wrapper that allow displaying my graphics engine in full screen to make it easy to create games in the language.

Is there any alternative to the MFC framework that can safely load ActiveX components in C99?

I am not allowed to use any static C library for calling the dynamic library since that would make my language difficult to use. I tried using the LoadModule function from the Windows API once but I could not know if it worked without a way to display it.

DirectX without compiler dependent linking

31 January 2014 - 02:27 PM

Is it possible to use DirectX from C without any linking of static libraries so that the user can easily re-compile generated code from a single source file with any C compiler?


Co-located or non-intrusive spelling suggestions. (Usability survey)

21 January 2014 - 10:03 AM

I am implementing spelling suggestions in my integrated programming environment and need to know how people prefer to have them presented visually.

 

* Co-located spelling suggestions can cause problems when trying to select text behind the drop down list.

* Having the suggestions on the side of the text editor can be less intrusive but can make you loose focus on your code.

 


Alternative to SDL to use with TCC

01 January 2014 - 06:48 AM

I am making a programming langauge that use the "Tiny C Compiler" as one of the backends and I try to find a suitable media layer for games.

I tried using "Simple Direct media Layer 2.0.1" because it was written in C and use the zlib license but it's redefinition of Main made it incompatible with TCC. The version specific workaround looks like a mess that no user of my language would accept. The resulting C code must be directly compatible with almost any C compiler without modifications so that beginners can recompile it.

PARTNERS