Difference between revisions of "Discussion4S16"

From Immersive Visualization Lab Wiki
Jump to: navigation, search
(Outline setup)
 
(OpenGL Pipeline, Once More With Feeling: Filled in most parts. Intermediate save.)
Line 17: Line 17:
 
===Why?===
 
===Why?===
 
Remember how we discussed in [[Discussion3S16|week 3]] that the modern OpenGL pipeline offers flexibility? Another thing it provides is also skipping the overhead of constant CPU to GPU communication.
 
Remember how we discussed in [[Discussion3S16|week 3]] that the modern OpenGL pipeline offers flexibility? Another thing it provides is also skipping the overhead of constant CPU to GPU communication.
 +
 +
Below is an illustration of the various functions and language supported keywords that let us transfer data without jumping back and forth between the CPU and GPU.
 +
 +
[[File:GPUDataPipeline.png|800px]]
 +
 +
Once we've set this pipeline up, after <code>glDrawElements</code> is called, we never have to return back to the CPU until the GPU has finished blazingly quickly drawin the frame! We'll take a look at each section in detail.
  
 
===CPU to GLSL===
 
===CPU to GLSL===
 +
We've already learned one way to transfer data from the CPU to GLSL by means of VAOs in [[Discussion3S16|week 3's discussion]]. However, that was useful for passing in tons of vertex data that will differ per run of the vertex shader. What if all we want is a simpler data that will be uniform throughout our execution of the shaders?
 +
 +
This is where the <code>uniform</code> keyword comes in. If you declare a variable <code>uniform</code> in GLSL, it will be assigned an accessible location that we can store data to.
 +
 +
====Where is my variable?====
 +
<code>glGetUniformLocation(shaderProgram, variableName)</code> returns a <code>GLuint</code> which is the location of where the variable is stored. This variable location can be used in the <code>glUniform*</code> functions to move data into the GPU.
 +
 +
Usage in <code>Cube.cpp</code>'s <code>draw</code> method:
 +
<pre>
 +
GLuint MatrixID = glGetUniformLocation(shaderProgram, "MVP");
 +
</pre>
 +
 +
====How do I store things in them?====
 +
The suite of <code>glUniform*</code> functions help us send data from the CPU to the GPU. Below are some typically used examples.
 +
 +
* <code>glUniform1i(variableLocation, value)</code>: Used for passing in a single int value. This is extremely simple to use and we can just give it the uniform location ID and value.
 +
* <code>glUniform3fv(variableLocation, num, value)</code>: Used for passing in a vector of 3 floats. The <code>num</code> in the middle is how many vectors we want to pass in. This is usually 1, as we're passing in one vector at a time, unless we have an array of vectors we want to pass in.
 +
* <code>glUniformMatrix4fv(variableLocation, num, transpose, value)</code>: Used for passing in a whole 4 by 4 matrix. The only different syntax is the <code>transpose</code> boolean value. This will usually be <code>GL_FALSE</code> in our case as <code>glm</code> already uses column major, matching OpenGL's matrix storage scheme. See <code>Cube.cpp</code>'s <code>draw</code> method for an example.
 +
 +
You can view the full list and function signature in the [https://www.opengl.org/sdk/docs/man/html/glUniform.xhtml OpenGL's glUniform* spec].
  
 
===Vertex Shader to Fragment Shader===
 
===Vertex Shader to Fragment Shader===
 +
Attributes such as normals aren't uniform across a fragment shader. How do we pass on such variables from Vertex shader to fragment shader?
 +
 +
Again, the key is for us to not return to the CPU and cause overhead once the GPU has begun its work. The <code>out</code> and <code>in</code> keyword lets us send data from the vertex shader, down to the next shader that will run(usually the fragment shader).
 +
 +
===A Direction Light Example===

Revision as of 19:29, 18 April 2016

Contents

Overview

Week 4 discussion recap (04/18/16)

Materials

Ambient

Diffuse

Specular

Shininess

Fiat Lux

Some Notation

Directional Lights

Point Lights

Spot Lights

OpenGL Pipeline, Once More With Feeling

Why?

Remember how we discussed in week 3 that the modern OpenGL pipeline offers flexibility? Another thing it provides is also skipping the overhead of constant CPU to GPU communication.

Below is an illustration of the various functions and language supported keywords that let us transfer data without jumping back and forth between the CPU and GPU.

GPUDataPipeline.png

Once we've set this pipeline up, after glDrawElements is called, we never have to return back to the CPU until the GPU has finished blazingly quickly drawin the frame! We'll take a look at each section in detail.

CPU to GLSL

We've already learned one way to transfer data from the CPU to GLSL by means of VAOs in week 3's discussion. However, that was useful for passing in tons of vertex data that will differ per run of the vertex shader. What if all we want is a simpler data that will be uniform throughout our execution of the shaders?

This is where the uniform keyword comes in. If you declare a variable uniform in GLSL, it will be assigned an accessible location that we can store data to.

Where is my variable?

glGetUniformLocation(shaderProgram, variableName) returns a GLuint which is the location of where the variable is stored. This variable location can be used in the glUniform* functions to move data into the GPU.

Usage in Cube.cpp's draw method:

GLuint MatrixID = glGetUniformLocation(shaderProgram, "MVP");

How do I store things in them?

The suite of glUniform* functions help us send data from the CPU to the GPU. Below are some typically used examples.

  • glUniform1i(variableLocation, value): Used for passing in a single int value. This is extremely simple to use and we can just give it the uniform location ID and value.
  • glUniform3fv(variableLocation, num, value): Used for passing in a vector of 3 floats. The num in the middle is how many vectors we want to pass in. This is usually 1, as we're passing in one vector at a time, unless we have an array of vectors we want to pass in.
  • glUniformMatrix4fv(variableLocation, num, transpose, value): Used for passing in a whole 4 by 4 matrix. The only different syntax is the transpose boolean value. This will usually be GL_FALSE in our case as glm already uses column major, matching OpenGL's matrix storage scheme. See Cube.cpp's draw method for an example.

You can view the full list and function signature in the OpenGL's glUniform* spec.

Vertex Shader to Fragment Shader

Attributes such as normals aren't uniform across a fragment shader. How do we pass on such variables from Vertex shader to fragment shader?

Again, the key is for us to not return to the CPU and cause overhead once the GPU has begun its work. The out and in keyword lets us send data from the vertex shader, down to the next shader that will run(usually the fragment shader).

A Direction Light Example