C#-OpenGL无法渲染但glGetError没有错误

时间:2019-02-08 21:33:33

标签: c# opengl-1.x

我正在尝试使用DllImport在C#中加载OpenGL和WinApi函数。由于某种原因,尽管OpenGL不会渲染。我尝试使用glGetError,但是没有错误(在创建glContext之前没有错误1282,但是我敢肯定这是可以预期的)。窗户只是保持白色。我已经使用完全相同的功能在C ++中完成了完全相同的操作,它工作得很好,但是由于某种原因,它在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);

主要

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;
}

0 个答案:

没有答案