240 likes | 322 Views
CSC345: Advanced Graphics & Virtual Environments. Lecture 2: Introduction to OpenGL (2) Patrick Olivier p.l.olivier@ncl.ac.uk 2 nd floor in the Devonshire Building. GL_POINTS. GL_POLYGON. GL_LINE_STRIP. GL_LINES. GL_LINE_LOOP. GL_TRIANGLES. GL_QUAD_STRIP. GL_TRIANGLE_FAN.
E N D
CSC345: Advanced Graphics &Virtual Environments Lecture 2: Introduction to OpenGL (2) Patrick Olivier p.l.olivier@ncl.ac.uk 2nd floor in the Devonshire Building Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
GL_POINTS GL_POLYGON GL_LINE_STRIP GL_LINES GL_LINE_LOOP GL_TRIANGLES GL_QUAD_STRIP GL_TRIANGLE_FAN GL_TRIANGLE_STRIP OpenGL Primitives Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Polygon issues • OpenGL will only display polygons correctly that are • Simple: edges cannot cross • Convex: All points on line segment between two points in a polygon are also in the polygon • Flat: all vertices are in the same plane • User program can check if above true • OpenGL will produce output if these conditions are violated but it may not be what is desired • Triangles satisfy all conditions Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Attributes • Attributes are part of the OpenGL state and determine the appearance of objects • Color (points, lines, polygons) • Size and width (points, lines) • Stipple pattern (lines, polygons) • Polygon mode • Display as filled: solid color or stipple pattern • Display edges • Display vertices Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Colour (color!) • Each colour component stored separately in frame buffer • Usually 8 bits per component in buffer glColor3f ranges from 0.0 to 1.0 glColor3ub ranges from 0 to 255 • Colour set by glColor is part of the state (used until changed) • Colours (all attributes) not part of object - assigned when rendering • We can create (conceptual) vertex colours by: glColor; glVertex; glColor; glVertex • We can create (conceptual) vertex colours by: • 1st vertex colour:glShadeModel(GL_SMOOTH) • Interpolates:glShadeModel(GL_FLAT) Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Viewports • Do not have use the entire window for the image: glViewport(x,y,w,h) • Values in pixels (screen coordinates) Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
OpenGL and 3D applications • In OpenGL, two-dimensional applications are a special case of three-dimensional graphics • Going to 3D • Not much changes • Use glVertex3*( ) • Worry about the order in which polygons are drawn or use hidden-surface removal • Polygons should be simple, convex, flat Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Sierpinski gasket or fractal (2D) • Start with a triangle • Connect bisectors of sides and remove central triangle • Repeat Repeated 5 times Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Gasket program #include <GL/glut.h> /* initial triangle */ GLfloat v[3][2]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}}; int n; /* number of recursive steps */ void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* display one triangle */ { glVertex2fv(a); glVertex2fv(b); glVertex2fv(c); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Triangle subdivision void divide_triangle(GLfloat *a,GLfloat *b, GLfloat *c, int m) { /* triangle subdivision using vertex numbers */ point2 v0, v1, v2; int j; if(m>0) { for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2; for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2; for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2; divide_triangle(a, v0, v1, m-1); divide_triangle(c, v1, v2, m-1); divide_triangle(b, v2, v0, m-1); } /* draw triangle at end of recursion */ else(triangle(a,b,c)); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
void display() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); divide_triangle(v[0], v[1], v[2], n); glEnd(); glFlush(); } void myinit() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glClearColor (1.0, 1.0, 1.0,1.0) glColor3f(0.0,0.0,0.0); }
main function int main(int argc, char **argv) { n=4; glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow(“2D Gasket"); glutDisplayFunc(display); myinit(); glutMainLoop(); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
3D Gasket • We can easily make the program three-dimensional: GLfloat v[3][3] glVertex3f glOrtho • Not interesting - instead, start with a tetrahedron Repeated 5 times Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Triangle code void triangle( GLfloat *a, GLfloat *b, GLfloat *c) { glVertex3fv(a); glVertex3fv(b); glVertex3fv(c); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Subdivision code void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int m) { GLfloat v1[3], v2[3], v3[3]; int j; if(m>0) { for(j=0; j<3; j++) v1[j]=(a[j]+b[j])/2; for(j=0; j<3; j++) v2[j]=(a[j]+c[j])/2; for(j=0; j<3; j++) v3[j]=(b[j]+c[j])/2; divide_triangle(a, v1, v2, m-1); divide_triangle(c, v2, v3, m-1); divide_triangle(b, v3, v1, m-1); } else(triangle(a,b,c)); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Tetrahedron code void tetrahedron( int m) { glColor3f(1.0,0.0,0.0); divide_triangle(v[0], v[1], v[2], m); glColor3f(0.0,1.0,0.0); divide_triangle(v[3], v[2], v[1], m); glColor3f(0.0,0.0,1.0); divide_triangle(v[0], v[3], v[1], m); glColor3f(0.0,0.0,0.0); divide_triangle(v[0], v[2], v[3], m); } Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Hidden surface removal • The triangles are drawn in order they are defined so the front triangles are not always rendered in front triangles behind them • We want to see only those surfaces in front of other surfaces • OpenGL uses a hidden-surface method called the z-buffer algorithm that saves depth information as objects are rendered so that only the front objects appear in the image Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Using the z-buffer • Requested in main.c • glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH) • Enabled in init.c • glEnable(GL_DEPTH_TEST) • Cleared in the display callback • glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Input & interaction • Most systems have more than one input device, each of which can be triggered at an arbitrary time by a user • Each trigger generates an event whose measure is put in an event queue which can be examined by the user program Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Event types • Window: resize, expose, iconify • Mouse: click one or more buttons • Motion: move mouse • Keyboard: press or release a key • Idle: nonevent (define what should be done if no other event is in queue) Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Callbacks • Programming interface for event-driven input • Define a callback function for each type of event the graphics system recognizes • This user-supplied function is executed when the event occurs • GLUT example: /* mouse callback function */ glutMouseFunc(mymouse) Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
GLUT callbacks GLUT recognizes a subset of the events recognized by any particular window system (Windows, X, Macintosh) • glutDisplayFunc • glutMouseFunc • glutReshapeFunc • glutKeyboardFunc • glutIdleFunc • glutMotionFunc • glutPassiveMotionFunc Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
The display callback • Recall that the last line in main.c for a program using GLUT must be glutMainLoop()which puts the program in an infinite event loop • In each pass through the event loop, GLUT • looks at the events in the queue • for each event in the queue, GLUT executes the appropriate callback function if one is defined • if no callback is defined for the event, the event is ignored Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)
Posting redisplays • Many events may invoke the display callback function which can lead to multiple executions of the display callback on a single pass through the event loop • We can avoid this problem by instead using glutPostRedisplay()which sets a flag. • GLUT checks to see if the flag is set at the end of the event loop • If set then the display callback function is executed Based on: Angel (4th Edition) & Akeine-Möller & Haines (2nd Edition)