Jump to content

  • Log In with Google      Sign In   
  • Create Account

EnlightenedOne

Member Since 02 Jul 2009
Offline Last Active Aug 28 2014 12:25 PM

#5171014 Raising the Deferred Depth Buffer Reconstruction Bar

Posted by EnlightenedOne on 01 August 2014 - 07:18 PM

Hi All,

 

I am a seasoned DX Developer and having scoured the web for decent deferred shader approaches I am trying to adapt samples from the web to the forsaken tongue smile.png

 

Deferred Rendering Tutorials I have seen:

In my attempt to port the last sample (based on the Second-Depth Anti-Alias sample) I get world space wrapped inside the light. Clearly the primary fault is that the inverse view projection is invalid (this was the worst number of artifacts I could generate rotating around a cube).

glitch.jpg

I intentionally have a very well rounded light sphere to make the distortions clear.

 

Provided I can get the basics like a world space position I can write beautiful shaders, I am struggling to get this point of reference and without it I feel about 2cm tall.

 

Because I want this to be available for everyone (I hate the lack of GL sample code!) here is what I have so far (apologies that there is no sample app):

 

GeomVertShader:

#version 330

in vec3 inPos;
in vec2 inUV;
in vec3 inNormal;
in vec3 inBinormal;
in vec3 inTangent;

uniform mat4 wvpMatrix;

out vec4 mWVPPosition;
out vec3 pNormal;
out vec3 pBinormal;
out vec3 pTangent;
out vec2 texCoord;

void main(void) {
mWVPPosition = wvpMatrix * vec4(inPos, 1.0f);
gl_Position = mWVPPosition;

pNormal = inNormal;
pBinormal = inBinormal;
pTangent = inTangent;

    texCoord = inUV;
}

GeomFragShader

#version 330

in vec4 mWVPPosition;
in vec3 pNormal;
in vec3 pBinormal;
in vec3 pTangent;
in vec2 texCoord;

uniform mat4 wvpMatrix;

uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
uniform sampler2D heightTexture;
uniform sampler2D specularTexture;

layout (location = 0) out vec4 colourOut;   
layout (location = 1) out vec4 normalOut;


void main(void) {

vec3 bump = 2 * texture(normalTexture, texCoord).xyz -1;

vec3 normal = pTangent * bump.x + pBinormal * bump.y + pNormal * bump.z;
normal = normalize(normal);

colourOut = texture( diffuseTexture, texCoord );
    // specular intensity
    vec3 specularSample = texture( specularTexture, texCoord ).xyz;
    colourOut.w = ( specularSample.x + specularSample.y + specularSample.z ) / 3;

    normalOut.xyz = normal;
    normalOut.w = 1;
}

PointLightVertShader

#version 330

in vec3 inPos;
in vec2 inUV;

uniform mat4 wvpMatrix;
uniform mat4 ivpMatrix;
uniform vec2 zBounds;
uniform vec3 camPos;
uniform float invRadius;

uniform vec3 lightPos;
uniform vec3 lightColour;
uniform float lightRadius;
uniform float lightFalloff;

out vec4 mWVPPosition;

void main(void) {

	vec3 position = inPos;

	position *= lightRadius;
	position += lightPos;

	mWVPPosition = wvpMatrix * vec4(position, 1.0f);
	gl_Position = mWVPPosition;
}

PointLightFragShader

#version 330

in vec4 mWVPPosition;

uniform mat4 wvpMatrix;
uniform mat4 ivpMatrix;
uniform vec2 zBounds;
uniform vec3 camPos;
uniform float invRadius;

uniform vec3 lightPos;
uniform vec3 lightColour;
uniform float lightRadius;
uniform float lightFalloff;

uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
uniform sampler2D depthTexture;

layout (location = 0) out vec4 colourOut;

void main(void) {

	vec2 UV = mWVPPosition.xy;
	
	float depth = texture(diffuseTexture, UV).x;

	vec3 addedLight = vec3(0,0,0);

	//if (depth >= zBounds.x && depth <= zBounds.y) 
	{
		
		vec4 diffuseTex = texture(diffuseTexture, UV);
		vec4 normal = texture(normalTexture, UV);

		// Screen-space position
		vec4 cPos = vec4(UV, depth, 1);
		
		// World-space position
		vec4 wPos = ivpMatrix * cPos;
		vec3 pos = wPos.xyz / wPos.w;

		// Lighting vectors
		vec3 lVec = (lightPos - pos) * invRadius;
		vec3 lightVec = normalize(lVec);
		vec3 viewVec = normalize(camPos - pos);

		// Attenuation that falls off to zero at light radius
		float atten = clamp(1.0f - dot(lVec, lVec), 0.0, 1.0);
		atten *= atten;

		// Lighting
		float colDiffuse = clamp(dot(lightVec, normal.xyz), 0, 1);
		float specular_intensity = diffuseTex.w * 0.4f;
		float specular = specular_intensity * pow(clamp(dot(reflect(-viewVec, normal.xyz), lightVec), 0.0, 1.0), 10.0f);

		addedLight = atten * (colDiffuse * diffuseTex.xyz + specular);
	}

	colourOut = vec4(addedLight.xyz, 1);
}

Note that for the moment I am totally ignoring the optimisation of "if (depth >= zBounds.x && depth <= zBounds.y)" because I want to crack the basic reconstruction before experimenting with this.

 

Shader Binding:

		Matrix4f inverseViewProjection = new Matrix4f();

		Vector3f camPos = cameraController.getActiveCameraPos();
		
		GL20.glUniform3f(shader.getLocCamPos(), camPos.x, camPos.y, camPos.z);
		
		inverseViewProjection = cameraController.getActiveVPMatrixInverse();
		
		//inverseViewProjection = inverseViewProjection.translate(new Vector3f(-1f, 1f, 0));
		//inverseViewProjection = inverseViewProjection.scale(new Vector3f(2, -2, 1));
		
		inverseViewProjection = inverseViewProjection.scale(new Vector3f(1f/engineParams.getDisplayWidth(), 1f/engineParams.getDisplayHeight(), 1));
		
		GL20.glUniformMatrix4(shader.getLocmIVPMatrix(), false, OpenGLHelper.getMatrix4ScratchBuffer(inverseViewProjection));
		
		float nearTest = 0, farTest = 0;
		
		Matrix4f projection = new Matrix4f(cameraController.getCoreCameraProjection());
		
		GL20.glUniformMatrix4(shader.getLocmWVP(), false, OpenGLHelper.getMatrix4ScratchBuffer(cameraController.getActiveViewProjectionMatrix()));
		
		Vector2f zw = new Vector2f(projection.m22, projection.m23);
		
		//Vector4f testLightViewSpace = new Vector4f(lightPos.getX(), lightPos.getY(), lightPos.getZ(), 1);
		
		//testLightViewSpace = OpenGLHelper.columnVectorMultiplyMatrixVector((Matrix4f)cameraController.getActiveCameraView(), testLightViewSpace);
		
		// Compute z-bounds
		Vector4f lPos = OpenGLHelper.columnVectorMultiplyMatrixVector(cameraController.getActiveCameraView(), new Vector4f(lightPos.x, lightPos.y, lightPos.z, 1.0f));
		float z1 = lPos.z + lightRadius;

		//if (z1 > NEAR_DEPTH)
		{
			float z0 = Math.max(lPos.z - lightRadius, NEAR_DEPTH);

			nearTest = (zw.x + zw.y / z0);
			farTest = (zw.x + zw.y / z1);

			if (nearTest > 1) {
				nearTest = 1;
			} else if (nearTest < 0) {
				nearTest = 0;
			}
			
			if (farTest > 1) {
				farTest = 1;
			} else if (farTest < 0) {
				farTest = 0;
			}
			
			GL20.glUniform3f(shader.getLocLightPos(), lightPos.getX(), lightPos.getY(), lightPos.getZ());
			GL20.glUniform3f(shader.getLocLightColour(), lightColour.getX(), lightColour.getY(), lightColour.getZ());
			GL20.glUniform1f(shader.getLocLightRadius(), lightRadius);
			GL20.glUniform1f(shader.getLocInvRadius(), 1f/lightRadius);
			GL20.glUniform1f(shader.getLocLightFalloff(), lightFalloff);
			
			GL20.glUniform2f(shader.getLocZBounds(), nearTest, farTest);
		}

The line "inverseViewProjection = cameraController.getActiveVPMatrixInverse();" depends on the multiplied result of the inverse of these two:

 

View Matrix

	public void updateViewMatrix(Matrix4f coreViewMatrix) {
		
 		Matrix4f.setIdentity(coreViewMatrix);
		
 		if (lookAtVector.length() != 0) {
 			lookAtVector.normalise();
 		}
		Vector3f.cross(up, lookAtVector, right);
		if (right.length() != 0) {
			right.normalise();
		}
		Vector3f.cross(lookAtVector, right, up);
		if (up.length() != 0) {
			up.normalise();
		}
		
		coreViewMatrix.m00 = right.x;
		coreViewMatrix.m01 = up.x;
		coreViewMatrix.m02 = lookAtVector.x;
		coreViewMatrix.m03 = 0;
		
		coreViewMatrix.m10 = right.y;
		coreViewMatrix.m11 = up.y;
		coreViewMatrix.m12 = lookAtVector.y;
		coreViewMatrix.m13 = 0;
		
		coreViewMatrix.m20 = right.z;
		coreViewMatrix.m21 = up.z;
		coreViewMatrix.m22 = lookAtVector.z;
		coreViewMatrix.m23 = 0;
		
		//Inverse dot from eye position
		coreViewMatrix.m30 = -Vector3f.dot(eyePosition, right);
		coreViewMatrix.m31 = -Vector3f.dot(eyePosition, up);
		coreViewMatrix.m32 = -Vector3f.dot(eyePosition, lookAtVector);
		coreViewMatrix.m33 = 1;
	}

Projection Matrix:

	public static void createProjection(Matrix4f projectionMatrix, float fov, float aspect, float znear, float zfar) {

		float scale = (float) Math.tan((Math.toRadians(fov)) * 0.5f) * znear;
	    float r = aspect * scale;
	    float l = -r;
	    float t = scale;
	    float b = -t;
		
		projectionMatrix.m00 = 2 * znear / (r-l);
		projectionMatrix.m01 = 0;
		projectionMatrix.m02 = 0;
		projectionMatrix.m03 = 0;

		projectionMatrix.m10 = 0;
		projectionMatrix.m11 = 2 * znear / (t-b);
		projectionMatrix.m12 = 0;
		projectionMatrix.m13 = 0;

		projectionMatrix.m20 = (r + l) / (r-l);
		projectionMatrix.m21 = (t+b)/(t-b);
		projectionMatrix.m22 = -(zfar + znear) / (zfar-znear);
		projectionMatrix.m23 = -1;

		projectionMatrix.m30 = 0;
		projectionMatrix.m31 = 0;
		projectionMatrix.m32 = -2 * zfar * znear / (zfar - znear);
		projectionMatrix.m33 = 0;
	}

 

TLDR:

Please help me diagnose what is wrong with the lighting from the picture/code above, my holy grail is a working sample of true depth reconstruction in OpenGL preferably to world space.




#5148353 Deferred Depth Reconstruction

Posted by EnlightenedOne on 20 April 2014 - 08:46 AM

My goodness it worked!

 

VERTEX

#version 330
 
in vec3 inPos;
in vec4 inCol;
//model being tested has no normals yet
 
uniform mat4 inverseProjectionMatrix;
 
uniform mat4 wvpMatrix;
uniform mat4 modelViewMatrix;
 
out vec3 pass_colour;
out vec4 worldPosition;
out float depth;
 
const float far_plane_distance = 15000.0f;
 
void main(void) {
gl_Position = wvpMatrix * vec4(inPos, 1);
 
worldPosition = gl_Position;
 
vec4 viewSpacePos = modelViewMatrix * vec4(inPos, 1);
 
depth = viewSpacePos.z / - far_plane_distance;
 
pass_colour = inCol.xyz;
}
 
 
FRAGMENT
 
#version 330
 
in vec3 pass_colour;
in vec4 worldPosition;
in float depth;
 
layout (location = 0) out vec4 ColourOut;   
layout (location = 1) out vec4 NormalOut;
layout (location = 2) out vec4 PosOut;     
 
void main(void) {
ColourOut = vec4(pass_colour, 1);
NormalOut = vec4(0.5,0.5,0.5,1); //dummy values please ignore
 
PosOut.xyz = worldPosition.xyz; //intending to use this to compare to the reconstructed positions as soon as I have either working smile.png
PosOut.w = 1;
gl_FragDepth = depth;
}

 

Then just sampling the depth:

    d = texture2D(texture_depth, pass_texCoord).x;
  DepthOut = vec4(d, d, d, 1.0);
 
My old linearisation from none linear depth buffer approach when using this is redundant as the depth texture is linear. Following on from his approach I expect I will get the desired view space positions necessary to get around.
 
I dug out this:
 
It suggests what I am doing is a recipe for performance disaster, however "gl_Position.z = viewSpacePos.z / - far_plane_distance;" simply causes depth testing to fail.
 
Interestingly but obviously I get less close banding from the none linear depth calculation, reconstructing linear depth without storing it must be the way forward.
 
I am about to find out if I stick with post GBuffer linear depth reconstruction can I still reconstruct the surface position using Yours3!f's method? more challenging will be to get the viewDir from this data.



#4873886 Migrating to GLKit Skybox Effect not working.

Posted by EnlightenedOne on 18 October 2011 - 06:44 AM

No one has read this and I have solved it after realising the skybox was using the vertex data from a model built after itself.

I just had to add a call to glBindVertexArrayOES(0); after drawing the skybox.

I do wish the delete thread button was reinstated for these embarrassing moments :P


#4873857 Migrating to GLKit Skybox Effect not working.

Posted by EnlightenedOne on 18 October 2011 - 06:15 AM

Hey all,

I have been migrating from OGLES2 Oolong to GLKit

Has anyone got a GLKSkyboxEffect to work? I am keen for an example of what people plug into the transforms, I have very little to go on.

Here is all code relating to the skybox effect.

glkSkyShader = [[GLKSkyboxEffect alloc] init];

glkSkyShader.textureCubeMap.name = [uzEngineState getVolWeather]->getCubeTexture(i);
[glkSkyShader setCenter:GLKVector3Make(0, 0,0)];
[glkSkyShader setXSize:SKYBOXSIZE];
[glkSkyShader setYSize:SKYBOXSIZE];
[glkSkyShader setZSize:SKYBOXSIZE];

Draw Loop:

glkSkyShader.transform.projectionMatrix = GLKMatrix4MakePerspective((float)CAMERAFOV, (float)460/(float)320, (float)1, (float)10);

glkSkyShader.transform.modelviewMatrix = GLKMatrix4MakeLookAt(3, 1, 0, 0, 0, 0, 0, -1, 0);

[glkSkyShader prepareToDraw];

[glkSkyShader draw];

Is there something you have to bind before you draw it? The resulting mess of pixels looks vaguely like a view frustum/one of my models. Below is the skybox and the model it looks like. The textures shown are from Oolong engine I do not own them.

screenshot.jpg

Thanks
EnlightenedOne


#4859010 Assigning classes

Posted by EnlightenedOne on 08 September 2011 - 06:05 AM

Thank you both for your replies, rip-off how does one disable the rich text editor, is it a part of game dev or IE? There certainly are some odd values in there, to clarify they allow users to select and drag images around a touch screen and when they release the images they slide about. I didn't include all the functions in the image because I couldn't easily do so. I like to include a string stream and string so that if I thread my classes and the classes have an integer that flags if they are okay any function can generate an error and any none threaded class can flag to its parent class that it has failed. In this instance its so any failing functions can just use the value to add to the string indicating how many things have gone wrong and in what context the error was collected by higher level objects. It always gives greater insight into the bugs :)

Textures should never be copied and should rarely ever contact anything but pointers, the copying happens before they are loaded, what is copied is their location on disk.

I wanted to randomise the array of images just so when the AI grabs an image to do a wrong or right move (in one of the games on the touchscreen) the AI does not select images in the same order every time. The do right or wrong move functions return false if the AI already has an image or no image is free to own, I did not want the function to have a probability of selecting an image so making the AI pick random images otherwise would have required an elaborate picking mechanism, implementing a shuffle required significantly less code and works a treat.

With Hodgmans example I was able to create a means of copying the image class I will not forget the rule of three, thank you for making me a more able c++ programmer.


#4858988 Assigning classes

Posted by EnlightenedOne on 08 September 2011 - 04:41 AM

Hello,

I am attempting to assign a copy of one of my classes to another copy of the same type so I can shuffle an array of this class.

First question, is there a special keyword that tells c++ compilers when copying a class to ignore a classmember such as a string stream or a Direct X texture pointer?

Second question, how does one overload an assignment operator in a way that allows members to be ignored?

Final question when are they going to fix this forums ability to show code!!!!! some irony in that copying fails here too. I cant even navigate my own post because the text cursor doesn't always decide to update (IE9)!


[font="Consolas"][size="2"][font="Consolas"][size="2"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]class

[/color][/size][/font]

[/color][/size][/font]

[/color][/size][/font][font="Consolas"][font="Consolas"][size="2"] ImageClass[/size][/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"] {

[/size][/font][/size][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]public

[/color][/size][/font]

[/color][/size][/font]

[/color][/size][/font][font="Consolas"][font="Consolas"][size="2"]:[/size][/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Default constructor needs to set these values.[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    ImageClass();

 

    ~ImageClass();

[/size][/font][/size][/font]    std::string getLastErrorMessage();

[/size][/font][/size][/font][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"][font="Consolas"][size="2"][color="#0000ff"]private

[/color][/size][/font]

[/color][/size][/font]

[/color][/size][/font][font="Consolas"][font="Consolas"][size="2"]:[/size][/font][/font]

[font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Every class has these to allow extraction of errors.[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    std::stringstream strStrError;

    std::string strError;

    

[/size][/font]

[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolImageLive;[/font][/font][/size]

[font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolCatagoryImage;[/font][/font][/size]

[font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]bool[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] boolCategoryImageOverlaid; [/font][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"]//Used to draw the category image as pulsating when overlaid[/color][/font][/color][/font][/color][/font][/size]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//Set by the game logic when starting up the scene[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    std::string strImageDir;

    std::string strImageFormatlessName;

    

[/size][/font]

[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//The image width and height is taken from the texture the position X and Y is in screen space as all drawing is set[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    

[/size][/font]

[/size][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"]//to run in screen space.[/color][/size][/font][/color][/font][/color][/font]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    

[/size][/font]

[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]float[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] fltCenterPosX, fltCenterPosY, fltPreviousPosX, fltPreviousPosY, fltVelocityX, fltVelocityY;[/font][/font][/size]

[font="Consolas"][size="2"][font="Consolas"][size="2"]     

[/size][/font]

[/size][/font][size="2"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"][font="Consolas"][color="#0000ff"]int[/color][/font][/color][/font][/color][/font][font="Consolas"][font="Consolas"] intWidth, intHeight, intImageOwner, intImageCatagory, intLastImageOwner; [/font][/font][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][color="#008000"]//Last image owner allows for inertia into category.[/color][/font][/color][/font][/color][/font][/size]

[font="Consolas"][color="#008000"][font="Consolas"][color="#008000"][font="Consolas"][size="2"][color="#008000"][/color][/size][/font][/color][/font][/color][/font][font="Consolas"][size="2"][font="Consolas"][size="2"]    IDirect3DTexture9* pd3dImageTexture;

};

[/size][/font][/size][/font]


Posted Image


struth

I enjoy learning by example and have no idea how to get an assignment operator to ignore a variable I believe a class constructor copy hack might be plausible but I do not know the syntax.

This is what I want to do.
for (int i = 0; i < (MAXIMAGESPERLIBRARY - 1); i++) {

std::tr1::uniform_int <
int> unifintGenWidth(0, MAXIMAGESPERLIBRARY - i);

int intRandomFree = i + unifintGenWidth(mtRandGenerator);

ImageClass icTemp = icImages[i];

icImages[i] = icImages[intRandomFree];

icImages[r] = icTemp;

}


That is genuinley what it looks like AFTER I attempted to clean up all the broken formatting, I hope it is legible. I cant just use pointers to images because I need to actually move the memory, the textures are not initialised at this point so dont panic about any impact on Direct X, I have found a work around to copying the image I can randomise the selection process using the same for loop. I still want to know how you fix the problem of having classes with string stream in them, most of my classes do for ease in my error handling technique.


#4795270 Unit Testing in C++

Posted by EnlightenedOne on 06 April 2011 - 05:43 PM

So far we have established that the functionality exists in a convoluted form and there is no rapid implementation available, there is perhaps no benefit from implementing boost tests in order to check values are equal. I might aswell completely write out my own function for each method which just runs every function and identifies the outputs validity completely from scratch. In fact that is exactly what I will have to do. I was only reiterating exactly what MSDN had told me in relation to the lack of plausibility for unit testing unmanaged code, I even had a reference pointing to something which implictly stated that unmanaged code and unit tests were not going to fly.

To clarify I do not want someone to do anything in my project for me, I find that particularly insulting I am (well was/am) concerned/insulted by the poor quality of support for what should be a normal functionality in any language when reflecting on the ease of functionality provided for basically all other languages in all APIs. I never used the terminology "doomed" although I am in a squeeze and while I am aware that unit testing is usually something you would perform as you develop it would easily over double the development time for this project because as my understanding of the components I am modifying has evolved so has the architecture I have used in an Agile fashion.

It is inefficient to start with debugging when your doing something that is going to evolve and go through essentially paradigm shifts. A prime example is learning that direct x resources are exclusive to their creating threads and that the direct x device must be initialised from the same thread as the thread which created the windows window it renders in. I had to alter the entire operation of multiple threaded classes to change the engine and make that work, It would have been a waste of maybe a hundred hours development if I had unit tested those unworkable classes. In a scenario where I started the project with the knowledge I have now and everything was less volatile I would certainly start with unit testing as I now have the prinicple understanding as to how to use the components I am using. It remains a fact that I am better off unit testing now as its good practice to have unit tests in place when you are confident the fundamental architecture for a project is sound. The unit tests are actually part of my own requirements for my project submitted in my last interim report I have done unit testing in other simpler projects/languages but in this case I had to prototype and the prototype evolved into something stable and worth unit testing.

Unit testing is not pixie dust neither is having the capacity to run unit tests which show failed or succeeded, how hard would it have been to have used the functionality that generates a class diagram to generate a class full of stubs for unit testing based on the classes I have in use autonamously, probably about as hard as it is to generate stub c# unit test cases as it already does. It is something I do expect as a standard for any language and while the capacity does exist to integrate unit testing through seperate third parties or reptitive "manual" labour my opinion of Visual Studio has been greatly smacked by this time delay.

I have decided unit testing becomes a lot less valuable when it consumes time and you already have error handling code to flag anomalies that are not obvious from the visual/audio/physics behaviour. With the time cost added from the lack of stub generation and the need to produce an entirely new project unit testing right now seems a massively cost inefficient additional burden. From my understanding now I have to produce a new project dependent on my engines project and produce a set of unit test sets that are just as likely to fail silently as the actual project when being run. Perhaps I will use the std string library to state no tests failed... what if I generate an error in the thing that registers the error handling is working properly? I guess that is why the third party libraries exist. Still seems like laziness on VS part wasting developers time. I do have to argue it might be faster to test my own tester than attempt to process the huge scope of components involved in the unit tester boost provides, as a library it is of collossul proportions.

That (last paragraph mainly) is my argument with this forum and why I have been angry I have not misunderstood unit testing as a magical concept, everyone has stigmatised my perception of unit tests and failed to acknowledge how many man hours VS have wasted by causing all these deviations of libraries that perform unit testing to manifest. Not to mention all the additional time everyone else has to spend learning how to use them, its unfathomably massive. You cannot argue with that its pretty solid logic :P

Anyway we are done now thank you for routing me to the behemoth unit testing libraries I will now have to make a selection from in order to proceed. I hope you have come to gain some insight in that I am not whining for the sake of pixie dust in unit testing but for the sake of fundamental practices existing on an API commercially worth roughly a grand. I will not look for a new API when I am done getting myself out of the mess I have been dropped in by this unfortunate lack of foresight on both my side and my API's side because no other API comes close. If you know an API that provides this base functionality off the bat for C++ I might transfer in order to perform unit tests and I would love to hear about it, if not we are done here and you can wish me luck or debate the validity of my argument on unit testing an evolving prototype before its stable :)




#4795029 Unit Testing in C++

Posted by EnlightenedOne on 06 April 2011 - 07:25 AM

Here is evidence that I am not going to get a fair trial for unit testing http://msdn.microsoft.com/en-us/library/ms243171.aspx no C++ libraries appear to be managed hence the errors I was being thrown earlier trying to use any libraries. Simply put I just found out what /clr does (ish) I am fresh out of university and the idea of any language not having unit testing capacity in it is moronic. Now I have shot myself in the foot in that I planned to do unit testing in my reports and I have no functionality that will enable me to do so therefore I have been skrewed by a technicality. I don't even know how to turn /clr behaviour on.

So in short I would have to use an external library to get some simple behaviour.


#4686769 2D "pathfinding" at prehistoric levels

Posted by EnlightenedOne on 03 August 2010 - 10:27 PM

I shall answer those questions as best as I can.

Quote:

what if one would like pixel-based movement in a maze, where walls are just lines (thus not equal sized to sprites).


There are many ways to solve collision issues the important thing to recognise is the scope you need collisions to happen on, I would say it was beyond the depth of the first game you builds needs but there are things to look up.

One other thing to take note of is that per pixel collisions are almost never the way to go its a brute force means of solving a problem that can be handled more elegantly without a great reduction in precision and if you do it right none. If your using python and no specific API to draw to the screen then the odds are you may stress the CPU doing all the calculations for collisions this way.

The two things I would recommend you search for instead of per pixel collisions are Axis Aligned Bounding Boxes (AABB as its commonly known) where you use the size of a box surrounding even a detailed object to calculate if two objects overlap, the beauty of this one is if you expand the size of the AABB you can use the detection of an overlap to make two objects be tested more precisely (such as for a per pixel collision or any other algorithms you use together).

The most common solution to making a 2D and or 3D world have collisions (I am studying the 3D version now) is Seperating Axis Theorum (SAT as it is more commonly known). With this you can create a series of lines that map the shape of a sprites edges and you can use these to detect collisions through a means of testing for a gap between the two objects for lack of a shorter description :p

Usually collisions represent a tradeoff, where bruteforce means cost you cpu cycles and elegant means cost you time and provide limitations, I always find the more elegant solutions are the way to go. The limitation of SAT is that all objects you test for collisions between must be convex in shape any concave areas will be treated as collisions without using an expansion on the algorithm, there are several beyond my scope here.

Quote:

Getting screen pixels and checking for a WALLCOLOR could come into my mind.

-But what if the walls have textures (ie of several colors)?

You would test for if the edges have any colour that is not your background colour. If you have a background made up of lots of colours then you could draw the two sprites with relative co-ordinates to each other offscreen. You can have a default colour for a background offscreen so you can detect an overlap, however there is probably a faster route than that to take.

Ordinarily unless you have alpha in your images you use one colour value out of the r,g,b spectrum (usually a strong pink) to represent a transparent pixel this is why alot of sprites you can search for on google will have a funny coloured background to them, that is the colour you cannot see in the game, implementing this depends on your API.

Quote:

How should AI sprites move among lines?


The best way to do AI if your using random sizes of walls is too create a group of nodes with links between them and attach a weighting to the link between every node. Then you can decide the AI wants to go toward one node from whatever node they are at and they can follow a linear path there without passing any lines(the destination can be updated based on the players distance to a node. To implement that I would recommend you research "Dijkstra's" algorithm its a fast efficient and more importantly simple (after you stare the code for afew hours ;p) algorithm once you wrap your head around it you will love it. An alternative method is A* path finding although I believe that one is harder to implement as I have never implemented it I can't go into depth on it.

Quote:

should I give up game programming 4ever? :(

No, start simple and build up your knowledge and skill. I recommend if you want to make games as a hobby start learning OpenGL or DirectX so you can build up toward 3D and beyond. If your not feeling confident enough to ignore the stop signs along the way and keep trying to make a game then you wont get far, so goodluck!



#4686480 2D "pathfinding" at prehistoric levels

Posted by EnlightenedOne on 03 August 2010 - 08:46 AM

If your using equally sized tiles to create an isometric (flat-ish) world and you want to have an easy place to start off making a game use an array to manage the world. It is not massively flexible but pacman is not coo complex for such an approach. I did something very similar to build my first game bomberman!. The best part about using an array is the ease with which you can draw the world using two for loop.

I cant find a screenshot of how I did things :( but to make up for it here is some psuedocode, well I say pseudo code its snippets of visual basic 6 :p

I can't garuntee its flawlessly written because I wrote it when I was 13 so apologise for spelling mistakes.

The basic premise is that you create a two dimensional array of positions and then cycle through the array changing the values of the arrays cells in order to define what is where in the world. The beauty of it is in rendering becuase everything is the same size theres a neat trick you can use!


Private Sub Level1()

'Set level Walls

ReDim LevelWalls(1 To 19, 1 To 19) As Byte

'Set Level Walls horizontal edges
For SetWalls1 = 1 To 19
LevelWalls(SetWalls1, 1) = 2
Next SetWalls1

For SetWalls2 = 1 To 19
LevelWalls(SetWalls2, 19) = 2
Next SetWalls2

'Set level Walls Vertical edges
For SetWalls3 = 1 To 19
LevelWalls(1, SetWalls3) = 2
Next SetWalls3

For SetWalls4 = 1 To 19
LevelWalls(19, SetWalls4) = 2
Next SetWalls4

'Gametype
GameType = "TeamGame"

'Set Levels Personal Features ----------------------------------------------

Dim XSetIncWall As Byte
Dim YSetIncWall As Byte

Dim TerrainSetup1 As Byte
Dim TerrainSetup2 As Byte
Dim TerrainSetup3 As Byte
Dim TerrainSetup4 As Byte

Dim ProbabilityOfBrick As Byte

'Randomly sets up bricks
YSetIncWall = 2

'You dont need to modify the edges because you always make them an impassible block using a loop.
For TerrainSetup1 = 2 To 18
XSetIncWall = 2
For TerrainSetup2 = 2 To 18
Randomize
ProbabilityOfBrick = Rand(1, 5)
If ProbabilityOfBrick = "1" Or ProbabilityOfBrick = "2" Or ProbabilityOfBrick = "3" Or ProbabilityOfBrick = "4" Then
LevelWalls(XSetIncWall, YSetIncWall) = 1
End If
XSetIncWall = XSetIncWall + 1
Next TerrainSetup2
YSetIncWall = YSetIncWall + 1
Next TerrainSetup1

'Sets up LevelBlocks

YSetIncWall = 3

For TerrainSetup3 = 1 To 8
XSetIncWall = 3
For TerrainSetup4 = 1 To 8
LevelWalls(XSetIncWall, YSetIncWall) = 2
XSetIncWall = XSetIncWall + 2
Next TerrainSetup4
YSetIncWall = YSetIncWall + 2
Next TerrainSetup3

'Clears player locations/Defaults of blocks ----------------------------------------------

LevelWalls(2, 2) = 0
LevelWalls(2, 3) = 0
LevelWalls(3, 2) = 0

LevelWalls(18, 18) = 0
LevelWalls(18, 17) = 0
LevelWalls(17, 18) = 0

LevelWalls(2, 18) = 0
LevelWalls(2, 17) = 0
LevelWalls(3, 18) = 0

LevelWalls(18, 2) = 0
LevelWalls(17, 2) = 0
LevelWalls(18, 3) = 0

'Create Player Starts

Person(1).X_Pos = 2
Person(1).Y_Pos = 2
Person(1).PlayerColour = "RedBomberSprite"

Person(2).X_Pos = 18
Person(2).Y_Pos = 18
Person(2).PlayerColour = "BlueBomberSprite"

Person(3).X_Pos = 2
Person(3).Y_Pos = 18
Person(3).PlayerColour = "GreenBomberSprite"

Person(4).X_Pos = 18
Person(4).Y_Pos = 2
Person(4).PlayerColour = "YellowBomberSprite"

'Set Players Exhistance/Prepare Motion Function for a player (Makes them optional)

PlayerControlsEnable 1
PlayerControlsEnable 2
PlayerControlsEnable 3
PlayerControlsEnable 4

End Sub




This is not something to copy and paste obviously but just shows you that you can tamper with the grid all you like before you start. Here is the sweet part, take notice of the value "GridSize" (belowin the drawing pesudo code) that can be the size of your sprites. If you make it the size of your sprites then do another for loop and multiply the position of the image with the number of times you have gone through both loops (making up x and y values) you can create a square or rectangular grid. You can use different integer values in the array to make different textures be drawn onto your grid.



Private Sub RenderFloorArray()

'Pointers for All Arrays Refreshing
XIncrement = 1
YIncrement = 1

'Loops
Dim XWallDisplay As Integer
Dim YWallDisplay As Integer

'DrawAllRectangles
For XWallDisplay = 1 To 19
YIncrement = 1
For YWallDisplay = 1 To 19

Select Case LevelWalls(XIncrement, YIncrement)
Case 0
DrawTexture FloorSprite, (XIncrement * GridSize), (YIncrement * GridSize)
Case 2
DrawTexture BlockSprite, (XIncrement * GridSize), (YIncrement * GridSize)
End Select

YIncrement = YIncrement + 1
Next YWallDisplay
XIncrement = XIncrement + 1
Next XWallDisplay

End Sub





Then you can use If statements to test if a player can move in a direction, because the outside layer is always made impassible (I used the integer value of 2 to represent a solid block) you can bypass the worry of having an exception because you had to test if the player could move down beyond the scope of the array. Obviously you can draw goodies and ghosts over the sprites making the terrain (I used a sperate array for goodies back in the day but a linked list is definetely the most efficient method you could try). If your new to programming games its a great place to start!

Make sure you store your players seperate from the grids values, you can draw them overlaying it afterward. If you make them part of the grid then you can't smooth over the animation when they jump between cells and you also have the trouble that you cant have them move over varying tiles with different terrain!

P.S. Apologise for my example code using such an old language I hope you can understand it! (the key thing to grasp is the arrays and use of for loops to draw) :p


PARTNERS