Изображение компьютера

jpg.

Нарисовать компьютер при помощи библиотеки 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.

Ключевые слова: 
OpenGL, сцена 3D, освещение, текстурирование
ВложениеРазмер
Komputer.rar197.43 кб