Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have found the following C++ code in this tutorial to draw a triangle with OpenGL 4:

float points[] = {
   0.0f,  0.5f,  0.0f,
   0.5f, -0.5f,  0.0f,
  -0.5f, -0.5f,  0.0f
};
GLuint vbo = 0;
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (float), points, GL_STATIC_DRAW);

I use C# and OpenTK, so I tried to translate the code:

        float[] points = 
        {
           0.0f,  0.5f,  0.0f,
           0.5f, -0.5f,  0.0f,
          -0.5f, -0.5f,  0.0f
        };
        uint[] vbo = {0};
        GL.GenBuffers(1, vbo);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo[0]);
        GL.BufferData(BufferTarget.ArrayBuffer, 9 * sizeof(float), ppoints, BufferUsageHint.StaticDraw);

The problem is that GL.GenBuffers() and GL.BufferData() require pointers (Visual Studio shows *int or out int and ref float*, IntPtr).

I've tried to fix this, but it didn't work:

        float[] points = 
        {
           0.0f,  0.5f,  0.0f,
           0.5f, -0.5f,  0.0f,
          -0.5f, -0.5f,  0.0f
        };
        uint[] vbo = {0};
        GL.GenBuffers(1, vbo);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo[0]);

        unsafe
        {
            fixed (float* ppoints = points)
            {
                GL.BufferData(BufferTarget.ArrayBuffer, 9 * sizeof(float), ppoints, BufferUsageHint.StaticDraw);
            }
        }

So my question is how to use these methods in a good C# style?

share|improve this question
    
Have you tried simply adding the out and ref to the parameters in the function call (don't see you mentioning that in your question)? –  UnholySheep Oct 7 '14 at 14:26
    
Don't allocate a whole array just to return a single value! See my answer below. –  The Fiddler Oct 7 '14 at 15:07

1 Answer 1

up vote 4 down vote accepted

The following code should work:

    var points = new float[] 
    {
       0.0f,  0.5f,  0.0f,
       0.5f, -0.5f,  0.0f,
      -0.5f, -0.5f,  0.0f
    };
    int vbo = GL.GenBuffer();
    GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);        
    GL.BufferData(BufferTarget.ArrayBuffer, points.Length * sizeof(float), points, BufferUsageHint.StaticDraw);

OpenTK provides three overloads for each method with typed pointers. For example:

const GLfloat* -> ref float, float[], float* (input)
      GLfloat* -> out float, float[], float* (output)
  1. Use ref/out float if you wish to pass/retrieve a single item.
  2. Use float[] if you wish to pass/retrieve an array of items.
  3. Use float* when writing unsafe code (e.g. a pointer to unmanaged memory or the stack).

Untyped pointers get the same overloads using generics:

const GLvoid* -> ref T, T[], IntPtr (input)
      GLvoid* -> out T, T[], IntPtr (output)

Starting with OpenTK 1.1, Gen* and Delete* methods get one additional overload, to simplify usage from F# (and similar functional languages). This is often the optimal approach:

int buffer = GL.GenBuffer();

Which is equivalent to the more verbose:

int buffer;
GL.GenBuffers(1, out buffer);

Note that unsigned types get both unsigned and signed overloads. For example, GLuint gets both uint and int overloads. The reason is that unsigned integers are not [CLS-Compliant][1] and cannot be used by all .Net languages (e.g. VB.Net). This is something to keep in mind if you are writing a public API to be consumed outside of C#.

[1] http://msdn.microsoft.com/en-us/library/12a7a7h3%28v=vs.110%29.aspx

share|improve this answer
    
Good explanations! But unfortunately this line does not work: GL.BufferData(BufferTarget.ArrayBuffer, points.Length * sizeof(float), points, BufferUsageHint.StaticDraw); I think it is, because points.Length * sizeof(float) is not an IntPtr !? –  user3621741 Oct 7 '14 at 16:14
    
It works on opentk/develop (version 1.1.5+). For previous versions you need to use new IntPtr(...). –  The Fiddler Oct 8 '14 at 5:33
    
OK, but where can I download the develop version? I only find the stable release. –  user3621741 Oct 8 '14 at 7:27
    
You can download the latest code from github. Simply double-click OpenTK.sln and build in release mode. v1.1.5 will be released this week. –  The Fiddler Oct 8 '14 at 8:54
    
In the Version.txt stand 1.1.1741.0, not 1.1.5? I have downloaded the ZIP from the link above. –  user3621741 Oct 8 '14 at 10:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.