-
|
|
|
I set the world matrix to Matrix.Identity and point the camera at 0,0,0, I see nothing at all! Hopefully someone can point out my error.
Also, I know a lot the content of this class doesn't follow good coding conventions (e.g. member variables being exposed) but it's very temporary, I'm just trying to get it to work first.
And if you have any ideas for better terrain handling (so it's more seamless or so I can load more at once), please let me know! I see these games with huge amounts of terrain being rendered yet they have an excellent frame-rate and play seamlessly. I don't know how they do it. Does it have to do with using effects files to offload all the work to the GPU? And if so, how difficult is it to write a good terrain handling script?
This is my terrain class:
| 1 |
using System; |
| 2 |
using System.Collections.Generic; |
| 3 |
using System.Text; |
| 4 |
using Microsoft.Xna.Framework.Graphics; |
| 5 |
using Microsoft.Xna.Framework; |
| 6 |
using Microsoft.Xna.Framework.Content; |
| 7 |
using System.Diagnostics; |
| 8 |
|
| 9 |
namespace GameClient |
| 10 |
{ |
| 11 |
public class Terrain |
| 12 |
{ |
| 13 |
public static int TileSize = 128; |
| 14 |
|
| 15 |
public struct Water |
| 16 |
{ |
| 17 |
private float height; |
| 18 |
|
| 19 |
public Water(float height) |
| 20 |
{ |
| 21 |
this.height = height; |
| 22 |
} |
| 23 |
|
| 24 |
public float Height |
| 25 |
{ |
| 26 |
get { return this.height; } |
| 27 |
set { this.height = value; } |
| 28 |
} |
| 29 |
} |
| 30 |
|
| 31 |
public struct CenterTile |
| 32 |
{ |
| 33 |
private int x; |
| 34 |
private int y; |
| 35 |
|
| 36 |
public CenterTile(int x, int y) |
| 37 |
{ |
| 38 |
this.x = x; |
| 39 |
this.y = y; |
| 40 |
} |
| 41 |
|
| 42 |
public int X |
| 43 |
{ |
| 44 |
get { return this.x; } |
| 45 |
} |
| 46 |
|
| 47 |
public int Y |
| 48 |
{ |
| 49 |
get { return this.y; } |
| 50 |
} |
| 51 |
|
| 52 |
public bool Equals(CenterTile obj) |
| 53 |
{ |
| 54 |
return (obj.X == this.X && obj.Y == this.Y); |
| 55 |
} |
| 56 |
} |
| 57 |
|
| 58 |
public struct VertexMultitextured |
| 59 |
{ |
| 60 |
public Vector3 Position; |
| 61 |
public Vector3 Normal; |
| 62 |
public Vector4 TextureCoordinate; |
| 63 |
public Vector4 TexWeights; |
| 64 |
|
| 65 |
public static int SizeInBytes = (3 + 3 + 4 + 4) * 4; |
| 66 |
public static VertexElement[ VertexElements = new VertexElement[ |
| 67 |
{ |
| 68 |
new VertexElement( 0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0 ), |
| 69 |
new VertexElement( 0, sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Normal, 0 ), |
| 70 |
new VertexElement( 0, sizeof(float) * 6, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0 ), |
| 71 |
new VertexElement( 0, sizeof(float) * 10, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 1 ), |
| 72 |
}; |
| 73 |
} |
| 74 |
|
| 75 |
#region Ground texture declarations |
| 76 |
/// <summary> |
| 77 |
/// Grass texture. |
| 78 |
/// </summary> |
| 79 |
private Texture2D grassTexture; |
| 80 |
|
| 81 |
/// <summary> |
| 82 |
/// Rock texture. |
| 83 |
/// </summary> |
| 84 |
private Texture2D rockTexture; |
| 85 |
|
| 86 |
/// <summary> |
| 87 |
/// Sand texture. |
| 88 |
/// </summary> |
| 89 |
private Texture2D sandTexture; |
| 90 |
|
| 91 |
/// <summary> |
| 92 |
/// Snow texture. |
| 93 |
/// </summary> |
| 94 |
private Texture2D snowTexture; |
| 95 |
#endregion |
| 96 |
|
| 97 |
#region Water texture declarations |
| 98 |
/// <summary> |
| 99 |
/// Water refraction map texture. |
| 100 |
/// </summary> |
| 101 |
private Texture2D refractionMap; |
| 102 |
|
| 103 |
/// <summary> |
| 104 |
/// Water reflection map texture. |
| 105 |
/// </summary> |
| 106 |
private Texture2D reflectionMap; |
| 107 |
|
| 108 |
/// <summary> |
| 109 |
/// Water bumpmap. |
| 110 |
/// </summary> |
| 111 |
private Texture2D waterBumpMap; |
| 112 |
#endregion |
| 113 |
|
| 114 |
/// <summary> |
| 115 |
/// Water refraction rendering target texture. |
| 116 |
/// </summary> |
| 117 |
private RenderTarget2D refractionRenderTarg; |
| 118 |
|
| 119 |
/// <summary> |
| 120 |
/// Water reflection rendering target texture. |
| 121 |
/// </summary> |
| 122 |
private RenderTarget2D reflectionRenderTarg; |
| 123 |
|
| 124 |
/// <summary> |
| 125 |
/// Vertex buffer for the terrain mesh. |
| 126 |
/// </summary> |
| 127 |
private VertexBuffer terrainVertexBuffer; |
| 128 |
|
| 129 |
/// <summary> |
| 130 |
/// Index buffer for the terrain mesh. |
| 131 |
/// </summary> |
| 132 |
private IndexBuffer terrainIndexBuffer; |
| 133 |
|
| 134 |
/// <summary> |
| 135 |
/// Buffer to hold the positions and textures of the water. |
| 136 |
/// </summary> |
| 137 |
private VertexPositionTexture[ waterVertices; |
| 138 |
|
| 139 |
/// <summary> |
| 140 |
/// Creates a skydome for displaying the sky. |
| 141 |
/// </summary> |
| 142 |
public Skydome skydome; |
| 143 |
|
| 144 |
/// <summary> |
| 145 |
/// The grayscale heightmap texture. |
| 146 |
/// </summary> |
| 147 |
private Texture2D heightMap; |
| 148 |
|
| 149 |
/// <summary> |
| 150 |
/// Array to hold height data. |
| 151 |
/// </summary> |
| 152 |
private float[,] heightData; |
| 153 |
|
| 154 |
/// <summary> |
| 155 |
/// 2D width of the heightmap. |
| 156 |
/// </summary> |
| 157 |
private int heightMapWidth; |
| 158 |
|
| 159 |
/// <summary> |
| 160 |
/// 2D height of the heightmap. |
| 161 |
/// </summary> |
| 162 |
private int heightMapHeight; |
| 163 |
|
| 164 |
/// <summary> |
| 165 |
/// Height of the water mesh. |
| 166 |
/// </summary> |
| 167 |
private Water waterHeight; |
| 168 |
|
| 169 |
/// <summary> |
| 170 |
/// Time variable for flowing water. |
| 171 |
/// </summary> |
| 172 |
public float elapsedTime; |
| 173 |
|
| 174 |
#region Base engine variables |
| 175 |
GraphicsDeviceManager graphics; |
| 176 |
Effect effect; |
| 177 |
GraphicsDevice device; |
| 178 |
Camera cam; |
| 179 |
ContentManager content; |
| 180 |
#endregion |
| 181 |
|
| 182 |
public Water WaterHeight |
| 183 |
{ |
| 184 |
get |
| 185 |
{ |
| 186 |
return this.waterHeight; |
| 187 |
} |
| 188 |
|
| 189 |
set |
| 190 |
{ |
| 191 |
this.waterHeight = value; |
| 192 |
this.SetUpWaterVertices(); |
| 193 |
} |
| 194 |
} |
| 195 |
|
| 196 |
public Terrain(ref GraphicsDeviceManager graphics, ref GraphicsDevice device, ref Effect effect, ref Camera cam, ref ContentManager content, Water waterHeight, ref float elapsedTime) |
| 197 |
{ |
| 198 |
this.graphics = graphics; |
| 199 |
this.device = device; |
| 200 |
this.effect = effect; |
| 201 |
this.cam = cam; |
| 202 |
this.content = content; |
| 203 |
this.elapsedTime = elapsedTime; |
| 204 |
|
| 205 |
skydome = new Skydome(ref device, ref cam, ref content, ref effect); |
| 206 |
|
| 207 |
this.waterHeight = waterHeight; |
| 208 |
|
| 209 |
this.waterBumpMap = content.Load<Texture2D>("waterbump"); |
| 210 |
this.heightMap = content.Load<Texture2D>("Maps/Elevation/0,0"); |
| 211 |
this.sandTexture = content.Load<Texture2D>("sand"); |
| 212 |
this.grassTexture = content.Load<Texture2D>("grass"); |
| 213 |
this.rockTexture = content.Load<Texture2D>("rock"); |
| 214 |
this.snowTexture = content.Load<Texture2D>("snow"); |
| 215 |
|
| 216 |
SetInitialValues(); |
| 217 |
} |
| 218 |
|
| 219 |
private CenterTile centerTile; |
| 220 |
|
| 221 |
public void Reload(Vector3 worldPosition) |
| 222 |
{ |
| 223 |
CenterTile cTile = GetCenterTile(worldPosition, TileSize); |
| 224 |
if (!centerTile.Equals(cTile)) |
| 225 |
{ |
| 226 |
this.centerTile = cTile; |
| 227 |
|
| 228 |
this.heightMap = content.Load<Texture2D>(String.Format("Maps/Elevation/{0},{1}", centerTile.X, centerTile.Y)); |
| 229 |
|
| 230 |
this.SetInitialValues(); |
| 231 |
} |
| 232 |
} |
| 233 |
|
| 234 |
/// <summary> |
| 235 |
/// Gets the X and Y coordinates of the center map tile |
| 236 |
/// </summary> |
| 237 |
/// <param name="GlobalPosition">The global position</param> |
| 238 |
/// <param name="TileSize">The width or height (tiles are always square) of the tiles</param> |
| 239 |
/// <returns>X and Y coordinate of the center map tile</returns> |
| 240 |
public static CenterTile GetCenterTile(Vector3 GlobalPosition, int TileSize) |
| 241 |
{ |
| 242 |
double TileX_decimal = Math.Floor(GlobalPosition.X / (float)TileSize); // Tile Value X |
| 243 |
double TileY_decimal = Math.Floor(GlobalPosition.Z / (float)TileSize); // Tile Value Y |
| 244 |
|
| 245 |
int TileX = ((TileX_decimal >= 0) ? (int)Math.Floor(TileX_decimal) : (int)Math.Ceiling(TileX_decimal)); |
| 246 |
int TileY = ((TileY_decimal >= 0) ? (int)Math.Floor(TileY_decimal) : (int)Math.Ceiling(TileY_decimal)); |
| 247 |
|
| 248 |
return new CenterTile(TileX, TileY); |
| 249 |
} |
| 250 |
|
| 251 |
/// <summary> |
| 252 |
/// Converts world coordinates to local map coordinates |
| 253 |
/// </summary> |
| 254 |
/// <param name="GlobalPosition">The global position</param> |
| 255 |
/// <param name="TileSize">The width or height (tiles are always square) of the tiles</param> |
| 256 |
/// <returns>The local map coordinates of the specified world coordinates</returns> |
| 257 |
private Vector3 GlobalToLocal(Vector3 GlobalPosition, int TileSize) |
| 258 |
{ |
| 259 |
if (GlobalPosition.X < 0) GlobalPosition.X += (float)Math.Ceiling(Math.Abs(GlobalPosition.X) / TileSize) * TileSize; |
| 260 |
if (GlobalPosition.Z < 0) GlobalPosition.Z += (float)Math.Ceiling(Math.Abs(GlobalPosition.Z) / TileSize) * TileSize; |
| 261 |
|
| 262 |
float LocalX = (GlobalPosition.X % TileSize) + TileSize; |
| 263 |
float LocalZ = (GlobalPosition.Z % TileSize) + TileSize; |
| 264 |
|
| 265 |
return new Vector3(LocalX, GlobalPosition.Y, LocalZ); |
| 266 |
} |
| 267 |
|
| 268 |
/// <summary> |
| 269 |
/// Calculates the height of the terrain at the given position |
| 270 |
/// </summary> |
| 271 |
/// <param name="Position">The position on the map</param> |
| 272 |
/// <returns>The height of the terrain</returns> |
| 273 |
public float TerrainHeight(Vector3 Position) |
| 274 |
{ |
| 275 |
try |
| 276 |
{ |
| 277 |
Position = GlobalToLocal(Position, TileSize); |
| 278 |
//Position.X -= TileSize; |
| 279 |
//Position.Y -= TileSize; |
| 280 |
|
| 281 |
int x = (int)Position.X; |
| 282 |
int z = (int)Position.Y; |
| 283 |
|
| 284 |
//x = x / (int)_scaleX; |
| 285 |
//z = z / (int)_scaleZ; |
| 286 |
|
| 287 |
//return (float)(_elevations[(z * this.NumberOfVertices.Z) + x]) * _scaleY; |
| 288 |
return heightData[(int)Position.X, (int)Position.Y]; |
| 289 |
} |
| 290 |
catch |
| 291 |
{ |
| 292 |
return 0; |
| 293 |
} |
| 294 |
} |
| 295 |
|
| 296 |
private void SetInitialValues() |
| 297 |
{ |
| 298 |
LoadHeightData(); |
| 299 |
SetUpTerrainterrainVertices(); |
| 300 |
SetUpTerrainterrainIndices(); |
| 301 |
SetUpWaterVertices(); |
| 302 |
|
| 303 |
refractionRenderTarg = new RenderTarget2D(device, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight, 1, device.PresentationParameters.BackBufferFormat, device.PresentationParameters.MultiSampleType, device.PresentationParameters.MultiSampleQuality); |
| 304 |
reflectionRenderTarg = new RenderTarget2D(device, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight, 1, device.PresentationParameters.BackBufferFormat, device.PresentationParameters.MultiSampleType, device.PresentationParameters.MultiSampleQuality); |
| 305 |
} |
| 306 |
|
| 307 |
private void SetUpTerrainterrainVertices() |
| 308 |
{ |
| 309 |
VertexMultitextured[ terrainVertices = new VertexMultitextured[heightMapWidth * heightMapHeight]; |
| 310 |
|
| 311 |
for (int x = 0; x < heightMapWidth; x++) |
| 312 |
{ |
| 313 |
for (int y = 0; y < heightMapHeight; y++) |
| 314 |
{ |
| 315 |
terrainVertices[x + y * heightMapWidth].Position = new Vector3(x, y, heightData[x, y]); |
| 316 |
terrainVertices[x + y * heightMapWidth].Normal = new Vector3(0, 0, 1); |
| 317 |
|
| 318 |
terrainVertices[x + y * heightMapWidth].TextureCoordinate.X = (float)x / 30.0f; |
| 319 |
terrainVertices[x + y * heightMapWidth].TextureCoordinate.Y = (float)y / 30.0f; |
| 320 |
|
| 321 |
terrainVertices[x + y * heightMapWidth].TexWeights.X = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 0) / 8.0f, 0, 1); |
| 322 |
terrainVertices[x + y * heightMapWidth].TexWeights.Y = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 12) / 6.0f, 0, 1); |
| 323 |
terrainVertices[x + y * heightMapWidth].TexWeights.Z = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 20) / 6.0f, 0, 1); |
| 324 |
terrainVertices[x + y * heightMapWidth].TexWeights.W = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 30) / 6.0f, 0, 1); |
| 325 |
|
| 326 |
float totalWeight = terrainVertices[x + y * heightMapWidth].TexWeights.X; |
| 327 |
totalWeight += terrainVertices[x + y * heightMapWidth].TexWeights.Y; |
| 328 |
totalWeight += terrainVertices[x + y * heightMapWidth].TexWeights.Z; |
| 329 |
totalWeight += terrainVertices[x + y * heightMapWidth].TexWeights.W; |
| 330 |
terrainVertices[x + y * heightMapWidth].TexWeights.X /= totalWeight; |
| 331 |
terrainVertices[x + y * heightMapWidth].TexWeights.Y /= totalWeight; |
| 332 |
terrainVertices[x + y * heightMapWidth].TexWeights.Z /= totalWeight; |
| 333 |
terrainVertices[x + y * heightMapWidth].TexWeights.W /= totalWeight; |
| 334 |
} |
| 335 |
} |
| 336 |
|
| 337 |
for (int x = 1; x < heightMapWidth - 1; x++) |
| 338 |
{ |
| 339 |
for (int y = 1; y < heightMapHeight - 1; y++) |
| 340 |
{ |
| 341 |
Vector3 normX = new Vector3((terrainVertices[x - 1 + y * heightMapWidth].Position.Z - terrainVertices[x + 1 + y * heightMapWidth].Position.Z) / 2, 0, 1); |
| 342 |
Vector3 normY = new Vector3(0, (terrainVertices[x + (y - 1) * heightMapWidth].Position.Z - terrainVertices[x + (y + 1) * heightMapWidth].Position.Z) / 2, 1); |
| 343 |
terrainVertices[x + y * heightMapWidth].Normal = normX + normY; |
| 344 |
terrainVertices[x + y * heightMapWidth].Normal.Normalize(); |
| 345 |
} |
| 346 |
} |
| 347 |
|
| 348 |
|
| 349 |
terrainVertexBuffer = new VertexBuffer(device, VertexMultitextured.SizeInBytes * heightMapWidth * heightMapHeight, BufferUsage.WriteOnly); |
| 350 |
|
| 351 |
terrainVertexBuffer.SetData(terrainVertices); |
| 352 |
} |
| 353 |
|
| 354 |
private void SetUpTerrainterrainIndices() |
| 355 |
{ |
| 356 |
int[ terrainIndices = new int[(heightMapWidth - 1) * (heightMapHeight - 1) * 6]; |
| 357 |
for (int x = 0; x < heightMapWidth - 1; x++) |
| 358 |
{ |
| 359 |
for (int y = 0; y < heightMapHeight - 1; y++) |
| 360 |
{ |
| 361 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6] = (x + 1) + (y + 1) * heightMapWidth; |
| 362 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6 + 1] = (x + 1) + y * heightMapWidth; |
| 363 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6 + 2] = x + y * heightMapWidth; |
| 364 |
|
| 365 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6 + 3] = (x + 1) + (y + 1) * heightMapWidth; |
| 366 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6 + 4] = x + y * heightMapWidth; |
| 367 |
terrainIndices[(x + y * (heightMapWidth - 1)) * 6 + 5] = x + (y + 1) * heightMapWidth; |
| 368 |
} |
| 369 |
} |
| 370 |
|
| 371 |
terrainIndexBuffer = new IndexBuffer(device, typeof(int), (heightMapWidth - 1) * (heightMapHeight - 1) * 6, BufferUsage.WriteOnly); |
| 372 |
terrainIndexBuffer.SetData(terrainIndices); |
| 373 |
} |
| 374 |
|
| 375 |
private void LoadHeightData() |
| 376 |
{ |
| 377 |
float minimumHeight = 255; |
| 378 |
float maximumHeight = 0; |
| 379 |
|
| 380 |
heightMapWidth = heightMap.Width; |
| 381 |
heightMapHeight = heightMap.Height; |
| 382 |
Color[ heightMapColors = new Color[heightMapWidth * heightMapHeight]; |
| 383 |
heightMap.GetData(heightMapColors); |
| 384 |
|
| 385 |
heightData = new float[heightMapWidth, heightMapHeight]; |
| 386 |
for (int x = 0; x < heightMapWidth; x++) |
| 387 |
{ |
| 388 |
for (int y = 0; y < heightMapHeight; y++) |
| 389 |
{ |
| 390 |
heightData[x, y] = heightMapColors[x + y * heightMapWidth].R; |
| 391 |
if (heightData[x, y] < minimumHeight) minimumHeight = heightData[x, y]; |
| 392 |
if (heightData[x, y] > maximumHeight) maximumHeight = heightData[x, y]; |
| 393 |
} |
| 394 |
} |
| 395 |
|
| 396 |
for (int x = 0; x < heightMapWidth; x++) |
| 397 |
{ |
| 398 |
for (int y = 0; y < heightMapHeight; y++) |
| 399 |
{ |
| 400 |
heightData[x, y] = (heightData[x, y] - minimumHeight) / (maximumHeight - minimumHeight) * 30; |
| 401 |
} |
| 402 |
} |
| 403 |
} |
| 404 |
|
| 405 |
private void SetUpWaterVertices() |
| 406 |
{ |
| 407 |
waterVertices = new VertexPositionTexture[6]; |
| 408 |
|
| 409 |
waterVertices[0] = new VertexPositionTexture(new Vector3(0, 0, this.WaterHeight.Height), new Vector2(0, 1)); |
| 410 |
waterVertices[2] = new VertexPositionTexture(new Vector3(heightMapWidth, heightMapHeight, this.WaterHeight.Height), new Vector2(1, 0)); |
| 411 |
waterVertices[1] = new VertexPositionTexture(new Vector3(0, heightMapHeight, this.WaterHeight.Height), new Vector2(0, 0)); |
| 412 |
|
| 413 |
waterVertices[3] = new VertexPositionTexture(new Vector3(0, 0, this.WaterHeight.Height), new Vector2(0, 1)); |
| 414 |
waterVertices[5] = new VertexPositionTexture(new Vector3(heightMapWidth, 0, this.WaterHeight.Height), new Vector2(1, 1)); |
| 415 |
waterVertices[4] = new VertexPositionTexture(new Vector3(heightMapWidth, heightMapHeight, this.WaterHeight.Height), new Vector2(1, 0)); |
| 416 |
} |
| 417 |
|
| 418 |
public void DrawTerrain(Matrix currentViewMatrix, Vector3 position) |
| 419 |
{ |
| 420 |
effect.CurrentTechnique = effect.Techniques["MultiTextured"]; |
| 421 |
effect.Parameters["xSandTexture"].SetValue(sandTexture); |
| 422 |
effect.Parameters["xGrassTexture"].SetValue(grassTexture); |
| 423 |
effect.Parameters["xRockTexture"].SetValue(rockTexture); |
| 424 |
effect.Parameters["xSnowTexture"].SetValue(snowTexture); |
| 425 |
|
| 426 |
CenterTile tile = GetCenterTile(position, TileSize); |
| 427 |
|
| 428 |
Matrix worldMatrix = Matrix.CreateTranslation(tile.X * TileSize, tile.Y * TileSize, GameClient.height); |
| 429 |
effect.Parameters["xWorld"].SetValue(worldMatrix); |
| 430 |
effect.Parameters["xView"].SetValue(currentViewMatrix); |
| 431 |
effect.Parameters["xProjection"].SetValue(cam.projectionMatrix); |
| 432 |
effect.Parameters["xEnableLighting"].SetValue(true); |
| 433 |
effect.Parameters["xLightDirection"].SetValue(new Vector3(-0.5f, -0.5f, -1)); |
| 434 |
effect.Parameters["xAmbient"].SetValue(0.2f); |
| 435 |
|
| 436 |
effect.Begin(); |
| 437 |
foreach (EffectPass pass in effect.CurrentTechnique.Passes) |
| 438 |
{ |
| 439 |
pass.Begin(); |
| 440 |
|
| 441 |
device.Vertices[0].SetSource(terrainVertexBuffer, 0, VertexMultitextured.SizeInBytes); |
| 442 |
device.Indices = terrainIndexBuffer; |
| 443 |
device.VertexDeclaration = new VertexDeclaration(device, VertexMultitextured.VertexElements); |
| 444 |
|
| 445 |
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, heightMapWidth * heightMapHeight, 0, (heightMapWidth - 1) * (heightMapHeight - 1) * 2); |
| 446 |
|
| 447 |
pass.End(); |
| 448 |
} |
| 449 |
effect.End(); |
| 450 |
} |
| 451 |
|
| 452 |
public void DrawRefractionMap() |
| 453 |
{ |
| 454 |
Vector3 planeNormalDirection = new Vector3(0, 0, -1); |
| 455 |
planeNormalDirection.Normalize(); |
| 456 |
|
| 457 |
Vector4 planeCoefficients = new Vector4(planeNormalDirection, this.WaterHeight.Height + 0.5f); |
| 458 |
|
| 459 |
Matrix camMatrix = cam.viewMatrix * cam.projectionMatrix; |
| 460 |
Matrix invCamMatrix = Matrix.Invert(camMatrix); |
| 461 |
invCamMatrix = Matrix.Transpose(invCamMatrix); |
| 462 |
|
| 463 |
planeCoefficients = Vector4.Transform(planeCoefficients, invCamMatrix); |
| 464 |
Plane refractionClipPlane = new Plane(planeCoefficients); |
| 465 |
|
| 466 |
device.ClipPlanes[0].Plane = refractionClipPlane; |
| 467 |
device.ClipPlanes[0].IsEnabled = true; |
| 468 |
|
| 469 |
device.SetRenderTarget(0, refractionRenderTarg); |
| 470 |
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0); |
| 471 |
DrawTerrain(cam.viewMatrix, new Vector3()); |
| 472 |
device.SetRenderTarget(0, null); |
| 473 |
refractionMap = refractionRenderTarg.GetTexture(); |
| 474 |
|
| 475 |
|
| 476 |
device.ClipPlanes[0].IsEnabled = false; |
| 477 |
|
| 478 |
// refractionMap.Save("refractionmap.jpg", ImageFileFormat.Jpg); |
| 479 |
} |
| 480 |
|
| 481 |
public void DrawReflectionMap() |
| 482 |
{ |
| 483 |
Vector3 planeNormalDirection = new Vector3(0, 0, 1); |
| 484 |
planeNormalDirection.Normalize(); |
| 485 |
Vector4 planeCoefficients = new Vector4(planeNormalDirection, -this.WaterHeight.Height + 0.5f); |
| 486 |
|
| 487 |
Matrix camMatrix = cam.reflectionViewMatrix * cam.projectionMatrix; |
| 488 |
Matrix invCamMatrix = Matrix.Invert(camMatrix); |
| 489 |
invCamMatrix = Matrix.Transpose(invCamMatrix); |
| 490 |
|
| 491 |
planeCoefficients = Vector4.Transform(planeCoefficients, invCamMatrix); |
| 492 |
Plane reflectionClipPlane = new Plane(planeCoefficients); |
| 493 |
|
| 494 |
device.ClipPlanes[0].Plane = reflectionClipPlane; |
| 495 |
device.ClipPlanes[0].IsEnabled = true; |
| 496 |
|
| 497 |
device.SetRenderTarget(0, reflectionRenderTarg); |
| 498 |
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0); |
| 499 |
DrawTerrain(cam.reflectionViewMatrix, new Vector3()); |
| 500 |
skydome.DrawSkyDome(cam.reflectionViewMatrix); |
| 501 |
|
| 502 |
device.SetRenderTarget(0, null); |
| 503 |
reflectionMap = reflectionRenderTarg.GetTexture(); |
| 504 |
|
| 505 |
|
| 506 |
device.ClipPlanes[0].IsEnabled = false; |
| 507 |
|
| 508 |
// reflectionMap.Save("refr.jpg", ImageFileFormat.Jpg); |
| 509 |
} |
| 510 |
|
| 511 |
public void DrawWater() |
| 512 |
{ |
| 513 |
effect.CurrentTechnique = effect.Techniques["Water"]; |
| 514 |
Matrix worldMatrix = Matrix.Identity; |
| 515 |
effect.Parameters["xWorld"].SetValue(worldMatrix); |
| 516 |
effect.Parameters["xView"].SetValue(cam.viewMatrix); |
| 517 |
effect.Parameters["xReflectionView"].SetValue(cam.reflectionViewMatrix); |
| 518 |
effect.Parameters["xProjection"].SetValue(cam.projectionMatrix); |
| 519 |
effect.Parameters["xReflectionMap"].SetValue(reflectionMap); |
| 520 |
effect.Parameters["xRefractionMap"].SetValue(refractionMap); |
| 521 |
|
| 522 |
effect.Parameters["xWaterBumpMap"].SetValue(waterBumpMap); |
| 523 |
effect.Parameters["xWaveLength"].SetValue(0.1f); |
| 524 |
effect.Parameters["xWaveHeight"].SetValue(0.3f); |
| 525 |
|
| 526 |
effect.Parameters["xCamPos"].SetValue(cam.cameraPosition); |
| 527 |
|
| 528 |
effect.Parameters["xTime"].SetValue(elapsedTime); |
| 529 |
effect.Parameters["xWindForce"].SetValue(20.0f); |
| 530 |
Matrix windDirection = Matrix.CreateRotationZ(MathHelper.PiOver2); |
| 531 |
effect.Parameters["xWindDirection"].SetValue(windDirection); |
| 532 |
|
| 533 |
effect.Begin(); |
| 534 |
foreach (EffectPass pass in effect.CurrentTechnique.Passes) |
| 535 |
{ |
| 536 |
pass.Begin(); |
| 537 |
device.VertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements); |
| 538 |
device.DrawUserPrimitives(PrimitiveType.TriangleList, waterVertices, 0, 2); |
| 539 |
pass.End(); |
| 540 |
} |
| 541 |
effect.End(); |
| 542 |
} |
| 543 |
} |
| 544 |
} |
| 545 |
|
|
|
-
|
|
Re: Terrain not appearing
|
Anyone have any clues as to why this isn't working?
|
|
-
-
- (4)
-
premium membership
-
Posts
124
|
Re: Terrain not appearing
|
Can I see your Game class?
|
|
-
|
|
Re: Terrain not appearing
|
| 1 |
namespace GameClient |
| 2 |
{ |
| 3 |
using System; |
| 4 |
using System.Collections.Generic; |
| 5 |
using System.Diagnostics; |
| 6 |
using System.IO; |
| 7 |
using Microsoft.Xna.Framework; |
| 8 |
using Microsoft.Xna.Framework.Audio; |
| 9 |
using Microsoft.Xna.Framework.Content; |
| 10 |
using Microsoft.Xna.Framework.Graphics; |
| 11 |
using Microsoft.Xna.Framework.Input; |
| 12 |
using Microsoft.Xna.Framework.Storage; |
| 13 |
using Microsoft.Xna.Framework.Gui; |
| 14 |
using System.ComponentModel; |
| 15 |
|
| 16 |
public class GameClient : Microsoft.Xna.Framework.Game |
| 17 |
{ |
| 18 |
private Network network; |
| 19 |
|
| 20 |
public static float height = 0; |
| 21 |
private GraphicsDeviceManager graphics; |
| 22 |
private ContentManager content; |
| 23 |
private GraphicsDevice device; |
| 24 |
|
| 25 |
private Vector2 viewportCentre; |
| 26 |
Texture2D logoTexture; |
| 27 |
Vector2 logoCentre; |
| 28 |
|
| 29 |
Texture2D backgroundTexture; |
| 30 |
Vector2 backgroundCentre; |
| 31 |
|
| 32 |
#region GUI variables |
| 33 |
private ServiceHelper serviceHelper; |
| 34 |
private FormCollection forms; |
| 35 |
private FormCollection introForms; |
| 36 |
#endregion |
| 37 |
|
| 38 |
private Effect effect; |
| 39 |
private Effect effect_fs; |
| 40 |
|
| 41 |
private SpriteBatch spriteBatch; |
| 42 |
private SpriteFont font; |
| 43 |
|
| 44 |
private Camera cam; |
| 45 |
private Terrain terrain; |
| 46 |
|
| 47 |
private ObjectBase tiny; |
| 48 |
|
| 49 |
private float elapsedTime; |
| 50 |
|
| 51 |
private Terrain.Water water = new Terrain.Water(0.0f); |
| 52 |
|
| 53 |
const int UP = 1; |
| 54 |
const int DOWN = -1; |
| 55 |
int waterDirection = UP; |
| 56 |
|
| 57 |
public GameClient() |
| 58 |
{ |
| 59 |
graphics = new GraphicsDeviceManager(this); |
| 60 |
content = new ContentManager(Services); |
| 61 |
content.RootDirectory = "Content"; |
| 62 |
cam = new Camera(this, water); |
| 63 |
network = new Network(); |
| 64 |
} |
| 65 |
|
| 66 |
private Size[ SIZES = new Size[5]; |
| 67 |
|
| 68 |
private void SetScreenSize(Size size) |
| 69 |
{ |
| 70 |
SetScreenSize(size.Width, size.Height); |
| 71 |
} |
| 72 |
|
| 73 |
private void SetScreenSize(int width, int height) |
| 74 |
{ |
| 75 |
device = graphics.GraphicsDevice; |
| 76 |
graphics.PreferredBackBufferWidth = width; |
| 77 |
graphics.PreferredBackBufferHeight = height; |
| 78 |
graphics.IsFullScreen = true; |
| 79 |
graphics.SynchronizeWithVerticalRetrace = false; |
| 80 |
graphics.ApplyChanges(); |
| 81 |
|
| 82 |
this.viewportCentre = new Vector2(this.graphics.GraphicsDevice.Viewport.Width / 2, this.graphics.GraphicsDevice.Viewport.Height / 2); |
| 83 |
} |
| 84 |
|
| 85 |
protected override void Initialize() |
| 86 |
{ |
| 87 |
SIZES[0] = new Size(graphics.GraphicsDevice.DisplayMode.Width, graphics.GraphicsDevice.DisplayMode.Height); |
| 88 |
SIZES[1] = new Size(720, 480); |
| 89 |
SIZES[2] = new Size(800, 600); |
| 90 |
SIZES[3] = new Size(1024, 768); |
| 91 |
SIZES[4] = new Size(1280, 1024); |
| 92 |
|
| 93 |
SetScreenSize(SIZES[0]); |
| 94 |
|
| 95 |
//this.IsFixedTimeStep = false; |
| 96 |
this.IsMouseVisible = true; |
| 97 |
this.Window.Title = "Skies of Astra Client"; |
| 98 |
|
| 99 |
this.InitializeGUI(); |
| 100 |
this.InitializeIntroGUI(); |
| 101 |
|
| 102 |
base.Initialize(); |
| 103 |
} |
| 104 |
|
| 105 |
protected override void LoadContent() |
| 106 |
{ |
| 107 |
spriteBatch = new SpriteBatch(device); |
| 108 |
|
| 109 |
effect = content.Load<Effect>("effects"); |
| 110 |
effect_fs = content.Load<Effect>("effects_fs"); |
| 111 |
font = content.Load<SpriteFont>("fps"); |
| 112 |
|
| 113 |
terrain = new Terrain(ref graphics, ref device, ref effect, ref cam, ref content, water, ref elapsedTime); |
| 114 |
|
| 115 |
tiny = new ObjectBase(device, content, "tiny", effect_fs); |
| 116 |
tiny.position = new Vector3(70, 70, terrain.TerrainHeight(new Vector3(70, 70, 0)) + 2.5f); |
| 117 |
tiny.rotation = new Vector3(0, 0, 0); |
| 118 |
tiny.scaling = new Vector3(0.01f, 0.01f, 0.01f); |
| 119 |
|
| 120 |
this.logoTexture = content.Load<Texture2D>("logo"); |
| 121 |
this.logoCentre = new Vector2(this.logoTexture.Width / 2, this.logoTexture.Height / 2); |
| 122 |
|
| 123 |
this.backgroundTexture = content.Load<Texture2D>("background"); |
| 124 |
this.backgroundCentre = new Vector2(this.backgroundTexture.Width / 2, this.backgroundTexture.Height / 2); |
| 125 |
} |
| 126 |
|
| 127 |
private void InitializeIntroGUI() |
| 128 |
{ |
| 129 |
int spacing = 8; |
| 130 |
int numButtons = 4; |
| 131 |
int buttonWidth = 150; |
| 132 |
|
| 133 |
SpriteFont guiFont = content.Load<SpriteFont>("Fonts/tahoma"); |
| 134 |
|
| 135 |
introForms = new FormCollection(); |
| 136 |
|
| 137 |
introForms.Add(new Form(new Vector2((device.Viewport.Width - ((numButtons * (buttonWidth + spacing)) + spacing)) / 2, 0), new Vector2((numButtons * (buttonWidth + spacing)) + spacing, 20 + (spacing * 2)), "ChooseOption", Color.LightGray, Color.Black, "tahoma", 1, false, false, false, false, Form.BorderStyle.None, Form.Style.BottomPanel)); |
| 138 |
introForms["ChooseOption"].Add(new TextButton("buttonLogin", new Vector2(spacing, spacing), "Login", buttonWidth, Color.LightGray, guiFont, Form.Style.Small)); |
| 139 |
introForms["ChooseOption"].Add(new TextButton("buttonCreateAcc", new Vector2(spacing + buttonWidth + spacing, spacing), "Create Account", buttonWidth, Color.LightGray, guiFont, Form.Style.Small)); |
| 140 |
introForms["ChooseOption"].Add(new TextButton("buttonOptions", new Vector2(spacing + ((buttonWidth + spacing) * 2), spacing), "Options", buttonWidth, Color.LightGray, guiFont, Form.Style.Small)); |
| 141 |
introForms["ChooseOption"].Add(new TextButton("buttonExit", new Vector2(spacing + ((buttonWidth + spacing) * 3), spacing), "Exit", buttonWidth, Color.LightGray, guiFont, Form.Style.Small)); |
| 142 |
|
| 143 |
((TextButton)introForms["ChooseOption"].Controls["buttonLogin"]).OnPress += new EventHandler(buttonLogin_OnPress); |
| 144 |
((TextButton)introForms["ChooseOption"].Controls["buttonCreateAcc"]).OnPress += new EventHandler(buttonCreateAcc_OnPress); |
| 145 |
((TextButton)introForms["ChooseOption"].Controls["buttonOptions"]).OnPress += new EventHandler(buttonOptions_OnPress); |
| 146 |
((TextButton)introForms["ChooseOption"].Controls["buttonExit"]).OnPress += new EventHandler(buttonExit_OnPress); |
| 147 |
} |
| 148 |
|
| 149 |
private void buttonLogin_OnPress(object sender, EventArgs e) |
| 150 |
{ |
| 151 |
SpriteFont guiFont = content.Load<SpriteFont>("Fonts/tahoma"); |
| 152 |
|
| 153 |
Size mlt = new Size(5, 30); |
| 154 |
Size mrb = new Size(5, 5); |
| 155 |
|
| 156 |
Size formSize = new Size(440, 155); |
| 157 |
|
| 158 |
if (introForms.Exist("Login")) |
| 159 |
{ |
| 160 |
introForms.Remove("Login"); |
| 161 |
} |
| 162 |
introForms.Add(new Form(new Vector2((device.Viewport.Width - formSize.Width) / 2, (device.Viewport.Height - formSize.Height) / 2), new Vector2(formSize.Width, formSize.Height), "Login", Color.LightGray, Color.Black, "tahoma", 1, false, false, false, false, Form.BorderStyle.FixedSingle, Form.Style.Default)); |
| 163 |
|
| 164 |
introForms["Login"].Add(new Label("labelUsername", new Vector2(mlt.Width + 4, mlt.Height + 4), "Username:", Label.Alignment.Left, 100, Color.Black, guiFont)); |
| 165 |
introForms["Login"].Add(new Label("labelPassword", new Vector2(mlt.Width + 4, mlt.Height + 28), "Password:", Label.Alignment.Left, 100, Color.Black, guiFont)); |
| 166 |
introForms["Login"].Add(new Label("labelServer", new Vector2(mlt.Width + 4, mlt.Height + 52), "Server:", Label.Alignment.Left, 100, Color.Black, guiFont)); |
| 167 |
|
| 168 |
introForms["Login"].Add(new Textbox("textboxUsername", new Vector2(mlt.Width + 104, mlt.Height + 4), 300, 20, "", "", 24, false, false, guiFont, Form.Style.Default)); |
| 169 |
introForms["Login"].Add(new Textbox("textboxPassword", new Vector2(mlt.Width + 104, mlt.Height + 28), 300, 20, "", "*", 40, false, false, guiFont, Form.Style.Default)); |
| 170 |
introForms["Login"].Add(new Combo("comboboxServer", new Vector2(mlt.Width + 104, mlt.Height + 52), 300, guiFont, Form.Style.Default)); |
| 171 |
|
| 172 |
introForms["Login"].Add(new TextButton("buttonLogin", new Vector2(mlt.Width + 153, mlt.Height + 76), "Login", 60, Color.LightGray, guiFont, Form.Style.Small)); |
| 173 |
introForms["Login"].Add(new TextButton("buttonCancel", new Vector2(formSize.Width - mlt.Width - 213, mlt.Height + 76), "Cancel", 60, Color.LightGray, guiFont, Form.Style.Small)); |
| 174 |
|
| 175 |
introForms["Login"].Add(new Label("labelConnectStatus", new Vector2(0, mlt.Height + 100), "", Label.Alignment.Center, formSize.Width, Color.Black, guiFont)); |
| 176 |
|
| 177 |
foreach (string str in Global.Servers) |
| 178 |
{ |
| 179 |
((Combo)introForms["Login"].Controls["comboboxServer"]).AddItem(str); |
| 180 |
} |
| 181 |
|
| 182 |
((TextButton)introForms["Login"].Controls["buttonLogin"]).OnPress += new EventHandler(loginConfirm_OnPress); |
| 183 |
((TextButton)introForms["Login"].Controls["buttonCancel"]).OnPress += new EventHandler(loginCancel_OnPress); |
| 184 |
|
| 185 |
introForms["Login"].Show(); |
| 186 |
} |
| 187 |
|
| 188 |
private void setConnectStatus(string text) |
| 189 |
{ |
| 190 |
introForms["Login"].Controls["labelConnectStatus"].Text = text; |
| 191 |
} |
| 192 |
|
| 193 |
private void loginConfirm_OnPress(object sender, EventArgs e) |
| 194 |
{ |
| 195 |
if (!network.IsConnecting) |
| 196 |
{ |
| 197 |
BackgroundWorker bw = new BackgroundWorker(); |
| 198 |
bw.DoWork += new DoWorkEventHandler(bw_DoWork); |
| 199 |
bw.RunWorkerAsync(); |
| 200 |
|
| 201 |
setConnectStatus("Connecting to server..."); |
| 202 |
} |
| 203 |
} |
| 204 |
|
| 205 |
private void bw_DoWork(object sender, DoWorkEventArgs e) |
| 206 |
{ |
| 207 |
string reason = ""; |
| 208 |
|
| 209 |
Network.ConnectionResult result = network.InitializeConnection(Global.HostnameFromServer(introForms["Login"].Controls["comboboxServer"].SelectedItem), introForms["Login"].Controls["textboxUsername"].Text, introForms["Login"].Controls["textboxPassword"].Text, out reason); |
| 210 |
|
| 211 |
if (result == Network.ConnectionResult.Connected) |
| 212 |
{ |
| 213 |
setConnectStatus("Connected to server."); |
| 214 |
} |
| 215 |
else if (result == Network.ConnectionResult.Failed) |
| 216 |
{ |
| 217 |
setConnectStatus("Failed to connect to server."); |
| 218 |
} |
| 219 |
else if (result == Network.ConnectionResult.AlreadyConnected) |
| 220 |
{ |
| 221 |
setConnectStatus("Already connected to server."); |
| 222 |
} |
| 223 |
} |
| 224 |
|
| 225 |
private void loginCancel_OnPress(object sender, EventArgs e) |
| 226 |
{ |
| 227 |
introForms["Login"].Hide(); |
| 228 |
} |
| 229 |
|
| 230 |
private void buttonCreateAcc_OnPress(object sender, EventArgs e) |
| 231 |
{ |
| 232 |
// inline create |
| 233 |
} |
| 234 |
|
| 235 |
private void buttonOptions_OnPress(object sender, EventArgs e) |
| 236 |
{ |
| 237 |
// show options dialog |
| 238 |
} |
| 239 |
|
| 240 |
private void buttonExit_OnPress(object sender, EventArgs e) |
| 241 |
{ |
| 242 |
this.Exit(); |
| 243 |
} |
| 244 |
|
| 245 |
private void InitializeGUI() |
| 246 |
{ |
| 247 |
SpriteFont guiFont = content.Load<SpriteFont>("Fonts\\tahoma"); |
| 248 |
SpriteFont guiFontSmall = content.Load<SpriteFont>("Fonts\\tahoma_small"); |
| 249 |
|
| 250 |
serviceHelper = new ServiceHelper(); |
| 251 |
serviceHelper.Initialize(graphics.GraphicsDevice, content); |
| 252 |
|
| 253 |
forms = new FormCollection(); |
| 254 |
|
| 255 |
int spacing = 6; |
| 256 |
int formWidth = 720; |
| 257 |
|
| 258 |
#region Top panel |
| 259 |
ControlCollection controlsTop = new ControlCollection(); |
| 260 |
|
| 261 |
// |
| 262 |
// menuButtons |
| 263 |
// |
| 264 |
int numMenuButtons = 12; |
| 265 |
string[ buttonTextureNames = new string[numMenuButtons]; |
| 266 |
buttonTextureNames[0] = "Inventory"; |
| 267 |
Button[ menuButtons = new Button[numMenuButtons]; |
| 268 |
int totalMenuButtonPixels = (formWidth - ((48 * numMenuButtons) + (spacing * (numMenuButtons + 1)))) / 2; |
| 269 |
for (int i = 0; i < numMenuButtons; i++) |
| 270 |
{ |
| 271 |
menuButtons[i] = new Button("menuButton" + (i + 1).ToString(), string.Empty, new Vector2(spacing + totalMenuButtonPixels, spacing), Color.White, Form.Style.Default); |
| 272 |
if (buttonTextureNames[i] != null) |
| 273 |
{ |
| 274 |
menuButtons[i].Image = content.Load<Texture2D>("GUI/TopButtons/" + buttonTextureNames[i]); |
| 275 |
} |
| 276 |
|
| 277 |
switch ((i + 1)) |
| 278 |
{ |
| 279 |
case 1: |
| 280 |
menuButtons[i].OnMousePress += new EventHandler(inventory_OnPress); |
| 281 |
break; |
| 282 |
case 12: |
| 283 |
menuButtons[i].OnMousePress += new EventHandler(exit_OnPress); |
| 284 |
break; |
| 285 |
} |
| 286 |
|
| 287 |
totalMenuButtonPixels += menuButtons[i].size.X + spacing; |
| 288 |
|
| 289 |
controlsTop.Add(menuButtons[i]); |
| 290 |
} |
| 291 |
|
| 292 |
// Create form |
| 293 |
forms.Add(new Form(new Vector2((device.Viewport.Width - (formWidth)) / 2, spacing), new Vector2(formWidth, menuButtons[0].size.Y + (spacing * 2)), "MenuForm", Color.White, Color.Black, "tahoma", 1, false, false, false, false, Form.BorderStyle.None, Form.Style.BottomPanel)); |
| 294 |
|
| 295 |
// Add controls to form |
| 296 |
for (int i = 0; i < controlsTop.Count; i++) |
| 297 |
{ |
| 298 |
forms["MenuForm"].Add(controlsTop[i]); |
| 299 |
} |
| 300 |
#endregion |
| 301 |
|
| 302 |
#region Bottom bar |
| 303 |
ControlCollection controls = new ControlCollection(); |
| 304 |
|
| 305 |
// |
| 306 |
// chatBox |
| 307 |
// |
| 308 |
int chatBoxHeight = 60; |
| 309 |
if (device.Viewport.Height >= 600) |
| 310 |
{ |
| 311 |
chatBoxHeight = 80; |
| 312 |
} |
| 313 |
if (device.Viewport.Height >= 768) |
| 314 |
{ |
| 315 |
chatBoxHeight = 100; |
| 316 |
} |
| 317 |
if (device.Viewport.Height >= 1024) |
| 318 |
{ |
| 319 |
chatBoxHeight = 120; |
| 320 |
} |
| 321 |
Textbox chatBox = new Textbox("chatBox", new Vector2(spacing, spacing), formWidth - (spacing * 2) - 16, chatBoxHeight, "", "", 32767, false, true, guiFont, Form.Style.Default); |
| 322 |
controls.Add(chatBox); |
| 323 |
|
| 324 |
// |
| 325 |
// chatInput |
| 326 |
// |
| 327 |
Textbox chatInput = new Textbox("chatInput", new Vector2(spacing, chatBox.Position.Y + (int)chatBox.height + spacing), formWidth - (spacing * 3) - 60, 20, "", "", 32767, false, false, guiFont, Form.Style.Default); |
| 328 |
chatInput.OnKeyPress += new EventHandler(chatInput_OnKeyPress); |
| 329 |
controls.Add(chatInput); |
| 330 |
|
| 331 |
// |
| 332 |
// sendChat |
| 333 |
// |
| 334 |
TextButton sendChat = new TextButton("sendChat", new Vector2(formWidth - spacing - 60, chatBox.Position.Y + (int)chatBox.height + spacing), "Send", 60, Color.LightGray, guiFont, Form.Style.Small); |
| 335 |
sendChat.OnPress += new EventHandler(sendChat_OnPress); |
| 336 |
controls.Add(sendChat); |
| 337 |
|
| 338 |
// |
| 339 |
// quickButtons |
| 340 |
// |
| 341 |
int numQuickButtons = 8; |
| 342 |
Button[ quickButtons = new Button[numQuickButtons]; |
| 343 |
int totalButtonPixels = 0; |
| 344 |
for (int i = 0; i < quickButtons.Length; i++) |
| 345 |
{ |
| 346 |
quickButtons[i] = new Button("button" + (i + 1).ToString(), string.Empty, new Vector2(spacing + totalButtonPixels, chatInput.Position.Y + (int)chatInput.height + spacing), Color.White, Form.Style.Default); |
| 347 |
|
| 348 |
totalButtonPixels += quickButtons[i].size.X + spacing; |
| 349 |
|
| 350 |
controls.Add(quickButtons[i]); |
| 351 |
} |
| 352 |
|
| 353 |
// |
| 354 |
// enemyHPBar |
| 355 |
// |
| 356 |
Progressbar enemyHPBar = new Progressbar("enemyHPBar", new Vector2(totalButtonPixels + spacing, quickButtons[0].Position.Y + ((quickButtons[0].size.Y - 18) / 2)), Color.Gray, Color.Red, formWidth - (totalButtonPixels + spacing) - spacing, 50, true); |
| 357 |
controls.Add(enemyHPBar); |
| 358 |
|
| 359 |
// |
| 360 |
// monsterLabel |
| 361 |
// |
| 362 |
string labelText = enemyHPBar.width.ToString(); |
| 363 |
Label monsterLabel = new Label("monsterLabel", enemyHPBar.Position, labelText, Label.Alignment.Center, enemyHPBar.width, Color.White, guiFontSmall); |
| 364 |
controls.Add(monsterLabel); |
| 365 |
|
| 366 |
// Get form height |
| 367 |
int[ controlHeights = new int[ { 48, (int)chatInput.height, (int)chatBox.height }; |
| 368 |
int formHeight = (controlHeights.Length + 1) * spacing; |
| 369 |
for (int i = 0; i < controlHeights.Length; i++) |
| 370 |
{ |
| 371 |
formHeight += controlHeights[i]; |
| 372 |
} |
| 373 |
|
| 374 |
// Create form |
| 375 |
forms.Add(new Form(new Vector2((device.Viewport.Width - formWidth) / 2, device.Viewport.Height - formHeight - spacing), new Vector2(formWidth, formHeight), "BottomPanelForm", Color.White, Color.Black, "tahoma", 1, false, false, false, false, Form.BorderStyle.None, Form.Style.BottomPanel)); |
| 376 |
|
| 377 |
// Add controls to form |
| 378 |
for (int i = 0; i < controls.Count; i++) |
| 379 |
{ |
| 380 |
forms["BottomPanelForm"].Add(controls[i]); |
| 381 |
} |
| 382 |
#endregion |
| 383 |
|
| 384 |
#region Dialog windows |
| 385 |
#region Inventory |
| 386 |
#endregion |
| 387 |
#endregion |
| 388 |
} |
| 389 |
|
| 390 |
private void inventory_OnPress(object sender, EventArgs e) |
| 391 |
{ |
| 392 |
int totalButtons = 12; |
| 393 |
int spacing = 4; |
| 394 |
int buttonsPerRow = 4; |
| 395 |
Size buttonSize = new Size(48, 48); |
| 396 |
|
| 397 |
if (forms.Exist("Inventory")) |
| 398 |
{ |
| 399 |
forms.Remove("Inventory"); |
| 400 |
} |
| 401 |
Size mlt = new Size(5, 30); |
| 402 |
Size mrb = new Size(5, 5); |
| 403 |
Size clientFormSize = new Size(212, 264); |
| 404 |
Size formSize = new Size(clientFormSize.Width + (mlt.Width + mrb.Width), clientFormSize.Height + (mlt.Height + mrb.Height)); |
| 405 |
Form form = new Form(new Vector2((device.Viewport.Width - formSize.Width) / 2, (device.Viewport.Height - formSize.Height) / 2), new Vector2(formSize.Width, formSize.Height), "Inventory", Color.LightGray, Color.Black, "FormTitle", 1, true, false, false, false, Form.BorderStyle.FixedSingle, Form.Style.Default); |
| 406 |
for (int i = 0; i < totalButtons; i++) |
| 407 |
{ |
| 408 |
form.Add(new Button("smallInventory" + (i + 1).ToString(), string.Empty, new Vector2(spacing + mlt.Width + ((i % buttonsPerRow) * (buttonSize.Width + spacing)), spacing + mlt.Height + ((i / buttonsPerRow) * (buttonSize.Height + spacing))), Color.LightGray, Form.Style.Default)); |
| 409 |
} |
| 410 |
form.Add(new Button("largeInventory", string.Empty, new Vector2((formSize.Width - buttonSize.Width) / 2, mlt.Height + 188), Color.LightGray, Form.Style.Default)); |
| 411 |
form.Add(new Button("mediumInventory1", string.Empty, new Vector2(form.Controls["largeInventory"].Position.X - buttonSize.Width - spacing, form.Controls["largeInventory"].Position.Y - (buttonSize.Height / 2) - spacing), Color.LightGray, Form.Style.Default)); |
| 412 |
form.Add(new Button("mediumInventory2", string.Empty, new Vector2(form.Controls["largeInventory"].Position.X + buttonSize.Width + spacing, form.Controls["largeInventory"].Position.Y - (buttonSize.Height / 2) - spacing), Color.LightGray, Form.Style.Default)); |
| 413 |
form.Add(new Button("mediumInventory3", string.Empty, new Vector2(form.Controls["largeInventory"].Position.X - buttonSize.Width - spacing, form.Controls["largeInventory"].Position.Y + (buttonSize.Height / 2)), Color.LightGray, Form.Style.Default)); |
| 414 |
form.Add(new Button("mediumInventory4", string.Empty, new Vector2(form.Controls["largeInventory"].Position.X + buttonSize.Width + spacing, form.Controls["largeInventory"].Position.Y + (buttonSize.Height / 2)), Color.LightGray, Form.Style.Default)); |
| 415 |
|
| 416 |
forms.Add(form); |
| 417 |
forms["Inventory"].Show(); |
| 418 |
} |
| 419 |
|
| 420 |
private void exit_OnPress(object sender, EventArgs e) |
| 421 |
{ |
| 422 |
ScreenManager.ActiveScreen = ScreenManager.Screen.Splash; |
| 423 |
} |
| 424 |
|
| 425 |
private void chatInput_OnKeyPress(object sender, EventArgs e) |
| 426 |
{ |
| 427 |
Keys keys = (Keys)sender; |
| 428 |
if (keys == Keys.Enter) |
| 429 |
{ |
| 430 |
AddChat(); |
| 431 |
} |
| 432 |
} |
| 433 |
|
| 434 |
private void sendChat_OnPress(object sender, EventArgs e) |
| 435 |
{ |
| 436 |
AddChat(); |
| 437 |
} |
| 438 |
|
| 439 |
private void AddChat() |
| 440 |
{ |
| 441 |
if (forms["BottomPanelForm"].Controls["chatInput"].Text.Length > 0) |
| 442 |
{ |
| 443 |
forms["BottomPanelForm"].Controls["chatBox"].Text += ((forms["BottomPanelForm"].Controls["chatBox"].Text.Length > 0) ? "\n" : "") + forms["BottomPanelForm"].Controls["chatInput"].Text; |
| 444 |
forms["BottomPanelForm"].Controls["chatInput"].Text = ""; |
| 445 |
} |
| 446 |
} |
| 447 |
|
| 448 |
private void DrawGUI() |
| 449 |
{ |
| 450 |
if (!forms["MenuForm"].bVisible) |
| 451 |
{ |
| 452 |
forms["MenuForm"].Show(); |
| 453 |
} |
| 454 |
|
| 455 |
if (!forms["BottomPanelForm"].bVisible) |
| 456 |
{ |
| 457 |
forms["BottomPanelForm"].Show(); |
| 458 |
} |
| 459 |
|
| 460 |
forms.Draw(); |
| 461 |
} |
| 462 |
|
| 463 |
private void UpdateGUI() |
| 464 |
{ |
| 465 |
forms.Update(); |
| 466 |
introForms.Update(); |
| 467 |
} |
| 468 |
|
| 469 |
protected override void UnloadContent() |
| 470 |
{ |
| 471 |
content.Unload(); |
| 472 |
} |
| 473 |
|
| 474 |
protected override void Update(GameTime gameTime) |
| 475 |
{ |
| 476 |
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) |
| 477 |
this.Exit(); |
| 478 |
base.Update(gameTime); |
| 479 |
|
| 480 |
FPS.Calculate(gameTime); |
| 481 |
|
| 482 |
ProcessInput((float)gameTime.ElapsedGameTime.Milliseconds / 30.0f); |
| 483 |
|
| 484 |
cam.SetCameraFollow(tiny, 15, 5); |
| 485 |
|
| 486 |
elapsedTime += (float)gameTime.ElapsedGameTime.Milliseconds / 100000.0f; |
| 487 |
terrain.elapsedTime = elapsedTime; |
| 488 |
|
| 489 |
// If the water's too high, tell it to go down |
| 490 |
if (terrain.WaterHeight.Height >= 0.05f) |
| 491 |
waterDirection = DOWN; |
| 492 |
|
| 493 |
// If it's too low, tell it to go up |
| 494 |
if (terrain.WaterHeight.Height <= -0.05f) |
| 495 |
waterDirection = UP; |
| 496 |
|
| 497 |
// Increase or decrease the water height |
| 498 |
terrain.WaterHeight = new Terrain.Water(terrain.WaterHeight.Height + (0.0005f * waterDirection)); |
| 499 |
|
| 500 |
UpdateGUI(); |
| 501 |
} |
| 502 |
|
| 503 |
private void ProcessInput(float amountOfMovement) |
| 504 |
{ |
| 505 |
Vector3 moveVector = new Vector3(); |
| 506 |
|
| 507 |
KeyboardState keys = Keyboard.GetState(); |
| 508 |
MouseState mouse = Mouse.GetState(); |
| 509 |
if (keys.IsKeyDown(Keys.Right)) |
| 510 |
{ |
| 511 |
//moveVector.X += amountOfMovement; |
| 512 |
//tiny.position = new Vector3(tiny.position.X + 0.1f, tiny.position.Y, tiny.position.Z); |
| 513 |
//tiny.SetHeight(terrain.TerrainHeight(tiny.position) + 2.5f); |
| 514 |
tiny.rotation.X += 1f; |
| 515 |
} |
| 516 |
if (keys.IsKeyDown(Keys.Left)) |
| 517 |
{ |
| 518 |
//moveVector.X -= amountOfMovement; |
| 519 |
//tiny.position = new Vector3(tiny.position.X - 0.1f, tiny.position.Y, tiny.position.Z); |
| 520 |
//tiny.SetHeight(terrain.TerrainHeight(tiny.position) + 2.5f); |
| 521 |
tiny.rotation.X -= 1f; |
| 522 |
} |
| 523 |
|
| 524 |
if (keys.IsKeyDown(Keys.Down)) |
| 525 |
{ |
| 526 |
//moveVector.Y -= amountOfMovement; |
| 527 |
tiny.MoveForwardBack(0.1f, -1); |
| 528 |
//tiny.position = new Vector3(tiny.position.X, tiny.position.Y + 0.1f, tiny.position.Z); |
| 529 |
tiny.SetHeight(terrain.TerrainHeight(tiny.position) + 2.5f); |
| 530 |
} |
| 531 |
if (keys.IsKeyDown(Keys.Up)) |
| 532 |
{ |
| 533 |
//moveVector.Y += amountOfMovement; |
| 534 |
tiny.MoveForwardBack(0.1f, 1); |
| 535 |
//tiny.position = new Vector3(tiny.position.X, tiny.position.Y - 0.1f, tiny.position.Z); |
| 536 |
tiny.SetHeight(terrain.TerrainHeight(tiny.position) + 2.5f); |
| 537 |
|
| 538 |
} |
| 539 |
|
| 540 |
//cam.cameraPosition = new Vector3(tiny.position.X, tiny.position.Y - 10, tiny.position.Z); |
| 541 |
//cam.SetCameraFollow(tiny, mouse.ScrollWheelValue, 5); |
| 542 |
|
| 543 |
//cam.SetCameraPosition(tiny, 50); |
| 544 |
|
| 545 |
|
| 546 |
//cam.Rotation = tiny.rotation; |
| 547 |
//cam.Rotation = new Vector3(tiny.rotation.X, tiny.rotation.Y, tiny.rotation.Z); |
| 548 |
|
| 549 |
//Matrix cameraRotation = Matrix.CreateRotationX(cam.Rotation.Z) * Matrix.CreateRotationZ(cam.Rotation.X); |
| 550 |
//cam.cameraPosition += Vector3.Transform(moveVector, cameraRotation); |
| 551 |
} |
| 552 |
|
| 553 |
protected override void Draw(GameTime gameTime) |
| 554 |
{ |
| 555 |
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.SkyBlue, 1.0f, 0); |
| 556 |
|
| 557 |
if (ScreenManager.ActiveScreen == ScreenManager.Screen.Game) |
| 558 |
{ |
| 559 |
terrain.Reload(tiny.position); |
| 560 |
|
| 561 |
//terrain.DrawRefractionMap(); |
| 562 |
//terrain.DrawReflectionMap(); |
| 563 |
|
| 564 |
terrain.DrawTerrain(cam.viewMatrix, tiny.position); |
| 565 |
terrain.skydome.DrawSkyDome(cam.viewMatrix); |
| 566 |
//terrain.DrawWater(); |
| 567 |
|
| 568 |
tiny.DrawModel(ref cam); |
| 569 |
|
| 570 |
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.BackToFront, SaveStateMode.SaveState); |
| 571 |
spriteBatch.DrawString(font, FPS.FPSString, new Vector2(4, 4), Color.White); |
| 572 |
spriteBatch.DrawString(font, tiny.position.ToString() + "\n\n\n\n\n\n", new Vector2(4, 500), Color.White); |
| 573 |
spriteBatch.End(); |
| 574 |
|
| 575 |
DrawGUI(); |
| 576 |
} |
| 577 |
else if (ScreenManager.ActiveScreen == ScreenManager.Screen.Splash) |
| 578 |
{ |
| 579 |
maxLogoScale = (float)device.Viewport.Height / (this.logoTexture.Height * 2); |
| 580 |
if (logoScale < maxLogoScale) |
| 581 |
{ |
| 582 |
logoScale += 0.01f; |
| 583 |
} |
| 584 |
else if (traj.Y > -(introForms["ChooseOption"].size.Y)) |
| 585 |
{ |
| 586 |
traj.Y -= 1.5f; |
| 587 |
} |
| 588 |
else |
| 589 |
{ |
| 590 |
if (!introForms["ChooseOption"].bVisible) |
| 591 |
{ |
| 592 |
introForms["ChooseOption"].position.Y = this.viewportCentre.Y + traj.Y + ((this.logoTexture.Height * maxLogoScale) / 2); |
| 593 |
introForms["ChooseOption"].Show(); |
| 594 |
} |
| 595 |
} |
| 596 |
|
| 597 |
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState); |
| 598 |
spriteBatch.Draw(this.backgroundTexture, this.viewportCentre, null, Color.White, 0, this.backgroundCentre, new Vector2((float)device.Viewport.Width / (float)this.backgroundTexture.Width, (float)device.Viewport.Height / (float)this.backgroundTexture.Height), SpriteEffects.None, 0); |
| 599 |
spriteBatch.Draw(this.logoTexture, this.viewportCentre + traj, null, Color.White, 0, this.logoCentre, logoScale, SpriteEffects.None, 0); |
| 600 |
spriteBatch.End(); |
| 601 |
|
| 602 |
introForms.Draw(); |
| 603 |
} |
| 604 |
|
| 605 |
base.Draw(gameTime); |
| 606 |
} |
| 607 |
|
| 608 |
private Vector2 creditsPosition = new Vector2(0, 0); |
| 609 |
private float creditsScale = 0; |
| 610 |
private Vector2 traj = new Vector2(0, 0); |
| 611 |
private float maxLogoScale = 1; |
| 612 |
private float logoScale = 0.1f; |
| 613 |
} |
| 614 |
} |
| 615 |
|
|
|
-
-
- (4)
-
premium membership
-
Posts
124
|
Re: Terrain not appearing
|
Hmmm... I'll have to take a closer look at this later. I have to go right now though. A few things to try: You should probably move your camera away from 0,0,0. If you're using a heightmap, odds are that the terrain is above 0,0,0, and with backface culling on, you won't see it. Also check what your camera's target is, make sure it's looking towards the terrain, because 0,0,0 is probably a corner of the terrain.
|
|
-
|
|
Re: Terrain not appearing
|
Sean James, thank you for trying to help. I found the problem. For some reason, Content.Load<Texture2D> does not seem to like images of uniform color. Some of my heightmaps were ENTIRELY RGB 127-127-127 - all pixels had that same value. As soon as I changed a single pixel to something other than 127-127-127, the terrain rendered properly. However, this seems like a pretty strange quirk, and although most games' heightmaps probably won't be completely flat, it seems strange to have the limitation of NEEDING to have a texture contain more than 1 unique color.
I hope someone can at least explain WHY this happens; I'm sure I'll be able to get by, but as I said... it seems odd. Does this have something to do with some powers-of-2 requirement?
NOTE: My textures are being loaded from 128x128 pixel PNG images.
|
|
|