8 Replies Latest reply on May 16, 2016 12:20 PM by Wissal Wissal

    Using OpenGL with VBO's in SolidWorks problem

    Tony Van De Velde

      Hi,

       

      I've been trying to draw some custom 3D objects in SolidWorks using OpenGL. This works when I use the immediate mode in OpenGL.

      However, I want to use Vertex Buffer Objects (VBO). I am using the OpenTK library for the OpenGL programming.

      I create and load the data in the VBO's and immediately check if everything is ok, which is the case. Then on the OnBufferSwapNotify event handler I call a method to draw the objects using the VBO's. Using the VBOID's I obtained in the previous method, I check again the data in the buffer and see that the values are changed.

      Further examination learns me that the data now in the buffer is from SolidWorks and represents pieces of a component already in the assembly which I use for testing.

      What can be wrong? How can I make sure that my buffer memory on the graphics card is preserved and overwritten by SolidWorks?

       

      Here's a short code example of what I'm doing...

       

      First the method which creates the VBO's.

       

      public override void CreateAndFillVertexBuffer()

      {

          if (m_Vertices == null && m_Indices == null)

              CreateVBOArrays(); // Creates the m_Vertices and m_Indices arrays.

       

          VBOID = new uint[2];

          GL.GenBuffers(2, VBOID); // first buffer for VertexData, second for indices to vertices.

       

          // Bind the buffers and fill them with data...

          GL.BindBuffer(BufferTarget.ArrayBuffer, VBOID[0]);

          GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (m_Vertices.Length * 3 * Vector3.SizeInBytes), m_Vertices, BufferUsageHint.StaticDraw);

          // Validate that the buffer is the correct size

          int bufferSize;

          GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);

          if (m_Vertices.Length * 3 * Vector3.SizeInBytes != bufferSize)

              throw new ApplicationException("Element array not uploaded correctly");

       

       

          // Test to check if buffer data is correct, not needed in final program. DATA IS OK RIGHT AFTER CREATION OF BUFFER.

          IntPtr ptrToBuffer = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.ReadOnly);

          if (ptrToBuffer != IntPtr.Zero)

          {

              VertexData[] tmpData = null;

              float[] destination = new float[m_Vertices.Count() * 3];

              Marshal.Copy(ptrToBuffer, destination, 0, m_Vertices.Count() * 3);

       

              GL.UnmapBuffer(BufferTarget.ArrayBuffer);

          }

          GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

         

          GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOID[1]);

          GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(m_Indices.Length * sizeof(uint)), m_Indices, BufferUsageHint.StaticDraw);

          // Validate that the buffer is the correct size

          GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out bufferSize);

          if (m_Indices.Length * sizeof(uint) != bufferSize)

              throw new ApplicationException("Element array not uploaded correctly");

          GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

      }

       

      Then the method which draws the objects using the VBO's which is called in the ModelView.OnBufferSwapNotify event handler.

       

      public override void Draw()

      {

           if (UsesVBO)

          {

              int[] polyMode = new int[1];

              GL.GetInteger(GetPName.PolygonMode, polyMode);

              AutoColor color = new AutoColor(m_Color);

              GL.EnableClientState(EnableCap.VertexArray);

              GL.BindBuffer(BufferTarget.ArrayBuffer, VBOID[0]);

       

              // Test to check if buffer data is correct, not needed in final program. ERROR: DATA HAS BEEN OVERWRITTEN WITH VALUES FROM SOLIDWORKS!!!

              IntPtr ptrToBuffer = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.ReadOnly);

              if (ptrToBuffer != IntPtr.Zero)

              {

                  VertexData[] tmpData = null;

                  float[] destination = new float[m_Vertices.Count() * 3];

                  Marshal.Copy(ptrToBuffer, destination, 0, m_Vertices.Count() * 3);

       

                  GL.UnmapBuffer(BufferTarget.ArrayBuffer);

              }

              GL.VertexPointer(3, VertexPointerType.Float, 3 * Vector3.SizeInBytes, IntPtr.Zero);

       


              GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOID[1]);

              GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);

              GL.DrawElements(BeginMode.Triangles, m_Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);

       

       

              AutoPointSize psize = new AutoPointSize((float)5.0);

              AutoColor color2 = new AutoColor(Color.Black);

              GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);

              GL.DrawElements(BeginMode.Triangles, m_Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);

              GL.DrawElements(BeginMode.Points, VertexCount, DrawElementsType.UnsignedInt, IntPtr.Zero);

       

              AutoColor color3 = new AutoColor(Color.Blue);

              GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Point);

              GL.DrawElements(BeginMode.Triangles, m_Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);

       

              GL.DisableClientState(EnableCap.VertexArray);

              GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

              GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

              GL.PolygonMode(MaterialFace.FrontAndBack, (PolygonMode)polyMode[0]);

          }

      }

       

      I really hope someone can help me. I have already spent days of debugging and researching this behavior without result unfortunately.

       

      Kind regards,

      Tony