6
\$\begingroup\$

I want to draw a quad (not two triangles). I actually know that triangles are faster, as I answered this question.

But let's say I am building a 3D modeling tool. It makes sense to draw a quad for the user (like Maya and 3D Max do) and not two triangles especially if he is actually working with quads. Is there any other option than using geometry shaders to accomplish this?

I understand that I can draw two triangles and make them co-planer. Unfortunately this will still make the two diagonal points connected, I don't want this. I want a pure quad. I don't want the line connecting the two points, Exactly like what you see in a modeling tool. I am actually rewriting a modeling tool that I wrote few years ago, and can't get the same behavior I got with the older OpenGL.

Here is an image of the tool I am re-writing using modern OpenGL. I used QUADS, so the question is about an alternative that gives this same behaviour especially I am using two pass rendering to render the model and it's outline. That's why I don't want the line separating the two triangles to appear.

enter image description here

\$\endgroup\$
4
\$\begingroup\$

You cannot do this with the out-of-the-box functionality provided by your GPU. The GPU only understands triangles. No amount of tweaking API configuration, clever use of degenerate triangles, or geometry shaders will change that fact.

If you want to render an collection of outlined quads, as is often done in 3D modeling programs that support quad-based modeling paradigms, you will have to build on top of the basic functionality of your graphics API to do it. This will require, to some extent, modifying or augmenting the data structure you use to store your mesh.

If you are only interested in the basic outline rendering of all quads, and your meshes are all composed of quads that are uniformly constructed from triangles (as is typical), you could simply utilize a rendering pass that rendered line strips using the four vertices of the quad.

B----C  fig 1                      B----C  fig 2
|   /|  {ABCD} form a quad for     |    |  {ABCD} form a quad for outline
|  / |  rendering as a pair        |    |  rendering as a line strip of
| /  |  of triangles {ABC} and     |    |  {A, B, C, D, A}.
|/   |  {ACD}.                     |    |
A----D                             A----D

If you wanted to do more interesting things, however, such as thicker rendering of lines or saner interaction with the depth buffer, you would probably want to construct a more complex data structure that understands what the edges of a quad are, and whether those edges are interior edges (like AC, above) or exterior edges (the ones you want to render).

You can then render these edges using any existing "thick line" rendering technique suitable for your graphics API (which itself often involves rendering the "lines" as oriented quads-formed-by-triangles, but in this case you'd be working one level of abstraction above that).

Hardware feature edge detection is a topic you'd probably want to look into if the latter options sounds appealing.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks, I think that's what am looking for. I don't even need geometry shader (which I thought I need at first), and the idea of thick line rendering is appealing. Also hardware edge detection is nice especially for CAD renderings. \$\endgroup\$ – concept3d Dec 7 '13 at 23:36
2
\$\begingroup\$

Modern OpenGL defines only points, lines or triangles; there are no 4-vertex primitive types, so you can't draw a quad without triangles.

Using a Geometry Shader won't even allow this as the only valid outputs are points, line-strip or triangle-strip; there's no quad output.

You can emulate a quad with a triangle strip (using the 4th vertex to complete the quad), and if you want to draw multiple quads in a single batch, use primitive restart to handle that.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Fair enough, my problem is that I don't want the separating line to appear. check my edited question. \$\endgroup\$ – concept3d Dec 7 '13 at 23:27
  • 1
    \$\begingroup\$ @concept3d - I've added "in wireframe" to your question title just for totally unambiguous clarity. \$\endgroup\$ – Maximus Minimus Dec 7 '13 at 23:42
2
\$\begingroup\$

It's all just perspective. The hardware only operates on triangles. It renders what you give it to render: If you want to create quads, you simply need to make sure that all four vertices shared by each such pair of triangles, are co-planar. Then any normals-based lighting algorithm running on the hardware is going to render them as a single, uniformly-shaded, seamless quad.

So create the vertices co-planar on the CPU, and the GPU will handle the rest.

P.S. You can use an older version of OpenGL + GL_QUADS if you really want to, but you're just going to force the GPU to break them down into triangles, anyway. That's why they deprecated this option.

EDIT I'm not sure which version of OpenGL you were previously using, but if any up to 3.0, the problem may be that you had GL_QUADS support before, and perhaps don't now (as you may be using 3.1 or higher)... if I understand this answer correctly, you can achieve the effect using GL_LINES with GL_QUADS. Could that be why you had it working previously? Older OpenGL version? A compatibility context may help you, if you're presently using 3.1+.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Yes I understand this, unfortuanately this will still make the two diagonal points connected, I don't want this. I want a pure quad. I don't want the line connecting the two points. Exactly like what you see in a modeling tool. actually I am rewriting one that I wrote few years ago, and can't get the same behavior. \$\endgroup\$ – concept3d Dec 7 '13 at 23:08
  • \$\begingroup\$ @concept3d GPUs don't support quad-based rendering. This is a hardware limitation -- you'll just have to live with it! \$\endgroup\$ – Engineer Dec 7 '13 at 23:10
  • 1
    \$\begingroup\$ You can easily render the two triangles that make up a quad in such a way as to not render that dividing line. That's exactly what modeling software would do. \$\endgroup\$ – user1430 Dec 7 '13 at 23:10
  • \$\begingroup\$ Josh is quite right, I thought this was obvious from my answer. If you render these as two meshes, you may well see a seam. But uploading 4 vertices and creating 2 triangle-faces from that, will result in a seamless surface -- every time. And making these coplanar will make them utterly seamless in terms of colour. The fragment renderer (in hardware) is designed never to produce seams in this instance. \$\endgroup\$ – Engineer Dec 7 '13 at 23:11
  • \$\begingroup\$ @JoshPetrie check my edited question. With my current two pass appraoch this doesn't work. Because the line will still appear in my mesh outline pass, so my question is about a work around. \$\endgroup\$ – concept3d Dec 7 '13 at 23:16

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.