OpenGL An introduction Camilla Berglund elmindreda@stacken.kth.se Introductory illustration by theodore This material is under a Creative Commons license http://creativecommons.org/licenses/by-sa/2.5/se/ http://www.elmindreda.org/opengl/
Requirements Basic ANSI C Basic linear algebra and trigonometry Basic familiarity with common computer graphics terminology
Before we begin... This lecture is not complete More states, commands, extensions and object types exist than will be shown here. You can get most of it from the Red Book But this way, you'll know what to look for. Examples are intended to be easily readable Don't confuse them with serious code.
Terminology This is a pixel Any questions?
What doesn't OpenGL do? Provide a scene graph or 3D-engine. Provide any kind of animation support. Handle input (keyboard, mouse, joystick, time). Handle windows or display modes. Import or export external data formats. Initialise OpenGL (?!) However, this is actually an advantage.
So what is OpenGL? A standardised, relatively platform independent, networkable API for rendering of two- and threedimensional graphical primitives, with a structure suitable for hardware acceleration. A portable interface to your 3D-card.
Why should you avoid OpenGL? It evolves slower than Direct3D does. It has a lower level of abstraction than Direct3D, and thus requires more work to write a proper rendering engine for. Support for hardware-accelerated OpenGL on Open/Free Unix-systems is still lacking. However, there is always Mesa.
Why then use OpenGL? It is standardised and portable. It is (probably) available on your platform. It is easy to get started with. The API is very stable; old code is still relevant. New core functionality tends to be future proof.
How does OpenGL evolve? ARB The Architecture Review Board Extension mechanism (ask your API for details) Every OEM and API can add their own extensions as they see fit: GL_NV_foo_bar GL_ARB_baz GLX_glork WGL_ARB_swizzled_quuxes
OpenGL is a state machine The old way; fixed pipeline A huge (but static) collection of wheels and knobs. Easy to get started with, lower demands on hardware, but very limiting for advanced rendering. The new way; programmability Large parts of the fixed pipeline can today be replaced by various kinds of programs. These programs can access all relevant states. More work to get started with, but also more flexible.
API naming conventions GL_FOO_BAR for constants glfoobar for functions and procedures GLfoobar for data types Suffixes on functions with several variants n specific number of parameters d f i s b specific data type v pointer to one or more values Example: glvertex3fv
State commands Setting boolean states glenable, gldisable Setting complex states gllight, glmaterial, gltexenv, glclearcolor, etc... Using the state stack glpushattrib, glpopattrib Retrieving states glgetinteger, glgeterror, glgetlight, etc...
#include <GL/glfw.h> int main(void) { if (!glfwinit()) return 1; if (glfwopenwindow(640, 480, 8, 8, 8, 0, 0, 0, GLFW_WINDOW)) { glclearcolor(1.f, 0.f, 0.f, 0.f); while (glfwgetwindowparam(glfw_opened)) { glclear(gl_color_buffer_bit); } } glfwswapbuffers(); glfwterminate(); } return 0;
Some nomenclature Vertex A position in space, plus associated attributes Used to define all supported 3D primitive types. Fragment A value from one part of the pixel pipeline. We will only be dealing with color fragments. Pixel The result of combining all relevant fragments. This is what gets written into the framebuffer.
Geometric primitives Points Line segments Strip, list, loop Triangles Strip, list, fan Quads (planar only) Strip, list Single polygon (simple, convex, planar only)
Line primitives Line loop Line list Line strip
Triangle primitives Triangle fan Triangle strip Triangle list
Quad primitives Quad list Quad strip
Geometric primitive commands Begin rendering glbegin(glenum mode) the desired primitive(s) Vertex attributes glcolor... for vertex color gltexcoord... for texture coordinate glnormal... for vertex normal glvertex... for finalising a vertex End rendering glend()
Basic vertex processing Modelview matrix transformation From object space into camera space Projection matrix transformation From camera space into clipping space Clipping to the viewing frustum Including user-defined clipping planes. Perspective divide Viewport transformation
Matrix commands Changing the active stack glmatrixmode Working with the stack glpushmatrix, glpopmatrix Working with the current matrix glloadidentity, glmultmatrix, glloadmatrix Commonly used matrix constructions glrotate..., gltranslate..., glscale..., glfrustum glulookat, gluprojection, gluortho2d
glmatrixmode(gl_projection); glloadidentity(); gluperspective(60.f, WIDTH / (GLdouble) HEIGHT, 0.1f, 100.f); glmatrixmode(gl_modelview); while (glfwgetwindowparam(glfw_opened)) { glclear(gl_color_buffer_bit); glloadidentity(); gltranslatef(0.f, 0.f, 2.f); glrotatef(glfwgettime() * 50.f, 0.f, 1.f, 0.f); glbegin(gl_triangles); glcolor3f(1.f, 0.f, 0.f); glvertex3f(0.f, 1.f, 0.f); glcolor3f(0.f, 1.f, 0.f); glvertex3f(1.f, 1.f, 0.f); glcolor3f(0.f, 0.f, 1.f); glvertex3f( 1.f, 1.f, 0.f); glend(); } glfwswapbuffers();
Lighting Four kinds of light source Spot-, point-, directional and global ambient lights. Fixed number of simultaneous lights But this is can be worked around. Lighting in fixed pipeline is per vertex Fragment programs allow more complex lighting models, as well as per-pixel lighting Lighting formula is basically Phong's model
Materials Defines emission and reflectivity parameters Ambient, diffuse and specular reflection. Emission (which does not affect other primitives). Ambient and/or diffuse reflection can be connected to glcolor commands But usually, you specify materials per primitive Texture mapping is better for detailed coloring.
n I =k local e i=0 Partial lighting formulas Per vertex for fixed pipeline lighting; programmable pipeline allows better models Note that attenuation isn't shown here I ia k a k d N L i k s V R i s I global =k a I ga I =I local I global
Lighting commands Enabling and disabling lighting GL_LIGHTING for global control GL_LIGHTn for individual lights Changing individual light parameters gllight... Changing material properties glmaterial... Changing the lighting model gllightmodel...
GLfloat position[4] = { 0.f, 0.f, 1.f, 0.f }; Glfloat color[4] = { 1.f, 0.f, 0.5f, 0.f }; [...] glenable(gl_lighting); glenable(gl_light0); gllightfv(gl_light0, GL_POSITION, position); glmaterialfv(gl_front, GL_DIFFUSE, color); while (...) { [...] draw_cube(); } [...]
Some more nomenclature Texel A fragment originating from a texture map, analogous to a framebuffer pixel. Mipmap One of several versions of a texture, used to minimise aliasing errors. Texture space The coordinate system within a texture map, usually but not always in the range [0, 1].
Texture mapping Textures are objects accessed through handles Textures can be 1D, 2D, 3D or cube maps Texture coordinates......are per vertex, unless you use fragment programs....address texture space, not object space....have their own transformation matrix stack....can be specified during rendering....can be generated with gltexgen.
Texture object commands Managing texture objects glgentextures, glistexture, gldeletetextures Setting the active texture object glbindtexture Setting texture object states gltexparameter... Setting global texture states gltexenv...
Texture data commands Writing texture data glteximage2d, gltexsubimage2d Reading texture data glgetteximage Copying from the color buffer glcopyteximage2d, glcopytexsubimage2d All of these exist for 1D (and nowadays 3D)
GLuint textureid; glenable(gl_texture_2d); glgentextures(1, &textureid); glbindtexture(gl_texture_2d, textureid); generate_texture(64, 64); glenable(gl_texture_gen_s); glenable(gl_texture_gen_t); gltexgeni(gl_s, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); gltexgeni(gl_t, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); while (...) { [...] draw_cube(); } [...]
void generate_texture(unsigned int width, unsigned int height) { GLubyte* data = (GLubyte*) malloc(width * height); /* Insert magic here */ glubuild2dmipmaps(gl_texture_2d, 1, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); } free(data);
Culling A simple form of hidden surface removal. Removes filled primitives based on their winding. Primitives with a certain winding, as it appears during rendering, will be culled when enabled. By default, clockwise winding is culled.
Culling commands Global culling control GL_CULL_FACE to glenable/gldisable Deciding which faces to cull glcullface Front, back or both Deciding which face is front glfrontface CW or CCW
Blending When blending, pixels are combined with the color buffer instead of simply written to it. This enables effects such as simple transparency. In fixed pipeline, there is a single, fixed formula for combining pixels Unless you have GL_ARB_imaging. s f f s d f f d
Blending commands Global blending control GL_BLEND to glenable/gldisable Setting source and destination factors glblendfunc Also, if you have GL_ARB_imaging glblendcolor glblendequation
glenable(gl_blend); glblendfunc(gl_one, GL_SRC_ALPHA); while (...) { [...] glloadidentity(); gltranslatef(0.f, 1.f, 4.5f); glrotatef(glfwgettime() * 40.f, 1.f, 1.f, 0.f); draw_cube(); glloadidentity(); gltranslatef(0.6f, 0.f, 3.f); glrotatef(glfwgettime() * 20.f, 1.f, 0.f, 1.f); draw_cube(); glloadidentity(); gltranslatef( 0.2f, 0.2f, 1.5f); glrotatef(glfwgettime() * 50.f, 1.f, 1.f, 1.f); draw_cube(); } [...]
Fog Tinting vertices based on distance Fixed pipeline fog has a single color Gives a crude impression of depth Useful for simulating certain atmospheric effects. Three fog formulas Linear, exponential and exponential squared.
Fog formulas Exponential Exponential squared Linear Final interpolation f =e density z density z 2 f =e f = end z end start C = f C i 1 f C f
Fog commands Global fog control GL_FOG to glenable/gldisable Setting fog parameters glfog... Controlling fog niceness GL_FOG_HINT to glhint
struct ColorRGBA color = { 0.8f, 0.8f, 0.7f, 0.f }; glclearcolor(color.r, color.g, color.b, 0.f); glenable(gl_fog); glfogi(gl_fog_mode, GL_LINEAR); glfogf(gl_fog_start, 0.f); glfogf(gl_fog_end, 10.f); glfogfv(gl_fog_color, (GLfloat*) &color); while (...) { glloadidentity(); gltranslatef(1.f, 0.f, 4.f); for (i = 0; i < 5; i++) { gltranslatef(0.f, 0.f, 1.5f); glrotatef(glfwgettime() * 50.f, 1.f, 1.f, 1.f); } draw_cube(); } [...]
Buffers Color buffer Depth buffer Z axis distance or eye distance values Stencil buffer Scratch values for dynamic masking effects Accumulation buffer Auxillary buffers
Texture / buffer formats Color (RGB) Intensity Luminance Alpha Depth Normal maps Combined or compressed variants of the above
Buffer commands Setting clearing values glclearcolor, glcleardepth, glclearstencil, etc... Clearing buffers glclear Masking buffer writes glcolormask, gldepthmask, glstencilmask Limiting writes to a specific area glscissor
Display lists Display lists are objects accessed through handles Records and plays back a sequence of commands A display list may call other display lists The surrounding state is not saved This may radically change the result of your list May save both coding and execution time Pure vertex display lists are often accelerated However, there are better ways to achieve this now
Display list commands Creating lists glgenlists Recording lists glnewlist, glendlist Calling lists glcalllist, glcalllists Destroying lists gldeletelists
Gluint listid; [...] listid = glgenlists(1); glnewlist(listid, GL_COMPILE); for (x = 0; x < 2; x++) { for (y = 0; y < 2; y++) { for (z = 0; z < 2; z++) { glpushmatrix(); gltranslatef(x * 2.f 1.f, y * 2.f 1.f, z * 2.f 1.f); draw_cube(); glpopmatrix(); } } } glendlist();
Reading an extension Very standardised format Dependencies Overview, Reasoning, Issues New Procedures and Functions, New Tokens Additions to Chapter n of the OpenGL x.x Specification Interactions with extension Errors New state
Various access methods GLUT (original or FreeGLUT) SDL, GLFW, Prophecy, etc... Bindings exist for Ada, C#, Java, Ruby, Python, PHP and most other languages Most GUI-toolkits provide access to OpenGL The hard way (GLX, AGL, CGL, WGL, NSOpenGL, etc...) Never, ever use GLAUX!
Resources The Red Book (programmer's guide) Version 1.1 is available on the Internet The specification is always free The OpenGL extension registry NeHe Productions and GameDev.net KTHB and other libraries Google is your friend IRC ( ##opengl on Freenode )
The End Thank you for your time Now go make something cool