3
\$\begingroup\$

I am trying to experimenting drawing method using VBO in OpenGL. Many people normally use 1 vbo to store one object data array. I was trying to do something quite opposite which is storing multiple object data into 1 vbo then drawing it. There is story behind why i want to do this. I want to group many of objects as a single object sometime. However my code doesn't do the justice. Following is my pseudo code:

//Data
int[] _vBO = new int[1]; //vertex buffer objects

_triangleVertices = new float[] 
                  { 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, //first triangle lineloop, positions in the middle of the screen.
                    3.0f, 1.0f, 0.0f, 2.0f, -1.0f, 0.0f, 4.0f, -1.0f, 0.0f, //second triangle lineloop, positions on the left side of the first triangle.
                    -3.0f, 1.0f, 0.0f, -4.0f, -1.0f, 0.0f, -2.0f, -1.0f, 0.0f  }; //third triangle lineloop, positions on the right side of the first triangle.

//Setting Up
void init()
{
   GL.GenBuffers(1, _vBO);
   GL.BindBuffer(BufferTarget.ArrayBuffer, _vBO[0]);
   GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * _triangleVertices.Length), _triangleVertices, BufferUsageHint.StaticDraw);
   GL.VertexPointer(3, VertexPointerType.Float, 0, 0);
   GL.EnableClientState(Array.VertexArray);
}

//Drawing
void display()
{
    GL.Clear(ClearBufferMask.ColorBufferBit);
    GL.Clear(ClearBufferMask.DepthBufferBit);

    //setting up camera and projection.
    float[] eyes = { 0.0f, 0.0f, -10.0f };
    float[] target = { 0.0f, 0.0f, 0.0f };
    Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(0.785398163f, 4.0f / 3.0f, 0.1f, 100f);  //45 degree = 0.785398163 rads
    Matrix4 view = Matrix4.LookAt(eyes[0], eyes[1], eyes[2], target[0], target[1], target[2], 0, 1, 0);
    Matrix4 model = Matrix4.Identity;
    Matrix4 MV = view * model;

    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadIdentity();
    GL.LoadMatrix(ref projection);

    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadIdentity();
    GL.LoadMatrix(ref MV);


    GL.Viewport(0, 0, glControlWindow.Width, glControlWindow.Height);
    GL.Enable(EnableCap.DepthTest); //Enable correct Z Drawings
    GL.DepthFunc(DepthFunction.Less); //Enable correct Z Drawings
    GL.MatrixMode(MatrixMode.Modelview);

    //Draw
    drawTriangleLineLoops();


    //Finally...
    GraphicsContext.CurrentContext.VSync = true; //Caps frame rate as to not over run GPU
    glControlWindow.SwapBuffers(); //Takes from the 'GL' and puts into control
}


void drawTriangleLineLoops()
{
   GL.BindBuffer(BufferTarget.ArrayBuffer, _vBO[0]);
   GL.VertexPointer(3, VertexPointerType.Float, 0, 0);
   GL.EnableClientState(ArrayCap.VertexArray);
   GL.DrawArrays(BeginMode.LineLoop, 0, 3); //drawing first triangle lineloop, first vertex starts at index 0.
   GL.DrawArrays(BeginMode.LineLoop, 9, 3); //drawing second triangle lineloop, first vertex starts at index 9.
   GL.DrawArrays(BeginMode.LineLoop, 18, 3); //drawing third triangle lineloop, first vertex starts at index 18.
   GL.DisableClientState(ArrayCap.VertexArray);
}    

I expect 3 different triangles to be drawn, but only one was drawn. I don't know what went wrong.

Line Loop Error

\$\endgroup\$
8
  • \$\begingroup\$ What is wrong? Is it not drawing anything? Have you checked for error codes from the GL calls? Is the output visible but mangled/incorrect? On a side note, you really should use 32-bit floats rather than 64-bit doubles for vertex data; only relatively newer hardware even supports doubles natively (drivers have to do inefficient conversion work for older hardware), and even on newer hardware it's simply slower to operate on doubles than on single-precision floats. \$\endgroup\$ – Sean Middleditch Oct 21 '13 at 21:36
  • \$\begingroup\$ What version of OpenGL you use? I don't remember correctly but atributes as doubles are supported from OpenGL 4.0 .You can stick with floats, because doubles give a very big overhead when are used. \$\endgroup\$ – Anastasios G Oct 22 '13 at 9:30
  • \$\begingroup\$ @SeanMiddleditch: It did the drawing but did not draw line loops correctly. I already inspected the line loop data, nothing wrong with the data. \$\endgroup\$ – stoney78us Oct 22 '13 at 20:48
  • \$\begingroup\$ @stoney78us: "did not draw correctly" is practically meaningless. Post a picture or something. Nobody here has any idea what you think your line loops are supposed to look like or what "incorrect" output you're seeing. \$\endgroup\$ – Sean Middleditch Oct 22 '13 at 21:11
  • \$\begingroup\$ @SeanMiddleditch: Sorry for the confusion, It has been really hard for me to describe how it looks like. My program practically reads in shape files (*.shp) which contains information about coordinates of some geometries then draw these geometries to the OpenGL window (in my case, these shape files contain only polygon geometry information). The attached photo is an example when i try to draw 5 polygons. Images: link \$\endgroup\$ – stoney78us Oct 22 '13 at 22:33
2
\$\begingroup\$

You are offsetting twice, you are specifying the line loop offset in the call to VertexPointer, then again in DrawArrays. DrawArrays starts drawing from the index specified in the second parameter.

The following calls should be enough:

GL.VertexPointer(3, VertexPointerType.Double, 0, lineloop1offset); //starting from the beginning of the array
GL.DrawArrays(BeginMode.LineLoop, lineloop1offset , lineloop1VertexNum  );
GL.DrawArrays(BeginMode.LineLoop, lineloop2offset , lineloop2VertexNum );
GL.DrawArrays(BeginMode.LineLoop, lineloop3offset , lineloop3VertexNum );
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for answer, but my problem still exists. This is really driving me crazy !! \$\endgroup\$ – stoney78us Oct 23 '13 at 17:31
  • \$\begingroup\$ It somehow still connects points of two different lineloops even though I already separated them from different DrawArrays calls. \$\endgroup\$ – stoney78us Oct 23 '13 at 17:44
0
\$\begingroup\$

The answer is:

GL.DrawArrays(BeginMode.LineLoop, 0, 3); 
GL.DrawArrays(BeginMode.LineLoop, 3, 3); 
GL.DrawArrays(BeginMode.LineLoop, 6, 3);

I guess the enable vertex array treats an element as a memory junk of whatever size you defined a vertex array with GL.VertexPointer coordinate for a vertex.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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