Transcript Document

Chapter 03:
Graphics Primitives
Course web page:
http://www.gomezconsultants.com
Chapter #3
Outline
• OpenGL & GLUT basics
– User interaction
– 2-D drawing
– Graphics Primitives
OpenGL – What is It?
• GL (Graphics Library): Library of 2-D, 3-D drawing
primitives and operations
– API for 3-D hardware acceleration
• GLU (GL Utilities): Miscellaneous functions dealing
with camera set-up and higher-level shape
descriptions
• GLUT (GL Utility Toolkit): Window-system
independent toolkit with numerous utility functions,
mostly dealing with user interface
• Course web page has links to online function
references (functions from each library start with
library prefix—i.e., gl*, glu*, glut*)
Event-driven GLUT program structure
1. Configure and open window
2. Initialize OpenGL state, program
variables
3. Register callback functions
•
•
•
Display (where rendering occurs)
Resize
User input: keyboard, mouse clicks,
motion, etc.
4. Enter event processing loop
Portions of some slides adapted from “An Interactive Introduction to OpenGL Programming”,
D. Shreiner, E. Angel, V. Shreiner, SIGGRAPH 2001 course
OpenGL Architecture
Polynomial
Evaluator
CPU
Display
List
Per Vertex
Operations &
Primitive
Assembly
Rasterization
Texture
Memory
Pixel
Operations
Per Fragment
Operations
Frame
Buffer
OpenGL as a Renderer
• Geometric primitives
– points, lines and polygons
• Image Primitives
– images and bitmaps
– separate pipeline for images and geometry
• linked through texture mapping
• Rendering depends on state
– colors, materials, light sources, etc.
Related APIs
• AGL, GLX, WGL
– glue between OpenGL and windowing systems
• GLU (OpenGL Utility Library)
– part of OpenGL
– NURBS, tessellators, quadric shapes, etc.
• GLUT (OpenGL Utility Toolkit)
– portable windowing API
– not officially part of OpenGL
OpenGL and Related APIs
application program
OpenGL Motif
widget or similar
GLX, AGL
or WGL
X, Win32, Mac O/S
GLUT
GLU
GL
software and/or hardware
Simple OpenGL program
#include <stdio.h>
#include <GL/glut.h>
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(100, 100);
glutCreateWindow(“hello”);
init();
// set OpenGL states, variables
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
// register callback routines
glutMainLoop();
// enter event-driven loop
}
adapted from E. Angel
Simple JOGL program
import java.awt.*;
import java.awt.event.*;
import net.java.games.jogl.*;
public class Simple {
public static void main(String[] args) {
Frame simpleFrame = new Frame("simple");
GLCanvas drawable = GLDrawableFactory.getFactory().
createGLCanvas(new GLCapabilities());
drawable.addGLEventListener(new simpleRenderer());
simpleFrame.add(drawable);
simpleFrame.show();
}…
Simple JOGL program - continued
static class simpleRenderer implements GLEventListener {
public void displayChanged(GLDrawable drawable, …) {}
public void reshape(GLDrawable drawable, …) {}
public void display(GLDrawable drawable) {
private GL gl = drawable.getGL();
private GLU glu = drawable.getGLU();
gl.glClear(GL.GL_COLOR_BUFFER_BIT); // clear window
gl.glBegin(GL.GL_POLYGON);
// draw unit square polygon
gl.glVertex2f(-0.5f, -0.5f);
gl.glVertex2f(-0.5f, 0.5f);
gl.glVertex2f(0.5f, 0.5f);
gl.glVertex2f(0.5f, -0.5f);
gl.glEnd();
gl.glFlush();
// flush GL buffers
}
public void init(GLDrawable drawable) { }
}}
JOGL Programming
public class Simple {
public static void main(String[] args) {
Frame simpleFrame = new Frame("simple"); // AWT Frame or
Window
GLCapabilities glc = new GLCapabilities();
// Configure OpenGL
glc.setDoubleBuffered(false);
GLCanvas drawable = GLDrawableFactory.getFactory().
createGLCanvas(glc);
// Create OpenGL drawing area
drawable.addGLEventListener(new simpleRenderer());
simpleFrame.add(drawable); // Insert Drawing Routines
simpleFrame.setLocation(100,100); // Define Window properties
simpleFrame.setSize(500, 500);
simpleFrame.setVisibility(true); } … // Show window
Simple OpenGL program
#include <stdio.h>
#include <GL/glut.h>
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(100, 100);
glutCreateWindow(“hello”);
init();
// set OpenGL states, variables
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
// register callback routines
glutMainLoop();
// enter event-driven loop
}
adapted from E. Angel
Initialization
• glutInit: Pass command-line flags on to GLUT
• glutInitDisplayMode: OR together bit masks to set modes on
pixel type (indexed vs. true color), buffering, etc.
• glutInitWindowSize, glutCreateWindow: Set drawing window
attributes, then make it
• init(): Set OpenGL state, program variables
– Use GL types/typedefs GLfloat, GLint, GL_TRUE, GL_FALSE, etc. for
cross-platform compatibility
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, right, 0, top);
}
sets “units” of subsequent draw commands
OpenGL screen coordinates
• Bottom left corner is
origin
• gluOrtho2D() sets
the units of the screen
coordinate system
from Hill
• gluOrtho2D(0, w, 0, h) means the
coordinates are in units of pixels
• gluOrtho2D(0, 1, 0, 1) means the
coordinates are in units of “fractions of window
size” (regardless of actual window size)
Example: Specifying the center of a square
gluOrtho2D(0, 640, 0, 480)
(320, 240)
Example: Specifying the center of a square
gluOrtho2D(0, 1, 0, 1)
1
(0.5, 0.5)
1
This is the method used in hello.cpp on the course web page
Simple OpenGL program
#include <stdio.h>
#include <GL/glut.h>
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(100, 100);
glutCreateWindow(“hello”);
init();
// set OpenGL states, variables
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
// register callback routines
glutMainLoop();
// enter event-driven loop
}
adapted from E. Angel
Callback registration functions
• Keypress in window: glutKeyboardFunc()
• Button press/release: glutMouseFunc()
• Mouse movement with button down:
glutMotionFunc()
• Window reshaping: glutResizeFunc()
• Nothing happening: glutIdleFunc()
• Passive motion, other input devices, etc.:
See GLUT reference pages linked on course page
• Render: glutDisplayFunc()
Example: Keyboard callback
• What key has been pressed and where the
cursor is:
glutKeyboardFunc(keyboard);
void keyboard(char key, int x, int y)
{
switch(key) {
case ‘q’ : case ‘Q’ :
exit(1);
break;
case ‘r’ : case ‘R’ :
rotate_mode = GL_TRUE;
break;
}
}
Example: Mouse button callback
• Which mouse button, where, and has it been
pressed or released:
glutMouseFunc(mouse);
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
left_down = TRUE;
mouse_x = x;
mouse_y = y;
}
else if (state == GLUT_UP)
left_down = FALSE;
}
}
Example: Idle callback
• Use for animation and continuous update
glutIdleFunc(idle);
void idle(void)
{
// change position variables, etc.
t += dt;
}
// call glutDisplayFunc() callback ASAP
glutPostRedisplay();
Rendering Steps
•
In function registered with glutDisplayFunc():
1. Clear window
•
glClear(GL_COLOR_BUFFER_BIT);
2. Draw shapes
•
•
Set colors, patterns, point/line sizes
Specify type of geometric primitive(s) and list vertices
3. Swap buffers if display mode is GLUT_DOUBLE
4. Optionally force all operations to complete with
glFlush()
Single- vs. double-buffering
• Single-buffering: Draw directly to screen
buffer
• Double-buffering: Draw to offscreen
buffer, then make that the screen buffer
when done
• For animation, double-buffering is
better because it eliminates flickering
OpenGL Geometric Primitives
GL_LINES
GL_LINE_STRIP
GL_POINTS
GL_LINE_LOOP
GL_POLYGON
GL_TRIANGLES
GL_QUADS
GL_QUAD_STRIP
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
Specifying Geometric Primitives
• Primitives are specified using
glBegin(primType);
...
glEnd();
– primType determines how vertices are combined
GLfloat red, green, blue;
GLfloat x, y;
glBegin(primType);
for (i = 0; i < nVerts; i++) {
glColor3f(red, green, blue);
glVertex2f(x, y);
... // change coord. values
}
glEnd();
OpenGL Command Formats
glVertex3fv( v )
glColor3fv( v )
Number of
components
2 - (x,y)
3 - (x,y,z),
(r,g,b)
4 - (x,y,z,w),
(r,g,b,a)
Data Type
b
ub
s
us
i
ui
f
d
-
byte
unsigned byte
short
unsigned short
int
unsigned int
float
double
Vector
omit “v” for
scalar form–
e.g.,
glVertex2f(x, y)
glColor3f(r, g, b)
Drawing: Miscellaneous
• glColor(): Range is [0, 1] for each color
channel
• glRect(x1, y1, x2, y2) specifying
opposite corners of rectangle is equivalent to
GL_POLYGON with four vertices listed (i.e.,
filled)
• Can set persistent attributes outside of
glBegin()/ glEnd()
– glPointSize(GLfloat size)
– glLineWidth(GLfloat width)
Questions ?