You are on page 1of 94

OpenGL

1.
TC #include < graphics.h>
PC TC 640*480 16

TC
OpenGL API DirectX
1 C
OpenGL C C OpenGL
TC graphics.h OpenGL TC
2
Direct3D API Windows XBOX
OpenGL Windows Unix/Linux
OpenGL

3
OpenGL OpenGL
OpenGL
OpenGL NB NB DOOM 3 QUAKE4

OpenGL
http://www.opengl.org
Windows OpenGL
OpenGL

Windows Visual StudioBroland C++ BuilderDev-C++ OpenGL


Visual Studio 2005 OpenGL
GLUT
GLUT OpenGL
Windows GLUT 150k
http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip
:
http://upload.programfan.com/upfile/200607311626279.zip
Windows GLUT
1 5
2gl.h VisualStudio2005
VC\PlatformSDK\include\gl glut.h
3 glut.lib glut32.lib VisualStudio2005
VC\lib

4 glut.dll glut32.dll system32


C:\Windows\System32
OpenGL
VisualStudio2005
File->New->Project Win32 Console Application OK
Application Settings Empty project Finish
OpenGL.c.c

OpenGL
OpenGL GLUT

#include <GL/glut.h>

void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
glFlush();
}

int main(int argc, char *argv[])


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow(" OpenGL ");
glutDisplayFunc(&myDisplay);
glutM ainLoop();
return 0;
}

#include <GL/glut.h> GLUT


OpenGL <GL/gl.h><GL/glu.h> GLUT

main
int main(int argc, char *argv[]) main

main return glut glut

GLUT
1glutInit GLUT GLUT
glutInit(&argc, argv)
2glutInitDisplayMode GLUT_RGB RGB GLUT_INDEX
GLUT_SINGLE GLUT_DOUBLE
Google
3glutInitWindowPosition
4glutInitWindowSize
5glutCreateWindow
glutM ainLoop
6glutDisplayFunc

7glutM ainLoop

glutDisplayFunc myDisplay myDisplay


myDisplay gl gl OpenGL

1glClearGL_COLOR_BUFFER_BIT glClear

2glRectf
3glFlush OpenGL fflush(stdout)

2.

OpenGL ~
OpenGL
OpenGL

OpenGL OpenGL
OpenGL

OpenGL

OpenGL

OpenGL

OpenGL glVertex 1~2

glVertex2d
glVertex2f
glVertex3f
glVertex3fv

2 3 4 ~
s 16 OpenGL GLshort
i 32 OpenGL GLint GLsizei
f 32 OpenGL GLfloat GLclampf
d 64 OpenGL GLdouble GLclampd
v

glVertex2i(1, 3);
glVertex2f(1.0f, 3.0f);
glVertex3f(1.0f, 3.0f, 0.0f);
glVertex4f(1.0f, 3.0f, 0.0f, 1.0f);
GLfloat VertexArr3[] = {1.0f, 3.0f, 0.0f};
glVertex3fv(VertexArr3);
glVertex*
OpenGL

OpenGL

OpenGL glBegin glEnd


glBegin

glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.0f);
glEnd();
GL_POINTS GL_LINES
OpenGL

glBegin GL_POINTS GL_LINES GL_LINE_STRIPGL_LINE_LOOP


GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN

www.opengl.orgOpenGL
1994
glBegin glBegin

void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin( /* */ );
/* glVertex* */
/* */
glEnd();
glFlush();
}
myDisplay

/*
n n
n

const int n n=3,4,5,8,10,15,20,30,50


GL_POLYGON GL_LINE_LOOPGL_POINTS
*/
#include <math.h>
const int n = 20;
const GLfloat R = 0.5f;
const GLfloat Pi = 3.1415926536f;
void myDisplay(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
for(i=0; i<n; ++i)
glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
glEnd();
glFlush();
}

/*

A
E

D C
a
.0
a = 1 / (2-2*cos(72*Pi/180));
B x bx y by C y

bx = a * cos(18 * Pi/180);
by = a * sin(18 * Pi/180);
cy = -a * cos(18 * Pi/180);

*/
#include <math.h>
const GLfloat Pi = 3.1415926536f;
void myDisplay(void)
{
GLfloat a = 1 / (2-2*cos(72*Pi/180));
GLfloat bx = a * cos(18 * Pi/180);
GLfloat by = a * sin(18 * Pi/180);
GLfloat cy = -a * cos(18 * Pi/180);
GLfloat
PointA[2] = { 0, a },

PointB[2] = { bx, by },
PointC[2] = { 0.5, cy },
PointD[2] = { -0.5, cy },
PointE[2] = { -bx, by };

glClear(GL_COLOR_BUFFER_BIT);
// A->C->E->B->D->A
glBegin(GL_LINE_LOOP);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd();
glFlush();
}

/*
OpenGL -1 1
factor

factor
*/
#include <math.h>
const GLfloat factor = 0.1f;
void myDisplay(void)
{
GLfloat x;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2f(-1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);

// x

glVertex2f(0.0f, -1.0f);
glVertex2f(0.0f, 1.0f);

// y

glEnd();
glBegin(GL_LINE_STRIP);
for(x=-1.0f/factor; x<1.0f/factor; x+=0.01f)
{
glVertex2f(x*factor, sin(x)*factor);
}
glEnd();
glFlush();
}

OpenGL
GL_LINE_STRIP
OpenGL

3.
1
1 glPointSize
void glPointSize(GLfloat size);
size 0.0f 1.0f
OpenGL size

void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0f);
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}

2
1
void glLineWidth(GLfloat width);
glPointSize
2
glEnable(GL_LINE_STIPPLE); glDisable(GL_LINE_STIPPLE)
glLineStipple
void glLineStipple(GLint factor, GLushort pattern);
pattern 1 0 16 1 factor
0 factor

www.opengl.orgOpenGL

1994

void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_LINE_STIPPLE);
glLineStipple(2, 0x0F0F);
glLineWidth(10.0f);
glBegin(GL_LINES);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}
3

glPolygonM ode(GL_FRONT, GL_FILL);

//

glPolygonM ode(GL_BACK, GL_LINE);

//

glPolygonM ode(GL_FRONT_AND_BACK, GL_POINT); //


2

Google

glFrontFace
glFrontFace(GL_CCW); // CCW CCW CounterClockWise
glFrontFace(GL_CW); // CW CW ClockWise
myDisplay glFrontFace(GL_CCW)
glFrontFace(GL_CW)
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPolygonM ode(GL_FRONT, GL_FILL); //
glPolygonM ode(GL_BACK, GL_LINE); //
glFrontFace(GL_CCW);
glBegin(GL_POLYGON);

//
//

glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f, -0.5f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.5f, 0.0f);
glEnd();
glBegin(GL_POLYGON);

//

glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.5f);
glVertex2f(0.5f, 0.5f);
glVertex2f(0.5f, 0.0f);
glEnd();
glFlush();
}
3

glEnable(GL_CULL_FACE); glDisable(GL_CULL_FACE)
glCullFace
glCullFace GL_FRONTGL_BACK GL_FRONT_AND_BACK

glCullFace(GL_FRONT_AND_BACK)

glEnable(GL_POLYGON_STIPPLE); glDisable(GL_POLYGON_STIPPLE)

glPolygonStipple
void glPolygonStipple(const GLubyte *mask);
mask 128 32*32
8 1
0 8
mask
static GLubyte M ask[128] =
{
0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00,
0x03, 0x80, 0x01, 0xC0, //
0x06, 0xC0, 0x03, 0x60, //
0x04, 0x60, 0x06, 0x20, //
0x04, 0x30, 0x0C, 0x20, //
0x04, 0x18, 0x18, 0x20, //
0x04, 0x0C, 0x30, 0x20, //

0x04, 0x06, 0x60, 0x20, //


0x44, 0x03, 0xC0, 0x22, //
0x44, 0x01, 0x80, 0x22, //
0x44, 0x01, 0x80, 0x22, //
0x44, 0x01, 0x80, 0x22, //
0x44, 0x01, 0x80, 0x22, //
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x66, 0x01, 0x80, 0x66,
0x33, 0x01, 0x80, 0xCC,
0x19, 0x81, 0x81, 0x98,
0x0C, 0xC1, 0x83, 0x30,
0x07, 0xE1, 0x87, 0xE0,
0x03, 0x3F, 0xFC, 0xC0,
0x03, 0x31, 0x8C, 0xC0,
0x03, 0x3F, 0xFC, 0xC0,
0x06, 0x64, 0x26, 0x60,
0x0C, 0xCC, 0x33, 0x30,
0x18, 0xCC, 0x33, 0x18,
0x10, 0xC4, 0x23, 0x08,
0x10, 0x63, 0xC6, 0x08,
0x10, 0x30, 0x0C, 0x08,
0x10, 0x18, 0x18, 0x08,
0x10, 0x00, 0x00, 0x08 //
};

Windows mask.bmp
-> 32

M ask
static GLubyte M ask[128];
FILE *fp;
fp = fopen("mask.bmp", "rb");
if( !fp )
exit(0);
// sizeof(M ask)
// -(int)sizeof(M ask)
// -sizeof(M ask) sizeof
if( fseek(fp, -(int)sizeof(M ask), SEEK_END) )
exit(0);
// sizeof(M ask) M ask
if( !fread(M ask, sizeof(M ask), 1, fp) )

exit(0);
fclose(fp);

mask M ask
factor factor

#include <stdio.h>
#include <stdlib.h>
void myDisplay(void)
{
static GLubyte M ask[128];
FILE *fp;
fp = fopen("mask.bmp", "rb");
if( !fp )
exit(0);
if( fseek(fp, -(int)sizeof(M ask), SEEK_END) )
exit(0);
if( !fread(M ask, sizeof(M ask), 1, fp) )
exit(0);
fclose(fp);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(M ask);
glRectf(-0.5f, -0.5f, 0.0f, 0.0f); //
glDisable(GL_POLYGON_STIPPLE);
glRectf(0.0f, 0.0f, 0.5f, 0.5f); //
glFlush();
}

4.
OpenGL RGBA
RGBA

1. RGBA

RGBA R G B
A alpha alpha

RGBA
glColor* RGB A
RGBA
void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
3f ~ glVertex*
0.0 1.0
glColor3f(1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 1.0f);
glColor3f(0.5f, 0.5f, 0.5f);

OpenGL
glColor3f
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 1.0f, 1.0f);
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
glFlush();
}
glColor
f d 1.0
b 127
ub 255
s 32767
us 65535

2
OpenGL

i i
k k
256~4096 2

2.1
glIndex* glIndexi
void glIndexi(GLint c);

2.2
OpenGL
Windows
Windows Windows
GLUT glutSetColor
OpenGL aux VisualStudio

#include <windows.h>
#include <GL/gl.h>
#include <GL/glaux.h>

#pragma comment (lib, "opengl32.lib")


#pragma comment (lib, "glaux.lib")

#include <math.h>
const GLdouble Pi = 3.1415926536;
void myDisplay(void)
{
int i;
for(i=0; i<8; ++i)
auxSetOneColor(i, (float)(i&0x04), (float)(i&0x02), (float)(i&0x01));
glShadeM odel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(0.0f, 0.0f);
for(i=0; i<=8; ++i)
{
glIndexi(i);
glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
}
glEnd();
glFlush();
}

int main(void)
{
auxInitDisplayM ode(AUX_SINGLE|AUX_INDEX);
auxInitPosition(0, 0, 400, 400);
auxInitWindow(L"");
myDisplay();
Sleep(10 * 1000);
return 0;

}
myDisplay auxSetOneColor

glShadeM odel
glVertex glIndexi

RGB 256
PC
PC RGB PC
GBA
3
glClear(GL_COLOR_BUFFER_BIT);

OpenGL
RGB glClearColor glColor4f
glClearIndex glIndexi

void myDisplay(void)
{
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
~
4
OpenGL
#include <math.h>
const GLdouble Pi = 3.1415926536;
void myDisplay(void)
{
int i;
// glShadeM odel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
for(i=0; i<=8; ++i)
{
glColor3f(i&0x04, i&0x02, i&0x01);

glVertex2f(cos(i*Pi/4), sin(i*Pi/4));
}
glEnd();
glFlush();
}
OpenGL
RGB

glShadeM odel

glShadeM odel
glShadeM odel(GL_SM OOTH); //
glShadeM odel(GL_FLAT);

//

RGB PC
glClear

5.
-1 1 X
Y Z

1
2
3

4
OpenGL
OpenGL

OpenGL
1

OpenGL

GL_M ODELVIEW glM atrixM ode


glM atrixM ode(GL_MODELVIEW);

glLoadIdentity();


glTranslate*

glRotate*(0,0,0)(x,y,z)
angle
glScale* x,y,z
XX

R T
v((RT)v)
((RT)v) = (R(Tv))

OpenGL

glRotate*
glTranslate*gluLookAt
(0,0,0)(x,y,z)

-1.0 1.0
OpenGL
GL_PROJECTION glM atrixM ode
glM atrixM ode(GL_PROJECTION);

glLoadIdentity();

glFrustum

www.opengl.orgOpenGL
1994
gluPerspective

www.opengl.orgOpenGL
1994

glOrtho

www.opengl.orgOpenGL
1994
gluOrtho2D glOrgho
3

www.opengl.orgOpenGL
1994

glViewport 0,0

glPushM atrix
glPopM atrix OpenGL
32 OpenGL 32

glM atrixM ode

12 30
360
0~359

OpenGL

X Y
X X

696000km6378km1738km 1.5 km=150000000km


380000km
69600000 100 15945000
2500 4345000 2500 38000000 100

(0, -200000000, 0) 150000000


-200000000 Z
(0, -200000000, 200000000) 45

gluPerspective 60
75 1.0 1.0
200000000*2=400000000gluPerspective(60, 1, 1, 400000000);

glut
glutSolidSphere
glTranslate* glRotate*

20

day
day/*360 360 day

glRotatef(day, 0, 0, -1);
/* Z */
glTranslatef(, 0, 0);
glutSolidSphere(, 20, 20);

glRotatef(, 0, 0, -1);
glTranslatef(, 0, 0);
glutSolidSphere(, 20, 20);
day/ 30*360

day/30*360 - day
glPushM atrix glPopM atrix

OpenGL

1 GL_DEPTH_TEST
glEnable 2
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT)
glClear(GL_DEPTH_BUFFER_BIT)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//
// 30
// 12 360
static int day = 200; // day 0 359
void myDisplay(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glM atrixM ode(GL_PROJECTION);


glLoadIdentity();
gluPerspective(75, 1, 1, 400000000);
glM atrixM ode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, -200000000, 200000000, 0, 0, 0, 0, 0, 1);

//
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidSphere(69600000, 20, 20);
//
glColor3f(0.0f, 0.0f, 1.0f);
glRotatef(day/360.0*360.0, 0.0f, 0.0f, -1.0f);
glTranslatef(150000000, 0.0f, 0.0f);
glutSolidSphere(15945000, 20, 20);
//
glColor3f(1.0f, 1.0f, 0.0f);
glRotatef(day/30.0*360.0 - day/360.0*360.0, 0.0f, 0.0f, -1.0f);
glTranslatef(38000000, 0.0f, 0.0f);
glutSolidSphere(4345000, 20, 20);

glFlush();
}

day
OpenGL
OpenGL
glM atrixM ode
glTranslate* glRotate*
glScale*
glOrtho gluOrtho2D
glFrustum gluPerspective
glViewport

glPushM atrix glPopM atrix

6.

24
25 30

60~120
n
1 1/24
2 1/24

n 1/24

C
for(i=0; i<n; ++i)
{
DrawScene(i);
Wait();
}
1

OpenGL
OpenGL
PC
GLUT main

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
GLUT_SINGLE GLUT_DOUBLE


GLUT
glutSwapBuffers

for(i=0; i<n; ++i)


{
DrawScene(i);
glutSwapBuffers();
Wait();
}
OpenGL
main glutDisplayFunc(&myDisplay);
myDisplay
myDisplay
Windows X

DrawScene

mp3
CPU

CPU
XX XX GLUT glutIdleFunc CPU
GLUT

#include <GL/glut.h>

//
// 30
// 12 360
static int day = 200; // day 0 359
void myDisplay(void)
{

/****************************************************

*****************************************************/
glutSwapBuffers();
}

void myIdle(void)
{
/* */
++day;
if( day >= 360 )
day = 0;
myDisplay();
}

int main(int argc, char *argv[])


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // GLUT_DOUBLE
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow(""); //
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);

//

glutM ainLoop();
return 0;
}
3.
CPU
CPU

60~120Hz 60~120

85Hz 85 CPU

60Hz
60FPS 60 /
1/60
1/50 1/60
1/60
1/30 30FPS 50FPS
60FPS30FPS20FPS60/1
60/260/3
1/60 1/60
60FPS 1/60 30FPS

CPU

OpenGL
4
3D M ark

FPS t
t=0.05s FPS 1/0.05=20
C time
clock FPS 60 FPS 100 t

50 t' t'

=t*50 FPS=1/t=50/t'

OpenGL
#include <time.h>
double CalFrequency()
{
static int count;
static double save;
static clock_t last, current;
double timegap;

++count;
if( count <= 50 )
return save;
count = 0;
last = current;
current = clock();
timegap = (current-last)/(double)CLK_TCK;
save = 50.0/timegap;
return save;
}

OpenGL
~ printf

#include <stdio.h>

double FPS = CalFrequency();


printf("FPS = %f\n", FPS);

#include <GL/glut.h>
#include <stdio.h>
#include <time.h>

//
// 12
// 12 360
static int day = 200; // day 0 359

double CalFrequency()
{
static int count;
static double save;
static clock_t last, current;
double timegap;

++count;
if( count <= 50 )
return save;
count = 0;
last = current;
current = clock();
timegap = (current-last)/(double)CLK_TCK;
save = 50.0/timegap;
return save;
}

void myDisplay(void)
{
double FPS = CalFrequency();

printf("FPS = %f\n", FPS);

glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glM atrixM ode(GL_PROJECTION);


glLoadIdentity();
gluPerspective(75, 1, 1, 400000000);
glM atrixM ode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, -200000000, 200000000, 0, 0, 0, 0, 0, 1);

//
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidSphere(69600000, 20, 20);
//
glColor3f(0.0f, 0.0f, 1.0f);
glRotatef(day/360.0*360.0, 0.0f, 0.0f, -1.0f);
glTranslatef(150000000, 0.0f, 0.0f);
glutSolidSphere(15945000, 20, 20);
//
glColor3f(1.0f, 1.0f, 0.0f);
glRotatef(day/30.0*360.0 - day/360.0*360.0, 0.0f, 0.0f, -1.0f);
glTranslatef(38000000, 0.0f, 0.0f);
glutSolidSphere(4345000, 20, 20);

glFlush();
glutSwapBuffers();
}

void myIdle(void)
{
++day;
if( day >= 360 )
day = 0;
myDisplay();
}

int main(int argc, char *argv[])


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutM ainLoop();
return 0;
}

OpenGL

OpenGL
CPU

FPS

7.

1
OpenGL

OpenGL

OpenGL

OpenGL
OpenGL

OpenGL

OpenGL

glColor*
glNormal*
glTranslate* glRotate*
glScale*
OpenGL
glScale*

.
OpenGL GL_LIGHT0 0 GL_LIGHT1
1 OpenGL 8 GL_LIGHT0 GL_LIGHT7 glEnable
glEnable(GL_LIGHT0); 0 glDisable
OpenGL
3D M ark

glLight*glLight*

1GL_AM BIENTGL_DIFFUSEGL_SPECULAR
R, G, B, A GL_AM BIENT

GL_DIFFUSE
GL_SPECULAR

2GL_POSITION X, Y, Z, W W

W X/W, Y/W, Z/W


glTranslate*glRotate*

3GL_SPOT_DIRECTIONGL_SPOT_EXPONENTGL_SPOT_CUTOFF

GL_SPOT_DIRECTION GL_SPOT_EXPONENT

GL_SPOT_CUTOFF
2 0 90 180
180 360

GL_CONSTANT_ATTENUATION

GL_LINEAR_ATTENUATION

GL_QUADRATIC_ATTENUATION
OpenGL

= 1 / (k1 + k2 * d + k3 * k3 * d)
d k1, k2, k3

GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATI


ON
34

.
glLight*
glM aterial*
glM aterial* GL_FRONT
GL_BACK GL_FRONT_AND_BACK

glLight* glM aterial*

1GL_AM BIENTGL_DIFFUSEGL_SPECULAR

GL_AM BIENT
GL_DIFFUSE
GL_SPECULAR
GL_AM BIENT
GL_DIFFUSE
GL_AM BIENT_AND_DIFFUSE GL_AM BIENT GL_DIFFUSE
2GL_SHININESS 0 128

3GL_EM ISSION OpenGL

4GL_COLOR_INDEXES
RGBA

OpenGL OpenGL

GL_SPECULAR )

glLightM odel*

GL_LIGHT_MODEL_AM BIENT
GL_LIGHT_MODEL_LOCAL_VIEWER GL_TRUE
GL_FALSE
GL_LIGHT_MODEL_TWO_SIDE GL_TRUE OpenGL

GL_LIGHT_MODEL_COLOR_CONTROL GL_SINGLE_COLOR

GL_SEPARATE_SPECULAR_COLOR GL_SPECULAR
GL_SPECULAR

OpenGL

glEnable(GL_LIGHTING);
glDisable(GL_LIGHTING);

OpenGL
^-^


glutSolidSphere

gluPerspective

#include < gl/glut.h>

#define WIDTH 400


#define HEIGHT 400

static GLfloat angle = 0.0f;

void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
glM atrixM ode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
glM atrixM ode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//
{
GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);


glLightfv(GL_LIGHT0, GL_AM BIENT, sun_light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);

glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}

//
{
GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_shininess = 0.0f;

glM aterialfv(GL_FRONT, GL_AM BIENT, sun_mat_ambient);


glM aterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);
glM aterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);
glM aterialfv(GL_FRONT, GL_EM ISSION, sun_mat_emission);
glM aterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);

glutSolidSphere(2.0, 40, 32);


}
//
{
GLfloat earth_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat earth_mat_shininess = 30.0f;

glM aterialfv(GL_FRONT, GL_AM BIENT, earth_mat_ambient);


glM aterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
glM aterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
glM aterialfv(GL_FRONT, GL_EM ISSION, earth_mat_emission);
glM aterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);

glRotatef(angle, 0.0f, -1.0f, 0.0f);


glTranslatef(5.0f, 0.0f, 0.0f);
glutSolidSphere(2.0, 40, 32);
}

glutSwapBuffers();
}
void myIdle(void)
{
angle += 1.0f;
if( angle >= 360.0f )
angle = 0.0f;

myDisplay();
}

int main(int argc, char* argv[])


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL ");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutM ainLoop();
return 0;
}

OpenGL OpenGL

glLight* glM aterial*


glLightM odel*
GL_AM BIENTGL_DIFFUSEGL_SPECULAR
GL_DIFFUSE
GL_SPECULAR

OpenGL

3DS M AX

8.
OpenGL
C
OpenGL OpenGL
OpenGL
glVertex*
glVertex*
60 glVertex*

const int segments = 100;


const GLfloat pi = 3.14f;
int i;
glLineWidth(10.0);
glBegin(GL_LINE_LOOP);
for(i=0; i<segments; ++i)
{
GLfloat tmp = 2 * pi * i / segments;
glVertex2f(cos(tmp), sin(tmp));
}
glEnd();

cossin CPU
cossin
CPU

OpenGL

OpenGL C C
OpenGL

glGenLists

glGenLists i i
glGenLists(3); 20 202122

glIsList

OpenGL glNewList
glEndList glNewList
GL_COM PILE
GL_COM PILE_AND_EXECUTE

(0, 0) list

glNewList(list, GL_COMPILE);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glEnd();
OpenGL
int i = 3;
glNewList(list, GL_COMPILE);
if( i > 20 )
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glEnd();
if i i>20 glColor3f

OpenGL
glCallList glCallLists

glCallList
10 glCallList(10);
glCallLists
GL_BYTE
GLbyte GL_UNSIGNED_BYTE GLubyte GL_SHORT
GL_UNSIGNED_SHORTGL_INTGL_UNSIGNED_INTGL_FLOAT
glListBase
k glCallLists l1, l2, l3, ...
l1+k, l2+k, l3+k, ...

GLuint lists[] = {1, 3, 4, 8};


glListBase(10);
glCallLists(4, GL_UNSIGNED_INT, lists);
11, 13, 14, 18

glDeleteLists
glDeleteLists(20, 4); 20212223

1 OpenGL Linux
OpenGL

2cossin

3 glTranslate*glRotate*glScale*

OpenGL

angle
360 0 angle
OpenGL

(-0.5, -5*sqrt(5)/48, sqrt(3)/6),


( 0.5, -5*sqrt(5)/48, sqrt(3)/6),
( 0, -5*sqrt(5)/48, -sqrt(3)/3),
( 0, 11*sqrt(6)/48,

0)

2007 4 24 AB, AC, AD, BC, BD, CD AD, BD, CD


1.0
A ( 0.5, -sqrt(6)/12, -sqrt(3)/6)
B ( -0.5, -sqrt(6)/12, -sqrt(3)/6)
C (

0, -sqrt(6)/12, sqrt(3)/3)

D (

0,

sqrt(6)/4,

0)

#include < gl/glut.h>

#define WIDTH 400


#define HEIGHT 400

#include <math.h>
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)

GLfloat angle = 0.0f;

void myDisplay(void)
{
static int list = 0;
if( list == 0 )
{
//
/* GLfloat
PointA[] = {-0.5, -5*sqrt(5)/48, sqrt(3)/6},
PointB[] = { 0.5, -5*sqrt(5)/48, sqrt(3)/6},
PointC[] = { 0, -5*sqrt(5)/48, -sqrt(3)/3},
PointD[] = { 0, 11*sqrt(6)/48,

0}; */

// 2007 4 27
GLfloat
PointA[] = { 0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
PointB[] = {-0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
PointC[] = { 0.0f, -sqrt(6.0f)/12, sqrt(3.0f)/3},

PointD[] = { 0.0f, sqrt(6.0f)/4,


GLfloat
ColorR[] = {1, 0, 0},
ColorG[] = {0, 1, 0},
ColorB[] = {0, 0, 1},
ColorY[] = {1, 1, 0};

list = glGenLists(1);
glNewList(list, GL_COMPILE);
glBegin(GL_TRIANGLES);
// ABC
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorB, PointC);
// ACD
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorB, PointC);
ColoredVertex(ColorY, PointD);
// CBD
ColoredVertex(ColorB, PointC);
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorY, PointD);
// BAD
ColoredVertex(ColorG, PointB);
ColoredVertex(ColorR, PointA);
ColoredVertex(ColorY, PointD);
glEnd();
glEndList();

glEnable(GL_DEPTH_TEST);

0};

}
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushM atrix();
glRotatef(angle, 1, 0.5, 0);
glCallList(list);
glPopM atrix();
glutSwapBuffers();
}

void myIdle(void)
{
++angle;
if( angle >= 360.0f )
angle = 0.0f;
myDisplay();
}

int main(int argc, char* argv[])


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL ");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutM ainLoop();
return 0;
}

OpenGL

angle
glColor3fv

(0, 0, 0)

void setNormal(GLfloat* Point1, GLfloat* Point2, GLfloat* Point3)


{
GLfloat normal[3];
int i;
for(i=0; i<3; ++i)
normal[i] = (Point1[i]+Point2[i]+Point3[i]) / 3;
glNormal3fv(normal);
}

1 2

OpenGL
OpenGL OpenGL

OpenGL

OpenGL

9.
OpenGL

OpenGL glEnable(GL_BLEND);
OpenGL glDisable(GL_BLEND);
RGBA

OpenGL

OpenGL

alpha (Rs, Gs, Bs, As)(Rd, Gd, Bd, Ad)


(Sr, Sg, Sb, Sa)(Dr, Dg, Db, Da)
(Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da)
1.0 1.0

glBlendFunc glBlendFunc

GL_ZERO

0.0

GL_ONE

1.0

GL_SRC_ALPHA alpha
GL_DST_ALPHA alpha
GL_ONE_M INUS_SRC_ALPHA 1.0 alpha
GL_ONE_M INUS_DST_ALPHA 1.0 alpha

GL_SRC_COLOR
GL_ONE_M INUS_SRC_COLOR GL_DST_COLOR GL_ONE_M INUS_DST_COLOR
OpenGL OpenGL
OpenGL
GL_CONST_COLOR
GL_ONE_M INUS_CONST_COLOR

GL_CONST_ALPHA

GL_ONE_M INUS_CONST_ALPHA GL_SRC_ALPHA_SATURATE


OpenGL alpha RGB
~

glBlendFunc(GL_ONE, GL_ZERO);

glBlendFunc(GL_ZERO, GL_ONE);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_M INUS_SRC_ALPHA);


alpha 1.0 alpha
alpha
alpha

glBlendFunc(GL_ONE, GL_ONE);
(1, 0, 0)(0, 1, 0)
(1, 1, 0)

glRectf(1, -1, 0.5, 0.5);glRectf(-0.5, -0.5, 1, 1);


glBlendFunc(GL_ONE, GL_ZERO);
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);

glColor4f(1, 0, 0, 0.5);
glRectf(-1, -1, 0.5, 0.5);
glColor4f(0, 1, 0, 0.5);
glRectf(-0.5, -0.5, 1, 1);

glutSwapBuffers();
}

glBlendFunc

glBlendFunc(GL_SRC_ALPHA, GL_ONE_M INUS_SRC_ALPHA);

glBlendFunc(GL_ONE, GL_ONE);
alpha 0.5

glDepthM ask(GL_FALSE);
glDepthM ask(GL_TRUE);
NeHe
glDisable(GL_DEPTH_TEST);


NeHe
glDepthM ask

(1, 1, -1)
void setLight(void)
{
static const GLfloat light_position[] = {1.0f, 1.0f, -1.0f, 1.0f};
static const GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
static const GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
static const GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

glLightfv(GL_LIGHT0, GL_POSITION, light_position);


glLightfv(GL_LIGHT0, GL_AM BIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}

void setM atirial(const GLfloat mat_diffuse[4], GLfloat mat_shininess)


{
static const GLfloat mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
static const GLfloat mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};

glM aterialfv(GL_FRONT, GL_AM BIENT_AND_DIFFUSE, mat_diffuse);


glM aterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glM aterialfv(GL_FRONT, GL_EM ISSION, mat_emission);
glM aterialf (GL_FRONT, GL_SHININESS, mat_shininess);
}

void myDisplay(void)
{
//
const static GLfloat red_color[] = {1.0f, 0.0f, 0.0f, 1.0f};
const static GLfloat green_color[] = {0.0f, 1.0f, 0.0f, 0.3333f};
const static GLfloat blue_color[] = {0.0f, 0.0f, 1.0f, 0.5f};

//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_M INUS_SRC_ALPHA);
//
setLight();
// (0, 0, 0.5).3
setM atirial(red_color, 30.0);
glPushM atrix();
glTranslatef(0.0f, 0.0f, 0.5f);
glutSolidSphere(0.3, 30, 30);
glPopM atrix();
//
glDepthM ask(GL_FALSE);
// (0.2, 0, -0.5).2
setM atirial(blue_color, 30.0);
glPushM atrix();
glTranslatef(0.2f, 0.0f, -0.5f);
glutSolidSphere(0.2, 30, 30);
glPopM atrix();
// (0.1, 0, 0).15
setM atirial(green_color, 30.0);
glPushM atrix();
glTranslatef(0.1, 0, 0);
glutSolidSphere(0.15, 30, 30);
glPopM atrix();
//
glDepthM ask(GL_TRUE);

glutSwapBuffers();
}
glDepthM ask


OpenGL

alpha 1.0 alpha


alpha

10.
bug grab
glReadBuffer(GL_FRONT);

OpenGL

1BMP
BMP
16 256 24 1/8
1/2 1 3 256 BM P 24 BM P
RLE BM P
24 BM P Windows
BMP
Windows BM P 54
24 BM P
32
0x0012 0x0016

GLint width, height; // OpenGL GLint 32


// C int 32
FILE* pFile;
//
fseek(pFile, 0x0012, SEEK_SET);

// 0x0012

fread(&width, sizeof(width), 1, pFile); //


fseek(pFile, 0x0016, SEEK_SET);

// 0x0016

// 0x0016
//
fread(&height, sizeof(height), 1, pFile); //
54 16 256 BMP 24 BMP
24 BM P

OpenGL RGB BM P BGR

BM P
4 4 17*15 24 BM P
834 17 51 52 15
780 54 834

int LineLength, TotalLength;


LineLength = ImageWidth * BytesPerPixel; //
//
while( LineLength % 4 != 0 )

// LineLength 4

++LineLenth;
TotalLength = LineLength * ImageHeight; // = *

2 OpenGL
OpenGL
glReadPixels

glDrawPixels
glCopyPixels

3glReadPixels
3.1

GL_RGB GL_RGBA
alpha GL_RED
GL_GREENGL_BLUE GL_ALPHA RGBA
GL_COLOR_INDEX

GL_UNSIGNED_BYTE
GLubyteGL_FLOAT GLfloat

256*256
RGB GLubyte256*256*3 = 196608
192 RGBA 256*256*4 = 262144 256
glReadP ixels

BMP
3.2 OpenGL RGB BMP BGR
RGB BGR
OpenGL GL_RGB
GL_BGR BM P
gl/gl.h GL_BGR
GL_BGR_EXT OpenGL GL_BGR_EXT
Windows OpenGL GL_BGR Windows
BGR RGB IBM -PC

3.3 BMP
OpenGL glPixelStore

int alignment = 4;
glPixelStorei(GL_UNPACK_ALIGNM ENT, alignment);

alignment 1, 2, 4, 8
4 BMP
glPixelStorei

BMP BM P

BM P 54 BM P
54
1*1 24 BMP dummy.bmp BMP grab.bmp

FILE* pOriginFile = fopen("dummy.bmp", "rb);


FILE* pGrabFile = fopen("grab.bmp", "wb");
char BM P_Header[54];
GLint width, height;
/* width height */
// dummy.bmp 54
fread(BM P_Header, sizeof(BMP_Header), 1, pOriginFile);
// BM P
fwrite(BM P_Header, sizeof(BMP_Header), 1, pGrabFile);
//

fseek(pGrabFile, 0x0012, SEEK_SET);


fwrite(&width, sizeof(width), 1, pGrabFile);
fwrite(&height, sizeof(height), 1, pGrabFile);
//
fseek(pGrabFile, 0, SEEK_END);
/* */

fclose(pOriginFile);
fclose(pGrabFile);
BM P

#define WindowWidth 400


#define WindowHeight 400

#include <stdio.h>
#include <stdlib.h>

/* grab
*
* WindowWidth WindowHeight
*/
#define BM P_Header_Length 54
void grab(void)
{
FILE*

pDummyFile;

FILE*

pWritingFile;

GLubyte* pPixelData;
GLubyte BM P_Header[BM P_Header_Length];
GLint

i, j;

GLint

PixelDataLength;

//

i = WindowWidth * 3; //
while( i%4 != 0 )
++i;

// i

//
//

PixelDataLength = i * WindowHeight;

//
pPixelData = (GLubyte*)malloc(PixelDataLength);
if( pPixelData == 0 )
exit(0);

pDummyFile = fopen("dummy.bmp", "rb");


if( pDummyFile == 0 )
exit(0);

pWritingFile = fopen("grab.bmp", "wb");


if( pWritingFile == 0 )
exit(0);

//
glPixelStorei(GL_UNPACK_ALIGNM ENT, 4);
glReadPixels(0, 0, WindowWidth, WindowHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);

// dummy.bmp
fread(BM P_Header, sizeof(BM P_Header), 1, pDummyFile);
fwrite(BM P_Header, sizeof(BM P_Header), 1, pWritingFile);
fseek(pWritingFile, 0x0012, SEEK_SET);
i = WindowWidth;
j = WindowHeight;

fwrite(&i, sizeof(i), 1, pWritingFile);


fwrite(&j, sizeof(j), 1, pWritingFile);

//
fseek(pWritingFile, 0, SEEK_END);
fwrite(pPixelData, PixelDataLength, 1, pWritingFile);

//
fclose(pDummyFile);
fclose(pWritingFile);
free(pPixelData);
}

grab
BMP

4glDrawPixels
glDrawPixels glReadPixels
glReadPixels
glReadPixels
glDrawPixels
glDrawPixels glReadPixels glReadPixels
glDrawPixels glRa
sterPos*glRasterPos* glVertex*//OpenGL

BM P glDrawPixels Window
s XP Bliss.bmp Windows XP
BMP 24 BM P
FileName
OpenGL

#include < gl/glut.h>

#define FileName "Bliss.bmp"

static GLint

ImageWidth;

static GLint

ImageHeight;

static GLint

PixelLength;

static GLubyte* PixelData;

#include <stdio.h>
#include <stdlib.h>

void display(void)
{
//
//
//
// glClear(GL_COLOR_BUFFER_BIT);

//
glDrawPixels(ImageWidth, ImageHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, PixelData);

//
glutSwapBuffers();
}

int main(int argc, char* argv[])


{
//
FILE* pFile = fopen("Bliss.bmp", "rb");
if( pFile == 0 )
exit(0);

//
fseek(pFile, 0x0012, SEEK_SET);
fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);

//
PixelLength = ImageWidth * 3;
while( PixelLength % 4 != 0 )
++PixelLength;
PixelLength *= ImageHeight;

//
PixelData = (GLubyte*)malloc(PixelLength);
if( PixelData == 0 )
exit(0);

fseek(pFile, 54, SEEK_SET);


fread(PixelData, PixelLength, 1, pFile);

//
fclose(pFile);

// GLUT

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(ImageWidth, ImageHeight);
glutCreateWindow(FileName);
glutDisplayFunc(&display);
glutM ainLoop();

//
// glutM ainLoop
//
//
free(PixelData);

return 0;
}

24 BM P BMP
BMP
OpenGL
/ glPixelZoom /
glPixelZoom(0.5f, 0.8f); 50%
80%

glRasterPos*
5glCopyPixels
glCopyPixels
glReadPixels glDrawPixels
1024*768 24 BGR 1024*768*3
2.25 glReadPixels glDrawPixels
CPU glCopyPix
els


glCopyPixels glRasterPos*

glCopyPixels
GL_COLOR
GL_DEPTH GL_STENCIL
glDrawPixels glReadPixels glPixelZoom glCopyPixels

grab grab.bmp Wi
ndowWidth WindowHeight

void display(void)
{
//
glClear(GL_COLOR_BUFFER_BIT);

//
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);

glVertex2f(0.0f, 0.0f);

glColor3f(0.0f, 1.0f, 0.0f);

glVertex2f(1.0f, 0.0f);

glColor3f(0.0f, 0.0f, 1.0f);

glVertex2f(0.5f, 1.0f);

glEnd();
glPixelZoom(-0.5f, -0.5f);
glRasterPos2i(1, 1);
glCopyPixels(WindowWidth/2, WindowHeight/2,
WindowWidth/2, WindowHeight/2, GL_COLOR);

// BM P
glutSwapBuffers();

grab();
}

Windows BM P OpenGL
glReadPixels glDrawPixels glCopyPixels

glPixelStore*glRasterPos* glPixelZoom

11.
BM P
OpenGL

glPixelZoom
OpenGL

OpenGL

~
1
OpenGL OpenGL

glEnable(GL_TEXTURE_2D); //
glDisable(GL_TEXTURE_2D); //

glTexImage2D

GL_TEXTURE_2D

OpenGL 1.0
RGB 3 RGBA
alpha 4 GL_RGB GL
_RGBA Wi
ndows BM P GL_BGR GL_RGB
GL_RGB
GL_BGROpenGL
OpenGL
2 16, 32, 64, 128, 256
OpenGL PC
OpenGL OpenGL
2 gluScaleImage
OpenGL
1024*1024 OpenGL
GLint max;
glGetIntegerv(GL_M AX_TEXTURE_SIZE, &max);

max OpenGL

256*256 256 2
8 2 8 256

glDrawPixels glReadPixels
10
width*height Windows 24 BGR pix
els
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pix
els);

512*512 BGR
0.75M

OpenGL
OpneGL
OpenGL

OpenGL

OpenGL
glShadeM ode(GL_SM OOTH);

OpenGL

(0, 0)(1, 1)

glTexCoord* glVertex*
glTexCoord2f(0.0f, 0.0f);(0, 0)

glBegin( /* ... */ );
glTexCoord2f( /* ... */ ); glVertex3f( /* ... */ );
glTexCoord2f( /* ... */ ); glVertex3f( /* ... */ );
/* ... */
glEnd();

glRotate*
glM atrixM ode(GL_TEXTURE);
GL_PROJECTION GL_MODELVIEW
glRotate*glScale*glTranslate*

glTexParameter*
GL_TEXTURE_M AG_FILTER
256*256 512*512
GL_NEAREST GL_LINEAR

GL_TEXTURE_M IN_FILTER
256*256 128*128
GL_NEARESTGL_LINEARGL_NEAREST_M IPMAP_N
EARESTGL_NEAREST_M IPM AP_LINEARGL_LINEAR_M IPM AP_NEAREST GL_LINEAR_M IPMA
P_LINEAR mipmap GL_TEXTURE_MAG_FI
LTER

GL_TEXTURE_WRAP_S 1.0 0.0


GL_CLAMP GL_REPEAT 1.0 1.0 0.0 0.0
[0.0, 1.0]
(3.
5, 0.5) 3.5 1.0 GL_CLAM P (1.0, 0.5)
GL_REPEAT (0.5, 0.5) OpenGL
GL_REPEAT
GL_TEXTURE_WRAP_T 1.0 0.0 G
L_TEXTURE_WRAP_S GL_REPEAT

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);


4

glDrawPixels
glDrawPixels glDrawPixels

glTexImage2D( /* ... */ ); //
//
glTexImage2D( /* ... */ ); //

//
//

glGenTextures
GLuint texture_ID;
glGenTextures(1, &texture_ID); //

GLuint texture_ID_list[5];
glGenTextures(5, texture_ID_list); // 5

glGenTextures
glGenTextures glDeleteTextures

glBindTexture glTe
xImage* glTexParameter* glTexCoord*
glBindTexture glTexImage*glTexParameter*glTexCoor
d* 0 glBindTexture

GL_TEXTURE_2D

OpenGL glBindTexture

//
glGenTextures( /* ... */ );
glBindTexture(GL_TEXTURE_2D, texture_ID_1);
//
glBindTexture(GL_TEXTURE_2D, texture_ID_2);
//

//
glBindTexture(GL_TEXTURE_2D, texture_ID_1); //
//
glBindTexture(GL_TEXTURE_2D, texture_ID_2); //
//

OpenGL 1.1 OpenGL 1.0


OpenGL 1.1 Windows 95 OpenGL 1.1
M icrosoft OpenGL Windows XP 1.1
Vista OpenGL 1.4
OpenGL 1.4
5

dummy.bmp 1*1 24 BM P
ground.bmp wall.bmp
jpg
BMP Windows XP

grab
grab.bmp
1*1 dummy.bmp
#define WindowWidth 400
#define WindowHeight 400
#define WindowTitle "OpenGL "

#include < gl/glut.h>


#include <stdio.h>
#include <stdlib.h>

/* grab
*
* WindowWidth WindowHeight
*/
#define BM P_Header_Length 54
void grab(void)
{
FILE*

pDummyFile;

FILE*

pWritingFile;

GLubyte* pPixelData;
GLubyte BM P_Header[BM P_Header_Length];
GLint

i, j;

GLint

PixelDataLength;

//
i = WindowWidth * 3; //
while( i%4 != 0 )
++i;

// i

//
//

PixelDataLength = i * WindowHeight;

//
pPixelData = (GLubyte*)malloc(PixelDataLength);
if( pPixelData == 0 )
exit(0);

pDummyFile = fopen("dummy.bmp", "rb");


if( pDummyFile == 0 )
exit(0);

pWritingFile = fopen("grab.bmp", "wb");


if( pWritingFile == 0 )
exit(0);

//
glPixelStorei(GL_UNPACK_ALIGNM ENT, 4);
glReadPixels(0, 0, WindowWidth, WindowHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);

// dummy.bmp
fread(BM P_Header, sizeof(BM P_Header), 1, pDummyFile);
fwrite(BM P_Header, sizeof(BM P_Header), 1, pWritingFile);
fseek(pWritingFile, 0x0012, SEEK_SET);
i = WindowWidth;
j = WindowHeight;
fwrite(&i, sizeof(i), 1, pWritingFile);
fwrite(&j, sizeof(j), 1, pWritingFile);

//

fseek(pWritingFile, 0, SEEK_END);
fwrite(pPixelData, PixelDataLength, 1, pWritingFile);

//
fclose(pDummyFile);
fclose(pWritingFile);
free(pPixelData);
}
power_of_two

load_texture BM P

/* power_of_two
* 2 1 0
* 1 1 0
*
* n &= (n-1) n
*/
int power_of_two(int n)
{
if( n <= 0 )
return 0;
return (n & (n-1)) == 0;
}

/* load_texture
* BMP
* 0

*/
GLuint load_texture(const char* file_name)
{
GLint width, height, total_bytes;
GLubyte* pixels = 0;
GLuint last_texture_ID, texture_ID = 0;

//
FILE* pFile = fopen(file_name, "rb");
if( pFile == 0 )
return 0;

//
fseek(pFile, 0x0012, SEEK_SET);
fread(&width, 4, 1, pFile);
fread(&height, 4, 1, pFile);
fseek(pFile, BMP_Header_Length, SEEK_SET);

//
{
GLint line_bytes = width * 3;
while( line_bytes % 4 != 0 )
++line_bytes;
total_bytes = line_bytes * height;
}

//
pixels = (GLubyte*)malloc(total_bytes);
if( pixels == 0 )
{

fclose(pFile);
return 0;
}

//
if( fread(pixels, total_bytes, 1, pFile) <= 0 )
{
free(pixels);
fclose(pFile);
return 0;
}

// OpenGL
//
// OpenGL
//
// OpenGL
{
GLint max;
glGetIntegerv(GL_M AX_TEXTURE_SIZE, &max);
if( !power_of_two(width)
|| !power_of_two(height)
|| width > max
|| height > max )
{
const GLint new_width = 256;
const GLint new_height = 256; //
GLint new_line_bytes, new_total_bytes;
GLubyte* new_pixels = 0;

//
new_line_bytes = new_width * 3;
while( new_line_bytes % 4 != 0 )
++new_line_bytes;
new_total_bytes = new_line_bytes * new_height;

//
new_pixels = (GLubyte*)malloc(new_total_bytes);
if( new_pixels == 0 )
{
free(pixels);
fclose(pFile);
return 0;
}

//
gluScaleImage(GL_RGB,
width, height, GL_UNSIGNED_BYTE, pixels,
new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);

// pixels width height


free(pixels);
pixels = new_pixels;
width = new_width;
height = new_height;
}
}

//
glGenTextures(1, &texture_ID);

if( texture_ID == 0 )
{
free(pixels);
fclose(pFile);
return 0;
}

//
//
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);
glBindTexture(GL_TEXTURE_2D, texture_ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_M IN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, last_texture_ID);

// pixels glTexImage2D
// OpenGL
free(pixels);
return texture_ID;
}
main main
glBindTexture
1.0 GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T
GL_REPEAT
5.0 10.0

/*
*/
GLuint texGround;
GLuint texWall;

void display(void)
{
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//
glM atrixM ode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75, 1, 1, 21);
glM atrixM ode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 5, 5, 0, 0, 0, 0, 0, 1);

//
glBindTexture(GL_TEXTURE_2D, texGround);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-8.0f, -8.0f, 0.0f);
glTexCoord2f(0.0f, 5.0f); glVertex3f(-8.0f, 8.0f, 0.0f);
glTexCoord2f(5.0f, 5.0f); glVertex3f(8.0f, 8.0f, 0.0f);
glTexCoord2f(5.0f, 0.0f); glVertex3f(8.0f, -8.0f, 0.0f);
glEnd();
//
glBindTexture(GL_TEXTURE_2D, texWall);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);

glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);


glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);
glEnd();

//
glRotatef(-90, 0, 0, 1);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 1.0f); glVertex3f(6.0f, -3.0f, 1.5f);
glTexCoord2f(5.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);
glEnd();

//
glutSwapBuffers();
grab();
}

int main(int argc, char* argv[])


{
// GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WindowTitle);
glutDisplayFunc(&display);

//

glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
texGround = load_texture("ground.bmp");
texWall = load_texture("wall.bmp");

//
glutM ainLoop();

return 0;
}

OpenGL
glReadPixels glDrawPixels

OpenGL

OpenGL 2
gluScaleImage

glBindTextures

OpenGL

12.

OpenGL

OpenGL

OpenGL
glDepthM ask(GL_FALSE)

OpenGL Alpha
1

glEnable(GL_SCISSOR_TEST); //
glDisable(GL_SCISSOR_TEST); //

(x, y) width height


glScissor(x, y, width, height);

OpenGL (0, 0)(width, height) Windows

2Alpha
Alpha Alpha Alph
a Alpha OpenGL Alpha Alpha

Alpha Alpha 0.0 Alpha


1.0 Alpha 0.5
Alpha 1.0 Alpha 0.0 0.5 Alp
ha

Alpha
glEnable(GL_ALPHA_TEST); // Alpha
glDisable(GL_ALPHA_TEST); // Alpha

Alpha 0.5
glAlphaFunc(GL_GREATER, 0.5f);

GL_LESS(
)
GL_ALWAYS
GL_NEVER
GL_LESS
GL_LEQUAL
GL_EQUAL
GL_GEQUAL
GL_NOTEQUAL

24 BMP
JPG Windows XP 24 BM P

24 BMP BGR 8 Alpha Alpha

Alpha 0.0 Alpha 1.0 Alpha 0.5


Color Key
11
Alpha
/* BGR BGRA
* RGB rgb absolute Alpha 0.0 1.0
*/
void texture_colorkey(GLubyte r, GLubyte g, GLubyte b, GLubyte absolute)
{
GLint width, height;
GLubyte* pixels = 0;

//
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);

//

pixels = (GLubyte*)malloc(width*height*4);
if( pixels == 0 )
return;
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);

// Alpha
// pixels[i*4], pixels[i*4+1], pixels[i*4+2], pixels[i*4+3]
// i Alpha 0 255
{
GLint i;
GLint count = width * height;
for(i=0; i<count; ++i)
{
if( abs(pixels[i*4] - b) <= absolute
&& abs(pixels[i*4+1] - g) <= absolute
&& abs(pixels[i*4+2] - r) <= absolute )
pixels[i*4+3] = 0;
else
pixels[i*4+3] = 255;
}
}

//
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
free(pixels);
}

void display(void)
{
static int initialized = 0;
static GLuint texWindow = 0;
static GLuint texPicture = 0;

// BGR BGRA
if( !initialized )
{
texPicture = load_texture("pic.bmp");
texWindow = load_texture("window.bmp");
glBindTexture(GL_TEXTURE_2D, texWindow);
texture_colorkey(255, 255, 255, 10);

glEnable(GL_TEXTURE_2D);

initialized = 1;
}

//
glClear(GL_COLOR_BUFFER_BIT);

// Alpha
glBindTexture(GL_TEXTURE_2D, texPicture);
glDisable(GL_ALPHA_TEST);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);

glVertex2f(-1.0f, -1.0f);

glTexCoord2f(0, 1);

glVertex2f(-1.0f, 1.0f);

glTexCoord2f(1, 1);

glVertex2f( 1.0f, 1.0f);

glTexCoord2f(1, 0);

glVertex2f( 1.0f, -1.0f);

glEnd();

// Alpha
glBindTexture(GL_TEXTURE_2D, texWindow);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);

glVertex2f(-1.0f, -1.0f);

glTexCoord2f(0, 1);

glVertex2f(-1.0f, 1.0f);

glTexCoord2f(1, 1);

glVertex2f( 1.0f, 1.0f);

glTexCoord2f(1, 0);

glVertex2f( 1.0f, -1.0f);

glEnd();

//
glutSwapBuffers();
}

load_texture 11 power_of_two
BMP_Header_Length main

RGB Alpha

Alpha OpenGL
Alpha Alpha
OpenGL
Alpha
Alpha

Alpha

Alpha

3
OpenGL

OpenGL GLUT
glutInitDisplayMode GLUT_STENCIL
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_STENCIL);

Windows

glEnable/glDisable
glEnable(GL_STENCIL_TEST); //
glDisable(GL_STENCIL_TEST); //

OpenGL

Alpha Alpha

glStencilFunc(GL_LESS, 3, mask);

3 glStencilFunc glAlphaFunc
mask 1
5 101 mask 000000115 01
3

glClear
glClear(GL_STENCIL_BUFFER_BIT);


glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glClearColor glClearStencil

glStencilOp(fail, zfail, zpass);

GL_KEEP
GL_ZERO
GL_REPLACE
GL_INCR 1
GL_INCR_WRAP 1
GL_DECR 1
GL_DECR_WRAP 1
GL_INVERT
OpenGL
glStencilFuncSeparate glStencilOpSeparate glStencilFunc
glStencilOp face
GL_FRONT, GL_BACK, GL_FRONT_AND_BACK

glDepthM ask(GL_FALSE);

OpenGL 1.0
CPU

glStencilFuncSeparate glStencilOpSeparate

(1)
(2) glClear 0
(3) glStencilFunc(GL_ALWA YS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1 0
(4) glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1

X Y
draw_sphere glScalef(1.0f, 1.

0f, -1.0f); draw_sphere

void draw_sphere()
{
//
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
{
GLfloat
pos[]

= {5.0f, 5.0f, 0.0f, 1.0f},

ambient[] = {0.0f, 0.0f, 1.0f, 1.0f};


glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_AM BIENT, ambient);
}

//
glColor3f(1, 0, 0);
glPushM atrix();
glTranslatef(0, 0, 2);
glutSolidSphere(0.5, 20, 20);

glPopM atrix();
}

void display(void)
{
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//
glM atrixM ode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 5, 25);
glM atrixM ode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5, 0, 6.5, 0, 0, 0, 0, 1, 0);

glEnable(GL_DEPTH_TEST);

//
glDisable(GL_STENCIL_TEST);
draw_sphere();

//
//
//
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_STENCIL_TEST);

glDisable(GL_LIGHTING);
glColor3f(0.5f, 0.5f, 0.5f);
glDepthM ask(GL_FALSE);
glRectf(-1.5f, -1.5f, 1.5f, 1.5f);
glDepthM ask(GL_TRUE);

//
// X Y Z
//
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glScalef(1.0f, 1.0f, -1.0f);
draw_sphere();

//
glutSwapBuffers();

//
grab();
}

display grab BM P
bug
glReadBuffer(GL_FRONT);

(1) glClearColor Alpha 0.0


(2)

Alpha 0.0
(3) Alpha 1.0
(4) GL_DST_ALPHA GL_ONE_M INUS_DST_ALPHA
Alpha 1.0 Alpha 0.0
Alpha 1.0
OpenGL

Alpha 0.0

GLUT
glutInitDisplayMode GLUT_DEPTH

OpenGL
glEnable/glDisable
glEnable(GL_DEPTH_TEST); //
glDisable(GL_DEPTH_TEST); //
Alpha glDepthFunc
GL_LESS
glDepthFunc(GL_LESS);

OpenGL

OpenGL Alpha
OpenGL

Alpha Alpha

OpenGL
GLUT glutInitDisplayMode
OpenGL OpenGL
OpenGL

OpenGL
glStencilFunc
glStencilFunc

bug grab
glReadBuffer(GL_FRONT);

http://file.pfan.cn/down/bbs/7/20071007731.zip

You might also like