OpenGL Fixed Function to Shaders - Porting a fixed function application to “modern” OpenGL - Webinar Mar 2016
11 Mar 2016•0 j'aime
5 j'aime
Soyez le premier à aimer ceci
afficher plus
•2,558 vues
vues
Nombre de vues
0
Sur Slideshare
0
À partir des intégrations
0
Nombre d'intégrations
0
Télécharger pour lire hors ligne
Signaler
Logiciels
Watch the video here: http://bit.ly/1TA24fU
OpenGL Fixed Function to Shaders - Porting a fixed function application to “modern” OpenGL - Webinar Mar 2016
OpenGL Fixed Function to Shaders - Porting a fixed function application to “modern” OpenGL - Webinar Mar 2016
Fixed Function to Shaders
Porting a fixed-function application to “modern”
Opengl.
Watch the video here: http://bit.ly/1TA24fU
Outline
There are many tutorials that introduce you to
“modern” OpenGL: (OpenGL 3.3/OpenGL ES
2.0 or greater which is where the fixed-function
APIs were removed from the spec.)
Here we will compare and contrast old fixed-
functionality and it’s new modern replacement.
We will cover some basic things you need to get
going: Vertex/Attribute data, rendering, and 3-
D math.
Geometry
Let’s use the famous OpenGL triangle as a
platform to talk about geometry/attributes.
It’s the probably the very first OpenGL program
you saw when learning OpenGL.
Rendering
What is the minimum need to “light up” a pixel?
First you need a window on your platform with
an OpenGL context bound to it.
You used to use GLUT and GLU “helper”
libraries
Here we use Qt to replace both.
For window/platform integration we’re using
QOpenGLWindow
initializeGL(), resizeGL(),
paintGL(), keyPressEvent()
Doesn’t Work ??
Previous slide will not render a triangle.
Why not?
Fixed-function example uses “fixed functionality”
to render.
With modern OpenGL, you have to program that
functionality yourself in the form of “shaders”.
Shaders
Many kinds of shaders in Modern OpenGL:
Vertex Shader
Tessellation Control Shader
Tessellation Evaluation Shader
Geometry Shader
Fragment Shader
Compute Shader
Only two are required.
Vertex Shader
Program that runs on the GPU.
Invoked once for each vertex in primitive shapes
drawn.
Input: Attribute data from vertex arrays
Output:
Clip space position of vertex: gl_Position
Data to pixel shader: varying variables.
Fragment Shader
Program run on the GPU once for each
fragment (pixel-candidate) displayed on
screen.
Inputs: varying variables from Vertex Shader
Outputs: pixel color: gl_FragColor
Pixels are produced by “Rasterization”
Program
All the shaders are compiled and linked together
similar to C++ program.
QOpenGLShaderProgram makes it easy
Once compiled and linked bind() must be called
to make it active.
Hold On ...
You may notice the fragment shader is
assigning the output color directly from it’s
input varying v_color variable set by the
Vertex Shader.
How is it that the colors are “mixed” inside the
triangle?
Outputs of the vertex shader (and
corresponding inputs to the pixel shader) are
interpolated between the vertices.
Equivalent to glShadeModel(GL_SMOOTH);
What about GL_FLAT ?
Okay so attribute data output from the vertex
shader is interpolated to the pixel shader
inputs.
What about glShadeModel(GL_FLAT)?
Use flat attribute on variable declaration in
shader code.
flat varying vec3 v_color;
Default is smooth. These are equivalent:
smooth varying vec3 v_color;
varying vec3 v_color;
Review: QGLBufferObject
Memory buffer on graphics card that holds
vertex attribute data.
Equivalent to glBegin/glEnd inside a display
list
Attributes inside glBegin/glEnd copied to
video card instead of being rendered.
Equivalent to alloc() on QGLBufferObject.
Vertex Buffer Objects (VBO) don’t save primitive
type.
Instead pass as parameter to glDraw()
Just like OpenGL 1.1 Vertex Arrays
Review: QGLVertexArrayObject
OpenGL 1.1 Vertex Arrays require setting up
attribute array specifications each time before
calling glDraw().
Modern OpenGL captures attribute array
specifications once when data is uploaded to
card using Vertex Array Objects (VAO).
VAO “remembers” vertex array state and
applies this state when .bind() is called.
Modern code only needs a vao.bind() before
glDraw()
Another thing to note …
Fixed-function primitive types: GL_QUAD,
GL_QUAD_STRIP, GL_POLYGON have been
removed.
You must change your geometry to
GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN, or GL_TRIANGLE.
Math
Fixed-function OpenGL had Matrix Stacks built
into the API.
Used to create concept of a “camera”
(GL_MODELVIEW) rendering a world through a
window (GL_PROJECTION) that’s painted on
your computer screen.
Convenience Functions: glLoadIdentity,
glTranslate, glRotate, glScale
Matrix stack: glMatrixMode,
glPushMatrix, glPopmatrix
Sorry...
Sorry, that’s all gone now.
You, the programmer, have to perform all this math.
Recall the vertex shader is responsible for outputting
the vertices clip-space position by assigning to
gl_Position.
It is this math that you use in the vertex shader to
perform this conversion.
On the CPU the typical thing to do is recreate the
camera/window idiom with model transform
matrices, a view transform matrix, and a projection
matrix.
Pass the matrices to the shaders as “uniforms”
Agnostic
Modern OpenGL is agnostic about these idioms.
But it does help you by providing matrix math
operators in the shader language.
You, the programmer, get to decide how to
transform your vertex positions to clip space.
If you can code it, you can use it.
Math Library
If you want to use the Model-View-Projection
concept in your program you have to perform
the math yourself.
Qt has a powerful/concise library built-in which
supports vectors, matrices, and quaternions.
Matrix functions to replace GL & GLU
gluPerspective, gluOrtho2D, glFrustum,
gluLookAt, glTranslate, glRotate, glScale,
etc.
Checkout: QVector[2,3,4]D, QQuaterion,
QMatrix4x4
Move out of Clip space (fixed-function)
Show code in Qt Creator.
Uniforms
A uniform is a OpenGL Shading Language
(GLSL) constant parameter.
Set in CPU code between glDraw() calls.
Constant in the fashion that it has a constant
value for all shader invocations originating
from glDraw() calls until the value is
changed.
Use QOpenGLProgram.setUniform() to
pass Model, View, Projection matrices to
shader code before drawing.
Move out of Clip Space (modern GL)
Show code in Qt Creator.
User Clip Planes
Another thing to note is the glClipPlane()
has been removed.
Perform point/plane equation tests in your pixel
shader and use keyword discard (instead of
assigning to gl_FragColor) to inform
OpenGL that that particular pixel should not be
displayed.
Managing OpenGL State
Another thing to note is that
glPushAttrib(), glPopAttrib(),
glPushClientAttrib() and
glPopClientAttrib() have been
removed.
You have to manually manage your OpenGL
state by either keeping track of it in your C++
program (the preferred method) or by using
glGet() to read the current state and then
restoring it afterwards.
Wrapping Up
We were able to cover transitioning from fixed-
function Vertex/Attribute data and the built-in
Matrix stacks (and associated matrix
functionality) to Modern OpenGL.
We learned that Modern OpenGL replaced the
“fixed” stuff with programmable shaders. We
learned about the Vertex and Fragment
shaders, what they do and how data flows
through them.
We learned that using Qt makes is very easy to
create cross-platform Modern OpenGL code.
For More Information
For more information checkout the four-part
blog series I wrote covering this topic.
www.ics.com/blog/fixed-function-modern-opengl-part-1-4
Also, check out our training class coming up in
April out in Silicon Valley
www.ics.com/learning/training/state-art-opengl-and-qt-3
Outline
For the Blog: Journal Entry Style
- Introduction:
Spent a lot of time in past life on porting
complex, scenegraph based, fixed function
OpenGL code to Modern Pipeline Code
...
- Three Things that spring out to be addressed
- Geometry and Lighting and Texturing
- Picking, Text is another one for another day
- Explain Geometry and Lighting using a simple
scene example
Simple Scene from <insert link here>
Screenshot
Code: window/context, geometry, drawing,
resize, camera modelview, projection, viewport,
light
Modern Code: QOpenGLWindow....
Geometry: VertexBuffer, IndexBuffer,
VertexArrayObjects, ...