آموزش openGL در دلفی
برای کار با OpenGL در دلفی، ابتدا باید پنجره مخصوص OpenGL را راه اندازی کنیم. مراحل انجام این کار در زیر توضیح داده شده است؛
1- شناسه های "OpenGL" و "SPF"را در قسمت USES اضافه کنید.
2- یک متغیر سراسری با نام و نوع f_Hdc : LongInt در فرم خود تعریف کنید.(برای برپایی فرمتDC بکار می رود).
3- کد های زیر را به رویداد FormCreate اضافه کنید؛
f_Hdc := GetDC(handle);
SetDCPixelFormat(f_Hdc,24,32); // Create a rendering context
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 0.0); // Black Background
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearDepth(1.0);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
InvalidateRect(Handle, nil, False);
4- در صورتی که میخواهید با تغییر سایز فرم، صفحه ی گرافیکی شما نیز به همان نسبت تغیر کند، دستورات زیر را در رویداد FormResize قرار دهید.
wglMakeCurrent(f_Hdc,hrc);
glViewport(0 , 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (40, Width/Height, 1, 50);
glMatrixMode(GL_MODELVIEW);
5- پروسیجر زیر را در فرم خود تعریف کنید؛
procedure DrawGLScene();
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
//تابع بالا برای پاک کردن صفحه و بافر عمق برای رسم تصویر جدید بکار می رود//
[بجای این عبارت، باید توابعی که در آینده برای رسم شکلها یا نگاشت و ... تعریف می کنید را قرار دهید]
//ازبین دوخط زیر، با توجه به نوع بافرینگ فرم، یکی را انتخاب کنید//
{فقط در حالت تک بافری استفاده می شودglFlush(); {
SwapBuffers(f_Hdc); {فقط در حالت بافر دوبل استفاده می شود}
End;
6- کد زیر را در رویداد formPaint قرار دهید؛
wglMakeCurrent(f_Hdc,hrc); //activate the RC
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
DrawGLScene;
7- کد زیر را در notepad کپی کرده و با نام SPF.pas در فایل پروژه دلفی تان ذخیره کنید؛
تابع زیر برای تنظیم فرمت پیکسل بندی است.
unit SPF; // setup pixel format
interface
uses { uses clause }
Windows ;
var
hrc: HGLRC; // Permanent Rendering Context
procedure CleanUp(Handle: HDC); //Properly Kill The Window
procedure SetDCPixelFormat(Handle: HDC;ColorBits,DepthBufferBits:integer);
implementation
procedure CleanUp(Handle: HDC); //Properly Kill The Window
begin
if hrc<> 0 then //Is There A Rendering Context?
begin
//Are We Able To Release Dc and Rc contexts?
if (not wglMakeCurrent(handle,0)) then
MessageBox(0,'Release of DC and RC failed.'
,' Shutdown Error',MB_OK or MB_IConerror);
//Are We Able To Delete The Rc?
if (not wglDeleteContext(hRc)) then
begin
MessageBox(0,'Release of Rendering Context failed.',
' Shutdown Error',MB_OK or MB_IConerror);
hRc:=0; //Set Rc To Null
end;
end;
end;
procedure SetDCPixelFormat(Handle: HDC;ColorBits,DepthBufferBits:integer);
var
pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do begin
nSize := sizeof(pfd); // Size of this structure
nVersion := 1; // Version number
dwFlags := PFD_SUPPORT_OPENGL Or PFD_DRAW_TO_WINDOW
Or PFD_TYPE_RGBA
or PFD_DOUBLEBUFFER ;{to avoid flickering} // Flags
iPixelType:= PFD_TYPE_RGBA; // RGBA pixel values
cColorBits:= ColorBits; // 24-bit color
cDepthBits:= DepthBufferBits; // 32-bit depth buffer
iLayerType:= PFD_MAIN_PLANE; // Layer type
end;
nPixelFormat := ChoosePixelFormat(Handle, @pfd);
//Did We Find A Matching Pixelformat?
if (nPixelFormat=0) then
begin
CleanUp(handle); //Reset The Display
MessageBox(0,'Cant''t Find A Suitable PixelFormat.'
,'Error',MB_OK or MB_ICONEXCLAMATION);
Halt(1); { Halt right here!}
end;
//Are We Able To Set The Pixelformat?
if (not SetPixelFormat(Handle, nPixelFormat, @pfd)) then
begin
CleanUp(handle); //Reset The Display
MessageBox(0,'Cant''t set PixelFormat.'
,'Error',MB_OK or MB_ICONEXCLAMATION);
Halt(1); { Halt right here!}
end;
hrc := wglCreateContext(Handle);
if (hRc=0) then
begin
CleanUp(handle); //Reset The Display
MessageBox(0,'Cant''t create a GL rendering context.'
,'Error',MB_OK or MB_ICONEXCLAMATION);
Halt(1); { Halt right here!}
end;
//Are We Able To Activate The Rendering Context?
if (not wglMakeCurrent(Handle, hrc)) then
begin
CleanUp(handle); //Reset The Display
MessageBox(0,'Cant''t activate the GL rendering context.'
,'Error',MB_OK or MB_ICONEXCLAMATION);
Halt(1); { Halt right here!}
end;
end;
end.
کد رسم اشکال هندسی دو بعدی:
//=============================================================//
//با دريافت مختصات دو نقطه، يك خط رسم مي كند//
glBegin(GL_LINES);
glVertex2f( -1, 1); // Vertex 1
glVertex2f( 2, 2); // Vertex 2
glVertex2f( 0, 0); // Vertex 3
glVertex2f( 1, -1); // Vertex 4
glEnd();
//=============================================================//
//جدول بندي کردن زمينه//
glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0101); // // عدد 1 براي انتخاب نوع کاراکتر در رسم خطوط
for i:=-9 to 9 do
begin
drawoneline(i,-9,i,9); // //رسم خطوط عمودي
drawoneline(-9,i,9,i); // //رسم خطوط افقي
end;
glDisable (GL_LINE_STIPPLE);
//=============================================================//
//خطوط متصل به هم ترسيم ميكند يعني با دريافت مختصات سه نقطه ، دو خط رسم مي كند//
;(glBegin (GL_LINE_STRIP
;(glVertex2f (-1, 1); glVertex2f (2, 2
glVertex2f (0, 0); glVertex2f (1, -1);
// ;(glVertex2f (-2, -2
glEnd();
//=============================================================//
//اين تابع، علاوه بر اينكه نقاط متوالي را به هم وصل مي كند با اتصال ابتدا و انتها حلقه ايجاد ميكند
//شكل ايجاد شده توسط اين تابع، رنگ نمي پذيرد//
glBegin (GL_LINE_LOOP);
glVertex2f (-1, 1); glVertex2f (2, 2);
glVertex2f (0, 0); glVertex2f (1, -1);
glVertex2f (-2, -2);
glEnd();
//=============================================================//
//با دريافت مختصات حداقل سه نقطه، يك چند ضلعي رنگ پذير ترسيم مي كند//
glBegin (GL_POLYGON);
glVertex2f (-1, 1); glVertex2f (2, 2);
glVertex2f (0, 0); glVertex2f (1, -2);
glVertex2f (-2, -2);
glEnd();
//=============================================================//
//براي ترسيم چهارضلعي رنگي//
glBegin (GL_QUADS);
glVertex2f (-1, 1);
glVertex2f (2, 2);
glVertex2f (0, 0);
glVertex2f (1, -2);
glEnd();
//=============================================================//
//چهار ضلعي هاي متصل به هم ترسيم مي كند//
glBegin (GL_QUAD_STRIP);
glVertex2f (-1, 1);
glVertex2f (2, 2);
glVertex2f (0, 0);
glVertex2f (1, -2);
glEnd();
//=============================================================//
//با دريافت مختصات هر سه نقطه، يك مثلث رسم مي كند//
glBegin (GL_TRIANGLES);
glVertex2f (-1, 1);
glVertex2f (2, 2);
glVertex2f (0, 0);
glVertex2f (1, -1);
glVertex2f (-2, -2);
glVertex2f (-3, -4);
glEnd();
//=============================================================//
//مثلث هاي به هم متصل ترسيم مي كند//
glBegin (GL_TRIANGLE_STRIP);
glVertex2f (-1, 1);
glVertex2f (2, 2);
glVertex2f (0, 0);
glVertex2f (1, -1);
glVertex2f (-2, -2);
glVertex2f (-3, -4);
glEnd();
//=============================================================//
//براي رسم مثلث و چند ضلعي//
glBegin (GL_TRIANGLE_FAN);
glVertex2f (-1, 1); glVertex2f (2, 2);
glVertex2f (0, 0); glVertex2f (1, -2);
glVertex2f (-2, -2););
glEnd();
//=============================================================//
پروسیجری برای رسم اشکال هندسی دو بعدی:
توجه داشته باشید که ورودی های رویه ای که تعریف می کنید سلیقه ای است. و میتوانید مقادیر مربوط به دوران در راستای x,y,z و زاویه ی دوران، یا انتقال به x,y,z را از ورودی حذف کنید. و تابع مربوطه را نیز از قسمت کد بردارید.
//تابع رسم چهار ضلعی//
procedure DrawQuad(x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3:double; R,G,B:Double; RotateAngle:
Glfloat);
var
I:integer;
begin
glLoadIdentity;
glTranslatef(x,y,z);
// glColor3f(R,G,B); // 1.7,0.6,0.0
glBegin (GL_QUADS);
// glVertex3f (x0,y0,z0); // -4.85,-2, -20
// glVertex3f (x1,y1,z1); // 4.85,-2, -20
// glVertex3f (x2,y2,z2); // 4.85,-2, 05
// glVertex3f (x3,y3,z3); // -4.85,-2, 05
glEnd();
end;
//تابع رسم دایره//
procedure DrawCircle(x0,y0,z0:integer; r_:double; R,G,B:Double; RotateAngle: Glfloat);
var
I:integer;
y1:Double;
begin
glLoadIdentity;
glTranslatef(x+x0,y+y0,z+z0);
glRotatef(RotateAngle,1.0,0.0,0.0);
glBegin (GL_POLYGON);
yi:=r_;
y1:=yi;
//--------------------------------------------
glColor3f(R,G,B);
xi:=0;
glVertex3f (xi, yi, 0.00); // start point
for I := 1 to 100 do
begin
yi:=yi-0.01;
if sqr(y1)-sqr(yi)<0 then
Continue;
xi:=Sqrt(sqr(y1)-sqr(yi));
//glColor3f(R,G+i,B);
glVertex3f (xi, yi, 0.00);
end;
yi:=-y1;
xi:=0;
glVertex3f (xi, yi, 0.00); // half point
//--------------------------------------------
for I := 1 to 100 do
begin
yi:=yi+0.01;
if sqr(y1)-sqr(yi)<0 then Continue;
xi:=-Sqrt(sqr(y1)-sqr(yi));
glVertex3f (xi, yi, 0.00);
end;
//--------------------------------------------
glEnd();
end;
موفق باشید