OpenGL - TUTORIAL - LESSON #1 DHTML (c) Artur Marques, 1999
OpenGL is a software interface to graphics hardware. The Open stands for "freely available to be used". The GL stands for "Graphics Library".
The main purpose of OpenGL is to allow the 2D and 3D rendering of objects in a frame buffer. The concepts of "rendering" and "frame buffer" will be detailed latter. 2D stands for bi-dimensional and in a graphical context, that means a width and a height. 3D stands for three-dimensional and in a graphical context, that means a width, a height and a depth.
The objects that OpenGL renders are sequences / lists of vertices or pixels. The vertices define the geometry of objects. The pixels define images. A pixel (picture element) is the smallest point that the graphics hardware can represent in its running resolution. OpenGL always works towards forming a final desired image in a frame buffer.
In order to understand OpenGL I am introducing:
OpenGL Primitives and Commands
Primitives are what OpenGL can really draw. They are points, line segments and polygons. These primitives build models (or objects, if you prefer). The process of generating the images corresponding to the models is called the rendering. The drawing of the primitives can be done is several modes. You set modes, primitives and other operations, via function calls. Several modes can be set at once, but that depends on the function you are calling and on the result you want. Primitives are defined by a list of vertices (plural of vertex). A vertex defines a single point, that marks the endpoint of a line or the corner of a polygon. By definition, a vertex is where two edges meet. Each vertex has data associated: coordinates, colors, normals, texture coordinates and edge flags.
The vertex and its data are processed independently, in order, and in the same way (vertex #n + vertex_data #n), but there can be exceptions, for example when some vertices must be clipped in order to fit their corresponding primitives into a specified region. In that case, not only the vertices may be modified, but also new vertices can be created. What is clipping and what types of clipping are available will be explained latter. Commands are always processed in the order they are received, respecting that each primitive is always completely drawn, before any other command gets a chance.
OpenGL allows precise control of all the fundamental graphical operations on 2D and 3D graphics, such as transformation matrices, lighting equation weights, antialiasing algorithms and pixel update operators. All these concepts and some introductory mathematics will be explained latter. OpenGL does NOT provide the means to directly describe complex objects (such as a car, or a teddy bear). OpenGL is procedural, in the sense that the programmer must describe the objects, without having direct control on how they will look like, when rendered. In that sense, OpenGL is not descriptive.
OpenGL is client / server oriented. The functions that a programmer calls, are executed by the OpenGL server. The program being written is the client. This means that the computer running the server can handle several OpenGL sessions, each on its OpenGL context. The communication between client and server happens via an already existing protocol, that can be expanded, or you can even design an all new protocol. OpenGL does not provide commands for obtaining user input. It also does NOT handle stuff that is of the responsability of the running windowing system, such as the creation of a window that will display some view, of some scene. The window system that allocates frame buffer resources, controls the effects of the OpenGL commands on the frame buffer:
- determines which portions of the frame buffer that OpenGL may access at any given time.
- communicates to OpenGL how those portions are structured.
There is no such thing as "OpenGL initialization". What there is, is the window system providing a window where OpenGL can render images.
OpenGL processes data in stages. These stages happen in such a way, that we can consider that there is a processing pipeline. Here is a small description of what happens at each stage:
#1 Display List - commands can follow directly to the pipeline, but it is often preferable to get them into a display list, for latter processing.
#2 Evaluator - provides an efficient way to approximate curve and surface geometry, by evaluating polynomial commands of input values.
#3 Per-vertex operations and primitive assembly - The primitives are described by vertices, as we have already seen. Here, vertices are transformed and lit, and primitives are clipped to the viewport, in preparation for rasterization. The concepts of "viewport" and "rasterization" will be better understood latter.
#4 Rasterization - here are produced frame buffer addresses, refering to bi-dimensional descriptions of primitives. Each fragmented produced goes to the per-fragment operations.
#5 Per-fragment operations - these operations come to pixel results, that are stored in the frame buffer. These operations can update the frame buffer, based on upcoming and previously stored data, such as depth (z axis) data, useful to the Z-buffering algorithm.
#6 Frame Buffer - data finally arrives at the end the pipeline.
If the input data is pixels, rather than vertices, OpenGL skips step #1 and goes to a processing stage, that we can call "pixel operations", from where the pixels get stored as texture memory, for use in #4 Rasterization, OR they are rasterized with the resulting fragments going to the frame buffer, as if they were geometric data (the one obtained from vertices inputs).
Next time, we will be coding our first lines :-)