【问题标题】:SharpGL & Kinect - Rendering ColorImageFrame Bitmap to OpenGL TextureSharpGL 和 Kinect - 将 ColorImageFrame 位图渲染到 OpenGL 纹理
【发布时间】:2013-05-13 07:36:58
【问题描述】:

我想从 Kinect 的视频输入中绘制一个带有纹理的简单 2D 四边形,但我的代码无法正常工作。

这是我的 ColorFrameReady 事件:

    void Sensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
    {
        ColorImageFrame cif = e.OpenColorImageFrame();

        if (cif != null)
        {
            middleBitmapSource = cif.ToBitmapSource();
            cif.Dispose();
        }
    }

这是我的 OpenGL 绘制方法:

    private void OpenGLControl_OpenGLDraw(object sender, OpenGLEventArgs args)
    {
        // Get the OpenGL instance being pushed to us.
        gl = args.OpenGL;

        // Clear the colour and depth buffers.
        gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

        // Enable textures
        gl.Enable(OpenGL.GL_TEXTURE_2D);

        // Reset the modelview matrix.
        gl.LoadIdentity();

        // Load textures
        if (middleBitmapSource != null)
        {
            middleBitmap = getBitmap(middleBitmapSource, quadMiddleWidth, quadMiddleHeight);
            //middleBitmap = new System.Drawing.Bitmap("C:\\Users\\Bobble\\Pictures\\Crate.bmp"); // When I use this texture, it works fine
            gl.GenTextures(1, textures);
            gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[0]);
            gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, 3, middleBitmap.Width, middleBitmap.Height, 0, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE,
                middleBitmap.LockBits(new System.Drawing.Rectangle(0, 0, middleBitmap.Width, middleBitmap.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb).Scan0);

            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR);
            gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
        }

        // Move back a bit
        gl.Translate(0.0f, 0.0f, -25.0f);

        gl.BindTexture(OpenGL.GL_TEXTURE_2D, textures[0]);

        // Draw a quad.
        gl.Begin(OpenGL.GL_QUADS);

            // Draw centre quad
            gl.TexCoord(0.0f, 0.0f); gl.Vertex(-(quadMiddleWidth / 2), quadMiddleHeight / 2, quadDepthFar);
            gl.TexCoord(0.0f, 1.0f); gl.Vertex(quadMiddleWidth / 2, quadMiddleHeight / 2, quadDepthFar);
            gl.TexCoord(1.0f, 1.0f); gl.Vertex(quadMiddleWidth / 2, -(quadMiddleHeight / 2), quadDepthFar);
            gl.TexCoord(1.0f, 0.0f); gl.Vertex(-(quadMiddleWidth / 2), -(quadMiddleHeight / 2), quadDepthFar);

        gl.End();

        gl.Flush();
    }

这是一个帮助方法,它将 BitmapSource 转换为给定大小的位图:

    private System.Drawing.Bitmap getBitmap(BitmapSource bitmapSource, double rectangleWidth, double rectangleHeight)
    {
        double newWidthRatio = rectangleWidth / (double)bitmapSource.PixelWidth;
        double newHeightRatio = ((rectangleWidth * bitmapSource.PixelHeight) / (double)bitmapSource.PixelWidth) / (double)bitmapSource.PixelHeight;

        BitmapSource transformedBitmapSource = new TransformedBitmap(bitmapSource, new ScaleTransform(newWidthRatio, newHeightRatio));

        int width = transformedBitmapSource.PixelWidth;
        int height = transformedBitmapSource.PixelHeight;
        //int stride = width * ((transformedBitmapSource.Format.BitsPerPixel + 7) / 8);
        int stride = ((width * transformedBitmapSource.Format.BitsPerPixel + 31) & ~31) / 8; // See: http://stackoverflow.com/questions/1983781/why-does-bitmapsource-create-throw-an-argumentexception/1983886#1983886

        byte[] bits = new byte[height * stride];

        transformedBitmapSource.CopyPixels(bits, stride, 0);

        unsafe
        {
            fixed (byte* pBits = bits)
            {
                IntPtr ptr = new IntPtr(pBits);

                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
                    width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, ptr);

                return bitmap;
            }
        }
    }

四边形渲染,但它只是白色,上面没有纹理。

【问题讨论】:

    标签: c# opengl textures kinect


    【解决方案1】:

    这原来是 SharpGL 的问题 - 我正在使用的 OpenGL 库。

    http://sharpgl.codeplex.com/discussions/348278 - 关于 CodePlex 的讨论导致 SharpGL 开发人员解决了该问题。

    【讨论】:

    • ToBitmapSource 是 SDK 的一部分还是您的功能?我是 kinect SDK 的新手,找不到它。
    • 这是一个非常古老的项目,所以请多多包涵。看起来 ToBitmapSource 函数是 SDK 的一部分,但我在文档中看不到它。请通过 bobble14988@gmail.com 给我留言,我会看看能不能帮你找出一些代码。
    • 谢谢 bobble,后来我在这里找到了一些东西:stackoverflow.com/questions/10848190/…
    【解决方案2】:

    我也有一张白色的图片,但是当我将函数 TexImage2D 的输入更改为使用 2 的倍数的宽度和高度时,它起作用了。根据文档:

    纹理图像的宽度(必须是 2 的幂,例如 64)。

    纹理图像的高度(必须是 2 的幂,例如 32)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2012-06-03
      • 2014-07-22
      • 2013-10-05
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      相关资源
      最近更新 更多