public override void Use(RenderState rstate, IVertexType vertextype, Lighting lights) { if (Camera == null) { return; } ShaderCaps caps = ShaderCaps.None; if (HasSpotlight(ref lights)) { caps |= ShaderCaps.Spotlight; } if (EtEnabled) { caps |= ShaderCaps.EtEnabled; } if (Fade) { caps |= ShaderCaps.FadeEnabled; } var dt = GetTexture(0, DtSampler); if (dt != null && dt.Dxt1) { caps |= ShaderCaps.AlphaTestEnabled; //Shitty way of dealing with alpha_mask } var shader = GetShader(vertextype, caps); shader.SetWorld(ref World); shader.SetView(Camera); shader.SetViewProjection(Camera); //Dt shader.SetDtSampler(0); BindTexture(rstate, 0, DtSampler, 0, DtFlags, ResourceManager.WhiteTextureName); //Dc shader.SetDc(Dc); //Oc shader.SetOc(Oc); if (AlphaEnabled || Fade || OcEnabled) { rstate.BlendMode = BlendMode.Normal; } else { rstate.BlendMode = BlendMode.Opaque; } //Fade if (Fade) { shader.SetFadeRange(new Vector2(FadeNear, FadeFar)); } //MaterialAnim if (MaterialAnim != null) { shader.SetMaterialAnim(new Vector4( MaterialAnim.UOffset, MaterialAnim.VOffset, MaterialAnim.UScale, MaterialAnim.VScale )); } else { shader.SetMaterialAnim(new Vector4(0, 0, 1, 1)); } shader.SetFlipNormal(FlipNormals); //Ec shader.SetEc(Ec); //EtSampler if (EtEnabled) { shader.SetEtSampler(1); BindTexture(rstate, 1, EtSampler, 1, EtFlags, ResourceManager.NullTextureName); } //Set lights SetLights(shader, lights); var normalMatrix = World; normalMatrix.Invert(); normalMatrix.Transpose(); shader.SetNormalMatrix(ref normalMatrix); shader.UseProgram(); }
public override void ApplyDepthPrepass(RenderState rstate) { throw new NotImplementedException(); }
public override void DepthPrepass(ICamera camera, RenderState rstate) { Init(); if (Model != null) { Model.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); if (Model.Levels.Length != 0) { var center = VectorMath.Transform(Model.Levels[0].Center, World); var lvl = GetLevel(Model, center, camera.Position); if (lvl == null) { return; } Model.DepthPrepassLevel(lvl, rstate, World); } } else if (Cmp != null || CmpParts != null) { if (Cmp != null) { Cmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); } else { _parentCmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); } //Check if -something- renders var partCol = (IEnumerable <Part>)CmpParts ?? Cmp.Parts; foreach (Part p in partCol) { var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { model.DepthPrepassLevel(lvl, rstate, w); } } } } else if (Sph != null) { Sph.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); Sph.DepthPrepass(rstate, _worldSph); } }
static void EnableCull(RenderState rs) { rs.Cull = true; }
public abstract void ApplyDepthPrepass(RenderState rstate);
static void BandShaderCleanup(RenderState state) { state.Cull = true; }
public void Run() { FLLog.Info("Engine", "Version: " + Platform.GetInformationalVersion <Game>()); //TODO: This makes i5-7200U on mesa 18 faster, but this should probably be a configurable option Environment.SetEnvironmentVariable("mesa_glthread", "true"); SSEMath.Load(); if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) { FLLog.Error("SDL", "SDL_Init failed, exiting."); return; } SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1"); SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); //Set GL states SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24); //Create Window var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE; if (fullscreen) { flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; } var sdlWin = SDL.SDL_CreateWindow( "LibreLancer", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, width, height, flags ); //Cursors curArrow = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW); curMove = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_CROSSHAIR); curTextInput = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_IBEAM); curResizeNS = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENS); curResizeEW = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZEWE); curResizeNESW = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENESW); curResizeNWSE = SDL.SDL_CreateSystemCursor(SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_SIZENWSE); //Window sizing if (minWindowSize != Point.Zero) { SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y); } if (sdlWin == IntPtr.Zero) { FLLog.Error("SDL", "Failed to create window, exiting."); return; } SDL.SDL_EventState(SDL.SDL_EventType.SDL_DROPFILE, SDL.SDL_ENABLE); windowptr = sdlWin; var glcontext = SDL.SDL_GL_CreateContext(sdlWin); if (glcontext == IntPtr.Zero || !GL.CheckStringSDL()) { SDL.SDL_GL_DeleteContext(glcontext); if (Platform.RunningOS == OS.Windows) { SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "Librelancer", "Failed to create OpenGL context, exiting.", IntPtr.Zero); } FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting."); return; } else { GL.LoadSDL(); Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER)); } SetVSync(true); //Init game state RenderState = new RenderState(); Load(); //Start game running = true; timer = new Stopwatch(); timer.Start(); double last = 0; double elapsed = 0; SDL.SDL_Event e; SDL.SDL_StopTextInput(); while (running) { //Pump message queue while (SDL.SDL_PollEvent(out e) != 0) { switch (e.type) { case SDL.SDL_EventType.SDL_QUIT: { if (WillClose != null) { WillClose(); } running = false; //TODO: Raise Event break; } case SDL.SDL_EventType.SDL_MOUSEMOTION: { Mouse.X = e.motion.x; Mouse.Y = e.motion.y; Mouse.OnMouseMove(); break; } case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN: { Mouse.X = e.button.x; Mouse.Y = e.button.y; var btn = GetMouseButton(e.button.button); Mouse.Buttons |= btn; Mouse.OnMouseDown(btn); break; } case SDL.SDL_EventType.SDL_MOUSEBUTTONUP: { Mouse.X = e.button.x; Mouse.Y = e.button.y; var btn = GetMouseButton(e.button.button); Mouse.Buttons &= ~btn; Mouse.OnMouseUp(btn); break; } case SDL.SDL_EventType.SDL_MOUSEWHEEL: { Mouse.OnMouseWheel(e.wheel.y); break; } case SDL.SDL_EventType.SDL_TEXTINPUT: { Keyboard.OnTextInput(GetEventText(ref e)); break; } case SDL.SDL_EventType.SDL_KEYDOWN: { Keyboard.OnKeyDown((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0); break; } case SDL.SDL_EventType.SDL_KEYUP: { Keyboard.OnKeyUp((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod); break; } case SDL.SDL_EventType.SDL_WINDOWEVENT: if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED) { SDL.SDL_GetWindowSize(windowptr, out width, out height); OnResize(); } break; case SDL.SDL_EventType.SDL_DROPFILE: { var file = UnsafeHelpers.PtrToStringUTF8(e.drop.file); OnDrop(file); SDL.SDL_free(e.drop.file); break; } } } //Do game things if (!running) { break; } Action work; while (actions.TryDequeue(out work)) { work(); } totalTime = timer.Elapsed.TotalSeconds; Update(elapsed); if (!running) { break; } Draw(elapsed); //Frame time before, FPS after var tk = timer.Elapsed.TotalSeconds - totalTime; frameTime = CalcAverageTime(tk); if (_screenshot) { TakeScreenshot(); _screenshot = false; } SDL.SDL_GL_SwapWindow(sdlWin); if (GL.FrameHadErrors()) //If there was a GL error, track it down. { GL.ErrorChecking = true; } elapsed = timer.Elapsed.TotalSeconds - last; renderFrequency = (1.0 / CalcAverageTick(elapsed)); last = timer.Elapsed.TotalSeconds; totalTime = timer.Elapsed.TotalSeconds; if (elapsed < 0) { elapsed = 0; FLLog.Warning("Timing", "Stopwatch returned negative time!"); } } Cleanup(); SDL.SDL_Quit(); }
public override void DepthPrepass(ICamera camera, RenderState rstate) { }
public override void Use(RenderState rstate, IVertexType vertextype, ref Lighting lights) { if (Camera == null) { return; } ShaderCaps caps = ShaderCaps.None; if (VertexLighting) { caps |= ShaderCaps.VertexLighting; } if (HasSpotlight(ref lights)) { caps |= ShaderCaps.Spotlight; } if (EtEnabled) { caps |= ShaderCaps.EtEnabled; } if (Fade) { caps |= ShaderCaps.FadeEnabled; } var dxt1 = GetDxt1(); if (dxt1) { caps |= ShaderCaps.AlphaTestEnabled; //Shitty way of dealing with alpha_mask //FL has a lot of DXT1 textures that aren't part of alpha_mask //so this brings overall performance down. //Don't change any of this stuff unless you can verify it works //in all places! (Check Li01 shipyards, Bw10 tradelanes) } var shader = GetShader(vertextype, caps); lastShader = shader; shader.SetWorld(ref World); shader.SetView(Camera); shader.SetViewProjection(Camera); //Dt shader.SetDtSampler(0); BindTexture(rstate, 0, DtSampler, 0, DtFlags, ResourceManager.WhiteTextureName); //Dc shader.SetDc(Dc); //Oc shader.SetOc(Oc); if (AlphaEnabled || Fade || OcEnabled || dxt1) { rstate.BlendMode = BlendMode.Normal; } else { rstate.BlendMode = BlendMode.Opaque; //TODO: Maybe I can just leave this out? } //Fade if (Fade) { shader.SetFadeRange(new Vector2(FadeNear, FadeFar)); } //MaterialAnim if (MaterialAnim != null) { shader.SetMaterialAnim(new Vector4( MaterialAnim.UOffset, MaterialAnim.VOffset, MaterialAnim.UScale, MaterialAnim.VScale )); } else { shader.SetMaterialAnim(new Vector4(0, 0, 1, 1)); } shader.SetFlipNormal(FlipNormals); if (Bones != null && vertextype is DfmVertex) { shader.Shader.UniformBlockBinding("Bones", 1); shader.SetSkinningEnabled(true); Bones.BindTo(1); } else { shader.SetSkinningEnabled(false); } //Ec shader.SetEc(Ec); //EtSampler if (EtEnabled) { shader.SetEtSampler(1); BindTexture(rstate, 1, EtSampler, 1, EtFlags, ResourceManager.NullTextureName); } //Set lights SetLights(shader, ref lights); var normalMatrix = World; normalMatrix.Invert(); normalMatrix.Transpose(); shader.SetNormalMatrix(ref normalMatrix); shader.UseProgram(); }
public unsafe void Run(RenderState state) { if (CmdType == RenderCmdType.Material || CmdType == RenderCmdType.MaterialFade) { var Material = (RenderMaterial)Source; if (Material == null) { return; } Material.MaterialAnim = MaterialAnim; Material.World = World; if (CmdType == RenderCmdType.MaterialFade) { Material.Fade = true; var fn = BaseVertex; var ff = Index; Material.FadeNear = *(float *)(&fn); Material.FadeFar = *(float *)(&ff); } if (Material.DisableCull) { state.Cull = false; } Material.Use(state, Buffer.VertexType, ref Lights); if ((CmdType != RenderCmdType.MaterialFade) && BaseVertex != -1) { Buffer.Draw(Primitive, BaseVertex, Start, Count); } else { Buffer.Draw(Primitive, Count); } if (Material.DoubleSided) { Material.FlipNormals = true; Material.UpdateFlipNormals(); state.CullFace = CullFaces.Front; if ((CmdType != RenderCmdType.MaterialFade) && BaseVertex != -1) { Buffer.Draw(Primitive, BaseVertex, Start, Count); } else { Buffer.Draw(Primitive, Count); } state.CullFace = CullFaces.Back; Material.FlipNormals = false; } if (CmdType == RenderCmdType.MaterialFade) { Material.Fade = false; } if (Material.DisableCull) { state.Cull = true; } } else if (CmdType == RenderCmdType.Shader) { var Shader = (Shader)Source; ShaderSetup(Shader, state, ref this); Shader.UseProgram(); if (BaseVertex != -1) { Buffer.Draw(Primitive, BaseVertex, Start, Count); } else { Buffer.Draw(Primitive, Start, Count); } if (Cleanup != null) { ((Action <RenderState>)Cleanup)(state); } } else if (CmdType == RenderCmdType.Billboard) { var Billboards = (Billboards)Source; Billboards.RenderStandard(Index, Hash, state); } else if (CmdType == RenderCmdType.BillboardCustom) { var billboards = (Billboards)Source; billboards.RenderCustom(state, (Shader)Cleanup, ShaderSetup, ref this); } }
static void Cleanup(RenderState rs) { rs.Cull = true; }
static void ResetState(RenderState state) { state.Cull = true; }
public void Run() { SSEMath.Load(); if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) { FLLog.Error("SDL", "SDL_Init failed, exiting."); return; } SDL.SDL_SetHint(SDL.SDL_HINT_IME_INTERNAL_EDITING, "1"); SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); //Set GL states SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_PROFILE_MASK, (int)SDL.SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 24); //Create Window var flags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE; if (fullscreen) { flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; } var sdlWin = SDL.SDL_CreateWindow( "LibreLancer", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, width, height, flags ); if (minWindowSize != Point.Zero) { SDL.SDL_SetWindowMinimumSize(sdlWin, minWindowSize.X, minWindowSize.Y); } if (sdlWin == IntPtr.Zero) { FLLog.Error("SDL", "Failed to create window, exiting."); return; } windowptr = sdlWin; if (forceANGLE) { LoadANGLE(); } else { var glcontext = SDL.SDL_GL_CreateContext(sdlWin); bool check = GL.CheckStringSDL(); if (!check) { FLLog.Warning("GL", "GL Version Insufficient - Using DX9"); SDL.SDL_GL_DeleteContext(glcontext); } if (glcontext == IntPtr.Zero || !check) { if (Platform.RunningOS == OS.Windows) { LoadANGLE(); } else { FLLog.Error("OpenGL", "Failed to create OpenGL context, exiting."); return; } } else { GL.LoadSDL(); Renderer = string.Format("{0} ({1})", GL.GetString(GL.GL_VERSION), GL.GetString(GL.GL_RENDERER)); } } SetVSync(true); //Init game state RenderState = new RenderState(); Load(); //Start game running = true; var timer = new Stopwatch(); timer.Start(); double last = 0; double elapsed = 0; SDL.SDL_Event e; SDL.SDL_StopTextInput(); while (running) { //Pump message queue while (SDL.SDL_PollEvent(out e) != 0) { switch (e.type) { case SDL.SDL_EventType.SDL_QUIT: { if (WillClose != null) { WillClose(); } running = false; //TODO: Raise Event break; } case SDL.SDL_EventType.SDL_MOUSEMOTION: { Mouse.X = e.motion.x; Mouse.Y = e.motion.y; Mouse.OnMouseMove(); break; } case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN: { Mouse.X = e.button.x; Mouse.Y = e.button.y; var btn = GetMouseButton(e.button.button); Mouse.Buttons |= btn; Mouse.OnMouseDown(btn); break; } case SDL.SDL_EventType.SDL_MOUSEBUTTONUP: { Mouse.X = e.button.x; Mouse.Y = e.button.y; var btn = GetMouseButton(e.button.button); Mouse.Buttons &= ~btn; Mouse.OnMouseUp(btn); break; } case SDL.SDL_EventType.SDL_MOUSEWHEEL: { Mouse.OnMouseWheel(e.wheel.y); break; } case SDL.SDL_EventType.SDL_TEXTINPUT: { Keyboard.OnTextInput(GetEventText(ref e)); break; } case SDL.SDL_EventType.SDL_KEYDOWN: { Keyboard.OnKeyDown((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod, e.key.repeat != 0); break; } case SDL.SDL_EventType.SDL_KEYUP: { Keyboard.OnKeyUp((Keys)e.key.keysym.sym, (KeyModifiers)e.key.keysym.mod); break; } case SDL.SDL_EventType.SDL_WINDOWEVENT: if (e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED) { SDL.SDL_GetWindowSize(windowptr, out width, out height); } break; } } //Do game things if (!running) { break; } Action work; while (actions.TryDequeue(out work)) { work(); } totalTime = timer.Elapsed.TotalSeconds; Update(elapsed); if (!running) { break; } Draw(elapsed); //Frame time before, FPS after var tk = timer.Elapsed.TotalSeconds - totalTime; frameTime = CalcAverageTime(tk); if (_screenshot) { TakeScreenshot(); _screenshot = false; } if (angle != null) { angle.SwapBuffers(); } else { SDL.SDL_GL_SwapWindow(sdlWin); } if (GL.FrameHadErrors()) //If there was a GL error, track it down. { GL.ErrorChecking = true; } elapsed = timer.Elapsed.TotalSeconds - last; renderFrequency = (1.0 / CalcAverageTick(elapsed)); last = timer.Elapsed.TotalSeconds; totalTime = timer.Elapsed.TotalSeconds; if (elapsed < 0) { elapsed = 0; FLLog.Warning("Timing", "Stopwatch returned negative time!"); } } Cleanup(); SDL.SDL_Quit(); }
public virtual void DepthPrepass(ICamera camera, RenderState rstate) { }
public abstract void Use(RenderState rstate, IVertexType vertextype, Lighting lights);
public override void ApplyDepthPrepass(RenderState rstate) { throw new InvalidOperationException(); }
public void StartFrame(ICamera cam, RenderState rs) { camera = cam; rstate = rs; lineVertices = 0; }