Ejemplo n.º 1
0
        protected void UpdateContextVersion()
        {
            //  If the request version number is anything up to and including 2.1, standard render contexts
            //  will provide what we need (as long as the graphics card drivers are up to date).
            var requestedVersionNumber = VersionAttribute.GetVersionAttribute(_requestedOpenGLVersion);

            if (requestedVersionNumber.IsAtLeastVersion(3, 0) == false)
            {
                return;
            }

            //  Now the none-trivial case. We must use the WGL_ARB_create_context extension to
            //  attempt to create a 3.0+ context.
            try
            {
                Int32[] attributes =
                {
                    WGL_CONTEXT_MAJOR_VERSION_ARB, requestedVersionNumber.Major,
                    WGL_CONTEXT_MINOR_VERSION_ARB, requestedVersionNumber.Minor,
                    WGL_CONTEXT_FLAGS_ARB,         WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
                    0
                };
                var hrc = CreateContextAttribsARB(IntPtr.Zero, attributes);
                GLWindows.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero);
                GLWindows.wglDeleteContext(_renderContextHandle);
                GLWindows.wglMakeCurrent(_deviceContextHandle, hrc);
                _renderContextHandle = hrc;
            }
            catch (Exception)
            {
                //  TODO: can we actually get the real version?
            }
        }
Ejemplo n.º 2
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);
        }