C# - OpenGL Not Rendering But No Errors From glGetError

0

I'm trying to use DllImport to load OpenGL and WinApi functions in C#. For some reason though OpenGL just won't render. I tried using glGetError but there are no errors (excluding error 1282 before the glContext is created but I'm pretty sure this is expected). The window just stays white. I've done this exact same thing in C++ using the exact same functions and it worked perfectly fine but for some reason it won't work in C#.

DllImports for WinApi

public enum ClassStyle
{
    OwnDC = 0x0020
}

public enum WindowStyle
{
    MinimizeBox = 0x20000,
    SystemMenu = 0x80000
}

public enum Pfd
{
    SupportOpenGL = 0x00000020,
    DrawToWindow = 0x00000004
}

public enum PM
{
    Remove = 0x0001
}

public enum WindowMsg
{
    Quit = 0x0012,
    Destroy = 0x0002
}

public struct WndClassEx
{
    public int size;
    public int style;
    public WndProcD windowProc;
    public int clsExtra;
    public int windowExtra;
    public IntPtr hInstance;
    public IntPtr icon;
    public IntPtr cursor;
    public IntPtr background;
    public string menuName;
    public string className;
    public IntPtr iconSm;

    public static int GetSize()
    {
        return Marshal.SizeOf(typeof(WndClassEx));
    }
}

public struct Msg
{
    public IntPtr window;
    public uint message;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public IntPtr pt;
    public uint lPrivate;
}

public struct PixelFormatDescriptor
{
    public int size;
    public ushort version;
    public uint flags;
    public byte pixelType;
    public byte colorBits;
    public byte redBits;
    public byte redShift;
    public byte greenBits;
    public byte greenShift;
    public byte blueBits;
    public byte blueShift;
    public byte alphaBits;
    public byte alphaShift;
    public byte accumRedBits;
    public byte accumGreenBits;
    public byte accumBlueBits;
    public byte accumAlphaBits;
    public byte depthBits;
    public byte stencilBits;
    public byte auxBuffers;
    public byte layerType;
    public byte reserved;
    public uint layerMask;
    public uint visibleMask;
    public uint damageMask;

    public static int GetSize()
    {
        return Marshal.SizeOf(typeof(PixelFormatDescriptor));
    }
}

public delegate IntPtr WndProcD(IntPtr window, uint msg, IntPtr w, IntPtr l);

[DllImport("user32.dll")]
public static extern IntPtr DefWindowProc(IntPtr window, uint msg, IntPtr w, IntPtr l);

[DllImport("user32.dll")]
public static extern int RegisterClassEx(ref WndClassEx wndClassEx);

[DllImport("user32.dll")]
public static extern IntPtr CreateWindowEx(uint exStyle, string className, string windowName, uint style, int x, int y, int w, int h, IntPtr parent, IntPtr menu, IntPtr hInstance, IntPtr param);

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr window, int show);
[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr window);

[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr window);

[DllImport("gdi32.dll")]
public static extern int ChoosePixelFormat(IntPtr windowDC, ref PixelFormatDescriptor pfd);
[DllImport("gdi32.dll")]
public static extern bool SetPixelFormat(IntPtr windowDC, int choosenPixelFormat, ref PixelFormatDescriptor pfd);

[DllImport("user32.dll")]
public static extern bool PeekMessage(out Msg msg, IntPtr window, uint filterMin, uint filterMax, uint removeMsg);
[DllImport("user32.dll")]
public static extern bool TranslateMessage(ref Msg msg);
[DllImport("user32.dll")]
public static extern IntPtr DispatchMessage(ref Msg msg);

[DllImport("kernel32.dll")]
public static extern int GetLastError();

[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);

DllImports for OpenGL

public const uint ColorBufferBit = 0x00004000;
public const uint Quads = 0x007;

[DllImport("opengl32.dll", EntryPoint = "wglCreateContext")]
public static extern IntPtr CreateContext(IntPtr windowDC);

[DllImport("opengl32.dll", EntryPoint = "wglMakeCurrent")]
public static extern IntPtr MakeCurrent(IntPtr windowDC, IntPtr glContext);

[DllImport("opengl32.dll", EntryPoint = "glBegin")]
public static extern void Begin(uint mode);
[DllImport("opengl32.dll", EntryPoint = "glEnd")]
public static extern void End();

[DllImport("opengl32.dll", EntryPoint = "glFlush")]
public static extern void Flush();

[DllImport("opengl32.dll", EntryPoint = "glClear")]
public static extern void Clear(uint mask);
[DllImport("opengl32.dll", EntryPoint = "glClearColor")]
public static extern void ClearColor(float r, float g, float b, float a);

[DllImport("opengl32.dll", EntryPoint = "glBindTexture")]
public static extern void BindTexture(uint mode, uint texture);

[DllImport("opengl32.dll", EntryPoint = "glEnable")]
public static extern void Enable(uint cap);

[DllImport("opengl32.dll", EntryPoint = "glColor3f")]
public static extern void Color3(float r, float g, float b);

[DllImport("opengl32.dll", EntryPoint = "glVertex3f")]
public static extern void Vertex3(float x, float y, float z);
[DllImport("opengl32.dll", EntryPoint = "glVertex3i")]
public static extern void Vertex3(int x, int y, int z);
[DllImport("opengl32.dll", EntryPoint = "glVertex3d")]
public static extern void Vertex3(double x, double y, double z);
[DllImport("opengl32.dll", EntryPoint = "glVertex3s")]
public static extern void Vertex3(short x, short y, short z);

[DllImport("opengl32.dll", EntryPoint = "glVertex2f")]
public static extern void Vertex2(float x, float y);
[DllImport("opengl32.dll", EntryPoint = "glVertex2i")]
public static extern void Vertex2(int x, int y);
[DllImport("opengl32.dll", EntryPoint = "glVertex2d")]
public static extern void Vertex2(double x, double y);
[DllImport("opengl32.dll", EntryPoint = "glVertex2s")]
public static extern void Vertex2(short x, short y);

[DllImport("opengl32.dll", EntryPoint = "glTexCoord3f")]
public static extern void TexCoord3(float x, float y);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord3i")]
public static extern void TexCoord3(int x, int y);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord3d")]
public static extern void TexCoord3(double x, double y);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord3s")]
public static extern void TexCoord3(short x, short y);

[DllImport("opengl32.dll", EntryPoint = "glTexCoord2f")]
public static extern void TexCoord2(float x, float y, float z);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord2i")]
public static extern void TexCoord2(int x, int y, int z);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord2d")]
public static extern void TexCoord2(double x, double y, double z);
[DllImport("opengl32.dll", EntryPoint = "glTexCoord2s")]
public static extern void TexCoord2(short x, short y, short z);

[DllImport("opengl32.dll", EntryPoint = "glGetError")]
public static extern uint GetError();
[DllImport("glu32.dll", EntryPoint = "gluErrorString")]
public static extern string ErrorString(uint code);

Main

static void Main()
{
    string name = "TestWin";

    Win.WndClassEx windowClass = new Win.WndClassEx();

    windowClass.className = name;
    windowClass.size = Win.WndClassEx.GetSize();
    windowClass.hInstance = Win.GetModuleHandle(null);
    windowClass.style = (int)Win.ClassStyle.OwnDC;
    windowClass.windowProc = WndProc;

    if (Win.RegisterClassEx(ref windowClass) == 0)
    {
        Console.WriteLine("Failed to register window class!");
        Console.WriteLine("Error: " + Win.GetLastError());
        Thread.Sleep(3000);
        return;
    }

    IntPtr window = Win.CreateWindowEx(0, name, "TEST", (uint)(Win.WindowStyle.MinimizeBox | Win.WindowStyle.SystemMenu), 160, 160, 640, 640, IntPtr.Zero, IntPtr.Zero, windowClass.hInstance, IntPtr.Zero);

    if (window == null)
    {
        Console.WriteLine("Failed to create window!");
        Console.WriteLine("Error: " + Win.GetLastError());
        Thread.Sleep(3000);
        return;
    }

    IntPtr windowDC = Win.GetDC(window);
    Win.ShowWindow(window, 1);

    Win.PixelFormatDescriptor pfd = new Win.PixelFormatDescriptor();

    pfd.version = 1;
    pfd.size = Win.PixelFormatDescriptor.GetSize();
    pfd.flags = (uint)(Win.Pfd.DrawToWindow | Win.Pfd.SupportOpenGL);
    pfd.pixelType = 0;
    pfd.colorBits = 32;

    int choosenPixelFormat = Win.ChoosePixelFormat(windowDC, ref pfd);

    if (choosenPixelFormat == 0)
    {
        Console.WriteLine("Failed to choose pixel format!");
        Console.WriteLine("Error: " + Win.GetLastError());
        Thread.Sleep(3000);
        return;
    }

    if (!Win.SetPixelFormat(windowDC, choosenPixelFormat, ref pfd))
    {
        Console.WriteLine("Failed to set pixel format!");
        Console.WriteLine("Error: " + Win.GetLastError());
        Thread.Sleep(3000);
        return;
    }

    IntPtr glContext = GL.CreateContext(windowDC);

    if (glContext == null)
    {
        Console.WriteLine("Failed to create opengl context!");
        Console.WriteLine("Error: " + GL.GetError());
        Thread.Sleep(3000);
        return;
    }

    GL.MakeCurrent(windowDC, glContext);

    while (true)
    {
        int frameStart = Environment.TickCount;

        Win.Msg msg = new Win.Msg();
        while (Win.PeekMessage(out msg, IntPtr.Zero, 0, 0, (uint)Win.PM.Remove))
        {
            Win.TranslateMessage(ref msg);
            Win.DispatchMessage(ref msg);
        }

        GL.Clear(GL.ColorBufferBit);

        GL.Begin(GL.Quads);

        GL.Color3(1.0f, 0.0f, 0.0f);

        GL.Vertex2(-0.5f, -0.5f);

        GL.Vertex2(-0.5f, 0.5f);

        GL.Vertex2(0.5f, 0.5f);

        GL.Vertex2(0.5f, -0.5f);

        GL.End();

        GL.Flush();

        int frameTime = Environment.TickCount - frameStart;
        if (frameTime < 1000 / 60)
            Thread.Sleep((1000 / 60) - frameTime);
    }
}

static IntPtr WndProc(IntPtr window, uint msg, IntPtr w, IntPtr l)
{
    switch (msg)
    {
        case (uint)Win.WindowMsg.Quit:
            Win.DestroyWindow(window);
            break;
        case (uint)Win.WindowMsg.Destroy:
            Environment.Exit(0);
            break;
        default:
            return Win.DefWindowProc(window, msg, w, l);
    }

    return IntPtr.Zero;
}
c#
opengl-1.x
asked on Stack Overflow Feb 8, 2019 by TheTVGuy

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0