Simple OpenGL Clarification - opengl

Does version OpenGL 3+ only uses "GL_TRIANGLES" ?
That's what I read, but in the documentation for OpenGL 3.3, http://www.opengl.org/sdk/docs/man3/, "glDrawArrays()" takes the following parameters:
GL_POINTS,
GL_LINE_STRIP,
GL_LINE_LOOP,
GL_LINES,
GL_LINE_STRIP_ADJACENCY,
GL_LINES_ADJACENCY,
GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN,
GL_TRIANGLES,
GL_TRIANGLE_STRIP_ADJACENCY,
GL_TRIANGLES_ADJACENCY

Does version OpenGL 3+ only uses "GL_TRIANGLES"
You mean "instead of also offering GL_QUADS and GL_POLYGON"?
Yes indeed. Quads and Polygons have been removed altogether. Most polygons needed to be tesselated into triangles anyway, since OpenGL can deal with convex polygons only (convex also imples planar!). Similar holds for quads.
Lines and points remain to be supported of course.

Does version OpenGL 3+ only uses "GL_TRIANGLES" ?? That's what I read
Where? Please provide a link.
There is a difference between "GL_TRIANGLES" and "triangles".
GL_TRIANGLES is a specific primitive type. It has a specific interpretation. It's base primitive type is "triangles" (as in, it generates triangles), but there's more to it than that.
"triangles" are exactly that: assemblages of 3 vertices that represent a planar area. GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_TRIANGLE_FAN produce triangles.
OpenGL 3.1+ core does not allow the use of the specific primitive types GL_QUADS, GL_QUAD_STRIP (ie: all "quad" types), and GL_POLYGON. Everything else is fair game.

According to section 2.6.1 of the specification commands like glDrawArrays() accept the primitives you posted. So, no, OpenGL 3.3 doesn't accept just GL_TRIANGLES.
What you read was probably meant to explain that OpenGL doesn't support primitives like GL_QUADS and GL_POLYGON anymore.
Quad and polygon primitives have been removed according to appendix E.2.2 of the specification (since version 3.1, prior versions still support them, although they're deprecated from version 3.0).
You can find the specification here.

Related

How can I use glut primitives with glfw3?

I'm learning about OpenGL graphics and the demonstrator has given us glut; however, it doesn't satisfy the needs of the project.
So, I want to move on to glfw3 but am having an issue with the primitives like, GL_TRIANGLES, GL_TRIANGLE_FAN, GL_LINE_LOOP, etc.
How can I use the primitives to draw polygons and lines using glfw3?

What are acceptable glPolygonMode first-argument values?

The documentation for glPolygonMode only specifies the enum GL_FRONT_AND_BACK as an acceptable first parameter (face). Are there other acceptable enums, such as only the front, or only the back?
glPolygonMode(GLenum face, GLenum mode);
I know that mode only supports GL_POINT, GL_LINE, and GL_FILL, but it just seems extremely strange that the only one the documentation specifies for face is GL_FRONT_AND_BACK, but it's a requirement to use it as an argument.
glPolygonMode accepted different parameters for the face in legacy OpenGL contexts. If you look at the Khronos man page for it for OpenGL 2.1, it says:
face Specifies the polygons that mode applies to. Must be GL_FRONT for
front-facing polygons, GL_BACK for back-facing polygons, or
GL_FRONT_AND_BACK for front- and back-facing polygons.
Conversely, in the OpenGL 4 man page, it says:
face Specifies the polygons that mode applies to. Must be
GL_FRONT_AND_BACK for front- and back-facing polygons.
In the OpenGL 3.3 spec, in the section 'E2. Deprecated and Removed Features', it lists:
Separate polygon draw mode - PolygonMode face values of FRONT and
BACK; polygons are always drawn in the same mode, no matter which face
is being rasterized.
Likely, the face parameter was just retained for compilation equivalence for different OpenGL context targets, even though in modern OpenGL, it can really only have one value, and is now redundant.

glDrawElements draw polygon

I have read that the first parameter of the glDrawElements is mode:
http://www.opengl.org/sdk/docs/man3/xhtml/glDrawElements.xml
Symbolic constants GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_LINE_STRIP_ADJACENCY, GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP_ADJACENCY and GL_TRIANGLES_ADJACENCY are accepted.
I do not see there GL_POLYGON. Is that means that I can not use GL_POLYGON? and if I got 10 indices? Am I need to transform it to a few polygons which contains 3 indices each one? If it is true, How do I do it?
The GL3 and GL4 level man pages on www.opengl.org only document the Core Profile of OpenGL. GL_POLYGON is deprecated, and was not part of the Core Profile when the spec was split into Core and Compatibility profiles in OpenGL 3.2.
You can still use GL_POLYGON if you create a context that supports the Compatibility Profile. But if you start out, I would suggest that you stick to Core Profile features. If you do need documentation for the deprecated features, you'll have to go back to the GL2 man pages.
To draw a polygon, GL_TRIANGLE_FAN is the easiest replacement. You can use the same set of vertices for a triangle fan as you would use for GL_POLYGON, and it will produce the same result.
You are linking to the GL3 manual pages, by the way.
Since GL_POLYGON was deprecated in 3.0 and removed in 3.1, you are not going to find it listed there. In fact, you will find some tokens there that are only supported in GL 3.2 (adjacency primitives, which were introduced when Geometry Shaders were); fortunately that is actually documented in the manual page itself unlike the fact that GL_POLYGON was deprecated.
For compatibility profiles (which you are using), you should view the GL2 manual page. The GL2 man page can be found here.

What about NURBS and opengl 4.2 core?

NURBS chapter in RedBook is denoted deprecated, including utility library: "Even though
some of this functionality is part of the GLU library, it relies on
functionality that has been removed from the core OpenGL library."
Does it mean OpenGL 4.2 actually lacks C++ toolkit for manipulating NURBS curves and surfaces? There are some commercial 3rd party toolkits, but they're not crossplatform ( windows, mainly )
...?
In OpenGL-3 and later you've got geometry, and vertex shaders at your disposal, OpenGL-4 even provides tesselation shaders. They offer everything to implement GPU accelerated NURBS and Bezier splines and surfaces. The evaluators of OpenGL-1.1 never were GPU accelerated on most hardware. So actually you're better off without them.
Just implement NURBS or Bezier evaluators in the shaders and send in vertices as surface sampling points.
With respect to your question regarding the Red Book, the GLU library wasn't officially deprecated by the OpenGL ARB, rather just ignored. However, GLU used features that were deprecated in OpenGL 3.0, and removed in OpenGL 3.1: immediate-mode rendering, display lists, matrix stacks, to name a few. Specific to NURBS, they used several of those features (assuming the GLU library associated with your OpenGL implementation was based on the SGI version of GLU, which most were), and so features just won't work in a core context. It's not the lack of the C++-based GLU library, as much as GLU used features removed from modern OpenGL.
#datenwolf - not quite. The GLU NURBS library supported trimming curves, which are challenging to implement in all cases using the OpenGL vertex shader pipeline (i.e., vertex, tessellation, and geometry shading only). Specifically, support for winding rules and correct trimming while respecting trim-curve crossings is pretty darned tough (it may be possible with a combination of compute shaders and fancy work in a fragment shader). You could hack trimming using an alpha texture, but you'd suffer aliasing results, but it's a quick fix.

glEnableClientState with modern OpenGL (glVertexAttribPointer etc)

I'd like to lay out some things I think I've learned, but am unsure about:
VBOs are the way to go. They're created with glGenBuffers and glBufferData.
For maximum flexibility, it's best to pass generic vertex attributes to shaders with glVertexAttribPointer, rather than glVertex, glNormal, etc..
glDrawElements can be used with vertex buffers and an index buffer to efficiently render geometry with lots of shared vertices, such as a landscape mesh.
Assuming all of that is correct so far, here's my question. All of the tutorials I've read about modern OpenGL completely omit glEnableClientState. But the OpenGL man pages say that without glEnableClientState, glDrawElements will do nothing:
http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml
The key passage is: "If GL_VERTEX_ARRAY is not enabled, no geometric primitives are constructed."
This leads me to the following questions:
None of the tutorials use glEnableClientState before calling glDrawElements. Does this mean the man page is wrong or outdated?
GL_VERTEX_ARRAY would seem to be the thing you enable if you're going to use glVertexPointer, and likewise you'd use GL_NORMAL_ARRAY with glNormalPointer, and so on. But if I'm not using those functions, and am instead using generic vertex attributes with glVertexAttribPointer, then why would it be necessary to enable GL_VERTEX_ARRAY?
If GL_VERTEX_ARRAY is not enabled, no geometric primitives are constructed.
That's because the man page is wrong. The man page covers GL 2.1 (and it's still wrong for that), and for whatever reason, the people updating the man page refuse to update the older GL versions for bug fixes.
In GL 2.1, you must use either generic attribute index 0 or GL_VERTEX_ARRAY. In GL 3.1+, you don't need to use any specific attribute indices.
This is because, in GL versions before 3.1, all array rendering functions were defined in terms of calls to glArrayElement, which used immediate mode-based rendering. That means that you need something to provoke the vertex. Recall that, in immediate mode, calling glVertex*() not only sets the vertex position, it also causes the vertex to be sent with the other attributes. Calling glVertexAttrib*(0, ...) does the same thing. That's why older versions require you to use either attribute 0 or GL_VERTEX_ARRAY.
In GL 3.1+, once they took out immediate mode, they had to specify array rendering differently. And because of that, they didn't have to limit themselves to using attribute 0.
If you want API docs for core GL 3.3 works, I suggest you look at the actual API docs for core GL 3.3. Though to be honest, I'd just look at the spec if you want accurate information. Those docs have a lot of misinformation in them. And since they're not actually wiki-pages, that information never gets corrected.
Your first 3 points are correct. And to answer your last half of your question, do not use glEnableClientState for modern OpenGL. Start coding!
VBOS are the way to go. They're created with glGenBuffers and
glBufferData.
VBOs are often used in high-performance applications. You might want to do something simpler first. Vertex arrays can be a good way to go to get started quickly. Because VBOs sit on top of vertex arrays anyway, you'll be using much of the same code when you switch to VBOs, and it might be good to run a test using vertex arrays or indexed vertex arrays first.
For maximum flexibility, it's best to pass generic vertex attributes
to shaders with glVertexAttribPointer, rather than glVertex, glNormal,
etc..
That's a good approach.
glDrawElements can be used with vertex buffers and an index buffer to
efficiently render geometry with lots of shared vertices, such as a
landscape mesh.
Perhaps. You have to be sure the vertices truly are shared, though. A vertex that is in the same location but has a different normal (e.g. for flat shading) isn't truly shared.