https://www.khronos.org/opengl/wiki_opengl/api.php?action=feedcontributions&user=WilliamKappler&feedformat=atomOpenGL Wiki - User contributions [en]2021-09-17T10:42:03ZUser contributionsMediaWiki 1.35.1https://www.khronos.org/opengl/wiki_opengl/index.php?title=Primitive&diff=14147Primitive2017-12-31T04:25:12Z<p>WilliamKappler: The enumeration for patches is GL_PATCHES not GL_PATCH.</p>
<hr />
<div>{{pipeline float}}<br />
<br />
The term '''Primitive''' in OpenGL is used to refer to two similar but separate concepts. The first is the interpretive scheme used by OpenGL to determine what a stream of vertices represents when being rendered. Such sequences of vertices can be arbitrarily long.<br />
<br />
The other meaning of "Primitive" is as the ''result'' of the interpretation of a vertex stream, as part of [[Primitive Assembly]]. Therefore, processing a vertex stream by one of these primitive interpretations results in an ordered sequence of primitives. The individual primitives are sometimes called "base primitives".<br />
<br />
== Vertex stream ==<br />
{{main|Vertex Specification}}<br />
<br />
A vertex stream is an ordered list of vertices. Where this stream comes from depends on when [[Primitive Assembly]] is taking place and which stages of the rendering pipeline are involved. Vertex streams can come from:<br />
<br />
* [[Vertex Rendering]] commands, defined via [[Vertex Specification]] and processed by a [[Vertex Shader]]. The primitive type is the type specified by the rendering command.<br />
* [[Tessellation]], after the execution of the [[Tessellation Evaluation Shader]]. The primitive type is defined by the [[Tessellation#Abstract_patch|abstract patch type]], specified in the TES.<br />
* [[Geometry Shader]] primitive outputs. The primitive type is [[Geometry_Shader#Primitive_in.2Fout_specification|specified by the GS]].<br />
<br />
The primitive associated with the stream defines how that stream is broken down into an ordered sequence of base primitives: points, lines, or triangles.<br />
<br />
== Point primitives ==<br />
<br />
There is only one kind of point primitive: {{enum|GL_POINTS}}. This will cause OpenGL to interpret each individual vertex in the stream as a point. Points that have a [[Texture]] mapped onto them are often called "point sprites".<br />
<br />
Points are rasterized as screen-aligned squares of a given window-space size. The size can be given in two methods: by the [[Vertex Processing|last active vertex processing shader stage]] or by the context's state. To set the point size from a shader, enable the {{enumapifunc|glEnable|(GL_PROGRAM_POINT_SIZE)}} to set the point size from the program. If {{enum|GL_PROGRAM_POINT_SIZE}} is enabled, then the point size comes from the output variable {{code|float gl_PointSize}}. If it is disabled, the point size is constant for all points in a primitive, and is set by the {{apifunc|glPointSize}} function.<br />
<br />
The size defines the number of window pixels that each side of the point's square takes up. The point's position defines the ''center'' of that square.<br />
<br />
Regardless of how the point size is defined, it must be greater than 0, or else undefined behavior results. There is an implementation-defined range for point sizes, and the size given by either method is clamped to that range. You can query the range with {{enum|GL_POINT_SIZE_RANGE}} (returns 2 floats). There is also a point granularity that you can query with {{enum|GL_POINT_SIZE_GRANULARITY}}; the implementation will clamp sizes to the nearest multiple of the granularity.<br />
<br />
=== Point fragment inputs ===<br />
<br />
Points are defined by only a single vertex. Therefore, every [[Fragment]] generated by rasterizing that point is given the same user-defined input values. However, it is useful to know exactly where within the point a particular [[Fragment Shader]] invocation is. While the specific position of the fragment, {{code|gl_FragCoord}} will change, per the fragment's location, it would be more useful to know where one is relative to the point primitive itself.<br />
<br />
To assist in this, the fragment shader can use the [[Fragment_Shader#System_inputs|built-in input]] {{code|vec2 gl_PointCoord}}. This gives coordinates on the range [0, 1]. The location of (0, 0) depends on the point parameter setting for {{enum|GL_POINT_SPRITE_COORD_ORIGIN}}: if it is set to {{enum|GL_LOWER_LEFT}}, then (0, 0) is the bottom-left coordinate. While if it is {{enum|GL_UPPER_LEFT}}, then (0, 0) is the top-left coordinate. The default is {{enum|GL_LOWER_LEFT}}, which fits with OpenGL's usual right-handed coordinate systems.<br />
<br />
=== Multisampling and fading ===<br />
{{todo}}<br />
<br />
When using [[Multisample]] rendering and drawing points, the [[Fragment Shader Output|fragment shader output]] variables can have their alphas adjusted to represent the point "fading" away.<br />
<br />
== Line primitives ==<br />
<br />
There are 3 kinds of line primitives, based on different interpretations of a vertex stream.<br />
<br />
* {{enum|GL_LINES}}: Vertices 0 and 1 are considered a line. Vertices 2 and 3 are considered a line. And so on. If the user specifies a non-even number of vertices, then the extra vertex is ignored.<br />
* {{enum|GL_LINE_STRIP}}: The adjacent vertices are considered lines. Thus, if you pass ''n'' vertices, you will get ''n''-1 lines. If the user only specifies 1 vertex, the drawing command is ignored.<br />
* {{enum|GL_LINE_LOOP}}: As line strips, except that the first and last vertices are also used as a line. Thus, you get ''n'' lines for ''n'' input vertices. If the user only specifies 1 vertex, the drawing command is ignored. The line between the first and last vertices happens after all of the previous lines in the sequence.<br />
<br />
=== Line width ===<br />
{{todo}}<br />
<br />
Lines are rasterized as a screen-aligned quad of uniform width.<br />
<br />
== Triangle primitives ==<br />
<br />
A triangle is a primitive formed by 3 vertices. It is the 2D shape with the smallest number of vertices, so renderers are typically designed to render them. Since it is created from only 3 vertices, it is also guaranteed to be planar.<br />
<br />
There are 3 kinds of triangle primitives, based again on different interpretations of the vertex stream:<br />
<br />
* {{enum|GL_TRIANGLES}}: Vertices 0, 1, and 2 form a triangle. Vertices 3, 4, and 5 form a triangle. And so on.<br />
* {{enum|GL_TRIANGLE_STRIP}}: Every group of 3 adjacent vertices forms a triangle. The [[Face Culling|face direction]] of the strip is determined by the winding of the first triangle. Each successive triangle will have its effective face order reversed, so the system compensates for that by testing it in the opposite way. A vertex stream of ''n'' length will generate ''n''-2 triangles.<br />
* {{enum|GL_TRIANGLE_FAN}}: The first vertex is always held fixed. From there on, every group of 2 adjacent vertices form a triangle with the first. So with a vertex stream, you get a list of triangles like so: (0, 1, 2) (0, 2, 3), (0, 3, 4), etc. A vertex stream of ''n'' length will generate ''n''-2 triangles.<br />
<br />
Any incomplete primitives will be ignored. For example, using {{enum|GL_TRIANGLES}} with a number of vertices not divisible by 3 will ignore the incomplete primitive at the end. Rendering with less than 3 vertices will result in nothing rendering.<br />
<br />
Here are some examples that can be more illustrative:<br />
<br />
{{enum|GL_TRIANGLES}}:<br />
Indices: 0 1 2 3 4 5 ...<br />
Triangles: {0 1 2}<br />
{3 4 5}<br />
<br />
{{enum|GL_TRIANGLE_STRIP}}:<br />
Indices: 0 1 2 3 4 5 ...<br />
Triangles: {0 1 2}<br />
{1 2 3} drawing order is (2 1 3) to maintain proper winding<br />
{2 3 4}<br />
{3 4 5} drawing order is (4 3 5) to maintain proper winding<br />
<br />
{{enum|GL_TRIANGLE_FAN}}:<br />
Indices: 0 1 2 3 4 5 ...<br />
Triangles: {0 1 2}<br />
{0} {2 3}<br />
{0} {3 4}<br />
{0} {4 5}<br />
<br />
=== Triangle facing ===<br />
<br />
The [[Winding Order]] determines the facing of a triangle. The triangle's facing can be used to [[Face Culling|cull faces based on whether it is the front or back face]]. Even if face culling is not used, the triangle's face can be used in [[Stencil Test]]s, and part of a [[Fragment]]'s data is a boolean value that says whether the fragment was generated from the front or back face of the triangle. This allows the [[Fragment Shader]] to do different processing based on the triangle's facing.<br />
<br />
Facing only matters for triangle primitive rasterization. All non-triangle primitive types are considered to rasterize the front face, and face culling only works on triangles.<br />
<br />
== Quads ==<br />
{{deprecated|section=}}<br />
<br />
A quad is a 4 vertex quadrilateral primitive. The four vertices are expected to be coplanar; failure to do so can lead to undefined results.<br />
<br />
A quad is typically rasterized as a pair of triangles. This is not defined by the GL spec, but it is allowed by it. This can lead to some artifacts due to how vertex/geometry shader outputs are interpolated over the 2 generated triangles.<br />
<br />
* {{enum|GL_QUADS}}: Vertices 0-3 form a quad, vertices 4-7 form another, and so on. The vertex stream must be a number of vertices divisible by 4 to work.<br />
* {{enum|GL_QUAD_STRIP}}: Similar to triangle strips, a quad strip uses adjacent edges to form the next quad. In the case of quads, the third and fourth vertices of one quad are used as the edge of the next quad. So vertices 0-3 are a quad, 2-5 are a quad, and so on. A vertex stream of ''n'' length will generate (''n'' - 2) / 2 quads. As with triangle strips, the winding order of quads is changed for every other quad.<br />
<br />
== Adjacency primitives ==<br />
{{todo}}<br />
<br />
These are special primitives that are expected to be used specifically with [[Geometry Shaders]] (GS). These primitives give the geometry shader more vertices to work with for each input primitive. Normally, when using any of the above primitives, the GS gets merely one of the base type. If you use a GS with a {{enum|GL_TRIANGLE_STRIP}}, each execution of the GS will only see the 3 vertices of one particular triangle. These special primitive modes allow the GS to access vertex data for adjacent triangles.<br />
<br />
== Patches ==<br />
{{main|Tessellation#Patches}}<br />
<br />
The {{enum|GL_PATCHES}} primitive type can only be used when [[Tessellation]] is active. It is a primitive with a user-defined number of vertices, which is then tessellated based on the [[Tessellation Control Shader|control]] and [[Tessellation Evaluation Shader|evaluation shaders]] into regular points, lines, or triangles, depending on the TES's settings.<br />
<br />
The number of vertices per patch is defined by calling {{apifunc|glPatchParameter|i}} with {{enum|GL_PATCH_VERTICES}} and some number of vertices, which must be less than {{enum|GL_MAX_PATCH_VERTICES}}. If the number of vertices in a patch is {{param|v}}, then the system will interpret every {{param|v}} vertices as a separate patch, much like {{enum|GL_LINES}} and {{enum|GL_TRIANGLES}}. So if you want strip-like behavior, you will need to use indices.<br />
<br />
As with other primitive types that take multiple values from the stream, incomplete patches are ignored. So if you render with a number of vertices not divisible by {{param|v}}, then those last vertices are ignored.<br />
<br />
== Provoking vertex ==<br />
<br />
One of the vertices in an output primitive is designated the "provoking vertex". This vertex has special meanings for the primitive. For example, when using [[Interpolation qualifier|flat-shading on output variables]], only outputs from the provoking vertex are used; every fragment generated by that primitive gets it's input from the output of the provoking vertex.<br />
<br />
Each primitive type defines which index in the vertex stream defines the provoking vertex for a particular output primitive. There is a way to change the provoking vertex convention (primarily for [[D3D Compatibility]]):<br />
<br />
void {{apifunc|glProvokingVertex}}(GLenum {{param|provokeMode}});<br />
<br />
{{param|provokeMode}} can be one of the two enumerators listed in the following table; the default is {{enum|GL_LAST_VERTEX_CONVENTION}}. This table defines which vertex index (using '''one-based indices''') is the provoking vertex for a particular primitive type. The {{param|i}} represents the '''one-based index''' of the primitive being drawn. For example, if you draw {{enum|GL_TRIANGLE_FANS}} with 5 vertices, that will yield 3 primitives, so {{param|i}} will range over [1, 3]. Thus, when using last vertex conventions, the provoking vertex of primitive index 2 will be the vertex index 4 (the zero-based index for the vertex is 3).<br />
<br />
'''Again, this table uses ''one-based indices''.'''<br />
<br />
{| class="wikitable"<br />
! Primitive type<br />
! {{enum|GL_FIRST_VERTEX_CONVENTION}}<br />
! {{enum|GL_LAST_VERTEX_CONVENTION}}<br />
|-<br />
| {{enum|GL_POINTS}}<br />
| {{param|i}}<br />
| {{param|i}}<br />
|-<br />
| {{enum|GL_LINES}}<br />
| 2{{param|i}} - 1<br />
| 2{{param|i}}<br />
|-<br />
| {{enum|GL_LINE_LOOP}}<br />
| {{param|i}}<br />
| {{param|i}} + 1, if {{param|i}} < the number of vertices.<br />
1 if {{param|i}} is equal to the number of vertices.<br />
|-<br />
| {{enum|GL_LINE_STRIP}}<br />
| {{param|i}}<br />
| {{param|i}} + 1<br />
|-<br />
| {{enum|GL_TRIANGLES}}<br />
| 3{{param|i}} - 2<br />
| 3{{param|i}}<br />
|-<br />
| {{enum|GL_TRIANGLE_STRIP}}<br />
| {{param|i}}<br />
| {{param|i}} + 2<br />
|-<br />
| {{enum|GL_TRIANGLE_FAN}}<br />
| {{param|i}} + 1<br />
| {{param|i}} + 2<br />
|-<br />
| {{enum|GL_LINES_ADJACENCY}}<br />
| 4{{param|i}} - 2<br />
| 4{{param|i}} - 1<br />
|-<br />
| {{enum|GL_LINE_STRIP_ADJACENCY}}<br />
| {{param|i}} + 1<br />
| {{param|i}} + 2<br />
|-<br />
| {{enum|GL_TRIANGLES_ADJACENCY}}<br />
| 6{{param|i}} - 5<br />
| 6{{param|i}} - 1<br />
|-<br />
| {{enum|GL_TRIANGLE_STRIP_ADJACENCY}}<br />
| 2{{param|i}} - 1<br />
| 2{{param|i}} + 3<br />
|}<br />
<br />
Patches do not have a provoking vertex, since {{enum|GL_PATCHES}} can only be used with [[Tessellation]]. This process transforms path primitives into other kinds of primitives, so by the time the rasterizer sees it, it will not be a patch anymore. The output primitives from the TES do have provoking vertices, but which vertex is the provoking one for a particular line/triangle is implementation-defined, and therefore cannot be relied upon. So using tessellation with {{code|flat}} interpolation is a dubious prospect if different primitives need different values.<br />
<br />
== Primitive restart ==<br />
{{main|Vertex Rendering#Primitive Restart}}<br />
<br />
Setting a primitive restart index will cause the interpretation of the primitive to be reset when that index is reached in the vertex stream. The vertex data at that index will ''not'' be processed, nor will a vertex be inserted into the vertex stream for that index value.<br />
<br />
== See Also ==<br />
<br />
* [[Vertex Specification]]<br />
** [[Vertex Rendering]]<br />
* [[Point Rasterization]]<br />
* [[Line Rasterization]]<br />
* [[Triangle Rasterization]]<br />
<br />
[[Category:Vertex Specification]]</div>WilliamKapplerhttps://www.khronos.org/opengl/wiki_opengl/index.php?title=Talk:Common_Mistakes&diff=12846Talk:Common Mistakes2016-02-08T18:24:47Z<p>WilliamKappler: /* BGRA Preference */</p>
<hr />
<div>The list of common mistakes is very long, and hard to read. The entries should be split into categories, perhaps also into different pages. I'm not sure how to categorize them, else I wound have done it.<br />
<br />
I'm not sure who wrote the line above. Please type a tilde 4 times to sign.<br />
Now about the Paletted textures section. I have noticed someone has edited to add the following "But there are still a lot of video cards around that don't support shaders, so you'll have to implement it using GL_EXT_paletted_texture as well.". There is an assumption being made that if a hardware doesn't support shaders, that it supports GL_EXT_paletted_texture. Furthermore, that section was added by me since I noticed that a few users were getting surprised that that extension was dropped. We don't need to tell the programmer there are a lot of hardware out there that supports GL_EXT_paletted_texture. That's ridiculous. For that reason, I'm pulling that text out. [[User:V-man|V-man]] 12:59, 3 July 2011 (PDT)<br />
<br />
It was me who posted the fist line, I thought the timestamps were added automatically back then. --[[User:Zyx 2000|Zyx 2000]] 14:06, 4 July 2011 (PDT)<br />
<br />
I have moved some sections related to deprecated features to a separate article. I still believe this article is too long, and I might split it up more in the future. --[[User:Zyx 2000|Zyx 2000]] 14:05, 9 July 2011 (PDT)<br />
<br />
= BGRA Preference =<br />
<br />
Under [[Common_Mistakes#Slow_pixel_transfer_performance|Slow pixel transfer performance]]:<br />
<br />
''"On which platforms is GL_BGRA preferred? Making a list would be too long but one example is Microsoft Windows."''<br />
<br />
'''Does''' such a list exist somewhere? I am currently developing an OpenGL-based library for which I cannot require 4.3, and would rather avoid possibly missing extensions to use ARB_internalformat_query2. --[[User:WilliamKappler|WilliamKappler]] ([[User talk:WilliamKappler|talk]]) 13:24, 8 February 2016 (EST)</div>WilliamKapplerhttps://www.khronos.org/opengl/wiki_opengl/index.php?title=Talk:Common_Mistakes&diff=12845Talk:Common Mistakes2016-02-08T18:24:35Z<p>WilliamKappler: </p>
<hr />
<div>The list of common mistakes is very long, and hard to read. The entries should be split into categories, perhaps also into different pages. I'm not sure how to categorize them, else I wound have done it.<br />
<br />
I'm not sure who wrote the line above. Please type a tilde 4 times to sign.<br />
Now about the Paletted textures section. I have noticed someone has edited to add the following "But there are still a lot of video cards around that don't support shaders, so you'll have to implement it using GL_EXT_paletted_texture as well.". There is an assumption being made that if a hardware doesn't support shaders, that it supports GL_EXT_paletted_texture. Furthermore, that section was added by me since I noticed that a few users were getting surprised that that extension was dropped. We don't need to tell the programmer there are a lot of hardware out there that supports GL_EXT_paletted_texture. That's ridiculous. For that reason, I'm pulling that text out. [[User:V-man|V-man]] 12:59, 3 July 2011 (PDT)<br />
<br />
It was me who posted the fist line, I thought the timestamps were added automatically back then. --[[User:Zyx 2000|Zyx 2000]] 14:06, 4 July 2011 (PDT)<br />
<br />
I have moved some sections related to deprecated features to a separate article. I still believe this article is too long, and I might split it up more in the future. --[[User:Zyx 2000|Zyx 2000]] 14:05, 9 July 2011 (PDT)<br />
<br />
= BGRA Preference =<br />
<br />
Under [[Common_Mistakes#Slow_pixel_transfer_performance|Slow pixel transfer performance]]:<br />
<br />
''"On which platforms is GL_BGRA preferred? Making a list would be too long but one example is Microsoft Windows."''<br />
<br />
'''Does''' such a list exist somewhere? I am currently developing an OpenGL-based library for which I cannot require 4.3, and would rather avoid possibly missing extensions to use ARB_internalformat_query2.</div>WilliamKappler