Professional Documents
Culture Documents
CG-module 5
CG-module 5
CURVED SURFACES
Property1:
• A very useful property of a Bézier curve is that the curve
connects the first and last control point.
Property 2:
• Another important property of any Bézier curve is that it lies within
the convex hull (convex polygon boundary) of the control points.
• This follows from the fact that the Bézier blending functions are all
positive and their sum is always 1:
Other Properties:
#define BOX 1
glNewList(BOX, GL_COMPILE);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
glVertex2f(1.0,1.0);
glVertex2f(-1.0,1.0);
glEnd();
glEndList();
• GL_COMPILE – Tells the system to send the list to
the server but not to display its contents.
• GL_COMPILE_AND_EXECUTE – Immediate display
of the contents while the list is being constructed.
void ourFont()
{
glTranslatef(0.5,0.5,0.0);
glBegin(GL_QUAD_STRIP);
for(int i=0;i<=12;i++)
{
angle=3.14159/6.0*i;
glVertex2f(0.4*cos(angle),0.4*sin(angle));
glVertex2f(0.5*cos(angle),0.5*sin(angle));
}
glEnd();
}
Fonts in Glut
• GLUT provides a few raster and stroke fonts
Module-5
1
Input Devices
• Physical input devices
– Keyboard devices and pointing devices
• Logical input devices
2
Pointing Devices – 1/2
• Mouse
– Mechanical versus optical
• Trackball
• Data tablet
3
Pointing Devices – 2/2
• Lightpen
• Joystick
• Spaceball
4
Positioning
• Relative
– Mouse, trackball, trackpoint
• Absolute
– Data tablet
5
Logical Input Devices – 1/2
• Characteristics
– The measurements returned to the programs
– The time these measurements returned
• Six classes of logical input devices
6
Logical Input Devices – 2/2
• String: by keyboard
• Locator: by mouse or trackball
• Pick: id of the selected object is returned
• Choice: select one of a distinct number of options,
e.g. menus
• Valuators: e.g. boxes to provide value.
• Stroke: returns an array of locations: multiple uses of
a locator, could be implemented by a “mouse
dragging”
7
Input Modes:
Measure and Trigger
• Measure: what returns to the user program
• Trigger: a physical input to signal the computer,
• for example:
– Measure of keyboard is single / set of chars
– Trigger is enter key.
8
Input Modes – 1/3
• Request mode: the measure of the device is
not returned to the program until the device is
triggered
• request_locator(device_id, &measure)
9
Input Modes – 2/3
• Sample mode: input is immediate, no trigger
is needed
• sample_locator(device_id, &measure)
• Both request and sample modes are useful for
the program where only one input device is
used.
10
Input Modes – 3/3
• Event mode: each time a device is triggered, an
event is generated, with the id for the device and
measurement is put in an event queue
11
Clients and Servers
• Servers: provide
services
– Print servers,
file servers,
graphics servers…
• Clients: users and user
programs that make
use of these services
– OpenGL application
programs
12
Display Lists
Display-processor architecture
13
Immediate Mode v.s. Retained Mode
• Immediate mode: as soon as the program
executes a statement for a object, the
primitive sent to the display and no memory is
retained for the object
• Retained mode: define an object once, and
put its description in the display list in the
server. Client issues a function call to the
server
14
Definition of Display Lists
• A unique identifier: #define BOX 1 /* or unused int */
• glNewList(BOX, GL_COMPILE);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(-1.0, -1.0);
glVertex2f(1.0, -1.0);
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
glEndList();
• GL_COMPILE
• GL_COMPILE_AND_EXECUTE
15
Execution of Display Lists – 1/2
• glCallList(BOX);
• Different clipping windows
glMatrixMode(GL_PROJECTION);
for(i=1; i<5; i++)
{
glLoadIdentity();
gluOrtho2D(-2.0*i, 2.0*i,-2.0*i, 2.0*i);
glCallList(BOX);
}
16
Execution of Display List – 2/2
• Using stack to avoid interference with the current
matrix or attributes
• At the beginning of a display lists:
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
• At the end:
glPopAttrib();
glPopMatrix();
17
Raster Text v.s. Stroke Text
• Raster text:
– Fixed size for each character
e.g. a 8x13 raster character takes 13 bytes
– Not good for scaling or rotation
• Stroke text:
– No fixed size
– Could store the patterns in ROM,
selection is based on a single byte
– Good for scaling or rotation
18
A Stroke Text Example Using
void OurFont(char c) The Display Lists – 1/3
{
switch(c)
{
case ‘a’:
…
break;
case ‘A’:
…
break;
…
}
}
19
A Stroke Text Example Using
The Display Lists – 2/3
case ‘O’:
glTranslate(0.5, 0.5, 0.0); /* move to center */
glBegin(GL_QUAD_STRIP);
for(i=0; i<=12; i++) /* 12 vertices */
{
angle=3.14159/6.0*i; /* 30 degrees in radians */
glVertex2f(0.4*cos(angle), 0.4*sin(angle));
glVertex2f(0.5*cos(angle), 0.5*sin(angle));
}
glEnd();
glTranslate(0.5, -0.5, 0.0); /* move to lower right */
break; 20
A Stroke Text Example Using The
Display Lists – 3/3
• Base=glGenLists(256);
/* returns index of first of 256 consecutive available ids */
For(i=0; i< 256; i++)
{
glNewList(base+i, GL_COMPILE);
OurFont(I);
glEndList();
}
• glListBase(base);
• char *text_string;
glCallLists( (Glint strlen(text_string), GL_BYTE, text_string);
21
Fonts in GLUT
22
Programming Event-Driven Input
• Using the pointing device
– Move event
• Mouse is moved and one of the button pressed
– Passive move event
• Mouse is moved and no buttons are pressed
– Mouse event: one of mouse buttons is pressed or
released
• glutMouseFunc(mouse): register the function
• void mouse(int button, int state, int x, int y)
23
Other Events and CallBacks
24
Display and Idle CallBacks
• glutDisplay(display);
• Iconify
• glutPostRedisplay()
ensures the display will drawn at most once in the
main loop
• Idle callback: is invoked when there is no other
events
• Callback could be changed at any time or disabled by
set to NULL
25
A Program Example:
Drawing Squares with Mouse – 1/5
int main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow(“square”);
myinit();
glutReshapeFunc(myReshape);
glutMouseFunc(mouse);
glutMotionFunc(drawSquare);
glutDisplayFunc(display)
glutMainLoop();
} 26
A Program Example:
Drawing
void display(){} Squares with Mouse – 2/5
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_RIGHT_BUTTON &&
state==GLUT_DOWN) exit(0);
}
/* globals */
GLsize I wh=500, ww=500; /* initial window size */
GLfloat size=3.0; /* one-half of side length of square */
27
A Program Example:
Drawing Squares with Mouse – 3/5
void myinit(void)
{
/* set viewing conditions */
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)ww, 0.0, (GLdouble) wh);
glMatrixMode(GL_MODELVIEW);
/* set clear color to black, and clear window */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
} 28
A Program Example:
Drawing Squares
void drawSquare(int x, int y)
with Mouse – 4/5
{
y=wh-y;
glColor3ub((char) rand()%256, (char) rand()%256,
(char) rand()%256);
glBegin(GL_POLYGON);
glVertex2f(x+size, y+size);
glVertex2f(x-size, y+size);
glVertex2f(x-size, y-size);
glVertex2f(x+size, y-size);
glEnd();
glFlush();
} 29
A Program Example:
voidDrawing
myReshape(GLsizeiSquares
w, GLsizei h) with Mouse – 5/5
{
/* adjust clipping box */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (Gldouble)w, 0.0, (Gldouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* adjust viewport and clear */
glViewport(0, 0, w, h);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
30
A Program Example:
Drawing Squares with Mouse
Demo
31
Window Management
• GLUT support multiple windows
• id=glutCreateWindow(“Second window);
glutSetWindow(id);
• Call glutInitDisplayMode before
glutCreateWindow() to set attributes
32
Menus – 1/2
• Pop-up menus
• glutCreateMenu(demo_menu); //register callback function
glutAddMenuEntry(“quit”,1);
glutAddMenuEntry(“increase square size”, 2);
glutAddMenuEntry(“decrease square size”, 3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
• Void demo_menu(int id)
{
if(id == 1) exit();
else if(id==2) size=2*size;
else size=size/2;
glutPostRedisplay();
} 33
Hierarchical Menus – 2/2
• sub_menu=glutCreateMenu(size_menu);
glutAddMenuEntry(“increase square size”, 2);
glutAddMenuEntry(“decrease square size”, 3);
glutCreateMenu(top_menu);
glutAddMenuEntry(“quit”,1);
glutAddSubMenu(“resize”, sub_menu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
34
Picking
35
Picking
• Identify a user-defined object on the display
• In principle, it should be simple because the mouse
gives the position and we should be able to determine
to which object(s) a position corresponds
• Practical difficulties
– Pipeline architecture is feed forward, hard to go from screen
back to world
– How close do we have to come to object to say we selected it?
36
Three Approaches
• Selection
– Adjusting the clipping region and viewport
such that we can keep track of which primitive
is near the cursor
• Use back or some other buffer to store
object ids as the objects are rendered
• Rectangular maps
– Easy to implement for many applications
– Boundary boxes or extents
37
Rendering Modes
• OpenGL can render in one of three modes
selected by glRenderMode(mode)
– GL_RENDER: normal rendering to the frame buffer
(default)
– GL_FEEDBACK: provides list of primitives rendered
but no output to the frame buffer
– GL_SELECTION: Each primitive in the view volume
generates a hit record that is placed in a name
stack which can be examined later
38
Selection Mode Functions
• glSelectBuffer(): specifies name buffer
• glInitNames(): initializes name buffer
• glPushName(id): push id on name buffer
• glPopName(): pop top of name buffer
• glLoadName(id): replace top name on buffer
39
Using Selection Mode
• Initialize name buffer
• Enter selection mode (using mouse)
• Render scene with user-defined identifiers
• Reenter normal render mode
– This operation returns number of hits
• Examine contents of name buffer (hit records)
– Hit records include id and depth information
40
Selection Mode and Picking
• As we just described it, selection mode won’t
work for picking because every primitive in
the view volume will generate a hit
• Change the viewing parameters so that only
those primitives near the cursor are in the
altered view volume
– Use gluPickMatrix(x,y,w,h,*vp)
41
Implementation of Picking
• Name stack: store the hit list
• glSelectBuffer(GLsizei n, GLuint *buff): specifies the
array “buff” of size n to place selection data
• glInitNames(): initializes the name stack
• glPushName(GLuint name): pushes name on the
name stack
• glPopName(): pops the top name from the name
stack
• glLoadName(GLuint name): replaces the top of the
name stack with the name
42
Implementation of Picking
44
Example Code for Picking
void mouse(int button, int state, int x, int y)
{
GLuint nameBuffer[SIZE]; /* define SIZE 512 */
GLint hits;
GLint viewport[4];
if(button==GLUT_LEFT_BUTTON &&
state==GLUT_DOWN)
{
/* initialize the name stack */
glInitName();
glPushName(0);
}
45
Example Code for Picking
glSelectBuffer(SIZE, nameBuffer);
glRenderMode(GL_SELECT);
/* set up viewing for selecting mode */
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
/* save original viewing matrix */
glPushMatrix();
glLoadIdentity();
46
Example Code for Picking
/* processHits(hits, nameBuffer);
/* normal render */
glutPostRedisplay();
}
}
48
Example Code for Picking
void display()
{
glClear(GL_COLOR_BUFFER_BUT);
draw_Objects(GL_RENDER);
glFlush();
}
void drawObjects(GLenum mode)
{
if(mode==GL_SELECT) glLoadName(1);
glColor3f(1.0, 0.0, 0.0);
glRectf(-0.5, -0.5, 1.0, 1.0);
if(mode==GL_SELECT) glLoadName(2);
glColor3f(0.0, 0.0, 1.0);
glRectf(-1.0, -1.0, 0.5, 0.5);
} 49
Example Code for Picking
void processHits(GLint hits, GLuint buffer[])
{ unsigned int i, j;
GLuint name, *ptr;
printf(“hits=%d\n”,hits);
for (i=0; i<hits; i++) /* loop over number of hits */
{ names=*ptr;
ptr+=3; /* skip over number of names and depths */
for(j=0; j< name; j++) /* check each name in record */
{ if(*ptr==1) printf(“red rectangle\n”);
else printf(“blue rectangle\n”);
ptr++;
}
/* go to next hit record */
}
} 50
Example Code for Picking
Demo
51
Animating Interactive Programs
• Suppose that we want to create a picture in
which one or more objects are changing or
moving and thus their images must change.
• For example, we might want to have an
animated character walk across the display, or
might want to move the viewer over time.
• We can gain insight into how we handle these
cases through a simple example.
52
Animating Interactive Programs
A Rotating Square
53
A Rotating Square
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
thetar=theta/((2*3.14159/360); /* degrees to radians */
glVertex2f((cos(thetar), sin(thetar));
glVertex2f(-sin(thetar), cos(thetar));
glVertex2f(-cos(thetar), -sin(thetar));
glVertex2f(sin(thetar), -cos(thetar));
glEnd();
}
54
A Rotating Square
glutIdleFunc(idle);
void idle()
{
theta+=2; /* or some other amount */
if(theta>=360.0) theta-=360.0;
glutPostRedisplay();
}
glutMouseFunc(mouse);
Void mouse(int button, int state, int x, int y) {
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
glutIdleFunc(idle);
if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN)
glutIdleFunc(NULL);
} 55
A Rotating Square
Demo
56
Double Buffering
• When we display the contents of the frame
buffer, we want to do so at the rate
sufficiently high that we cannot notice the
clearing and redrawing of the screen.
• As long as the contents of the frame buffer are
unchanged and we refresh at the rate 60 and
85 times per second or we will notice the
display flickering.
57
• If the display being drawn is complex and
cannot be drawn in a single refresh cycle, we
see different parts of the objects on
successive refreshes.
• Double buffering provides the solution to this
problem.
• The front buffer is always the one displayed,
whereas the back buffer is the one into which
we draw.
• We can swap the front and back buffers at will
from the application program.
58
Double Buffering
• Front buffer and back buffer
• glutInitDisplayMode(GLUT_DOUBLE)
• Add glutSwapBuffers() at the end of the
display function.
59
Using a Timer
• Consider what happens if we take a simple
program such as the rotating square and
execute it on a fast GPU.
• Square will be rendered thousands of times
per second and we will see it rotating very fast
and hence it may look blur.
60
There are three approaches for this problem
– Use various timing mechanism provided by
libraries or OS to include delay in the application
program.
– Allow the user to set an option under which
swapping of buffers is locked to the refresh rate.
– GLUT provides the following third option through
the timer function:
glutTimerFunc(int delay, void (*timer_func)(int), int
value)
61
Design of Interactive Programs
• Features of good interactive program
– A smooth display with no flickering
– A variety of interactive devices
– A variety of methods for entering and displaying
information
– An easy-to-use interface
– Feedback to the user
– Tolerance for user error
– A design that incorporates consideration of both the visual
and motor properties of the human.
62
Rubberbanding
Demo
63
Rubberbanding
• Technique used for displaying primitives that
change as they are manipulated interactively.
• One end is fixed to the first location and the
other end are stretched to wherever the
cursor is moved.
• Rubber banding begins when a mouse button
is pressed and continues until the mouse
button is released.
64
Logic Operation
• When a program specifies a primitive that is visible,
OpenGL renders it into a set of colored pixels that are
written into the present drawing buffer.
• Default mode- pixels simply replace the corresponding
pixels that are in the frame buffer.
• Copy (replacement )mode-pixel that we want to write
is source pixel, the pixel in the drawing buffer that the
source pixel will affect is called destination pixels.
• In copy mode the source pixel replaces the destination
pixel.
65
Logic Operation
• There are 16 possible operations between 2 bits
Source pixel and destination pixel
• The first is replacement mode.
• Second mode is exclusive or
• d=ds, where means XOR (exclusive or)
d=(ds) s, which means drawing something twice
will erase it
• OpenGL support all 16 logic modes, GL_COPY is the
default
• glEnable(GL_COLOR_LOGIC_OP);
glLogicOP(GL_XOR); /* change it to XOR mode */
66
XOR and Color
• (00000000, 00000000, 11111111)
(11111111, 11111111, 11111111) =
(11111111, 11111111, 00000000)
Blue White = Yellow
• If a blue line crosses a red object, it will be
colored as magenta inside the object
• XOR mode is used for drawing a Cursor on the
display.
67
• If there is a bit set in the red overlay plane and
the corresponding bit is not set in the green and
blue overlay plane, then the corresponding point
is red, no matter what its original RGB value is.
• The contents of the overlay planes act as if their
values were copied into the color buffer.
• Overlay planes are hardware features and are
not present in all systems.
69