Jump to content
Site Stability Read more... ×
  • Advertisement
Sign in to follow this  

OpenGL VAO and VBOs in OpenTK don't draw with simple shader

This topic is 2771 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[color=#333333][font=arial,helvetica,sans-serif]I'm implementing a "Mesh" class to use in my OpenTK game. You pass in a vertex array and an index array when you create it, and then you can call Mesh.Draw() to draw it using a shader.[/font]
[color=#333333][font=arial,helvetica,sans-serif]I've heard VBO's and VAO's are the way to go for this approach, but nowhere have I found a guide that shows how to get Data > Video Memory > Shader.[/font]
[color=#333333][font=arial,helvetica,sans-serif]Can anyone give me a quick rundown of how this works?[/font]

[color=#333333][font=arial, helvetica, sans-serif]EDIT:[/font]

[font=arial, helvetica, sans-serif][color=#333333]I implemented a VBO and VAO system based on the HelloGL3 example that comes with OpenTK. When I copy and paste the example code into my project, it works perfectly, but mine doesn't draw a thing.[/font]


using System;
using System.Threading;

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using OpenTK.Input;

namespace OpenTKTest
class Application : GameWindow
Matrix4 matProjection;
Matrix4 matView;
Matrix4 matWorld;
int uniformProjection;
int uniformView;
int uniformWorld;
int uniformNormalTransform;

Shader shader;
Mesh triangle;
float angle = 0.0f;

public Application() : base(800, 600, new GraphicsMode(), "OpenGL 3 Example", 0, DisplayDevice.Default, 3, 0,
GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug)
VSync = VSyncMode.On;

protected override void OnLoad(EventArgs e)

GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);

// load the shader
shader = new Shader("shaders/shader.vert", "shaders/shader.frag");
uniformProjection = shader.GetUniformLocation("mat_projection");
uniformView = shader.GetUniformLocation("mat_view");
uniformWorld = shader.GetUniformLocation("mat_world");
uniformNormalTransform = shader.GetUniformLocation("mat_normalTransform");

// vertices
Vector3[] pos = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(1.0f, -1.0f, 0.0f)
Vector3[] nml = {
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, -1.0f)

// indices
ushort[] ia = { 0, 1, 2 };

// create a mesh
triangle = new Mesh(pos, nml, ia, shader);

protected override void OnResize(EventArgs e)

GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);

matProjection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 0.1f, 100.0f);

protected override void OnUpdateFrame(FrameEventArgs e)

angle += (float)e.Time;

if (Keyboard[Key.Escape])

protected override void OnRenderFrame(FrameEventArgs e)

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

Vector3 eye = new Vector3(0.0f, 0.0f, -1.0f);
Vector3 target = Vector3.Zero;
Vector3 up = new Vector3(0.0f, 1.0f, 0.0f);
matView = Matrix4.LookAt(eye, target, up);

matWorld = Matrix4.CreateRotationY(angle);

Matrix4 matNormalTransform;
Matrix4.Mult(ref matProjection, ref matView, out matNormalTransform);
Matrix4.Mult(ref matNormalTransform, ref matWorld, out matNormalTransform);

GL.UniformMatrix4(uniformProjection, false, ref matProjection);
GL.UniformMatrix4(uniformView, false, ref matView);
GL.UniformMatrix4(uniformWorld, false, ref matWorld);
GL.UniformMatrix4(uniformNormalTransform, true, ref matNormalTransform);



static void Main()
// The 'using' idiom guarantees proper resource cleanup.
// We request 30 UpdateFrame events per second, and unlimited
// RenderFrame events (as fast as the computer can handle).
using (Application game = new Application())


using System;
using OpenTK;
using OpenTK.Graphics.OpenGL;
namespace OpenTKTest
class Mesh
// buffer handles
private uint vboPositions;
private uint vboNormals;
private uint ibo;
private uint vao;

private Shader currentShader;

private int numVertices;
private int numIndices;

private ushort[] indices;

public Mesh(Vector3[] positions, Vector3[] normals, ushort[] indices, Shader shader)
// set from parameters
numVertices = positions.Length;
numIndices = indices.Length;
this.indices = indices;

// create VBOs and IBO
vboPositions = CreateVBO<Vector3>(positions, Vector3.SizeInBytes);
vboNormals = CreateVBO<Vector3>(normals, Vector3.SizeInBytes);
ibo = CreateIBO(indices);

// create VAO
GL.GenVertexArrays(1, out vao);

// position attribute
GL.BindBuffer(BufferTarget.ArrayBuffer, vboPositions);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);

// normal attribute
GL.BindBuffer(BufferTarget.ArrayBuffer, vboNormals);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0);

// finalize
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);

// unbind VAO, and VBO
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

private uint CreateVBO<T>(T[] data, int size) where T : struct
uint vbo;
GL.GenBuffers(1, out vbo);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
GL.BufferData<T>(BufferTarget.ArrayBuffer, (IntPtr)(data.Length * size), data, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
return vbo;

private uint CreateIBO(ushort[] data)
uint ibo;
GL.GenBuffers(1, out ibo);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(data.Length * sizeof(ushort)), data, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
return ibo;

public void BindToShader(Shader shader)
GL.BindAttribLocation(shader.program, 0, "in_position");
GL.BindAttribLocation(shader.program, 1, "in_normal");
currentShader = shader;

public void Render()
// use correct shader

// render
GL.DrawElements(BeginMode.Triangles, numIndices, DrawElementsType.UnsignedShort, IntPtr.Zero);

public void Free()
// delete buffers
GL.DeleteBuffers(1, ref vboPositions);
GL.DeleteBuffers(1, ref vboNormals);
GL.DeleteBuffers(1, ref ibo);
GL.DeleteVertexArrays(1, ref vao);


using System;
using System.IO;
using System.Collections.Generic;
using OpenTK.Graphics.OpenGL;
namespace OpenTKTest
public class Shader
public int program { get; private set; }
private int vertexShader;
private int fragmentShader;

public Shader(string vertexShaderPath, string fragmentShaderPath)
// load and compile vertex shader
vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertexShader, new StreamReader(vertexShaderPath).ReadToEnd());

// load and compile fragment shader
fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragmentShader, new StreamReader(fragmentShaderPath).ReadToEnd());

// create shader program
program = GL.CreateProgram();
GL.AttachShader(program, vertexShader);
GL.AttachShader(program, fragmentShader);

// check for errors
string log;
GL.GetProgramInfoLog(program, out log);

public void Use()

public int GetUniformLocation(string uniform)
return GL.GetUniformLocation(program, uniform);


#version 330

uniform mat4 mat_projection;
uniform mat4 mat_view;
uniform mat4 mat_world;
uniform mat4 mat_normalTransform

in vec4 in_position;
in vec3 in_normal;

out vec3 normal;

void main()
normal = (vec4(in_normal, 1.0f) * mat_normalTransform).xyz;
vec4 wPos = vec4(in_position, 1.0f) * mat_world;
vec4 vPos = wPos * mat_view;
vec4 gl_Position = vPos * mat_projection;


#version 330
out vec4 out_color;
void main()
out_color = vec4(1.0f, 1.0f, 1.0f, 1.0f);

The main source of the problem will probably with Application.cs or Mesh.cs.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!