mirror of
				https://github.com/Ryujinx/Opentk.git
				synced 2025-11-04 09:55:01 +00:00 
			
		
		
		
	This commit is contained in:
		
							parent
							
								
									35abdde1ed
								
							
						
					
					
						commit
						d31eabf905
					
				| 
						 | 
					@ -1,296 +0,0 @@
 | 
				
			||||||
#region --- License ---
 | 
					 | 
				
			||||||
/* Licensed under the MIT/X11 license.
 | 
					 | 
				
			||||||
 * Copyright (c) 2006-2008 the OpenTK Team.
 | 
					 | 
				
			||||||
 * This notice may not be removed from any source distribution.
 | 
					 | 
				
			||||||
 * See license.txt for licensing detailed licensing details.
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * Written by Christoph Brandtner
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.Windows.Forms;
 | 
					 | 
				
			||||||
using System.Diagnostics;
 | 
					 | 
				
			||||||
using System.Drawing;
 | 
					 | 
				
			||||||
using System.Drawing.Imaging;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using OpenTK;
 | 
					 | 
				
			||||||
using OpenTK.Graphics;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Examples.Tutorial
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    /// Demonstrates how to render an animated Julia Set in real-time. Quality is sacrificed for speed.
 | 
					 | 
				
			||||||
    /// Info about the fractal: http://en.wikipedia.org/wiki/Julia_set
 | 
					 | 
				
			||||||
    /// One more major optimization could be applied (exploit the symmetry of the image with RTT), but
 | 
					 | 
				
			||||||
    /// that would make the program alot more complicated to follow. You can do this as an exercise.
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    [Example("GLSL Animated Julia Set", ExampleCategory.GLSL)]
 | 
					 | 
				
			||||||
    public class T11_Julia_Set : GameWindow
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public T11_Julia_Set()
 | 
					 | 
				
			||||||
            : base(512, 512)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region Private Fields
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // GLSL Objects
 | 
					 | 
				
			||||||
        int VertexShaderObject, FragmentShaderObject, ProgramObject;
 | 
					 | 
				
			||||||
        int TextureObject;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Julia Variables for animation
 | 
					 | 
				
			||||||
        float AnimOffsetX = 0.213f; // using non-zero as starting point to make it more interesting
 | 
					 | 
				
			||||||
        float AnimOffsetY = 0.63f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const double AnimSpeedX = 0.65; // anim speed scaling is solely used to make the anim more interesting
 | 
					 | 
				
			||||||
        const double AnimSpeedY = 1.05;
 | 
					 | 
				
			||||||
        const double AnimCosinusPercent = 0.85f; // scales the cosinus down to 85% to avoid the (boring) borders
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        float UniformScaleFactorX; // fractal horizontal scaling is only affected by window resize
 | 
					 | 
				
			||||||
        float UniformScaleFactorY; // fractal vertical scaling is only affected by window resize
 | 
					 | 
				
			||||||
        float UniformOffsetX = 1.8f; // fractal horizontal offset
 | 
					 | 
				
			||||||
        float UniformOffsetY = 1.8f; // fractal vertical offset
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Text drawing (for fps)
 | 
					 | 
				
			||||||
        TextPrinter printer = new TextPrinter();
 | 
					 | 
				
			||||||
        TextureFont font = new TextureFont(new Font(FontFamily.GenericSansSerif, 14.0f));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion private Fields
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region OnLoad
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Setup OpenGL and load resources here.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="e">Not used.</param>
 | 
					 | 
				
			||||||
        public override void OnLoad(EventArgs e)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Check for necessary capabilities:
 | 
					 | 
				
			||||||
            if (!GL.SupportsExtension("VERSION_2_0"))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                MessageBox.Show("You need at least OpenGL 2.0 to run this example. Aborting.",
 | 
					 | 
				
			||||||
                                 "GLSL not supported", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
 | 
					 | 
				
			||||||
                this.Exit();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.VSync = VSyncMode.On;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.Disable(EnableCap.Dither);
 | 
					 | 
				
			||||||
            GL.ClearColor(0.2f, 0f, 0.4f, 0f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // declare some variables for tracking which shader did compile, and which texture to use
 | 
					 | 
				
			||||||
            string[] ShaderFilenames = new string[2];
 | 
					 | 
				
			||||||
            ShaderFilenames[0] = "Data/Shaders/JuliaSet_SM3_FS.glsl";
 | 
					 | 
				
			||||||
            ShaderFilenames[1] = "Data/Shaders/JuliaSet_SM2_FS.glsl";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            byte CurrentOption = 0;
 | 
					 | 
				
			||||||
            string LogInfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #region Shaders
 | 
					 | 
				
			||||||
            // Load&Compile Vertex Shader
 | 
					 | 
				
			||||||
            using (StreamReader sr = new StreamReader("Data/Shaders/JuliaSet_VS.glsl"))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                VertexShaderObject = GL.CreateShader(ShaderType.VertexShader);
 | 
					 | 
				
			||||||
                GL.ShaderSource(VertexShaderObject, sr.ReadToEnd());
 | 
					 | 
				
			||||||
                GL.CompileShader(VertexShaderObject);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.GetShaderInfoLog(VertexShaderObject, out LogInfo);
 | 
					 | 
				
			||||||
            if (LogInfo.Length > 0 && !LogInfo.Contains("hardware"))
 | 
					 | 
				
			||||||
                Trace.WriteLine("Vertex Shader Log:\n" + LogInfo);
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                Trace.WriteLine("Vertex Shader compiled without complaint.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Load&Compile Fragment Shader
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            FragmentShaderObject = GL.CreateShader(ShaderType.FragmentShader);
 | 
					 | 
				
			||||||
            do
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                using (StreamReader sr = new StreamReader(ShaderFilenames[CurrentOption]))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    GL.ShaderSource(FragmentShaderObject, sr.ReadToEnd());
 | 
					 | 
				
			||||||
                    GL.CompileShader(FragmentShaderObject);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                GL.GetShaderInfoLog(FragmentShaderObject, out LogInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (LogInfo.Length > 0 && !LogInfo.Contains("hardware"))
 | 
					 | 
				
			||||||
                    Trace.WriteLine("Compiling " + ShaderFilenames[CurrentOption] + " failed!\nLog:\n" + LogInfo);
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Trace.WriteLine("Fragment Shader compiled without complaint.");
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (++CurrentOption > 1)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    MessageBox.Show("Neither SM2 nor SM3 Fragment Shader compiled successfully. Aborting.",
 | 
					 | 
				
			||||||
                                     "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
 | 
					 | 
				
			||||||
                    this.Exit();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } while (true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Link the Shaders to a usable Program
 | 
					 | 
				
			||||||
            ProgramObject = GL.CreateProgram();
 | 
					 | 
				
			||||||
            GL.AttachShader(ProgramObject, VertexShaderObject);
 | 
					 | 
				
			||||||
            GL.AttachShader(ProgramObject, FragmentShaderObject);
 | 
					 | 
				
			||||||
            GL.LinkProgram(ProgramObject);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // make current
 | 
					 | 
				
			||||||
            GL.UseProgram(ProgramObject);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Flag ShaderObjects for delete when app exits
 | 
					 | 
				
			||||||
            GL.DeleteShader(VertexShaderObject);
 | 
					 | 
				
			||||||
            GL.DeleteShader(FragmentShaderObject);
 | 
					 | 
				
			||||||
            #endregion Shaders
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #region Textures
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Load&Bind the 1D texture for color lookups
 | 
					 | 
				
			||||||
            GL.ActiveTexture(TextureUnit.Texture0); // select TMU0
 | 
					 | 
				
			||||||
            GL.GenTextures(1, out TextureObject);
 | 
					 | 
				
			||||||
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
 | 
					 | 
				
			||||||
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
 | 
					 | 
				
			||||||
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapS, (int)(TextureWrapMode)All.ClampToEdge);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            using (Bitmap bitmap = new Bitmap("Data/JuliaColorTable.bmp"))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
 | 
					 | 
				
			||||||
                                                  System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 | 
					 | 
				
			||||||
                GL.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.Rgb8, data.Width, 0, OpenTK.Graphics.PixelFormat.Bgr,
 | 
					 | 
				
			||||||
                              PixelType.UnsignedByte, data.Scan0);
 | 
					 | 
				
			||||||
                bitmap.UnlockBits(data);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            #endregion Textures
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region OnUnLoad
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override void OnUnload(EventArgs e)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GL.DeleteTextures(1, ref TextureObject);
 | 
					 | 
				
			||||||
            GL.DeleteProgram(ProgramObject); // implies deleting the previously flagged ShaderObjects
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region OnResize
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Respond to resize events here.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="e">Contains information on the new GameWindow size.</param>
 | 
					 | 
				
			||||||
        /// <remarks>There is no need to call the base implementation.</remarks>
 | 
					 | 
				
			||||||
        protected override void OnResize(OpenTK.Platform.ResizeEventArgs e)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Magic numbers so the fractal almost fits inside the window.
 | 
					 | 
				
			||||||
            // If changing this, also change the -1.6f offset in the fragment shader accordingly.
 | 
					 | 
				
			||||||
            UniformScaleFactorX = Width / (UniformOffsetX * 2f);
 | 
					 | 
				
			||||||
            UniformScaleFactorY = Height / (UniformOffsetY * 2f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.Viewport(0, 0, Width, Height);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.MatrixMode(MatrixMode.Projection);
 | 
					 | 
				
			||||||
            GL.LoadIdentity();
 | 
					 | 
				
			||||||
            GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 1.0); // 2D setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.MatrixMode(MatrixMode.Modelview);
 | 
					 | 
				
			||||||
            GL.LoadIdentity();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region OnUpdateFrame
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Add your game logic here.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="e">Contains timing information.</param>
 | 
					 | 
				
			||||||
        /// <remarks>There is no need to call the base implementation.</remarks>
 | 
					 | 
				
			||||||
        public override void OnUpdateFrame(UpdateFrameEventArgs e)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            base.OnUpdateFrame(e);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (Keyboard[OpenTK.Input.Key.Escape])
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                this.Exit();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region OnRenderFrame
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Add your game rendering code here.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="e">Contains timing information.</param>
 | 
					 | 
				
			||||||
        /// <remarks>There is no need to call the base implementation.</remarks>
 | 
					 | 
				
			||||||
        public override void OnRenderFrame(RenderFrameEventArgs e)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            //this.Title = "FPS: " + 1 / e.Time;
 | 
					 | 
				
			||||||
            GL.Clear(ClearBufferMask.ColorBufferBit);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // First, render the next frame of the Julia fractal.
 | 
					 | 
				
			||||||
            GL.UseProgram(ProgramObject);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // advance the animation by elapsed time, scaling is solely used to make the anim more interesting
 | 
					 | 
				
			||||||
            AnimOffsetX += (float)(e.Time * AnimSpeedX);
 | 
					 | 
				
			||||||
            AnimOffsetY += (float)(e.Time * AnimSpeedY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // pass uniforms into the fragment shader
 | 
					 | 
				
			||||||
            // first the texture
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "COLORTABLE"), TextureObject);
 | 
					 | 
				
			||||||
            // the rest are floats
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "CETX"), (float)(Math.Cos(AnimOffsetX) * AnimCosinusPercent));
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "CETY"), (float)(Math.Cos(AnimOffsetY) * AnimCosinusPercent));
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "SCALINGX"), UniformScaleFactorX);
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "SCALINGY"), UniformScaleFactorY);
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "OFFSETX"), UniformOffsetX);
 | 
					 | 
				
			||||||
            GL.Uniform1(GL.GetUniformLocation(ProgramObject, "OFFSETY"), UniformOffsetY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Fullscreen quad. Using immediate mode, since this app is fragment shader limited anyways.
 | 
					 | 
				
			||||||
            GL.Begin(BeginMode.Quads);
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                GL.Vertex2(-1.0f, -1.0f);
 | 
					 | 
				
			||||||
                GL.Vertex2(1.0f, -1.0f);
 | 
					 | 
				
			||||||
                GL.Vertex2(1.0f, 1.0f);
 | 
					 | 
				
			||||||
                GL.Vertex2(-1.0f, 1.0f);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            GL.End();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Then, render the fps:
 | 
					 | 
				
			||||||
            GL.UseProgram(0);
 | 
					 | 
				
			||||||
            printer.Begin();
 | 
					 | 
				
			||||||
            GL.Color3(Color.PaleGoldenrod);
 | 
					 | 
				
			||||||
            printer.Draw((1 / e.Time).ToString("F2"), font);
 | 
					 | 
				
			||||||
            printer.End();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SwapBuffers();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region public static void Main()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Entry point of this example.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        [STAThread]
 | 
					 | 
				
			||||||
        public static void Main()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            using (T11_Julia_Set example = new T11_Julia_Set())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Utilities.SetWindowTitle(example);
 | 
					 | 
				
			||||||
                example.Run(30.0);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in a new issue