private void DrawView() { if (!(DrawView_Enabled && IsGLInitialized)) { return; } if (GraphicsContext.CurrentContext != OpenGLControl.Context) { OpenGLControl.MakeCurrent(); } GL.Clear(ClearBufferMask.ColorBufferBit); var map = MainMap; if (map == null) { GL.Flush(); OpenGLControl.SwapBuffers(); Refresh(); return; } var xyInt = new XYInt(); var unrotatedPos = new XYDouble(); var texCoord0 = new XYDouble(); var texCoord1 = new XYDouble(); var texCoord2 = new XYDouble(); var texCoord3 = new XYDouble(); GL.MatrixMode(MatrixMode.Projection); var temp_mat = Matrix4.CreateOrthographicOffCenter(0.0F, GLSize.X, GLSize.Y, 0.0F, -1.0F, 1.0F); GL.LoadMatrix(ref temp_mat); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); if (map.Tileset != null) { TileUtil.GetTileRotatedTexCoords(App.TextureOrientation, ref texCoord0, ref texCoord1, ref texCoord2, ref texCoord3); GL.Enable(EnableCap.Texture2D); GL.Color4(0.0F, 0.0F, 0.0F, 1.0F); var x = 0; var y = 0; var num = 0; var a = 0; for (y = 0; y <= TextureCount.Y - 1; y++) { for (x = 0; x <= TextureCount.X - 1; x++) { num = (TextureYOffset + y) * TextureCount.X + x; if (num >= map.Tileset.TileCount) { goto EndOfTextures1; } a = map.Tileset.Tiles[num].GlTextureNum; GL.BindTexture(TextureTarget.Texture2D, a); GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Decal); GL.Begin(BeginMode.Quads); GL.TexCoord2(texCoord0.X, texCoord0.Y); GL.Vertex2(x * 64, y * 64); // Top Left GL.TexCoord2(texCoord1.X, texCoord1.Y); GL.Vertex2(x * 64 + 64, y * 64); // Bottom Left GL.TexCoord2(texCoord3.X, texCoord3.Y); GL.Vertex2(x * 64 + 64, y * 64 + 64); // Bottom right GL.TexCoord2(texCoord2.X, texCoord2.Y); GL.Vertex2(x * 64, y * 64 + 64); // Top right GL.End(); } } EndOfTextures1: GL.Disable(EnableCap.Texture2D); if (DisplayTileTypes) { GL.Begin(BeginMode.Quads); for (y = 0; y <= TextureCount.Y - 1; y++) { for (x = 0; x <= TextureCount.X - 1; x++) { num = (TextureYOffset + y) * TextureCount.X + x; if (num >= map.Tileset.TileCount) { goto EndOfTextures2; } a = map.TileTypeNum[num]; GL.Color3(App.TileTypes[a].DisplayColour.Red, App.TileTypes[a].DisplayColour.Green, App.TileTypes[a].DisplayColour.Blue); GL.Vertex2(x * 64 + 24, y * 64 + 24); GL.Vertex2(x * 64 + 24, y * 64 + 40); GL.Vertex2(x * 64 + 40, y * 64 + 40); GL.Vertex2(x * 64 + 40, y * 64 + 24); } } EndOfTextures2: GL.End(); } if (App.DisplayTileOrientation) { GL.Disable(EnableCap.CullFace); unrotatedPos.X = 0.25F; unrotatedPos.Y = 0.25F; var vertex0 = TileUtil.GetTileRotatedPos_sng(App.TextureOrientation, unrotatedPos); unrotatedPos.X = 0.5F; unrotatedPos.Y = 0.25F; var vertex1 = TileUtil.GetTileRotatedPos_sng(App.TextureOrientation, unrotatedPos); unrotatedPos.X = 0.5F; unrotatedPos.Y = 0.5F; var vertex2 = TileUtil.GetTileRotatedPos_sng(App.TextureOrientation, unrotatedPos); GL.Begin(BeginMode.Triangles); GL.Color3(1.0F, 1.0F, 0.0F); for (y = 0; y <= TextureCount.Y - 1; y++) { for (x = 0; x <= TextureCount.X - 1; x++) { num = (TextureYOffset + y) * TextureCount.X + x; if (num >= map.Tileset.TileCount) { goto EndOfTextures3; } GL.Vertex2(x * 64 + vertex0.X * 64, y * 64 + vertex0.Y * 64); GL.Vertex2(x * 64 + vertex2.X * 64, y * 64 + vertex2.Y * 64); GL.Vertex2(x * 64 + vertex1.X * 64, y * 64 + vertex1.Y * 64); } } EndOfTextures3: GL.End(); GL.Enable(EnableCap.CullFace); } if (DisplayTileNumbers && App.UnitLabelFont != null) //TextureViewFont IsNot Nothing Then { GL.Enable(EnableCap.Texture2D); for (y = 0; y <= TextureCount.Y - 1; y++) { for (x = 0; x <= TextureCount.X - 1; x++) { num = (TextureYOffset + y) * TextureCount.X + x; if (num >= map.Tileset.TileCount) { goto EndOfTextures4; } clsTextLabel textLabel = new clsTextLabel(); textLabel.Text = num.ToStringInvariant(); textLabel.SizeY = 24.0F; textLabel.Colour.Red = 1.0F; textLabel.Colour.Green = 1.0F; textLabel.Colour.Blue = 0.0F; textLabel.Colour.Alpha = 1.0F; textLabel.Pos.X = x * 64; textLabel.Pos.Y = y * 64; textLabel.TextFont = App.UnitLabelFont; //TextureViewFont textLabel.Draw(); } } EndOfTextures4: GL.Disable(EnableCap.Texture2D); } if (App.SelectedTextureNum >= 0 & TextureCount.X > 0) { a = App.SelectedTextureNum - TextureYOffset * TextureCount.X; xyInt.X = a - a / TextureCount.X * TextureCount.X; xyInt.Y = a / TextureCount.X; GL.Begin(BeginMode.LineLoop); GL.Color3(1.0F, 1.0F, 0.0F); GL.Vertex2(xyInt.X * 64, xyInt.Y * 64); GL.Vertex2(xyInt.X * 64, xyInt.Y * 64.0D + 64); GL.Vertex2(xyInt.X * 64 + 64, xyInt.Y * 64 + 64); GL.Vertex2(xyInt.X * 64 + 64, xyInt.Y * 64); GL.End(); } } GL.Flush(); OpenGLControl.SwapBuffers(); Refresh(); }
public override void Perform() { var terrain = Map.Terrain; var tileset = Map.Tileset; var tileTerrainHeight = new double[5]; var vertices = new XYZDouble[5]; //4 corners + center var normals = new XYZDouble[5]; var texCoords = new XYDouble[5]; //Texture binding code copied from clsDrawTileOld if (terrain.Tiles[TileX, TileY].Texture.TextureNum < 0) { GL.BindTexture(TextureTarget.Texture2D, App.GLTexture_NoTile); } else if (tileset == null) { GL.BindTexture(TextureTarget.Texture2D, App.GLTexture_OverflowTile); } else if (terrain.Tiles[TileX, TileY].Texture.TextureNum < tileset.TileCount) { var viewGlTextureNum = tileset.Tiles[terrain.Tiles[TileX, TileY].Texture.TextureNum].GlTextureNum; if (viewGlTextureNum == 0) { GL.BindTexture(TextureTarget.Texture2D, App.GLTexture_OverflowTile); } else { GL.BindTexture(TextureTarget.Texture2D, viewGlTextureNum); } } else { GL.BindTexture(TextureTarget.Texture2D, App.GLTexture_OverflowTile); } GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate); //Vertex order: //0 1 // 4 //2 3 tileTerrainHeight[0] = terrain.Vertices[TileX, TileY].Height; tileTerrainHeight[1] = terrain.Vertices[TileX + 1, TileY].Height; tileTerrainHeight[2] = terrain.Vertices[TileX, TileY + 1].Height; tileTerrainHeight[3] = terrain.Vertices[TileX + 1, TileY + 1].Height; tileTerrainHeight[4] = (tileTerrainHeight[0] + tileTerrainHeight[1] + tileTerrainHeight[2] + tileTerrainHeight[3]) / 4; //middle height is average of the corners TileUtil.GetTileRotatedTexCoords(terrain.Tiles[TileX, TileY].Texture.Orientation, ref texCoords[0], ref texCoords[1], ref texCoords[2], ref texCoords[3]); //cowboy: don't forget the middle texture coordinate regardless of rotation. texCoords[4].X = 0.5f; texCoords[4].Y = 0.5f; vertices[0].X = TileX * Constants.TerrainGridSpacing; vertices[0].Y = (float)(tileTerrainHeight[0] * Map.HeightMultiplier); vertices[0].Z = -TileY * Constants.TerrainGridSpacing; vertices[1].X = (TileX + 1) * Constants.TerrainGridSpacing; vertices[1].Y = (float)(tileTerrainHeight[1] * Map.HeightMultiplier); vertices[1].Z = -TileY * Constants.TerrainGridSpacing; vertices[2].X = TileX * Constants.TerrainGridSpacing; vertices[2].Y = (float)(tileTerrainHeight[2] * Map.HeightMultiplier); vertices[2].Z = -(TileY + 1) * Constants.TerrainGridSpacing; vertices[3].X = (TileX + 1) * Constants.TerrainGridSpacing; vertices[3].Y = (float)(tileTerrainHeight[3] * Map.HeightMultiplier); vertices[3].Z = -(TileY + 1) * Constants.TerrainGridSpacing; vertices[4].X = (TileX + 0.5f) * Constants.TerrainGridSpacing; vertices[4].Y = (float)(tileTerrainHeight[4] * Map.HeightMultiplier); vertices[4].Z = -(TileY + 0.5f) * Constants.TerrainGridSpacing; normals[0] = Map.TerrainVertexNormalCalc(TileX, TileY); normals[1] = Map.TerrainVertexNormalCalc(TileX + 1, TileY); normals[2] = Map.TerrainVertexNormalCalc(TileX, TileY + 1); normals[3] = Map.TerrainVertexNormalCalc(TileX + 1, TileY + 1); normals[4] = (normals[0] + normals[1] + normals[2] + normals[3]) / 4; //Linearly interpolate from corner vertices normals[4] /= normals[4].GetMagnitude(); //normalize vector length GL.Begin(BeginMode.Triangles); int[] indices = { 1, 0, 4, 3, 1, 4, 2, 3, 4, 0, 2, 4 }; foreach (var i in indices) { GL.Normal3(normals[i].X, normals[i].Y, -normals[i].Z); GL.TexCoord2(texCoords[i].X, texCoords[i].Y); GL.Vertex3(vertices[i].X, vertices[i].Y, -vertices[i].Z); } GL.End(); }