Maxime Mangel
Maxime Mangel

Reputation: 1996

How to draw a triangle with VBO and F#

I am trying to draw a triangle using OpenTK and VBO.

But the only thins that appear is a brown background.

open System
open OpenTK
open OpenTK.Graphics.OpenGL4
open OpenTK.Graphics

type Window(width, height, mode, title, options) =
    inherit GameWindow(width, height, mode, title, options)

    let mutable buffers :int = 0


    let createVertexBuffer =
        let vertices = 
            [|
                new Vector3(-1.f,-1.f,0.f)
                new Vector3(1.f,-1.f,0.f)
                new Vector3(0.f,-1.f,0.f)
            |]
        buffers <- GL.GenBuffer()
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers)
        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertices.Length * Vector3.SizeInBytes), vertices, BufferUsageHint.StaticDraw)

    // Function for initialization.
    override this.OnLoad(e) =
        // The background will just cleared with blue color.
        base.OnLoad(e)
        //GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f)
        GL.ClearColor(Color4.Brown)
        //GL.Enable(EnableCap.DepthTest)
        createVertexBuffer


    // Function is called before first update and every time when the window is resized.
    override this.OnResize(e) =
        GL.Viewport(0, 0, this.Width, this.Height)
        base.OnResize(e)

    // Function to render and display content. 
    override this.OnRenderFrame(e) =
        base.OnRenderFrame(e)
        GL.Clear(ClearBufferMask.ColorBufferBit)
        GL.Clear(ClearBufferMask.DepthBufferBit)

        GL.EnableVertexAttribArray(0)
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffers)
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0)
        GL.DrawArrays(PrimitiveType.Triangles, 0, 3)

        GL.DisableVertexAttribArray(0)

        // Swap the front and back buffers
        this.Context.SwapBuffers()

[<EntryPoint>]
let main argv = 
    use window = new Window(640, 480, Graphics.GraphicsMode.Default, "Example Window", GameWindowFlags.Default)
    window.Run()
    0  

Does anyone have a idea of what I'm doing wrong ?

Upvotes: 0

Views: 203

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54562

You're trying to render a degenerate triangle:

    let vertices = 
        [|
            new Vector3(-1.f,-1.f,0.f)
            new Vector3(1.f,-1.f,0.f)
            new Vector3(0.f,-1.f,0.f)
        |]

Note that the y- and z-coordinates are the same for all 3 vertices, which means that all 3 points are on a line. OpenGL does not render any pixels for degenerate triangles. You probably want something like this instead:

    let vertices = 
        [|
            new Vector3(-1.f,-1.f,0.f)
            new Vector3(1.f,-1.f,0.f)
            new Vector3(0.f,1.f,0.f)
        |]

There's another aspect that looks at least risky, unless the OpenGL bindings you are using (which I'm not familiar with) are handling this magically for you. You're using generic vertex attributes, but I don't see any shaders. You normally have to provide your own shaders written in GLSL if you're using generic vertex attributes.

If you want to use the deprecated fixed pipeline, you have to use fixed function vertex attributes, calling functions like glVertexPointer and glEnableClientState, instead of glVertexAttribPointer and glEnableVertexAttribArray.

You can sometimes get away with mixing the two, particularly as long as you're only using a single attribute for positions. But you will likely run into problems with this approach once you start using additional attributes, e.g. for normals or colors. There can also be different behavior on different platforms when using generic vertex attributes without shaders.

Upvotes: 1

Related Questions