جمعبندی، منابع پیشنهادی و تمرینهای فصل دوم
جمعبندی و یادداشتها
در این فصل بهاندازهای از API مربوط به OpenGL را معرفی کردیم که بتوانیم مفاهیم پایهٔ فصل ۱ را به کار ببریم. هرچند نخستین برنامهای که برای توسعهٔ مثال اولیه استفاده کردیم دوبعدی بود، از ابتدا گرافیک دوبعدی را حالت خاصی از گرافیک سهبعدی در نظر گرفتیم؛ به همین دلیل توانستیم با تغییرات اندک همان مثال را به سه بعد گسترش دهیم.
واشر سیرپینسکی نقطهٔ شروع ساده اما غیرسطحیای برای برنامهنویسی گرافیک فراهم کرد. چند تعمیم و مسئلهٔ ریاضی مرتبط در تمرینهای پایان فصل آمدهاند. منابع بخش «مطالعات پیشنهادی» نمونههای فراوانی از منحنیها و سطوح جالب ارائه میکنند که با برنامههای ساده قابل تولیدند.
سیر تاریخی APIهای گرافیکی و مدلهای گرافیکی اهمیت آغاز از فضای سهبعدی را نشان میدهد. مدل Pen Plotter فصل ۱ سالها استفاده شد و پایهٔ APIهای مهمی مانند PostScript است. تلاش برای تعریف استاندارد بینالمللی APIهای گرافیکی از دههٔ ۱۹۷۰ آغاز شد و در سال ۱۹۸۴ با پذیرش GKS از سوی سازمان بینالمللی استانداردسازی (ISO) به نتیجه رسید. اما GKS بر مدل Pen Plotter استوار و APIای دوبعدی بود، بنابراین در جامعهٔ CAD کاربرد محدودی داشت. هرچند بعداً به GKS-3D گسترش یافت، محدودیتهای مدل زیربنایی اولیه باعث شد استاندارد سهبعدی حاصل در جنبههای مختلف کاستی داشته باشد. APIهای PHIGS و PHIGS+ که در جامعهٔ CAD شکل گرفتند ذاتاً سهبعدیاند و بر مدل دوربین مصنوعی تکیه دارند.
OpenGL از API مربوط به IrisGL مشتق شده است؛ APIای که مدل دوربین مصنوعی را با معماری خط لوله پیاده میکرد. IrisGL برای Workstationهای Silicon Graphics, Inc. (SGI) توسعه یافت؛ سامانههایی که معماری خط لولهٔ آنها در آغاز با تراشههای VLSI ویژه پیادهسازی میشد. ازاینرو، هرچند PHIGS و GL اشتراکهای فراوانی دارند، GL مشخصاً برای رندر بلادرنگ و پرسرعت طراحی شده بود. OpenGL زمانی شکل گرفت که کاربران برنامهها مزیتهای برنامهنویسی GL را دیدند و خواستند این مزایا را به سکوهای دیگر منتقل کنند. با حذف ورودی و عملیات پنجرهای از GL و تمرکز بر رندر، OpenGL به API قابلحملی تبدیل شد که در عین حال ویژگیهای قدرتمند GL را حفظ میکرد.
اگرچه بیشتر برنامهنویسان OpenGL برنامهنویسی با C را ترجیح میدهند، علاقهٔ قابلتوجهی به رابطهای سطح بالاتر نیز وجود دارد. جایگزینی C با C++ تغییر کد اندکی میخواهد، اما بهتنهایی رابط واقعاً شیءگرا برای OpenGL ایجاد نمیکند. در میان برنامهنویسان شیءگرا هم OpenGL و هم APIهای سطح بالاتر مورد توجه بودهاند. پیوندهای مختلفی برای Java و OpenGL ساخته شده است. مسئله ساده نیست، زیرا کاربران میخواهند شیءگرایی Java و Toolkitهای آن را با مشخصات غیرشیءگرای OpenGL ترکیب کنند. چند Binding در دسترس بوده و Sun Microsystems نیز Bindingهای Java خود را منتشر کرده است؛ بسیاری از برنامهنویسان Java از JOGL استفاده میکنند.
در فصل ۸ «گراف صحنه» (Scene Graph) معرفی میشود که رابطی شیءگرا و بسیار سطح بالاتر برای سختافزار گرافیکی فراهم میکند. بیشتر APIهای Scene Graph روی OpenGL ساخته شدهاند.
در جامعهٔ بازی، غالببودن Windows امکان توسعهٔ کد برای یک سکوی واحد را فراهم کرده است. DirectX فقط روی سکوهای Windows اجرا میشود و برای سرعت در همین سامانهها بهینه شده است. هرچند بخش زیادی از کد DirectX ظاهری شبیه OpenGL دارد، برنامهنویس میتواند از قابلیتهای وابسته به دستگاه موجود در کارتهای گرافیکی متداول استفاده کند. در نتیجه برنامههای DirectX قابلیت حمل و ثبات برنامههای OpenGL را ندارند. به همین دلیل DirectX در دنیای بازی غالب شده، در حالی که برنامههای علمی و مهندسی عموماً با OpenGL نوشته میشوند. OpenGL برای برنامهنویسانی که خواهان امکانات ویژهٔ سختافزار معین هستند سازوکار Extension دارد، هرچند با هزینهٔ کاهش قابلیت حمل. خط لولههای برنامهپذیر قابل دسترس از طریق OpenGL Shading Language و Cg سبب شدهاند اختلاف کارایی OpenGL و DirectX در برنامههای سطح بالا کوچک باشد.
مثالها و برنامههای ما نشان دادند چگونه اشیای هندسی را به روشی ساده توصیف و نمایش دهیم. در چارچوب الگوی Modeling–Rendering فصل ۱ تمرکز ما عمدتاً بر Modeling بوده است؛ بااینحال مدلهای فعلی کاملاً بدون ساختارند و نمایش اشیا چیزی جز فهرست رأسها و ویژگیها نیست. در فصل ۸ ساخت مدلهای سلسلهمراتبی را یاد میگیریم که روابط میان اشیا را نیز نمایش میدهند. با وجود این، در همین مرحله نیز میتوان برنامههای جالبی نوشت. تمرینهای پایان فصل را انجام دهید و چند مسئلهٔ دوبعدی را به سه بعد تعمیم دهید.
مطالعات پیشنهادی
واشر سیرپینسکی مقدمهٔ مناسبی برای هندسهٔ فراکتال است و منابع [Bar93, Hil01, Man82, Pru90] بحثهای خوبی در این زمینه دارند.
API مدل Pen Plotter در PostScript [Ado85] و LOGO [Pap81] استفاده میشود. LOGO «گرافیک لاکپشتی» (Turtle Graphics) را ارائه میکند؛ APIای که هم یادگیری آن ساده است و هم میتواند چند منحنی ریاضی دوبعدی مورد استفاده در فصل ۱۱ را توصیف کند؛ تمرین ۲.۴ را نیز ببینید.
GKS [ANSI85]، GKS-3D [ISO88]، PHIGS [ANSI88] و PHIGS+ [PHI89] استانداردهای ملی ایالات متحده و بینالمللی هستند. توصیف رسمی آنها از ANSI و ISO قابل دریافت است. کتابهای متعددی از این APIها استفاده میکنند [Ang90, End84, Fol94, Hea04, Hop83, Hop91].
X Window System [Sch88] به استاندارد Workstationهای UNIX تبدیل شد و بر توسعهٔ سامانههای پنجرهای دیگر سکوها اثر گذاشت. رابط RenderMan در [Ups89] توصیف شده است.
مرجع استاندارد OpenGL، OpenGL Programming Guide [Shr10] است. OpenGL Reference Manual [Ope04] صفحات راهنمای نسخههای قدیمیتر را دارد. مشخصات رسمی OpenGL نیز در [Seg92] آمده است. OpenGL Shading Language در [Ros09] شرح داده شده است.
اسناد استاندارد، منابع تکمیلی و ارجاع به نمونهکدها در وبسایت OpenGL معرفی شدهاند.
از ویرایش دوم تا این ویرایش، Programming Guide از کتابخانهٔ GLUT توسعهیافته توسط Mark Kilgard [Kil94b] استفاده کرده است. این راهنما نمونهکدهای OpenGL بسیار بیشتری دارد. GLUT برای X Window System [Kil96] توسعه داده شد، اما نسخههایی برای Windows و Macintosh نیز دارد. بخش زیادی از این اطلاعات و برنامههای نمونه روی اینترنت در دسترس بودهاند و سایتهای نمونه در ابتدای ضمیمهٔ A ذکر شدهاند.
کتاب همراه این متن، OpenGL: A Primer [Ang08]، جزئیات توابع OpenGL استفادهشده در اینجا و نمونهبرنامههای بیشتری را ارائه میکند. کاربران Windows نمونههای بیشتری را در [Wri11] و [Fos97] و کاربران Mac OS X جزئیات مرتبط را در [Kue08] مییابند.
بخش گرافیکی API مربوط به DirectX در آغاز Direct3D نام داشت. نسخهٔ مورد اشاره در متن، 11.0 است.
تمرینها
۲.۱ تغییر کوچکی در تولید واشر سیرپینسکی با چندضلعیهای مثلثی، «کوههای فراکتالی» مورد استفاده در انیمیشنهای رایانهای را ایجاد میکند. پس از یافتن نقطهٔ میانی هر ضلع مثلث، پیش از تقسیم محل آن را اندکی Perturb کنید. مثلثها را بدون Fill تولید کنید. بعداً همین تمرین را در سه بعد انجام دهید و Shading اضافه کنید. پس از چند تقسیم باید جزئیات بهاندازهای باشند که مثلثها شبیه کوه به نظر برسند.
۲.۲ واشر سیرپینسکی تمرین ۲.۱ بسیاری از پیچیدگیهای هندسی مورد مطالعه در هندسهٔ فراکتال [Man82] را نشان میدهد. فرض کنید واشر را با خطوط ریاضی دارای طول و بدون عرض بسازید. در حد نهایی، پس از حذف مثلث مرکزی در هر تقسیم، چه درصدی از مساحت مثلث اصلی باقی میماند؟ محیط مثلثهای باقیمانده پس از هر حذف را بررسی کنید؛ در حد نهایی برای مجموع طول محیط همهٔ مثلثهای باقیمانده چه اتفاقی میافتد؟
۲.۳ در پایینترین سطح پردازش، بیتهای Framebuffer را دستکاری میکنیم. OpenGL دستورهای Pixel-Oriented دارد که دسترسی مستقیم به Framebuffer را ممکن میکنند. میتوانید با تابعی که یک نقطه تولید میکند الگوریتمهای Raster ساده مانند رسم خط یا دایره را آزمایش کنید. کتابخانهٔ کوچکی بنویسید که اجازه دهد در یک Framebuffer مجازی ساختهشده در حافظه کار کنید. توابع اصلی باید WritePixel و ReadPixel باشند. کتابخانه باید راهاندازی و نمایش Framebuffer مجازی و اجرای برنامهٔ کاربری برای خواندن و نوشتن پیکسلها را ممکن کند.
۲.۴ Turtle Graphics سامانهٔ موقعیتدهی دیگری بر پایهٔ لاکپشتی است که با قلمی در زیر پوسته در صفحه حرکت میکند. موقعیت لاکپشت با سهتایی (x,y,θ) برای مکان مرکز و جهتگیری آن توصیف میشود.
شکل ۲.۴۸ — تولید دانهبرف کخ.
API معمول Turtle Graphics توابعی شبیه موارد زیر دارد:
init(x,y,theta); /* initialize position and orientation
of turtle */
forward(distance);
right(angle);
left(angle);
pen(up_down);
یک کتابخانهٔ Turtle Graphics با OpenGL پیادهسازی کنید.
۲.۵ با کتابخانهٔ تمرین ۲.۴ واشر سیرپینسکی و کوههای فراکتالی تمرینهای ۲.۱ و ۲.۲ را تولید کنید.
۲.۶ منحنیهای پُرکنندهٔ فضا قرنها مورد توجه ریاضیدانان بودهاند. در حد نهایی طول آنها بینهایت است، اما درون مستطیلی محدود باقی میمانند و هرگز خودشان را قطع نمیکنند. بسیاری بهصورت تکراری تولید میشوند. قاعدهٔ شکل ۲.۴۸ یک پارهخط را با چهار پارهخط کوتاهتر جایگزین میکند. برنامهای بنویسید که با یک مثلث آغاز و این قاعده را بهطور تکراری بر تمام پارهخطها اعمال کند. شیء حاصل «دانهبرف کخ» (Koch Snowflake) نام دارد. نمونههای دیگر را در [Hil07] و [Bar93] ببینید.
۲.۷ میتوان یک Maze ساده را از آرایهای مستطیلی از Cellها ساخت. هر Cell چهار ضلع دارد. ضلعها، بهجز محیط بیرونی، حذف میشوند تا همهٔ Cellها به هم متصل شوند. سپس با حذف دو ضلع از محیط، ورودی و خروجی ساخته میشود. نمونهای در شکل ۲.۴۹ آمده است. برنامهای با OpenGL بنویسید که دو عدد صحیح N و M را بگیرد و Maze به اندازهٔ N × M رسم کند.
شکل ۲.۴۹ — Maze.
۲.۸ توضیح دهید چگونه مدل رنگ RGB در OpenGL را برای کار با مدل رنگ کاهشی سازگار میکنید.
۲.۹ دیدیم که یک عملیات بنیادی در سامانههای گرافیکی نگاشت نقطهٔ (x,y) داخل مستطیل Clipping به نقطهٔ (xs,ys) در Viewport پنجره است. فرض کنید Viewport با
و مستطیل مشاهده با کرانهای زیر تعریف شده باشد:
xmin ≤ x ≤ xmax و ymin ≤ y ≤ ymax.
معادلات ریاضی نگاشت (x,y) به (xs,ys) را بیابید.
شکل ۲.۵۰ — Mesh چندضلعی.
۲.۱۰ بسیاری از APIهای گرافیکی از موقعیتدهی نسبی استفاده میکنند. در چنین سامانهای توابعی مانند
move_rel(x,y);
line_rel(x,y);
برای رسم خطوط و چندضلعیها وجود دارد. move_rel یک موقعیت داخلی یا Cursor را به مکان جدید میبرد و line_rel هم Cursor را جابهجا میکند و هم میان موقعیت قدیم و جدید پارهخط میسازد. مزایا و معایب موقعیتدهی نسبی در مقایسه با موقعیتدهی مطلق OpenGL چیست؟ توضیح دهید چگونه موقعیتدهی نسبی را به OpenGL اضافه میکنید.
۲.۱۱ در عمل آزمودن تکتک نقاط یک چندضلعی برای تشخیص داخل یا خارج بودن بسیار ناکارآمد است. راهبردهای عمومی برای پرهیز از آزمون نقطهبهنقطه را توضیح دهید.
۲.۱۲ آزمونی برای تشخیص سادهبودن (Simple) یک چندضلعی دوبعدی طراحی کنید.
۲.۱۳ شکل ۲.۵۰ مجموعهای از چندضلعیها به نام Mesh را نشان میدهد که برخی یالها و رأسها را مشترک دارند. یک یا چند ساختار دادهٔ ساده برای نمایش Mesh طراحی کنید. ساختار خوب باید اطلاعات رأسها و یالهای مشترک را در بر گیرد. با OpenGL روش کارآمدی برای نمایش Mesh ذخیرهشده در ساختار خود ارائه کنید. راهنما: از آرایه یا Linked List شامل موقعیت رأسها آغاز کنید.
۲.۱۴ در بخش ۲.۴ دیدیم که OpenGL چندضلعیها را با فهرست رأسها مشخص میکند. چرا ممکن است تعریف چندضلعی بر اساس یالها بهتر باشد؟ راهنما: نمایش کارآمد Mesh را در نظر بگیرید.
۲.۱۵ در OpenGL میتوان به هر رأس رنگی نسبت داد. اگر دو انتهای یک پارهخط رنگهای متفاوتی داشته باشند، OpenGL هنگام رندر میان رنگها درونیابی میکند؛ همین کار برای چندضلعیها نیز انجام میشود.
از این ویژگی برای نمایش «مثلث ماکسول» استفاده کنید: مثلث متساویالاضلاعی با رأسهای قرمز، سبز و آبی. رابطهٔ مثلث ماکسول با مکعب رنگ چیست؟
۲.۱۶ بسیاری از جلوههای واقعگرایانه را میتوان با واردکردن فیزیک ساده به مدل شبیهسازی کرد. حرکت توپ جهنده را در دو بعد، با گرانش و برخورد کشسان با سطح، شبیهسازی کنید. توپ را میتوان با چندضلعی بستهای با تعداد ضلع کافی برای ظاهری نرم مدل کرد.
۲.۱۷ تعمیم جالب ولی دشوار تمرین ۲.۱۶ شبیهسازی بازی Pool یا Billiards است. چند توپ باید با دیوارههای میز و با یکدیگر تعامل کنند. راهنما: با دو توپ شروع و روش تشخیص برخورد احتمالی را بررسی کنید.
۲.۱۸ سامانهٔ گرافیکی دارای CRT تبلیغ میکند که میتواند هر چهار رنگ از میان ۶۴ رنگ را نمایش دهد. این گفته دربارهٔ Framebuffer و کیفیت نمایشگر چه اطلاعاتی میدهد؟
۲.۱۹ آزمونی برای تشخیص محدببودن چندضلعی دوبعدی طراحی کنید.
۲.۲۰ رویکرد دیگری برای واشر سهبعدی آن است که فقط وجههای چهاروجهی اولیه تقسیم شوند. برنامهای با این روش بنویسید. نتیجه چه تفاوتی با برنامهٔ بخش ۲.۱۰ دارد؟
۲.۲۱ هر بار که چهاروجهی را تقسیم میکنیم و فقط چهار چهاروجهی کوچک متناظر با رأسهای اولیه را نگه میداریم، حجم با ضریب f کاهش مییابد. f را بیابید. نسبت مساحت سطح جدید چهار چهاروجهی به مساحت سطح چهاروجهی اولیه چیست؟
۲.۲۲ ساخت بازیهای ساده راه خوبی برای آشنایی با برنامهنویسی گرافیک تعاملی است. بازی Checkers را برنامهنویسی کنید. هر خانهٔ صفحه را میتوان شیئی در نظر گرفت که کاربر انتخاب میکند. میتوانید با برنامهای آغاز کنید که یک کاربر هر دو طرف بازی را کنترل میکند.
۲.۲۳ برنامهای تعاملی بنویسید که اجازه دهد یک موش گرافیکی را در Maze ساختهشده در تمرین ۲.۷ هدایت کنید. از دکمههای چپ و راست برای چرخاندن موش و دکمهٔ میانی برای حرکت رو به جلو استفاده کنید.
۲.۲۴ بستههای رسم نمودار روشهای مختلفی برای نمایش داده دارند. برنامهٔ رسم تعاملی برای منحنیهای دوبعدی بنویسید که کاربر بتواند حالت نمایش ــ Polyline، Bar Chart یا Pie Chart ــ و نیز رنگ و سبک خط را انتخاب کند.
۲.۲۵ نرخ نوسازی لازم برای نمایشگرهای CRT، حدود ۵۰ تا ۸۵ هرتز، بر استفاده از فسفرهای با ماندگاری کوتاه تکیه دارد که پس از تحریک فقط مدت بسیار کوتاهی نور میدهند. فسفرهای با ماندگاری بلند نیز وجود دارند. چرا در بیشتر نمایشگرهای Workstation استفاده نمیشوند؟ در چه نوع کاربردهایی میتوانند مفید باشند؟
این صفحه عمداً خالی گذاشته شده است.