Axelill's picture

VBO using OpenTK

I tried to create VBO with openTK without success.

I've already implemented VBO in c++ so I think my initialization is quite correct.

It is maybe a wrong type of parameter. When I want to destroy the buffer it just go with an error telling me that my memory is mayb corrupted. Any idea??

public sealed class CIndexedTrianglesMesh : CMesh
    {
        Int32[] m_indexes;
        Single[] m_data;
 
        UInt32 m_gl_index_buffer;
        UInt32 m_gl_vertex_buffer;
 
        public CIndexedTrianglesMesh(String _name)
            : base(_name)
        {
        }
 
        ~CIndexedTrianglesMesh()
        {
            //GL.DeleteBuffers(1, ref m_gl_index_buffer);
           // GL.DeleteBuffers(1, ref m_gl_vertex_buffer);
        }
 
        public override void GLBuildObject()
        {
            GL.ARB.GenBuffers(1, out m_gl_index_buffer);
            GL.ARB.GenBuffers(1, out m_gl_vertex_buffer);
 
            IntPtr t1 = new IntPtr(m_data.Length * sizeof(Single));
            IntPtr t2 = new IntPtr(m_indexes.Length * sizeof(Int32));
 
            GL.ARB.BindBuffer(GL.Enums.ARB_vertex_buffer_object.ARRAY_BUFFER_ARB, m_gl_vertex_buffer);
            GL.ARB.BufferData(GL.Enums.ARB_vertex_buffer_object.ARRAY_BUFFER_ARB, 
                t1, m_data, GL.Enums.ARB_vertex_buffer_object.DYNAMIC_DRAW_ARB);
 
            GL.ARB.BindBuffer(GL.Enums.ARB_vertex_buffer_object.ELEMENT_ARRAY_BUFFER_ARB, m_gl_index_buffer);
            GL.ARB.BufferData(GL.Enums.ARB_vertex_buffer_object.ELEMENT_ARRAY_BUFFER_ARB,
                t2 , m_indexes, GL.Enums.ARB_vertex_buffer_object.DYNAMIC_DRAW_ARB);
 
        }
        public override void GLDrawObject()
        {
            GL.ARB.BindBuffer(GL.Enums.ARB_vertex_buffer_object.ARRAY_BUFFER_ARB, m_gl_vertex_buffer);
            GL.ARB.BindBuffer(GL.Enums.ARB_vertex_buffer_object.ELEMENT_ARRAY_BUFFER_ARB, m_gl_index_buffer);
 
            GL.EnableClientState(GL.Enums.EnableCap.VERTEX_ARRAY);
            GL.VertexPointer(3, GL.Enums.VertexPointerType.FLOAT, 8 * sizeof(Single), 0);
            //GL.EnableClientState(GL.Enums.EnableCap.NORMAL_ARRAY);
            //GL.NormalPointer(GL.Enums.NormalPointerType.FLOAT, 8 * sizeof(Single), 3 * sizeof(Single));
            //GL.EnableClientState(GL.Enums.EnableCap.TEXTURE_COORD_ARRAY);
            //GL.TexCoordPointer(2, GL.Enums.TexCoordPointerType.FLOAT, 8 * sizeof(Single), 6 * sizeof(Single));
 
 
            GL.DrawElements(GL.Enums.BeginMode.TRIANGLES, m_indexes.Length, GL.Enums.All.INT, 0);
 
            GL.DisableClientState(GL.Enums.EnableCap.TEXTURE_COORD_ARRAY);
            GL.DisableClientState(GL.Enums.EnableCap.NORMAL_ARRAY);
            GL.DisableClientState(GL.Enums.EnableCap.VERTEX_ARRAY);
         }

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler.'s picture

Is the destruction taking place in the finalizer?

        ~CIndexedTrianglesMesh()
        {
            // Dangerous code: may run after the destruction of the OpenGL context.
            // GL.DeleteBuffers(1, ref m_gl_index_buffer);
            // GL.DeleteBuffers(1, ref m_gl_vertex_buffer);
        }

If yes, there is no guarantee regarding when this code will run - it probably runs after the OpenGL render context has been destroyed, thus the crash. To make this work, you will need to implement the Disposable pattern and ensure that the buffers are only destroyed on manual disposal.

Axelill's picture

Thanks for you quick answer,

I'll implement the IDispose interface.

but the problem is that it draws nothing. If I use a glbegin it draws but not with vbo implemenation.

anything wrong in my code ?

Axel.

the Fiddler's picture

Oh, I thought the drawing worked. I was having some difficulties with VBO's not drawing yesterday which I haven't completely solved yet - if I use just a vertex buffer it works, but add a color buffer and it crashes. Vertex arrays/immediate mode work correctly, which might mean there is a bug lurking in the VBO functions (your code looks correct).

I'm still trying to find out what's wrong. Do you get any other crashes, in the GL.DrawElements call for example? Also, what OS and which OpenTK version are you using? This will help narrow down the problem.

Axelill's picture

I use vista x64 with opentk version 0.3.12.
There is no crash when I run the application. It just runs all the functions but draws nothing.

Even when I disable the color and normal array and enable just the vertex array it does not work (apparently it works for you).

I've tried to not create a Element_array_buffer et draws with

GL.DrawElements(GL.Enums.BeginMode.TRIANGLES, m_indexes.Length, GL.Enums.All.INT, m_indexes);

without success too.

Axelill's picture

do you think the reason is the x64 platform I use.

Problem with size of array because of the different sizeof with platform.

I use mainly safe data type but you never know.

the Fiddler's picture

Ok, can you try to change GL.Enums.All.INT to GL.Enums.All.UNSIGNED_INT? i.e:

GL.DrawElements(GL.Enums.BeginMode.TRIANGLES, m_indexes.Length, GL.Enums.All.UNSIGNED_INT, m_indexes);

For some strange reason, using INT seems to break the rendering.

the Fiddler's picture

No, I don't think that's the issue. I do my developing on 64-bit platforms, too (Linux and Vista), and I haven't had any problems with that. Although, now that I think of it, 32-bit to 64-bit cast with sign extension may be the reason INT breaks while UNSIGNED_INT works (see post above)!

Axelill's picture

I've tried Unsigned_int and it does the same : no drawing.

Axelill's picture

even worst now. It does not respond. It says like my video driver is not responding. ;)

the Fiddler's picture

Oops! Ok, I wrote a small application that works here, download and see if it works on your PC.

However, I think I found the culprit: instead of specifying 0 to the GL.VertexPointer function, you'll have to use (void*)0. The same holds for GL.DrawElements.

This is a genuine bug (the need for unsafe code), which is fixed in the current svn. Try and see if it works!