3. ofCamera
Camera movement and matrices
• Extends from ofNode
• Basic GLUT camera functions
• Coordinate conversions
4. ofCamera
Frustum setup
angle of field of view in y direction, in degrees
setFov(float)
(45-60)
setNearClip(float) near clipping plane distance
setFarClip(float) set far clipping plane distance
6. ofCamera
Coordinate conversion
worldToScreen() Convert openGL world to screen
screenToWorld() Convert screen to GL world
worldToCamera() Convert world to camera
cameraToWorld() Convert camera to world
7. ofCamera
testApp.h
class testApp : public ofBaseApp{
public:
...
ofCamera cam;
};
8. ofCamera
testApp.cpp
void testApp::setup(){
ofBackground(33,33,33);
cam.setNearClip(0.1);
cam.setFarClip(100);
// "1 meter" to the right, "5 meters" away from object
cam.setPosition(ofVec3f(1,0,5));
}
void testApp::draw(){
cam.begin();
glPointSize(10);
glBegin(GL_POINTS);
glVertex3f(0,0,0);
glEnd();
cam.end();
}
10. ofNode
3D object container
• Standard 3D scene item
• Manage position, scale and orientation
• Lots of fantastic helper functions
• ofCamera extends from this class
11. ofNode
Movement
truck() Move left to right (x-axis)
boom() Move up and down (y-axis)
dolly() Move forward and backward (z-axis)
setPosition() Set position directly
12. ofNode
Rotation
tilt() Rotate around x-axis
pan() Rotate around y-axis
dolly() Rotate around z-axis
rotate(a,axis) Rotate around arbitrary axis
13. ofNode
Testing movement/orientation
Apply ofNode transformation (does a
transformGL()
glPushMatrix/glMultMatrixf())
Does a glPopMatrix, call after transformGL and
restoreTransformGL()
drawing.
resetTransform() Resets the orientation and position
15. ofNode
Custom 3D nodes
• Create custom class and inherit from ofNode
• Implement virtual customDraw(void) member
function.
• To draw, just call draw(void) on instance
16. ofNode
Extend ofNode
class MyCustom3DNode : public ofNode {
public:
virtual void customDraw() {
ofSphere(0,0,0,0.7);
ofDrawAxis(2
);
}
};
17. ofEasyCam
Camera interaction made easy
begin()/end() Put your draw calls between these
setTarget(ofNode) Follow and look at a target
18. ofEasyCam
Custom ofNode - example ofEasyCam
class MyCustom3DNode : public ofNode {
public:
virtual void customDraw() {
ofSphere(0,0,0,0.7);
ofDrawAxis(2);
}
};
class testApp : public ofBaseApp{
public:
ofEasyCam easy_cam;
vector<MyCustom3DNode*> custom_nodes;
MyCustom3DNode* mover;
};
19. ofEasyCam
Custom ofNode - example ofEasyCam
void testApp::setup(){
ofBackground(33,33,33);
// set distance of camera "5" meters away
easy_cam.setDistance(5);
// create a bunch of custom 3D nodes
float r = 4;
for(int i = 0; i < 10; ++i) {
MyCustom3DNode* node = new MyCustom3DNode();
node->setPosition(
cos((float)i/10*TWO_PI) * r
,sin((float)i/10*TWO_PI) * r
,-5
);
custom_nodes.push_back(node);
mover = node;
}
// set target for camera
easy_cam.setTarget(*mover);
}
20. ofEasyCam
Custom ofNode - example ofEasyCam
void testApp::draw(){
easy_cam.begin();
// draw custom nodes.
for(int i = 0; i < custom_nodes.size(); ++i) {
custom_nodes[i]->draw();
}
// move over x-axis.
float truck_amount = sin(ofGetElapsedTimef()*0.5) * 0.001;
mover->truck(truck_amount);
easy_cam.end();
}
21. ofMesh
Container for all vertex related data
• Use this when working with 3D meshes. It creates a model that is used
by openGL to draw 3D shapes.
• Future proof (ready for modern openGL)
• Clean API for most used data:
add[Vertex,Color,TexCoord]()
• Nice interface for writing 3D exports (OBJ, PLY)
• Use this with Vertex Buffer Objects (VBO)
22. ofMesh
Adding vertices
addVertex(ofVec3f) Add one vertex
addVertices(vector<ofVec3f>&) Reference to ofVec3f
addVertices(ofVec3f*, int num) Pointer to vertices
setVertex(int index) Remove by index
Remove vertices
removeVertex(int index) Remove by index
clearVertices() Remove all vertices
Get vertex
getVertex(int) Get one vertex
23. ofMesh
Adding normals
addNormal(ofVec3f&) Add a normal
addNormals(vector<ofVec3f>) Add vector of normals
addNormals(ofVec3f*, int) Add array of normals
setNormal(int, ofVec3f&) Set one normal by index
Removing normals
removeNormal(int) Remove by index
clearNormals() Remove all normals
Retrieving normals
getNormal(int) Get normal by index
24. ofMesh
Adding indices
addIndex(ofIndexType) Add a index
addIndices(const<ofIndextype>&) Add a bunch of indices
addIndices(ofIndexType*,int) Add bunch of indices
setIndex(int, ofIndexType) Set a specific index
Removing indices
removeIndex(int i) Remove by index
clearIndices() Remove all indices
Retrieving indices
getIndex(int) Get index by index ;-)
25. ofMesh
Adding colors
addColor(const ofFloatColor& c) Add a index
addColors(const<ofFloatColor>& cols) Add a bunch of indices
addColors(const ofFloatColor* cols, int amt) Add bunch of indices
setColor(int index, const ofFloatColor& c) Set a specific index
Removing colors
removeColor(int index) Remove by index
clearColors() Remove all indices
Retrieving colors
ofFloatColor getColor(int i) Get index by index ;-)
26. ofMesh
Useful for GL_ARRAY_BUFFER / VBO
getNumVertices() Total number of vertices
getNumColors() Total number of colors
getNumTexCoords() Total number of texture coords
getNumIndices() Total number of indices
float* getVerticesPointer() Get a pointer to the vertices
float* getColorsPointer() Get a pointer to the colors
float* getNormalsPointer() Get pointer to stored normals
ofIndexType* getTexCoordsPointer() Get pointer to texcoords
27. ofMesh
Same API for the rest
• Same API for Colors, TexCoord
• Helper function addTriangle(int,int,int)
28. Create two planes testApp.cpp
void testApp::setup(){
// bottom
cube.addVertex(ofVec3f(-1,0,1));
cube.addVertex(ofVec3f(1,0,1));
cube.addVertex(ofVec3f(1,0,-1));
cube.addVertex(ofVec3f(-1,0,-1));
// top
cube.addVertex(ofVec3f(-1,1,1));
cube.addVertex(ofVec3f(1,1,1));
cube.addVertex(ofVec3f(1,1,-1));
cube.addVertex(ofVec3f(-1,1,-1));
// triangles bottom
cube.addIndex(0);
cube.addIndex(1);
cube.addIndex(2);
cube.addIndex(2);
cube.addIndex(3);
testApp.h
cube.addIndex(0);
class testApp : public ofBaseApp{
// triangles top
cube.addIndex(4);
public:
cube.addIndex(5);
ofMesh cube;
cube.addIndex(6);
};
cube.addIndex(6);
cube.addIndex(7);
cube.addIndex(4);
}
29. Create a cube testApp.cpp
void testApp::setup(){
// bottom vertices
cube.addVertex(ofVec3f(-1,0,1));
cube.addVertex(ofVec3f(1,0,1));
cube.addVertex(ofVec3f(1,0,-1));
cube.addVertex(ofVec3f(-1,0,-1));
// top vertices
cube.addVertex(ofVec3f(-1,1,1));
cube.addVertex(ofVec3f(1,1,1));
cube.addVertex(ofVec3f(1,1,-1));
cube.addVertex(ofVec3f(-1,1,-1));
// indices
cube.addTriangle(0,1,2); // bottom
cube.addTriangle(2,3,0);
cube.addTriangle(4,5,6); // top
cube.addTriangle(6,7,4);
cube.addTriangle(0,4,5); // front
cube.addTriangle(0,1,5);
testApp.h
cube.addTriangle(1,2,6); // right
cube.addTriangle(6,5,1);
class testApp : public ofBaseApp{
cube.addTriangle(2,6,3); // back
cube.addTriangle(3,7,6);
public:
cube.addTriangle(0,3,7); // left
ofMesh cube;
cube.addTriangle(7,4,0);
}; }