OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline...

53

Transcript of OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline...

Page 1: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,
Page 2: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

OpenGL – An introduction

Camilla [email protected]

Introductory illustration by theodore

This material is under a Creative Commons licensehttp://creativecommons.org/licenses/by-sa/2.5/se/

http://www.elmindreda.org/opengl/

Page 3: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Requirements

● Basic ANSI C● Basic linear algebra and trigonometry● Basic familiarity with common computer

graphics terminology

Page 4: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 5: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Terminology

This is a pixel

Any questions?

Page 6: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 7: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

So what is OpenGL?

● A standardised, relatively platform independent, networkable API for rendering of two- and three-dimensional graphical primitives, with a structure suitable for hardware acceleration.

● A “portable” interface to your “3D-card”.

Page 8: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 9: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 10: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 11: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 12: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 13: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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...

Page 14: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

#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;}

Page 15: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 16: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Geometric primitives

● Points● Line segments

– Strip, list, loop

● Triangles– Strip, list, fan

● Quads (planar only)– Strip, list

● Single polygon (simple, convex, planar only)

Page 17: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Line primitives

Line list

Line strip

Line loop

Page 18: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Triangle primitives

Triangle fan

Triangle list

Triangle strip

Page 19: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Quad primitives

Quad list

Quad strip

Page 20: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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()

Page 21: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 22: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 23: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();}

Page 24: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 25: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 26: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Partial lighting formulas

I local=ke∑i=0

n

I ia kakd N⋅L ik s V⋅Ris

I global=k a I ga

Per vertex for fixed pipeline lighting;programmable pipeline allows better models

Note that attenuation isn't shown here

I= I local I global

Page 27: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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...

Page 28: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();

  [...]}

Page 29: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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].

Page 30: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 31: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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...

Page 32: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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)

Page 33: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();

  [...]}

Page 34: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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);}

Page 35: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 36: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 37: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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 sd f∗ f d

Page 38: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 39: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();

  [...]}

Page 40: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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.

Page 41: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Fog formulas

f =e−density∗z

f =e−density∗z 2

f =end−zend− start

C= f C i1− f C f

Exponential

Exponential squared

Linear

Final interpolation

Page 42: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Fog commands

● Global fog control– GL_FOG to glEnable/glDisable

● Setting fog parameters– glFog...

● Controlling fog niceness– GL_FOG_HINT to glHint

Page 43: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();  }

  [...]}

Page 44: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Buffers

● Color buffer● Depth buffer

– Z axis distance or eye distance values

● Stencil buffer– Scratch values for dynamic masking effects

● Accumulation buffer● Auxillary buffers

Page 45: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Texture / buffer formats

● Color (RGB)● Intensity● Luminance● Alpha● Depth● Normal maps● Combined or compressed variants of the above

Page 46: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 47: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 48: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

Display list commands

● Creating lists– glGenLists

● Recording lists– glNewList, glEndList

● Calling lists– glCallList, glCallLists

● Destroying lists– glDeleteLists

Page 49: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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();

Page 50: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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

Page 51: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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!

Page 52: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

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 )

Page 53: OpenGL – An introduction - elmindreda · OpenGL is a state machine The old way; fixed pipeline – A huge (but static) collection of wheels and knobs. – Easy to get started with,

The End

Thank you for your time

Now go make something cool