public Bitmap ReadFramebufferTest()
        {
            Size bmpSize = new Size(Width, Height);;

            if (GL.IsFramebuffer(frameBuffer[isCore, 1]))
            {
                bmpSize = _videoSize;
            }
            if ((bmpSize.Height <= 0) || (bmpSize.Width <= 0))
            {
                return(null);
            }
            Bitmap testBmp = new Bitmap(bmpSize.Width, bmpSize.Height);
            //Graphics gr = Graphics.FromImage(testBmp);
            //gr.Clear(Color.Red);
            var testData = testBmp.LockBits(
                new Rectangle(0, 0, testBmp.Width, testBmp.Height),
                ImageLockMode.WriteOnly,
                System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            RenderControl.GLError("A");

            GL.ReadPixels(0, 0, testBmp.Width, testBmp.Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, testData.Scan0);
            RenderControl.GLInfo("B");
            // SetRenderTarget(RenderControl.RenderTarget.ScreenDirect);
            // GL.DrawPixels(Width, Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, testData.Scan0);
            testBmp.UnlockBits(testData);
            // testBmp.Dispose();
            return(testBmp);
        }
        /// <summary>
        /// Recursive rendering function
        /// </summary>
        /// <param name="node">Current node</param>
        /// <param name="visibleMeshesByNode"> </param>
        /// <param name="flags">Rendering flags</param>
        /// <param name="animated">Play animation?</param>
        /// <returns>whether there is any need to do a second render pass with alpha blending enabled</returns>
        protected bool RecursiveRender(Node node,
                                       Dictionary <Node, List <Mesh> > visibleMeshesByNode,
                                       RenderFlags flags, bool animated, int currDispList)
        {
            var needAlpha = false;

            Matrix4 m;

            if (animated)
            {
                Owner.SceneAnimator.GetLocalTransform(node, out m);
            }
            else
            {
                m = AssimpToOpenTk.FromMatrix(node.Transform);
            }
            // TODO for some reason, all OpenTk matrices need a ^T - we should clarify our conventions somewhere
            RenderControl.GLError("A11");
            m.Transpose();
            PushWorld(ref m);
            RenderControl.GLError("B11");

            if ((node.HasMeshes) && (currDispList == GetDispList(node.Name)))
            {
                needAlpha = DrawOpaqueMeshes(node, visibleMeshesByNode, flags, animated);
            }

            for (var i = 0; i < node.ChildCount; i++)
            {
                needAlpha = RecursiveRender(node.Children[i], visibleMeshesByNode, flags, animated, currDispList) || needAlpha;
            }
            RenderControl.GLError("C11");
            PopWorld();
            return(needAlpha);
        }
        /// <summary>
        /// Switches between all available targets.
        /// </summary>
        /// <returns></returns>
        public void SetRenderTarget(RenderTarget rt)
        {
            RenderControl.GLError("BeforeTargetChange");
            switch (rt)
            {
            case RenderTarget.ScreenDirect:
                this.MakeCurrent();
                //   GL.Viewport(Left, Top, Width, Height);
                isCore = 0;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
                break;

            case RenderTarget.ScreenCompat:
                this.MakeCurrent();
                //   GL.Viewport(Left, Top, Width, Height);
                isCore = 0;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 0]);
                break;

            case RenderTarget.ScreenCore:
                glCore.MakeCurrent();
                //    GL.Viewport(Left, Top, Width, Height);
                isCore = 1;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 0]);
                break;

            case RenderTarget.VideoCompat:
                this.MakeCurrent();
                GL.Viewport(0, 0, _videoSize.Width, _videoSize.Height);
                isCore = 0;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 1]);
                break;

            case RenderTarget.VideoCore:
                glCore.MakeCurrent();
                GL.Viewport(0, 0, _videoSize.Width, _videoSize.Height);
                isCore = 1;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 1]);
                break;

            case RenderTarget.VideoSSCompat:
                this.MakeCurrent();
                GL.Viewport(0, 0, _videoSize.Width, _videoSize.Height);
                isCore = 0;
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 2]);
                break;

            case RenderTarget.VideoSSCore:
                glCore.MakeCurrent();
                isCore = 1;
                GL.Viewport(0, 0, _videoSize.Width, _videoSize.Height);
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer[isCore, 2]);
                break;
            }
            RenderControl.GLError("AfterTargetChange");
        }
Beispiel #4
0
        /// <summary>
        /// Draws the mesh geometry given the current pipeline state.
        ///
        /// The pipeline is restored afterwards.
        /// </summary>
        /// <param name="flags">Rendering mode</param>
        public void Render(RenderFlags flags)
        {
            Debug.Assert(_vbo.VertexBufferId != 0);
            Debug.Assert(_vbo.ElementBufferId != 0);
            GL.BindVertexArray(_vbo.VertexArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo.VertexBufferId);

            // primitives
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _vbo.ElementBufferId);
            GL.DrawElements(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, _vbo.NumIndices,
                            _vbo.Is32BitIndices ? DrawElementsType.UnsignedInt : DrawElementsType.UnsignedShort, IntPtr.Zero);
            RenderControl.GLError("EndModernRender");
        }
Beispiel #5
0
        /// <summary>
        /// <see cref="ISceneRenderer.Render"/>
        /// </summary>
        /// </summary>
        public void Render(ICameraController cam, Dictionary <Node, List <Mesh> > visibleMeshesByNode,
                           bool visibleSetChanged,
                           bool texturesChanged,
                           RenderFlags flags,
                           Renderer renderer)
        {
            RenderControl.GLError("ModernRenderStart");

            GL.Enable(EnableCap.DepthTest);
            GL.FrontFace(FrontFaceDirection.Ccw);
            if (flags.HasFlag(RenderFlags.Wireframe))
            {
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            }

            var view = cam == null?Matrix4.LookAt(0, 10, 5, 0, 0, 0, 0, 1, 0) : cam.GetView();

            var tmp = InitposeMax.X - InitposeMin.X;

            tmp = Math.Max(InitposeMax.Y - InitposeMin.Y, tmp);
            tmp = Math.Max(InitposeMax.Z - InitposeMin.Z, tmp);
            int   logScale = (int)Math.Truncate(Math.Log10(tmp * 10 / 50)); //  Up to 50units max size = 50m: keep scale (for smaller scenes).
            float scale    = 1;

            for (int i = 0; i < logScale; i++)
            {
                scale = scale / 10;
            }
            Owner.Scale = scale;
            Matrix4 world = Matrix4.Identity;//want to keep unity in our world


            // set a proper perspective matrix for rendering
            int[] CurrentViewport = new int[4];
            GL.GetInteger(GetPName.Viewport, CurrentViewport);
            var     aspectRatio = (float)CurrentViewport[2] / CurrentViewport[3];
            Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(cam.GetFOV(), aspectRatio, renderer.zNear, renderer.zFar);

            Owner.MaterialMapper.SetMatrices(world, view, perspective);
            PushWorld(ref world);
            Owner.MaterialMapper.BeginScene(renderer, flags.HasFlag(RenderFlags.UseSceneLights)); //here we switch on lights

            // If textures changed, we may need to upload some of them to VRAM.
            if (texturesChanged)
            {
                UploadTextures();
            }
            var animated = Owner.SceneAnimator.IsAnimationActive;

            int currDispList = 0;
            int count        = 1;

            switch (cam.GetScenePartMode())
            {
            case ScenePartMode.Background: currDispList = 0; break;

            case ScenePartMode.Foreground: currDispList = 2; break;

            case ScenePartMode.Others: currDispList = 1; break;

            case ScenePartMode.GreenScreen: currDispList = 3; break;

            case ScenePartMode.All: currDispList = 0; count = 4; break;

            default: break;    //at other modes we do not render anything
            }

            for (int countDispList = 0; countDispList < count; countDispList++)
            {
                var needAlpha     = RecursiveRender(Owner.Raw.RootNode, visibleMeshesByNode, flags, animated, currDispList);
                var needAlphaAnim = RecursiveRender(Owner.Raw.RootNode, visibleMeshesByNode, flags, animated, currDispList + 4);
                if (flags.HasFlag(RenderFlags.ShowSkeleton) || flags.HasFlag(RenderFlags.ShowNormals))
                {
                    //RecursiveRenderNoScale(Owner.Raw.RootNode, visibleMeshesByNode, flags, 1.0f / tmp, animated);
                }
                if (needAlpha)
                {
                    // handle semi-transparent geometry
                    RecursiveRenderWithAlpha(Owner.Raw.RootNode, visibleMeshesByNode, flags, animated, currDispList);
                }
                if (needAlphaAnim)
                {
                    // handle semi-transparent geometry
                    RecursiveRenderWithAlpha(Owner.Raw.RootNode, visibleMeshesByNode, flags, animated, currDispList + 4);
                }
                currDispList++;

                /* RenderFlags application:
                 * Wireframe = 0x1, - Scene renderer,OK
                 * Shaded = 0x2, - MaterialMapper.ApplyMaterial, OK
                 * ShowBoundingBoxes = 0x4,
                 * ShowNormals = 0x8, - Scene renderer, unused in GL4
                 * ShowSkeleton = 0x10,  - Scene renderer, unused in GL4
                 * Textured = 0x20, - MaterialMapper.ApplyMaterial, OK
                 * ShowGhosts = 0x40, unused, always ON, InternDrawMesh applies own showGhost to MaterialMapper.Apply(Ghost)Material,
                 * UseSceneLights = 0x80, - MaterialMapper.BeginScene, OK
                 */
            }
            PopWorld();
            // always switch back to FILL
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            GL.Disable(EnableCap.DepthTest);
            RenderControl.GLError("SceneRendererModernGLEnd");
        }
Beispiel #6
0
        /// <summary>
        /// Upload the texture to video RAM.
        ///
        /// This requires that State == TextureState.WinFormsImageCreated, i.e. the
        /// RAM texture image must be ready for use and the Gl object may not have
        /// been created yet.
        ///
        /// Must be called on a thread that is allowed to use Gl APIs.
        /// </summary>
        public void Upload()
        {
            if (State == TextureState.GlTextureCreated)
            {
                return;
            }
            Debug.Assert(State == TextureState.WinFormsImageCreated);
            // this may be required if ReleaseUpload() has been called before
            if (_gl != 0)
            {
                GL.DeleteTexture(_gl);
                _gl = 0;
            }

            lock (_lock) { // this is a long CS, but at this time we don't expect concurrent action, i.e. updating texture by loader.
                // http://www.opentk.com/node/259
                Bitmap textureBitmap       = null;
                var    shouldDisposeBitmap = false;

                // in order to LockBits(), we need to create a Bitmap. In case the given Image
                // *is* already a Bitmap however, we can directly re-use it.
                try {
                    if (_image is Bitmap)
                    {
                        textureBitmap = (Bitmap)_image;
                    }
                    else
                    {
                        textureBitmap       = new Bitmap(_image);
                        shouldDisposeBitmap = true;
                    }
                    RenderControl.GLError("StartUploadTex");
                    // apply texture resolution bias? (i.e. low quality textures)
                    if (GraphicsSettings.Default.TexQualityBias > 0)
                    {
                        var b = ApplyResolutionBias(textureBitmap, GraphicsSettings.Default.TexQualityBias);
                        if (shouldDisposeBitmap)
                        {
                            textureBitmap.Dispose();
                        }
                        textureBitmap       = b;
                        shouldDisposeBitmap = true;
                    }
                    var textureData = textureBitmap.LockBits(
                        new Rectangle(0, 0, textureBitmap.Width, textureBitmap.Height),
                        ImageLockMode.ReadOnly,
                        System.Drawing.Imaging.PixelFormat.Format32bppArgb
                        );

                    // determine alpha pixels if this has not been done before
                    if (_alphaState == AlphaState.NotKnownYet)
                    {
                        _alphaState = LookForAlphaBits(textureData) ? AlphaState.HasAlpha : AlphaState.Opaque;
                    }
                    int tex;
                    GL.GenTextures(1, out tex);
                    GL.Arb.ActiveTexture(TextureUnit.Texture0);
                    GL.BindTexture(TextureTarget.Texture2D, tex);

                    // upload
                    {
                        RenderControl.GLError("BeforeUploadTex");
                        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8,
                                      textureBitmap.Width,
                                      textureBitmap.Height,
                                      0,
                                      PixelFormat.Bgra,
                                      PixelType.UnsignedByte,
                                      textureData.Scan0);
                        RenderControl.GLError("EndUploadTex");
                    }
                    textureBitmap.UnlockBits(textureData);

                    // set final state only if the Gl texture object has been filled successfully
                    if (GL.GetError() == ErrorCode.NoError)
                    {
                        _gl   = tex;
                        State = TextureState.GlTextureCreated;
                    }
                    ConfigureFilters(); //Contains Generate mipmaps, texture must be uploaded and GlTextureCreated;
                }
                finally {
                    if (shouldDisposeBitmap)
                    {
                        textureBitmap.Dispose();
                    }
                }
            }

            /* check upload is OK
             *          {
             *              GL.BindTexture(TextureTarget.Texture2D, _gl);
             *              Bitmap xtestBmp = new Bitmap(1080, 1080);
             *              var testData = xtestBmp.LockBits(new Rectangle(0, 0, xtestBmp.Width, xtestBmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
             *              GL.GetTexImage(TextureTarget.Texture2D, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, testData.Scan0);
             *              xtestBmp.UnlockBits(testData);
             *              xtestBmp.Dispose();
             *          }  */
        }
Beispiel #7
0
        public override void ApplyMaterial(Mesh mesh, Material mat, bool textured, bool shaded, bool twoSided)
        {
            RenderControl.GLError("StartMaterialMapper");
            ShaderGen.GenFlags flags = 0;
            var hasAlpha             = false;
            var hasTexture           = false;

            // note: keep this up-to-date with the code in MaterialMapper.UploadTextures()
            for (int i = 0; i < Renderer.modernGLUsedTextureTypeCount; i++)
            {
                TextureType currTextureType = (TextureType)((int)TextureType.Diffuse + i);
                GL.ActiveTexture((TextureUnit)((int)TextureUnit.Texture0 + i));
                GL.BindTexture(TextureTarget.Texture2D, Renderer.modernGLTextureType[i]); //we use own texture always, even when textures off to supply preset values
                if (textured && mat.GetMaterialTextureCount(currTextureType) > 0)
                {
                    hasTexture = true;
                    //flags |= ShaderGen.GenFlags.Texture; flag not used, we always have some texture
                    TextureSlot tex;
                    mat.GetMaterialTexture(currTextureType, 0, out tex);
                    var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath);
                    hasAlpha = hasAlpha || gtex.HasAlpha == Texture.AlphaState.HasAlpha;
                    if (gtex.State == Texture.TextureState.GlTextureCreated)
                    {
                        gtex.BindGlTexture();
                    }
                }
            }
            GL.ActiveTexture(TextureUnit.Texture0);
            RenderControl.GLError("EndTextureSettings");
            if (shaded)
            {
                flags |= ShaderGen.GenFlags.Lighting;
            }
            var hasColors = mesh != null && mesh.HasVertexColors(0);

            if (hasColors)
            {
                flags |= ShaderGen.GenFlags.VertexColor;
            }
            if (_UseSceneLights)
            {
                flags |= ShaderGen.GenFlags.PhongSpecularShading;
            }
            if ((mat.IsTwoSided) || (twoSided))
            {
                flags |= ShaderGen.GenFlags.TwoSide;
            }
            Shader shader = _shaderGen.GenerateOrGetFromCache(flags, _LightCount > 0 ? _LightCount : 1);

            shader.BindIfNecessary();
            Matrix4 curView = Matrix4.CreateScale(_scene.Scale) * _View;

            shader.SetMat4("WorldViewProjection", _World * curView * _Perspective);
            Matrix4 cameraPos      = _View.ClearRotation();
            Matrix4 cameraRotation = _View.ClearTranslation();
            Matrix4 cam            = Matrix4.Identity;

            cam = cameraPos * cameraRotation;
            Vector3 cameraPosition = -cam.ExtractTranslation() / _scene.Scale;//does not work for orbitcontroller

            //            cameraPosition = new Vector3(200,100,-100); //1m = 100units and positive
            cameraPosition.Z = -cameraPosition.Z;
            shader.SetVec3("CameraPosition", -cameraPosition);
            shader.SetMat4("World", _World);
            shader.SetMat4("WorldView", _World * curView); //_world* curView keeps light source at "fixed" position during rotating of the model
            shader.SetFloat("SceneBrightness", _SceneBrightness);
            shader.SetFloat("Material.diffuse", 0);
            shader.SetFloat("Material.ambient", 1);
            shader.SetFloat("Material.specular", 2);
            shader.SetFloat("Material.emissive", 3);
            shader.SetFloat("Material.height", 4);
            shader.SetFloat("Material.normal", 5);
            shader.SetLights(_GLLights, _LightCount);
            RenderControl.GLError("UniformSettings");

            // note: keep semantics of hasAlpha consistent with IsAlphaMaterial()
            var alpha = 1.0f;

            if (mat.HasOpacity)
            {
                alpha = mat.Opacity;
                if (alpha < AlphaSuppressionThreshold) // suppress zero opacity, this is likely wrong input data
                {
                    alpha = 1.0f;
                }
            }
            var color = new Color4(.8f, .8f, .8f, 1.0f);

            if (mat.HasColorDiffuse)
            {
                color = AssimpToOpenTk.FromColor(mat.ColorDiffuse);
                if (color.A < AlphaSuppressionThreshold) // s.a.
                {
                    color.A = 1.0f;
                }
            }
            color.A *= alpha;
            hasAlpha = hasAlpha || color.A < 1.0f;

            if (shaded)
            {
                // if the material has a texture but the diffuse color texture is all black,
                // then heuristically assume that this is an import/export flaw and substitute
                // white.
                if (hasTexture && color.R < 1e-3f && color.G < 1e-3f && color.B < 1e-3f)
                {
                    color = Color4.White;
                }
                shader.SetCol4("MaterialDiffuse_Alpha", color);

                color = new Color4(0, 0, 0, 1.0f);
                if (mat.HasColorSpecular)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorSpecular);
                }
                shader.SetCol4("MaterialSpecular", color);

                color = new Color4(.2f, .2f, .2f, 1.0f);
                if (mat.HasColorAmbient)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorAmbient);
                }
                shader.SetCol4("MaterialAmbient", color);

                color = new Color4(0, 0, 0, 1.0f);
                if (mat.HasColorEmissive)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorEmissive);
                }
                shader.SetCol4("MaterialEmissive", color);

                float shininess = 1;
                float strength  = 1;
                if (mat.HasShininess)
                {
                    shininess = mat.Shininess;
                }
                // todo: I don't even remember how shininess strength was supposed to be handled in assimp .. Scales the specular color of the material.Not implemented here.
                if (mat.HasShininessStrength)
                {
                    strength = mat.ShininessStrength;
                }
                var exp = shininess;
                if (exp >= 128.0f) // 128 is the maximum exponent as per the Gl spec
                {
                    exp = 128.0f;
                }
                shader.SetFloat("MaterialShininess", exp);
                //Shininess may be at mat.ColorSpecular.a too..?? but in FBX is
            }
            else if (!hasColors)
            {
                shader.SetCol4("MaterialDiffuse_Alpha", color);
            }

            if (hasAlpha)
            {
                GL.Enable(EnableCap.Blend);
                GL.BlendFuncSeparate(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
                GL.DepthMask(false);
            }
            else
            {
                GL.DepthMask(true);
                GL.Disable(EnableCap.Blend);
            }
            RenderControl.GLError("EndMaterialMapper");
        }
Beispiel #8
0
 public override void Dispose()
 {
     _shaderGen.Dispose();
     GC.SuppressFinalize(this);
     RenderControl.GLError("MaterialNewDispose");
 }
Beispiel #9
0
        public override void BeginScene(Renderer renderer, bool useSceneLights = true)
        {
            _UseSceneLights = useSceneLights;
            if (useSceneLights)
            {
                var lightNodes = GenerateLightNodes();
                var Lights     = GenerateLights();
                _LightCount = LightCount();
                _GLLights   = new GLLight[_LightCount];
                for (var i = 0; i < _LightCount; i++)
                {
                    Node node = lightNodes[i];
                    if ((node != null) && ((node == _scene.ActiveLight) || (null == _scene.ActiveLight)))
                    {
                        var mat1 = Matrix4x4.Identity;
                        var cur  = node;
                        while (cur != null)
                        {
                            var trafo = cur.Transform;
                            trafo.Transpose();
                            mat1 = trafo * mat1;
                            cur  = cur.Parent;
                        }
                        mat1.Transpose();
                        var mat = renderer.LightRotation;
                        //here move position info into lights[]
                        _GLLights[i].lightType = (int)Lights[i].LightType;
                        Vector3 lposTemp = new Vector3(mat1.A4, mat1.B4, mat1.C4);
                        Vector3 ldirTemp = new Vector3(mat1.B1, -mat1.B2, mat1.B3); //partially a guess, needed verification

                        _GLLights[i].position  = lposTemp;
                        _GLLights[i].direction = -ldirTemp;

                        float baseBrightness = 0.01f;
                        float lightScale     = _GLLights[i].lightType == 1 ? baseBrightness : 1.0f;
                        _GLLights[i].ambient  = Colo3DToVector3(Lights[i].ColorAmbient) * lightScale;
                        _GLLights[i].specular = Colo3DToVector3(Lights[i].ColorSpecular) * lightScale * 2;
                        _GLLights[i].diffuse  = Colo3DToVector3(Lights[i].ColorDiffuse) * lightScale;

                        _GLLights[i].constant    = Lights[i].AttenuationConstant;
                        _GLLights[i].linear      = Lights[i].AttenuationLinear * _scene.Scale;
                        _GLLights[i].quadratic   = Lights[i].AttenuationQuadratic * _scene.Scale * _scene.Scale;
                        _GLLights[i].outerCutOff = Lights[i].AngleOuterCone;
                        _GLLights[i].cutOff      = Lights[i].AngleInnerCone;
                    }
                }
                _SceneBrightness = (0.25f + 1.5f * GraphicsSettings.Default.OutputBrightness / 100.0f) * 1.5f;
                int neededUniformComponents = 21 * 4 * _LightCount + 15 * 4 * 4;//approximately
                if (neededUniformComponents > GL.GetInteger(GetPName.MaxFragmentUniformComponents))
                {
                    throw new Exception("Too many lights");
                }
            }
            else
            {
                _LightCount = 1;

                // light direction
                var dir = new Vector3(0, 0, 1);
                var mat = renderer.LightRotation;
                Vector3.TransformNormal(ref dir, ref mat, out dir);
                // light color
                var col = new Vector3(1, 1, 1);
                _SceneBrightness       = (0.00f + 5f * GraphicsSettings.Default.OutputBrightness / 100.0f);
                _GLLights              = new GLLight[_LightCount];
                _GLLights[0].lightType = 1;
                _GLLights[0].direction = dir;
                _GLLights[0].specular  = col;
                _GLLights[0].diffuse   = col;
            }
            RenderControl.GLError("BeginSceneEnd");
        }
        /// <summary>
        /// Sets up initiate values and buffers.
        /// </summary>
        /// <returns></returns>
        public void InitGlControl(int videoSizeX, int videoSizeY)
        {
            ErrorCode err = GL.GetError();//nVidia does not like something at real beginning

            RenderControl.GLError("InitializeGLControl");

            _videoSize.Width  = videoSizeX;
            _videoSize.Height = videoSizeY;
            GL.GenRenderbuffers(numBuffers, renderBuffer);
            GL.GenRenderbuffers(numBuffers, depthBuffer);
            GL.GenBuffers(numBuffers, pixelPackBuffer);
            GL.GenBuffers(numBuffers, pixelUnpackBuffer);

            GL.Enable(EnableCap.Multisample);

            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer[0]);
            GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, RenderbufferStorage.Rgba8, Width, Height);
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer[0]);
            GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, RenderbufferStorage.Depth24Stencil8, Width, Height);

            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer[1]);
            GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, RenderbufferStorage.Rgba8, videoSizeX, videoSizeY);
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer[1]);
            GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, samples, RenderbufferStorage.Depth24Stencil8, videoSizeX, videoSizeY);

            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderBuffer[2]);
            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Rgba8, videoSizeX, videoSizeY);
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthBuffer[2]);
            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, videoSizeX, videoSizeY);

            this.MakeCurrent();
            VSync  = false;
            isCore = 0;
            int[] frameBufferCompat = new int[numBuffers];
            GL.GenFramebuffers(numBuffers, frameBufferCompat);
            frameBuffer[isCore, 0] = frameBufferCompat[0];
            frameBuffer[isCore, 1] = frameBufferCompat[1];
            frameBuffer[isCore, 2] = frameBufferCompat[2];
            BindBuffers();
            GL.BindBuffer(BufferTarget.PixelPackBuffer, pixelPackBuffer[0]);
            GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)(Width * Height * bytePerPixel), (IntPtr)0, BufferUsageHint.DynamicCopy);
            GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pixelUnpackBuffer[0]);
            GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)(Width * Height * bytePerPixel), (IntPtr)0, BufferUsageHint.DynamicCopy);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);

            glCore.MakeCurrent();
            glCore.VSync = false;
            isCore       = 1;
            int[] frameBufferCore = new int[numBuffers];
            GL.GenFramebuffers(numBuffers, frameBufferCore);
            frameBuffer[isCore, 0] = frameBufferCore[0];
            frameBuffer[isCore, 1] = frameBufferCore[1];
            frameBuffer[isCore, 2] = frameBufferCore[2];
            BindBuffers();
            GL.BindBuffer(BufferTarget.PixelPackBuffer, pixelPackBuffer[1]);
            GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)(videoSizeX * videoSizeY * bytePerPixel), (IntPtr)0, BufferUsageHint.DynamicRead);
            GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pixelUnpackBuffer[1]);
            GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)(videoSizeX * videoSizeY * bytePerPixel), (IntPtr)0, BufferUsageHint.DynamicDraw);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
            initialized = true;
            RenderControl.GLError("AfterInit");
        }