public void SetAnimated(int ID, double rate, string[] textures, int tid, int oSpot) { for (int i = 0; i < textures.Length; i++) { TEngine.LoadTextureIntoArray(textures[i], ID + i, TWidth); } GraphicsUtil.CheckError("TextureBlock - SetAnimated - TENG"); if (oSpot > 0) { GL.BindTexture(TextureTarget.Texture2DArray, HelpTextureID); double time = rate * 32; int id_z = oSpot / (TWidth * TWidth); int id_xy = oSpot % (TWidth * TWidth); int ix = id_xy % TWidth; int iy = id_xy / TWidth; // ARGB float[] t = new float[4] { (float)time / 256f, textures.Length / 256f, 0.0f, 1.0f }; GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, ix, iy, id_z, 1, 1, 1, OpenTK.Graphics.OpenGL4.PixelFormat.Rgba, PixelType.Float, t); GraphicsUtil.CheckError("TextureBlock - SetAnimated - OSp"); } }
/// <summary> /// Calculates and loads some light helper information. /// </summary> public void LoadLightHelpers() { c_FBO = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, c_FBO); c_FBO_Tex = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, c_FBO_Tex); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Window.Width / Pixelation, Window.Height / Pixelation, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (uint)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (uint)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (uint)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (uint)TextureWrapMode.ClampToEdge); GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, c_FBO_Tex, 0); l_FBO = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, l_FBO); l_FBO_Tex = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, l_FBO_Tex); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, Window.Width / Pixelation, Window.Height / Pixelation, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (uint)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (uint)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (uint)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (uint)TextureWrapMode.ClampToEdge); GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, l_FBO_Tex, 0); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.BindTexture(TextureTarget.Texture2D, 0); GraphicsUtil.CheckError("LoadLightHelpers"); }
/// <summary> /// Builds or rebuilds the the light sources for the world. /// TODO: Call this whenenver render distance changes! /// </summary> public void BuildLightsForWorld() { if (TheSun != null) { TheSun.Destroy(); MainWorldView.Lights.Remove(TheSun); TheSunClouds.Destroy(); MainWorldView.Lights.Remove(TheSunClouds); ThePlanet.Destroy(); MainWorldView.Lights.Remove(ThePlanet); } GraphicsUtil.CheckError("Load - World - Deletes"); int wid = CVars.r_shadowquality.ValueI; TheSun = new SkyLight(Location.Zero, MaximumStraightBlockDistance() * 2, SunLightDef, new Location(0, 0, -1), MaximumStraightBlockDistance() * 2 + Chunk.CHUNK_SIZE * 2, false, wid); MainWorldView.Lights.Add(TheSun); GraphicsUtil.CheckError("Load - World - Sun"); // TODO: Separate cloud quality CVar? TheSunClouds = new SkyLight(Location.Zero, MaximumStraightBlockDistance() * 2, CloudSunLightDef, new Location(0, 0, -1), MaximumStraightBlockDistance() * 2 + Chunk.CHUNK_SIZE * 2, true, wid); MainWorldView.Lights.Add(TheSunClouds); GraphicsUtil.CheckError("Load - World - Clouds"); // TODO: Separate planet quality CVar? ThePlanet = new SkyLight(Location.Zero, MaximumStraightBlockDistance() * 2, PlanetLightDef, new Location(0, 0, -1), MaximumStraightBlockDistance() * 2 + Chunk.CHUNK_SIZE * 2, false, wid); MainWorldView.Lights.Add(ThePlanet); GraphicsUtil.CheckError("Load - World - Planet"); OnCloudShadowChanged(null, null); GraphicsUtil.CheckError("Load - World - Changed"); }
public void SquishGrassSwing(Vector4 swinger) { if (!TheClient.CVars.r_compute.ValueB) { return; } Location spos = new Location(swinger.X, swinger.Y, swinger.Z); double maxdist = (swinger.W + Chunk.CHUNK_SIZE) * (swinger.W + Chunk.CHUNK_SIZE) * 4; GL.UseProgram(Shader_Compute_Grass_Swing); foreach (Chunk chk in LoadedChunks.Values) { Location cwor = chk.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE; Location wpos = cwor + new Location(Chunk.CHUNK_SIZE * 0.5); if (chk.Plant_C > 0 && chk.Plant_VAO > 0 && wpos.DistanceSquared(spos) < maxdist) { Location relp = spos - cwor; GL.Uniform1(11, (uint)chk.Plant_C); GL.Uniform4(12, new Vector4(ClientUtilities.Convert(relp), swinger.W)); GL.Uniform1(13, (float)GlobalTickTimeLocal); GL.Uniform1(14, (float)Delta); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, chk.Plant_VBO_Pos); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, chk.Plant_VBO_Tcs); GL.DispatchCompute(chk.Plant_C / 90 + 1, 1, 1); } } GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, 0); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, 0); GraphicsUtil.CheckError("Squishing Grass"); }
/// <summary> /// Renders all entities and render helpers. /// </summary> /// <param name="lights">Whether to include things that don't cast shadows.</param> /// <param name="shouldShadow">The method to determine if an object should cast a shadow.</param> private void RenderAll(bool lights, Func <ClientEntity, bool> shouldShadow) { try { StackNoteHelper.Push("GameEngine2D - RenderAll", this); Textures.White.Bind(); RenderHelper.SetColor(Vector4.One); RenderAllObjectsPre?.Invoke(lights); // This dups the list inherently, preventing glitches from removal while rendering, helpfully! foreach (ClientEntity ent in Entities.Values .Where((e) => ShouldRender(e.Renderer, lights) && (shouldShadow == null || shouldShadow(e))) .OrderBy((e) => e.Renderer.RenderingPriorityOrder)) { try { StackNoteHelper.Push("GameEngine2D - Render Specific Entity", ent); ent.Renderer.RenderStandard2D(MainRenderContext); } finally { StackNoteHelper.Pop(); } } RenderAllObjectsPost?.Invoke(lights); GraphicsUtil.CheckError("Render - all Entities rendered"); } finally { StackNoteHelper.Pop(); } }
/// <summary> /// Loads any additional final data. /// </summary> public override void PostLoad() { MainContext.Engine = this; FogMaxDist = () => ZFar(); GraphicsUtil.CheckError("PostLoad - Pre"); SysConsole.Output(OutputType.INIT, "GameEngine configuring graphics..."); GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Front); SysConsole.Output(OutputType.INIT, "GameEngine loading main 3D view..."); if (!IsSubEngine) { SubSize = new Vector2i(Window.Width, Window.Height); } MainView.Width = SubSize.X; MainView.Height = SubSize.Y; if (IsSubEngine) { MainView.GenerateFBO(); } MainView.Generate(this, SubSize.X, SubSize.Y); MainView.Render3D = Render3D; MainView.PostFirstRender = ReverseEntities; MainView.CameraUp = () => MainCamera.Up; AudioCamera = MainCamera; ZFar = () => MainCamera.ZFar; GraphicsUtil.CheckError("PostLoad - Post"); }
public void SetAnimated(int ID, double rate, Bitmap[] textures, int tid) { for (int i = 0; i < textures.Length; i++) { TEngine.LockBitmapToTexture(textures[i], ID + i); } GraphicsUtil.CheckError("TextureBlock - SetAnimated - TENG"); }
public void RenderLoader(float x, float y, float size, double delta) { // TODO: 2D Logic version! Shaders.ColorMultShader.Bind(); RenderLoadIconV2(x, y, size, delta); Shaders.ColorMult2DShader.Bind(); GraphicsUtil.CheckError("RenderLoader"); }
/// <summary> /// Loads all shaders for the standard Game Engine 2D. /// </summary> public override void GetShaders() { Shader_Lightmap = Shaders.GetShader("lightmap2d"); Shader_Lightmap1D = Shaders.GetShader("lightmap1d_2d?line_densen"); Shader_Addlighttoscene = Shaders.GetShader("addlighttoscene2d"); Shader_Combine = Shaders.GetShader("combine2d"); Shader_ApplyLights1D = Shaders.GetShader("applylights1d_2d"); GraphicsUtil.CheckError("GetShaders"); }
/// <summary> /// Performs a render on this element. /// </summary> /// <param name="view">The UI view.</param> /// <param name="delta">The time since the last render.</param> public override void Render(ViewUI2D view, double delta) { if (ResetOnRender) { GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0f, 0.5f, 0.5f, 1f }); GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1f }); GraphicsUtil.CheckError("RenderScreen - Reset"); } }
/// <summary> /// Renders a single frame of the game, and also ticks. /// </summary> /// <param name="sender">Irrelevant.</param> /// <param name="e">Holds the frame time (delta).</param> private void Window_RenderFrame(object sender, FrameEventArgs e) { try { StackNoteHelper.Push("GameClientWindow - Render and tick frame", this); // First step: check delta if (e.Time <= 0.0) { return; } // Mouse handling PreviousMouse = CurrentMouse; CurrentMouse = Mouse.GetState(); // Standard pre-tick PreTick(e.Time); ErrorCode ec = GL.GetError(); while (ec != ErrorCode.NoError) { SysConsole.Output(OutputType.WARNING, "Uncaught GL Error: " + ec); ec = GL.GetError(); } // Second step: clear the screen GL.ClearBuffer(ClearBuffer.Color, 0, ScreenClearColor); GL.ClearBuffer(ClearBuffer.Depth, 0, DepthClear); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.DrawBuffer(DrawBufferMode.Back); GraphicsUtil.CheckError("GameClient - Pre"); // Tick helpers Models.Update(GlobalTickTime); GraphicsUtil.CheckError("GameClient - PostModelUpdate"); // Third step: general game rendering CurrentEngine.RenderSingleFrame(); GraphicsUtil.CheckError("GameClient - PostMainEngine"); // Add the UI Layer too MainUI.Draw(); GraphicsUtil.CheckError("GameClient - PostUI"); // Fourth step: clean up! GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindVertexArray(0); GL.UseProgram(0); // Semi-final step: Tick logic! GraphicsUtil.CheckError("GameClient - PreTick"); // Main instance tick. Tick(); // Primary UI tick MainUI.Tick(); Resized = false; GraphicsUtil.CheckError("GameClient - PostTick"); // Final step: Swap the render buffer onto the screen! Window.SwapBuffers(); GraphicsUtil.CheckError("GameClient - Post"); } finally { StackNoteHelper.Pop(); } }
/// <summary> /// Destroys the light object. /// </summary> public void Destroy() { GL.DeleteTexture(FBO_Tex); if (FBO_DTex > 0) { GL.DeleteTexture(FBO_DTex); } GL.DeleteFramebuffer(FBO); GraphicsUtil.CheckError("PointLight2D destroy"); }
/// <summary> /// Loads light helpers. /// </summary> public override void PostLoad() { GraphicsUtil.CheckError("PostLoad - Pre"); SysConsole.Output(OutputType.INIT, "GameEngine loading render helpers..."); RenderHelper = new Renderer2D(Textures, Shaders); RenderHelper.Init(); GraphicsUtil.CheckError("PostLoad - RenderHelper Done"); SysConsole.Output(OutputType.INIT, "GameEngine loading 2D light helpers..."); LoadLightHelpers(); GraphicsUtil.CheckError("PostLoad - Post"); }
/// <summary> /// Constructs the point light 2D. /// </summary> /// <param name="pos">Its starting position.</param> /// <param name="str">Its strength.</param> /// <param name="sdscale">The subdivision scale.</param> /// <param name="_engine">The powering game engine.</param> public PointLight2D(Vector2 pos, float str, float sdscale, GameEngine2D _engine) { if (str < 1) { throw new Exception("Invalid strength!"); } Engine = _engine; Position = pos; Strength = str; FBO = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO); FBO_Tex = GL.GenTexture(); if (Engine.OneDLights) { Width = 8192; GL.BindTexture(TextureTarget.Texture1D, FBO_Tex); GL.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.R32f, Width, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, (uint)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, (uint)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapS, (uint)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapT, (uint)TextureWrapMode.ClampToEdge); GL.FramebufferTexture1D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture1D, FBO_Tex, 0); GraphicsUtil.CheckError("PointLight2D init - 1D Tex"); FBO_DTex = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture1D, FBO_DTex); GL.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.DepthComponent, Width, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero); GraphicsUtil.CheckError("PointLight2D init - 1D DTex - Tex"); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, (uint)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, (uint)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapS, (uint)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapT, (uint)TextureWrapMode.ClampToEdge); GraphicsUtil.CheckError("PointLight2D init - 1D DTex"); GL.FramebufferTexture1D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture1D, FBO_DTex, 0); GraphicsUtil.CheckError("PointLight2D init - 1D DTex Attach"); } else { GL.BindTexture(TextureTarget.Texture2D, FBO_Tex); // TODO: Utilities.NextPowerOfTwo? Should probably only be added if it's confirmed as need (POT-only hardware on OpenGL 4.3 is unlikely... NPOTs are common!) Width = (int)(Strength * 2f); // TODO: Alpha texture!? GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Width, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (uint)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (uint)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (uint)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (uint)TextureWrapMode.ClampToEdge); GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, FBO_Tex, 0); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.BindTexture(TextureTarget.Texture2D, 0); SubDivider = Math.Max((float)Math.Sqrt(Strength) * sdscale, 1f); GraphicsUtil.CheckError("PointLight2D init"); }
public void TickInvMenu() { if (CInvMenu != null) { MainItemView.CameraPos = -Forw * 10; MainItemView.ForwardVec = Forw; MainItemView.CameraUp = () => Location.UnitY; // TODO: Should this really be Y? Probably not... View3D temp = MainWorldView; MainWorldView = MainItemView; MainItemView.Render(); MainWorldView = temp; GraphicsUtil.CheckError("ItemRender"); } }
/// <summary> /// Loads all content for the game, and starts the systems. /// </summary> /// <param name="sender">Irrelevant.</param> /// <param name="e">Irrelevant.</param> private void Window_Load(object sender, EventArgs e) { SysConsole.Output(OutputType.INIT, "GameClient starting load sequence..."); GL.Viewport(0, 0, Window.Width, Window.Height); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Disable(EnableCap.CullFace); GraphicsUtil.CheckError("GEB - Initial"); SysConsole.Output(OutputType.INIT, "GameClient loading file helpers..."); Files = new FileHandler(); Files.Init(); SysConsole.Output(OutputType.INIT, "GameClient loading shader helpers..."); Shaders = new ShaderEngine(); Shaders.InitShaderSystem(); SysConsole.Output(OutputType.INIT, "GameClient loading texture helpers..."); Textures = new TextureEngine(); Textures.InitTextureSystem(Files); GraphicsUtil.CheckError("GEB - Textures"); SysConsole.Output(OutputType.INIT, "GameClient loading font helpers..."); GLFonts = new GLFontEngine(Textures, Shaders); GLFonts.Init(Files); FontSets = new FontSetEngine(GLFonts) { FixTo = Shaders.ColorMult2DShader }; // TODO: FGE/Core->Languages engine! FontSets.Init((subdata) => null, () => Ortho, () => GlobalTickTime); GraphicsUtil.CheckError("GEB - Fonts"); SysConsole.Output(OutputType.INIT, "GameClient loading 2D/UI render helper..."); MainUI = new ViewUI2D(this); SysConsole.Output(OutputType.INIT, "GameEngine loading model engine..."); Animations = new AnimationEngine(); Models = new ModelEngine(); Models.Init(Animations, this); SysConsole.Output(OutputType.INIT, "GameEngine loading render helper..."); Rendering3D = new Renderer(Textures, Shaders, Models); Rendering3D.Init(); Rendering2D = new Renderer2D(Textures, Shaders); Rendering2D.Init(); SysConsole.Output(OutputType.INIT, "GameClient calling engine load..."); CurrentEngine.Load(); SysConsole.Output(OutputType.INIT, "GameClient calling external load event..."); OnWindowLoad?.Invoke(); SysConsole.Output(OutputType.INIT, "GameClient is ready and loaded! Starting main game loop..."); GraphicsUtil.CheckError("GEB - Loaded"); Loaded = true; }
/// <summary> /// Draw the menu to the relevant back buffer. /// </summary> public void Draw() { GraphicsUtil.CheckError("ViewUI2D - Draw - Pre"); if (DirectToScreen) { UIContext.ZoomMultiplier = Client.Window.Width * 0.5f; UIContext.Width = Client.Window.Width; UIContext.Height = Client.Window.Height; float aspect = UIContext.Width / (float)UIContext.Height; float sc = 1.0f / (UIContext.Zoom * UIContext.ZoomMultiplier); UIContext.Scaler = new Vector2(sc, -sc * aspect); UIContext.ViewCenter = new Vector2(-Client.Window.Width * 0.5f, -Client.Window.Height * 0.5f); UIContext.Adder = UIContext.ViewCenter; UIContext.AspectHelper = UIContext.Width / (float)UIContext.Height; Client.Ortho = Matrix4.CreateOrthographicOffCenter(0, Client.Window.Width, Client.Window.Height, 0, -1, 1); GraphicsUtil.CheckError("ViewUI2D - Draw - DirectToScreenPost"); } // TODO: alternate Ortho setting from scaler/adder def! Client.Shaders.ColorMult2DShader.Bind(); Rendering.SetColor(Color4F.White); GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(UIContext.Scaler.X, UIContext.Scaler.Y, UIContext.AspectHelper)); GL.Uniform2(2, ref UIContext.Adder); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.CullFace); Shader s = Client.FontSets.FixTo; Client.FontSets.FixTo = Client.Shaders.ColorMult2DShader; GraphicsUtil.CheckError("ViewUI2D - Draw - PreUpdate"); LastRenderedSet.Clear(); if (CurrentScreen.Position.HasAnyMatchParent()) { CurrentScreen.Position.Dirty |= Client.Resized; } CurrentScreen.UpdatePositions(LastRenderedSet, Client.Delta); GraphicsUtil.CheckError("ViewUI2D - Draw - PreDraw"); foreach (UIElement elem in (SortToPriority ? LastRenderedSet.OrderBy((e) => e.RenderPriority) : (IEnumerable <UIElement>)LastRenderedSet)) { elem.Render(this, Client.Delta); } GraphicsUtil.CheckError("ViewUI2D - Draw - PostDraw"); Client.FontSets.FixTo = s; }
public void SetTexture(int ID, string texture, int oSpot) { TEngine.LoadTextureIntoArray(texture, ID, TWidth); GraphicsUtil.CheckError("TextureBlock - SetTexture - TENG"); if (oSpot > 0) { GL.BindTexture(TextureTarget.Texture2DArray, HelpTextureID); int id_z = oSpot / (TWidth * TWidth); int id_xy = oSpot % (TWidth * TWidth); int ix = id_xy % TWidth; int iy = id_xy / TWidth; float[] t = new float[4] { (1.0f / 8.0f), 0.0f, 0.0f, 1.0f }; GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, ix, iy, id_z, 1, 1, 1, OpenTK.Graphics.OpenGL4.PixelFormat.Rgba, PixelType.Float, t); GraphicsUtil.CheckError("TextureBlock - SetTexture - OSp"); } }
public void Render(double mind, double maxd, bool outview = false) { GraphicsUtil.CheckError("Rendering - Particles - Pre"); if (TheClient.MainWorldView.FBOid == FBOID.FORWARD_TRANSP || TheClient.MainWorldView.FBOid.IsMainTransp() || (TheClient.MainWorldView.FBOid == FBOID.DYNAMIC_SHADOWS && TheClient.MainWorldView.TranspShadows)) { double mindsq = mind * mind; double maxdsq = maxd * maxd; GraphicsUtil.CheckError("Rendering - Particles - PreFX"); List <Vector3> pos = new List <Vector3>(); List <Vector4> col = new List <Vector4>(); List <Vector2> tcs = new List <Vector2>(); // TODO: If this gets too big, try to async it? Parallel.ForEach or similar could speed it up, in that situation! Would require a logic adjustment though. (See cloud section!) for (int i = 0; i < ActiveEffects.Count; i++) { if (ActiveEffects[i].Type == ParticleEffectType.SQUARE) { double dist = ActiveEffects[i].Start(ActiveEffects[i]).DistanceSquared(TheClient.MainWorldView.RenderRelative); if (dist < mindsq || dist >= maxdsq) { continue; } Tuple <Location, Vector4, Vector2> dets = ActiveEffects[i].GetDetails(); if (dets != null) { pos.Add(ClientUtilities.Convert(dets.Item1 - TheClient.MainWorldView.RenderRelative)); if (TheClient.MainWorldView.FBOid == FBOID.FORWARD_TRANSP) { col.Add(Vector4.Min(dets.Item2, Vector4.One)); } else { col.Add(dets.Item2); } tcs.Add(dets.Item3); } } else { ActiveEffects[i].Render(); // TODO: Deprecate / remove / fully replace!? } if (ActiveEffects[i].TTL <= 0) { ActiveEffects[i].OnDestroy?.Invoke(ActiveEffects[i]); ActiveEffects.RemoveAt(i--); } } GraphicsUtil.CheckError("Rendering - Particles - PreClouds"); ParticleData pd = new ParticleData(); if (TheClient.CVars.r_clouds.ValueB) { int cloudID = GetTextureID("effects/clouds/cloud2"); // TODO: Cache! Task[] tasks = new Task[TheClient.TheRegion.Clouds.Count]; bool lessClouds = TheClient.CVars.r_less_clouds.ValueB; int posn = 0; foreach (Cloud tcl in TheClient.TheRegion.Clouds) { Cloud cloud = tcl; int wid = 0; if (lessClouds) { wid = cloud.Points.Count / 3; } else { wid = cloud.Points.Count; } posn += wid; } pd.Poses = new Vector3[posn]; pd.Cols = new Vector4[posn]; pd.TCs = new Vector2[posn]; int n = 0; posn = 0; foreach (Cloud tcl in TheClient.TheRegion.Clouds) { int id = n; int posid = posn; Cloud cloud = tcl; int wid = 0; if (lessClouds) { wid = cloud.Points.Count / 3; } else { wid = cloud.Points.Count; } posn += wid; // TODO: Replace async nonsense? tasks[id] = Task.Factory.StartNew(() => { for (int i = 0; i < cloud.Points.Count; i++) { if (lessClouds && i % 3 != 2) { continue; } int c = i / 3; Location ppos = (cloud.Position + cloud.Points[i]) - TheClient.MainWorldView.RenderRelative; pd.Poses[posid + c] = ClientUtilities.Convert(ppos); pd.Cols[posid + c] = Vector4.One; // TODO: Colored clouds? pd.TCs[posid + c] = new Vector2(cloud.Sizes[i], cloudID); } }); n++; } int count = pos.Count; for (int i = 0; i < tasks.Length; i++) { tasks[i].Wait(); } // TODO: Could probably skip this addrange step with more clever usage of arrays! pos.AddRange(pd.Poses); col.AddRange(pd.Cols); tcs.AddRange(pd.TCs); GraphicsUtil.CheckError("Rendering - Particles - PostClouds"); } if (TheClient.MainWorldView.FBOid == FBOID.FORWARD_TRANSP) { TheClient.Engine.Shaders3D.s_forw_particles = TheClient.Engine.Shaders3D.s_forw_particles.Bind(); Matrix4 mat = outview ? TheClient.MainWorldView.OutViewMatrix : TheClient.MainWorldView.PrimaryMatrix; GL.UniformMatrix4(1, false, ref mat); } else if (TheClient.MainWorldView.FBOid == FBOID.DYNAMIC_SHADOWS) { TheClient.Engine.Shaders3D.s_shadow_parts = TheClient.Engine.Shaders3D.s_shadow_parts.Bind(); } else { // TODO: From FBOid if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.Engine.Shaders3D.s_transponlylitsh_ll_particles = TheClient.Engine.Shaders3D.s_transponlylitsh_ll_particles.Bind(); } else { TheClient.Engine.Shaders3D.s_transponlylitsh_particles = TheClient.Engine.Shaders3D.s_transponlylitsh_particles.Bind(); } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.Engine.Shaders3D.s_transponlylit_ll_particles = TheClient.Engine.Shaders3D.s_transponlylit_ll_particles.Bind(); } else { TheClient.Engine.Shaders3D.s_transponlylit_particles = TheClient.Engine.Shaders3D.s_transponlylit_particles.Bind(); } } GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, TheClient.MainWorldView.RS4P.DepthTexture); Matrix4 mat = outview ? TheClient.MainWorldView.OutViewMatrix : TheClient.MainWorldView.PrimaryMatrix; GL.UniformMatrix4(1, false, ref mat); } GraphicsUtil.CheckError("Rendering - Particles - 1"); Matrix4 ident = Matrix4.Identity; GL.UniformMatrix4(2, false, ref ident); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2DArray, TextureID); Vector3[] posset = pos.ToArray(); Vector4[] colorset = col.ToArray(); Vector2[] texcoords = tcs.ToArray(); uint[] posind = new uint[posset.Length]; for (uint i = 0; i < posind.Length; i++) { posind[i] = i; } GraphicsUtil.CheckError("Rendering - Particles - 2"); Part_C = posind.Length; GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Pos); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(posset.Length * Vector3.SizeInBytes), posset, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Tcs); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(texcoords.Length * Vector2.SizeInBytes), texcoords, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Col); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(colorset.Length * Vector4.SizeInBytes), colorset, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, Part_VBO_Ind); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(posind.Length * sizeof(uint)), posind, BufferUsageHint.StaticDraw); GL.BindVertexArray(Part_VAO); if (!prepped) { GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Pos); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0); GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Tcs); GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 0, 0); GL.EnableVertexAttribArray(2); GL.BindBuffer(BufferTarget.ArrayBuffer, Part_VBO_Col); GL.VertexAttribPointer(4, 4, VertexAttribPointerType.Float, false, 0, 0); GL.EnableVertexAttribArray(4); GL.BindBuffer(BufferTarget.ElementArrayBuffer, Part_VBO_Ind); prepped = true; } GL.DrawElements(PrimitiveType.Points, Part_C, DrawElementsType.UnsignedInt, IntPtr.Zero); GL.BindVertexArray(0); TheClient.isVox = true; TheClient.SetEnts(); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); GraphicsUtil.CheckError("Rendering - Particles - 3"); } }
/// <summary> /// Called when the window is loading, only to be used by the startup process. /// </summary> void Window_Load(object sender, EventArgs e) { SysConsole.Output(OutputType.CLIENTINIT, "Window generated!"); DPIScale = Window.Width / CVars.r_width.ValueF; SysConsole.Output(OutputType.CLIENTINIT, "DPIScale is " + DPIScale + "!"); SysConsole.Output(OutputType.CLIENTINIT, "Setting up a game engine backend placeholder..."); FakeEngine(); SysConsole.Output(OutputType.CLIENTINIT, "Loading base textures..."); PreInitRendering(); Textures = new TextureEngine(); Textures.InitTextureSystem(Files); ItemFrame = Textures.GetTexture("ui/hud/item_frame"); CWindow.Textures = Textures; SysConsole.Output(OutputType.CLIENTINIT, "Loading shaders..."); Shaders = new ShaderEngine(); GLVendor = GL.GetString(StringName.Vendor); GLVersion = GL.GetString(StringName.Version); GLRenderer = GL.GetString(StringName.Renderer); SysConsole.Output(OutputType.CLIENTINIT, "Vendor: " + GLVendor + ", GLVersion: " + GLVersion + ", Renderer: " + GLRenderer); if (GLVendor.ToLowerFast().Contains("intel")) { SysConsole.Output(OutputType.CLIENTINIT, "Disabling good graphics (Appears to be Intel: '" + GLVendor + "')"); Shaders.MCM_GOOD_GRAPHICS = false; } Shaders.InitShaderSystem(); CWindow.Shaders = Shaders; Engine.GetShaders(); GraphicsUtil.CheckError("Load - Shaders"); SysConsole.Output(OutputType.CLIENTINIT, "Loading animation engine..."); Animations = new AnimationEngine(); CWindow.Animations = Animations; SysConsole.Output(OutputType.CLIENTINIT, "Loading model engine..."); Models = new ModelEngine(); Models.Init(Animations, CWindow); LODHelp = new ModelLODHelper(this); CWindow.Models = Models; SysConsole.Output(OutputType.CLIENTINIT, "Loading rendering helper..."); Rendering = new Renderer(Textures, Shaders, Models); Rendering.Init(); CWindow.Rendering3D = Rendering; CWindow.Rendering2D = new Renderer2D(Textures, Shaders); CWindow.Rendering2D.Init(); SysConsole.Output(OutputType.CLIENTINIT, "Preparing load screen..."); load_screen = Textures.GetTexture("ui/menus/loadscreen"); Establish2D(); SWLoading.Start(); PassLoadScreen(); SysConsole.Output(OutputType.CLIENTINIT, "Loading block textures..."); TBlock = new TextureBlock(); TBlock.Generate(this, CVars, Textures, false); GraphicsUtil.CheckError("Load - Textures"); SysConsole.Output(OutputType.CLIENTINIT, "Loading fonts..."); Fonts = new GLFontEngine(Textures, Shaders); Fonts.Init(Files); FontSets = new FontSetEngine(Fonts); FontSets.Init((subdat) => Languages.GetText(Files, subdat), () => Ortho, () => GlobalTickTimeLocal); GraphicsUtil.CheckError("Load - Fonts"); PassLoadScreen(); CWindow.FontSets = FontSets; CWindow.GLFonts = Fonts; SysConsole.Output(OutputType.CLIENTINIT, "Loading general graphics settings..."); CVars.r_vsync.OnChanged += OnVsyncChanged; OnVsyncChanged(CVars.r_vsync, EventArgs.Empty); CVars.r_cloudshadows.OnChanged += OnCloudShadowChanged; CVars.r_transpll.OnChanged += OnLLChanged; OnLLChanged(CVars.r_transpll, EventArgs.Empty); GraphicsUtil.CheckError("Load - General Graphics"); SysConsole.Output(OutputType.CLIENTINIT, "Loading UI engine..."); UIConsole.InitConsole(); // TODO: make this non-static InitChatSystem(); PassLoadScreen(); GraphicsUtil.CheckError("Load - UI"); SysConsole.Output(OutputType.CLIENTINIT, "Preparing rendering engine..."); InitRendering(); GraphicsUtil.CheckError("Load - Rendering"); SysConsole.Output(OutputType.CLIENTINIT, "Loading particle effect engine..."); Particles = new ParticleHelper(this) { Engine = new ParticleEngine(this) }; SysConsole.Output(OutputType.CLIENTINIT, "Preparing mouse and keyboard handlers..."); KeyHandler.Init(); Gamepad = new GamePadHandler(); Gamepad.Init(this); PassLoadScreen(); GraphicsUtil.CheckError("Load - Keyboard/mouse"); SysConsole.Output(OutputType.CLIENTINIT, "Building the sound system..."); Sounds.Init(Engine); GraphicsUtil.CheckError("Load - Sound"); SysConsole.Output(OutputType.CLIENTINIT, "Building game world..."); BuildWorld(); PassLoadScreen(); GraphicsUtil.CheckError("Load - World"); SysConsole.Output(OutputType.CLIENTINIT, "Preparing networking..."); Network = new NetworkBase(this); RegisterDefaultEntityTypes(); GraphicsUtil.CheckError("Load - Net"); PassLoadScreen(); SysConsole.Output(OutputType.CLIENTINIT, "Loading Voxel computer..."); try { VoxelComputer = new VoxelComputeEngine(); VoxelComputer.Init(this); } catch (Exception ex) { SysConsole.Output(ex); } PassLoadScreen(); SysConsole.Output(OutputType.CLIENTINIT, "Playing background music..."); BackgroundMusic(); CVars.a_musicvolume.OnChanged += OnMusicVolumeChanged; CVars.a_musicpitch.OnChanged += OnMusicPitchChanged; CVars.a_music.OnChanged += OnMusicChanged; CVars.a_echovolume.OnChanged += OnEchoVolumeChanged; OnEchoVolumeChanged(null, null); PassLoadScreen(); SysConsole.Output(OutputType.CLIENTINIT, "Setting up screens..."); TheMainMenuScreen = new MainMenuScreen(this); TheGameScreen = new GameScreen(this); TheSingleplayerMenuScreen = new SingleplayerMenuScreen(this); TheLoadScreen = new LoadScreen(this); CScreen = TheMainMenuScreen; SysConsole.Output(OutputType.CLIENTINIT, "Trying to grab RawGamePad..."); try { RawGamePad = new XInput(); } catch (Exception ex) { SysConsole.Output(OutputType.CLIENTINIT, "Failed to grab RawGamePad: " + ex.Message); } SysConsole.Output(OutputType.CLIENTINIT, "Preparing inventory..."); InitInventory(); PassLoadScreen(); SysConsole.Output(OutputType.CLIENTINIT, "Creating sky..."); CreateSkyBox(); SysConsole.Output(OutputType.CLIENTINIT, "Requesting a menu server..."); LocalServer?.ShutDown(); LocalServer = new Server(28009) { IsMenu = true }; // TODO: Grab first free port? Object locky = new Object(); bool ready = false; Schedule.StartAsyncTask(() => { LocalServer.StartUp("menu", () => { lock (locky) { ready = true; } }); }); while (true) { lock (locky) { if (ready) { break; } } PassLoadScreen(); Thread.Sleep(50); } SysConsole.Output(OutputType.CLIENTINIT, "Connecting to a menu server..."); Network.LastConnectionFailed = false; Network.Connect("localhost", "28009", true, null); // TODO: Grab accurate local IP? Stopwatch sw = new Stopwatch(); sw.Start(); bool annc = false; while (true) { if (Network.LastConnectionFailed) { SysConsole.Output(OutputType.CLIENTINIT, "Failed to connect to menu server! Failing!"); Window.Close(); return; } if (Network.IsAlive) { break; } sw.Stop(); long ms = sw.ElapsedMilliseconds; sw.Start(); if (ms > 10000 && !annc) { annc = true; SysConsole.Output(OutputType.WARNING, "Taking weirdly long, did something fail?!"); } if (ms > 20000) { SysConsole.Output(OutputType.CLIENTINIT, "Timed out while trying to connect to menu server! Failing!"); Window.Close(); return; } PassLoadScreen(); Thread.Sleep(50); } SysConsole.Output(OutputType.CLIENTINIT, "Showing main menu..."); ShowMainMenu(); GraphicsUtil.CheckError("Load - Final"); SysConsole.Output(OutputType.CLIENTINIT, "Ready and looping!"); }
// TODO: Merge with base.Render() as much as possible! public override void Render() { GraphicsUtil.CheckError("Render - Player - Pre"); Location renderrelpos = GetWeldSpot(); if (TheClient.IsMainMenu || !TheClient.CVars.r_drawself.ValueB) { return; } TheClient.SetEnts(true); if (TheClient.CVars.n_debugmovement.ValueB) { if (ServerLocation.IsInfinite() || ServerLocation.IsNaN() || renderrelpos.IsInfinite() || renderrelpos.IsNaN()) { SysConsole.Output(OutputType.WARNING, "NaN server data"); } else { TheClient.Rendering.RenderLine(ServerLocation, renderrelpos, TheClient.MainWorldView); GraphicsUtil.CheckError("Render - Player - Line"); TheClient.Rendering.RenderLineBox(ServerLocation + new Location(-0.2), ServerLocation + new Location(0.2), TheClient.MainWorldView); GraphicsUtil.CheckError("Render - Player - LineBox"); /*if (GraphicsUtil.CheckError("Render - Player - LineBox")) * { * SysConsole.Output(OutputType.DEBUG, "Caught: " + (ServerLocation + new Location(-0.2)) + "::: " + (ServerLocation + new Location(0.2))); * }*/ } } if (TheClient.VR != null) { return; } GraphicsUtil.CheckError("Render - Player - 0"); OpenTK.Matrix4d mat = OpenTK.Matrix4d.Scale(1.5f) * OpenTK.Matrix4d.CreateRotationZ((Direction.Yaw * Utilities.PI180)) * PlayerAngleMat * OpenTK.Matrix4d.CreateTranslation(ClientUtilities.ConvertD(renderrelpos)); TheClient.MainWorldView.SetMatrix(2, mat); TheClient.Rendering.SetMinimumLight(0.0f, TheClient.MainWorldView); model.CustomAnimationAdjustments = new Dictionary <string, OpenTK.Matrix4>(SavedAdjustmentsOTK) { // TODO: safe (no-collision) rotation check? { "spine04", GetAdjustmentOTK("spine04") * OpenTK.Matrix4.CreateRotationX(-(float)(Direction.Pitch / 2f * Utilities.PI180)) } }; GraphicsUtil.CheckError("Render - Player - 1"); if (!TheClient.MainWorldView.RenderingShadows && TheClient.CVars.g_firstperson.ValueB) { model.CustomAnimationAdjustments["neck01"] = GetAdjustmentOTK("neck01") * OpenTK.Matrix4.CreateRotationX(-(float)(160f * Utilities.PI180)); } else { model.CustomAnimationAdjustments["neck01"] = GetAdjustmentOTK("neck01"); } model.Draw(aHTime, hAnim, aTTime, tAnim, aLTime, lAnim); Model mod = TheClient.GetItemForSlot(TheClient.QuickBarPos).Mod; bool hasjp = HasJetpack(); GraphicsUtil.CheckError("Render - Player - 2"); if (!hasjp && tAnim != null && mod != null) { mat = OpenTK.Matrix4d.CreateTranslation(ClientUtilities.ConvertD(renderrelpos)); TheClient.MainWorldView.SetMatrix(2, mat); Dictionary <string, Matrix> adjs = new Dictionary <string, Matrix>(SavedAdjustments); // TODO: Logic of this rotation math? Matrix rotforw = Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitX, ((float)(Direction.Pitch / 2f * Utilities.PI180) % 360f))); adjs["spine04"] = GetAdjustment("spine04") * rotforw; SingleAnimationNode hand = tAnim.GetNode("metacarpal2.r"); Matrix m4 = Matrix.CreateScale(1.5f, 1.5f, 1.5f) * (Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)((-Direction.Yaw + 90) * Utilities.PI180) % 360f)) * hand.GetBoneTotalMatrix(aTTime, adjs)) * Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)((-90) * Utilities.PI180) % 360f)); OpenTK.Matrix4 bonemat = new OpenTK.Matrix4((float)m4.M11, (float)m4.M12, (float)m4.M13, (float)m4.M14, (float)m4.M21, (float)m4.M22, (float)m4.M23, (float)m4.M24, (float)m4.M31, (float)m4.M32, (float)m4.M33, (float)m4.M34, (float)m4.M41, (float)m4.M42, (float)m4.M43, (float)m4.M44); GL.UniformMatrix4(100, false, ref bonemat); mod.LoadSkin(TheClient.Textures); mod.Draw(); bonemat = OpenTK.Matrix4.Identity; GL.UniformMatrix4(100, false, ref bonemat); } GraphicsUtil.CheckError("Render - Player - 3"); if (hasjp) { // TODO: Abstractify! Model jetp = GetHeldItem().Mod; mat = OpenTK.Matrix4d.CreateTranslation(ClientUtilities.ConvertD(renderrelpos)); TheClient.MainWorldView.SetMatrix(2, mat); Dictionary <string, Matrix> adjs = new Dictionary <string, Matrix>(); Matrix rotforw = Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitX, ((float)(Direction.Pitch / 2f * Utilities.PI180) % 360f))); adjs["spine04"] = GetAdjustment("spine04") * rotforw; SingleAnimationNode spine = tAnim.GetNode("spine04"); Matrix m4 = Matrix.CreateScale(1.5f, 1.5f, 1.5f) * (Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitZ, (float)((-Direction.Yaw + 90) * Utilities.PI180) % 360f)) * spine.GetBoneTotalMatrix(aTTime, adjs)) * Matrix.CreateFromQuaternion(BEPUutilities.Quaternion.CreateFromAxisAngle(Vector3.UnitX, (float)((90) * Utilities.PI180) % 360f)); OpenTK.Matrix4 bonemat = new OpenTK.Matrix4((float)m4.M11, (float)m4.M12, (float)m4.M13, (float)m4.M14, (float)m4.M21, (float)m4.M22, (float)m4.M23, (float)m4.M24, (float)m4.M31, (float)m4.M32, (float)m4.M33, (float)m4.M34, (float)m4.M41, (float)m4.M42, (float)m4.M43, (float)m4.M44); GL.UniformMatrix4(100, false, ref bonemat); jetp.LoadSkin(TheClient.Textures); jetp.Draw(); bonemat = OpenTK.Matrix4.Identity; GL.UniformMatrix4(100, false, ref bonemat); } GraphicsUtil.CheckError("Render - Player - 4"); if (IsTyping) { TheClient.Textures.GetTexture("ui/game/typing").Bind(); // TODO: store! TheClient.Rendering.RenderBillboard(renderrelpos + new Location(0, 0, 4), new Location(2), TheClient.MainWorldView.CameraPos, TheClient.MainWorldView); } GraphicsUtil.CheckError("Render - Player - Post"); }
/// <summary> /// Creates the sky box texture. /// </summary> public void CreateSkyBox() { GraphicsUtil.CheckError("SKYBOX - Pre"); if (SKY_TEX < 0) { SKY_TEX = GL.GenTexture(); SKY_FBO = new int[6]; GL.BindTexture(TextureTarget.Texture2DArray, SKY_TEX); GraphicsUtil.CheckError("SKYBOX - GenPrep"); GL.TexStorage3D(TextureTarget3d.Texture2DArray, 1, SizedInternalFormat.Rgba8, SKY_TEX_SIZE, SKY_TEX_SIZE, 6); GraphicsUtil.CheckError("SKYBOX - TexConfig 0.1"); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)(TextureMinFilter.Linear)); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)(TextureMagFilter.Linear)); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GL.BindTexture(TextureTarget.Texture2DArray, 0); GraphicsUtil.CheckError("SKYBOX - TexConfig"); for (int i = 0; i < 6; i++) { SKY_FBO[i] = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, SKY_FBO[i]); GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, SKY_TEX, 0, i); GraphicsUtil.CheckError("SKYBOX - FBO " + i); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); } GL.Viewport(0, 0, SKY_TEX_SIZE, SKY_TEX_SIZE); GraphicsUtil.CheckError("SKYBOX - Render/Fast - Uniforms Prep"); Engine.Shaders3D.s_forwt_nofog.Bind(); GL.Uniform1(6, (float)Engine.GlobalTickTime); GL.Uniform4(12, new OpenTK.Vector4(0f, 0f, 0f, 0f)); GL.Uniform1(13, FogMaxDist()); //GL.Uniform2(14, zfar_rel); Engine.Rendering.SetColor(Color4F.White, MainWorldView); Engine.Shaders3D.s_forwt.Bind(); GraphicsUtil.CheckError("SKYBOX - Render/Fast - Uniforms 4.2"); GL.Uniform1(6, (float)Engine.GlobalTickTime); GraphicsUtil.CheckError("SKYBOX - Render/Fast - Uniforms 4.3"); GL.Uniform4(12, new OpenTK.Vector4(0f, 0f, 0f, 0f)); GraphicsUtil.CheckError("SKYBOX - Render/Fast - Uniforms 4.4"); GL.Uniform1(13, FogMaxDist()); Matrix4 projo = Matrix4.CreatePerspectiveFieldOfView((float)(90.0 * Utilities.PI180), 1f, 60f, ZFarOut()); GL.ActiveTexture(TextureUnit.Texture3); Textures.Black.Bind(); GL.ActiveTexture(TextureUnit.Texture2); Textures.Black.Bind(); GL.ActiveTexture(TextureUnit.Texture1); Textures.NormalDef.Bind(); GL.ActiveTexture(TextureUnit.Texture0); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); Rendering.SetColor(Color4.White, MainWorldView); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Color"); float skyAlpha = (float)Math.Max(Math.Min((SunAngle.Pitch - 70.0) / (-90.0), 1.0), 0.06); for (int i = 0; i < 6; i++) { GL.BindFramebuffer(FramebufferTarget.Framebuffer, SKY_FBO[i]); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Color1.1"); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Color1.2"); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0.0f, 1.0f, 1.0f, 1.0f }); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Color1.3"); Matrix4 viewo = Matrix4.LookAt(OpenTK.Vector3.Zero, SkyDirs[i], SkyUps[i]); Matrix4 pv = viewo * projo; GL.UniformMatrix4(1, false, ref pv); Rendering.SetColor(Color4.White, MainWorldView); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Color2"); Matrix4 scale = Matrix4.CreateScale(GetSecondSkyDistance()); GL.UniformMatrix4(2, false, ref scale); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep - Scale"); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Prep"); // TODO: Only render relevant side? // TODO: Save textures! Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/bottom").Bind(); skybox[0].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/top").Bind(); skybox[1].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/xm").Bind(); skybox[2].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/xp").Bind(); skybox[3].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/ym").Bind(); skybox[4].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "_night/yp").Bind(); skybox[5].Render(false); Rendering.SetColor(new OpenTK.Vector4(1, 1, 1, skyAlpha), MainWorldView); scale = Matrix4.CreateScale(GetSkyDistance()); GL.UniformMatrix4(2, false, ref scale); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Night"); // TODO: Save textures! Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/bottom").Bind(); skybox[0].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/top").Bind(); skybox[1].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/xm").Bind(); skybox[2].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/xp").Bind(); skybox[3].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/ym").Bind(); skybox[4].Render(false); Textures.GetTexture("skies/" + CVars.r_skybox.Value + "/yp").Bind(); skybox[5].Render(false); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Light"); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Sun - Pre 1"); Rendering.SetColor(Color4.White, MainWorldView); Engine.Shaders3D.s_forwt_nofog.Bind(); GL.UniformMatrix4(1, false, ref pv); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Sun - Pre 2"); float zf = ZFar(); float spf = ZFarOut() * 0.3333f; Textures.GetTexture("skies/sun").Bind(); // TODO: Store var! Matrix4 rot = Matrix4.CreateTranslation(-spf * 0.5f, -spf * 0.5f, 0f) * Matrix4.CreateRotationY((float)((-SunAngle.Pitch - 90f) * Utilities.PI180)) * Matrix4.CreateRotationZ((float)((180f + SunAngle.Yaw) * Utilities.PI180)) * Matrix4.CreateTranslation(ClientUtilities.Convert(TheSun.Direction * -(GetSkyDistance() * 0.95f))); Rendering.RenderRectangle(0, 0, spf, spf, rot); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Sun"); Textures.GetTexture("skies/planet_sphere").Bind(); // TODO: Store var! float ppf = ZFarOut() * 0.5f; GL.Enable(EnableCap.CullFace); Rendering.SetColor(new Color4(PlanetLight, PlanetLight, PlanetLight, 1), MainWorldView); rot = Matrix4.CreateScale(ppf * 0.5f) * Matrix4.CreateTranslation(-ppf * 0.5f, -ppf * 0.5f, 0f) * Matrix4.CreateRotationZ((float)((180f + PlanetAngle.Yaw) * Utilities.PI180)) * Matrix4.CreateTranslation(ClientUtilities.Convert(PlanetDir * -(GetSkyDistance() * 0.79f))); GL.UniformMatrix4(2, false, ref rot); Models.Sphere.Draw(); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - Planet"); GL.BindTexture(TextureTarget.Texture2D, 0); Matrix4 ident = Matrix4.Identity; GL.UniformMatrix4(2, false, ref ident); GL.Disable(EnableCap.CullFace); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - N3 - Pre"); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - N3 - Light"); Rendering.SetColor(Color4.White, MainWorldView); GraphicsUtil.CheckError("SKYBOX - Rendering - Sky - N3 - Color"); // TODO: other sky/outview data here as well? (Chunks, trees, etc.?) } GL.Enable(EnableCap.CullFace); GL.Enable(EnableCap.DepthTest); Shaders.ColorMultShader.Bind(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.DrawBuffer(DrawBufferMode.Back); GL.Viewport(0, 0, Window.Width, Window.Height); }
public void Generate(Client tclient, ClientCVar cvars, TextureEngine eng, bool delayable) { TheClient = tclient; if (TextureID > -1) { GL.DeleteTexture(TextureID); GL.DeleteTexture(NormalTextureID); GL.DeleteTexture(HelpTextureID); } List <MaterialTextureInfo> texs = new List <MaterialTextureInfo>(MaterialHelpers.Textures.Length); TexList = texs; int extras = 0; for (int i = 0; i < MaterialHelpers.Textures.Length; i++) { string[] basic = MaterialHelpers.Textures[i].SplitFast('@')[0].SplitFast('$')[0].SplitFast('%')[0].SplitFast(','); texs.Add(new MaterialTextureInfo() { Mat = i, ResultantID = extras }); extras += basic.Length; } TEngine = eng; TextureID = GL.GenTexture(); TWidth = cvars.r_blocktexturewidth.ValueI; HelpTWMin = TEX_REQUIRED_BITS / (TWidth * TWidth); GL.BindTexture(TextureTarget.Texture2DArray, TextureID); int levels = TheClient.CVars.r_block_mipmaps.ValueB ? (TWidth == 256 ? 6 : 4) : 1; // TODO: 6/4 -> Setting GL.TexStorage3D(TextureTarget3d.Texture2DArray, levels, SizedInternalFormat.Rgba8, TWidth, TWidth, extras); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)(cvars.r_blocktexturelinear.ValueB ? TextureMinFilter.LinearMipmapLinear : TextureMinFilter.Nearest)); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)(cvars.r_blocktexturelinear.ValueB ? TextureMagFilter.Linear : TextureMagFilter.Nearest)); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); HelpTextureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2DArray, HelpTextureID); GL.TexStorage3D(TextureTarget3d.Texture2DArray, levels, SizedInternalFormat.Rgba8, TWidth, TWidth, extras + HelpTWMin); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); NormalTextureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2DArray, NormalTextureID); GL.TexStorage3D(TextureTarget3d.Texture2DArray, levels, SizedInternalFormat.Rgba8, TWidth, TWidth, extras); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); // TODO: Use normal.a! IntTexs = new string[MaterialHelpers.Textures.Length]; for (int ia = 0; ia < MaterialHelpers.Textures.Length; ia++) { int i = ia; Action a = () => { MaterialTextureInfo tex = texs[i]; int resID = tex.ResultantID; string[] refrornot = MaterialHelpers.Textures[i].SplitFast('@'); if (refrornot.Length > 1) { string[] rorn = refrornot[1].SplitFast('%'); if (rorn.Length > 1) { tex.RefrRate = Utilities.StringToFloat(rorn[1]); } tex.RefractTextures = rorn[0].SplitFast(','); } string[] glowornot = refrornot[0].SplitFast('!'); if (glowornot.Length > 1) { tex.GlowingTextures = glowornot[1].SplitFast(','); } string[] reflornot = glowornot[0].SplitFast('*'); if (reflornot.Length > 1) { tex.ReflectTextures = reflornot[1].SplitFast(','); } string[] specularornot = reflornot[0].SplitFast('&'); if (specularornot.Length > 1) { tex.SpecularTextures = specularornot[1].SplitFast(','); } string[] normalornot = specularornot[0].SplitFast('$'); GL.BindTexture(TextureTarget.Texture2DArray, NormalTextureID); if (normalornot.Length > 1) { string[] rorn = normalornot[1].SplitFast('%'); if (rorn.Length > 1) { tex.NormRate = Utilities.StringToFloat(rorn[1]); } tex.NormalTextures = rorn[0].SplitFast(','); if (tex.NormalTextures.Length > 1) { SetAnimated((int)resID, tex.NormRate, tex.NormalTextures, NormalTextureID, -1); } } else { SetTexture((int)resID, "normal_def", -1); } string[] rateornot = normalornot[0].SplitFast('%'); if (rateornot.Length > 1) { tex.Rate = Utilities.StringToFloat(rateornot[1]); } tex.Textures = rateornot[0].SplitFast(','); GL.BindTexture(TextureTarget.Texture2DArray, TextureID); if (tex.Textures.Length > 1) { SetAnimated((int)resID, tex.Rate, tex.Textures, TextureID, resID); if (tex.NormalTextures == null) { GL.BindTexture(TextureTarget.Texture2DArray, NormalTextureID); tex.NormalTextures = new string[tex.Textures.Length]; tex.NormRate = tex.Rate; for (int fz = 0; fz < tex.NormalTextures.Length; fz++) { tex.NormalTextures[fz] = "normal_def"; } SetAnimated((int)resID, tex.Rate, tex.NormalTextures, NormalTextureID, -1); } } else { SetTexture((int)resID, tex.Textures[0], resID); if (tex.NormalTextures == null) { tex.NormalTextures = new string[] { "normal_def" }; } } if (tex.ReflectTextures == null) { tex.ReflectTextures = new string[tex.Textures.Length]; for (int fz = 0; fz < tex.ReflectTextures.Length; fz++) { tex.ReflectTextures[fz] = "black"; } tex.RefractTextures = tex.ReflectTextures; tex.GlowingTextures = tex.ReflectTextures; tex.SpecularTextures = tex.ReflectTextures; } if (tex.NormRate != tex.Rate || tex.RefrRate != tex.Rate) { SysConsole.Output(OutputType.WARNING, "Rates wrong for " + MaterialHelpers.Textures[i]); tex.NormRate = tex.Rate; tex.RefrRate = tex.Rate; } if (tex.Textures.Length != tex.NormalTextures.Length || tex.ReflectTextures.Length != tex.Textures.Length) { SysConsole.Output(OutputType.WARNING, "Texture counts wrong for " + MaterialHelpers.Textures[i]); } IntTexs[(int)tex.Mat] = tex.Textures[0]; if (!delayable) { TheClient.PassLoadScreen(); } }; if (delayable) { TheClient.Schedule.ScheduleSyncTask(a, i * LoadRate); } else { a(); } } double time = (MaterialHelpers.Textures.Length + 1) * LoadRate; for (int ia = 0; ia < texs.Count; ia++) { int i = ia; Action a = () => { GL.BindTexture(TextureTarget.Texture2DArray, HelpTextureID); Bitmap combo = GetCombo(texs[i], 0); if ((texs[i].SpecularTextures != null) && (texs[i].ReflectTextures != null) && (texs[i].RefractTextures != null) && (texs[i].GlowingTextures != null) && texs[i].SpecularTextures.Length > 1) { Bitmap[] bmps = new Bitmap[texs[i].SpecularTextures.Length]; bmps[0] = combo; for (int x = 1; x < bmps.Length; x++) { bmps[x] = GetCombo(texs[i], x); } SetAnimated((int)texs[i].ResultantID + HelpTWMin, texs[i].RefrRate, bmps, HelpTextureID); for (int x = 1; x < bmps.Length; x++) { bmps[x].Dispose(); } } else { TEngine.LockBitmapToTexture(combo, (int)texs[i].ResultantID + HelpTWMin); } combo.Dispose(); if (!delayable) { TheClient.PassLoadScreen(); } }; if (delayable) { TheClient.Schedule.ScheduleSyncTask(a, time + i * LoadRate); } else { a(); } } if (TheClient.CVars.r_block_mipmaps.ValueB) { Action mipmap = () => { GL.BindTexture(TextureTarget.Texture2DArray, TextureID); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GL.BindTexture(TextureTarget.Texture2DArray, NormalTextureID); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GL.BindTexture(TextureTarget.Texture2DArray, HelpTextureID); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); GraphicsUtil.CheckError("Mipmapping"); }; if (delayable) { TheClient.Schedule.ScheduleSyncTask(mipmap, time * 2); } else { mipmap(); } } GL.BindTexture(TextureTarget.Texture2DArray, 0); }
/// <summary> /// Renders the entire GameEngine2D. /// </summary> private void Render() { GraphicsUtil.CheckError("Render - Pre"); if (!UseLightEngine) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); GL.Viewport(0, 0, Window.Width / Pixelation, Window.Height / Pixelation); Shaders.ColorMult2DShader.Bind(); MainRenderContext.CalcShadows = false; Scaler = OriginalScaler; Adder = OriginalAdder; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; RenderAll(false, null); return; } GraphicsUtil.CheckError("Render - Begin"); if (Lights.Count > 0) { GL.BindFramebuffer(FramebufferTarget.Framebuffer, Lights[0].FBO); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); } // TODO: Discard fully out-of-view lights! if (OneDLights) { Shader_Lightmap1D.Bind(); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); } else { Shader_Lightmap.Bind(); } GraphicsUtil.CheckError("Render - Before Light Precalcer"); MainRenderContext.CalcShadows = true; for (int i = 0; i < Lights.Count; i++) { Lights[i].PrepareLightmap(); GraphicsUtil.CheckError("Render - Light Precalcer (Prep)"); Scaler = Lights[i].GetScaler(); GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, Adder = Lights[i].GetAdder()); if (OneDLights) { GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1f }); GL.Uniform4(21, new Vector4(ViewCenterInverse.X / OriginalScaler.X, Math.Max(OriginalScaler.X, OriginalScaler.Y), ViewCenterInverse.Y / OriginalScaler.Y + 1.0f, Lights[i].IsSkyLight ? 1.0f : 0.0f)); } MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GraphicsUtil.CheckError("Render - Light Precalcer"); RenderAll(true, Lights[i].ShouldShadow); } if (OneDLights) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); } MainRenderContext.CalcShadows = false; GraphicsUtil.CheckError("Render - Lights precalced"); GL.Viewport(0, 0, Window.Width / Pixelation, Window.Height / Pixelation); Shaders.ColorMult2DShader.Bind(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, c_FBO); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0, 0, 0, 1 }); Scaler = OriginalScaler; Adder = OriginalAdder; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GraphicsUtil.CheckError("Render - Lights prepped"); RenderAll(false, null); if (OneDLights) { Shader_ApplyLights1D.Bind(); } else { Shader_Combine.Bind(); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, l_FBO); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0, 0, 0, 1 }); Scaler = Vector2.One; Adder = Vector2.Zero; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; MainRenderContext.Engine = this; GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One); GraphicsUtil.CheckError("Render - Setup Lights combine"); for (int i = 0; i < Lights.Count; i++) { GL.Uniform2(3, Lights[i].GetSecondScaler(MainRenderContext)); GL.Uniform2(4, Lights[i].GetSecondAdder(MainRenderContext)); GL.Uniform4(6, new Vector4(Lights[i].Color.R, Lights[i].Color.G, Lights[i].Color.B, Lights[i].Color.A)); if (!OneDLights) { GL.Uniform1(5, (float)Lights[i].Width); GL.Uniform1(8, Lights[i].SubDivider); } else { GL.Uniform1(8, Lights[i].ExtraLightDist); GL.Uniform4(21, new Vector4(ViewCenterInverse.X / OriginalScaler.X, Math.Max(OriginalScaler.X, OriginalScaler.Y), ViewCenterInverse.Y / OriginalScaler.Y + 1.0f, Lights[i].IsSkyLight ? 1.0f : 0.0f)); } GL.BindTexture(OneDLights ? TextureTarget.Texture1D : TextureTarget.Texture2D, Lights[i].FBO_Tex); RenderHelper.RenderRectangle(MainRenderContext, -1, -1, 1, 1); } GraphicsUtil.CheckError("Render - Lights combined"); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, l_FBO_Tex); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, c_FBO_Tex); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.DrawBuffer(DrawBufferMode.Back); Shader_Addlighttoscene.Bind(); Scaler = Vector2.One; Adder = Vector2.Zero; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GL.Viewport(0, 0, Window.Width, Window.Height); RenderHelper.RenderRectangle(MainRenderContext, -1, -1, 1, 1); GraphicsUtil.CheckError("Render - Added"); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture0); Shaders.ColorMult2DShader.Bind(); GraphicsUtil.CheckError("Render - Complete"); }
/// <summary> /// Renders a single frame of the 2D game engine. /// </summary> public override void RenderSingleFrame() { GraphicsUtil.CheckError("RenderSingleFrame"); // Audio handling Sounds.Update(AudioCamera.Position, AudioCamera.Direction, AudioCamera.Up, Location.Zero, Window.Focused); // First step: setup MainRenderContext.Width = Window.Width / Pixelation; MainRenderContext.Height = Window.Height / Pixelation; MainRenderContext.Zoom = OriginalZoom; MainRenderContext.ZoomMultiplier = ZoomMultiplier; MainRenderContext.ViewCenter = ViewCenterInverse; MainRenderContext.Engine = this; MainRenderContext.AspectHelper = MainRenderContext.Width / (float)MainRenderContext.Height; GlobalTickTime += Delta; // Second step: Prepare positioning and blank out shaders if (Zoom > MaximumZoom) { Zoom = MaximumZoom; } else if (Zoom < MinimumZoom) { Zoom = MinimumZoom; } OriginalZoom = Zoom; float aspect = Window.Width / (float)Window.Height; float sc = 1.0f / (OriginalZoom * ZoomMultiplier); OriginalScaler = new Vector2(sc, sc * aspect); OriginalAdder = ViewCenterInverse; Client.Ortho = Matrix4.CreateOrthographicOffCenter(OriginalAdder.X - OriginalScaler.X, OriginalAdder.X + OriginalScaler.X, OriginalAdder.Y + OriginalScaler.Y, OriginalAdder.Y - OriginalScaler.Y, -1, 1); Scaler = OriginalScaler; Adder = OriginalAdder; float wx = Client.MouseX / (float)Window.Width; float wy = 1.0f - (Client.MouseY / (float)Window.Height); wx -= 0.5f; wy -= 0.5f; wx *= 2f; wy *= 2f; wx /= OriginalScaler.X; wy /= OriginalScaler.Y; MouseCoords = new Vector2(wx, wy) + ViewCenter; if (OneDLights) { Shader_ApplyLights1D.Bind(); } else { Shader_Combine.Bind(); } GraphicsUtil.CheckError("RenderSingleFrame - 2"); GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); GL.Uniform1(7, aspect); GraphicsUtil.CheckError("RenderSingleFrame - 2.5"); Shader_Lightmap1D.Bind(); Shaders.ColorMult2DShader.Bind(); GraphicsUtil.CheckError("RenderSingleFrame - 3"); GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); Rendering.SetColor(Vector4.One); // Third step: Pass to the primary rendering system try { GraphicsUtil.CheckError("Pre-Render"); Render(); GraphicsUtil.CheckError("Post-Render"); } catch (Exception ex) { if (ex is ThreadAbortException) { throw; } Console.WriteLine("Rendering exception: " + ex); } }