protected override void DrawModel(Player p) { IGraphicsApi api = game.Graphics; api.BindTexture(GetTexture(p.MobTextureId)); DrawHeadRotate(-p.PitchRadians, 0, 0, Head); DrawPart(Torso); DrawRotate(p.anim.legXRot, 0, 0, LeftLegFront); DrawRotate(-p.anim.legXRot, 0, 0, RightLegFront); DrawRotate(-p.anim.legXRot, 0, 0, LeftLegBack); DrawRotate(p.anim.legXRot, 0, 0, RightLegBack); UpdateVB(); if (!Fur) { return; } ModelCache cache = game.ModelCache; api.BindTexture(cache.Textures[furIndex].TexID); DrawHeadRotate(-p.PitchRadians, 0, 0, FurHead); DrawPart(FurTorso); DrawRotate(p.anim.legXRot, 0, 0, FurLeftLegFront); DrawRotate(-p.anim.legXRot, 0, 0, FurRightLegFront); DrawRotate(-p.anim.legXRot, 0, 0, FurLeftLegBack); DrawRotate(p.anim.legXRot, 0, 0, FurRightLegBack); UpdateVB(); }
// Render solid and fully transparent to fill depth buffer. // These blocks are treated as having an alpha value of either none or full. void RenderNormalChunks(double deltaTime) { int[] texIds = game.TerrainAtlas1D.TexIds; gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.Texturing = true; gfx.AlphaTest = true; for (int batch = 0; batch < _1DUsed; batch++) { if (totalUsed[batch] <= 0) { continue; } if (pendingNormal[batch] || usedNormal[batch]) { gfx.BindTexture(texIds[batch]); RenderNormalBatch(batch); pendingNormal[batch] = false; } } CheckWeather(deltaTime); gfx.AlphaTest = false; gfx.Texturing = false; #if DEBUG_OCCLUSION DebugPickedPos(); #endif }
public void Render(double delta, float t) { if (terrainCount == 0 && rainCount == 0) { return; } IGraphicsApi graphics = game.Graphics; graphics.Texturing = true; graphics.AlphaTest = true; graphics.SetBatchFormat(VertexFormat.Pos3fTex2fCol4b); int count = RenderParticles(terrainParticles, terrainCount, delta, t); if (count > 0) { graphics.BindTexture(game.TerrainAtlas.TexId); graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, vb, vertices, count, count * 6 / 4); } count = RenderParticles(rainParticles, rainCount, delta, t); if (count > 0) { graphics.BindTexture(ParticlesTexId); graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, vb, vertices, count, count * 6 / 4); } graphics.AlphaTest = false; graphics.Texturing = false; }
/// <inheritdoc/> public override void DrawModel(Entity p) { IGraphicsApi gfx = game.Graphics; gfx.BindTexture(GetTexture(p)); DrawRotate(-p.HeadXRadians, 0, 0, Head, true); DrawPart(Torso); DrawRotate(p.anim.leftLegX, 0, 0, LeftLegFront, false); DrawRotate(p.anim.rightLegX, 0, 0, RightLegFront, false); DrawRotate(p.anim.rightLegX, 0, 0, LeftLegBack, false); DrawRotate(p.anim.leftLegX, 0, 0, RightLegBack, false); UpdateVB(); if (Utils.CaselessEquals(p.ModelName, "sheep_nofur")) { return; } ModelCache cache = game.ModelCache; gfx.BindTexture(cache.Textures[furIndex].TexID); DrawRotate(-p.HeadXRadians, 0, 0, FurHead, true); DrawPart(FurTorso); DrawRotate(p.anim.leftLegX, 0, 0, FurLeftLegFront, false); DrawRotate(p.anim.rightLegX, 0, 0, FurRightLegFront, false); DrawRotate(p.anim.rightLegX, 0, 0, FurLeftLegBack, false); DrawRotate(p.anim.leftLegX, 0, 0, FurRightLegBack, false); UpdateVB(); }
/// <summary> Renders all opaque and transparent blocks. </summary> /// <remarks> Pixels are either treated as fully replacing existing pixel, or skipped. </remarks> public void RenderNormal(double deltaTime) { if (chunks == null) { return; } int[] texIds = game.TerrainAtlas1D.TexIds; gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.Texturing = true; gfx.AlphaTest = true; gfx.EnableMipmaps(); for (int batch = 0; batch < _1DUsed; batch++) { if (normalPartsCount[batch] <= 0) { continue; } if (pendingNormal[batch] || usedNormal[batch]) { gfx.BindTexture(texIds[batch]); RenderNormalBatch(batch); pendingNormal[batch] = false; } } gfx.DisableMipmaps(); CheckWeather(deltaTime); gfx.AlphaTest = false; gfx.Texturing = false; #if DEBUG_OCCLUSION DebugPickedPos(); #endif }
public void Render(double deltaTime) { if (sidesVb == -1 || edgesVb == -1) { return; } graphics.Texturing = true; graphics.AlphaTest = true; graphics.BindTexture(sideTexId); graphics.SetBatchFormat(VertexFormat.Pos3fTex2fCol4b); if (game.Map.SidesBlock != Block.Air) { graphics.BindVb(sidesVb); graphics.DrawIndexedVb_TrisT2fC4b(sidesVertices * 6 / 4, 0); } graphics.AlphaBlending = true; graphics.BindTexture(edgeTexId); graphics.BindVb(edgesVb); // Do not draw water when we cannot see it. // Fixes some 'depth bleeding through' issues with 16 bit depth buffers on large maps. float yVisible = Math.Min(0, map.SidesHeight); if (game.Map.EdgeBlock != Block.Air && game.CurrentCameraPos.Y >= yVisible) { graphics.DrawIndexedVb_TrisT2fC4b(edgesVertices * 6 / 4, 0); } graphics.AlphaBlending = false; graphics.Texturing = false; graphics.AlphaTest = false; }
public void RenderEdges(double delta) { if (edgesVb == -1) { return; } BlockID block = game.World.Env.EdgeBlock; IGraphicsApi gfx = game.Graphics; Vector3 camPos = game.CurrentCameraPos; gfx.Texturing = true; gfx.SetupAlphaState(BlockInfo.Draw[block]); gfx.EnableMipmaps(); gfx.BindTexture(edgeTexId); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(edgesVb); // Do not draw water when we cannot see it. // Fixes some 'depth bleeding through' issues with 16 bit depth buffers on large maps. float yVisible = Math.Min(0, map.Env.SidesHeight); if (camPos.Y >= yVisible) { gfx.DrawVb_IndexedTris(edgesVertices); } gfx.DisableMipmaps(); gfx.RestoreAlphaState(BlockInfo.Draw[block]); gfx.Texturing = false; }
void RenderRainParticles(IGraphicsApi gfx, Particle[] particles, int elems, double delta, float t) { int count = elems * 4; if (count > vertices.Length) { vertices = new VertexP3fT2fC4b[count]; } int index = 0; for (int i = 0; i < elems; i++) { particles[i].Render(game, delta, t, vertices, ref index); } int drawCount = Math.Min(count, maxParticles * 4); if (drawCount == 0) { return; } gfx.BindTexture(ParticlesTexId); gfx.UpdateDynamicIndexedVb(DrawMode.Triangles, vb, vertices, drawCount); }
protected override void DrawModel(Player p) { // TODO: using 'is' is ugly, but means we can avoid creating // a string every single time held block changes. if (p is FakePlayer) { Player realP = game.LocalPlayer; col = game.World.IsLit(realP.EyePosition) ? game.World.Env.Sunlight : game.World.Env.Shadowlight; // Adjust pitch so angle when looking straight down is 0. float adjPitch = realP.PitchDegrees - 90; if (adjPitch < 0) { adjPitch += 360; } // Adjust colour so held block is brighter when looking straght up float t = Math.Abs(adjPitch - 180) / 180; float colScale = Utils.Lerp(0.9f, 0.7f, t); col = FastColour.Scale(col, colScale); block = ((FakePlayer)p).Block; } else { block = Utils.FastByte(p.ModelName); } CalcState(block); colPacked = col.Pack(); if (game.BlockInfo.IsAir[block]) { return; } lastTexId = -1; atlas = game.TerrainAtlas1D; bool sprite = game.BlockInfo.IsSprite[block]; DrawParts(sprite); if (index == 0) { return; } IGraphicsApi api = game.Graphics; api.BindTexture(lastTexId); TransformVertices(); if (sprite) { api.FaceCulling = true; } UpdateVB(); if (sprite) { api.FaceCulling = false; } }
void RenderClouds(double delta) { if (game.World.Env.CloudHeight < -2000) { return; } double time = game.accumulator; float offset = (float)(time / 2048f * 0.6f * map.Env.CloudsSpeed); IGraphicsApi gfx = game.Graphics; gfx.SetMatrixMode(MatrixType.Texture); Matrix4 matrix = Matrix4.Identity; matrix.Row3.X = offset; // translate X axis gfx.LoadMatrix(ref matrix); gfx.SetMatrixMode(MatrixType.Modelview); gfx.AlphaTest = true; gfx.Texturing = true; gfx.BindTexture(cloudsTex); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(cloudsVb); gfx.DrawVb_IndexedTris(cloudVertices); gfx.AlphaTest = false; gfx.Texturing = false; gfx.SetMatrixMode(MatrixType.Texture); gfx.LoadIdentityMatrix(); gfx.SetMatrixMode(MatrixType.Modelview); }
protected void DrawName() { if (nameTex.ID == 0) { MakeNameTexture(); } if (nameTex.ID == -1) { return; } IGraphicsApi api = game.Graphics; api.BindTexture(nameTex.ID); Vector3 pos = Position; pos.Y += Model.NameYOffset * ModelScale; float scale = Math.Min(1, Model.NameScale * ModelScale) / 70f; Vector3 p111, p121, p212, p222; int col = FastColour.WhitePacked; Vector2 size = new Vector2(nameTex.Width * scale, nameTex.Height * scale); Utils.CalcBillboardPoints(size, pos, ref game.View, out p111, out p121, out p212, out p222); api.texVerts[0] = new VertexP3fT2fC4b(ref p111, nameTex.U1, nameTex.V2, col); api.texVerts[1] = new VertexP3fT2fC4b(ref p121, nameTex.U1, nameTex.V1, col); api.texVerts[2] = new VertexP3fT2fC4b(ref p222, nameTex.U2, nameTex.V1, col); api.texVerts[3] = new VertexP3fT2fC4b(ref p212, nameTex.U2, nameTex.V2, col); api.SetBatchFormat(VertexFormat.P3fT2fC4b); api.UpdateDynamicIndexedVb(DrawMode.Triangles, api.texVb, api.texVerts, 4); }
public static void Draw(Game game, byte block, float size, float x, float y) { info = game.BlockInfo; cache = game.ModelCache; atlas = game.TerrainAtlas1D; minBB = info.MinBB[block]; maxBB = info.MaxBB[block]; fullBright = info.FullBright[block]; if (info.IsSprite[block]) { minBB = Vector3.Zero; maxBB = Vector3.One; } if (info.IsAir[block]) { return; } index = 0; api = game.Graphics; // isometric coords size: cosY * -scale - sinY * scale // we need to divide by (2 * cosY), as the calling function expects size to be in pixels. scale = size / (2 * cosY); // screen to isometric coords (cos(-x) = cos(x), sin(-x) = -sin(x)) pos.X = x; pos.Y = y; pos.Z = 0; pos = Utils.RotateY(Utils.RotateX(pos, cosX, -sinX), cosY, -sinY); if (info.IsSprite[block]) { SpriteXQuad(block, TileSide.Right, false); SpriteZQuad(block, TileSide.Back, false); SpriteZQuad(block, TileSide.Back, true); SpriteXQuad(block, TileSide.Right, true); } else { XQuad(block, Make(maxBB.X), TileSide.Left); ZQuad(block, Make(minBB.Z), TileSide.Back); YQuad(block, Make(maxBB.Y), TileSide.Top); } if (index == 0) { return; } if (atlas.TexIds[texIndex] != lastTexId) { lastTexId = atlas.TexIds[texIndex]; api.BindTexture(lastTexId); } for (int i = 0; i < index; i++) { TransformVertex(ref cache.vertices[i]); } api.UpdateDynamicIndexedVb(DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4); }
// Render solid and fully transparent to fill depth buffer. // These blocks are treated as having an alpha value of either none or full. void RenderNormal() { int[] texIds = game.TerrainAtlas1D.TexIds; api.SetBatchFormat(VertexFormat.Pos3fTex2fCol4b); api.Texturing = true; api.AlphaTest = true; for (int batch = 0; batch < _1DUsed; batch++) { if (pendingNormal[batch] || usedNormal[batch]) { api.BindTexture(texIds[batch]); RenderNormalBatch(batch); pendingNormal[batch] = false; } } api.AlphaTest = false; api.Texturing = false; DebugPickedPos(); }
public void RenderSides(double delta) { if (sidesVb == -1) { return; } BlockID block = game.World.Env.SidesBlock; gfx.Texturing = true; gfx.SetupAlphaState(BlockInfo.Draw[block]); gfx.EnableMipmaps(); gfx.BindTexture(sideTexId); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(sidesVb); gfx.DrawVb_IndexedTris(sidesVertices); gfx.DisableMipmaps(); gfx.RestoreAlphaState(BlockInfo.Draw[block]); gfx.Texturing = false; }
public void RenderSides(double delta) { if (sidesVb == -1) { return; } byte block = game.World.Env.SidesBlock; if (game.BlockInfo.IsAir[block]) { return; } graphics.Texturing = true; graphics.AlphaTest = true; graphics.BindTexture(sideTexId); graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); graphics.BindVb(sidesVb); graphics.DrawIndexedVb_TrisT2fC4b(sidesVertices * 6 / 4, 0); graphics.Texturing = false; graphics.AlphaTest = false; }
public void RenderSides(double delta) { if (sidesVb == -1) { return; } BlockID block = game.World.Env.SidesBlock; if (game.BlockInfo.Draw[block] == DrawType.Gas) { return; } gfx.SetupAlphaState(game.BlockInfo.Draw[block]); gfx.Texturing = true; gfx.BindTexture(sideTexId); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(sidesVb); gfx.DrawIndexedVb_TrisT2fC4b(sidesVertices * 6 / 4, 0); gfx.RestoreAlphaState(game.BlockInfo.Draw[block]); gfx.Texturing = false; }
public override void Render(double delta) { IGraphicsApi gfx = game.Graphics; if (!texture.IsValid) { return; } Texture back = Active ? selectedTex : shadowTex; if (Disabled) { back = disabledTex; } back.ID = game.UseClassicGui ? game.Gui.GuiClassicTex : game.Gui.GuiTex; back.X1 = X; back.Y1 = Y; back.Width = (ushort)Width; back.Height = (ushort)Height; if (Width == 400) { // Button can be drawn normally back.U1 = 0; back.U2 = uWidth; back.Render(gfx); } else { // Split button down the middle float scale = (Width / 400f) * 0.5f; gfx.BindTexture(back.ID); // avoid bind twice back.Width = (ushort)(Width / 2); back.U1 = 0; back.U2 = uWidth * scale; gfx.Draw2DTexture(ref back, FastColour.White); back.X1 += (short)(Width / 2); back.U1 = uWidth - uWidth * scale; back.U2 = uWidth; gfx.Draw2DTexture(ref back, FastColour.White); } FastColour col = Disabled ? disabledCol : (Active ? activeCol : normCol); texture.Render(gfx, col); }
protected void DrawName() { IGraphicsApi api = game.Graphics; api.BindTexture(nameTex.ID); Vector3 pos = Position; pos.Y += Model.NameYOffset; Vector3 p111, p121, p212, p222; FastColour col = FastColour.White; Vector2 size = new Vector2(nameTex.Width / 70f, nameTex.Height / 70f); Utils.CalcBillboardPoints(size, pos, ref game.View, out p111, out p121, out p212, out p222); api.texVerts[0] = new VertexPos3fTex2fCol4b(p111, nameTex.U1, nameTex.V2, col); api.texVerts[1] = new VertexPos3fTex2fCol4b(p121, nameTex.U1, nameTex.V1, col); api.texVerts[2] = new VertexPos3fTex2fCol4b(p222, nameTex.U2, nameTex.V1, col); api.texVerts[3] = new VertexPos3fTex2fCol4b(p212, nameTex.U2, nameTex.V2, col); api.SetBatchFormat(VertexFormat.Pos3fTex2fCol4b); api.UpdateDynamicIndexedVb(DrawMode.Triangles, api.texVb, api.texVerts, 4, 6); }
protected void DrawName() { if (nameTex.ID == 0) { MakeNameTexture(); } if (nameTex.ID == -1) { return; } IGraphicsApi gfx = game.Graphics; gfx.BindTexture(nameTex.ID); Vector3 pos; Model.RecalcProperties(this); Vector3.TransformY(Model.NameYOffset, ref transform, out pos); float scale = Math.Min(1, Model.NameScale * ModelScale.Y) / 70f; int col = FastColour.WhitePacked; Vector2 size = new Vector2(nameTex.Width * scale, nameTex.Height * scale); if (game.Entities.NamesMode == NameMode.AllUnscaled && game.LocalPlayer.Hacks.CanSeeAllNames) { // Get W component of transformed position Matrix4 mat; Matrix4.Mult(out mat, ref gfx.View, ref gfx.Projection); // TODO: This mul is slow, avoid it float tempW = pos.X * mat.Row0.W + pos.Y * mat.Row1.W + pos.Z * mat.Row2.W + mat.Row3.W; size.X *= tempW * 0.2f; size.Y *= tempW * 0.2f; } int index = 0; TextureRec rec; rec.U1 = 0; rec.V1 = 0; rec.U2 = nameTex.U2; rec.V2 = nameTex.V2; Particle.DoRender(ref gfx.View, ref size, ref pos, ref rec, col, gfx.texVerts, ref index); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.UpdateDynamicVb_IndexedTris(gfx.texVb, gfx.texVerts, 4); }
static void FlushIfNotSame() { int texId = atlas.TexIds[texIndex]; if (texId == lastTexId) { return; } if (lastTexId != -1) { for (int i = 0; i < index; i++) { TransformVertex(ref cache.vertices[i]); } api.UpdateDynamicIndexedVb(DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4); index = 0; } lastTexId = texId; api.BindTexture(texId); }
void RenderTerrainParticles(IGraphicsApi gfx, Particle[] particles, int elems, double delta, float t) { int count = elems * 4; if (count > vertices.Length) { vertices = new VertexP3fT2fC4b[count]; } Update1DCounts(particles, elems); for (int i = 0; i < elems; i++) { int index = particles[i].Get1DBatch(game); particles[i].Render(game, delta, t, vertices, ref terrain1DIndices[index]); } int drawCount = Math.Min(count, maxParticles * 4); if (drawCount == 0) { return; } gfx.SetDynamicVbData(vb, vertices, drawCount); int offset = 0; for (int i = 0; i < terrain1DCount.Length; i++) { int partCount = terrain1DCount[i]; if (partCount == 0) { continue; } gfx.BindTexture(game.TerrainAtlas1D.TexIds[i]); gfx.DrawIndexedVb(DrawMode.Triangles, partCount * 6 / 4, offset * 6 / 4); offset += partCount; } }
void RenderBorders(BlockID block, int vb, int tex, int count) { if (vb == 0) { return; } IGraphicsApi gfx = game.Graphics; gfx.Texturing = true; gfx.SetupAlphaState(BlockInfo.Draw[block]); gfx.EnableMipmaps(); gfx.BindTexture(tex); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(vb); if (count > 0) { gfx.DrawVb_IndexedTris(count); } gfx.DisableMipmaps(); gfx.RestoreAlphaState(BlockInfo.Draw[block]); gfx.Texturing = false; }
public void Render( IGraphicsApi graphics, FastColour colour ) { graphics.BindTexture( ID ); graphics.Draw2DTexture( ref this, colour ); }
public void Render(double deltaTime) { Weather weather = map.Env.Weather; if (weather == Weather.Sunny) { return; } if (heightmap == null) { InitHeightmap(); } IGraphicsApi gfx = game.Graphics; gfx.BindTexture(weather == Weather.Rainy ? rainTexId : snowTexId); Vector3 camPos = game.CurrentCameraPos; Vector3I pos = Vector3I.Floor(camPos); bool moved = pos != lastPos; lastPos = pos; WorldEnv env = game.World.Env; float speed = (weather == Weather.Rainy ? 1.0f : 0.2f) * env.WeatherSpeed; float vOffset = (float)game.accumulator * speed; rainAcc += deltaTime; bool particles = weather == Weather.Rainy; int vCount = 0; PackedCol col = game.World.Env.Sun; VertexP3fT2fC4b v = default(VertexP3fT2fC4b); for (int dx = -extent; dx <= extent; dx++) { for (int dz = -extent; dz <= extent; dz++) { int x = pos.X + dx, z = pos.Z + dz; float y = RainHeight(x, z); float height = Math.Max(game.World.Height, pos.Y + 64) - y; if (height <= 0) { continue; } if (particles && (rainAcc >= 0.25 || moved)) { game.ParticleManager.AddRainParticle(new Vector3(x, y, z)); } float alpha = AlphaAt(dx * dx + dz * dz); Utils.Clamp(ref alpha, 0, 0xFF); col.A = (byte)alpha; // NOTE: Making vertex is inlined since this is called millions of times. v.Col = col; float worldV = vOffset + (z & 1) / 2f - (x & 0x0F) / 16f; float v1 = y / 6f + worldV, v2 = (y + height) / 6f + worldV; float x1 = x, y1 = y, z1 = z; float x2 = x + 1, y2 = y + height, z2 = z + 1; v.X = x1; v.Y = y1; v.Z = z1; v.U = 0; v.V = v1; vertices[vCount++] = v; v.Y = y2; v.V = v2; vertices[vCount++] = v; v.X = x2; v.Z = z2; v.U = 1; vertices[vCount++] = v; v.Y = y1; v.V = v1; vertices[vCount++] = v; v.Z = z1; vertices[vCount++] = v; v.Y = y2; v.V = v2; vertices[vCount++] = v; v.X = x1; v.Z = z2; v.U = 0; vertices[vCount++] = v; v.Y = y1; v.V = v1; vertices[vCount++] = v; } } if (particles && (rainAcc >= 0.25 || moved)) { rainAcc = 0; } if (vCount == 0) { return; } gfx.AlphaTest = false; gfx.DepthWrite = false; gfx.AlphaArgBlend = true; gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.UpdateDynamicVb_IndexedTris(vb, vertices, vCount); gfx.AlphaArgBlend = false; gfx.AlphaTest = true; gfx.DepthWrite = true; }
public void Render( IGraphicsApi graphics ) { graphics.BindTexture( ID ); graphics.Draw2DTexture( ref this ); }
public static void Draw( Game game, byte block, float size, float x, float y ) { info = game.BlockInfo; cache = game.ModelCache; atlas = game.TerrainAtlas1D; minBB = info.MinBB[block]; maxBB = info.MaxBB[block]; fullBright = info.FullBright[block]; if( info.IsSprite[block] ) { minBB = Vector3.Zero; maxBB = Vector3.One; } if( info.IsAir[block] ) return; index = 0; api = game.Graphics; // isometric coords size: cosY * -scale - sinY * scale // we need to divide by (2 * cosY), as the calling function expects size to be in pixels. scale = size / (2 * cosY); // screen to isometric coords (cos(-x) = cos(x), sin(-x) = -sin(x)) pos.X = x; pos.Y = y; pos.Z = 0; Utils.RotateX( ref pos.Y, ref pos.Z, cosX, -sinX ); Utils.RotateY( ref pos.X, ref pos.Z, cosY, -sinY ); if( info.IsSprite[block] ) { SpriteXQuad( block, Side.Right, false ); SpriteZQuad( block, Side.Back, false ); SpriteZQuad( block, Side.Back, true ); SpriteXQuad( block, Side.Right, true ); } else { XQuad( block, Make( maxBB.X ), Side.Left ); ZQuad( block, Make( minBB.Z ), Side.Back ); YQuad( block, Make( maxBB.Y ), Side.Top ); } if( index == 0 ) return; if( atlas.TexIds[texIndex] != lastTexId ) { lastTexId = atlas.TexIds[texIndex]; api.BindTexture( lastTexId ); } for( int i = 0; i < index; i++ ) TransformVertex( ref cache.vertices[i] ); api.UpdateDynamicIndexedVb( DrawMode.Triangles, cache.vb, cache.vertices, index, index * 6 / 4 ); }
public void Render(IGraphicsApi gfx, FastColour colour) { gfx.BindTexture(ID); gfx.Draw2DTexture(ref this, colour); }
public void Render(IGraphicsApi gfx) { gfx.BindTexture(ID); gfx.Draw2DTexture(ref this, PackedCol.White); }
/// <summary> Renders all translucent (e.g. water) blocks. </summary> /// <remarks> Pixels drawn blend into existing geometry. </remarks> public void RenderTranslucent(double deltaTime) { if (chunks == null) { return; } IGraphicsApi gfx = game.Graphics; // First fill depth buffer int vertices = game.Vertices; gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.Texturing = false; gfx.AlphaBlending = false; gfx.ColourWriteMask(false, false, false, false); for (int batch = 0; batch < _1DUsed; batch++) { if (translucentPartsCount[batch] <= 0) { continue; } if (pendingTranslucent[batch] || usedTranslucent[batch]) { RenderTranslucentBatch(batch); pendingTranslucent[batch] = false; } } game.Vertices = vertices; // Then actually draw the transluscent blocks gfx.AlphaBlending = true; gfx.Texturing = true; gfx.ColourWriteMask(true, true, true, true); gfx.DepthWrite = false; // we already calculated depth values in depth pass int[] texIds = TerrainAtlas1D.TexIds; gfx.EnableMipmaps(); for (int batch = 0; batch < _1DUsed; batch++) { if (translucentPartsCount[batch] <= 0) { continue; } if (!usedTranslucent[batch]) { continue; } gfx.BindTexture(texIds[batch]); RenderTranslucentBatch(batch); } gfx.DisableMipmaps(); gfx.DepthWrite = true; // If we weren't under water, render weather after to blend properly if (!inTranslucent && game.World.Env.Weather != Weather.Sunny) { gfx.AlphaTest = true; game.WeatherRenderer.Render(deltaTime); gfx.AlphaTest = false; } gfx.AlphaBlending = false; gfx.Texturing = false; }
public void Render(double deltaTime) { Weather weather = map.Env.Weather; if (weather == Weather.Sunny) { return; } if (heightmap == null) { InitHeightmap(); } graphics.BindTexture(weather == Weather.Rainy ? RainTexId : SnowTexId); Vector3 camPos = game.CurrentCameraPos; Vector3I pos = Vector3I.Floor(camPos); bool moved = pos != lastPos; lastPos = pos; WorldEnv env = game.World.Env; float speed = (weather == Weather.Rainy ? 1.0f : 0.2f) * env.WeatherSpeed; vOffset = (float)game.accumulator * speed; rainAcc += deltaTime; bool particles = weather == Weather.Rainy; int index = 0; FastColour col = game.World.Env.Sunlight; for (int dx = -extent; dx <= extent; dx++) { for (int dz = -extent; dz <= extent; dz++) { float rainY = GetRainHeight(pos.X + dx, pos.Z + dz); float height = Math.Max(game.World.Height, pos.Y + 64) - rainY; if (height <= 0) { continue; } if (particles && (rainAcc >= 0.25 || moved)) { game.ParticleManager.AddRainParticle(new Vector3(pos.X + dx, rainY, pos.Z + dz)); } float alpha = AlphaAt(dx * dx + dz * dz); Utils.Clamp(ref alpha, 0, 0xFF); col.A = (byte)alpha; MakeRainForSquare(pos.X + dx, rainY, height, pos.Z + dz, col, ref index); } } if (particles && (rainAcc >= 0.25 || moved)) { rainAcc = 0; } if (index == 0) { return; } graphics.AlphaTest = false; graphics.DepthWrite = false; graphics.AlphaArgBlend = true; graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, weatherVb, vertices, index, index * 6 / 4); graphics.AlphaArgBlend = false; graphics.AlphaTest = true; graphics.DepthWrite = true; }
public void Render(IGraphicsApi gfx, PackedCol col) { gfx.BindTexture(ID); gfx.Draw2DTexture(ref this, col); }
public void Render(double delta) { if (game.Graphics.LostContext) { return; } IGraphicsApi gfx = game.Graphics; #if !USE_DX && !ANDROID gfx.AlphaBlending = true; //gfx.DepthWrite = false; gfx.DrawLine(new Vector3(pos2.X, pos2.Y, pos2.Z), new Vector3(pos1.X, pos2.Y, pos2.Z)); gfx.DrawLine(new Vector3(pos1.X, pos2.Y, pos2.Z), new Vector3(pos1.X, pos2.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos1.X, pos2.Y, pos1.Z), new Vector3(pos2.X, pos2.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos2.X, pos2.Y, pos1.Z), new Vector3(pos2.X, pos2.Y, pos2.Z)); gfx.DrawLine(new Vector3(pos2.X, pos2.Y, pos2.Z), new Vector3(pos2.X, pos1.Y, pos2.Z)); gfx.DrawLine(new Vector3(pos1.X, pos2.Y, pos2.Z), new Vector3(pos1.X, pos1.Y, pos2.Z)); gfx.DrawLine(new Vector3(pos1.X, pos2.Y, pos1.Z), new Vector3(pos1.X, pos1.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos2.X, pos2.Y, pos1.Z), new Vector3(pos2.X, pos1.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos2.X, pos1.Y, pos2.Z), new Vector3(pos1.X, pos1.Y, pos2.Z)); gfx.DrawLine(new Vector3(pos1.X, pos1.Y, pos2.Z), new Vector3(pos1.X, pos1.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos1.X, pos1.Y, pos1.Z), new Vector3(pos2.X, pos1.Y, pos1.Z)); gfx.DrawLine(new Vector3(pos2.X, pos1.Y, pos1.Z), new Vector3(pos2.X, pos1.Y, pos2.Z)); //gfx.DepthWrite = true; gfx.AlphaBlending = false; #else gfx.AlphaBlending = true; gfx.DepthWrite = false; gfx.SetBatchFormat(VertexFormat.P3fC4b); gfx.UpdateDynamicVb_IndexedTris(vb, vertices, index); gfx.DepthWrite = true; gfx.AlphaBlending = false; #endif if (pickingBlock) { //gfx.AlphaTest = true; gfx.Texturing = true; //gfx.AlphaTest = true; gfx.AlphaBlending = true; gfx.FaceCulling = true; float[] texCols = new float[4]; texCols[0] = (127f / 256f); texCols[1] = (127f / 256f); texCols[2] = (127f / 256f); texCols[3] = (128f / 256f); /*GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Combine); * //GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.CombineRgb, (int)TextureEnvModeCombine.Subtract); * GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.CombineAlpha, (int)TextureEnvModeCombine.Subtract); * GL.TexEnvfv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvColor, texCols); * //GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.Source0Rgb, (int)TextureEnvModeSource.Texture); * GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src0Alpha, (int)TextureEnvModeSource.PrimaryColor); * //GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src1Rgb, (int)TextureEnvModeSource.Constant); * GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src1Alpha, (int)TextureEnvModeSource.Constant);*/ //GL.Enable(EnableCap.ColorMaterial); //graphics.AlphaTestFunc(CompareFunc.Greater, 0.0f); //GL.BlendFuncSeparate(BlendingFactor.DstColor, BlendingFactor.SrcColor, BlendingFactor.DstAlpha, BlendingFactor.DstAlpha); graphics.RGBAlphaBlendFunc(BlendFunc.DestColor, BlendFunc.SourceColor, BlendFunc.DestAlpha, BlendFunc.SourceAlpha); //VertexP3fT2fC4b[] vertices2 = new VertexP3fT2fC4b[8 * 10 * (4 * 4)]; //game.Graphics.CreateDynamicVb(VertexFormat.P3fT2fC4b, vertices.Length); gfx.BindTexture(pickTexId); gfx.SetBatchFormat(VertexFormat.P3fT2fC4b); gfx.BindVb(vb2); gfx.UpdateDynamicVb_IndexedTris(vb2, vertices2, index2); //graphics.AlphaBlendFunc(BlendFunc.SourceAlpha, BlendFunc.InvSourceAlpha); graphics.AlphaBlendFunc(BlendFunc.SourceAlpha, BlendFunc.InvSourceAlpha); //graphics.AlphaTestFunc(CompareFunc.Greater, 0.5f); //GL.Disable(EnableCap.ColorMaterial); //GL.TexEnvi(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate); gfx.FaceCulling = false; gfx.AlphaBlending = false; //gfx.AlphaTest = false; gfx.Texturing = false; //gfx.AlphaTest = false; } }
unsafe void RenderTerrainParticles(IGraphicsApi gfx, TerrainParticle[] particles, int elems, double delta, float t) { int count = elems * 4; if (count > vertices.Length) { vertices = new VertexP3fT2fC4b[count]; } Update1DCounts(particles, elems); for (int i = 0; i < elems; i++) { int index = Atlas1D.Get1DIndex(particles[i].texLoc); particles[i].Render(game, t, vertices, ref terrain1DIndices[index]); } int drawCount = Math.Min(count, maxParticles * 4); if (drawCount == 0) { return; fixed(VertexP3fT2fC4b *ptr = vertices) { gfx.SetDynamicVbData(vb, (IntPtr)ptr, drawCount); int offset = 0; for (int i = 0; i < Atlas1D.AtlasesCount; i++) { int partCount = terrain1DCount[i]; if (partCount == 0) { continue; } gfx.BindTexture(Atlas1D.TexIds[i]); gfx.DrawVb_IndexedTris(partCount, offset); offset += partCount; } } } void Update1DCounts(TerrainParticle[] particles, int elems) { for (int i = 0; i < Atlas1D.MaxAtlases; i++) { terrain1DCount[i] = 0; terrain1DIndices[i] = 0; } for (int i = 0; i < elems; i++) { int index = Atlas1D.Get1DIndex(particles[i].texLoc); terrain1DCount[index] += 4; } for (int i = 1; i < Atlas1D.AtlasesCount; i++) { terrain1DIndices[i] = terrain1DIndices[i - 1] + terrain1DCount[i - 1]; } } void RenderRainParticles(IGraphicsApi gfx, RainParticle[] particles, int elems, double delta, float t) { int count = elems * 4; if (count > vertices.Length) { vertices = new VertexP3fT2fC4b[count]; } int index = 0; for (int i = 0; i < elems; i++) { particles[i].Render(game, t, vertices, ref index); } int drawCount = Math.Min(count, maxParticles * 4); if (drawCount == 0) { return; } gfx.BindTexture(ParticlesTexId); gfx.UpdateDynamicVb_IndexedTris(vb, vertices, drawCount); }