예제 #1
0
        public static CVar Register(string Name, object DefaultVal = null, CVarType Type = CVarType.Default, CVarSetFunc OnSet = null, CVarGetFunc OnGet = null)
        {
            if (Find(Name) != null)
            {
                throw new Exception("CVar " + Name + " already registered");
            }

            CVar Var = new CVar(Name, DefaultVal, Type, OnSet, OnGet);

            CVars.Add(Var);
            return(Var);
        }
예제 #2
0
        public static string GetString(string Name, string Default = "")
        {
            CVar CVar = Find(Name);

            if (CVar != null)
            {
                object Val = CVar.Value;

                if (Val != null)
                {
                    return(Val.ToString());
                }
            }

            return(Default);
        }
예제 #3
0
        static void LoadContent()
        {
            string GameDllPath = Path.Combine(CVar.GetString("game"), "Game.dll");

            if (!File.Exists(GameDllPath))
            {
                FatalError("File not found: {0}", GameDllPath);
            }

            Assembly GameAssembly = Reflect.LoadAssembly(GameDllPath);

            Importers.RegisterAll(GameAssembly);

            Type[] GameImplementations = Reflect.GetAllImplementationsOf(GameAssembly, typeof(LibTechGame)).ToArray();

            if (GameImplementations.Length == 0)
            {
                FatalError("Could not find game implementation in {0}", GameDllPath);
            }
            if (GameImplementations.Length > 1)
            {
                FatalError("Found too many game implementations in {0}", GameDllPath);
            }

            Game = (LibTechGame)Activator.CreateInstance(GameImplementations[0]);
            Game.Load();

            RenderDevice = new RenderDevice(ShaderProgram.GUI, Width, Height);
            NuklearAPI.Init(RenderDevice);
            NuklearAPI.SetClipboardCallback((Txt) => {
                if (string.IsNullOrEmpty(Txt))
                {
                    return;
                }

                Glfw.SetClipboardString(Window, Txt);
            }, () => {
                string Str = Glfw.GetClipboardString(Window);
                if (Str == null)
                {
                    Str = "";
                }

                return(Str);
            });

            Glfw.SetCursorPosCallback(Window, (Wnd, X, Y) => {
                RenderDevice.OnMouseMove((int)X, (int)Y);
            });

            Glfw.SetMouseButtonCallback(Window, (Wnd, Button, State, Mods) => {
                NuklearEvent.MouseButton NkButton;
                bool IsDown = State == Glfw.InputState.Press ? true : false;

                if (!(State == Glfw.InputState.Press || State == Glfw.InputState.Release))
                {
                    return;
                }

                if (Button == Glfw.MouseButton.ButtonLeft)
                {
                    NkButton = NuklearEvent.MouseButton.Left;
                }
                else if (Button == Glfw.MouseButton.ButtonMiddle)
                {
                    NkButton = NuklearEvent.MouseButton.Middle;
                }
                else if (Button == Glfw.MouseButton.ButtonRight)
                {
                    NkButton = NuklearEvent.MouseButton.Right;
                }
                else
                {
                    return;
                }

                RenderDevice.OnMouseButton(NkButton, (int)MousePos.X, (int)MousePos.Y, IsDown);
            });

            Glfw.SetScrollCallback(Window, (Wnd, X, Y) => {
                RenderDevice.OnScroll((float)X, (float)Y);
            });

            Glfw.SetCharCallback(Window, (Wnd, Chr) => {
                RenderDevice.OnText(((char)Chr).ToString());
            });

            Glfw.SetKeyCallback(Window, (Wnd, KCode, SCode, State, Mods) => {
                if (KCode == Glfw.KeyCode.F1 && State == Glfw.InputState.Press)
                {
                    GConsole.Open = true;
                }

                NkKeys K = ConvertToNkKey(KCode, Mods);

                if (K != NkKeys.None)
                {
                    RenderDevice.OnKey(K, State == Glfw.InputState.Press);
                    if (State == Glfw.InputState.Repeat)
                    {
                        RenderDevice.OnKey(K, true);
                    }
                }
            });

            Glfw.SetDropCallback(Window, (Wnd, Cnt, Paths) => {
                DragDropPaths = Paths;
            });
        }
예제 #4
0
        static void CreateContext(/*params string[] RequiredExtensions*/)
        {
            GConsole.WriteLine("Initializing OpenGL");

#if DEBUG
            Khronos.KhronosApi.Log += (S, E) => {
                if (E.Name == "glGetError")
                {
                    return;
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("OpenGL> {0}", string.Format("{0}({1}) = {2}", E.Name, string.Join(", ", E.Args), E.ReturnValue ?? "null"));
                Console.ResetColor();
            };
            Khronos.KhronosApi.LogEnabled = false;            //*/
#endif

            GConsole.WriteLine("Initializing GLFW");
            Glfw.ConfigureNativesDirectory("native/glfw3_64");
            if (!Glfw.Init())
            {
                FatalError("Could not initialize GLFW");
            }

            Glfw.SetErrorCallback((Err, Msg) => {
                FatalError("GLFW({0}) {1}", Err, Msg);
            });

            Width  = CVar.GetInt("width", 800);
            Height = CVar.GetInt("height", 600);

            Glfw.WindowHint(Glfw.Hint.Resizable, CVar.GetBool("resizable"));

            //Glfw.WindowHint(Glfw.Hint.ClientApi, Glfw.ClientApi.None);
            Glfw.WindowHint(Glfw.Hint.ClientApi, Glfw.ClientApi.OpenGL);
            Glfw.WindowHint(Glfw.Hint.ContextCreationApi, Glfw.ContextApi.Native);
            Glfw.WindowHint(Glfw.Hint.Doublebuffer, CVar.GetBool("gl_doublebuffer"));
            Glfw.WindowHint(Glfw.Hint.ContextVersionMajor, CVar.GetInt("gl_major"));
            Glfw.WindowHint(Glfw.Hint.ContextVersionMinor, CVar.GetInt("gl_minor"));

            Glfw.WindowHint(Glfw.Hint.Samples, CVar.GetInt("gl_samples"));
            Glfw.WindowHint(Glfw.Hint.OpenglForwardCompat, CVar.GetBool("gl_forwardcompat"));
            Glfw.WindowHint(Glfw.Hint.OpenglProfile, Glfw.OpenGLProfile.Core);
#if DEBUG
            Glfw.WindowHint(Glfw.Hint.OpenglDebugContext, true);
#endif

            GConsole.WriteLine("Creating window");
            Window = Glfw.CreateWindow(Width, Height, "libTech");
            if (!Window)
            {
                FatalError("Could not create window({0}x{1})", Width, Height);
            }

            Gl.Initialize();
            Glfw.MakeContextCurrent(Window);

            /*bool AllSupported = true;
             *
             * for (int i = 0; i < RequiredExtensions.Length; i++) {
             *      if (!Glfw.ExtensionSupported(RequiredExtensions[i])) {
             *              GConsole.WriteLine("{0} not supported", RequiredExtensions[i]);
             *              AllSupported = false;
             *      }
             * }
             *
             * if (!AllSupported)
             *      while (true)
             *              Thread.Sleep(10);*/

#if DEBUG
            Gl.DebugMessageCallback((Src, DbgType, ID, Severity, Len, Buffer, UserPtr) => {
                if (Severity == Gl.DebugSeverity.Notification)
                {
                    return;
                }

                GConsole.WriteLine("OpenGL {0} {1} {2}, {3}", Src, DbgType, ID, Severity);
                GConsole.WriteLine(Encoding.ASCII.GetString((byte *)Buffer, Len));

                if ((/*Severity == Gl.DebugSeverity.Medium ||*/ Severity == Gl.DebugSeverity.High) && Debugger.IsAttached)
                {
                    Debugger.Break();
                }
            }, IntPtr.Zero);

            Gl.Enable((EnableCap)Gl.DEBUG_OUTPUT);
            Gl.Enable((EnableCap)Gl.DEBUG_OUTPUT_SYNCHRONOUS);
#endif

            GConsole.WriteLine("{0}, {1}", Gl.GetString(StringName.Vendor), Gl.GetString(StringName.Renderer));
            GConsole.WriteLine("OpenGL {0}", Gl.GetString(StringName.Version));
            GConsole.WriteLine("GLSL {0}", Gl.GetString(StringName.ShadingLanguageVersion));

            Gl.ClearColor(69 / 255.0f, 112 / 255.0f, 56 / 255.0f, 1.0f);

            // F**k the police
            Gl.Enable((EnableCap)Gl.DEPTH_CLAMP);
            Gl.Enable(EnableCap.Blend);
            //Gl.VERTEX_PROGRAM_POINT_SIZE;
            Gl.Enable((EnableCap)Gl.VERTEX_PROGRAM_POINT_SIZE);
            //Gl.Enable((EnableCap)Gl.SAMPLE_SHADING);
            //Gl.Enable(EnableCap.FramebufferSrgb);

            Gl.BlendEquationSeparate(BlendEquationMode.FuncAdd, BlendEquationMode.FuncAdd);
            Gl.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            //Gl.BlendEquation(BlendEquationMode.FuncAdd);
            //Gl.BlendFunc(BlendingFactor.One, BlendingFactor.One);

            ShaderProgram.LoadDefaultShaders();
        }
예제 #5
0
        static void Main(string[] args)
        {
            CVar.InitMode = true;
            CVar.Register("game", "basegame", CVarType.Replicated | CVarType.Init, (This, Old, New) => This.Value = Path.GetFullPath((string)New));

            CVar.Register("width", 1366, CVarType.Archive);
            CVar.Register("height", 768, CVarType.Archive);
            CVar.Register("borderless", false, CVarType.Archive);
            CVar.Register("resizable", false, CVarType.Archive);
            CVar.Register("gl_doublebuffer", true, CVarType.Archive);
            CVar.Register("gl_samples", 8, CVarType.Archive);

            CVar.Register("gl_forwardcompat", true, CVarType.Archive | CVarType.Init | CVarType.Unsafe);
            CVar.Register("gl_major", 4, CVarType.Archive | CVarType.Init | CVarType.Unsafe);
            CVar.Register("gl_minor", 5, CVarType.Archive | CVarType.Init | CVarType.Unsafe);

            // Parse all arguments and set CVars
            foreach (var Arg in ArgumentParser.All)
            {
                switch (Arg.Key)
                {
                case "console":
                    GConsole.Open = true;
                    break;

                default: {
                    CVar CVar = CVar.Find(Arg.Key);

                    if (CVar != null)
                    {
                        CVar.Value = Arg.Value.LastOrDefault();
                    }
                    else
                    {
                        CVar.Register(Arg.Key, Arg.Value.LastOrDefault());
                    }

                    break;
                }
                }
            }

            CVar.InitMode = false;
            foreach (var CVar in CVar.GetAll())
            {
                GConsole.WriteLine(CVar);
            }

            FileWatcher.Init("content");
            Importers.RegisterAll(Reflect.GetExeAssembly());

            CreateContext();
            InitPhysics();

            LoadContent();

            Stopwatch SWatch = Stopwatch.StartNew();
            float     Target = 1.0f / 120;
            float     Dt     = Target;

            TextureTarget Tgt = TextureTarget.Texture2dMultisample;

            if (CVar.GetInt("gl_samples") == 0)
            {
                Tgt = TextureTarget.Texture2d;
            }

            Texture ColorTex = new Texture(Width, Height, Tgt, 1, InternalFormat.Rgb16f);
            Texture DepthTex = new Texture(Width, Height, Tgt, 1, InternalFormat.Depth24Stencil8);

            Framebuffer FB = new Framebuffer();

            FB.AttachColorTexture(ColorTex);
            FB.AttachDepthTexture(DepthTex);

            Texture SkyboxCubeMap = new Texture(1024, 1024, TextureTarget.TextureCubeMap, 1, InternalFormat.Srgb8Alpha8);

            SkyboxCubeMap.SetFilter(Gl.LINEAR, Gl.LINEAR);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/front.png"), Z: Texture.FRONT);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/back.png"), Z: Texture.BACK);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/left.png"), Z: Texture.LEFT);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/right.png"), Z: Texture.RIGHT);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/top.png"), Z: Texture.TOP);
            SkyboxCubeMap.SubImage3D(Image.FromFile("content/textures/skybox/interstellar/bottom.png"), Z: Texture.BOTTOM);

            //FB.Clear(new Vector4(1, 0, 0, 1));

            Model SkyboxCube = Importers.Load <Model>("content/models/cube.obj");

            SkyboxCube.Scale = new Vector3(2);
            SkyboxCube.Meshes[0].Material.Shader  = ShaderProgram.Skybox;
            SkyboxCube.Meshes[0].Material.Diffuse = SkyboxCubeMap;

            //bool DoDebug = true;

            while (!Glfw.WindowShouldClose(Window))
            {
                /*if (Khronos.KhronosApi.LogEnabled) {
                 *      Khronos.KhronosApi.LogCommand("END FRAME", null, null);
                 *      Khronos.KhronosApi.LogEnabled = false;
                 * }
                 *
                 * if (DoDebug) {
                 *      DoDebug = false;
                 *      Khronos.KhronosApi.LogEnabled = true;
                 *      Khronos.KhronosApi.LogCommand("BEGIN FRAME", null, null);
                 * }*/

                Update(Dt);
                Gl.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit | ClearBufferMask.StencilBufferBit);

                FB.Bind();
                {
                    Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
                    SetupState();

                    Gl.Disable(EnableCap.CullFace);
                    Gl.DepthMask(false);
                    SkyboxCube.Position = Camera.ActiveCamera?.Position ?? Vector3.Zero;
                    SkyboxCube.Draw();
                    Gl.DepthMask(true);

                    DrawScene(Dt);
                }
                FB.Unbind();

                // Swap to GUI camera
                Gl.Disable(EnableCap.DepthTest);
                Gl.Disable(EnableCap.CullFace);
                Camera.ActiveCamera = Camera.GUICamera;

                Immediate.UseShaders(() => {
                    if (ColorTex.Multisampled)
                    {
                        Immediate.TriangleShader = ShaderProgram.PostMultisample;
                        Immediate.TriangleShader.Uniform2f("TexSize", new Vector2(ColorTex.Width, ColorTex.Height));
                    }
                    else
                    {
                        Immediate.TriangleShader = ShaderProgram.Post;
                    }

                    Immediate.TriangleShader.Uniform1f("Exposure", 1.0f);

                    Gl.Enable(EnableCap.FramebufferSrgb);
                    Immediate.Texture2D(Vector2.Zero, ColorTex, UVInvertY: true);
                    Gl.Disable(EnableCap.FramebufferSrgb);
                });

                DrawGUI(Dt);
                Glfw.SwapBuffers(Window);

                // Cap at Target framerate
                while ((float)SWatch.ElapsedMilliseconds / 1000 < Target)
                {
                    ;
                }

                Dt  = (float)SWatch.ElapsedMilliseconds / 1000;
                FPS = (int)(1.0f / Dt);
                SWatch.Restart();
            }

            Environment.Exit(0);
        }