Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Programming in OpenGL Shaders

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 42

WEEK 3: PROGRAMMING IN

OPENGL 2 COMPLETE PROGRAMS


Kuliah Grafika Komputer Jurusan Teknik Informatika ITS 2014
Objectives
Build a complete first program
Introduce shaders
Introduce a standard program structure

Simple viewing
Two-dimensional viewing as a special case of three-
dimensional viewing

Initialization steps and program structure
Program Structure
Most OpenGL programs have a similar structure that
consists of the following functions
main():
specifies the callback functions
opens one or more windows with the required properties
enters event loop (last executable statement)
init(): sets the state variables
Viewing
Attributes
initShader(): read, compile, and link shaders
callbacks
Display function
Input and window functions
simple.c revisited
main() function similar to last lecture
Mostly GLUT functions

init() will allow more flexible colors

initShader() will hides details of setting up
shaders for now

Key issue is that we must form a data array to send
to GPU and then render it
main.c
GLUT functions
glutInit initializes the GLUT system allows it to receive
command line arguments (always include this line)

gluInitDisplayMode requests properties for the window
(the rendering context)
RGBA color (default) or indexed colour (rare now)
Double buffering (usually) or Single buffering (redraw flickers)
Depth buffer (usually in 3D) stores pixel depths to find closest surfaces
[usually with glEnable(GL_DEPTH_TEST);]
Properties are bitwise ORed together with | (vertical bar)

glutInitWindowSize in pixels

glutInitWindowPosition from top-left corner of display
GLUT functions
glutCreateWindow create window with title Title
many functions need to be called prior to creating the window
similarly many other functions can only be called afterwards
glutDisplayFunc set display callback
glutKeyboardFunc set keyboard callback
glutReshapeFunc set window resize callback
glutTimerFunc set timer callback
glutIdleFunc set idle callback

glutMainLoop enter infinite event loop
never returns, but may exit
Immediate Mode Graphics
Geometry specified by vertices
Locations in space( 2 or 3 dimensional)
Points, lines, circles, polygons, curves, surfaces

Immediate mode
Each time a vertex is specified in application, its location
is sent to the GPU
Old style uses glVertex
Creates bottleneck between CPU and GPU
Removed from OpenGL 3.1
Retained Mode Graphics
Put all vertex and attribute data in array

Send array to GPU to be rendered immediately

Almost OK but problem is we would have to send
array over each time we need another render of it

Better to send array over and store on GPU for
multiple renderings
Display Callback
Once we get data to GPU, we can initiate the
rendering with a simple callback
void mydisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);

// glFlush(); // Single buffering
glutSwapBuffers(); // Double buffering
}

Arrays are buffer objects that contain vertex arrays
Vertex Arrays
Vertices can have many attributes
Position
Color
Texture Coordinates
Application data

A vertex array holds these data

Using types in vec.h
point2 vertices[3] = {point2(0.0, 0.0),
point2( 0.0, 1.0), point2(1.0, 1.0)};
Vertex Array Object
Bundles all vertex data (positions, colors, ..,)

Get name for buffer then bind
GLunit abuffer;
glGenVertexArrays(1, &abuffer);
glBindVertexArray(abuffer);

At this point we have a current vertex array but no
contents

Use of glBindVertexArray lets us switch between
VBOs
Buffer Object
Buffers objects allow us to transfer large amounts
of data to the GPU

Need to create, bind and identify data
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER,
sizeof(points), points);

Data in current vertex array is sent to GPU

Initialization
Vertex array objects and buffer objects can be set up
on init()

Also set clear color and other OpenGL parameters

Also set up shaders as part of initialization
Read
Compile
Link

First lets consider a few other issues
Coordinate Systems
The units in points are determined by the application
and are called object, world, model or problem coordinates

Viewing specifications are also in object coordinates and it
is the size of the viewing volume that determines what will
appear in the image

Eventually, pixels will be produced in screen coordinates
(a.k.a. window coordinates)

OpenGL shaders also often use some internal
representations that usually are not visible to the
application, such as camera coordinates (generally prior to
perspective transformation)
OpenGL Camera
OpenGL places a camera at the origin in object
space pointing in the negative z direction

The default viewing volume
is a box centered at the
origin with a side of
length 2
Orthographic Viewing

z=0
z=0
In the default orthographic view, points are
projected forward along the z axis onto the
plane z=0
Viewports
Do not have use the entire window for the image:
glViewport(x,y,w,h)
Values in pixels (screen/window coordinates)
Transformations and Viewing
In OpenGL, projection is carried out by a projection matrix
(transformation)

Transformation functions are also used for changes in
coordinate systems

Pre 3.0 OpenGL had a set of transformation functions
which have been deprecated
Three choices in OpenGL 3+
Application code
GLSL functions
vec.h and mat.h
WEEK 3 PART 2: PROGRAMMING IN
OPENGL 2 SHADERS
Kuliah Grafika Komputer Jurusan Teknik Informatika ITS 2014
Objectives
Simple Shaders
Vertex shader
Fragment shaders

Programming shaders with GLSL

Finish first program
Vertex Shader Applications
Geometric transformations
Change relative location, rotation, scale of objects/camera
3D perspective transformation make far objects smaller
Moving vertices
Morphing
Wave motion & deformation due to physical forces
Particle effects for fire, smoke, rain, waterfalls,
Fractals
Lighting
Calculate shading color using light and surface properties
Can choose between less/more realistic models (unlike the fixed
pipeline)
Cartoon shaders, other special effects
Fragment Shader Applications
Per fragment lighting calculations
per vertex lighting per fragment lighting
Fragment Shader Applications
Texture mapping
smooth shading environment mapping bump mapping
Writing Shaders
First programmable shaders were programmed in an
assembly-like manner

OpenGL extensions added for vertex and fragment
shaders

Cg (C for graphics) C-like language for programming
shaders
Works with both OpenGL and DirectX
Interface to OpenGL complex

OpenGL Shading Language (GLSL)
GLSL
OpenGL Shading Language

Part of OpenGL 2.0 and up

High level C-like language

New data types
Matrices
Vectors
Samplers

As of OpenGL 3.1, application must provide shaders
Simple Vertex Shader
Execution Model
Simple Fragment Program
#version 150

out vec4 fragcolor;

void main(void) {
fragcolor = vec4(1.0, 0.0, 0.0, 1.0);
}
Execution Model
Data Types
C types: int, float, bool
Vectors:
float vec2, vec3, vec4
Also int (ivec) and boolean (bvec)
Matrices: mat2, mat3, mat4
Stored by columns
Standard referencing m[row][column]
C++ style constructors
vec3 a =vec3(1.0, 2.0, 3.0)
vec2 b = vec2(a)
Pointers
There are no pointers in GLSL

We can use C structs which can be copied back
from functions

Because matrices and vectors are basic types they
can be passed into and output from GLSL functions,
e.g.
mat3 func(mat3 a)
Qualifiers
GLSL has many of the same qualifiers such as const
as C/C++
Need others due to the nature of the execution
model
Variables can change
Once per primitive
Once per vertex
Once per fragment
At any time in the application
Vertex attributes are interpolated by the rasterizer
into fragment attributes
Attribute Qualifier
Attribute-qualified variables can change at most
once per vertex

There are a few built in variables such as
gl_Position but most have been deprecated

User defined (in application program)
Use in qualifier to get to shader
in float temperature
in vec3 velocity
Uniform Qualified
Variables that are constant for an entire primitive

Can be changed in application and sent to shaders

Cannot be changed in shader

Used to pass information to shader such as the
bounding box of a primitive
Varying Qualified
Variables that are passed from vertex shader to
fragment shader

Automatically interpolated by the rasterizer

Old style used the varying qualifier
varying vec4 color;

Now use out in vertex shader and in in the fragment
shader
out vec4 color;
Example: Vertex Shader
#version 150

const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
in vec4 vPosition;
out vec4 color_out;

void main(void)
{
gl_Position = vPosition;
color_out = red;
}
Required Fragment Shader
#version 150

in vec4 color_out;
out vec4 fragcolor;

void main(void) {

fragcolor = color_out;

}

// in pre-OpenGL 3.2 versions use built-in:
// gl_FragColor = color_out;
Passing values
call by value-return

Variables are copied in

Returned values are copied back

Three possibilities
in
out
inout (deprecated)
Operators and Functions
Standard C functions
Trigonometric
Arithmetic
Normalize, reflect, length

Overloading of vector and matrix types
mat4 a;
vec4 b, c, d;
c = b*a; // a column vector stored as a 1d array
d = a*b; // a row vector stored as a 1d array
Swizzling and Selection
Can refer to array elements by element using [] or
selection (.) operator with
x, y, z, w
r, g, b, a
s, t, p, q
a[2], a.b, a.z, a.p are the same

Swizzling operator lets us manipulate components
vec4 a;
a.yz = vec2(1.0, 2.0);
Next week: Programming in OpenGL
4-5: Polygons & Attributes, More GLSL

You might also like