opengl shader language vertex and fragment shading programs

20
OpenGL Shader Language Vertex and Fragment Shading Programs

Upload: phillip-nicholson

Post on 05-Jan-2016

237 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: OpenGL Shader Language Vertex and Fragment Shading Programs

OpenGL Shader LanguageVertex and

Fragment Shading Programs

Page 2: OpenGL Shader Language Vertex and Fragment Shading Programs

Shader Pipeline

VertexShader

Program

FragmentShader

Program

GeometryShader

Program

Vertex shader takes in attributes (like normals), performs calculations, and sends the colour out to the fragment shader.

Fragment shader takes data in from the vertex shader and calculates pixel (fragment) colour.

Geometry Shaders are covered in chapter 11 of the OpenGL Super Bible.

Page 3: OpenGL Shader Language Vertex and Fragment Shading Programs

Data types

Primitives:

bool, int, uint, float

Vectors:

vec2, vec3, vec4 (floats)

ivec2, ivec3, ivec4 (integers)

uvec2.... bvec2... (uints and bools)

Matrices: *floating point only

mat2 = mat2x2, mat3 = mat3x3, mat4=mat4x4

mat2x3, mat2x4, mat3x2, mat3x4, mat4x2,

mat4x3

Page 4: OpenGL Shader Language Vertex and Fragment Shading Programs

Vector Operations

Initializing:

vec4 vPos; vec4 vPos = vec4(0,0,0,1.0f);

Addition:

vPos = vOldPos + vOffset;(also +=)

Scaled:

vPos *= float;

Reassigning: xyzw, rgba, stpq

vPos.x = 1.0f; vPos.xy = vec2(0,1.0f);

vPos.xyz = vNewPos.xyz;

(use any three any time but don't mix: ~.st = ~.xt)

Page 5: OpenGL Shader Language Vertex and Fragment Shading Programs

Matrix Operations

Matrices are arrays of column vectors.

Initializing:

mat2 m = mat2(1.0f,0.0f,0.0f,1.0f);

mat4x4 mvpMatrix = mat4(1.0f);

mvpMatrix[3] = vec4(0,0,0,1.0f);

Multiplication:

vOutPos = mvpMatrix * vVertex;

Extraction:

vec4 vTrans = mvpMatrix[3].xyz;

Page 6: OpenGL Shader Language Vertex and Fragment Shading Programs

Storage Qualifiers 1

For vertex and fragment program globals.

<none> only local variable

const same as c++

in variable passed from previous stage

out pass to the next stage or assign a

return value in a function

inout read/write for local function params

uniform client code value that doesn't change

centroiduses centroid interpolation on ins/outs

(see chapter 9 on multi sampling)

Page 7: OpenGL Shader Language Vertex and Fragment Shading Programs

Storage Qualifiers 2

By default parameters are smoothly interpolated between stages in a perspective correct manner.

nopersepective out disable perspective inter.

flat out disable all interpolation

smooth out specify smooth inter. in a

perspective correct

manner (the default)

Page 8: OpenGL Shader Language Vertex and Fragment Shading Programs

A Vertex Shader

#version 330 //shader language version

in vec4 vVertex; //input vertex position data

in vec4 vColour; //input vertex colour data

out vec4 vOutColour; //output colour to frag.

void main (void) {

vOutColour = vColour;

gl_Position = vVertex; //needed by geometry

}

(page 236 from the Super Bible)

Page 9: OpenGL Shader Language Vertex and Fragment Shading Programs

A Fragment Shader

#version 330

out vec4 vFragColour; //output colour

in vec4 vOutColour; //in from vertex stage

void main(void){

vFragColour = vOutColour;

}

(page 236 from the Super Bible)

Page 10: OpenGL Shader Language Vertex and Fragment Shading Programs

Using the Shader

Check gltLoadShaderPairWithAttributes(....) function in ~~~~.cpp for a look at how this works.

Note that this calls gltLoadShaderFile(.....) in the file ~~~~~.cpp

Page 11: OpenGL Shader Language Vertex and Fragment Shading Programs

Creating a Shader (GLTools)

A custom shader can be created with the following command:

Glint myShader = gltLoadShaderPairWithAttributes(“shader.vp”, “shader.fp”,2,GLT_ATTRIBUTE_VERTEX, “vVertex”,GLT_ATTRIBUTE_NORMAL,”vNormal”)

2 = # of input attributes to vertex shader

vVertex = changing vertex position to v Shader

cNormal = changing vertex normal to v Shader

Page 12: OpenGL Shader Language Vertex and Fragment Shading Programs

Creating a Shader (Stand Alone)

First open the file and extract all information to a GLchar array.

GLchar* vertShader = (GLchar*) fileText;

GLuint vertShaderNum;

glShaderSource(shaderNum, 1, vertShader, Null);

The variable 'vertShaderNum' is what we will use to imply the vertex shader for remaining calls to openGL.

Page 13: OpenGL Shader Language Vertex and Fragment Shading Programs

Compile, Combine, Delete

To compile the shaders:

glCompileShader(vertShaderNum);

To create the main shader program:

GLint shaderProg = glCreateProgram();

glAttachShader(shaderProg,vertShaderNum);

glAttachShader(shaderProg,fragShaderNum);

glLinkProgram(shaderProg);

To delete the shaders and shader program:

glDeleteShader(GLint shaderNumber);

glDeleteProgram(shaderProg);

Page 14: OpenGL Shader Language Vertex and Fragment Shading Programs

Input Attribute Locations

You will need to get the attribute locations of the 'in' variables for the vertex shader.

glBindAttribLocation(shaderProg, index, “vVertex”);

shaderProg = our compiled shader program

GLint index = index that “vVertex” has in the shader's variable list

“vVertex” = an input vector for the shader program specifying the vertex positions

Page 15: OpenGL Shader Language Vertex and Fragment Shading Programs

Vertex Buffer ObjectsVertex Array Objects

VBOs can be used by the OpenGL shader to make efficient decisions on how to use your vertex data on the graphics card.

VBOs can store data such as vertex positions, colors, normals, etc. VAOs can be used to store multiple VBOs.

GLuint vao[1], vbo;

glGenVertexArrays(1, &vao);

glBindVertexArrays(vao[0]);

glGenBuffers(1, &vbo)

glBindBuffer(GL_ARRAY_BUFFER, vbo);

Page 16: OpenGL Shader Language Vertex and Fragment Shading Programs

Initializing the VBO

Allocate space:

glBufferData(GL_ARRAY_BUFFER, sizeof(positions)+sizeof(colors), NULL, GL_STATIC_DRAW )

where positions and colors are float arrays, we need their size to determine how big the buffer is.

NULL can be a pointer to the data but here we will show how to store the info by hand

page 692 of Super Bible for an in depth discussion of the other two parameters

Page 17: OpenGL Shader Language Vertex and Fragment Shading Programs

Loading data into the VBO

Loading data is done easily with the command:

glBufferSubData(type, startPos,sizeofDat,data);

where type = GL_ARRAY_BUFFER for now

startPos = 0, sizeof(verts), sizeof(verts) + sizeof(colors)... the index to start data at

data = GLfloat* / GLfloat[]

Do this for all vertex data then then for another buffer load faces the same way except:

type = GL_ELEMENT_ARRAY

Page 18: OpenGL Shader Language Vertex and Fragment Shading Programs

Mapping VBO vertex data to the Shader

First enable the input attribute that we want to map with the index obtained in slide 14:

glEnableVertexAttribArray(index);

Now we will provide the data to map:

glVertexAttribPoint(index, size, type, stride, pointer)

size: the size of a single component (1,2,3,4)

type: kind of data stride: offset between data

pointer: the startPos as in slide 17 for data in the currently bound GL_ARRAY_BUFFER

Page 19: OpenGL Shader Language Vertex and Fragment Shading Programs

Uniforms

You may want some data to be the same across all vertices in the shader such as the projection and model view matrices.

First get the location during setupRC():

GLint MVPlocation = glGetUniformLocation(shader, “mvpMatrix”);

Then change it in renderScene() right before drawing and after glUseProgram(shader):

glUniformMatrix4fv(MVPlocation,1,GL_FALSE, transformPipeline.getModelViewPro....)

1 = number of elements to modify, GL_FALSE = transpose mat status

Page 20: OpenGL Shader Language Vertex and Fragment Shading Programs

Error Checking

Sometimes errors may arise during compilation or shader use.

glGetShaderiv(program, symbol, &outValue);

where program = individual or complete shader program

symbol = GL_COMPILE_STATUS, GL_LINK_STATUS, etc.

outValue = a boolean passed by reference

you can also check for any errors that have occured with:

cout << glGetError() << endl;