如何摆脱奇怪的OpenTK渲染?

时间:2015-04-24 17:55:20

标签: c# opengl graphics opentk

我完全清楚我可以在OpenTK中加载纹理。但是当我试图仅使用点渲染图片时,当ClientSize.Width完全等于正在渲染的图片的宽度时,它会显示非常奇怪的线条。像这样:

Weird

如果我调整大小(放大)窗口线的ClientSize.Width变得有点正常,并且它们出现的实际原因(它们覆盖了无法渲染的区域):

Not weird

无论我打开的图片如何,这似乎都会发生。有人可以解释为什么第一张图片中有线条?

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace Miracle
{
    class Program
    {
        public static void Main()
        {
            using (Window w = new Window())
                w.Run(30);
        }
    }

    class Window : GameWindow
    {
        private Color[,] pixels;
        private int width, height;
        private bool blink = true;
        private int blinkcounter;

        public Window() : base(1337, 666, GraphicsMode.Default, "Miracle", GameWindowFlags.Default) { }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Bitmap pic = new Bitmap("sample.png");
            width = pic.Width;
            height = pic.Height;
            ClientSize = new Size(width, height);
            pixels = new Color[width, height];

            for (int x = 0; x < width; x++)
                for (int y = 0; y < height; y++)
                    pixels[x, y] = pic.GetPixel(x, y);

            GL.ClearColor(Color.FromArgb(0, 255, 0));
            GL.Ortho(0, width, height, 0, -1, 1);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            Title = ClientSize.Width + "x" + ClientSize.Height + (ClientSize.Width == width && ClientSize.Height == height ? " (original)" : "");
            GL.Viewport(ClientSize);
        }

        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);
            if (blinkcounter == 6)
            {
                GL.ClearColor(blink ? Color.FromArgb(255, 0, 0) : Color.FromArgb(0, 255, 0));
                blink = !blink;
                blinkcounter = 0;
            }
            blinkcounter++;
        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
            GL.Clear(ClearBufferMask.ColorBufferBit);
            GL.MatrixMode(MatrixMode.Projection);
            GL.Begin(PrimitiveType.Points);

            for (int x = 0; x < width; x++)
                for (int y = 0; y < height; y++)
                {
                    GL.Color4(pixels[x, y]);
                    GL.Vertex2(x, y);
                }

            GL.End();
            SwapBuffers();
        }
    }
}

1 个答案:

答案 0 :(得分:2)

我将描述您的问题的解决方案以及我认为您解决问题的原因。

首先,我认为你为什么会遇到这个问题: 点的光栅化是奇怪的并且依赖于硬件。此问题看起来是点的光栅化阶段中浮点精度的误差。投影点位于2个像素之间选择的边界上,由于FP的限制,它选择了错误的点。

解决方案: 不建议使用点栅格化图像。那不是光栅化的用途。相反,栅格化全屏四边形,为四边形的每个顶点提供纹理坐标,并在片段着色器中使用插值纹理坐标从存储要渲染的图像的纹理中获取。这避免了您使用GL_POINTS时遇到的问题,因为它确保每个像素都被绘制一次。