Нарисовать компьютер при помощи библиотеки OpenGL в среде Delphi с использованием текстур, подгружаемых с внешнего графического файла. Использовать методы освещения сцены.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, math, ExtCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormResize(Sender: TObject);
private
DC : HDC;
hrc: HGLRC;
ry : GLfloat;
LightPos : Array [0..3] of GLfloat;
quadObj : GLUquadricObj;
Bitmap: TBitmap;
Bits: Array [0..255, 0..127, 0..2] of GLubyte;
procedure BmpTexture;
end;
var
Form1: TForm1;
mode : (POINT, LINE, FILL, SILHOUETTE) = FILL;
gluobj : (SPHERE, CONE, CYLINDER, DISK) = SPHERE;
orientation : (OUTSIDE, INSIDE) = OUTSIDE;
normals : (NONE, FLAT, SMOOTH) = SMOOTH;
implementation
{$R *.DFM}
procedure TForm1.BmpTexture;
var
i, j: Integer;
begin
bitmap := TBitmap.Create;
bitmap.LoadFromFile('monik.bmp'); //считывание картинки рабочего стола монитора
For i := 0 to 255 do
For j := 0 to 127 do begin
bits [i, j, 0] := GetRValue(bitmap.Canvas.Pixels[i,j]);
bits [i, j, 1] := GetGValue(bitmap.Canvas.Pixels[i,j]);
bits [i, j, 2] := GetBValue(bitmap.Canvas.Pixels[i,j]);
end;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
256, 128,
0, GL_RGB, GL_UNSIGNED_BYTE, @Bits);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glEnable(GL_TEXTURE_2D);
end;
{Перерисовка окна}
procedure TForm1.FormPaint(Sender: TObject);
var
i,j:real;
begin
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // очистка буфера цвета
glLightfv(GL_LIGHT0, GL_POSITION, @LightPos); //позиция света
glPushMatrix;
glRotatef (ry, 0.0, 0.5, 0.0); //поворот картинки
glTranslatef (-1.5, 0.0, 0.0); //перенос по оси координат
glEnable(GL_TEXTURE_2D);
glBegin (GL_QUADS);
glTexCoord2d (0.5, 0.0); //экран
glVertex3f (0.0, 0.0, 0.0);
glTexCoord2d (0.5, 1.0);
glVertex3f (3.0, 0.0, 0.0);
glTexCoord2d (0.0, 1.0);
glVertex3f (3.0, 1.5, 0.0);
glTexCoord2d (0.0, 0.0);
glVertex3f (0.0, 1.5, 0.0);
glEnd;
glDisable(GL_TEXTURE_2D);
glcolor3f(1,1,1);
glBegin (GL_QUADS);
glnormal3f (3.0, 0.0, 0.0); // корпус
glnormal3f (3.0, 1.5, 0.0);
glnormal3f (3.0, 1.5, 0.05);
glnormal3f (3.0, 0.0, 0.05);
glnormal3f (0.0, 0.0, 0.0);
glnormal3f (0.0, 1.5, 0.0);
glnormal3f (0.0, 1.5, 0.05);
glnormal3f (0.0, 0.0, 0.05);
glnormal3f (0.0, 1.5, 0.0);
glnormal3f (3.0, 1.5, 0.0);
glnormal3f (3.0, 1.5, 0.05);
glnormal3f (0.0, 1.5, 0.05);
glnormal3f (0.0, 0, 0.0);
glnormal3f (3.0, 0, 0.0);
glnormal3f (3.0, 0, 0.05);
glnormal3f (0.0, 0, 0.05);
glnormal3f (-0.1, -0.1, 0.05);
glnormal3f (3.1, -0.1, 0.05);
glnormal3f (3.1, 0.0, 0.05);
glnormal3f (-0.1, 0.0, 0.05);
glnormal3f (-0.1, 1.6, 0.05);
glnormal3f (3.1, 1.6, 0.05);
glnormal3f (3.1, 1.5, 0.05);
glnormal3f (-0.1, 1.5, 0.05);
glnormal3f (3.1, 1.5, 0.05);
glnormal3f (3.0, 1.5, 0.05);
glnormal3f (3.0, 0, 0.05);
glnormal3f (3.1, 0, 0.05);
glnormal3f (-0.1, 1.5, 0.05);
glnormal3f (0.0, 1.5, 0.05);
glnormal3f (0.0, 0, 0.05);
glnormal3f (-0.1, 0, 0.05);
glnormal3f (3.1, -0.1, -0.1);
glnormal3f (3.1, 1.6, -0.1);
glnormal3f (3.1, 1.6, 0.05);
glnormal3f (3.1, -0.1, 0.05);
glnormal3f (-0.1, -0.1, -0.1);
glnormal3f (-0.1, 1.6, -0.1);
glnormal3f (-0.1, 1.6, 0.05);
glnormal3f (-0.1, -0.1, 0.05);
glnormal3f (-0.1, 1.6, -0.1);
glnormal3f (3.1, 1.6, -0.1);
glnormal3f (3.1, 1.6, 0.05);
glnormal3f (-0.1, 1.6, 0.05);
glnormal3f (-0.1, -0.1, -0.1);
glnormal3f (3.1, -0.1, -0.1);
glnormal3f (3.1, -0.1, 0.05);
glnormal3f (-0.1, -0.1, 0.05);
glnormal3f (-0.1, -0.1, -0.1);
glnormal3f (3.1, -0.1, -0.1);
glnormal3f (3.1, 1.6, -0.1);
glnormal3f (-0.1, 1.6, -0.1);
glVertex3f (3.0, 0.0, 0.0);
glVertex3f (3.0, 1.5, 0.0);
glVertex3f (3.0, 1.5, 0.05);
glVertex3f (3.0, 0.0, 0.05);
glVertex3f (0.0, 0.0, 0.0);
glVertex3f (0.0, 1.5, 0.0);
glVertex3f (0.0, 1.5, 0.05);
glVertex3f (0.0, 0.0, 0.05);
glVertex3f (0.0, 1.5, 0.0);
glVertex3f (3.0, 1.5, 0.0);
glVertex3f (3.0, 1.5, 0.05);
glVertex3f (0.0, 1.5, 0.05);
glVertex3f (0.0, 0, 0.0);
glVertex3f (3.0, 0, 0.0);
glVertex3f (3.0, 0, 0.05);
glVertex3f (0.0, 0, 0.05);
glVertex3f (-0.1, -0.1, 0.05);
glVertex3f (3.1, -0.1, 0.05);
glVertex3f (3.1, 0.0, 0.05);
glVertex3f (-0.1, 0.0, 0.05);
glVertex3f (-0.1, 1.6, 0.05);
glVertex3f (3.1, 1.6, 0.05);
glVertex3f (3.1, 1.5, 0.05);
glVertex3f (-0.1, 1.5, 0.05);
glVertex3f (3.1, 1.5, 0.05);
glVertex3f (3.0, 1.5, 0.05);
glVertex3f (3.0, 0, 0.05);
glVertex3f (3.1, 0, 0.05);
glVertex3f (-0.1, 1.5, 0.05);
glVertex3f (0.0, 1.5, 0.05);
glVertex3f (0.0, 0, 0.05);
glVertex3f (-0.1, 0, 0.05);
glVertex3f (3.1, -0.1, -0.1);
glVertex3f (3.1, 1.6, -0.1);
glVertex3f (3.1, 1.6, 0.05);
glVertex3f (3.1, -0.1, 0.05);
glVertex3f (-0.1, -0.1, -0.1);
glVertex3f (-0.1, 1.6, -0.1);
glVertex3f (-0.1, 1.6, 0.05);
glVertex3f (-0.1, -0.1, 0.05);
glVertex3f (-0.1, 1.6, -0.1);
glVertex3f (3.1, 1.6, -0.1);
glVertex3f (3.1, 1.6, 0.05);
glVertex3f (-0.1, 1.6, 0.05);
glVertex3f (-0.1, -0.1, -0.1);
glVertex3f (3.1, -0.1, -0.1);
glVertex3f (3.1, -0.1, 0.05);
glVertex3f (-0.1, -0.1, 0.05);
glVertex3f (-0.1, -0.1, -0.1); //задняя крышка
glVertex3f (3.1, -0.1, -0.1);
glVertex3f (3.1, 1.6, -0.1);
glVertex3f (-0.1, 1.6, -0.1);
glEnd;
glRotatef (90, 1.0, 0.0, 0.0); //поворот картинки
glTranslatef (1.5, 0.0, 0.0); //перенос по оси координат
gluCylinder (quadObj, 0.05, 0.05, 0.4, 10, 10);
glTranslatef (0.0, 0.0, 0.4); //перенос по оси координат
gluCylinder (quadObj, 0.5, 0.5, 0.1, 30, 30);
glbegin(gl_triangles);
i := 1;
while i <= 360 do
begin
glnormal3f(0,0,0.1);
glvertex3f(0,0,0.1);
glnormal3f(cos(math.DegToRad(i))*0.5,sin(math.DegToRad(i))*0.5,0);
glvertex3f(cos(math.DegToRad(i))*0.5,sin(math.DegToRad(i))*0.5,0);
glnormal3f(cos(math.DegToRad(i+12))*0.5,sin(math.DegToRad(i+12))*0.5,0);
glvertex3f(cos(math.DegToRad(i+12))*0.5,sin(math.DegToRad(i+12))*0.5,0);
i := i + 12;
end;
glend;
glbegin(gl_triangles);
i := 1;
while i <= 360 do
begin
glnormal3f(0,0,0.1);
glvertex3f(0,0,0.1);
glnormal3f(cos(math.DegToRad(i))*3,sin(math.DegToRad(i))*3,0.1);
glvertex3f(cos(math.DegToRad(i))*3,sin(math.DegToRad(i))*3,0.1);
glnormal3f(cos(math.DegToRad(i+12))*3,sin(math.DegToRad(i+12))*3,0.1);
glvertex3f(cos(math.DegToRad(i+12))*3,sin(math.DegToRad(i+12))*3,0.1);
i := i + 12;
end;
glend;
glTranslatef (-1.5, 1.0, 0.0);
glbegin(gl_quads);
glnormal3f(0,0,0);
glnormal3f(2,0,0);
glnormal3f(2,0.5,0);
glnormal3f(0,0.5,0);
glvertex3f(0,0,0);
glvertex3f(2,0,0);
glvertex3f(2,0.5,0);
glvertex3f(0,0.5,0);
glend;
glbegin(gl_quads);
glcolor3f(0.6,0.6,0.6);
j := 0;
while j < 0.4 do
begin
i := 0;
while i < 2 do
begin
glnormal3f(i,j,-0.04);
glnormal3f(i+0.07,j,-0.04);
glnormal3f(i+0.07,j+0.07,-0.04);
glnormal3f(i,j+0.07,-0.04);
i := i + 0.1;
end;
j := j + 0.1;
end;
j := 0;
while j < 0.4 do
begin
i := 0;
while i < 2 do
begin
glvertex3f(i,j,-0.04);
glvertex3f(i+0.07,j,-0.04);
glvertex3f(i+0.07,j+0.07,-0.04);
glvertex3f(i,j+0.07,-0.04);
glvertex3f(i,j,-0.04);
glvertex3f(i+0.07,j,-0.04);
glvertex3f(i+0.07,j,0.0);
glvertex3f(i,j,0.0);
glvertex3f(i,j+0.07,-0.04);
glvertex3f(i+0.07,j+0.07,-0.04);
glvertex3f(i+0.07,j+0.07,0.0);
glvertex3f(i,j+0.07,0.0);
glvertex3f(i,j,-0.04);
glvertex3f(i,j+0.07,-0.04);
glvertex3f(i,j+0.07,0.0);
glvertex3f(i,j,0.0);
glvertex3f(i+0.07,j,-0.04);
glvertex3f(i+0.07,j+0.07,-0.04);
glvertex3f(i+0.07,j+0.07,0.0);
glvertex3f(i+0.07,j,0.0);
i := i + 0.1;
end;
j := j + 0.1;
end;
glend;
glcolor3f(1,1,1);
glTranslatef (2.5, 0.2, 0);
glbegin(gl_quads);
i := 1;
while i < 360 do
begin
glnormal3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,0.0);
glnormal3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,-0.05);
glnormal3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,-0.05);
glnormal3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,0.0);
i := i + 12;
end;
i := 1;
while i < 360 do
begin
glnormal3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,-0.05);
glnormal3f(cos(math.DegToRad(i))*0.10,sin(math.DegToRad(i))*0.15,-0.1);
glnormal3f(cos(math.DegToRad(i+12))*0.10,sin(math.DegToRad(i+12))*0.15,-0.1);
glnormal3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,-0.05);
i := i + 12;
end;
glend;
glbegin(gl_triangles);
i := 1;
while i <= 360 do
begin
glnormal3f(0,0,-0.1);
glnormal3f(cos(math.DegToRad(i))*0.10,sin(math.DegToRad(i))*0.15,-0.1);
glnormal3f(cos(math.DegToRad(i+12))*0.10,sin(math.DegToRad(i+12))*0.15,-0.1);
i := i + 12;
end;
glend;
glbegin(gl_quads);
i := 1;
while i < 360 do
begin
glvertex3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,0.0);
glvertex3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,-0.05);
glvertex3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,-0.05);
glvertex3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,0.0);
i := i + 12;
end;
i := 1;
while i < 360 do
begin
glvertex3f(cos(math.DegToRad(i))*0.15,sin(math.DegToRad(i))*0.2,-0.05);
glvertex3f(cos(math.DegToRad(i))*0.10,sin(math.DegToRad(i))*0.15,-0.1);
glvertex3f(cos(math.DegToRad(i+12))*0.10,sin(math.DegToRad(i+12))*0.15,-0.1);
glvertex3f(cos(math.DegToRad(i+12))*0.15,sin(math.DegToRad(i+12))*0.2,-0.05);
i := i + 12;
end;
glend;
glbegin(gl_triangles);
i := 1;
while i <= 360 do
begin
glvertex3f(0,0,-0.1);
glvertex3f(cos(math.DegToRad(i))*0.10,sin(math.DegToRad(i))*0.15,-0.1);
glvertex3f(cos(math.DegToRad(i+12))*0.10,sin(math.DegToRad(i+12))*0.15,-0.1);
i := i + 12;
end;
glend;
glPopMatrix;
SwapBuffers(DC);
end;
{Формат пикселя}
procedure SetDCPixelFormat (hdc : HDC);
var
pfd : TPixelFormatDescriptor;
nPixelFormat : Integer;
begin
FillChar (pfd, SizeOf (pfd), 0);
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
nPixelFormat := ChoosePixelFormat (hdc, @pfd);
SetPixelFormat (hdc, nPixelFormat, @pfd);
end;
{Создание формы}
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
DC := GetDC (Handle);
SetDCPixelFormat(DC);
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
glClearColor (0.0, 0.0, 0.0, 0.0); // цвет фона
glLineWidth (1.5);
glEnable (GL_LIGHTING); //включаем свет
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glEnable (GL_COLOR_MATERIAL);
quadObj := gluNewQuadric;
ry := 0.0;
BmpTexture;
LightPos [0] := 0.0; //позиция света
LightPos [1] := 2.0;
LightPos [2] := 10.0;
LightPos [3] := 1.0;
end;
{Конец работы приложения}
procedure TForm1.FormDestroy(Sender: TObject);
begin
gluDeleteQuadric (quadObj);
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
ReleaseDC (Handle, DC);
DeleteDC (DC);
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; //перехват нажатия кнопок
Shift: TShiftState);
begin
If Key = VK_ESCAPE then Close;
If Key = VK_LEFT then begin
ry := ry + 2.0;
InvalidateRect(Handle, nil, False);
end;
If Key = VK_RIGHT then begin
ry := ry - 2.0;
InvalidateRect(Handle, nil, False);
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1, 1, -1, 1, 2, 9);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
// придаем фигуре трёхмерность трёхмерности
glTranslatef(0.0, 0.0, -5.0); // перенос объекта - ось Z
glRotatef(30.0, 1.0, 0.0, 0.0); // поворот объекта - ось X
glRotatef(70.0, 0.0, 1.0, 0.0); // поворот объекта - ось Y
InvalidateRect(Handle, nil, False);
end;
end.