- Reference
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview
http://www.glprogramming.com/red/chapter03.html(red book)
- Basic concept
VAO = Vertex ArrayObject
Vertex Array Objectsdefine what data each vertex has, while Vertex Buffer Objects store the actualvertex data itself.
Avertex's data is a series of attributes.
As OpenGL Objects, VAOs have the usual creation,destruction, and binding functions: glGenVertexArrays, glDeleteVertexArrays, and glBindVertexArray.
Note: VAOs cannot be shared between OpenGL contexts.
GLuintVertexArrayID;
glGenVertexArrays(1, &VertexArrayID); //by default create one VAO, which disables allattributes.
glBindVertexArray(VertexArrayID);
GL object flow:
Define - Gen - Bind(with current context)
A color is,conceptually, exactly the same as a position : it’s just data. In OpenGL terms,they are “attributes”. As a matter of fact, we already used this withglEnableVertexAttribArray() and glVertexAttribPointer().
A newly-created VAOhas array access disabled for all attributes. Array access is enabled bybinding the VAO in question and calling: glEnableVertexAttribArray()
Rendering Pipeline
https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview
Primitives
Thepurpose of the primitive assembly step is to convert a vertex stream into asequence of base primitives. For example, aprimitive which is a line list of 12 vertices needs to generate 11 line base primitives.Primitives is a group of data to describe the shape/color to draw vertices.
Theresult of rasterizing a primitive is a sequence of Fragments.
A fragment is a set of statethat is used to compute the final data for a pixel (or sample if multisampling is enabled) in the output framebuffer. The state for a fragment includes its position in screen-space, the sample coverageif multisampling is enabled, and a list of arbitrary datathat was output from the previous vertex or geometry shader.
Primitive type | GL_FIRST_VERTEX_CONVENTION | GL_LAST_VERTEX_CONVENTION |
GL_POINTS | i | i |
GL_LINES | 2i - 1 | 2i |
GL_LINE_LOOP | i | i + 1, if i < the number of vertices. 1 if i is equal to the number of vertices. |
GL_LINE_STRIP | i | i + 1 |
GL_TRIANGLES | 3i - 2 | 3i |
GL_TRIANGLE_STRIP | i | i + 2 |
GL_TRIANGLE_FAN | i + 1 | i + 2 |
GL_LINES_ADJACENCY | 4i - 2 | 4i - 1 |
GL_LINE_STRIP_ADJACENCY | i + 1 | i + 2 |
GL_TRIANGLES_ADJACENCY | 6i - 5 | 6i - 1 |
GL_TRIANGLE_STRIP_ADJACENCY | 2i - 1 | 2i + 3 |
The output from afragment shader is a listof colors for each of the color buffers being written to, a depth value, and a stencil value.
- Multiple Contexts
OpenGL Restricts Each Context to a Single Thread
Each thread in an OS X process hasa single current OpenGL rendering context. Every time your application calls anOpenGL function, OpenGL implicitly looks up the context associated with thecurrent thread and modifies the state or objects associated with that context.
OpenGL is not reentrant. If youmodify the same context from multiple threads simultaneously, the results areunpredictable. Your application might crash or it might render improperly. Iffor some reason you decide to set more than one thread to target the samecontext, then you must synchronize threads by placing a mutex around all OpenGLcalls to the context, such as gl* and CGL*.OpenGL commands that block—such as fence commands—do not synchronize threads.
An OpenGL context represents many things. A context stores all ofthe state associated with this instance of OpenGL. It represents the(potentially visible) default framebuffer that rendering commands will draw to when notdrawing to a framebuffer object. Think of a context as an object that holds all ofOpenGL; when a context is destroyed, OpenGL is destroyed.
Contextsare localized within a particular process of execution (an application, more orless) on an operating system. A process can createmultiple OpenGL contexts. Each context can represent a separate viewablesurface, like a window in an application. If youcreate multiple contexts in one thread, need to call makeCurrent to attach oneas the current context with this thread.
Each context has its own set of OpenGL Objects, which are independent of those from other contexts.A context's objects can be shared with other contexts. Any OpenGL object typeswhich are not containers are sharable, as well as Sync Objects and GLSL Objects (excludingprogram pipeline objects). All container objects are not shared betweencontexts.
Thecurrent context is athread-local variable (means the context is stored in thread and will bethread-safe if switch back from other threads automatically due to threadprotection, following gl call changes on its own thread gl context), soa single process can have several threads, each of which has its own currentcontext. However, a single context cannot be current in multiple threads at thesame time.
From <https://www.khronos.org/opengl/wiki/OpenGL_Context>
Howto make context to be thread local variable? First, you can get thread id whenexecute opengl api; second, thread has its own address space. Like for linux,using POSIX pthread API to bind the data with a key to current thread.(pthread_getspecific/pthread_setspecific).
- Shaders
twoshaders : one called Vertex Shader, which will be executed for each vertex, andone called Fragment Shader, which will be executed for each sample. And sincewe use 4x antialising, we have 4 samples in each pixel.
GLSLhas to be compiled at run time, which means that each and every time you launchyour application, all your shaders are recompiled.
Usuallywe write a common piece of code to load and compile and combine the shadercode.
Inthe vertex shader, gl_Position is a “built-in” variable, others you need todeclare with out/in;
- Matrices
Untilthen, we only considered 3D vertices as a (x,y,z) triplet. Let’s introduce w.We will now have (x,y,z,w) vectors.
Thiswill be more clear soon, but for now, just remember this :
Ifw == 1, then the vector (x,y,z,1) is a position in space.
Ifw == 0, then the vector (x,y,z,0) is a direction.
From <http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/>
Affine Transformation
Transformation
TransformedVector = TranslationMatrix * RotationMatrix * ScaleMatrix * OriginalVector;
(Payattention to the order!)
The Model, View andProjection matrices
MVPmatrix = projection * view * model; (left multiplication)
Perspective Projection:
For two vertices with similar x and y coordinates,the vertex with the biggest z coordinate will be more on the center of thescreen than the other. In order to create a 3D scene on 2D surface withdistance distortion.
- Depth (Z-) Buffer
WithoutZ-buffer, it overdraws the “near” one, even though it’s supposed to be behindit ! This is what happens with our cube : some faces are supposed to be hidden,but since they are drawn last, they are visible.
// Enable depthtest
glEnable(GL_DEPTH_TEST);
//Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Clear thescreen
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
FoV is the level of zoom. 80° = very wideangle, huge deformations. 60° - 45° : standard. 20° : big zoom.
- Texture
UV coordinates - a way to tell toOpenGL which part of the image has to be used for each triangle.
Eachvertex can have, on top of its position, a couple of floats, U and V.
Gen and Bind textures
// Create one OpenGLtexture
GLuinttextureID;
glGenTextures(1, &textureID);
// "Bind"the newly created texture : all future texture functions will modify thistexture
glBindTexture(GL_TEXTURE_2D,textureID);
// Give the image toOpenGL
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, width, height,0, GL_BGR,GL_UNSIGNED_BYTE, data);
Texture Filter
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Magnify/Minify
GL_NEAREST/GL_LINEAR/GL_LINEAR_MIPMAP_LINEAR
Compress Texture
glCompressedTexImage2D();
- Interaction
Sphericalcoordinates to Cartesian coordinates conversion
Backface Culling
TheGPU computes the normal of the triangle (using the cross product) and checkswhether this normal is oriented towards the camera or not.
// Cull triangleswhich normal is not towards the camera
glEnable(GL_CULL_FACE);
- Shading Effects (Models)
- Lightness
- Beeing more bright when closer to a light source
- Having highlights when looking in the reflection of a light (specular lighting)
- Beeing darker when light is not directly towards the model (diffuse lighting)
- Cheating a lot (ambient lighting)
- Shadows. This is a broad topic that deserves its own tutorial(s)
- Mirror-like reflections (this includes water)
- Any sophisticated light-matter interaction like subsurface scattering (like wax)
- Anisotrophic materials (like brushed metal)
- Physically based shading, which tries to mimic the reality closely
- Ambient Occlusion (it’s darker in a cave)
- Color Bleeding (a red carpet will make a white ceiling a litte bit red)
- Transparency
- Any kind of Global Illumination whatsoever (it’s the name that regroups all previous ones)
Touse
Triangle normals
Thenormal of a plane is a vector of length 1 that is perpendicular to this plane.
Vertex normals
Byextension, we call the normal of a vertex the combination of the normals of thesurroundings triangles.
Tocompute the lighting effects.
- VBO Index
VBO= vertex buffer object, contains various attribute buffers (position, colour,UV coordinates, other UV coordinates, normal, …)
VBOindex, an array of index to point to the shared VBO, in order to save VBObuffer and share VBO info.
Thismeans that for a vertex to be shared between two triangles, all attributes mustbe the same.
Notall cases are suitable for using VBO index, especially when vertex share sameposition but different other attributes like normal.
Vertex-> vertices
Index-> indices
Besides,it is good for performance improvement as well.
- FSAA
full-screenantialiasing
https://en.wikipedia.org/wiki/Spatial_anti-aliasing
Multisamplingantialiasing (MSAA)
Withmultisampling, each pixel at the edge of a polygon is sampled multiple times.For each sample-pass, a slight offset is applied to all screen coordinates.This offset is smaller than the actual size of the pixels. By averaging allthese samples, the result is a smoother transition of the colors at the edges.
Most modern GPUs support 2×, 4×, 8×, and 16× MSAA samples. Highervalues result in better quality, but are slower.
- FBO
FramebufferObjects are OpenGL Objects, which allow for the creation of user-defined Framebuffers.With them, one can render to non-Default Framebuffer locations, and thus render without disturbing themain screen.
As standard OpenGL Objects, FBOs have the usual glGenFramebuffers and glDeleteFramebuffers functions. As expected, italso has the usual glBindFramebuffer function, to bind an FBO tothe context.
A renderbuffer is an object thatcontains a single image. Renderbuffers cannot be accessed by Shaders in any way. The only way to workwith a renderbuffer, besides creating it, is to put it into an FBO.
Attach
To connect one object to another. This term is used across all of OpenGL, butFBOs make the most use of the concept. Attachment is different from binding.Objects are bound tothe context; objects are attached to one another.
From:https://www.khronos.org/opengl/wiki/Framebuffer_Object
- Window system
OpenGLneeds to bind with OS window system to get display and framebuffer/Surface.
EGLBoolean eglMakeCurrent(
EGLDisplay display,
EGLSurface draw,
EGLSurface read,
EGLContext context);
From <https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtml>
Besides,it needs to create context for local thread and pass to eglMakeCurrent
EGLContext eglCreateContext( | EGLDisplay display, |
| EGLConfig config, |
| EGLContext share_context, |
| EGLint const * attrib_list); |
Another EGL facilitated function:
EGLBoolean eglSwapBuffers(
EGLDisplay display,
EGLSurface surface);
eglSwapBuffers performs an implicit flushoperation on the context (glFlush for an OpenGL ES or OpenGL context, vgFlush for an OpenVG context) boundto surface beforeswapping. Subsequent client API commands may be issued on that contextimmediately after calling eglSwapBuffers, but are not executed until the buffer exchange iscompleted.
PBOs have nothing to do with Framebuffer Objects. Note the capitalization; "framebuffer"is one word. FBOs are not buffer objects; PBOs are. FBOs are about rendering to off-screen images; PBOsare about pixel transfers to/from the user from/to images in OpenGL. They arenot alike.
- Stencil
Stencilis a shape with empty holes (gaps) inside in order to allow painting its shapeon a surface below it.
- Render to Texture
Render-To-Textureis a handful method to create a variety of effects. The basic idea is that yourender a scene just like you usually do, but this time in a texture that youcan reuse later.
From <http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/>
- Steps of GL programming
- Egl - createContext
- Egl - createWindowSurface
- Egl - makeCurrent(surface, context)
- Gl - createVertexArray (VA Buffer)
- Define vertex_buffer_data ={ matrix x, y, z }
- Bind vertex buffer data;
- Call other gl APIs to define GL state;
- Bind and compile Vertex/fragment shader programs;
- Gl - DrawXXX
- Egl - swapbuffers()
- Destroy allocated context, buffers, VA, programs.
- Exist