ثابت ها یی که در نور پردازی حتما باید فعال باشند.
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0) ; برای تمام منبع ها
glEnable( GL_COLOR_MATERIAL );
GL_COLOR_MATERIAL
glEnable( GL_COLOR_MATERIAL );
تابع glLightfv (نور پرادازی در Opengl )
پارامتر اول : در اپن جی ال تعداد منابع نور محدود است پارامتر اول مشخص میکند که کدام منبع نور را در نظر
دارین برای مثال : GL_LIGHT0 .
پارامتر دوم : میتواند ثابت موقعیت منبع نور GL_POSITION و یا ثابت نوع نور مثل GL_DIFFUSE یا هر کدام
از انواع دیگر نور را داشته باشد .
پارامتر سوم : پارامتر سوم بسته به اینکه پارامتر دوم چه بوده تعریف میشود مثلا اگر پارامتر دوم موقعیت بوده
مختصات است واگر نور بوده رنگ نور منبع است RGBA ، که A شدت نور است .
GLfloat specular[] = { 0.7, 0.7, 0.3, 1 };
GLfloat lightpos[] = {1.5, 1.,- 1., 0.};
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
نور پردازی در opengl
آشنایی با انواع نور تعریف شده در opengl:
1-نور محیطی (Ambient): نوری که در محیط وجود دارد به طوری که جهت آن قابل تشخیص نیست.

2- نور انتشاری(Diffuse): فرض کنید منبع در بی نهایت قرار گرفته هنگامی که شی از نور این منبع روشن
میشود نور انتشاری از خود باز تابش میکند.

3-نور آینه ای(Specular):از جهت خاصی تابیده شده است وتمایل دارد به جهت منبع تابیده شود که این ویژگی
بیشتر برای فلزات است.

نور پردازی در opengl
نکته قابل توجه این است که نور پردازی برای محیط سه بعدی تعریف شده است .
اما مشکل این جاست که اپن جی ال به طور پیش فرض عمق شکل در نور پردازی را متوجه نمیشود.
برای همین برای یک نور پردازی صحیح باید در مقدار دهی اولیه بافر عمق هم باید تعریف شود.
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH );
هم چنین باید انجایی که دارین منابع نوریتان راتعریف میکنین این ویژگی را فعال کنید.
glEnable(GL_DEPTH_TEST);
در تابع Display هم باید بافر عمق را پاک کرد.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
تابع () glutPostRedisplay
از این تابع زمانی استفاده میشود که شما بخواهید داخل تابع دیگری تابع display تان را دوباره فراخوانی کنید.
اگر به کد چرخش کره نگاه کنید اونجا استفاده شده.
کاربرد بافر دوگانه در opengl
اما در متحرک سازی یا همون به اصطلاح پویا نمایی این طور نیست .
تنها زمانی شما بهترین کارایی را دارین که بافر شما دو گانه باشد. این طوری از پر پر زدن شکل جلو گیری میکنیم
با تعویض بافر ها اشیا ترسیم شده به نمایش در می آید.
یادتان به گوشه کتابهای درسیتون نیفتاد ؟؟! با ورق زدن سریع کتاب شکلتون متحرک میشد!
یک تکنیک
sample code___ چرخش کره
#include GLfloat angle=0.0; void idle(void) { if(angle<360) angle+=0.1; else angle=0.0; glutPostRedisplay(); } void winInit(void) { glClearColor(1.0,1.0,1.0,0.0); } void display(){ glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); glColor3f(1.1,0.0,1.0); glRotated(angle,1.0,1.0,0.0); glutWireSphere(0.9,50,50); glEnd(); glPopMatrix(); glutSwapBuffers(); } int main(int argc, char** argv){ glutInit(& argc,argv); glutInitDisplayMode(GLUT_DOUBLE |GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("simple"); winInit(); glutDisplayFunc(display); glutIdleFunc(idle); glutMainLoop(); return 0; }
تابع glTranslatef یا glTranslated
تابع glScalef یا glScaled
این تابع هم بزرگنمایی یا انقباض را دارد .نسبت به هر کدام از محورها این نقباض یا کشیدگی را میتوان
انجام داد.
این تابع سه پارامتر دارد.
پارامتر اول کشیدگی(انقباض) حول محور x،
پارامتر دوم کشیدگی(انقباض) حول محور y ،
پارامتر سوم کشیدگی(انقباض) حول محور Z است.
اگر پارامتر ها بزرگتر از یک باشد بزرگنمایی داریم و اگر پارامترها کمتر از یک باشند انقباض را داریم . اگر هم
از 1- استفاده کنید قرینه شکل حول محور مربوطه را داریم .
تابع glRotatef
glRotatef(angle,x،y,z);
مقصود از x,y,z محورهای مختصات است .
کار این تابع دوران است . دوران حول یکی از محورهای مختصات .
کدام محور؟
هر کدام از محور ها را خواستید مقدار ان را یک کنید و بقیه را صفر کنید.
مثال:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(66,0,0,1);
glColor3f(2,2,0);
glutSolidTeapot(0.5);
glFlush();
}
تابع glMatrixMode
تابع glMatrixMode یکی از ثابتهای زیر را به عنوان پارامتر دارد:
GL_MODELVIEW:
.برای انتقال وتغییر مکان ودوران و...استفاده میشود وحالت پیش فرض است
GL_PROJEXTION:
.برای حالت دو بعدی استفاده میشود
GL_TEXTURE:
به جای این که شکل را رنگ کند از بافت تکسچر استفاده میکند.
تابع glFlush
مشاهده نخواهید کرد.
چون اطلاعات داخل بافر است و هنوز روی صفحه نمایش اعمال نشده است ! بافر یک حافظه میانی است
اگر شما از یک بافر استفاده میکنید با نوشتن glFlush دستور انتقال اطلاعات از حافظه میانی(بافر) به صفحه
نمایش را میدهید.
چگونه تعداد بافر را مشخص کنیم؟
حتما تابع زیر را در main دیدین
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB)
GLUT_SINGLE معرف تک بافره و GLUT_DOUBLE معرف دو بافر هستش
پس وقتی دستوری برای اعمال روی صفحه داشتین مثل دستورا ت ترسیم شکل برای اعمال شدن نتیجه
اگر یک بافر داشتین از دستور ;()glFlush واگر دو بافر داشتین از دستور ;()glutSwapBuffers استفاده
میکنیم.
تابع glutIdleFunc
برای مثال میخواهید در موقع بیکاری سیستم مکعب بچرخد. یا یک شکل حرکت کند از این تابع کمک میگرند.
منظور از بیکاری:
یعنی زمانی که شما هیچ تعاملی با کاربر نداشته اید .
در جواب دوست عزیزی که نظر گذاشته باید بگم که این تابع در زمانی که با کاربر تعامل دارید کار نمیکند و در
در حالتی که سیستم هیچ تعاملی ندارد و بیکار است فعالیت خودش رو از سر میگیرد .
مثال : فرض کنید کره در صفحه می چرخد و کاربر هم میخواد راست کلیک کند تا با انتخاب یکی از گزینه ها
منو شکلی را رسم کند تا زمانی که راست کلیک را در صفحه میبیند و تعامل ادامه دارد Idle کار نمیکند.
بعد از انتخاب و بسته شدن راست کلیک دوباره زمان بیکاری سیستم شروع میشود.
حالا فرض کنید به جای اینکه از منو استفاده کنید از یکی از کلید های کیبورد استفاده کرده اید . خب
چون زمان تعامل خیلی کوتاه است در واقع سیستم بیکار به نظر میرسد.
توابع opengl از نوع callback هستند به چه معناست؟
تابع glutKeyboardFunc
;(اسم تابع)glutKeyboardFunc
فرضا: ( glutKeyboardFunc( mykeyboard
تابع فراخوانی شده توسط این تابع سه پارامتر دارد:
void mykeyboard( unsigned char key, int x, int y)
پارامتر اول حاوی کد اسکی کاراکتر فشار داده شده ی روی keyboard است.
(این تابع برای کاراکترهایی استفاده میشه که یک قسمتی هستند.
برای بعضی کلید های خاص keyboard مثل F ها و کلید های پیمایش باید از تابع
glutSpecialFunc استفاده بشه)
پارامتر دوم و سوم موقعیت موس را نگه میدارند.
ادامه مطلب به زودی
تابع glutMotionFunc
glutMotionFunc برای زمانی است که یکی از دکمه های موس فشرده شود و
هم زمان موس حرکت کند . در واقع با فرا خوانی این تابع به محض حرکت
موس با فشردن دکمه موس دستورات تابع اجرا میشود.
پس در ()main بنویسید :
(اسم تابع ) glutMotionFunc
فرض کنید که اسم تابع mouse است.
این تابع دو پارامتر دارد :
void mouse ( int x , int y )
تابع glutMouseFunc
glutMouseFunc ( نام تابع );
برای مثال نام تابع را mouse میگذاریم پس در ()main مینویسیم :
glutMouseFunc (mouse );
تابعی که اکنون تحت نام mouse نوشته میشود 4 پارامتر دارد :
void mouse( int button , int state , int x , int y )
پارامتر اول مشخص می کند که کدام دکمه ماوس فشرده شده یا رها می شود.که خود این پارامتر 3 حالت دارد:
برای چک کردن این که کدام کلید زده شده از یک if استفاده می کنیم که مقادیر bottun , state را چک می کند.
نمونه کد:
void mouse(int button, int state, int x, int y) { switch (button){ case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) exit(0); }}تابع glViewport(پنجــــــــره دید)
برای مثال قبلا برنامه یک مثلث را نوشته اید . این برنامه خودش برای یک پنجره
نمایش با مختصات و ویژگی های خودش بوده اما ما در برنامه جدیدمان میخواهیم
از برنامه قبلیمان استفاده کنیم اما از سایز ومکان شکل در پنجره راضی نیستیم
در واقع دیدمان به پنجره عوض شده است. به عکس پرچم پاناما نگاه کنید . ابتدا
تمام سایز پنجره را گرفته اما بعد هم کوچکش کردم وهم مکانش را تغییر دادم.
برای مثال:
void mydisplay(){
glClear(GL_COLOR_BUFFER_BIT);
//glViewport(0,0,200,400);
glBegin(GL_POLYGON);
glVertex2f(-0.9,0.4);
glVertex2f(-0.5,0.8);
glVertex2f(-0.125,0.4);
glEnd();
glFlush();
}
اما الان می خواهید دید پنجره نمایش نسبت به این شکل تغییرکند مثلا مثلث به
جای اینکه مثل این برنامه در ربع دوم با این سایز کشیده شود در مکان دیگری از
صفحه نمایش با سایز دیگری کشیده شود.
نکته مهم 1 : برای گرفتن نتیجه تابع glviewport را قبل از glBegin بنویسید.
برای اینکارها از تابع glViewport استفاده میشود. شکل کلی تابع glViewport به
صورت زیر است:
(طول شئ , عرض شئ , مختصات Y , مختصات glViewPort( X
نکته مهم 2 :این تابع بر حسب پیکسل است یعنی مختصات دهی بر حسب
پیکسل میباشد.
این هم عکس برای فهم بیشتر ودرک کاربرد:

نکته مهم 3:مختصات (0،0 ) پنجره در اپن جی ال گوشه سمت چپ پایین
صفحه است. در حالی که خود پنجره نمایشی مختصات دیگری برای
صفر وصفرش دارد وآن گوشه سمت چپ بالای صفحه است.

منو و زیر منو در opengl +مثال
طریقه ایجاد منو از طریق تابع:
int id=glutCreateMenu(mymenu);
تعریف ورودی های منو (منظور همون گزینه های منو است)
glutAddMenuEntry("نام گزینه",id);
تعریف زیر منو از طریق :
glutAddSubMenu("نام زیر منو",id);
در اخر هم منو رو با یکی از کلیدهای موس متصل میکنیم:
glutAttachMenu(GLUT_RIGHT_BUTTON);
توضیح پارامترها برام سخت بود که بنویسمشون یه مثال گذاشتم:
#include
int s=-1;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
if(s==0)
{
glClearColor(1.0,0.0,1.0,1.0); //pink
glClear(GL_COLOR_BUFFER_BIT);
}
if(s==1)
{
glClearColor(0.0,0.0,1.0,1.0); //blue
glClear(GL_COLOR_BUFFER_BIT);
}
if(s==2)
{
glClearColor(1,0,0,1); //red
glClear(GL_COLOR_BUFFER_BIT);
}
glFlush();
}
void mymenu(int id)
{
if(id==1)
{
s=0;
glutPostRedisplay();
}
if(id==2)
exit(0);
if(id==3)
{
s=1;
glutPostRedisplay();
}
if(id==4)
{
s=2;
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Menu");
glutDisplayFunc(display);
////////////////////////////
int menu_ids=glutCreateMenu(mymenu);
glutAddMenuEntry("pink", 1);
glutAddMenuEntry("red",4);
glutAddMenuEntry("blue", 3);
int id_id=glutCreateMenu(mymenu);
glutAddSubMenu("COLORS",menu_ids);
glutAddMenuEntry("exit",2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
////////////////////////////////////////////
glutMainLoop();
return 0;
}
کتابخانه OpenGl برای ++C
قوانین نوشتاری در opengl
opengl از کتابخونه های زیادی تشکیل شده که دو کتابخونه ی مهمش GLU و
GLUT هستند.
از مشخصه های توابعی که در این دو کتابخونه وجود دارد دارد این است که باGLU یا GLUT شروع میشنوند.درواقع پیشوند تابع معرف کتابخانه آن نیز هست.
2- ثابتها هم کلا با حروف بزرگ نوشته میشوند وپیشوند _GL را دارند.