so I was told to write a code and then post my problem. So I did.
this is the invader shooting code:
Texture2D Background;
Texture2D invader;
Texture2D invaderBullet;
Rectangle rectInvaderBullet;
Rectangle[,] rectInvader;
bool[,] isInvaderAlive;
const int rows = 5;
const int cols = 10;
bool invaderBulletVisible = false;
const int bulletSpeed = 5;
int invaderSpeed = 2;
int invadersAliveCounter;
Update:
`//invader shooting thinking begin
for (int r = 0; r < rows; r++)
for (int c = 0; c < cols; c++)
{
int check = rnd.Next(0, 1000);
if (check < 800 && invaderBulletVisible == false)
{
invaderBulletVisible = true;
rectInvaderBullet.X = rectInvader[r, c].X + (rectInvader[r, c].Width / 2) - (rectInvaderBullet.Width / 2);
rectInvaderBullet.Y = rectInvader[r, c].Y - rectInvaderBullet.Height + 35;
}
if (invaderBulletVisible)
rectInvaderBullet.Y = rectInvaderBullet.Y + bulletSpeed;
}
//invader shooting thinking end`
and this is the draw code:
if (invaderBulletVisible)
spriteBatch.Draw(invaderBullet, rectInvaderBullet, Color.White);
Now of course something is wrong. First off I'm an amatuer and I haven't even finished school but I'm trying my best. Secondly, the bullet isn't even appearing. The bullet isn't even appearing. So basically I want to understand why. And also, how do I make it so that only an invader with no one infront of it can shoot?
Thank you so much in advance!!!
Related
so I'm rewriting my old code for a hydraulic erosion terrain generator, I knew about this problem on my old code but never asked why, but now I'm rewriting it and want to get everything working smoothly
this is the issue on my Z-axis at the edges the terrain has a step up and on the X-axis it goes down but it's hard to see in the photo plz tell me why
I'm using the built-in terrain generator FYI if you need more code just tell me
public void GenerateHeightMap () {
mapSizeWithBorder = mapSize + erosionBrushRadius * 2;
map = FindObjectOfType<HeightMapGenerator> ().GenerateHeightMap (mapSizeWithBorder);
terrain.terrainData = GenerateTerrain(terrain.terrainData);
}
TerrainData GenerateTerrain(TerrainData terrainData) {
Erode();
float[,] noiseMap = new float[mapSizeWithBorder,mapSizeWithBorder];
int x = 0;
int y = 0;
for (int i = 0; i < map.Length; ++i)
{
noiseMap[x, y] = map[i];
y++;
if (y == mapSizeWithBorder)
{
y = 0;
x++;
}
}
terrainData.size = new Vector3(mapSizeWithBorder * scale, elevationScale, mapSizeWithBorder * scale);
terrainData.SetHeights(0, 0, (noiseMap));
return terrainData;
}
So I have been trying to find an answer for this since two days now, i'm still a student and I don't know if couldn't understand the other posts, or if my case is too specific to be solved with anything I found on the internet.
As I said in my title I have a 2D array of class called "piece", anytime I start the game it'll create a 2D array with random rows and columns (to explain quickly the goal is to connect all the pieces to win, you rotate the pieces to make the connections). It was going fine with the OnMouseClick(); function but since I need to use the arrows of my keyboard to archieve this, I'm encountering some troubles.
I've got a function which is generating the puzzle each time I start or reset it (So it's called in Start(); and the Update(); when I'm pressing a "clear" button) which is going like this :
public piece[,] pieces;
public GameObject Cursor;
void GeneratePuzzle()
{
pieces = new piece[width, height];
int[] auxValues = { 0, 0, 0, 0 };
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
//width restrictions
if (w == 0)
auxValues[3] = 0;
else
auxValues[3] = pieces[w - 1, h].values[1];
if (w == width - 1)
auxValues[1] = 0;
else
auxValues[1] = Random.Range(0, 2);
//heigth resctrictions
if (h == 0)
auxValues[2] = 0;
else
auxValues[2] = pieces[w, h - 1].values[0];
if (h == height - 1)
auxValues[0] = 0;
else
auxValues[0] = Random.Range(0, 2);
//tells piece type
int valueSum = auxValues[0] + auxValues[1] + auxValues[2] + auxValues[3];
if (valueSum == 2 && auxValues[0] != auxValues[2])
valueSum = 5;
go = (GameObject)Instantiate(piecesPrefabs[valueSum], new Vector3(origin.position.x + w, origin.position.y, origin.position.z + h), Quaternion.identity);
go.transform.parent = gameObject.transform;
while (go.GetComponent<piece>().values[0] != auxValues[0] ||
go.GetComponent<piece>().values[1] != auxValues[1] ||
go.GetComponent<piece>().values[2] != auxValues[2] ||
go.GetComponent<piece>().values[3] != auxValues[3])
{
go.GetComponent<piece>().RotatePiece();
}
pieces[w, h] = go.GetComponent<piece>();
instantiatedPieces.Add(go.gameObject);
}
}
}
So far I've been trying something like this to make my cursor move in this array :
public void Update()
{
for (int h = 0; h < height; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
for (int w = 0; w < width; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
}
But I end up being out of range or the cursor is so fast I can't see it going over each piece. So to be clear I'd like to be able to move my cursor over each pieces in this 2D array, by row and column (I suppose this is the way to go), after that I'll need to call the function from the piece class for the specific piece my cursor is over but I think I will be able to find this out.
English is not my native language so sorry and I'll try my best if you need any more informations to help me.
Thank you very much any help will be really appreciated !
Here is an example of my comment:
If you want to move a cursor over the elements of your array in update based off of keypress, there is no need for a for loop.
// Declared outside of your update makes these class variables that
// will live as long as this object exists.
int w = 0; // May be better to change this to cursorXPos
int h = 0; // May be better to name this cursorYPos
public void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
w--;
if (w < 0)
w = width -1;
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
w++;
if (w >= width)
w = 0;
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
h--;
if (h < 0)
h = height -1;
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
h++;
if (h >= height)
h = 0;
}
Cursor.transform.position = pieces[w, h].transform.position;
}
I am not sure exactly what you're trying to do with your code but.
I don't get what you're using the following line in update for.
for (int h = 0; h < height; h++)
try removing that line.
try this:
public void Update()
{
for (int h = 0; h < height; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
}
for (int w = 0; w < width; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
or this:
public void Update()
{
for (int h = 0; h < width; h++)
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
h++;
if (h > height)
h = 0;
}
}
for (int w = 0; w < height; w++)
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
w++;
if (w > width)
w = 0;
}
// Cursor.transform.position = pieces[w, h].transform.position; ==> I suppose this is where it should be
}
}
with WindowsForms I would use the KeyDown event and increase/decrease h or w and set them to zero or max when reaching an edge.
I am currently working on a platforming game and I am trying to draw 40 items in one screenstate, but I don't want to hard code them all. Here's what I've tried so far:
Sprite class:
class Sprite
{
//texture, position and color
public Texture2D texture;
public Vector2 position;
public Color color;
}
Definiton:
Sprite levelboxbg;
int LevelBoxX = 20;
Loading:
levelboxbg = new Sprite();
levelboxbg.texture = Content.Load<Texture2D>("LevelBoxBeta");
levelboxbg.position = new Vector2(0, 0);
levelboxbg.color = Color.White;
Execution:
public void DrawLevelBoxes(SpriteBatch spriteBatch)
{
for (int i = 0; i < 10; i++)
{
spriteBatch.Draw(levelboxbg.texture, new Vector2(LevelBoxX + 20 ,0), levelboxbg.color);
LevelBoxX += 20;
}
}
I then call the method in my draw function.
Visual studio has given me 0 errors for this and it will run; however, when I get to the screen where it's supposed to draw the boxes, it draws them all but only for a fraction of a second, then they dissipate.
Any help is greatly appreciated, thank you for taking the time to read this.
Your LevelBoxX goes to infinity, so the boxes are running out of the screen pretty fast. You can reset LevelBoxX just before the for-loop like so:
public void DrawLevelBoxes(SpriteBatch spriteBatch)
{
LevelBoxX = 20;
for (int i = 0; i < 10; i++)
{
spriteBatch.Draw(levelboxbg.texture, new Vector2(LevelBoxX + 20 ,0), levelboxbg.color);
LevelBoxX += 20;
}
}
Or just declare a local variable:
public void DrawLevelBoxes(SpriteBatch spriteBatch)
{
int counter = 20;
for (int i = 0; i < 10; i++)
{
spriteBatch.Draw(levelboxbg.texture, new Vector2(counter + 20 ,0), levelboxbg.color);
counter += 20;
}
}
I have a problem regarding frame rate drop while trying to make real time 3D terrain changes. I use C#, XNA 4.0 and VS 2010. This is my old school project and time has come to finish it.
I already did terrain generation from image file, with all effects and stuff and it is running smoothly no matter what resolution image file is. Problem is with my terrain editor. I want it to be able to manually alter the terrain. I did that part too, but it works only if terrain size is equal or less than 128x128 pixels. If the terrain size is greater I start to get frame rate drops around 150x150 pixels, and it is completely unmanageable if terrain size is greater than 512x512 pixels.
I already tried several approaches:
tried to use threads, but then I get weird error saying something like "Draw method can be called in one thread at a time" or something similar, and that I can't resolve.
next I tried to use DynamicVertexBuffer and DynamicIndexBuffer. That helped a lot and now my code is working with acceptable frame rate for terrain size of up to 256x256 pixels.
Have a look at my code:
public void ChangeTerrain(float[,] heightData)
{
int x, y;
int v = 1;
if (currentMouseState.LeftButton == ButtonState.Pressed && currentMouseState.X < 512)
{
x = (int)currentMouseState.X / 2;
y = (int)currentMouseState.Y / 2;
if (x < 5)
x = 5;
if (x >= 251)
x = 251;
if (y < 5)
y = 5;
if (y >= 251)
y = 251;
for (int i = x - 4; i < x + 4; i++)
{
for (int j = y - 4; j < y + 4; j++)
{
if (i == x - 4 || i == x + 3 || j == y - 4 || j == y + 3)
v = 3;
else
v = 5;
if (heightData[i, j] < 210)
{
heightData[i, j] += v;
}
}
}
}
if (currentMouseState.RightButton == ButtonState.Pressed && currentMouseState.X < 512)
{
x = (int)currentMouseState.X / 2;
y = (int)currentMouseState.Y / 2;
if (x < 5)
x = 5;
if (x >= 251)
x = 251;
if (y < 5)
y = 5;
if (y >= 251)
y = 251;
for (int i = x - 4; i < x + 4; i++)
{
for (int j = y - 4; j < y + 4; j++)
{
if (heightData[i, j] > 0)
{
heightData[i, j] -= 1;
}
}
}
}
if (keyState.IsKeyDown(Keys.R))
{
for (int i = 0; i < 256; i++)
for (int j = 0; j < 256; j++)
heightData[i, j] = 0f;
}
SetUpTerrainVertices();
CalculateNormals();
terrainVertexBuffer.SetData(vertices, 0, vertices.Length);
}
I work with resolution of 1024x512 pixels, so I scale mouse position by 1/2 to get terrain position. I use left and right mouse button to alter terrain, i.e. to alter heightData from which 3D terrain is generated.
Last 3 lines create Vertices from new heightData, calculate Normals so shades could be applied and last line is just throwing Vertices data to Vertex Buffer.
Prior to that, I set up dynamic Vertex and Index buffer in LoadContent method and call initial Vertices and Indices setup. This method (ChangeTerrain) is called from Update method.
I did some debugging and found out that maximum size of vertices in most extreme case would be around 260000 +- few thousands. Is it possible that .SetData is so much time consuming it is causing frame rate drops? Or is it something else? How can I fix that and make my editor functioning normally for any terrain size?
Also, i red that I need to use this code with DynamicVertexBuffer, but I can't make it work in XNA 4.0.
terrainVertexBuffer.ContentLost += new EventHandler(TerrainVertexBufferContentLost);
public void TerrainVertexBufferContentLost()
{
terrainVertexBuffer(vertices, 0, vertices.Length, SetDataOptions.NoOverwrite);
}
Thanks for your help!
EDIT:
This is my SetUpTerrainVertices code:
private void SetUpTerrainVertices()
{
vertices = new VertexPositionNormalColored[terrainWidth * terrainLength];
for (int x = 0; x < terrainWidth; x++)
{
for (int y = 0; y < terrainLength; y++)
{
vertices[x + y * terrainWidth].Position = new Vector3(x, heightData[x, y], -y);
vertices[x + y * terrainWidth].Color = Color.Gray;
}
}
}
And my CalculateNormals
private void CalculateNormals()
{
for (int i = 0; i < vertices.Length; i++)
vertices[i].Normal = new Vector3(0, 0, 0);
for (int i = 0; i < indices.Length / 3; i++)
{
int index1 = indices[i * 3];
int index2 = indices[i * 3 + 1];
int index3 = indices[i * 3 + 2];
Vector3 side1 = vertices[index1].Position - vertices[index3].Position;
Vector3 side2 = vertices[index1].Position - vertices[index2].Position;
Vector3 normal = Vector3.Cross(side1, side2);
vertices[index1].Normal += normal;
vertices[index2].Normal += normal;
vertices[index3].Normal += normal;
}
for (int i = 0; i < vertices.Length; i++)
vertices[i].Normal.Normalize();
}
I set up vertex and index buffers in XNA LoadContent Method using lines:
terrainVertexBuffer = new DynamicVertexBuffer(device, VertexPositionNormalColored.VertexDeclaration, vertices.Length,
BufferUsage.None);
terrainIndexBuffer = new DynamicIndexBuffer(device, typeof(int), indices.Length, BufferUsage.None);
I call ChangeTerrain method from Update and this is how i Draw:
private void DrawTerrain(Matrix currentViewMatrix)
{
device.DepthStencilState = DepthStencilState.Default;
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
effect.CurrentTechnique = effect.Techniques["Colored"];
Matrix worldMatrix = Matrix.Identity;
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["xView"].SetValue(currentViewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xEnableLighting"].SetValue(true);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
device.Indices = terrainIndexBuffer;
device.SetVertexBuffer(terrainVertexBuffer);
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, indices.Length / 3);
}
}
EDIT2:
Ok, I decided to go for your second suggestion and got into some problems. I modified my methods like this:
public void ChangeTerrain(Texture2D heightmap)
{
Color[] mapColors = new Color[256 * 256];
Color[] originalColors = new Color[256 * 256];
for (int i = 0; i < 256 * 256; i++)
originalColors[i] = new Color(0, 0, 0);
heightMap2.GetData(mapColors);
device.Textures[0] = null;
device.Textures[1] = null;
int x, y;
int v = 1;
if (currentMouseState.LeftButton == ButtonState.Pressed && currentMouseState.X < 512)
{
x = (int)currentMouseState.X / 2;
y = (int)currentMouseState.Y / 2;
if (x < 4)
x = 4;
if (x >= 251)
x = 251;
if (y < 4)
y = 4;
if (y >= 251)
y = 251;
for (int i = x-4; i < x+4; i++)
{
for (int j = y-4; j < y+4; j++)
{
if (i == x - 4 || i == x + 3 || j == y - 4 || j == y + 3)
v = 3;
else
v = 5;
if (mapColors[i + j * 256].R < 210)
{
mapColors[i + j * 256].R += (byte)(v);
mapColors[i + j * 256].G += (byte)(v);
mapColors[i + j * 256].B += (byte)(v);
}
heightMap2.SetData(mapColors);
}
}
}
if (currentMouseState.RightButton == ButtonState.Pressed && currentMouseState.X < 512)
{
x = (int)currentMouseState.X / 2;
y = (int)currentMouseState.Y / 2;
if (x < 4)
x = 4;
if (x >= 251)
x = 251;
if (y < 4)
y = 4;
if (y >= 251)
y = 251;
for (int i = x - 4; i < x + 4; i++)
{
for (int j = y - 4; j < y + 4; j++)
{
if (mapColors[i + j * 256].R > 0)
{
mapColors[i + j * 256].R -= 1;
mapColors[i + j * 256].G -= 1;
mapColors[i + j * 256].B -= 1;
}
heightMap2.SetData(mapColors);
}
}
}
if (keyState.IsKeyDown(Keys.R))
heightMap2.SetData(originalColors);
}
Generating flat surface - only once in LoadContent() method:
vertices are assigned only once
private void SetUpTerrainVertices()
{
for (int x = 0; x < terrainWidth; x++)
{
for (int y = 0; y < terrainLength; y++)
{
vertices[x + y * terrainWidth].Position = new Vector3(x, 0, -y);
vertices[x + y * terrainLength].Color = Color.Gray;
}
}
}
Draw method is same as previous, but with one extra line:
effect.Parameters["xTexture0"].SetValue(heightMap2);
also, I made new technique called Editor and it looks like this:
//------- Technique: Editor --------
struct EditorVertexToPixel
{
float4 Position : POSITION;
float4 Color : COLOR0;
float LightingFactor: TEXCOORD0;
float2 TextureColor : TEXCOORD1;
};
struct EditorPixelToFrame
{
float4 Color : COLOR0;
};
EditorVertexToPixel EditorVS( float4 inPos : POSITION, float4 inColor: COLOR, float3 inNormal: NORMAL, float2 inTextureColor: TEXCOORD1)
{
EditorVertexToPixel Output = (EditorVertexToPixel)0;
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
float4 Height;
float4 position2 = inPos;
position2.y += Height;
Output.Color = inColor;
Output.Position = mul(position2, preWorldViewProjection);
Output.TextureColor = inTextureColor;
float3 Normal = normalize(mul(normalize(inNormal), xWorld));
Output.LightingFactor = 1;
if (xEnableLighting)
Output.LightingFactor = saturate(dot(Normal, -xLightDirection));
return Output;
}
EditorPixelToFrame EditorPS(EditorVertexToPixel PSIn)
{
EditorPixelToFrame Output = (EditorPixelToFrame)0;
//float4 height2 = tex2D(HeightSAmpler, PSIn.TextureColor);
float4 colorNEW = float4(0.1f, 0.1f, 0.6f, 1);
Output.Color = PSIn.Color * colorNEW;
Output.Color.rgb *= saturate(PSIn.LightingFactor) + xAmbient;
return Output;
}
technique Editor
{
pass Pass0
{
VertexShader = compile vs_3_0 EditorVS();
PixelShader = compile ps_3_0 EditorPS();
}
}
this code doesn't work because float4 Height is not set. What I wanted to do is to sample texture colors into float4 Height (using Sample), but I can not use sampler in VertexShader. I get error message "X4532 cannot map expression to vertex shader instruction set".
Then, I red that you can use SampleLevel in VertexShader to sample color data and thought I found solution, but I get strange error that is only documented in one Russian blog, but I can't speak or read Russian. Error is: "X4814 unexpected Alias on texture declaration"
Is there a way to sample colors in PixelShader and then pass them to VertexShader?
This could work cos I managed to set float4 Height to various values and it altered vertices height. Problem is, I don't know how to read texture color in VertexShader, or how to pass red texture color data from PixelShader to VertexShader.
EDIT3:
I think I found solution. Was searching the net and found out about tex2Dlod function to use as VertexShader texture sampler. But there are different syntax displayed and I can't make them work.
Can anyone point out on good HLSL literature to learn a bit about HLSL coding. This task seems pretty easy, but somehow, I can't make it to work.
Ok, so I can't offer "real" performance advice - because I haven't measured your code. And measuring is probably the most important part of performance optimisation - you need to be able to answer the questions: "am I slower than my performance target?" and "why am I slower than my target?"
That being said - here are the things that stand out to me as a seasoned developer:
This method (ChangeTerrain) is called from Update method
You should probably consider splitting that method up so that, rather than recreating your data every frame, it only does work when the terrain is actually changed.
vertices = new VertexPositionNormalColored[terrainWidth * terrainLength];
Allocating a new vertices buffer each frame is huge memory allocation (6MB at 512x512). This is going to put a big strain on the garbage collector - and I suspect this is the primary cause of your performance issues.
Given that you're about to set all the data in that array anyway, simply delete that line and the old data in the array will be overwritten.
Better yet, you could leave the data that doesn't change as-is, and only modify the vertices that are actually changed. In much the same way you are doing for heightData.
As part of this, it would be a very good idea to modify CalculateNormals so that, rather than having to rely on the index buffer and going through every triangle, it could calculate the indices of surrounding vertices (that form triangles) for any specific vertex - something you can do because vertices is ordered. Again, kind of like what you're doing for heightData.
terrainVertexBuffer.SetData(vertices, 0, vertices.Length);
This is sending the full 6MB buffer to the GPU. There are versions of SetData that only send a subset of the full buffer to the GPU. You should probably try and use these.
Just remember that each SetData call comes with some overhead, so don't get too granular. It's probably best to have just one call per vertex buffer, even if that means some unmodified parts of the buffer must be sent.
This is probably the only place where "chunking" your terrain would have an significant impact, as it would allow you to specify a tighter region for each SetData call - allowing you to send less unmodified data. (I'll leave figuring out why this is the case as an exercise.)
(You're already using DynamicVertexBuffer, which is good, because this means the GPU will automatically handle the pipeline issues of having its buffer changed on-the-fly.)
Finally, if performance is still an issue, you could consider a different approach entirely.
One example might be to offload the calculation of the geometry to the GPU. You'd convert your heightData to a texture, and use a vertex shader (with a flat grid of vertices as input) to sample that texture and output the appropriate positions and normals.
One big advantage of this approach is that heightData can be a lot smaller (0.25MB at 512x512) than your vertex buffer - that's much less data that the CPU needs to process and send to the GPU.
My code seems to compile okay, but when I try to run it, it hangs very badly.
I've been following along with Riemers XNA tutorial here.
I'm pretty familiar with C#, but an expert by no means. I've had no problems getting any of this to work up to this point, and there are no errors or exceptions being thrown... it just hangs up. I've read on his related forum, where users discussed having other problems, usually relating to typos or code errors, but there's nothing like this in there... everyone seems to be able to run it fine.
Is there something I've done wrong perhaps? The nested for-loop at the bottom seems a bit heavy-handed to me. screenWidth and screenHeight are 500 and 500.
BTW: this is run from the LoadContent override method, so it should only run once as far as I know.
private void GenerateTerrainContour()
{
terrainContour = new int[screenWidth];
for (int x = 0; x < screenWidth; x++)
terrainContour[x] = screenHeight / 2;
}
private void CreateForeground()
{
Color[] foregroundColors = new Color[screenWidth * screenHeight];
for (int x = 0; x < screenWidth; x++)
{
for (int y = 0; y < screenHeight; y++)
{
if (y > terrainContour[x])
foregroundColors[x + y * screenWidth] = Color.Green;
else
foregroundColors[x + y * screenWidth] = Color.Transparent;
fgTexture = new Texture2D(device, screenWidth, screenHeight, false, SurfaceFormat.Color);
fgTexture.SetData(foregroundColors);
}
}
}
Probably something to do with the fact that you're creating 250,000 screen sized textures (holy moly)!
Resource allocation is always heavy - especially when you're dealing with media such as sounds and images.
It seems like you only really need one texture here, try moving fgTexture = new Texture2D(device, screenWidth, screenHeight, false, SurfaceFormat.Color); outside of the loop. Then try moving fgTexture.SetData(foregroundColors); outside of the loop too.
private void CreateForeground()
{
Color[] foregroundColors = new Color[screenWidth * screenHeight];
fgTexture = new Texture2D(device, screenWidth, screenHeight, false, SurfaceFormat.Color);
for (int x = 0; x < screenWidth; x++)
{
for (int y = 0; y < screenHeight; y++)
{
if (y > terrainContour[x])
foregroundColors[x + y * screenWidth] = Color.Green;
else
foregroundColors[x + y * screenWidth] = Color.Transparent;
}
}
fgTexture.SetData(foregroundColors);
}
for (int x = 0; x < screenWidth; x++)
{
for (int y = 0; y < screenHeight; y++)
{
if (y > terrainContour[x])
foregroundColors[x + y * screenWidth] = Color.Green;
else
foregroundColors[x + y * screenWidth] = Color.Transparent;
}
}
foregroundTexture = new Texture2D(device, screenWidth, screenHeight, false, SurfaceFormat.Color);
foregroundTexture.SetData(foregroundColors);
Your issue is on the last two lines. In your loop, you're creating 500 x 500 Texture2D objects, which is slowing you down. Move them outside the for loop.