OpenGL Create Context

  • C#
  • .NET (FX) 4.0

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von ThuCommix.

    OpenGL Create Context

    Ich versuche gerade einen OpenGL Context zu erstellen, dazu verwende ich folgendes:

    C#-Quellcode

    1. _windowHandle = windowHandle;
    2. Width = width;
    3. Height = height;
    4. _deviceContext = NativeMethods.GetDC(windowHandle);
    5. var pixelFormatDescriptor = new NativeMethods.PIXELFORMATDESCRIPTOR();
    6. pixelFormatDescriptor.Init();
    7. pixelFormatDescriptor.nVersion = 1;
    8. pixelFormatDescriptor.dwFlags = 37u;
    9. pixelFormatDescriptor.iPixelType = 0;
    10. pixelFormatDescriptor.cColorBits = (byte)bitDepth;
    11. pixelFormatDescriptor.cDepthBits = 16;
    12. pixelFormatDescriptor.cStencilBits = 8;
    13. pixelFormatDescriptor.iLayerType = 0;
    14. int iPixelFormat;
    15. if ((iPixelFormat = NativeMethods.ChoosePixelFormat(_deviceContext, pixelFormatDescriptor)) == 0)
    16. {
    17. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    18. }
    19. if (NativeMethods.SetPixelFormat(_deviceContext, iPixelFormat, pixelFormatDescriptor) == 0)
    20. {
    21. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    22. }
    23. _renderContext = NativeMethods.wglCreateContext(_deviceContext);
    24. MakeCurrent();


    MakeCurrent und Blit sehen folgendermaßen aus:

    C#-Quellcode

    1. /// <summary>
    2. /// Makes the render context the current context.
    3. /// </summary>
    4. public void MakeCurrent()
    5. {
    6. if (_renderContext != IntPtr.Zero)
    7. {
    8. NativeMethods.wglMakeCurrent(_deviceContext, _renderContext);
    9. }
    10. }
    11. /// <summary>
    12. /// Blit the rendered data to the supplied device context.
    13. /// </summary>
    14. /// <param name="hdc">The HDC.</param>
    15. public void Blit(IntPtr hdc)
    16. {
    17. if (_deviceContext != IntPtr.Zero || _windowHandle != IntPtr.Zero)
    18. {
    19. NativeMethods.SwapBuffers(_deviceContext);
    20. }
    21. }


    Bei jeden neuen Frame rufe Ich MakeCurrent auf, und nach allen Draws dann Blit. Aber alles was ich erhalte ist ein Schwarzer Hintergrund, keiner der OpenGL Calls ist erfolgreich. Habe ich einen Fehler bei der Kontexterstellung gemacht? Eigentlich muss der Fehler ja hier liegen..
    makecurrent musst du eigdl. nur ein mal machen, damit legst du den DC fest. Wichtig wäre welchen Wrapper du verwendest. Hier habe ich ein Tutorial zu SharpGL dotnet-forum.org/showthread.php?tid=19&pid=64#pid64 OpenGL zeichnet pro Thread auf nur einen Layer.
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    Huhu,
    ich nehme mal an es liegt am ChoosePixelFormat. Was nutzt du da für Flags? Am Besten kann man da eben ne Enum für machen, weil 37u ist nicht sonderlich wartbar. Da weiß man nicht was gesetzt ist. Ob iPixelType und iLayerType null sein dürfen, weiß ich im Moment nicht. Ich guck mal kurz in die Header.
    Wenn ich wglCreateContext schmeißt mir OpenGL GL_INVALID_OPERATION zurück merkwürdig, da kann es ja nur am pixelFormatDescriptor liegen oder?

    C#-Quellcode

    1. _deviceContext = NativeMethods.GetDC(windowHandle);
    2. var pixelFormatDescriptor = new NativeMethods.PIXELFORMATDESCRIPTOR();
    3. pixelFormatDescriptor.Init();
    4. pixelFormatDescriptor.nVersion = 1;
    5. pixelFormatDescriptor.dwFlags = PixelFormatDescription.PFD_SUPPORT_OPENGL |
    6. PixelFormatDescription.PFD_DOUBLEBUFFER |
    7. PixelFormatDescription.PFD_DRAW_TO_WINDOW;
    8. pixelFormatDescriptor.iPixelType = PixelFormatType.PFD_TYPE_RGBA;
    9. pixelFormatDescriptor.cColorBits = (byte)bitDepth;
    10. pixelFormatDescriptor.cDepthBits = 24;
    11. pixelFormatDescriptor.cStencilBits = 8;
    12. pixelFormatDescriptor.iLayerType = LayerType.PFD_MAIN_PLANE;
    13. int iPixelFormat;
    14. if ((iPixelFormat = NativeMethods.ChoosePixelFormat(_deviceContext, pixelFormatDescriptor)) == 0)
    15. {
    16. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    17. }
    18. if (NativeMethods.SetPixelFormat(_deviceContext, iPixelFormat, pixelFormatDescriptor) == 0)
    19. {
    20. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    21. }
    22. _renderContext = NativeMethods.wglCreateContext(_deviceContext);
    23. System.Diagnostics.Debug.WriteLine((OpenGLError)OpenGL.glGetError());


    Habe den PixelDescriptor mal angepasst, immer noch Invalid Operation.. @Gonger96

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ThuCommix“ ()

    Invalid Operation heißt ja meistens, dass du etwas ausgelassen hast. Hast du mal hier vorbei geschaut: cs.rit.edu/~ncs/Courses/570/UserGuide/OpenGLonWin-11.html
    Soviel ich sehe wird dort folgende Reihenfolge einhalten:
    1. DC holen
    2. ChoosePixelFormat
    3. Palette "setzen"
    4. wglCreateContext
    ​Geht man also nach dem Code dort dann lässt du folgendes aus:

    C-Quellcode

    1. void
    2. setupPalette(HDC hDC)
    3. {
    4. int pixelFormat = GetPixelFormat(hDC);
    5. PIXELFORMATDESCRIPTOR pfd;
    6. LOGPALETTE* pPal;
    7. int paletteSize;
    8. DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
    9. if (pfd.dwFlags & PFD_NEED_PALETTE) {
    10. paletteSize = 1 << pfd.cColorBits;
    11. } else {
    12. return;
    13. }
    14. pPal = (LOGPALETTE*)
    15. malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
    16. pPal->palVersion = 0x300;
    17. pPal->palNumEntries = paletteSize;
    18. /* build a simple RGB color palette */
    19. {
    20. int redMask = (1 << pfd.cRedBits) - 1;
    21. int greenMask = (1 << pfd.cGreenBits) - 1;
    22. int blueMask = (1 << pfd.cBlueBits) - 1;
    23. int i;
    24. for (i=0; i<paletteSize; ++i) {
    25. pPal->palPalEntry[i].peRed =
    26. (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
    27. pPal->palPalEntry[i].peGreen =
    28. (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
    29. pPal->palPalEntry[i].peBlue =
    30. (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
    31. pPal->palPalEntry[i].peFlags = 0;
    32. }
    33. }
    34. hPalette = CreatePalette(pPal);
    35. free(pPal);
    36. if (hPalette) {
    37. SelectPalette(hDC, hPalette, FALSE);
    38. RealizePalette(hDC);
    39. }
    40. }


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Zunächst welchen wrapper nutzt du ? ich habe noch nie in einer OpenGL Anwendung das Pixelformat bestimmen müssen. Bei meinem Wrapper bräuchtest du nur

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. using System.Windows.Forms;
    10. namespace NetGL_Tutorial
    11. {
    12. public partial class Form1 : Form
    13. {
    14. private NetGL.OpenGL OpenGL;
    15. public Form1()
    16. {
    17. InitializeComponent();
    18. }
    19. private void Form1_Load(object sender, EventArgs e)
    20. {
    21. }
    22. private void Form1_Shown(object sender, EventArgs e)
    23. {
    24. this.OpenGL = new NetGL.OpenGL();
    25. this.OpenGL.Initial(this.Handle);
    26. }
    27. private void Form1_Paint(object sender, PaintEventArgs e)
    28. {
    29. this.OpenGL.Clear(NetGL.OpenGL.ColorBufferBit | NetGL.OpenGL.DepthBufferBit);
    30. this.OpenGL.MatrixMode(NetGL.OpenGL.Projection);
    31. this.OpenGL.LoadIdentity();
    32. this.OpenGL.Begin(NetGL.OpenGL.Triangles);
    33. this.OpenGL.Color3f(Color.Red.R, Color.Red.G, Color.Red.B);
    34. this.OpenGL.Vertex3f(0.0f, -1.0f, 0.0f);
    35. this.OpenGL.Color3f(Color.Green.R, Color.Green.G, Color.Green.B);
    36. this.OpenGL.Vertex3f(-1.0f, 1.0f, 0.0f);
    37. this.OpenGL.Color3f(Color.Blue.R, Color.Blue.G, Color.Blue.B);
    38. this.OpenGL.Vertex3f(1.0f, 1.0f, 0.0f);
    39. this.OpenGL.End();
    40. this.OpenGL.Flush();
    41. }
    42. }
    43. }
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    Er schreibt selbst einen Wrapper (glaube ich zumindest). Wie ich, ein Mensch mit idealen und einer Schwäche für geistige Selbstverstümmelung ;). Schreibe auch fast alle Wrapper selbst und bringt einem recht oft zur Weißglut wobei OGL da eh noch halbwegs human ist, da eig. DllImporte genügen :).


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    achso :) Meiner ist OpenSource und kann unter netgl.org herunter geladen werden. Allerdings habe ich für den Source eine Registrierung vorgesehen. Ich kann aber auch Intitial() hier posten.
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    Ich habe mir diverse Tutorials für OpenGL in C++ angesehen z.B hier: nullterminator.net/opengl32.html

    Nirgends wurde eine Platte verwendet, der Fehler muss irgendwo anders liegen.. Der PixelDescriptor dürfte ja nun richtig sein :/
    Was macht denn die .Init()? Das Tutorial ist übrigens ziemlich bescheiden ;)

    Edit:
    Note: It was pointed out to me that under some OpenGL ICDs (ATI Rage
    Pro, RivaTNT, etc.), the window style of CS_OWNDC must be included in the window
    class. Otherwise OpenGL will not function. This information was provided by Ryan
    Haksi (thanx Ryan!). I have corrected this in the GLSAMPLE program given at the
    end

    Gib deinem Fenster mal CS_OWNDC. Einfach zu den Klassenstilen hinzufügen. Vielleicht war das schon der Fehler.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gonger96“ ()

    C#-Quellcode

    1. _windowHandle = windowHandle;
    2. Version = version;
    3. Width = width;
    4. Height = height;
    5. _deviceContext = NativeMethods.GetDC(windowHandle);
    6. System.Diagnostics.Debug.WriteLine(Marshal.GetLastWin32Error());
    7. NativeMethods.PIXELFORMATDESCRIPTOR pfd = new NativeMethods.PIXELFORMATDESCRIPTOR();// The pixel format descriptor
    8. pfd.nSize = (short)Marshal.SizeOf(pfd); // Size of the pixel format descriptor
    9. pfd.nVersion = 1; // Version number (always 1)
    10. pfd.dwFlags = (int)PixelFormatDescription.PFD_DRAW_TO_WINDOW | // Format must support windowed mode
    11. (int)PixelFormatDescription.PFD_SUPPORT_OPENGL | // Format must support OpenGL
    12. (int)PixelFormatDescription.PFD_DOUBLEBUFFER; // Must support double buffering
    13. pfd.iPixelType = (byte)PixelFormatType.PFD_TYPE_RGBA; // Request an RGBA format
    14. pfd.cColorBits = (byte) bitDepth; // Select our color depth
    15. pfd.cRedBits = 0; // Individual color bits ignored
    16. pfd.cRedShift = 0;
    17. pfd.cGreenBits = 0;
    18. pfd.cGreenShift = 0;
    19. pfd.cBlueBits = 0;
    20. pfd.cBlueShift = 0;
    21. pfd.cAlphaBits = 0; // No alpha buffer
    22. pfd.cAlphaShift = 0; // Alpha shift bit ignored
    23. pfd.cAccumBits = 0; // Accumulation buffer
    24. pfd.cAccumRedBits = 0; // Individual accumulation bits ignored
    25. pfd.cAccumGreenBits = 0;
    26. pfd.cAccumBlueBits = 0;
    27. pfd.cAccumAlphaBits = 0;
    28. pfd.cDepthBits = 24; // Z-buffer (depth buffer)
    29. pfd.cStencilBits = 8; // No stencil buffer
    30. pfd.cAuxBuffers = 0; // No auxiliary buffer
    31. pfd.iLayerType = (byte)LayerType.PFD_MAIN_PLANE; // Main drawing layer
    32. pfd.bReserved = 0; // Reserved
    33. pfd.dwLayerMask = 0; // Layer masks ignored
    34. pfd.dwVisibleMask = 0;
    35. pfd.dwDamageMask = 0;
    36. int iPixelFormat;
    37. if ((iPixelFormat = NativeMethods.ChoosePixelFormat(_deviceContext, ref pfd)) == 0)
    38. {
    39. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    40. }
    41. System.Diagnostics.Debug.WriteLine((OpenGLError)OpenGL.glGetError());
    42. System.Diagnostics.Debug.WriteLine(Marshal.GetLastWin32Error());
    43. if (!NativeMethods.SetPixelFormat(_deviceContext, iPixelFormat, ref pfd))
    44. {
    45. throw new RenderDeviceException("Unable to initialize NativeRenderContext.");
    46. }
    47. System.Diagnostics.Debug.WriteLine((OpenGLError)OpenGL.glGetError());
    48. System.Diagnostics.Debug.WriteLine(Marshal.GetLastWin32Error());
    49. _renderContext = NativeMethods.wglCreateContext(_deviceContext);
    50. System.Diagnostics.Debug.WriteLine((OpenGLError)OpenGL.glGetError());
    51. MakeCurrent();

    C#-Quellcode

    1. protected override CreateParams CreateParams
    2. {
    3. get
    4. {
    5. Int32 CS_VREDRAW = 0x1;
    6. Int32 CS_HREDRAW = 0x2;
    7. Int32 CS_OWNDC = 0x20;
    8. CreateParams cp = base.CreateParams;
    9. cp.ClassStyle = cp.ClassStyle | CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
    10. return cp;
    11. }
    12. }


    Nach dem das Fensterhandle erstellt wurde, das ist also Valid..