OPENGL graphics programming
OPENGL is a three-dimensional graphics and model library. Due to its outstanding performance in three-dimensional graphics, many high-level languages currently provide interfaces with OPENGL, such as: VC, DELPHI, C++Builder, etc. Using OPENGL can greatly reduce the difficulty for users to develop graphics and images, allowing users to produce high-level commercial advertisements, graphic CAD, three-dimensional animation, graphic simulation and film and television collection.
1. Functions of OPENGL
OPENGL was originally a graphics software library on workstations. Due to its wide application in commercial, military, medical, aerospace and other fields, graphics that meet user requirements can now be developed on low-end computers. OPENGL can not only draw basic images, but also provides a large number of functions and procedures for processing graphic images.
1. Graphic transformation
It is the basis of graphic display and production. Animation design and animation display are inseparable from graphic transformation. Graphic transformation is mathematically realized by the multiplication of rectangles. Transformation generally includes translation, rotation and scaling. According to the display properties of graphics: viewpoint transformation, model transformation, projection transformation, clipping transformation and viewport transformation, etc.
2. Lighting effect
The color of a non-luminous object is caused by the object reflecting external light, which is illumination. In three-dimensional graphics, if lighting is used improperly, the three-dimensional graphics will lose their true three-dimensional sense. OPENGL divides lighting into: radiant light, ambient light, scattered light, reflected light, etc.
3. Texture mapping
Texture mapping allows you to add real-world textures to three-dimensional surfaces. For example: a rectangle cannot represent an object in the real world. If it is filled with "essential" texture, it will become realistic.
4. Graphic special effects
The blending function, anti-aliasing function and fog function can handle the transparency and translucence of three-dimensional graphics, let the object be smooth, use line segments to smooth and provide a fog effect.
5. Image special effects
Basic functions for processing bitmaps: image drawing, image copying and storage, mapping and transfer, image scaling, etc. The bitmap operation function can explain the formation process of Chinese characters at the lower level of the original drawing.
2. Create OPENGL application
1. General principles
A. Add OPENGL support unit in uses: OpenGL;
B initialize OPENGL during the form's OnCreate event;
C initializes OPENGL during the window's OnPaing event;
D initializes OPENGL during the window's OnResize event;
E initializes OPENGL during the window's OnDestroy event;
2. Simple example
A Create a project FILE->New application
B Add code in the OnCreate event:
PRocedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor; //Set description table
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientWidth;
h:=ClientHeight;
end;
C code in OnDestroy event
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
D code in OnPaint event
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
MyDraw;
glFlush;
SwapBuffers(Canvas.Handle);
end;
E code in OnResize event
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,ClientWidth,ClientHeight);
MyDraw;
end;
F code in MyDraw function (declared by the user in the window class)
procedure TfrmMain.MyDraw;
begin
glPushMatrix;
Sphere:=gluNewQuadric;
gluQuadricDrawStyle(Sphere,GLU_LINE);
gluSphere(Sphere,0.5,25,25);
glPopMatrix;
SwapBuffers(Canvas.handle);
gluDeleteQuadric(Sphere);
end;
Attached is the original code of this program:
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL;
type
TfrmMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{Private declarations}
hrc:HGLRC;
w,h:glFloat;
Sphere:GLUquadricObj;
public
{Public declarations}
procedure MyDraw;
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor;
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientWidth;
h:=ClientHeight;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
MyDraw;
glFlush;
SwapBuffers(Canvas.Handle);
end;
procedure TfrmMain.MyDraw;
begin
glPushMatrix;
Sphere:=gluNewQuadric;
gluQuadricDrawStyle(Sphere,GLU_LINE);
gluSphere(Sphere,0.5,25,25);
glPopMatrix;
SwapBuffers(Canvas.handle);
gluDeleteQuadric(Sphere);
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,ClientWidth,ClientHeight);
MyDraw;
end;
end.
3. Conventions on OPENGL variables and functions
1. OPENGL library conventions
It has three libraries in total: basic library, practical library, and auxiliary library. In DELPHI, the basic library is implemented by the OpenGL unit. In the Windows environment, auxiliary libraries are generally not used.
2. OPENGL constant convention
OPENGL constants use capital letters, starting with "GL", and use underscores to separate words, such as: GL_LINES, which means using the basic library to draw straight lines.
3. Naming convention of OPENGL functions
A The first part starts with gl or wgl, like gl in glColor3f.
B The second part is the function expressed in English, with the first letter of the word capitalized.
The third part of C is a number, representing the parameters of the function.
The fourth part of D is a lowercase letter indicating the type of function.
b9-bit integer
s16-bit integer
i32-bit integer
f32-bit floating point number
d64-bit floating point number
ub9-bit unsigned integer
Example: glVertex2f(37,40); {two 32-bit floating point numbers as parameters}
glVertex3d(37,40,5); {Three 64-bit floating point numbers as parameters}
p[1..3]:array of glFloat;
glVertes3fv(p); {3f represents three floating point numbers, v represents calling an array as the vertex coordinate input}
4. Initialization of OPENGL
1. PIXELFORMATDESCRIPTOR structure
It mainly describes the properties of pixels, such as the color mode of pixels and the composition of red, green, and blue colors.
tagPIXELFORMATDESCRIPTOR = packed record
nSize: Word;
nVersion: Word;
dwFlags: DWORD;
iPixelType: Byte;
cColorBits: Byte;
cRedBits: Byte;
cRedShift: Byte;
cGreenBits: Byte;
cGreenShift: Byte;
cBlueBits: Byte;
cBlueShift: Byte;
cAlphaBits: Byte;
cAlphaShift: Byte;
cAccumBits: Byte;
cAccumRedBits: Byte;
cAccumGreenBits: Byte;
cAccumBlueBits: Byte;
cAccumAlphaBits: Byte;
cDepthBits: Byte;
cStencilBits: Byte;
cAuxBuffers: Byte;
iLayerType: Byte;
bReserved: Byte;
dwLayerMask: DWORD;
dwVisibleMask: DWORD;
dwDamageMask: DWORD;
end;
TPixelFormatDescriptor = tagPIXELFORMATDESCRIPTOR;
dwFlags represents the attributes of the point format:
PFD_DRAW_TO_WINDOW graphics are drawn on the screen or device surface
PFD_DRAW_TO_BITMAP draws bitmap in memory
PFD_SUPPORT_GDI supports GDI drawing
PFD_SUPPORT_OPENGL supports OPENGL functions
PFD_DOUBLEBUFFER uses double buffering
PFD_STEREO stereo cache
PFD_NEED_PALLETTE uses RGBA palette
PFD_GENERIC_FORMAT selects the format drawing supported by GDI
PFD_NEED_SYSTEM_PALETTE uses OPENGL supported hardware palette
iPixelType sets the pixel color mode: PFD_TYPE_RGBA or PFD_TYPE_INDEX..
cColorBits sets the color bits. If it is 9, it means that there are 256 colors to represent the color of the point.
cRedBits, cGreenBits, cBlueBits When using RGBA, the number of bits used for the three primary colors.
cRedShitfs, cGreenShifts, cBlueShifts When using RGBA, the number of digits that can be adjusted for the three primary colors.
cAlphaBits, cAlphaShifts When using RGBA, the number of bits used by Alpha and the number of adjustable bits.
cAccumBits sets the total number of bits in the accumulation buffer area.
cAccumRedBits, cAccumGreenBits, and cAccumBlueBits set the total number of three primary color planes in the accumulation buffer area.
cAccumAlphaBits sets the total number of Alpha bits in the accumulation buffer.
cDepthBits sets the depth of the concentration buffer.
cStencilBits sets the depth of the Stencil cache.
cAuxBuffers refers to the size of the auxiliary buffer.
iLayerType specifies the type of layer.
bReserved is not used and must be zero.
dwLayerMask specifies the mask of the overlay.
dwDamageMask sets whether the same pixel mode is shared in the same frame cache.
2. Initialization steps of OPENGL
A Use Canvas.Handle to obtain the window handle.
B Create a TPixelFormatDescriptor variable to define the pixel format.
C Use the ChoosePixelFormat function to select the pixel format.
D Use the SetPixelFormat function to use the pixel format to take effect.
E Use the wglCreateContext function to create a translation description table.
F Use the wglMakeCurrent function to use the created translation description table as the current translation description table.
3. Resource release
A Use the wglDeleteContext procedure to delete the pixel context table.
B Use the ReleaseDC procedure to release window memory.
In the window's OnDestroy event:
begin
if hrc<>null then
wglDeleteCurrent(hrc);
if hdc<>null then
ReleaseDC(Handle,hdc);
end;
5. Drawing of OPENGL basic graphics
1. Color of graphics
Pay attention to the setting of the background color. The color setting is usually related to the pixel description variable, that is, to the iPixelType member in the TPixelFormatDescriptor definition.
iPixelType:=PFD_TYPE_COLORINDEX;
Then you can only use the glIndexd, glIndexf, glIndexi, glIndexs, glIndexv, glIndexfv, glIndexiv, glIndexsv procedures to set the graphics color.
iPixelType:=PFD_TYPE_RGBA;
Then you can only use glColor3b, glColor3f, glColor4b, glColor4f, glColor4fv to set the graphics color.
A Graphics background color: the color of the screen and window, that is, the color of the color buffer. To change the background color of graphics, you should first use the glClearColor procedure to set the background color, and then use the glClear procedure to refresh the window and screen with this background color.
procedure glClearColor(red:GLClampf,green:GLClampf,blue:GLClampf,alpha:GLClampf);
procedure glClear(mask:GLBitField);
red, green, blue, and alpha are the background colors to be set, and their values are 0 to 1. Mask is a way to refresh the background color.
Example: Set the coloring window to green
glClearColor(0,1,0,1);
glClear(GL_COLOR_BUFFER_BIT);
The value and meaning of mask:
GL_COLOR_BUFFER_BIT sets the current color buffer
GL_DEPTH_BUFFER_BIT sets the current depth buffer
GL_ACCUM_BUFFER_BIT sets the current accumulation buffer
GL_STENCIL_BUFFER_BIT sets the current STENCIL (template) buffer
The drawing window is set to gray
glClearColor(0.3,0.3,0.3,1);
glClear(GL_COLOR_BUFFER_BIT);
B graphic color
Use glClear3f and glClear4f to set the drawing color of graphics. If three parameters are used, it means setting the three colors of red, blue and green light respectively. If four parameters are used, the fourth one represents the RGBA value.
Example of setting the current drawing color to blue:
glColor3f(0,0,1);
Set the plot color to white:
glColor3f(1,1,1);
2. Drawing of simple graphics
Draw simple graphics, such as points, lines, polygons, etc., between the glBegin and glEnd procedures.
glBegin(mode:GLenum);{Drawing process}glEnd;
The value of mode:
GL_POINTS draws multiple points
GL_LINES draws multiple lines, drawing a straight line every two points
GL_LINE_STRIP draws polyline
GL_LINE_LOOP draws closed polygons connected end to end
GL_TRIANGLES draws triangles
GL_TRIANGLE_STRIP draws a triangle, drawing a triangle every three points
GL_TRIANGLE_FAN draws triangles
GL_QUADS draws quadrilaterals
GL_QUAD_STRIP draws quadrilateral strips, one quadrilateral strip is drawn for every four points
GL_POLYGON draws polygons
Example of drawing three points:
begin
glPushMatrix;
glBegin(GL_POINT);
glVertex2f(0.1,0.1);
glVertex2f(0.5,0.5);
glVertex2f(0.1,0.3);
glEnd;
SwapBuffers(Canvas.Handle);
end;
If you change GL_POINT to GL_LINES, you will draw a line. The third point is invalid. Doing glColor3f(0,0,1) before glVertex2f will change the color of the line to green. If you change GL_LINES to GL_LINE_STRIP, you can draw two A straight line.
Use the glPointSize procedure to set the point size; use the glLineWidth procedure to set the line width.
Use the glLineStipple procedure to set the template for dotted lines, and use the glEnable(GL_LINE_STIPPLE) procedure and corresponding parameters to enable drawing to draw dotted lines. The glDisable(GL_LINE_STIPPLE) procedure and corresponding parameters turn off dotted lines.
procedure glLineStipple(factor:GLint,pattern:GLushort);
The parameter factor represents the number of repetitions of the dot-dash line template Pattern. The value of factor is 1255. Pattern is a binary sequence.
glLineStipple(1,0,0x11C);{0x11C is represented as 10001110, 0 means not to draw points, 1 means to draw points}
Example: begin
glColor3f(1,0,0);
glLineWidth(2);
glLineStipple(1,$11C);
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
glVertex2f(-0.9,0.3);
glVertex2f(0.9,0.3);
glEnd;
glDisable(GL_LINE_STIPPLE);
glColor3f(1,0,1);
glLineStipple(2,$11C);
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
glVertex2f(-0.9,0.1);
glVertex2f(0.9,0.1);
glEnd;
glDisable(GL_LINE_STIPPLE);
SwapBuffers(Canvas.Handle);
end;
Polygon drawing is similar to point-line drawing. You need to change the parameters to GL_POLYGON, GL_QUADS, GL_TRANGLES. Things to note when drawing:
The sides of a polygon intersect only at the vertices
The B polygon must be a convex polygon. If it is a concave polygon, the user can only fold it into a convex polygon to speed up the drawing.
Example: glBegin(GL_POLYGON);
glVertex2f(-0.9,0.3);
glVertex2f(0.9,0.3);
glVertex2f(0.9,-0.6);
glVertex2f(0.5,-0.6);
glVertex2f(-0.9,-0.2);
glEnd;
Polygons have front and back sides, and the processes related to them are:
glPolygonMode controls polygon front and back drawing modes
glFrontface specifies the front face of the polygon
glCullFace displays polygons that are set to eliminate faces
glPolygonStripple forms the style of a polygon fill
3. Simple quadratic surface
Cylinders, rings and spheres are all quadratic surfaces.
A cylinder
gluCylinder(qobj:GLUquadricObj,baseRadius:GLdouble,topRadius:GLdouble,height:GLdouble,
slices:GLint,stacks:GLint);
qobj specifies a quadratic surface, baseRadius is the base radius of the cylinder; topRadius is the top radius of the drawn cylinder; height is the height of the cylinder; slices is the number of dividing lines around the Z axis; stacks is the number of dividing lines along the Z axis. .
If baseRadius and topRadius are not equal, you can draw a frustum and a cone.
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
gluCylinder(qObj,0.5,0.1,0.2,10,10);
end;
B ring
gluDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
loops:GLint);
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
gluDisk(qObj,0.2,0.5,10,5);
SwapBuffers(Canvas.Handle);
end;
C half circle
gluPartialDisk(qobj:GLUquadricObj,innerRadius:GLdouble,outerRadius:GLdouble,slices:GLint,
loops:GLint,startAngle:GLdouble,sweepAngle:GLdouble);
startAngle, sweepAngle are the starting angle and ending angle of the semicircle.
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
gluPartialDisk(qObj,0.2,0.5,10,5,90,190);
SwapBuffers(Canvas.Handle);
end;
D sphere
function gluSphere(qObj:GLUquadricObj,radius:GLdouble,slices:GLint,stacks:GLint);
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
{ silhouette[ silu(:)5et ]n. silhouette, outline}
gluSphere(qObj,0.5,20,20);
SwapBuffers(Canvas.Handle);
end;
E About the process of quadratic surface
gluNewQuadric creates a new quadratic surface object
gluDeleteQuadric deletes a quadratic surface object
gluQuadricDrawStyle specifies the type of quadric surface to draw
gluQuadricNormal sets the normal vector of the quadratic surface
gluQuadricOrientation sets whether the quadratic surface is internally rotated or externally rotated
gluQuadricTexture sets whether the quadratic surface uses texture
F General steps for drawing quadratic surfaces
First define a GLUquadricObj object;
Secondly, create a surface object gluNewQuadric;
Set the properties of the quadratic surface again (gluQuadricDrawStyle, gluQuadricTexture)
Draw quadratic surfaces (gluCylinder, gluSphere, gluDisk, gluPartialDisk)
6. Transformation in OPENGL
Transformation is the basis of animation design, including graphic translation, rotation, scaling and other operations, which are mathematically implemented through matrices.
1 glLoadIdentity process
Able to convert the current matrix into an identity matrix.
2 glLoadMatrix process
Able to set the specified matrix as the current matrix.
procedure glLoadmatrixd(m:GLdouble);
procedure glLoadmatrixf(m:GLfloat);
m represents a 4X4 matrix, the following code defines and makes it the current matrix
M:array[1..4,1..4] of GLfloat;
glLoadMatrix(@M);
3 glMultMatrix process
Able to multiply the current moment by the specified matrix and use the result as the current moment.
procedure glMultMatrixd(M:GLdouble);
procedure glMultMatrixf(M:GLfloat);
4 glPushMatrix and glPopmatrix
glPushMatrix can push the current moment into the matrix stack, and glPopMatrix can pop the current moment out of the matrix stack.
glPushMatrix can remember the current position of the matrix, and glPopmatrix can return the previous position.
Note: glPushMatrix and glPopMatrix must be placed outside glBegin and glEnd.
5 Projection transformation
A glOrtho can create an orthographic projection matrix, multiply the current moment by the orthographic projection matrix, and use the result as the current matrix.
function glOrtho(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble,
near:GLdouble,far:GLdouble);
procedure TfrmMain.FormResize(Sender: TObject);
var
nRange:GLfloat;
begin
nRange:=50.0;
w:=clientWidth;
h:=clientHeight;
if h=0 then
h:=1;
glViewPort(0,0,w,h);
if w<=h then
glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
-nRange,nRange)
else
glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
-nRange,nRange);
repaint;
end;
B glOrtho2D only defines the front, back, left and right of the orthographic viewing volume.
procedure glOrtho(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble);
C glMatrixMode procedure
Ability to set the type of the current operation matrix
procedure glMatrixMode(mode:GLenum);
The value of mode:
GL_MODELVIEW specifies that subsequent matrix operations are model matrix stacks
GL_PROJECTION specifies that subsequent matrix operations be projection matrix stacks
GL_TEXTURE specifies that subsequent matrix operations are texture matrix stacks
D glFrustum process
Create a perspective oblique projection matrix and multiply the current matrix by the oblique projection matrix. The result is the current matrix.
procedure glFrustum(left:GLdouble,right:GLdouble,bottom:GLdouble,top:GLdouble,
next:GLdouble,far:GLdouble);
These parameters define the left, right, top, bottom, front, and back clipping planes of the oblique projection.
E gluPerspective process
Able to define a four-sided pyramid viewing volume with the Z axis as the centerline.
procedure gluPerspetive(fovy:GLdouble,aspect:GLdouble,zNear:GLdouble,zFar:GLdouble);
fovy defines the perspective of the xoz plane, aspect defines the ratio in the x and y directions, zNear and zFar define the distances from the viewpoint to the clipping plane and the back clipping plane respectively.
procedure TfrmMain.FormResize(Sender: TObject);
var
aspect:GLfloat;
begin
w:=ClientWidth;
h:=ClientHeight;
if h=0 then
h:=1;
glViewPort(0,0,clientWidth,Clientheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
aspect:=w/h;
gluPerspective(30.0,aspect,1.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
6 Geometric transformation matrix
The movement posture transformation of a three-dimensional object refers to the translation, rotation, and scaling of the object.
A glTranslate process can move the coordinate origin to (x, y, z), its declaration syntax:
procedure glTranslated(x:GLdouble,y:GLdouble,z:GLdouble);
procedure glTranslatef(x:GLdouble,y:GLdouble,z:GLdouble);
B glRotate can rotate an object to a certain angle. Its declaration syntax is:
procedure glRotated(angle:GLdouble,x:GLdouble,y:GLdouble,z:GLdouble);
procedure glRotatef(angle:GLdouble,x:GLdouble,y:GLdouble,z:GLdouble);
Among them, angle is the rotation angle, and the central axis of rotation is the line connecting the two points (0,0,0) and (x,y,z).
C glScale can scale the coordinate system, and its declaration syntax is:
procedure glScaled(x:GLdouble,y:GLdoble,z:GLdouble);
procedure glScalef(x:GLdouble,y:GLdoble,z:GLdouble);
Values of x, y, and z greater than 1 represent enlargement, and values less than 1 represent reduction.
Example original code:
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL, ExtCtrls;
type
TfrmMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{Private declarations}
hrc:HGLRC;
w,h:Integer;
latitude,longitude:GLfloat;
radius:GLdouble;
public
{Public declarations}
procedure MyDraw;
procedure InitializeGL(var width:GLsizei;height:GLsizei);
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor;
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientRect.Right;
h:=ClientRect.Bottom;
InitializeGL(w,h);
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
MyDraw;
glFlush;
end;
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
glRotated(0.5,0.0,1.0,0.0);
glRotated(-latitude,1.0,0.0,0.0);
glrotated(longitude,0.0,0.0,1.0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
gluSphere(qObj,0.5,20,20);
SwapBuffers(Canvas.Handle);
end;
{procedure TfrmMain.FormResize(Sender: TObject);
var
nRange:GLfloat;
begin
nRange:=50.0;
w:=clientWidth;
h:=clientHeight;
if h=0 then
h:=1;
glViewPort(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
if w<=h then
glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
-nRange,nRange)
else
glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
-nRange,nRange);
glMatrixMode(GL_MODELVIEW);
glLoadidentity;
repaint;
end;
}
procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_ESCAPE then
Close;
if Key=VK_UP then
glRotatef(-5,1.0,0.0,0.0);
if Key=VK_DOWN then
glRotatef(5,1.0,0.0,0.0);
if Key=VK_LEFT then
glRotatef(-5,0.0,1.0,0.0);
if Key=VK_RIGHT then
glRotatef(5.0,0.0,1.0,0.0);
repaint;
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,clientWidth,clientHeight);
repaint;
invalidate;
end;
procedure TfrmMain.InitializeGL(var width: GLsizei; height: GLsizei);
var
maxObjectSize,aspect:GLfloat;
near_plane:GLdouble;
begin
glClearindex(0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
aspect:=1.0;
gluPerspective(45.0,aspect,3.0,7.0);
glmatrixMode(GL_MODELVIEW);
near_plane:=0.3;
maxObjectSize:=0.3;
radius:=near_plane+maxObjectSize/2.0;
latitude:=0.3;
longitude:=0.6;
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
timer1.Enabled:=false;
MyDraw;
Yield;
Timer1.Enabled:=true;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
timer1.Enabled:=false;
if hrc<>null then
wglDeleteContext(hrc);
end;
end.
7. Lighting and texture of OPENGL
They are all means to enhance the three-dimensional effect and color effect. Lighting can increase the brightness and three-dimensional effect of graphics, and texture can make graphics more realistic. Through the use of lighting, the appearance of an object can be expressed in a strong manner, and textures can make the object show a variety of appearances.
1 Lighting and light source processes and applications
A glIndex procedure makes a color in the color index table the current color.
procedure glIndexd(c:GLdouble);
procedure glIndexf(c:GLdouble);
procedure glIndexi(c:GLdouble);
procedure glIndexs(c:GLdouble);
Parameter C is the index value. If the glIndex procedure is used, the iPixelType member in the TPiexlFormatDescriptor structure is set to PFD_TYPE_COLORINDEX.
B glShadeModel procedure
The glShadeModel process sets the fill mode, value: GL_SMOOTH.
procedure glShadeModel(mode:GLenum);
Note: The above two processes can only be used outside glBegin....glEnd.
C glLight procedure defines light source
procedure glLightf(light:GLenum,pname:GLenum,param:GLfloat);
procedure glLighti(light:GLenum,pname:GLenum,param:GLfloat);
The parameter light defines the light source, its value can be: GL_LIGHT0....GL_LIGHTN, the N value is less than GL_MAX_LIGHT.
The parameter pname specifies the light source parameters:
GL_AMBIENT component intensity of ambient light
GL_DIFFUSE component intensity of scattered light
GL_SPECULAR component intensity of reflected light
GL_POSITION light source position
GL_SPOT_DIRECTION The focus direction of the light source
GL_SPOT_EXPONENT light source index
GL_SPOT_CUTOFF light source direction
GL_CONSTANT_ATTENUATION light constant decay factor
GL_LINEAR_ATTENUATION light secondary attenuation factor
Enable and turn off light sources using glEnable() and glDisable() procedures
glEnable(GL_LIGHTING); //Enable light source
glDisable(GL_LIGHTING); //Turn off the light source
glEnable(GL_LIGHT0); //Enable the 0th light source
glDisable(GL_LIGHT0); //Turn off the 0th light source
Example of setting the light source:
var
sdirection:Array[1..4] of GLfloat:={0.0,1.0,0.0,0.0};
glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,60);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,sdirection);
2 Material and lighting model
A glMaterial procedure sets material parameters
procedure glMaterialf(face:GLenum,pname:GLenum,param:GLfloat);
procedure glMateriali(face:GLenum,pname:GLenum,param:GLfloat);
procedure glMaterialfv(face:GLenum,pname:GLenum,param:GLfloat);
procedure glMaterialiv(face:GLenum,pname:GLenum,param:GLfloat);
The parameter face specifies the surface of the object, and its values are: GL_FRONT, GL_BACK, GL_FRONT_BACK.
pname,param are not introduced in this material.
B glLightModel process
procedure glLightModelf(pname:GLenum,param:GLfloat);
The parameter pname is the light source model parameter, which can take the value GL_LIGHT_MODEL_AMBIENT,
GL_LIGHT_MODEL_LOCAL_VIEWER,GL_LIGHT_MODEL_TWO_SIDE.
Example code:
procedure TfrmMain.SetLighting;
var
MaterialAmbient:array[1..4] of GLfloat;
MaterialDiffuse:Array[1..4] of GLfloat;
MaterialSpecular:Array[1..4] of GLfloat;
AmbientLightPosition:Array[1..4] of GLfloat;
LightAmbient:Array[1..4] of GLfloat;
MaterialShininess:GLfloat;
begin
MaterialAmbient[1]:=0.5;
MaterialAmbient[2]:=0.8;
MaterialAmbient[1]:=0.2;
MaterialAmbient[1]:=1.0;
MaterialDiffuse[1]:=0.4;
MaterialDiffuse[2]:=0.8;
MaterialDiffuse[3]:=0.1;
MaterialDiffuse[4]:=1.0;
MaterialSpecular[1]:=1.0;
MaterialSpecular[2]:=0.5;
MaterialSpecular[3]:=0.1;
MaterialSpecular[4]:=1.0;
materialShininess:=50.0;
AmbientLightPosition[1]:=0.5;
AmbientLightPosition[2]:=1.0;
AmbientLightPosition[3]:=1.0;
AmbientLightPosition[4]:=0.0;
LightAmbient[1]:=0.5;
LightAmbient[2]:=0.2;
LightAmbient[3]:=0.8;
LightAmbient[4]:=1.0;
glMaterialfv(GL_FRONT,GL_AMBIENT,@MaterialAmbient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,@MaterialDiffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,@MaterialSpecular);
glMaterialfv(GL_FRONT,GL_SHININESS,@MaterialShininess);
glLightfv(GL_LIGHT0,GL_POSITION,@AmbientLightPosition);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,@LightAmbient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLShadeModel(GL_SMOOTH);
end;
3 Application of texture
A glTexImage1D defines a one-dimensional texture map.
procedure glTexImage1D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
The parameter targer value is GL_TEXTURE_1D, which is defined as texture mapping, level is the level of the texture image with multi-level resolution, width is the texture width, the value is 2n, and the value of n is 32, 64, 129, etc. Border is the boundary of the texture, and its value is 0 or 1, Pixel is the location of the texture in memory. Component specifies the mixing and adjustment of RGBA:
1Select B ingredient
2Select ingredients B and A
3Select R, G, B ingredients
4Select R,G,B,A ingredients
B glTexImage2D defines two-dimensional texture mapping
procedure glTexImage2D(target:GLenum,level:GLint,components:GLint,width:GLsizei,
border:GLint,format:GLenum,type:GLenum,pixels:GLvoid);
If the parameter target is GL_TEXTURE_2D, the meaning is two-dimensional texture mapping, height is the height of the texture, and other parameters in the function are the same as glTexImage1D. The value of the component parameter is the same as above.
Example code:
procedure TfrmMain.SetTextures;
var
bits:Array[1..64,1..64,1..64] of GLubyte;
bmp:TBitmap;
i,j:Integer;
begin
bmp:=TBitmap.Create;
bmp.LoadFromFile('d:/dsoft/1119/01/logon.bmp');
for i:=1 to 64 do
for j:=1 to 64 do
begin
bits[i,j,1]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
bits[i,j,2]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
bits[i,j,3]:=GLbyte(GetRValue(bmp.Canvas.Pixels[i,j]));
bits[i,j,4]:=255;
end;
{0 represents a single color shading level, GL_RGBA represents a mixed value
64X64 represents the height and width of the texture, 0 represents no border,
GL_RGBA represents the texture type, GL_UNSIGNED_TYPE represents the data type, @generation object address}
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,64,0,GL_RGBA,
GL_UNSIGNED_BYTE,@bits);
glEnable(GL_TEXTURE_2D);
end;
C glTexParameter procedure sets texture parameters
procedure glTexParameterf(target:GLenum,pname:GLenum,param:GLfloat);
procedure glTexParameteri(target:GLenum,pname:GLenum,param:GLfloat);
The parameter target represents GL_TEXTURE_1D or GL_TEXTURE_2D, and param is the texture value.
D glTexEnv function sets the environment parameters of the texture
function glTexEnvf(target:GLenum,pname:GLenum,param:GLfloat);
function glTexEnvi(target:GLenum,pname:GLenum,param:GLfloat);
The parameter target is GL_TEXTURE_ENV,
The parameter pname is the texture parameter value, and the value is GL_TEXTURE_ENV_MODE
The parameter param is the environment value, and its values are GL_MODULATE, GL_DECAL and GL_BLEND.
Sample code for this program:
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL, ExtCtrls;
type
TfrmMain = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{Private declarations}
hrc:HGLRC;
w,h:Integer;
latitude,longitude:GLfloat;
radius:GLdouble;
public
{Public declarations}
procedure SetLighting;
procedure SetTextures;
procedure MyDraw;
procedure InitializeGL(var width:GLsizei;height:GLsizei);
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
var
pfd:TPixelFormatDescriptor;
PixelFormat:Integer;
begin
ControlStyle:=ControlStyle+[csOpaque];
FillChar(pfd,sizeof(pfd),0);
with pfd do
begin
nSize:=sizeof(TPixelFormatDescriptor);
nVersion:=1;
dwFlags:=PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24;
cDepthBits:=32;
iLayerType:=PFD_MAIN_PLANE;
end;
PixelFormat:=ChoosePixelFormat(Canvas.Handle,@pfd);
SetPixelFormat(Canvas.Handle,PixelFormat,@pfd);
hrc:=wglCreateContext(Canvas.Handle);
w:=ClientRect.Right;
h:=ClientRect.Bottom;
InitializeGL(w,h);
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
procedure TfrmMain.FormPaint(Sender: TObject);
begin
wglMakeCurrent(Canvas.Handle,hrc);
glClearColor(1,1,1,1);
glColor3f(1,0,0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
SetTextures;
MyDraw;
SetLighting;
glFlush;
end;
procedure TfrmMain.MyDraw;
var
qObj:GLUQuadricObj;
begin
glPushMatrix;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
glRotated(0.5,0.0,1.0,0.0);
glRotated(-latitude,1.0,0.0,0.0);
glrotated(longitude,0.0,0.0,1.0);
qObj:=gluNewQuadric;
gluQuadricDrawStyle(qObj,GLU_LINE);
gluSphere(qObj,0.5,20,20);
SwapBuffers(Canvas.Handle);
SetLighting;
SetTextures;
end;
{procedure TfrmMain.FormResize(Sender: TObject);
var
nRange:GLfloat;
begin
nRange:=50.0;
w:=clientWidth;
h:=clientHeight;
if h=0 then
h:=1;
glViewPort(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
if w<=h then
glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,
-nRange,nRange)
else
glOrtho(-nRange*h/w,nRange*h/w,-nRange,nRange,
-nRange,nRange);
glMatrixMode(GL_MODELVIEW);
glLoadidentity;
repaint;
end;
}
procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=VK_ESCAPE then
Close;
if Key=VK_UP then
glRotatef(-5,1.0,0.0,0.0);
if Key=VK_DOWN then
glRotatef(5,1.0,0.0,0.0);
if Key=VK_LEFT then
glRotatef(-5,0.0,1.0,0.0);
if Key=VK_RIGHT then
glRotatef(5.0,0.0,1.0,0.0);
repaint;
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);
glViewPort(0,0,clientWidth,clientHeight);
repaint;
invalidate;
end;
procedure TfrmMain.InitializeGL(var width: GLsizei; height: GLsizei);
var
maxObjectSize,aspect:GLfloat;
near_plane:GLdouble;
begin
glClearindex(0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
aspect:=1.0;
gluPerspective(45.0,aspect,3.0,7.0);
glmatrixMode(GL_MODELVIEW);
near_plane:=0.3;
maxObjectSize:=0.3;
radius:=near_plane+maxObjectSize/2.0;
latitude:=0.3;
longitude:=0.6;
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
timer1.Enabled:=false;
MyDraw;
Yield;
Timer1.Enabled:=true;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
timer1.Enabled:=false;
if hrc<>null then
wglDeleteContext(hrc);
end;
procedure TfrmMain.SetLighting;
var
MaterialAmbient:array[1..4] of GLfloat;
MaterialDiffuse:Array[1..4] of GLfloat;
MaterialSpecular:Array[1..4] of GLfloat;
AmbientLightPosition:Array[1..4] of GLfloat;
LightAmbient:Array[1..4] of GLfloat;
MaterialShininess:GLfloat;
begin
MaterialAmbient[1]:=0.5;
MaterialAmbient[2]:=0.8;
MaterialAmbient[1]:=0.2;
MaterialAmbient[1]:=1.0;
MaterialDiffuse[1]:=0.4;
MaterialDiffuse[2]:=0.8;
MaterialDiffuse[3]:=0.1;
MaterialDiffuse[4]:=1.0;
MaterialSpecular[1]:=1.0;
MaterialSpecular[2]:=0.5;
MaterialSpecular[3]:=0.1;
MaterialSpecular[4]:=1.0;
materialShininess:=50.0;
AmbientLightPosition[1]:=0.5;
AmbientLightPosition[2]:=1.0;
AmbientLightPosition[3]:=1.0;
Ambientlightposition [4]: = 0.0;
LightAmbient [1]: = 0.5;
LightAmbient [2]: = 0.2;
LightAmbient [3]: = 0.8;
LightAmbient [4]: = 1.0;
GlmateriaLFV (GL_FRONT, GL_Ambient,@Materialambient);
GlmateriaLFV (GL_FRONT, GL_Diffuse,@Materialdiffuse);
Glmaterialfv (GL_FRONT, GL_SPECULAR,@MaterialSpecular);
GlmateriaLFV (GL_FRONT, GL_SHININESS,@MaterialShinines);
GLLIGHTFV (GL_LIGHT0, GL_POSITION,@AmbientLightposition);
GLLIGHTMODELFV (GL_LIGHT_MODEL_AMBIENT,@LightAmbient);
GLENABLE (GL_LIGHTING);
GLENABLE (GL_LIGHT0);
Glshademodel (GL_SMOOTH);
end;
Procedure tfrmmain.setTextures;
var
bits: Array [1..64, 1..64, 1..64] of glibyte;
bmp: tbitmap;
i, j: integer;
begin
BMP: = tBitmap.create;
BMP.LoadfromFile ('D: /dsoft/1119/02/logon.bmp');
for I: = 1 to 64 DO
for j: = 1 to 64 do
begin
bits [i, j, 1]: = Glbyte (Getrvalue (bmp.canvas.pixels [i, j]));
bits [i, j, 2]: = Glbyte (Getrvalue (bmp.canvas.pixels [i, j]));
bits [i, j, 3]: = Glbyte (GetRvalue (bmp.canvas.pixels [i, j]));
bits [i, j, 4]: = 255;
end;
glpixelstorei (GL_UNPACK_ALIGNMENT, 4);
GLTEXPARAMETERI (GL_Texture_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
GLTEXPARAMETERI (GL_TEXTURE_2D, GL_TEXTUR
GLTEXPAMETERI (GL_Texture_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
{0 means monochrome color color level, GL_RGBA represents a mixed value
64x64 represents the height and width of the texture, 0 means no boundary,
GL_RGBA represents texture type, gl_unsigned_type represents data type,@g object address}
GLTEXIMAGE2D (GL_Texture_2D, 0, GL_RGBA, 64,64,0, GL_RGBA,
Gl_unsigned_byte,@bits);
GLENABLE (GL_Texture_2D);
GLTEXENVF (GL_Texture_env, GL_TEXTURE_ENV_MODE, GL_DECAL);
end;
end.