private void UpdateMesh(Shader shader) { Mesh mesh = Obj2Mesh.FromObj(Resourcen.suzanne); geometry = VAOLoader.FromMesh(mesh, shader); //per instance attributes var rnd = new Random(12); Func <float> Rnd01 = () => (float)rnd.NextDouble(); Func <float> RndCoord = () => (Rnd01() - 0.5f) * 8.0f; var instancePositions = new Vector3[particelCount]; for (int i = 0; i < particelCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } geometry.SetAttribute(shader.GetAttributeLocation("instancePosition"), instancePositions, VertexAttribPointerType.Float, 3, true); Func <float> RndSpeed = () => (Rnd01() - 0.5f); var instanceSpeeds = new Vector3[particelCount]; for (int i = 0; i < particelCount; ++i) { instanceSpeeds[i] = new Vector3(RndSpeed(), RndSpeed(), RndSpeed()); } geometry.SetAttribute(shader.GetAttributeLocation("instanceSpeed"), instanceSpeeds, VertexAttribPointerType.Float, 3, true); }
public Deferred(IContentLoader contentLoader, Dictionary <Enums.EntityType, DefaultMesh> meshes) { _deferredProgram = contentLoader.Load <IShaderProgram>("deferred.*"); foreach (var meshContainer in meshes) { VAO geometry = VAOLoader.FromMesh(meshContainer.Value, _deferredProgram); if (meshContainer.Value is TBNMesh mesh) { var loc = _deferredProgram.GetResourceLocation(ShaderResourceType.Attribute, TBNMesh.TangentName); geometry.SetAttribute(loc, mesh.Tangent.ToArray(), VertexAttribPointerType.Float, 3); loc = _deferredProgram.GetResourceLocation(ShaderResourceType.Attribute, TBNMesh.BitangentName); geometry.SetAttribute(loc, mesh.Bitangent.ToArray(), VertexAttribPointerType.Float, 3); } _geometries.Add(meshContainer.Key, geometry); } _defaultMap = contentLoader.Load <ITexture2D>("Nvidia.png"); _projectilesGenerationNvidia = new ProjectileGeneration(contentLoader, meshes[Enums.EntityType.NvidiaParticle], Enums.EntityType.NvidiaParticle); _projectilesGenerationRadeon = new ProjectileGeneration(contentLoader, meshes[Enums.EntityType.RadeonParticle], Enums.EntityType.RadeonParticle); _addProjectilesNvidia = new AddWithDepthTest(contentLoader); _addProjectilesRadeon = new AddWithDepthTest(contentLoader); _tesselation = new Tesselation(contentLoader); _addTesselation = new AddWithDepthTest(contentLoader); }
private void UpdateAttributes(IShaderProgram shaderProgram) { //per instance attributes var rnd = new Random(12); float Rnd01() => (float)rnd.NextDouble(); float RndCoord() => (Rnd01() - 0.5f) * 8.0f; var instancePositions = new Vector3[particleCount]; for (int i = 0; i < particleCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instancePosition"), instancePositions, true); float RndSpeed() => (Rnd01() - 0.5f); var instanceSpeeds = new Vector3[particleCount]; for (int i = 0; i < particleCount; ++i) { instanceSpeeds[i] = new Vector3(RndSpeed(), RndSpeed(), RndSpeed()); } geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instanceSpeed"), instanceSpeeds, true); }
private void InitParticles() { //per instance attributes var rnd = new Random(12); float Rnd01() => (float)rnd.NextDouble(); float RndCoord() => (Rnd01() - 0.5f) * 2.0f; for (int i = 0; i < instanceCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instancePosition"), instancePositions, true); #if SOLUTION float RndVelocity() => (Rnd01() - 0.5f) * 0.01f; for (int i = 0; i < instanceCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); instanceVelocity[i] = new Vector3(RndVelocity(), RndVelocity(), RndVelocity()); instanceColor[i] = new Vector3(0.5f) + instancePositions[i] * 0.5f; instanceRotation[i] = Rnd01() * MathHelper.TWO_PI; } geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instanceColor"), instanceColor, true); #endif }
private void UpdateGeometry(Shader shader) { geometry = new VAO(); //generate position arrray on CPU var rnd = new Random(12); Func <float> Rnd01 = () => (float)rnd.NextDouble(); Func <float> RndCoord = () => (Rnd01() - 0.5f) * 2.0f; var positions = new Vector2[pointCount]; for (int i = 0; i < pointCount; ++i) { positions[i] = new Vector2(RndCoord(), RndCoord()); } //copy positions to GPU geometry.SetAttribute(shader.GetAttributeLocation("in_position"), positions, VertexAttribPointerType.Float, 2); //generate velocity arrray on CPU Func <float> RndSpeed = () => (Rnd01() - 0.5f) * 0.1f; var velocities = new Vector2[pointCount]; for (int i = 0; i < pointCount; ++i) { velocities[i] = new Vector2(RndSpeed(), RndSpeed()); } //copy velocities to GPU geometry.SetAttribute(shader.GetAttributeLocation("in_velocity"), velocities, VertexAttribPointerType.Float, 2); }
private void UpdateGeometry(IShaderProgram shaderProgram) { geometry = new VAO(PrimitiveType.Points); //generate position array on CPU var rnd = new Random(12); float Rnd01() => (float)rnd.NextDouble(); float RndCoord() => (Rnd01() - 0.5f) * 2.0f; var positions = new Vector2[pointCount]; for (int i = 0; i < pointCount; ++i) { positions[i] = new Vector2(RndCoord(), RndCoord()); } //copy positions to GPU geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "in_position"), positions, VertexAttribPointerType.Float, 2); //generate velocity arrray on CPU float RndSpeed() => (Rnd01() - 0.5f) * 0.1f; var velocities = new Vector2[pointCount]; for (int i = 0; i < pointCount; ++i) { velocities[i] = new Vector2(RndSpeed(), RndSpeed()) * 10.0f; } //copy velocities to GPU geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "in_velocity"), velocities, VertexAttribPointerType.Float, 2); }
private static VAO CreateMesh(Shader shader) { Mesh mesh = Obj2Mesh.FromObj(Resourcen.suzanne); var vao = new VAO(); vao.SetAttribute(shader.GetAttributeLocation("position"), mesh.positions.ToArray(), VertexAttribPointerType.Float, 3); vao.SetAttribute(shader.GetAttributeLocation("normal"), mesh.normals.ToArray(), VertexAttribPointerType.Float, 3); vao.SetID(mesh.ids.ToArray(), PrimitiveType.Triangles); return vao; }
private static VAO CreateMesh(Shader shader) { Mesh mesh = Meshes.CreateSphere(0.03f, 2); var vao = new VAO(); vao.SetAttribute(shader.GetAttributeLocation("position"), mesh.positions.ToArray(), VertexAttribPointerType.Float, 3); vao.SetAttribute(shader.GetAttributeLocation("normal"), mesh.normals.ToArray(), VertexAttribPointerType.Float, 3); vao.SetID(mesh.ids.ToArray(), PrimitiveType.Triangles); return vao; }
private static VAO CreateMesh(Shader shader) { Mesh mesh = Meshes.CreateSphere(0.03f, 2); var vao = new VAO(); vao.SetAttribute(shader.GetAttributeLocation("position"), mesh.positions.ToArray(), VertexAttribPointerType.Float, 3); vao.SetAttribute(shader.GetAttributeLocation("normal"), mesh.normals.ToArray(), VertexAttribPointerType.Float, 3); vao.SetID(mesh.ids.ToArray(), PrimitiveType.Triangles); return(vao); }
public VisualLevel(IContentLoader contentLoader) { void Add(ElementType elementType, string resourceName, int sliceID) { tileTypes.Add(elementType, new Tuple <string, int>(resourceName, sliceID)); } int slice = 0; Add(ElementType.Floor, "GroundGravel_Grass", slice++); Add(ElementType.Man, "character4", slice++); Add(ElementType.Box, ".Crate_Brown", slice++); Add(ElementType.Goal, "EndPoint_Red", slice++); Add(ElementType.ManOnGoal, "EndPointCharacter", slice++); Add(ElementType.BoxOnGoal, "EndPointCrate_Brown", slice++); Add(ElementType.Wall, "Wall_Beige", slice++); var names = from item in tileTypes select item.Value.Item1; texArray = contentLoader.Load <ITexture2dArray>(names); shdTexColor = contentLoader.Load <IShaderProgram>("texColor.*"); vaoLevelGeometry = new VAO(PrimitiveType.Quads); var quadPos = new Vector2[4] { Vector2.Zero, Vector2.UnitX, Vector2.One, Vector2.UnitY }; var locPosition = shdTexColor.GetResourceLocation(ShaderResourceType.Attribute, "position"); vaoLevelGeometry.SetAttribute(locPosition, quadPos); }
public void SetPointLights(List <PointLight> pointLights) { Vector3[] instPos = new Vector3[pointLights.Count]; Vector4[] instCols = new Vector4[pointLights.Count]; float[] instRadius = new float[pointLights.Count]; float[] instIntensity = new float[pointLights.Count]; Vector4[] instSpecCol = new Vector4[pointLights.Count]; float[] instSpecFact = new float[pointLights.Count]; float[] instSpecIntensity = new float[pointLights.Count]; for (int i = 0; i < pointLights.Count; i++) { instPos[i] = pointLights[i].position; instCols[i] = pointLights[i].lightColor; instRadius[i] = pointLights[i].radius; instIntensity[i] = pointLights[i].intensity; instSpecCol[i] = pointLights[i].specularColor; instSpecFact[i] = pointLights[i].specularFactor; instSpecIntensity[i] = pointLights[i].specularIntensity; } pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instancePosition"), instPos, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceColor"), instCols, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceRadius"), instRadius, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceIntensity"), instIntensity, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceSpecularColor"), instSpecCol, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceSpecularFactor"), instSpecFact, true); pointLightSphere.SetAttribute(GL.GetAttribLocation(pointLightShader.ProgramID, "instanceSpecularIntensity"), instSpecIntensity, true); pointLightAmount = pointLights.Count; }
private void UpdateChunkGeometry(Vector3I position, VoxelMesh mesh) { VAO geometry = VAOLoader.FromMesh(mesh.DefaultMesh, _voxelShader); var loc = _voxelShader.GetResourceLocation(ShaderResourceType.Attribute, "uv3d"); geometry.SetAttribute(loc, mesh.TexCoord3D.ToArray(), OpenGl4.VertexAttribPointerType.Float, 3); loc = _voxelShader.GetResourceLocation(ShaderResourceType.Attribute, "voxelId"); geometry.SetAttribute(loc, mesh.VoxelId.ToArray(), OpenGl4.VertexAttribPointerType.Float, 1); BufferObject amountBuffer = new BufferObject(OpenGl4.BufferTarget.ShaderStorageBuffer); amountBuffer.Set(mesh.MaterialAmount.ToArray(), OpenGl4.BufferUsageHint.StaticCopy); BufferObject idBuffer = new BufferObject(OpenGl4.BufferTarget.ShaderStorageBuffer); idBuffer.Set(mesh.MaterialId.ToArray(), OpenGl4.BufferUsageHint.StaticCopy); if (_chunkGeometrys.ContainsKey(position)) { _chunkGeometrys[position] = geometry; } else { _chunkGeometrys.Add(position, geometry); } if (_amountBuffers.ContainsKey(position)) { _amountBuffers[position] = amountBuffer; } else { _amountBuffers.Add(position, amountBuffer); } if (_idBuffers.ContainsKey(position)) { _idBuffers[position] = idBuffer; } else { _idBuffers.Add(position, idBuffer); } }
public Deferred(IContentLoader contentLoader, Dictionary <Enums.EntityType, DefaultMesh> meshes) { _deferredProgram = contentLoader.Load <IShaderProgram>("deferred.*"); foreach (var meshContainer in meshes) { VAO geometry = VAOLoader.FromMesh(meshContainer.Value, _deferredProgram); if (meshContainer.Value is TBNMesh mesh) { var loc = _deferredProgram.GetResourceLocation(ShaderResourceType.Attribute, TBNMesh.TangentName); geometry.SetAttribute(loc, mesh.Tangent.ToArray(), VertexAttribPointerType.Float, 3); loc = _deferredProgram.GetResourceLocation(ShaderResourceType.Attribute, TBNMesh.BitangentName); geometry.SetAttribute(loc, mesh.Bitangent.ToArray(), VertexAttribPointerType.Float, 3); } _geometries.Add(meshContainer.Key, geometry); } _defaultMap = contentLoader.Load <ITexture2D>("mercury.jpg"); }
public void Render(IEnumerable <IBody> bodies, float time, Transformation3D camera) { GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); if (shaderProgram is null) { return; } var instancePositions = new List <Vector3>(); var instanceScale = new List <float>(); foreach (var body in bodies) { instancePositions.Add(body.Location); instanceScale.Add((float)Math.Pow(body.Mass, 0.33f)); } geometryBody.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instancePosition"), instancePositions.ToArray(), VertexAttribPointerType.Float, 3, true); geometryBody.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "instanceScale"), instanceScale.ToArray(), VertexAttribPointerType.Float, 1, true); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); shaderProgram.Activate(); shaderProgram.Uniform("time", time); shaderProgram.Uniform("camera", camera.CalcLocalToWorldColumnMajorMatrix()); geometryBody.Draw(instancePositions.Count); shaderProgram.Deactivate(); floorShaderProgram.Activate(); floorShaderProgram.Uniform("time", time); floorShaderProgram.Uniform("floorColor", new Vector4(0, .5f, .5f, 1f)); floorShaderProgram.Uniform("camera", camera.CalcLocalToWorldColumnMajorMatrix()); floor.Draw(); floorShaderProgram.Uniform("floorColor", new Vector4(0, 0, 1, 0.5f)); waterCube.Draw(); floorShaderProgram.Deactivate(); GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.DepthTest); }
private static void CreatePerInstanceAttributes(VAO vao, Shader shader) { //per instance attributes var rnd = new Random(12); Func <float> Rnd01 = () => (float)rnd.NextDouble(); Func <float> RndCoord = () => (Rnd01() - 0.5f) * 2.0f; var instancePositions = new Vector3[particelCount]; for (int i = 0; i < particelCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } vao.SetAttribute(shader.GetAttributeLocation("instancePosition"), instancePositions, VertexAttribPointerType.Float, 3, true); Func <float> RndSpeed = () => (Rnd01() - 0.5f) * 0.1f; var instanceSpeeds = new Vector3[particelCount]; for (int i = 0; i < particelCount; ++i) { instanceSpeeds[i] = new Vector3(RndSpeed(), RndSpeed(), RndSpeed()); } vao.SetAttribute(shader.GetAttributeLocation("instanceSpeed"), instanceSpeeds, VertexAttribPointerType.Float, 3, true); }
public MainVisual(IRenderState renderState, IContentLoader contentLoader) { renderState.Set(new ClearColorState(1, 1, 1, 1)); renderState.Set(BoolState <IDepthState> .Enabled); renderState.Set(BoolState <IBackfaceCullingState> .Enabled); envMap = contentLoader.Load <ITexture2D>("beach"); envMap.WrapFunction = TextureWrapFunction.MirroredRepeat; envMap.Filter = TextureFilterMode.Linear; sphereTex = contentLoader.Load <ITexture2D>("hatefield1"); sphereTex.WrapFunction = TextureWrapFunction.MirroredRepeat; sphereTex.Filter = TextureFilterMode.Linear; shaderProgram = contentLoader.Load <IShaderProgram>("envMapping.*"); var sphere = Meshes.CreateSphere(1, 4); var envSphere = sphere.SwitchTriangleMeshWinding(); var refSphere = Meshes.CreateSphere(.1f, 4).Transform(new Translation3D(new Vector3(-.1f, 0, 0))); var refractSphere = Meshes.CreateSphere(.1f, 4).Transform(new Translation3D(new Vector3(.1f, 0, 0))); geometry = VAOLoader.FromMesh(envSphere, shaderProgram); geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "specularity"), new[] { 0.0f }, VertexAttribPointerType.Float, 1, true); geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "translucency"), new[] { 0.0f }, VertexAttribPointerType.Float, 1, true); geometry.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "refractionIndex"), new[] { 1.0f }, VertexAttribPointerType.Float, 1, true); geometryRef = VAOLoader.FromMesh(refSphere, shaderProgram); geometryRef.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "specularity"), new[] { .2f }, VertexAttribPointerType.Float, 1, true); geometryRef.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "translucency"), new[] { 0.0f }, VertexAttribPointerType.Float, 1, true); geometryRef.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "refractionIndex"), new[] { 1.0f }, VertexAttribPointerType.Float, 1, true); geometryRefract = VAOLoader.FromMesh(refractSphere, shaderProgram); geometryRefract.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "specularity"), new[] { .0f }, VertexAttribPointerType.Float, 1, true); geometryRefract.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "translucency"), new[] { 1.0f }, VertexAttribPointerType.Float, 1, true); geometryRefract.SetAttribute(shaderProgram.GetResourceLocation(ShaderResourceType.Attribute, "refractionIndex"), new[] { 1.6f }, VertexAttribPointerType.Float, 1, true); }
private static void CreatePerInstanceAttributes(VAO vao, Shader shader) { //per instance attributes var rnd = new Random(12); Func<float> Rnd01 = () => (float)rnd.NextDouble(); Func<float> RndCoord = () => (Rnd01() - 0.5f) * 2.0f; var instancePositions = new Vector3[particelCount]; for (int i = 0; i < particelCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } vao.SetAttribute(shader.GetAttributeLocation("instancePosition"), instancePositions, VertexAttribPointerType.Float, 3, true); //todo: students: add per instance attribute speed here //var locInstSpeed = shader.GetAttributeLocation("instanceSpeed"); }
private void UpdateGeometry(Shader shader) { Mesh mesh = Meshes.CreateSphere(0.03f, 2); geometry = VAOLoader.FromMesh(mesh, shader); //per instance attributes var rnd = new Random(12); Func <float> Rnd01 = () => (float)rnd.NextDouble(); Func <float> RndCoord = () => (Rnd01() - 0.5f) * 2.0f; var instancePositions = new Vector3[instanceCount]; for (int i = 0; i < instanceCount; ++i) { instancePositions[i] = new Vector3(RndCoord(), RndCoord(), RndCoord()); } geometry.SetAttribute(shader.GetAttributeLocation("instancePosition"), instancePositions, VertexAttribPointerType.Float, 3, true); //todo students: add per instance attribute speed here }
public void UpdateTransforms(Dictionary <Enums.EntityType, Matrix4x4[]> transforms) { _trianglesGeometry.SetAttribute(_projectileGenerationProgram.GetResourceLocation(ShaderResourceType.Attribute, "transform"), transforms[_triangleType], true); }
public void SetInstancePositions(Vector3[] positions) { deferredMesh.SetAttribute(deferredShader.GetResourceLocation(Zenseless.HLGL.ShaderResourceType.Attribute, "instancePosition"), positions, true); lightViewMesh.SetAttribute(lightViewShader.GetResourceLocation(Zenseless.HLGL.ShaderResourceType.Attribute, "instancePosition"), positions, true); shadowMapMesh.SetAttribute(shadowMapShader.GetResourceLocation(Zenseless.HLGL.ShaderResourceType.Attribute, "instancePosition"), positions, true); }
List <GameObject> GetSphereSampleScene() { List <GameObject> goList = new List <GameObject>(); DefaultMesh plane = Meshes.CreatePlane(10, 10, 10, 10).Transform(Transformation.Translation(new Vector3(0, -1f, 0))); VAO planeMesh = VAOLoader.FromMesh(plane, renderer.GetPBRShader()); GameObject planeGO = new GameObject(); PBRMaterial planemat = new PBRMaterial(); planemat.albedoColor = new Vector3(1); planemat.roughness = 1; planemat.metal = 0; planeGO.mesh = planeMesh; planeGO.material = planemat; //goList.Add(planeGO); //return goList; int gridSize = 7; float sphereSize = 0.1f; float spacing = sphereSize + sphereSize * 2f; float startX = gridSize / 2 * spacing; Vector3 startVector = new Vector3(startX, startX, 0); float paramSteps = 1.0f / gridSize; string texPrefix = "rustediron2_"; ITexture2D albedoText = contentLoader.Load <ITexture2D>(texPrefix + "basecolor.png"); ITexture2D metallicText = contentLoader.Load <ITexture2D>(texPrefix + "metallic.png"); ITexture2D normalText = contentLoader.Load <ITexture2D>(texPrefix + "normal.png"); ITexture2D roughnessText = contentLoader.Load <ITexture2D>(texPrefix + "roughness.png"); DefaultMesh mesh = contentLoader.Load <DefaultMesh>("uvSphere").Transform(Transformation.Scale(0.1f)); //DefaultMesh mesh = Meshes.CreateSphere(sphereSize, 2); VAO geom = VAOLoader.FromMesh(mesh, renderer.GetPBRShader()); TangentSpaceData tangentData = GetTangentSpaceData(mesh.Position, mesh.TexCoord); int tangentLocation = renderer.GetPBRShader().GetResourceLocation(ShaderResourceType.Attribute, "tangent"); int biTangentLocation = GL.GetAttribLocation(renderer.GetPBRShader().ProgramID, "biTangent"); geom.SetAttribute(tangentLocation, tangentData.tangent); geom.SetAttribute(biTangentLocation, tangentData.biTangent); for (int i = 0; i < gridSize; i++) { Vector3 tmpStart = startVector; for (int j = 0; j < gridSize; j++) { GameObject go = new GameObject(); go.transform.position = tmpStart; go.material.metal = i * paramSteps; go.material.roughness = j * paramSteps; go.material.albedoColor = new Vector3(1, 0, 0); go.mesh = geom; /* * go.material.albedoMap = albedoText; * go.material.metallicMap = metallicText; * go.material.normalMap = normalText; * go.material.roughnessMap = roughnessText; */ goList.Add(go); tmpStart.X -= spacing; } startVector.Y -= spacing; } return(goList); }