Exemplo n.º 1
0
        private RenderTarget CreateRenderTarget(Vector2i size, RenderTargetColorFormat colorFormat,
                                                TextureSampleParameters?sampleParameters = null, string name = null)
        {
            // Generate color attachment texture.
            var texture = new OGLHandle(GL.GenTexture());

            GL.BindTexture(TextureTarget.Texture2D, texture.Handle);

            _applySampleParameters(sampleParameters);

            var internalFormat = colorFormat switch
            {
                RenderTargetColorFormat.Rgba8 => PixelInternalFormat.Rgba8,
                RenderTargetColorFormat.Rgba16F => PixelInternalFormat.Rgba16f,
                RenderTargetColorFormat.Rgba8Srgb => PixelInternalFormat.Srgb8Alpha8,
                RenderTargetColorFormat.R11FG11FB10F => PixelInternalFormat.R11fG11fB10f,
                _ => throw new ArgumentOutOfRangeException(nameof(colorFormat), colorFormat, null)
            };

            var(width, height) = size;
            GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, width, height, 0, PixelFormat.Red,
                          PixelType.Byte, IntPtr.Zero);

            // Generate FBO.
            var fbo = new OGLHandle(GL.GenFramebuffer());

            // Cache currently bound framebuffers
            // so if somebody creates a framebuffer while drawing it won't ruin everything.
            var boundDrawBuffer = GL.GetInteger(GetPName.DrawFramebufferBinding);
            var boundReadBuffer = GL.GetInteger(GetPName.ReadFramebufferBinding);

            // Bind color attachment to FBO.
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo.Handle);

            GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, texture.Handle,
                                  0);

            // This should always pass but OpenGL makes it easy to check for once so let's.
            var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);

            DebugTools.Assert(status == FramebufferErrorCode.FramebufferComplete,
                              $"new framebuffer has bad status {status}");

            // Re-bind previous framebuffers.
            GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, boundDrawBuffer);
            GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, boundReadBuffer);

            var textureObject = _genTexture(texture, size, name);
            var handle        = AllocRid();
            var renderTarget  = new RenderTarget(size, textureObject, fbo, this, handle);

            _renderTargets.Add(handle, renderTarget);
            return(renderTarget);
        }
        public Texture LoadTextureFromImage <T>(Image <T> image, string name = null) where T : struct, IPixel <T>
        {
            DebugTools.Assert(_mainThread == Thread.CurrentThread);

            if (typeof(T) != typeof(Rgba32))
            {
                throw new NotImplementedException("Cannot load images other than Rgba32");
            }

            var texture = new OGLHandle(GL.GenTexture());

            GL.BindTexture(TextureTarget.Texture2D, texture.Handle);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                            (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                            (int)TextureMagFilter.Nearest);

            var span = ((Image <Rgba32>)(object) image).GetPixelSpan();

            unsafe
            {
                fixed(Rgba32 *ptr = &MemoryMarshal.GetReference(span))
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, image.Width, image.Height, 0,
                                  PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)ptr);
                }
            }

            if (name != null)
            {
                _objectLabelMaybe(ObjectLabelIdentifier.Texture, texture, name);
            }

            var loaded = new LoadedTexture
            {
                OpenGLObject = texture,
                Width        = image.Width,
                Height       = image.Height,
                Name         = name,
            };

            var id = ++_nextTextureId;

            _loadedTextures.Add(id, loaded);

            return(new OpenGLTexture(id, image.Width, image.Height));
        }
Exemplo n.º 3
0
        private ClydeTexture _genTexture(OGLHandle oglHandle, Vector2i size, string name)
        {
            if (name != null)
            {
                _objectLabelMaybe(ObjectLabelIdentifier.Texture, oglHandle, name);
            }

            var(width, height) = size;

            var loaded = new LoadedTexture
            {
                OpenGLObject = oglHandle,
                Width        = width,
                Height       = height,
                Name         = name
            };

            var id = ++_nextTextureId;

            _loadedTextures.Add(id, loaded);

            return(new ClydeTexture(id, size, this));
        }
Exemplo n.º 4
0
 private void _objectLabelMaybe(ObjectLabelIdentifier identifier, OGLHandle name, string label)
 {
     _objectLabelMaybe(identifier, name.Handle, label);
 }
Exemplo n.º 5
0
        private void _initOpenGL()
        {
            _loadExtensions();

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            var vendor   = GL.GetString(StringName.Vendor);
            var renderer = GL.GetString(StringName.Renderer);
            var version  = GL.GetString(StringName.Version);

            Logger.DebugS("ogl", "OpenGL Vendor: {0}", vendor);
            Logger.DebugS("ogl", "OpenGL Renderer: {0}", renderer);
            Logger.DebugS("ogl", "OpenGL Version: {0}", version);
            _loadVendorSettings(vendor, renderer, version);

#if DEBUG
            _hijackDebugCallback();
#endif

            _loadStockTextures();
            _loadStockShaders();

            var quadVertices = new[]
            {
                new Vertex2D(1, 0, 1, 1),
                new Vertex2D(0, 0, 0, 1),
                new Vertex2D(1, 1, 1, 0),
                new Vertex2D(0, 1, 0, 0),
            };

            QuadVBO = new Buffer <Vertex2D>(this, BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, quadVertices,
                                            "QuadVBO");

            QuadVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(QuadVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, QuadVAO, "QuadVAO");
            // Vertex Coords
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            // Texture Coords.
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);
            // Texture Array Index.
            GL.VertexAttribPointer(2, 1, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 4 * sizeof(float));
            GL.EnableVertexAttribArray(2);

            BatchVBO = new Buffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw,
                                  Vertex2D.SizeOf * BatchVertexData.Length, "BatchVBO");

            BatchVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(BatchVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchVAO, "BatchVAO");
            // Vertex Coords
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            // Texture Coords.
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);

            BatchEBO = new Buffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw,
                                  sizeof(ushort) * BatchIndexData.Length, "BatchEBO");

            ProjViewUBO = new Buffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw, "ProjViewUBO");
            unsafe
            {
                ProjViewUBO.Reallocate(sizeof(ProjViewMatrices));
            }

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, ProjViewBindingIndex, ProjViewUBO.Handle);

            UniformConstantsUBO = new Buffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw,
                                             nameof(UniformConstantsUBO));
            unsafe
            {
                UniformConstantsUBO.Reallocate(sizeof(UniformConstants));
            }

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, UniformConstantsBindingIndex,
                              UniformConstantsUBO.Handle);

            LightFBO     = new OGLHandle(GL.GenFramebuffer());
            LightTexture = new OGLHandle(GL.GenTexture());

            var(lightW, lightH) = _lightMapSize();
            GL.BindTexture(TextureTarget.Texture2D, LightTexture.Handle);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba16f, lightW, lightH, 0,
                          PixelFormat.Rgba, PixelType.Float, IntPtr.Zero);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)OpenTK.Graphics.OpenGL.TextureWrapMode.ClampToEdge);

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, LightFBO.Handle);

            _objectLabelMaybe(ObjectLabelIdentifier.Framebuffer, LightFBO, "LightFBO");
            _objectLabelMaybe(ObjectLabelIdentifier.Texture, LightTexture, "LightTexture");

            GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0,
                                  LightTexture.Handle, 0);

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

            _drawingSplash = true;

            _renderHandle = new RenderHandle(this);

            GL.Viewport(0, 0, _window.Width, _window.Height);

            Render(null);
        }
Exemplo n.º 6
0
 public bool Equals(OGLHandle other)
 {
     return(Handle == other.Handle);
 }
Exemplo n.º 7
0
        private void _initOpenGL()
        {
            _loadExtensions();

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            Logger.DebugS("ogl", "OpenGL Vendor: {0}", GL.GetString(StringName.Vendor));
            Logger.DebugS("ogl", "OpenGL Version: {0}", GL.GetString(StringName.Version));

#if DEBUG
            _hijackDebugCallback();
#endif

            Vertex2DProgram = _compileProgram(
                new ResourcePath("/Shaders/Internal/sprite.vert"),
                new ResourcePath("/Shaders/Internal/sprite.frag"));

            _objectLabelMaybe(ObjectLabelIdentifier.Program, Vertex2DProgram, "Vertex2DProgram");

            Vertex2DUniformModel      = GL.GetUniformLocation(Vertex2DProgram.Handle, "modelMatrix");
            Vertex2DUniformView       = GL.GetUniformLocation(Vertex2DProgram.Handle, "viewMatrix");
            Vertex2DUniformProjection = GL.GetUniformLocation(Vertex2DProgram.Handle, "projectionMatrix");
            Vertex2DUniformModUV      = GL.GetUniformLocation(Vertex2DProgram.Handle, "modifyUV");
            Vertex2DUniformModulate   = GL.GetUniformLocation(Vertex2DProgram.Handle, "modulate");

            var quadVertices = new[]
            {
                new Vertex2D(1, 0, 1, 1),
                new Vertex2D(0, 0, 0, 1),
                new Vertex2D(1, 1, 1, 0),
                new Vertex2D(0, 1, 0, 0),
            };

            QuadVBO = new OGLHandle(GL.GenBuffer());
            GL.BindBuffer(BufferTarget.ArrayBuffer, QuadVBO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.Buffer, QuadVBO, "QuadVBO");
            GL.BufferData(BufferTarget.ArrayBuffer, quadVertices.Length * Vertex2D.SizeOf, quadVertices, BufferUsageHint.StaticDraw);

            QuadVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(QuadVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, QuadVAO, "QuadVAO");
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);

            BatchVBO = new OGLHandle(GL.GenBuffer());
            GL.BindBuffer(BufferTarget.ArrayBuffer, BatchVBO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.Buffer, BatchVBO, "BatchVBO");
            GL.BufferData(BufferTarget.ArrayBuffer, Vertex2D.SizeOf * BatchVertexData.Length, IntPtr.Zero,
                          BufferUsageHint.DynamicDraw);

            BatchVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(BatchVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchVAO, "BatchVAO");
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);

            BatchEBO = new OGLHandle(GL.GenBuffer());
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, BatchEBO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.Buffer, BatchEBO, "BatchEBO");
            GL.BufferData(BufferTarget.ElementArrayBuffer, sizeof(ushort) * BatchIndexData.Length, IntPtr.Zero,
                          BufferUsageHint.DynamicDraw);

            _drawingSplash = true;
            Render(null);
        }
Exemplo n.º 8
0
        private void InitOpenGL()
        {
            _loadExtensions();

            _hijackDebugCallback();

            var vendor   = GL.GetString(StringName.Vendor);
            var renderer = GL.GetString(StringName.Renderer);
            var version  = GL.GetString(StringName.Version);

            Logger.DebugS("clyde.ogl", "OpenGL Vendor: {0}", vendor);
            Logger.DebugS("clyde.ogl", "OpenGL Renderer: {0}", renderer);
            Logger.DebugS("clyde.ogl", "OpenGL Version: {0}", version);
            _loadVendorSettings(vendor, renderer, version);

            var major = GL.GetInteger(GetPName.MajorVersion);
            var minor = GL.GetInteger(GetPName.MinorVersion);

            DebugInfo = new ClydeDebugInfo(new Version(major, minor), MinimumOpenGLVersion, renderer, vendor, version);

            GL.Enable(EnableCap.Blend);
            GL.Enable(EnableCap.FramebufferSrgb);
            GL.Enable(EnableCap.PrimitiveRestart);
            GL.PrimitiveRestartIndex(ushort.MaxValue);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            _loadStockTextures();
            _loadStockShaders();

            // Quad drawing.
            {
                var quadVertices = new[]
                {
                    new Vertex2D(1, 0, 1, 1),
                    new Vertex2D(0, 0, 0, 1),
                    new Vertex2D(1, 1, 1, 0),
                    new Vertex2D(0, 1, 0, 0),
                };

                QuadVBO = new Buffer <Vertex2D>(this, BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, quadVertices,
                                                nameof(QuadVBO));

                QuadVAO = new OGLHandle((uint)GL.GenVertexArray());
                GL.BindVertexArray(QuadVAO.Handle);
                _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, QuadVAO, "QuadVAO");
                // Vertex Coords
                GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
                GL.EnableVertexAttribArray(0);
                // Texture Coords.
                GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
                GL.EnableVertexAttribArray(1);
            }

            // Batch rendering
            {
                BatchVBO = new Buffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw,
                                      Vertex2D.SizeOf * BatchVertexData.Length, "BatchVBO");

                BatchVAO = new OGLHandle(GL.GenVertexArray());
                GL.BindVertexArray(BatchVAO.Handle);
                _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchVAO, "BatchVAO");
                // Vertex Coords
                GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
                GL.EnableVertexAttribArray(0);
                // Texture Coords.
                GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
                GL.EnableVertexAttribArray(1);

                BatchEBO = new Buffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw,
                                      sizeof(ushort) * BatchIndexData.Length, "BatchEBO");
            }

            ProjViewUBO = new Buffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw, "ProjViewUBO");
            unsafe
            {
                ProjViewUBO.Reallocate(sizeof(ProjViewMatrices));
            }

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, ProjViewBindingIndex, ProjViewUBO.ObjectHandle);

            UniformConstantsUBO = new Buffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw,
                                             nameof(UniformConstantsUBO));
            unsafe
            {
                UniformConstantsUBO.Reallocate(sizeof(UniformConstants));
            }

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, UniformConstantsBindingIndex,
                              UniformConstantsUBO.ObjectHandle);

            _regenerateLightRenderTarget();

            EntityPostRenderTarget = CreateRenderTarget(Vector2i.One * 4 * EyeManager.PIXELSPERMETER,
                                                        RenderTargetColorFormat.Rgba8Srgb, name: nameof(EntityPostRenderTarget));

            _drawingSplash = true;

            _renderHandle = new RenderHandle(this);

            GL.Viewport(0, 0, ScreenSize.X, ScreenSize.Y);

            // Quickly do a render with _drawingSplash = true so the screen isn't blank.
            Render();
        }
Exemplo n.º 9
0
        public Texture LoadTextureFromImage <T>(Image <T> image, string name     = null,
                                                TextureLoadParameters?loadParams = null) where T : unmanaged, IPixel <T>
        {
            DebugTools.Assert(_mainThread == Thread.CurrentThread);

            var actualParams = loadParams ?? TextureLoadParameters.Default;
            var pixelType    = typeof(T);

            var texture = new OGLHandle((uint)GL.GenTexture());

            GL.BindTexture(TextureTarget.Texture2D, texture.Handle);
            _applySampleParameters(actualParams.SampleParameters);

            PixelInternalFormat internalFormat;
            PixelFormat         pixelDataFormat;
            PixelType           pixelDataType;

            if (pixelType == typeof(Rgba32))
            {
                internalFormat  = actualParams.Srgb ? PixelInternalFormat.Srgb8Alpha8 : PixelInternalFormat.Rgba8;
                pixelDataFormat = PixelFormat.Rgba;
                pixelDataType   = PixelType.UnsignedByte;
            }
            else if (pixelType == typeof(Alpha8))
            {
                if (image.Width % 4 != 0 || image.Height % 4 != 0)
                {
                    throw new ArgumentException("Alpha8 images must have multiple of 4 sizes.");
                }
                internalFormat  = PixelInternalFormat.R8;
                pixelDataFormat = PixelFormat.Red;
                pixelDataType   = PixelType.UnsignedByte;

                // TODO: Does it make sense to default to 1 for RGB parameters?
                // It might make more sense to pass some options to change swizzling.
                var swizzle = new[] { (int)All.One, (int)All.One, (int)All.One, (int)All.Red };
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle);
            }
            else if (pixelType == typeof(Gray8) && !actualParams.Srgb)
            {
                // Can only use R8 for Gray8 if sRGB is OFF.
                // Because OpenGL doesn't provide non-sRGB single/dual channel image formats.
                // Vulkan when?
                if (image.Width % 4 != 0 || image.Height % 4 != 0)
                {
                    throw new ArgumentException("Gray8 non-sRGB images must have multiple of 4 sizes.");
                }

                internalFormat  = PixelInternalFormat.R8;
                pixelDataFormat = PixelFormat.Red;
                pixelDataType   = PixelType.UnsignedByte;

                var swizzle = new[] { (int)All.Red, (int)All.Red, (int)All.Red, (int)All.One };
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle);
            }
            else
            {
                throw new NotImplementedException($"Unable to handle pixel type '{pixelType.Name}'");
            }

            unsafe
            {
                var span = image.GetPixelSpan();
                fixed(T *ptr = span)
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, image.Width, image.Height, 0,
                                  pixelDataFormat, pixelDataType, (IntPtr)ptr);
                }
            }

            return(_genTexture(texture, (image.Width, image.Height), name));
        }
Exemplo n.º 10
0
        private void _initOpenGL()
        {
            _loadExtensions();

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            var vendor   = GL.GetString(StringName.Vendor);
            var renderer = GL.GetString(StringName.Renderer);
            var version  = GL.GetString(StringName.Version);

            Logger.DebugS("ogl", "OpenGL Vendor: {0}", vendor);
            Logger.DebugS("ogl", "OpenGL Renderer: {0}", renderer);
            Logger.DebugS("ogl", "OpenGL Version: {0}", version);
            _loadVendorSettings(vendor, renderer, version);

#if DEBUG
            _hijackDebugCallback();
#endif

            _loadStockTextures();

            Vertex2DProgram = _compileProgram(
                new ResourcePath("/Shaders/Internal/sprite.vert"),
                new ResourcePath("/Shaders/Internal/sprite.frag"),
                "Vertex2DProgram");

            Vertex2DProgram.BindBlock("projectionViewMatrices", ProjViewBindingIndex);

            Vertex2DArrayProgram = _compileProgram(
                new ResourcePath("/Shaders/Internal/sprite-arrayed.vert"),
                new ResourcePath("/Shaders/Internal/sprite-arrayed.frag"),
                "Vertex2DArrayProgram");

            Vertex2DArrayProgram.BindBlock("projectionViewMatrices", ProjViewBindingIndex);

            var quadVertices = new[]
            {
                new Vertex2D(1, 0, 1, 1, 1),
                new Vertex2D(0, 0, 0, 1, 1),
                new Vertex2D(1, 1, 1, 0, 1),
                new Vertex2D(0, 1, 0, 0, 1),
            };

            QuadVBO = new Buffer <Vertex2D>(this, BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, quadVertices,
                                            "QuadVBO");

            QuadVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(QuadVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, QuadVAO, "QuadVAO");
            // Vertex Coords
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            // Texture Coords.
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);
            // Texture Array Index.
            GL.VertexAttribPointer(2, 1, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 4 * sizeof(float));
            GL.EnableVertexAttribArray(2);

            BatchVBO = new Buffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw,
                                  Vertex2D.SizeOf * BatchVertexData.Length, "BatchVBO");

            BatchVAO = new OGLHandle(GL.GenVertexArray());
            GL.BindVertexArray(BatchVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchVAO, "BatchVAO");
            // Vertex Coords
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            // Texture Coords.
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);

            BatchEBO = new Buffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw,
                                  sizeof(ushort) * BatchIndexData.Length, "BatchEBO");

            BatchArrayedVAO = new OGLHandle(GL.GenVertexArray());
            BatchVBO.Use();
            BatchEBO.Use();
            GL.BindVertexArray(BatchArrayedVAO.Handle);
            _objectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchArrayedVAO, "BatchArrayedVAO");
            // Vertex Coords
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
            GL.EnableVertexAttribArray(0);
            // Texture Coords.
            GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
            GL.EnableVertexAttribArray(1);
            // Texture Array Index.
            GL.VertexAttribPointer(2, 1, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 4 * sizeof(float));
            GL.EnableVertexAttribArray(2);

            ProjViewUBO = new Buffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw, "ProjViewUBO");
            unsafe
            {
                ProjViewUBO.Reallocate(sizeof(ProjViewMatrices));
            }
            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, ProjViewBindingIndex, ProjViewUBO.Handle);

            _drawingSplash = true;

            _renderHandle = new RenderHandle(this);

            GL.Viewport(0, 0, _window.Width, _window.Height);

            Render(null);
        }
Exemplo n.º 11
0
        public Texture LoadTextureFromImage <T>(Image <T> image, string name     = null,
                                                TextureLoadParameters?loadParams = null) where T : unmanaged, IPixel <T>
        {
            DebugTools.Assert(_mainThread == Thread.CurrentThread);

            var pixelType = typeof(T);

            var texture = new OGLHandle(GL.GenTexture());

            GL.BindTexture(TextureTarget.Texture2D, texture.Handle);
            var actualParams = loadParams ?? TextureLoadParameters.Default;

            if (actualParams.SampleParameters.Filter)
            {
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                                (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                                (int)TextureMagFilter.Linear);
            }
            else
            {
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                                (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                                (int)TextureMagFilter.Nearest);
            }

            switch (actualParams.SampleParameters.WrapMode)
            {
            case TextureWrapMode.None:
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.ClampToEdge);
                break;

            case TextureWrapMode.Repeat:
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.Repeat);
                break;

            case TextureWrapMode.MirroredRepeat:
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.MirroredRepeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.MirroredRepeat);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            PixelInternalFormat internalFormat;
            PixelFormat         pixelDataFormat;
            PixelType           pixelDataType;

            if (pixelType == typeof(Rgba32))
            {
                internalFormat  = PixelInternalFormat.Rgba8;
                pixelDataFormat = PixelFormat.Rgba;
                pixelDataType   = PixelType.UnsignedByte;
            }
            else if (pixelType == typeof(Alpha8))
            {
                internalFormat  = PixelInternalFormat.R8;
                pixelDataFormat = PixelFormat.Red;
                pixelDataType   = PixelType.UnsignedByte;

                // TODO: Does it make sense to default to 1 for RGB parameters?
                // It might make more sense to pass some options to change swizzling.
                var swizzle = new[] { (int)All.One, (int)All.One, (int)All.One, (int)All.Red };
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle);
            }
            else
            {
                throw new NotImplementedException($"Unable to handle pixel type '{pixelType.Name}'");
            }

            unsafe
            {
                var span   = image.GetPixelSpan();
                var length = span.Length;
                var val1   = span[0];
                fixed(T *ptr = span)
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, image.Width, image.Height, 0,
                                  pixelDataFormat, pixelDataType, (IntPtr)ptr);
                }
            }

            if (name != null)
            {
                _objectLabelMaybe(ObjectLabelIdentifier.Texture, texture, name);
            }

            var loaded = new LoadedTexture
            {
                OpenGLObject = texture,
                Width        = image.Width,
                Height       = image.Height,
                Name         = name,
                Type         = LoadedTextureType.Texture2D
            };

            var id = ++_nextTextureId;

            _loadedTextures.Add(id, loaded);

            return(new OpenGLTexture(id, image.Width, image.Height));
        }
Exemplo n.º 12
0
        public TextureArray LoadArrayFromImages <T>(ICollection <Image <T> > images, string name = null,
                                                    TextureLoadParameters?loadParams             = null)
            where T : unmanaged, IPixel <T>
        {
            DebugTools.Assert(images.Count != 0);
            (int x, int y)? size = null;
            foreach (var image in images)
            {
                if (size == null)
                {
                    size = (image.Width, image.Height);
                }

                if (size.Value.x != image.Width || size.Value.y != image.Height)
                {
                    throw new ArgumentException("All images must be of the same dimensions.", nameof(images));
                }
            }

            var textureId = ++_nextTextureId;
            var texture   = new OGLHandle(GL.GenTexture());

            GL.BindTexture(TextureTarget.Texture2DArray, texture.Handle);
            if (name != null)
            {
                _objectLabelMaybe(ObjectLabelIdentifier.Texture, texture, name);
            }

            DebugTools.Assert(size.HasValue);
            var(width, height) = size.Value;
            GL.TexImage3D(TextureTarget.Texture2DArray, 0, PixelInternalFormat.Rgba8, width, height, images.Count, 0,
                          PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
            var actualParams = loadParams ?? TextureLoadParameters.Default;

            if (actualParams.SampleParameters.Filter)
            {
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter,
                                (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter,
                                (int)TextureMagFilter.Linear);
            }
            else
            {
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter,
                                (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter,
                                (int)TextureMagFilter.Nearest);
            }

            switch (actualParams.SampleParameters.WrapMode)
            {
            case TextureWrapMode.None:
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.ClampToEdge);
                break;

            case TextureWrapMode.Repeat:
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.Repeat);
                break;

            case TextureWrapMode.MirroredRepeat:
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS,
                                (int)OGLTextureWrapMode.MirroredRepeat);
                GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT,
                                (int)OGLTextureWrapMode.MirroredRepeat);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var index          = 0;
            var refTextureList = new List <OpenGLTexture>();

            foreach (var image in images)
            {
                var span = ((Image <Rgba32>)(object) image).GetPixelSpan();
                unsafe
                {
                    fixed(Rgba32 *ptr = span)
                    {
                        GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, 0, 0, index, width, height, 1,
                                         PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)ptr);
                    }
                }

                index += 1;
                refTextureList.Add(new OpenGLTexture(textureId, width, height, index));
            }

            var loaded = new LoadedTexture
            {
                OpenGLObject = texture,
                Width        = width,
                Height       = height,
                ArrayDepth   = images.Count,
                Name         = name,
                Type         = LoadedTextureType.Array2D
            };

            _loadedTextures.Add(textureId, loaded);
            return(new TextureArray(refTextureList.ToArray()));
        }