openFrameworks 007 - GL

51,005 views
51,068 views

Published on

openFrameworks 007 - GL

Published in: Technology, Art & Photos
2 Comments
26 Likes
Statistics
Notes
No Downloads
Views
Total views
51,005
On SlideShare
0
From Embeds
0
Number of Embeds
32,158
Actions
Shares
0
Downloads
359
Comments
2
Likes
26
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • openFrameworks 007 - GL

    1. 1. openFrameworks openGL
    2. 2. openGLOF uses openGL to draw things to your screen.openGL is a standard which is implemented bymost big operating systems and video cards. It’sheavily in use by game developers.Besided openGL there exist another big playercalled DirectX. This is not (yet) used by OF.These slides give you a model of how openGLroughly works. For in depth information you canvisit www.opengl.org
    3. 3. GL ofVBO ofMaterial ofFBO ofTextureofShader ofGLRenderer ofLight ofGLUtilsofVboMesh
    4. 4. Overview GLofTextureAn ofTexture is an object which holds pixels and isused to draw images to your screen. When youwant to draw an image onto a lets say a 3D cube,you tell openGL what texture you want to use, thesize, how the pixels are stored in memory etc..etc.. Nice thing: you don’t need to know thedetails, ofTexture does it all for you.
    5. 5. Overview GLofLightofLight is used to tell openGL how to simulatelights in your 3D scene. In 3D graphics there are acouple of standard light models. As in the realworld not every light has the same effect on anobject; the same count for openGL. There are i.e.directional and spot lights.
    6. 6. Overview GLofMaterialEach object in the real world has a specific kind ofsurface. Some are rough some are smooth. UsingofMaterial you can define the what kind of materialyour 3D object has. openGL uses the materialproperties together with the light properties tocalculate the colors of your 3D object.
    7. 7. Overview GLofVboopenGL has the concept of “buffers”. In relationwith VBOs you can think of these as arrays withlots of data describing a 3D scene. For examplewhere the 3D vertices of a cube are located in yourworld. You can send these arrays with informationto your graphic card. VBO is short for Vertex BufferObject. ofVbo helps you managing the data youcan store in these buffers.
    8. 8. Overview GLofFboFrame Buffer Objects (FBO) are used to renderthings, which you normally render to your screento something else, often to another texture. FBOsare mostly used to apply special effects to yourscenes. ofFbo helps you to setup and manageFBOs.
    9. 9. Overview GLIn short... Frame Buffer Object used to render FBO ofFbo offscreen. Vertex Buffer Object: used to store VBO ofVbo data about your 3D scene. OpenGL uses light settings to calculate Light ofLight the colors of your 3D objects. Light color values are affected by the Material ofMaterial material properties.
    10. 10. importantDeprecatedThe current version of openFrameworks usesdeprecated openGL functions to simulate light andmaterials. So if you’re interested in how it’s done,make sure to look at the current state of openGL.Though you’re probably safe to use ofLight andofMaterialA very good, the best I’ve found, online and freetutorial can be found here:http://www.arcsynthesis.org/gltut/
    11. 11. ofLightsetup ofLightlight.enable();light.setDirectional();light.setPosition(0,0,150);ofFloatColor ambient_color(1.0, 0.0, 0.0,1.0);ofFloatColor diffuse_color(1.0, 1.0, 1.0);ofFloatColor specular_color(0.0, 1.0, 0.0);light.setAmbientColor(ambient_color);light.setDiffuseColor(diffuse_color);light.setSpecularColor(specular_color);
    12. 12. ofLightDraw something with light void testApp::draw(){ // use an easy cam! cam.begin(); // rotate around origin of view space float xx = 0; float yy = sin(ofGetElapsedTimef()*0.4)*150; float zz = cos(ofGetElapsedTimef()*0.4)*150; light.enable(); light.setPosition(xx,yy,zz); light.draw(); // draw a box ofPushStyle(); ofRotateY(45); ofSetColor(255,255,255); ofBox(0,0,10,220); ofPopStyle(); }
    13. 13. ofVboA VBO is an openGL concept used to reduce thenumber of openGL function calls. With one call youcan draw millions of vertices at once.ofVbo sets up all things related to VBOs. You needto provide the vertex data yourself.ofMesh (see the 3D keynote), is anopenFrameworks container for 3D related data.ofMesh and ofVbo are therefore very related andused together.
    14. 14. ofVboSo how does this work?Simple, first create an ofMesh and fill it with somevertices, then pass it to an ofVbo and you’re readyto go! // our vbo/mesh ofVbo my_vbo; ofMesh my_mesh; // store position data my_mesh.addVertex(ofVec3f(-1,0,1)); my_mesh.addVertex(ofVec3f(1,0,1)); my_mesh.addVertex(ofVec3f(1,0,-1)); my_mesh.addVertex(ofVec3f(-1,0,-1)); // pass the mesh to the vbo my_vbo.setMesh(my_mesh, GL_STATIC_DRAW);
    15. 15. ofVboGL_STATIC_DRAW (?)Here we use raw openGL. The VBO and relatedvertex data is stored in high performance memory.When you supply data to a VBO (remember, whichis just an array), you give openGL a hint on howoften this data is changed. openGL can applydifferent performance tricks based on this hint.
    16. 16. ofVboHints about VBO data When vertices data are never or almost never GL_STATIC_DRAW updatedGL_DYNAMIC_DRA When vertices data could be updated between each frames. W When vertices data could be updated betweenGL_STREAM_DRAW each rendering.
    17. 17. ofVboclass My3DObject : public ofNode {public: My3DObject() { // store position data my_mesh.addVertex(ofVec3f(-1,0,1)); my_mesh.addVertex(ofVec3f(1,0,1)); my_mesh.addVertex(ofVec3f(1,0,-1)); my_mesh.addVertex(ofVec3f(-1,0,-1)); // pass the mesh to the vbo my_vbo.setMesh(my_mesh, GL_STATIC_DRAW); } void customDraw() { setScale(100); glDisable(GL_CULL_FACE); We inherit from rotate(0.05, getXAxis()); my_vbo.draw(GL_QUADS, 0, 4); ofNode so we got all ofScale(1.1,1.1,1.1); the functions like } my_vbo.draw(GL_LINE_LOOP, 0, 4); scaling, positioning, ofVbo my_vbo; rotating etc.. ofMesh my_mesh;};
    18. 18. ofVboNote that when adding more information thenjust the positions, like color, normals, texcoords,you need to provide the same number ofelements. So 4 vertices mean 4 colors.// store position datamy_mesh.addVertex(ofVec3f(-1,0,1));my_mesh.addVertex(ofVec3f(1,0,1));my_mesh.addVertex(ofVec3f(1,0,-1));my_mesh.addVertex(ofVec3f(-1,0,-1)); // store colorsmy_mesh.addColor(ofFloatColor(1.0, 0.0, 0.0, 1.0));my_mesh.addColor(ofFloatColor(0.0, 1.0, 0.0, 1.0));my_mesh.addColor(ofFloatColor(0.0, 0.0, 1.0, 1.0));my_mesh.addColor(ofFloatColor(0.0, 1.0, 1.0, 1.0));
    19. 19. ofVboMeshvoid setMesh(const ofMesh& mesh, int usage)void updateMesh(const ofMesh& mesh)Vertex Datavoid setVertexData(const ofVec3f* verts, int total, int usage)void setVertexData(const ofVec2f* verts, int total, int usage)void updateVertexData(const ofVec3f* verts, int total)void updateVertexData(const ofVe2f* verts, int total)GLuint getVertId()
    20. 20. ofVboTexCoord datavoid setTexCoordData(const ofVec2f* texcoords, int total, int usage)void updateTexCoordData(const ofFloatColor* colors, int total)GLuint getTexCoordId()Normal datavoid updateNormalData(const ofFloatColor* colors, int total)void setNormalData(const ofVec3f* normals, int total, int usage)GLuint getNormalId()
    21. 21. ofVboColor datavoid setColorData(const ofFloatColor* colors, int total, int usage)void updateColorData(const ofFloatColor* colors, int total)GLuint getColorId()Index datavoid setIndexData(const ofIndexType* indices, int total, int usage)void updateIndexData(const oofIndexType* indices, int total)GLuint getIndexId()
    22. 22. ofFboA FBO, frame buffer object, is mainly used torender something to a offscreen “thing”. This thingcan be a texture which you then can apply onsomething else.Note: although a FBO has the word buffer in it, itdoes not allocate any memory itself. You hookupother objects that have memory storage such asrender buffers or textures.
    23. 23. ofFbo How to use an ofFbo Create a member for the ofFbo •Allocate the size of the FBO •Call begin() •[DRAW] •call end() •Use the fbo texture to draw the capture [DRAW]. Pseude code (!) my_fbo.allocate(320,240); ... my_fbo.begin(); my_cam.begin(); my_3d_object.draw(); my_cam.end(); my_fbo.end(); my_fbo.draw(0,0);
    24. 24. ofFbo exampleCustom 3D object using ofVbo and ofMesh testApp.h (standard functions hidden)class My3DObject : public ofNode {public: class testApp : public ofBaseApp{ My3DObject() { // store position data public: my_mesh.addVertex(ofVec3f(-1,0,1)); ofEasyCam cam; my_mesh.addVertex(ofVec3f(1,0,1)); My3DObject my_3d_object; my_mesh.addVertex(ofVec3f(1,0,-1)); ofFbo my_fbo; my_mesh.addVertex(ofVec3f(-1,0,-1)); }; my_mesh.addColor(ofFloatColor(1.0, 1.0, 0.0, 1.0)); my_mesh.addColor(ofFloatColor(1.0, 1.0, 1.0, 1.0)); my_mesh.addColor(ofFloatColor(1.0, 0.0, 1.0, 1.0)); my_mesh.addColor(ofFloatColor(0.0, 1.0, 1.0, 1.0)); // pass the mesh to the vbo my_vbo.setMesh(my_mesh, GL_STATIC_DRAW); } void customDraw() { setScale(100); glDisable(GL_CULL_FACE); // we want to see both sides. rotate(0.05, getXAxis()); my_vbo.draw(GL_QUADS, 0, 4); ofScale(1.1,1.1,1.1); my_vbo.draw(GL_LINE_LOOP, 0, 4); } ofVbo my_vbo; ofMesh my_mesh;};
    25. 25. ofFbo example Drawing the VBO (not into the FBO...yet)void testApp::setup(){ ofBackground(33,33,33); my_fbo.allocate(ofGetWidth(),ofGetHeight());}void testApp::draw(){ cam.begin(); my_3d_object.draw();}
    26. 26. ofFbo example Drawing into the FBOvoid testApp::setup(){ ofBackground(33,33,33); my_fbo.allocate(ofGetWidth(),ofGetHeight());}void testApp::draw(){ my_fbo.begin(); cam.begin(); my_3d_object.draw(); cam.end(); my_fbo.end(); my_fbo.draw(0,0,320,240);}
    27. 27. ofFbo example Drawing the FBO texture more then oncevoid testApp::draw(){ cam.begin(); my_fbo.begin(); cam.begin(); my_3d_object.draw(); cam.end(); my_fbo.end(); for(int i = 0; i < 2; ++i) { for(int j = 0; j < 2; ++j) { my_fbo.draw(i*320,j*240,320,240); } }}
    28. 28. ofFbovoid allocate(int width, int height, int internalformat = GL_RGBA, int numSamples = 0)void allocateForShadow(int width, int height)void draw(float x, float y)void draw(float x, float y, float width, float height)float getWidth()float getHeight()void begin()void end()ofTexture& getTexture(int attachmnetPoint = 0)For more information see ofFbo.h
    29. 29. ofShaderShaders let you create amazing effects. A shader isa small program which runs on your graphics card.There are several kinds of programs you can createand the programs run in parallel on your graphicscard.You can create a shader for vertices and i.e.change the position of these. Such a shader iscalled a vertex shader. Another type of shader iscalled a fragment shader which operates on onepixel.
    30. 30. ofShader Vertex and fragment shadersSo each shader has a specific purpose. Vertex andfragment shaders form a “group”. Often with a“shader” we mean both a vertex and fragmentshader.There are more kinds of shaders like geometryshaders which let you generate vertices on thegraphics card. Mac OSX 10.6.x does not supportthese. 10.7 will!
    31. 31. ofShaderFor a shader you need to write the code for theshader-program. The language is called openGLShader Language (GLSL) and looks a lot like C.Just like any other programming language youneed to compile it. This is done by the openGLdriver. openGL provides functions to compile theshaders.ofShader sets up all necessary things like loadingthe shader, compiling, linking, etc..
    32. 32. ofShaderGeometry Shader Shaders are executed in different, successive stages. Vertex ShaderFragment Shader
    33. 33. ofShaderCommonly used file extensions .vert For vertex shaders .frag For fragment shaders .geom For geometry shaders
    34. 34. Vertex Shader Basic vertex shader example void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }This example shows a very basic shader. It uses(by openGL) globally defined variables. gl_Position The final position of the 3D point gl_ModelViewProjectionMatrix Converts a point from object space to screen space The 3D position we’re working with. When you created gl_Vertex an ofMesh and added vertices to it, this variable will hold the value of the set vertices.
    35. 35. Fragment Shader Basic fragment shader example void main() { gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); }A fragment shader is executed for each fragmentand is the final shader stage. It is executed afterthe vertex shader. gl_FragColor The final color of a fragment
    36. 36. Recap shadersSo what you need to remember is that a shader is aprogram which runs on GPU. The vertex shader isused to set a position of a 3D point; the fragmentshader is used to set the color of a fragment.There are several globally defined variables, i.e.gl_Position, gl_ModelViewProjectionMatrix,gl_Vertex, gl_FragData.Note: some of these are deprecated
    37. 37. Shader programmingGLSL looks like C. There are several data types andfunctions. Just like any other language thevariables have scope.Some common data types are int, vec2, vec3, vec4,mat3 and mat4. For boolean values you can use anint. GLSL has some special variable identifierscalled varying and uniform.varying variables will be interpolated between thevertex and fragment shader. uniform variable willstay... uniform (immutable)
    38. 38. Shader programmingLets say you have two vertices and a varyingvariable. When the value is 0.0 for the first vertexand 1.0 for the second vertex it will beinterpolated between 0.0 and 1.0 between thevertices. v0 0.1 0.5 0.95 v1
    39. 39. Shader programmingUniform variables are used to “communicate”between a shader and the host application (the OFapplication in this case).To change a value of an uniform variable yourapplication needs to know where in (GPU) memorythe location of the variable is stored. openGL usesglGetUniformLocation(program, name) for this.You don’t have to worry about this becauseofShader handles this for you.
    40. 40. AttributesThere is another type of variables I didn’t mentionyet. Attributes are a special kind of variables whichare the way to go when you want to startprogramming shaders. They allow you to usecustom data for gl_Vertex, gl_FrontColor,gl_TexCoord etc... For now we will focus on theglobally defined variables as this makes it a loteasier to start creating shaders.
    41. 41. Using ofShaderTo create a shader, follow these steps:1. Lets assume we call the shader “my_shader”. Then create two files my_shader.vert and my_shader.frag in your data directory.2. Create a member ofShader my_shader in your testApp.3. Load the shaders4. Create a simple ofVBO/ofMesh and draw while the shader is enabled.
    42. 42. 1. create shader filesbin/data/my_shader.vertvoid main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;}bin/data/my_shader.fragvoid main() { gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);}
    43. 43. 2. create ofShader member testApp.h (we add some more members at step 4) class testApp : public ofBaseApp{ public: ofShader my_shader; }
    44. 44. 3. Load the shaderstestApp.cpp (we add some more code at the next step) void testApp::setup(){ my_shader.load("of"); }
    45. 45. 4a. Create simple ofVbo and ofMesh testApp.h class testApp : public ofBaseApp{ public: ofShader my_shader; ofMesh my_mesh; ofVbo my_vbo; ofEasyCam cam; } testApp.cpp void testApp::setup(){ // Load of.vert and of.frag my_shader.load("of"); // Create a simple QUAD float s = 100; my_mesh.addVertex(ofVec3f(-s,s,0)); my_mesh.addVertex(ofVec3f(s,s,0)); my_mesh.addVertex(ofVec3f(s,-s,0)); my_mesh.addVertex(ofVec3f(-s,-s,0)); my_vbo.setMesh(my_mesh, GL_STATIC_DRAW); }
    46. 46. 4b. Draw using shader testApp.cpp void testApp::draw(){ cam.begin(); my_shader.begin(); my_vbo.draw(GL_QUADS,0,4); my_shader.end(); cam.end(); }
    47. 47. Using ofShader - all codetestApp.h testApp.cpp void testApp::setup(){class testApp : public ofBaseApp{ ofBackground(33,33,33); public: ofShader my_shader; ofMesh my_mesh; // Load of.vert and of.frag ofVbo my_vbo; my_shader.load("of"); ofEasyCam cam;} // Create a simple QUAD float s = 100; my_mesh.addVertex(ofVec3f(-s,s,0)); my_mesh.addVertex(ofVec3f(s,s,0));of.vert my_mesh.addVertex(ofVec3f(s,-s,0));void main() { my_mesh.addVertex(ofVec3f(-s,-s,0)); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; my_vbo.setMesh(my_mesh, GL_STATIC_DRAW);} }of.frag void testApp::draw(){ cam.begin();void main() { my_shader.begin(); gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); my_vbo.draw(GL_QUADS,0,4);} my_shader.end(); cam.end(); }
    48. 48. ofShaderUsing uniformsUniforms allow you to change values of variables in ashader. You can do this by defining a uniformvariable and using one of the setUniform**()functions. The next example uses an uniform tochange the value of gl_FragData
    49. 49. ofShaderUsing uniforms - vertex shaderuniform int u_color;void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;}Using uniforms - fragment shaderuniform int u_color;void main() { vec4 diffuse_color = vec4(1.0, 0.0, 0.0, 1.0); if(u_color == 1) { diffuse_color.rgb = vec3(1.0, 0.0, 0.0); } else if(u_color == 2) { diffuse_color.rgb = vec3(0.0, 1.0, 0.0); } else if(u_color == 3) { diffuse_color.rgb = vec3(0.0, 0.0, 1.0); } gl_FragColor = diffuse_color;}
    50. 50. ofShaderUsing uniformsWhen you want to set an uniform value make surethat you enable the shader first! You can do this bycalling thebegin() function. void testApp::draw(){ cam.begin(); my_shader.begin(); my_shader.setUniform1i("u_color", use_color); my_vbo.draw(GL_QUADS,0,4); my_shader.end(); cam.end(); }
    51. 51. ofShaderUsing uniformsPress “1” Press “2” Press “3”
    52. 52. ofShader Simple light Here follows an example of a simple light shader. For more information on shaders you can visit this page which has lots of interesting information: http://www.arcsynthesis.org/gltut/of.vert of.fragvarying vec3 v_light_dir;varying vec3 v_normal; varying vec3 v_light_dir;uniform float time; varying vec3 v_normal; uniform float time;void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; void main() { // get view space position. vec4 diffuse_color = vec4(1.0, 0.0, 0.0, 1.0); vec4 position = gl_ModelViewMatrix * gl_Vertex; // IMPORTANT: you need to normalize the normal and light dir! // we create our light position in "view space". float ndotl = max(dot(normalize(v_normal), normalize(v_light_dir)),0.0); vec3 light_position = vec3(1.0, sin(time)*130.0,1.0); vec4 result_color = diffuse_color * ndotl; v_light_dir = (position.xyz - light_position); gl_FragColor = result_color; } // get normal in eye coordinates. v_normal = (gl_NormalMatrix * gl_Normal);}
    53. 53. ofShaderGeneralvoid load(string shaderName)void load(string vertName, string fragName, string geomName = “”)void begin()void end()Uniforms: integersvoid setUniformTexture(const char* name, ofBaseHasTexture& img, int textureLocation)void setUniformTexture(const char* name, ofTexture& img, int textureLocation)void setUniform1i(const char* name, int v1)void setUniform2i(const char* name, int v1, int v2)void setUniform3i(const char* name, int v1, int v2, int v3)void setUniform4i(const char* name, int v1, int v2, int v3, int v4)
    54. 54. ofShaderUniforms: floatsvoid setUniform1f(const char* name, float v1)void setUniform2f(const char* name, float v1, float v2)void setUniform3f(const char* name, float v1, float v2, float v3)void setUniform4f(const char* name, float v1, float v2, float v3, float v4)Uniforms: floats arraysvoid setUniform1f(const char* name, float* v, int count = 1)void setUniform2f(const char* name, float* v, int count = 1)void setUniform3f(const char* name, float* v, int count = 1)void setUniform4f(const char* name, float* v, int count = 1)For more information see ofShader.h
    55. 55. roxluwww.roxlu.com

    ×