1
votes

I'm working on a simple GUI for my application on OpenGL and all I need is to draw a bunch of rectangles and a 1px border arround them. Instead of going with glBegin and glEnd for each widget that has to draw (which can reduce performance). I need to know if this can be done with some sort of arrays/lists (batch data) of coordinates and their color.

Requirements:

  • Rectangles are simple filled with one color for every corner or each corner with a color. (mainly to form gradients)
  • Lines/borders are simple with one color and 1px thick, but they may not always closed (do not form a loop).
  • Use of textures/images is excluded. Only geometry data.
  • Must be compatible with older OpenGL versions (down to version 1.3)

Is there a way to achieve this with some sort of arrays and not glBegin and glEnd? I'm not sure how to do this for lines/borders.

I've seen this kind of implementation in Gwen GUI but it uses textures.

Example: jQuery EasyUI Metro Theme

1
You might look into vertex buffer objects. This is the type of batch drawing you talk about. Though I would be surprised if you were too slow to draw a few rectangles in a gui, even if it is immediate mode.BWG
Thanks :) Right now I'm looking into glVertexPointer(), glPolygonMode() and glColorPointer() to see if that can solve anything. But I'm guessing that glBegin and glEnd will still be the preferred option. The GUI elements are somewhat dynamic and VBO's might not be the best solution as v.oddou's answer also suggests.SLC

1 Answers

1
votes

In any case in modern OpenGL you should restrain to use old fashion API calls like glBegin and the likes. You should use the purer approach that has been introduced with core contexts from OpenGL 3.0. The philosophy behind it is to become much closer to actual way of modern hardware functionning. DiretX10 took this approach, somehow OpenGL ES also.

It means no more lists, no more immediate mode, no more glVertex or glTexCoord. In any case the drivers were already constructing VBOs behind this API because the hardware only understands that. So the OpenGL core "initiative" is to reduce OpenGL implementation complexity in order to let the vendors focus on hardware and stop producing bad drivers with buggy support.

Considering that, you should go with VBO, so you make an interleaved or multiple separated buffer data to store positions and color information, then you bind to attributes and use a shader combination to render the whole. The attributes you declare in the vertex shader are the attributes you bound using glBindVertexBuffer.

good explanation here:
http://www.opengl.org/wiki/Vertex_Specification

The recommended way is then to make one vertex buffer for the whole GUI and every element should just be put one after another in the buffer, then you can render your whole GUI in one draw call. This is how you will get the best performance.

Then if your GUI has dynamic elements this is no longer possible exept if using glUpdateBufferSubData or the likes but it has complex performance implications. You are better to cut your vertex buffer in as many buffers that are necessary to compose the independent parts, then you can render with uniforms modified between each draw call at will to configure the change of looks that is necessary in the dynamic part.