OpenGL C# (OpenTK) Load and Draw Image functions not working

Joel picture Joel · Jul 25, 2012 · Viewed 17.2k times · Source

I'm trying to load and display a texture on the screen, however am receiving a black box where it is meant to be shown.

The two main methods are "LoadTexture" and "Draw Image", I'm assuming the mistake is in one of them.

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

namespace FailRender
{
    public class FailRender: GameWindow
    {
        public FailRender() : base(800, 600, GraphicsMode.Default, "Hoard of Upgrades")
        {
            GL.ClearColor(0, 0.1f, 0.4f, 1);

            texture = LoadTexture("sand.jpg");
        }

        private int texture;

        public int LoadTexture(string file)
        {
            Bitmap bitmap = new Bitmap(file);

            int tex;
            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

            GL.GenTextures(1, out tex);
            GL.BindTexture(TextureTarget.Texture2D, tex);

            BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
                OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, data.Scan0);
            bitmap.UnlockBits(data);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            return tex;
        }

        public static void DrawImage(int image)
        {
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix();
            GL.LoadIdentity();

            GL.Ortho(0, 800, 0, 600, -1, 1);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.PushMatrix();
            GL.LoadIdentity();

            GL.Disable(EnableCap.Lighting);

            GL.Enable(EnableCap.Texture2D);

            GL.Color4(1, 0, 0, 1);

            GL.BindTexture(TextureTarget.Texture2D, image);

            GL.Begin(BeginMode.Quads);

            GL.TexCoord2(0, 0);
            GL.Vertex3(0, 0, 0);

            GL.TexCoord2(1, 0);
            GL.Vertex3(256, 0, 0);

            GL.TexCoord2(1, 1);
            GL.Vertex3(256, 256, 0);

            GL.TexCoord2(0, 1);
            GL.Vertex3(0, 256, 0);

            GL.End();

            GL.Disable(EnableCap.Texture2D);
            GL.PopMatrix();

            GL.MatrixMode(MatrixMode.Projection);
            GL.PopMatrix();

            GL.MatrixMode(MatrixMode.Modelview);
        } 

        protected override void OnRenderFrame( FrameEventArgs e )
        {
            GL.Clear( ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit );

            DrawImage(texture);

            SwapBuffers();
        }
    }

    public class Program
    {
        [STAThread]
        public static void Main()
        {
            using (FailRender win = new FailRender())
            {
                win.Run();
            }
        }
    }
}

Answer

Joel picture Joel · Jul 26, 2012

Removing the line "GL.Color4(1, 0, 0, 1);"

and changing the load texture function to:

public int LoadTexture(string file)
{
    Bitmap bitmap = new Bitmap(file);

    int tex;
    GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

    GL.GenTextures(1, out tex);
    GL.BindTexture(TextureTarget.Texture2D, tex);

    BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
        ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
        OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
    bitmap.UnlockBits(data);


    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Linear);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.Repeat);
    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.Repeat);

    return tex;
}

Fixes the issue. System.Drawing.PixelFormat.Argb goes with OpenGL format Bgra.