PDA

View Full Version : اعمال رنگ به چند ضلعی ها در OpenGL



Vahid_Nasiri
پنج شنبه 12 تیر 1382, 00:56 صبح
در این مثال قصد داریم مثال سیاه و سفید قبلی را با رنگ و لعاب بهتری ارائه دهیم!

توابع که در مثال جاری بکار گرفته شده اند شامل
glColor3ub, glViewport, glMatrixMode, glLoadIdentity, gluPerspective, glClear, gluLookAt, glBegin, glEnd
می باشند


چون یک سری از مفاهیم در مثال ساده ی قبلی مرور شدند سرعت ما در به پایان بردن این مثال بیشتر خواهد بود :
طبق معمول در ابتدا یونیت OpenGL و سپس یونیت برپاسازی فرمت نقطه ای خودمان یعنی SPF را به برنامه اضافه می کنیم :


unit ex02;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs , OpenGL, SPF;



سپس متغیر عمومی معروف خودمان را برای دریافت HDC فرم و فرستادن آن به SPF اضافه می نماییم .


type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

var
f_Hdc : LongInt;


دو قسمت تکراری زیر یعنی برپا سازی فرمت نقطه ای هنگام ایجاد فرم و سپس خذف منابع اختصاص داده شده هنگان بسته شدن فرم را نیز به برنامه اضافه می نماییم :

روی فرم دوبار کلیک نمایید تا کار برپا سازی فرمت نقطه ای را در اینجا انجام دهیم . یعنی :



procedure TForm1.FormCreate(Sender: TObject);
begin
// Create a rendering context.
f_Hdc := GetDC(handle);
SetDCPixelFormat(f_Hdc,16,16);
InitGL;
end;



از برگه ی خواص رخدادهای مربوط به فرم را انتخاب نمایید و در قسمت OnDestory مربوط به فرم دوبار کلیک کنید تا روال رخداد آن آماده شود . از آن برای پاکسازی برنامه استفاده خواهیم کرد (یک تعهد اخلاقی ! ) . یعنی :



procedure TForm1.FormDestroy(Sender: TObject);
begin
CleanUp(f_Hdc);// Clean up and terminate.
end;


تا اینجا هیچی! ( همه چیز تکراری بودند و خواهند بود! )

در ادامه روال InitGL را برای ست کردن یک سری از پارامترهای فضای جدید ایجاد شده تعریف می کنیم :



procedure InitGL; // All Setup For OpenGL Goes Here
begin
// select clearing color
glClearColor( 0.0, 0.0, 0.0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
end;



حالا نوبت به تابع DrawGLScene برای ترسیم صحنه می رسد :



procedure DrawGLScene ();
// Here's Where We Do All The Drawing!!!
begin

// سبب پاک شدن صفحه و عمق بافر می شود
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
// ماتریس های مورد استفاده و در نتیجه صفحه را ریست می کند
glLoadIdentity();
// بدین وسیله محل قرار گیری دوربین را برای نمایش مثلث مشخص می کنیم
gluLookAt(0, 0, 6, 0, 0, 0, 0, 1, 0);

// The position has an X Y and Z. Right now, we are standing at (0, 0, 6)
// The view also has an X Y and Z. We are looking at the center of the axis (0, 0, 0)
// The up vector is 3D too, so it has an X Y and Z. We say that up is (0, 1, 0)
// Unless you are making a game like Descent(TM), the up vector can stay the same.

//در اینجا ما به اپن جی ال می گوییم کی می خواهیم ترسیم یک مثلث را شروع کنیم
glBegin (GL_TRIANGLES);
// در ادامه سه راس مثلث را برای ترسیم مشخص می نماییم
// در اینجا نسبت به مثال قبل به هر راس یک رنگ اختصاص داده شده است
glColor3ub(255, 0, 0);
glVertex3f(0, 1, 0);

glColor3ub(0, 255, 0);
glVertex3f(-1, 0, 0);

glColor3ub(0, 0, 255);
glVertex3f(1, 0, 0);
// و در اینجا خاتمه ترسیم را اعلام می نماییم
glEnd();
// You can have as many points inside the BEGIN and END, but it must be in three's.
// Try GL_LINES or GL_QUADS. Lines are done in 2's and Quads done in 4's.

SwapBuffers(f_Hdc); // Swap the backbuffers to the foreground
// استفاده از تابع فوق الزامی است. در غیر اینصورت چیزی روی صفحه ترسیم نخواهد شد
end;



همانطور که مشاهده کردید از تابع glColor3f برای ایجاد رنگ استفاده می شود و همانند توابع ایجاد رنگهای RGB عمل می کند با این تفاوت که آرگومانهای ورودی آن در بازه ی صفر و یک قرار دارند. برای مثال :


glColor3f(1.0, 0.0, 0.0); = RED




در پایان دو روال رخداد OnPaint و OnResize را اضافه می کنیم.

برای اطمینان حاصل شدن از ترسیم مجدد فرم برای مثال هنگامیکه یک فرم دیگر روی آن قرار گرفته است.


procedure TForm1.FormPaint(Sender: TObject);
begin
wglMakeCurrent(f_Hdc,hrc); //activate the RC
DrawGLScene;// Draw the scene.
end;




با توجه به اینکه فرم برنامه می تواند به هر اندازه ای از طرف کاربر تغییر کنید به رخداد OnResize هم نیاز داریم :



procedure TForm1.FormResize(Sender: TObject);
begin
if (height=0) then
// در اینجا از تقسیم شدن ارتفاع صفحه بر صفر که در توابع بعدی استفاده می شوند جلوگیری میشود
height:=1;

// در این حالت دریچه ی دید را کل صفحه انتخاب می نماییم
glViewport(0,0,width,height);
// The glViewport takes (x, y, width, height)
// This basically means, what our our drawing boundries

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
// The parameters are:
// (view angle, aspect ration of the width to the height,
// The closest distance to the camera before it clips,
// FOV // Ratio // The farthest distance before it stops drawing)
gluPerspective(45.0,width/height, 1 ,150.0);

// * Note * - The farthest distance should be at least 1 if you don't want some
// funny artifacts when dealing with lighting and distance polygons. This is a special
// thing that not many people know about. If it's less than 1 it creates little flashes
// on far away polygons when lighting is enabled.

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix

end;



هدف از اینگونه مثالهای ساده آشنایی با روال منطقی اینگونه برنامه نویسی است .