protected virtual Boolean SetPixelFormat(IntPtr hDC, Int32 bitCount) { // Create the big lame pixel format majoo. var pixelFormat = new Pixelformatdescriptor(); pixelFormat.Init(); // Set the values for the pixel format. pixelFormat.nVersion = 1; pixelFormat.dwFlags = (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI); pixelFormat.iPixelType = PFD_TYPE_RGBA; pixelFormat.cColorBits = (Byte)bitCount; pixelFormat.cDepthBits = 32; pixelFormat.iLayerType = PFD_MAIN_PLANE; // Match an appropriate pixel format Int32 iPixelformat; if ((iPixelformat = Native.ChoosePixelFormat(hDC, pixelFormat)) == 0) { return(false); } // Sets the pixel format if (Native.SetPixelFormat(hDC, iPixelformat, pixelFormat) == 0) { var _ = Marshal.GetLastWin32Error(); return(false); } return(true); }
public void Initialize() { SetSizeFromHost(); _windowHandle = _windowBuilder.BuildNativeWindow(_roundedWidth, _roundedHeight); _deviceContextHandle = Native.GetDC(_windowHandle); var pfd = new Pixelformatdescriptor(); pfd.Init(); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = _bitDepth; pfd.cDepthBits = 16; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; Int32 iPixelformat; if ((iPixelformat = Native.ChoosePixelFormat(_deviceContextHandle, pfd)) == 0) { throw new InvalidOperationException(); } if (Native.SetPixelFormat(_deviceContextHandle, iPixelformat, pfd) == 0) { throw new InvalidOperationException(); } _renderContextHandle = GLWindows.wglCreateContext(_deviceContextHandle); GLWindows.wglMakeCurrent(_deviceContextHandle, _renderContextHandle); UpdateContextVersion(); CreateDBOs(); GL.glShadeModel(GL.SMOOTH); GL.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); GL.glClearDepth(1.0f); GL.glEnable(GL.DEPTHTEST); GL.glDepthFunc(GL.LEQUAL); GL.glHint(GL.PERSPECTIVE_CORRECTION_HINT, GL.NICEST); OnSizeChanged(); ///////////////////////////////////////////////////////////////// var vertexShaderSource = "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" + "}\0"; var fragmentShaderSource = "#version 330 core\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" + "}\n\0"; var vertexShader = GL.CreateVertexShader(); GL.ShaderSource(vertexShader, vertexShaderSource); GL.CompileShader(vertexShader); var rdrr = GL.GetCompileStatus(vertexShader); var fragmentShader = GL.CreateShader(GL.GL_FRAGMENT_SHADER); GL.ShaderSource(fragmentShader, fragmentShaderSource); GL.CompileShader(fragmentShader); rdrr = GL.GetCompileStatus(fragmentShader); GL.DeleteShader(vertexShader); GL.DeleteShader(fragmentShader); ////////////////////////////// float[] vertices = { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; ushort[] indices = { // note that we start from 0! 0, 1, 3, // first Triangle 1, 2, 3 // second Triangle }; uint VBO, VAO = 1, EBO; uint[] vaoIds = new uint[1]; GL.GenVertexArrays(1, vaoIds); VAO = vaoIds[0]; uint[] vboBuffers = new uint[1]; GL.GenBuffers(1, vboBuffers); VBO = vboBuffers[0]; uint[] ebobuffers = new uint[1]; GL.GenBuffers(1, ebobuffers); EBO = ebobuffers[0]; //// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). GL.BindVertexArray(VAO); GL.BindBuffer(GL.GL_ARRAY_BUFFER, VBO); GL.BufferData(GL.GL_ARRAY_BUFFER, vertices, GL.GL_STATIC_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, EBO); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW); GL.VertexAttribPointer(0, 3, GL.GL_FLOAT, false, 3 * 0, IntPtr.Zero); GL.EnableVertexAttribArray(0); //// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind GL.BindBuffer(GL.GL_ARRAY_BUFFER, 0); // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. GL.BindVertexArray(0); ///////////////////////////////////////////////////////////////// }
public HelloTriangle(Form form, IntPtr handle) { _form = form; _requestedOpenGLVersion = OpenGLVersion.OpenGL4_4; _delegateCache = new DelegateCache(); _windowBuilder = new GLWindowBuilder("OpenGLSurface"); _dibSection = new DIBSection(); var _hostGraphics = Graphics.FromHwnd(handle); _hostDc = _hostGraphics.GetHdc(); _windowHandle = _windowBuilder.BuildNativeWindow(_roundedWidth, _roundedHeight); _deviceContextHandle = Native.GetDC(_windowHandle); var pfd = new Pixelformatdescriptor(); pfd.Init(); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = _bitDepth; pfd.cDepthBits = 16; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; Int32 iPixelformat; if ((iPixelformat = Native.ChoosePixelFormat(_deviceContextHandle, pfd)) == 0) { throw new InvalidOperationException(); } if (Native.SetPixelFormat(_deviceContextHandle, iPixelformat, pfd) == 0) { throw new InvalidOperationException(); } _renderContextHandle = GLWindows.wglCreateContext(_deviceContextHandle); GLWindows.wglMakeCurrent(_deviceContextHandle, _renderContextHandle); UpdateContextVersion(); CreateDBOs(); OnSizeChanged(); const String vertexShaderSource = "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" + "}\0"; const String fragmentShaderSource = "#version 330 core\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" + "}\n\0"; var vertexShader = GL.CreateVertexShader(); GL.ShaderSource(vertexShader, vertexShaderSource); GL.CompileShader(vertexShader); var rdrr = GL.GetCompileStatus(vertexShader); if (!rdrr) { throw new InvalidProgramException("Unable to compile vertex shader"); } var fragmentShader = GL.CreateShader(GL.GL_FRAGMENT_SHADER); GL.ShaderSource(fragmentShader, fragmentShaderSource); GL.CompileShader(fragmentShader); rdrr = GL.GetCompileStatus(fragmentShader); if (!rdrr) { throw new InvalidProgramException("Unable to compile fragment shader"); } _shaderProgram = GL.CreateProgram(); GL.AttachShader(_shaderProgram, vertexShader); GL.AttachShader(_shaderProgram, fragmentShader); GL.LinkProgram(_shaderProgram); // check for linking errors var parameters = new[] { 0 }; GL.GetProgram(_shaderProgram, GL.GL_LINK_STATUS, parameters); var ok = parameters[0] == GL.GL_TRUE; if (!ok) { throw new InvalidProgramException("Unable to link shader"); } GL.DeleteShader(vertexShader); GL.DeleteShader(fragmentShader); var vertices = new[] { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; UInt16[] indices = { // note that we start from 0! 0, 1, 3, // first Triangle 1, 2, 3 // second Triangle }; var buff = new UInt32[1]; GL.GenVertexArrays(1, buff); VAO = buff[0]; GL.GenBuffers(1, buff); VBO = buff[0]; GL.GenBuffers(1, buff); EBO = buff[0]; //// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). GL.BindVertexArray(VAO); GL.BindBuffer(GL.GL_ARRAY_BUFFER, VBO); GL.BufferData(GL.GL_ARRAY_BUFFER, vertices, GL.GL_STATIC_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, EBO); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW); GL.VertexAttribPointer(0, 3, GL.GL_FLOAT, false, 3 * sizeof(Single), IntPtr.Zero); GL.EnableVertexAttribArray(0); //// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind GL.BindBuffer(GL.GL_ARRAY_BUFFER, 0); // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound. //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. GL.BindVertexArray(0); }