modern openglminho-kim.com/courses/16fa71033/data/2013/redbook-01.pdf · opengl programming guide...
TRANSCRIPT
Modern OpenGLMinho Kim
Dept. of Computer Science
University of Seoul
First Thing First
• Please download the first sample files (GL430_minimal.zip) at http://db.tt/6ATsNpZw
• Please start downloading the sample file (samples.zip, 350MB) at http://db.tt/7B0d7q7X
OpenGL Resources
OpenGL Programming Guide (8th edition)
• Main textbook• Dave Shreiner, Graham Sellers, John M. Kessenich,
Bill M. Licea-Kane• Published on March 2013• Version 4.3 (latest)• A whole makeover of the classical “red book” for
modern OpenGL• Lacks of theory (transformations, lighting, etc.)• Largely overlaps with the “orange book”• Example source codes are buggy• http://www.opengl-redbook.com/
Learning Modern 3D Graphics Programming
• An online tutorial by Jason L. McKesson
• Version 3.3 and above
• Highly recommended
• Doesn’t cover the whole topics
• Nice cross-platform sample codes
• http://www.arcsynthesis.org/gltut/
OpenGL 4.0 Shading Language Cookbook
• David Wolff
• Published on July 2011
• Version 4.0 and above
• Useful sample codes – Used be using Qt but recently ported to GLFW
• Lacks of structured theory
• http://www.packtpub.com/opengl-4-0-shading-language-cookbook/book
OpenGL Development Cookbook
• Muhammad Mobeen Movania
• Published on June 2013
• Version 3.3 and above
• Hardcopy not released yet (e-book only)
• You can download the sample codes
• http://www.packtpub.com/opengl-development-cookbook/book
OpenGL Shading Language (3rd edition)
• Randi J. Rost, Bill M. Licea-Kane, Dan Ginsburg, John M. Kessenich, Barthold Lichtenbelt, Hugh Malan, Mike Weiblen
• Published on July 2009
• Version 3.1 and above
• A.k.a. “orange book”
• Little bit old
• https://www.informit.com/store/opengl-shading-language-9780321637635
Other Resources
• OpenGL Programming Wikibookhttps://en.wikibooks.org/wiki/OpenGL_Programming
(2011) (2008) (2013)
Chapter 1: Introduction to OpenGL
Short Introduction
What is OpenGL?
• Stands for “Open Graphics Library”
• Managed by non-profit industry consortium Khronos
• Not a library, but an “API specification”
• Drivers implemented by graphics hardware vendors
• Cross-platform API for rendering interactive 3D graphics scenes• No platform-dependent APIs – window management, UI handling, etc.• No high level APIs – image load/save, scene graph management, etc.
• Client-server model (CPU-GPU)
• A big state machine OpenGL context (“an object that holds all of OpenGL”)
• Latest version – ver. 4.3 released on Aug 6, 2012.
• Derivatives – OpenGL ES, WebGL, etc.
Modern OpenGL
• OpenGL 3.0 – Deprecation mechanism introduced
• OpenGL 3.1 and later• Deprecated functions are removed
• Core vs. compatibility profiles
• Some important changes• Heavily relies on shaders – It’s all about “shaders” now!
• No immediate rendering mode – via buffers only
• No lighting-relevant functions – More things to do for programmers
• No transformation stacks for hierarchical transformations – Additional library required
Our First Program – triangles.cpp
triangles.cpp
• Modified from the triangles.cpp in the textbook
• No additional header file required
• Almost no error checking
• Compilation1. Create an empty project in Visual Studio 2010
2. Set include & lib paths for freeglut & GLEW
3. Add “glew32.lib” (“freeglut.lib” is included by #pragma)
4. glew32.dll & freeglut.dll are required for execution
OpenGL Syntax
• Function names start with “gl*”• GLUT – “glut*”
• GLEW – “glew*”
• Constants start with “GL_*” – defined in “glcorearb.h” & “glext.h”
• No function overloading suffixes used to distinguish parameter types (*b, *s, *i, *f, *d, *ub, *us, *ui)
intmain(int argc, char** argv){
glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA);glutInitWindowSize(512, 512);glutInitContextVersion(4, 3);glutInitContextProfile(GLUT_CORE_PROFILE);glutCreateWindow(argv[0]);if (glewInit()) {
cerr << "Unable to initialize GLEW ... exiting" << endl;exit(EXIT_FAILURE);
}init();glutDisplayFunc(display);glutMainLoop();
}
Error(?) in main()
glutInitContextVersion(4,3);glutInitContextFlags (GLUT_CORE_PROFILE | GLUT_DEBUG);glutInitContextProfile(GLUT_FORWARD_COMPATIBLE);
Helper Libraries
GLUT (OpenGL Utility Toolkit)
• For OpenGL context management, window management, UI handling, event handling, etc.
• (Almost) Cross-platform (except mobile platforms) – Some slight differences exist between platforms
• The original version by Mark Kilgard is too old and obsolete (https://user.xmission.com/~nate/glut.html)
• Use freeglut instead (http://freeglut.sourceforge.net)• Alternatives
• Native window APIs – platform-dependent• GUI libraries such as Qt, wxWidgets, etc. – too heavy• GLFW (http://www.glfw.org/)• GLUI (http://sourceforge.net/projects/glui/)• ... and more
GLEW (OpenGL Extension Wrangler Library)
• http://glew.sourceforge.net/
• Cross-platform function loading library
• Alternatives (https://www.opengl.org/wiki/OpenGL_Loading_Library)• GLLoad
(http://glsdk.sourceforge.net/docs/html/group__module__glload.html)
• GL3W (https://github.com/skaslev/gl3w)
OpenGL Rendering Pipeline
(Joe Groff)
OpenGL Rendering Pipeline
• “...a sequence of processing stages for converting the data your application provides to OpenGL into a final rendered image.”• Input: Scene description (geometry,
transformation, lighting, camera, etc.)
• Output: 2D image
• Highly parallelizable
• Usually accelerated by a graphics hardware
• Detailed pipeline map (courtesy of http://openglinsights.com)
(image courtesy of OpenGL Wikibook)
Preparing to Send Data to OpenGL
• Vertex attributes stored in VBOs (vertex buffer objects)• Position, color, normal, etc. OpenGL doesn’t
know what the contents mean
• Additional topology (connectivity) info required for indexed rendering
• Uploaded to the host (GPU) memory for rendering – glBufferData()
• More in Chapter 3
(image courtesy of OpenGL Wikibook)
Sending Data to OpenGL
• Vertex attributes accompanied with its primitive info (points, lines, triangles, etc.) are fed into the graphics pipeline
• Non-indexed rendering (glDrawArrays()) or indexed rendering (glDrawElements())
• More in Chapter 3
(image courtesy of OpenGL Wikibook)
Vertex Shading
• Mandatory programmable stage
• Per-vertex computations• Input – vertex attributes• Output – varying variables including gl_Position
• Attributes cannot be shared independent processing
• Post-transform cache• same output for the same attributes• How to determine if the same input exists in the cache? indexed rendering required
• Transformations, lighting/shading, etc.
(image courtesy of OpenGL Wikibook)
(NVIDIA)
Tessellation Shading
• Optional stage
• Quadrilateral or triangular patches are tessellated for detailed representation
• Composed of two shaders• Tessellation control shader
• Tessellation evaluation shader
• More in Chapter 9
(image courtesy of OpenGL Wikibook)
Geometry Shading
• Optional stage
• Per-primitive processing
• More in Chapter 10
(hairfur.com)
(image courtesy of OpenGL Wikibook)
Primitive Assembly
• Fixed stage
• Organizes the vertices into their associated geometric primitives (lines, triangles, etc.)
(image courtesy of OpenGL Wikibook)
Clipping
• Fixed stage
• Clip primitives such that no part of primitives is outside the view frustum
(image courtesy of OpenGL Wikibook)
Rasterization
• Primitives defined by “numbers” are converted to fragments• Fragments – candidate pixels
• Linear interpolation is done for each varying variable
(image courtesy of OpenGL Wikibook)(arcsynthesis.org)
Fragment Shading
• Mandatory programmable stage
• Per-fragment computations
• Determines the color or discards the fragment
• Lighting/shading, texture mapping, etc.
(image courtesy of OpenGL Wikibook)
Per-Fragment Operations
• Depth testing (z-buffering)
• Stencil testing
• Blending
• ... and more
(image courtesy of OpenGL Wikibook)
More on triangles.cpp
main()
1. GLUT initialization – glutInit()2. OpenGL context & window
initialization• glutInitDisplayMode()• glutInitWindowSize()• glutInitContextVersion()• glutInitContextFlags()• glutInitContextPofile()• glutCreateWindow()
3. GLEW initialization – glewInit()4. GLUT callback function registration – glut*Func()5. Enter the infinite messaging loop – glutMainLoop()
intmain(int argc, char** argv){
glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA);glutInitWindowSize(512, 512);glutInitContextVersion(4,3);glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);glutInitContextProfile(GLUT_FORWARD_COMPATIBLE);glutCreateWindow(argv[0]);if (glewInit()) {
cerr << "Unable to initialize GLEW ... exiting" << endl;exit(EXIT_FAILURE);
}init();glutDisplayFunc(display);glutMainLoop();
}
init()
1. A VAO (vertex array object) is created
2. A VBO (vertex buffer object) is bound to the VAO
3. VBO data sent from CPU to GPU
4. Two shaders are compiled and linked together to build a program
5. “Plumbing”
voidinit(void){
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);GLfloat vertices[NumVertices][2] = {
{ -0.90, -0.90 }, // Triangle 1{ 0.85, -0.90 },{ -0.90, 0.85 },{ 0.90, -0.85 }, // Triangle 2{ 0.90, 0.90 },{ -0.85, 0.90 }
};glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
vertices, GL_STATIC_DRAW);ShaderInfo shaders[] = {
{ GL_VERTEX_SHADER, "triangles.vert" },{ GL_FRAGMENT_SHADER, "triangles.frag" },{ GL_NONE, NULL }
};GLuint program = LoadShaders(shaders);glUseProgram(program);glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
}
OpenGL Objects Management
• Conventional steps1. Create a name (pointer/reference) by glGen*()
2. Allocate (structure-like) memory and make it “current” by glBind*()
3. Manipulate the object using various functions
4. Release the object by glDelete*()
5. Check the validity of a name by glIs*()
• http://www.arcsynthesis.org/gltut/Basics/Intro What is OpenGL.html
VAOs (Vertex Array Objects)
• An OpenGL Object that encapsulates all of the state needed to specify vertex data (vertex attributes)
• Vertex data are stored in VBOs and a VAO references them – multiple VBOs for one VAO is allowed
• glGenVertexArrays, glBindVertexArray, glDeleteVertexArrays, glIsVertexArray
• glVertexAttribPointer – specifies where in the buffer the attrib data exist
• glEnable/DisableVertexAttribArray – turns on/off the attrib (all disabled by default)
• https://www.opengl.org/wiki/Vertex_Specification
VBOs (Vertex Buffer Objects)
• A Buffer Object which is used as the source for vertex array data No different from any other buffers. It’s just a chunk of memory
• Actual vertex attributes are stored
• glGenBuffers, glDeleteBuffers, glIsBuffer
• glBindBuffer – target is GL_ARRAY_BUFFER when used as a VBO
• glBufferData• to allocate and load data
• hint is given for hardware optimization
VAO Initialization
1 2 3 4 5 ...
used N/U used N/U used ...
1 2 3 4 5 ...
used used N/U used N/U ...
current VAO N/A
GL_ARRAY_BUFFER N/A
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
VAOs
buffers
targets
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
VAO Initialization
1 2 3 4 5 ...
used N/U used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO N/A
GL_ARRAY_BUFFER N/A
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
VAOs
targetsglGenVertexArrays
buffers
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
VAO Initialization
1 2 3 4 5 ...
used N/U used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER N/A
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
VAOs
targets
VAO structureglBindVertexArray
buffers
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
attrib 0 VBO N/A
enabled? disabled
size N/A
type N/A
stride N/A
offset N/A
attrib 1 ... ...
...
VAO Initialization
1 2 3 4 5 ...
used used used N/U used ...
attrib 0 VBO N/A
enabled? disabled
size N/A
type N/A
stride N/A
offset N/A
attrib 1 ... ...
...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER N/A
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
VAOs
targets
VAO structure
glGenBuffers
buffers
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
VAO Initialization
1 2 3 4 5 ...
used used used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER 2
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
VAOs
targets
VAO structure
buffers
buffer address N/A
... ...
BO structureglBindBuffer
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
attrib 0 VBO 2
enabled? disabled
size N/A
type N/A
stride N/A
offset N/A
attrib 1 ... ...
...
VAO Initialization
1 2 3 4 5 ...
used used used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER 2
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
buffer
VAOs
targets
VAO structure
buffers
buffer address XXXX
... ...
BO structure glBindBuffer
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
attrib 0 VBO 2
enabled? disabled
size N/A
type N/A
stride N/A
offset N/A
attrib 1 ... ...
...
VAO Initialization
1 2 3 4 5 ...
used used used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER 2
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
buffer
VAOs
targets
VAO structure
buffers
buffer address XXXX
... ...
BO structure
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
attrib 0 VBO 2
enabled? disabled
size 2
type GL_FLOAT
stride 0
offset 0
attrib 1 ... ...
...
glVertexAttribPointer
VAO Initialization
1 2 3 4 5 ...
used used used N/U used ...
1 2 3 4 5 ...
used used used used N/U ...
current VAO 3
GL_ARRAY_BUFFER 2
GL_ELEMENT_ARRAY_BUFFER N/A
... ...
buffer
VAOs
targets
VAO structure
buffers
buffer address XXXX
... ...
BO structure
glGenVertexArrays(NumVAOs, VAOs);glBindVertexArray(VAOs[Triangles]);
...
glGenBuffers(NumBuffers, Buffers);glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
...
glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
attrib 0 VBO 2
enabled? enabled
size 2
type GL_FLOAT
stride 0
offset 0
attrib 1 ... ...
...
glEnableVertexAttribArray
Shader Compilation
• Shader sources are compiled and linked into a program• Program ≈ executable• Shaders ≈ source codes
• Steps1. glCreateProgram – creates a program object2. For each shader type,
1. glCreateShader – creates a shader object2. glShaderSource – provides the source as a string3. glCompileShader – compiles the shader4. glAttatchShader – attaches the shader to the program
3. glLinkProgram
• Usually error checkings are required
Vertex Shader – triangles.vert
• Required OpenGL version is specified – 110 by default
• A simple pass-through shader
• How to “connect” vPosition between the VBO and the vertex shader?
• Alternative: glBindAttribLocation – should be called before linking
• See chapter01-basic and chapter01-basic-layout of “GLSL Cookbook”
#version 430 corelayout(location = 0) in vec4 vPosition;voidmain(){
gl_Position = vPosition;}
enum Attrib_IDs { vPosition = 0 };...voidinit(void){
...glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, BUFFER_OFFSET(0));glEnableVertexAttribArray(vPosition);
}
triangles.cpp (Client(CPU)-side) triangles.vert (Host(GPU)-side)
Fragment shader – triangles.frag
• A fixed color (blue) is assigned to every fragment (pixel)
• No plumbing between the vertex & fragment shaders – Incoming variable (e.g. gl_FragCoord) is not explicitly used in the fragment shader
• Only one “out” variable is allowed It’s the fragment color!
#version 430 coreout vec4 fColor;voidmain(){
fColor = vec4(0.0, 0.0, 1.0, 1.0);}
display()
• Called whenever the current window needs to be updated
• Steps1. glClear – Clears the framebuffer
2. glBindVertexArray – Specifies the VAO for the vertex data
3. glDrawArrays – Sends primitives to the rendering pipeline
4. glFlush – Flushes the queue asynchronously (usually glutSwapBuffers() for double buffering) (cf: glFinish is synchronous)
voiddisplay(void){
glClear(GL_COLOR_BUFFER_BIT);glBindVertexArray(VAOs[Triangles]);glDrawArrays(GL_TRIANGLES, 0, NumVertices);glFlush();
}
Error Checking by glGetError
////////////////////////////////////////////////////////////////////////////////// --- CheckError.h ---////////////////////////////////////////////////////////////////////////////////
#ifndef __CHECKERROR_H__#define __CHECKERROR_H__
#include <stdio.h>#include <GL/gl.h>
//----------------------------------------------------------------------------
static const char*ErrorString( GLenum error ){
const char* msg;switch( error ) {
#define Case( Token ) case Token: msg = #Token; break;Case( GL_NO_ERROR );Case( GL_INVALID_VALUE );Case( GL_INVALID_ENUM );Case( GL_INVALID_OPERATION );Case( GL_STACK_OVERFLOW );Case( GL_STACK_UNDERFLOW );Case( GL_OUT_OF_MEMORY );
#undef Case }
return msg;}
//----------------------------------------------------------------------------
static void_CheckError( const char* file, int line ){
GLenum error = glGetError();
do {fprintf( stderr, "[%s:%d] %s\n", file, line, ErrorString(error) );
} while ((error = glGetError()) != GL_NO_ERROR );
}
//----------------------------------------------------------------------------
#define CheckError() _CheckError( __FILE__, __LINE__ )
//----------------------------------------------------------------------------
#endif // !__CHECKERROR_H__
# - stringizing operator
Try yourselves!
• Try changing the background color using glClearColor
• Try changing the shape of the triangles
• Try changing the color of the triangles
• Try changing the shape of the window. What happens? Why?
• Try changing # of components for each vertex to 4 by setting the 3rd
and 4th component to 0 and 1, respectively. “homogeneous coordinates”
• Try changing the last component of vertex attributes to other values (including 0)
• Try using other “attribute id” other than 0