بهینه سازی در بازی ها چه معنایی دارد؟

شنبه ۱۰ مهر ۱۳۹۵ - ۲۳:۰۲
مطالعه 12 دقیقه
Crysis
زومجی در این مطلب مفهوم بهینه‌سازی در بازی‌ها را بررسی خواهد کرد.
تبلیغات

اگر به انجمن تبادل نظر پیرامون یک بازی جدید پی‌سی یا کنسول سر بزنید خواهید دید که یک کلمه زیاد تکرار می‌شود و آن هم "بهینه سازی" است. مثلا بازیکنی در مورد Deus Ex: Mankind Divided در استیم می‌نویسد که " به نظر من این بازی اصلا بهینه نشده است"، یا مثلا در مورد بازی FIFA 17 شکایات زیادی از کاربران نسخه‌ی پی‌سی در مورد مصرف بالای پردازنده وجود دارد و باز هم از بهینه نبودن پورت نسخه‌ی مخصوص رایانه‌های شخصی سخن به میان می‌آید.

اما چگونه می‌توان مطمئن شد که راندمان پایین بازی ناشی از بهینه نبودنِ برنامه نویسی آن است یا این که روی سخت افزار شما به نهایت سقف کارایی خود رسیده و بیشتر از آن قادر به گرفتن راندمان بالاتر نخواهید بود؟

در این مقاله می‌کوشیم بهینه سازی (Optimization) را تشریح کنیم و یک دید کلی از برخی امکانات تکنیکی مانند نورپردازی و anti-aliasing ارائه کنیم، امکاناتی که ذاتا محاسبات سنگینی نیاز دارند. همچنین خواهیم گفت که توسعه دهندگان بازی‌ها چگونه تنظیمات گرافیکی پیش فرض و ملزومات بازی را تعیین می‌کنند.

کپی لینک

بهینه سازی چیست و آیا می‌توان آن را اندازه گیری کرد؟

بهینه سازی در مبحثِ گیمینگ معنی یکسانی با بهینه سازی در علم کامپیوتر ندارد و بیش از آنکه به بهینه سازیِ یک پروسه یا الگوریتم ثابت اشاره داشته باشد، در کل به معنی بهتر کردن اجرای بازی است. تفاوت این دو در این است که در علم کامپیوتر، فقط وقتی می‌گویند بهینه سازی صورت گرفته که نتیجه‌ی خروجی یک محاسبه‌ی خاص دقیقا برابر با حالت غیر بهینه شده‌ی آن محاسبه باشد.

مثلا به جای عبارت زیر:

a = b*c + b*c + b*c

می‌توان این عبارات را حساب کرد:

d = b*c

a = d + d + d

و این یک بهینه سازی است، چرا که تنها یک عملِ ضرب به جای سه عمل ضرب در محاسبه‌ی اولی نیاز دارد. به عبارت دقیق‌تر، ایده‌ی مقایسه‌ی سطح بهینه سازی در بینِ بازی‌های متفاوت و با سبک‌های مختلف بر خلاف محاسبات این‌چنینی امری دشوار و غیر عملی خواهد بود. پس چگونه باید از بهینه سازی در بازی صحبت کرد تا معنی ملموس و واقعی هم در بر داشته باشد؟

یکی از اعضای استودیوی Croteam (سازنده‌ی باز‌ی‌هایی مانندِ Serious Sam)می‌گوید:

بهینه سازی خوب به معنی آن است که بازی بتواند روی طیف وسیعی از سخت افزارهای مختلف که حتی شامل سخت افزارهای رده پایین هم می‌شود با نرخ فریم یکسانی اجرا شود.

حفظ میزان فریم پایدار در بازی همان جایی است که سازندگان اهمیت تنظیمات گرافیکی را می‌بینند، چرا که از طریق آن می‌توانند شکاف تکنیکی گسترده بین سخت افزارهای ضعیف و محصولات رده حرفه‌ای و قدرتمند را پوشش دهند.

Dean Sekulic از استودیوی Croteam که بیش از ۲۰ سال است که بهینه سازی بازی‌ها را انجام می‌دهد معتقد است که نمی‌توان به راحتی بازی‌های متفاوتی را مقایسه کرد و گفت که بهینه سازی خوبی داشته‌اند یا خیر، اما شاید بتوان با مقایسه‌ی کیفیت خروجی تولید شده توسط دو بازی متفاوت و راندمانی که بدست آورده‌اند در مورد بهینه بودن یا نبودن آنها قضاوتی نسبی داشت. فقط باید این را هم در نظر گرفت که عوامل زیادی وجود دارند که چگونگی اجرای یک بازی را تحت تاثیر قرار می‌دهند.

کپی لینک

افکت‌های سطح بالا و تاثیر آنها در راندمان

اگر آن راندمانی را که از بازی انتظار داشته‌اید بدست نیاورده‌اید، احتمال زیادی دارد که یکی از این تنظیمات مقصر باشد. اینها بزرگترین موانع در سر راه اجرای روان بازی هستند و باید در صدرِ‌ گزینه‌هایی باشند که برای رسیدن به هدف ۶۰ فریم بر ثانیه تنظیم می‌کنید.

کیفیت نمایش تصویر یا Image Quality

ممکن است لحاظ کردن تک گزینه‌‌ای با بیشترین تاثیر در راندمان در مقایسات بهینه سازی کار دشواری نباشد:

Rendering Resolution

رزولوشن پردازش بازی که معمولا شامل دو عدد می‌شود و در تمام بازی‌ها وجود دارد. مقایسه در رزولوشن‌های مشابه هم امری بدیهی است. توانایی و میزان پردازشِ مورد نیاز برای رندر خروجی با تعداد پیکسل‌های رزولوشنِ تصویر نسبت مستقیم دارد.

Anti-aliasing

در مقام مقایسه یک عنوان بسیار پیچیده‌تر است. در بازی‌های مدرن معمولا برخی از گزینه‌های زیر را می‌توانید پیدا کنید:

  • روش‌های تمام صفحه‌ی خالص، مانند FXAA یا SMAA. آنها به تصاویر رندر شده‌ی نهایی نگاه می‌کنند و تلاش می‌کنند به شیوه‌ی post-processing آثاری مانند لبه‌های پلکانی اشیا را کشف کرده و بهبود دهند.
  • روش‌های هموار سازی زمانی (Temporal AA). آنها تصاویر را در آفست‌های متفاوت در هر فریم رندر می‌کنند و در حین ترکیبِ نتایج سعی می‌کنند مشکلات لبه‌های مشبک حاصل از حرکت اشیا یا دوربین را برطرف کنند.
  • روش MSAA) Multisampling) در درجات مختلف که چندین نمونه از هر پیکسل قرار گرفته در لبه‌های یک چند ضلعی را تولید می‌کند.
  • روش SSAA)Supersampling) در سطوح مختلف که چندین نمونه از تمام پیکسل‌های قرار گرفته در صفحه را تولید می‌کند.
  • ترکیبی از حالت‌های بالا مانند روش معروف TXAA ابداع شرکت انویدیا

این روش‌ها بر اساس تاثیرشان در راندمان به صورت صعودی فهرست شده‌اند، به جز دسته بندی آخر که به میزان سنگینی متدهای در برگیرنده‌ی آن بستگی دارد. روش‌های FXAA یا SMAA عموما سبُک کار می‌کنند و روش‌های هموار سازی زمانی هم بر اساس موقعیتِ اشیا، تاثیر منفی ناچیزی روی راندمان خواهند داشت. روش MSAA کار مقایسات راندمانی‌ را دشوار می‌کند، چرا که تاثیرش روی راندمان بر اساس شیوه‌ی پیاده سازی می‌تواند بسیار متفاوت باشد. اما SSAA بالاترین فشار را ایجاد می‌کند و سنگینی آن به سادگی به رزولوشنی که در آن ایجاد می‌شود بستگی دارد: SSAA با دقت N برابر دقیقا مساوی است با پردازش همان تصویر در رزولوشن N بار بالاتر.

تنظیمات گرافیکی AA برای هموار سازی لبه ی اشیا در باری ها

نورپردازی و سایه زنی

از لحاظ نورپردازی، هر قابلیتی که در آن Volumetric یا Global illumination به کار رفته باشد اغلب سنگینی زیادی دارد. این شامل پیاده سازی رده بالای God rays هم می‌شود، افکتی که سعی می‌کند تابش نور از میان گرد و غبار را روی یک پس زمینه‌ی تاریک‌تر شبیه سازی کند.

شبیه سازی God rays در بازی Fall out 4

وقتی نوری هست، سایه‌ای هم ایجاد می‌شود، اما متاسفانه این امر همانند دنیای واقعی، به صورت طبیعی در بازی‌‌ها رخ نخواهد داد. معمولا در بازی‌های امروزی حداقل دو منبع نوری در آنِ واحد داریم: یکی سایه‌های تماسی یا Ambient Occlusion که کاهش تابش نور یا بازتابِ آن روی اشیا و بافت‌ها را به خاطر تاثیر عواملی محیطی و مجاورِ خود شبیه سازی می‌کند و دیگری هم سایه زنی مستقیم یا Direct Shadowing که با تاثیر مستقیم منبع نوری از اشیای مختلف ایجاد می‌شود.

Smbient Occlusion زمانی که در بازی Crysis معرفی شد، به خودیِ خود افکت بسیار سنگینی بود. اما این روزها دیگر افکتِ با کیفیتِ سایه‌ی تماسی، راندمان بازی را نمی‌بلعد و به تکنیکی عادی بدل شده است. با این حال تکنیک‌های جدیدتر مانند Voxel ambient occlusion یا سایه زنی تماسیِ مبتنی بر میدان دید در بازی، که قرار است برخی مشکلات ذاتی روش‌های رایج را برطرف کنند، مجددا تاثیر قابل توجهی روی راندمان در زمان کنونی دارند.

در ارتباط با سایه‌های مستقیم هم شیوه‌ی موسوم به Contact Hardening افکت سختی برای شبیه سازی در بازی‌ها است. این شیوه بیانگر این واقعیت است که خطوطِ سایه‌ها در نزدیکی ایجاد کننده‌ی سایه تیزتر و دقیق‌تر هستند و هر چقدر از شی دور می‌شویم، به تدریج محوتر و نرم‌تر به نظر می‌رسند. پیاده سازی‌های مختلفی از این افکت وجود دارد (مثل PCSS)، اما هرگز افکت سهل الوصول و سبکی برای پیاده سازی نبوده است.

نمونه ی واقعی از چگونگی ایجاد سایه  و شبیه سازی آن در PCSS

مورد مهمی هست که باید در ارتباط با بهینه سازی به خاطر داشته باشیم: برخی تغییرات غیر قابل پیش بینی در بازی وجود دارد که ناچارا به واکنش‌های دیگر در بازی منجر می‌شود. نورهایی که جابجا می‌شوند یا شدت روشنایی آنها تغییر می‌کند، حرکتِ بازیکن در بازی و در بدترین سناریوی ممکن حتی جابجایی زمین و تغییر بافت آنها همه در این دسته از تغییرات قرار می‌گیرند. تمام واکنش‌های حاصل از تغییرات یاد شده در بازی تاثیر منفی به مراتب بیشتری روی راندمان خواهند داشت که ممکن است حتی از تاثیر افکت‌های شرح داده شده در بخش نور پردازی و سایه زنی بازی که از قبل برای آنها پیش بینی و محاسبه صورت گرفته هم بدتر باشد.

افکت‌های متفرقه

بسیاری از افکت‌های دیگر که در هیچ یک از دسته بندی‌‌های بالا جای نمی‌گیرند عمدتا به شبیه سازی رفتارِ بصری دوربین و لنز مربوطه دلالت دارند و اغلب هم سنگین نیستند. به جز افکت‌هایی مانند افکت معروف عکاسیِ bokeh که بخشی از محیط را که خارج از فوکوس دوربین باشد محوتر می‌کند و همین کار می‌تواند به قیمت افت راندمان ببیشتر منجر شود.

برخی افکت‌های دیگر مثل Screen-Space Reflections برای بازسازی انعکاس تصویر اشیا هم به صورت بالقوه می‌توانند بر راندمان تاثیرگذار باشند. افکت‌های دیگری هم وجود دارند که در دسته‌ی شبیه‌سازی‌های فیزیکی طبقه بندی می‌شوند و این بار به جز تراشه‌ی گرافیکی می‌توانند روی پردازنده‌ی اصلی یا هر دو با هم فشار وارد کنند. شبیه سازی مو و لباس و در امتداد آن شبیه سازی جریانِ مایعات، گازها، تخریب حاصل از اشیای مختلف و تاثیر پویای آنها بر محیط اطراف همگی در این طبقه بندی جای می‌گیرند.

کپی لینک

جنبه‌های مختلف بهینه سازی

حالا که ایده‌هایی درباره‌ی برخی از سنگین‌ترین افکت‌های مرسوم در بازی‌های امروزی داریم، می‌توانیم بررسی کنیم که چه عواملی باید در ساخت بازی لحاظ شود تا سرانجام آن را به عنوان یک بازی بهینه شده مطرح کند.

تعیین تنظیمات پیش فرض و ملزومات بازی

تنظیمات پیش فرض گرافیکی – گزینه‌های معمول Low، Medium، High، Very High و Ultra– تقریبا هیچ گاه مستقیما بین بازی‌های مختلف قابل مقایسه نیستند، اما بسیار مهم هستند: آنها برای راهنمایی گیمرهایی هستند که نمی‌خواهند به جزئیات فنی وارد شوند و تک تک گزینه‌ها را خودشان تنظیم کنند.

در Croteam، یک پیش فرض ساده برای تنظیمات متوسط یا Medium در همان ابتدای ساخت بازی در نظر گرفته می‌شود که بر مبنای محدودیت‌های سخت افزاری و انتظارات سازندگان استوار است. تمام طراحی‌های هنری و فنی هم پس از آن با حفظ همان استاندارد انجام می‌شود. نزدیک به زمان عرضه‌ی بازی، تیم تکنیکی سازنده تنظیمات لازم برای Preset ها یا پیش‌فرض‌های در نظر گرفته شده را استخراج و تعبیه می‌کند و تلاش می‌کند که جلوه‌های گرافیکی بازی و راندمان را در هر یک از این سطوح متعادل و متناسب سازد.

رویکرد جالبی که این استودیو در هنگام ساخت بازی دارد این است که آنها هر گزینه‌ی موثر در راندمان را در دسته‌های محدود به تراشه‌ی گرافیکی (GPU-bound)، محدود به پردازنده (CPU-bound) و همین طور محدود به ظرفیت حافظه (memory capacity-bound) قرار می‌دهند تا این که بخواهند کشف تاثیر آن را به عهده‌ی کاربر باقی گذارند. این رویکرد باعث تسهیل در کار گیمرها با پردازنده‌ها و کارت‌های گرافیکی ضعیف و قوی خواهد شد و به آنها اجازه می‌دهد تا بیشترین بهره را از سخت افزارشان در بازی بدست آورند.

تنظیمات پیش فرض بازی Talos Principle

از نگاه یکی از افراد تیم سازنده که بیش از همه با پورت کردن نسخه‌های کنسولی به پی‌سی سر و کار داشته است، تنظیمات استاندارد کنسولی معمولا به تنظیمات پیش فرضِ Medium در پی‌سی‌ها تعبیر می‌شود، هر چند که باز هم برخی جنبه‌های بازی ممکن است بر اساس خصوصیات و تفاوت‌ پلتفرم‌های مختلف بهینه سازی شوند و گزینه‌های مقیاس پذیری هم تا هر سطحی که مقدور باشد فرآهم می‌شود.

این که تنظیمات پیش فرض و ملزومات تعیین شده برای بازی چگونه به یکدیگر مربوط می‌شوند هم همیشه از نگاه گیمرها ناشناخته باقی مانده است. در حالی که هر سازنده‌ای استانداردهای مختص به خود را دارد، ملزومات حداقلی یا Minimum از نظر Croteam به معنی آن است که بازی با تنظیمات پایین به خوبی اجرا خواهد شد و اگر آن ملزوماتِ حداقلی در سخت افزار کاربر رعایت نشده باشند، پشتیبانی فنی کاملی هم برای کاربر در نظر گرفته نخواهد شد. در سوی دیگر ملزومات Recommended هم یعنی اینکه بازی در رزولوشن 1080p و تنظیمات گرافیکی High به خوبی قابل اجرا خواهد بود.

چگونه در مورد بهینه بودن بازی‌ها قضاوت کنیم

اکنون که به دانش بیشتری در مورد مفهوم بهینه سازی و میزان سنگینی افکت‌های مختلف مجهز شده‌ایم، کوشش می‌کنیم چند نمونه از بازی‌هایی را بازبینی کنیم که بحث‌های داغی در مورد بهینه نبودنشان در فضای مجازی شکل گرفته بود.

اتفاقی است که تقریبا همین اواخر برای بازی Dying Light رخ داده بود و می‌توانیم آن را یکی از موارد جدی مرتبط با بحثمان در نظر بگیریم، چرا که در ابتدا با واکنش منفی بسیاری از کاربران روبرو شده بود. Dying Light یک بازی جهان باز با کاراکترهای قابل بازی و غیر قابل بازی و اجزای تغییر پذیر زیادی است که همگی تحرکات بسیاری دارند و یک چرخه‌ی پویای روز و شب هم در محیط بازی تاثیرگذار است و از نظر تکنیکی آن را به بازی سنگینی بدل کرده است. یکی از گزینه‌های گرافیکی بازی به طور خاص هم Draw Distance است و از آن نوع تنظیماتی است که به میزان زیادی بار پردازشی CPU و GPU را همزمان تحت تاثیر قرار می‌دهد.

تنظیم گزینه‌ی تاثیر گذار میدان دید در بازی Dying Light

در ابتدا شکایاتی در مورد "بهینه نبودن وحشتناک پورتِ پی‌سی بازی "مطرح بود که اجرای آن را در حداکثر تنظیمات غیر قابل قبول اعلام می‌کردند. بعدا مشخص شد که گزینه‌ی Draw Distance در نسخه‌ی زمان انتشار بازی حتی در کمترین حالتش هم بالاتر از تنظیمِ پیش فرض کنسول در نظر گرفته شده بود. ناراحتی روز افزون کاربران سازنده را وادار کرد که با انتشار یک بروز رسانی قابلیت تغییر این گزینه را به ۵۵ درصد چیزی که قبلا در نظر گرفته بودند کاهش دهند تا راندمان روی سخت افزارهای مختلف بهبود پیدا کند. به نظر می‌رسد اگر این اقدام قبل از انتشار بازی صورت می‌گرفت، بازی برچسب غیر بهینه نمی‌خورد. این نمونه خود به تنهایی مبین این موضوع است که قضاوت در مورد بهینه بودن یا نبودن چقدر مشکل است و از سوی دیگر هم دغدغه‌ی سازندگان را در مورد محدودیت‌هایی که برای تنظیم گزینه‌های بازی دارند و تلاش برای اجتناب از بازخوردهای منفیِ احتمالی نشان می‌دهد. امری که گاهی اوقات ممکن است آنها را از پیاده سازی تنظیمات خیلی سنگین و با کیفیت‌تر منصرف کند.

Deus Ex: Mankind Divided's deferred renderer

نمونه‌ی مشابه‌ی دیگری که به تازگی رخ داد هم به بازی Deus Ex: Mankind Divided مربوط بود که دارای قابلیت اجرای MSAA تا سطح 8X است. از آنجا که بازی از تکنیک Deferred Shading– یک تکنیک رندر رایج برای پیاده سازی MSAA که با پیاده سازی شتاب‌دهنده‌های سخت افزاری آن متفاوت است – استفاده کرده، فعال کردن این گزینه تاثیر شدیدی روی راندمان باقی می‌گذارد. در واقع اگر این قابلیت در بازی تعبیه نمی‌شد یا از تکنیک سبک‌تر مشابه‌ای برای پیاده سازی MSAA استفاده می‌شد، قطعا بازی از ابتدا بسیار بهینه‌تر تلقی می‌شد و بازخورد عمومی بهتری هم می‌گرفت.

بازی‌ها را عموما نمی‌توان یک موجودیتِ یک دستِ مستقل در نظر گرفت که یا بهینه هستند یا غیر بهینه. ممکن است افکت‌های منحصر به فردی در آنها وجود داشته باشد که به خوبی بهینه نشده باشند، اما بخش عمده‌ی موتور بهینه باشد. این اتفاق معمولا در مورد قابلیت‌های جدید رخ می‌دهد. مثلا وقتی اولین بار بازی Crysisاز ambient occlusion پشتیبانی می‌کرد، این افکت در مقایسه با پیاده سازی‌های امروزی اصلا بهینه عمل نمی‌کرد. به صورت مشابه، اولین پیاده سازی نوع جدیدی از ambient occlusionمبتنی بر Voxelدر بازی Rise of the Tomb Raider هم همین سرنوشت را دارد و با وجود بهینه بودن کلی و تجربه‌ی عالی آن ممکن است در آینده پیاده سازی بسیار سبکتری پیدا کند.

البته بازی‌هایی که واقعا بهینه نشده باشند هم وجود دارند. علت آن هم معمولا منابع محدود یا یک توسعه دهنده‌ی کوچک است که پروژه‌ای بالاتر از توانش را انجام می‌دهد یا فاقد مهارت‌های تکنیکی لازم است. وقتی یک بازی در تنظیمات پیش فرضش روی یک سخت افزار قوی هم پر از لگ و وقفه باشد، یا یک بازی دو بعدی نسبتا ساده که روی کنسول نسلِ جدید به زیر ۲۰ فریم در ثانیه افت می‌کند، حتی خوشبینانه‌ترین تحلیل‌‌ها هم جایی برای نتیجه گیری دیگری باقی نمی‌گذارد.

چالش‌های بهینه سازی

فرآیند اصلی یک بهینه‌سازی واقعی در بازی‌ها چالش برانگیز است. بدترین کابوس برای یک بازی‌ساز وقتی است که به خروجی یک Profiler نگاه کند و ببیند که بالاترین تابع فقط سه درصد از زمان را در اختیار دارد. برای ارائه‌ی یک دید سطح بالا از معنی این عبارات باید بگوییم که Profiler ابزاری است که به برنامه نویس می‌گوید که یک تابع خاص چه کسری از زمان را برای اجرا لازم دارد و معمولا این توابع بر اساس میزان زمان بیشترِ استفاده شده به صورت نزولی مرتب می‌شوند.

بهینه سازی بازی‌ها با توجه به قابلیت‌هایی که دارند، عموما کاری تدریجی و پر زحمت خواهد بود

وقتی که سنگین‌ترین تابع تنها سه درصد از زمان را تصاحب کرده باشد، به این معنی است که حتی اگر بتوانید آن را تا دو برابر هم بهینه کنید، باز هم کل برنامه‌ی شما تنها تا یک و نیم درصد سریع‌تر خواهد شد از آنجا که این شرایط در کل بسیار پیش می‌آید، بهینه سازی بیشتر از این حد عموما کاری تدریجی و پر زحمت خواهد بود.

کپی لینک

جمع بندی

با وجود تمام جزئیات ارائه شده، این مقاله تنها در بر گیرنده‌ی بخش بسیار اندک از اطلاعاتی کلی است از آنچه که در بهینه سازی بازی‌های مدرن می‌گذرد.

وقتی راندمان بازی‌ها را با هم مقایسه می‌کنید، سعی کنید شیوه‌ی کارکرد آنها را هم در نظر داشته باشید. همان گونه که در بالا شرح دادیم، نورپردازی بلادرنگ (Realtime) و اشیای تعاملی به طرز غیر قابل قیاسی سخت‌تر از نمایش صحنه‌های ایستا است و بنابراین با برخی واقعیت‌ها و محدودیت‌های بازسازی صحنه‌ها روبرو هستیم که از نظر گرافیکی حتی در ابعاد کوچک هم شدیدا روی راندمان تاثیرگذار خواهند بود، فارغ از این که بازی تا چه حد خوب بهینه شده باشد.

به طور مشابه، ایده‌ای را در نظر بگیرید که تنظیمات گرافیکی رده بالای بیشتر، حتی اگر به طور کامل هم در ابتدای عرضه‌ی بازی قابل استفاده نباشند، هرگز نسبت به این که اصلا در بازی وجود نداشته باشند گزینه‌ی بدتری نیستند. قطعا این امر به معنی بهینه نبودن بازی نخواهد بود. همیشه اعتقاد داشتم که بازگشت به یک بازی رده بالا سال‌ها پس از انتشارش و دیدن شکوه و عظمت بیشتر و جلوه‌های بصری بالاتر آن روی سخت افزار جدید یکی از برتری‌های عمده‌ی پلتفرم پی‌سی است و جای تاسف است که ببینیم از چنین روندی به خاطر قضاوت‌های کوته بینانه در مورد بهینگی بازی‌ها کاسته شده است.

مقاله رو دوست داشتی؟
نظرت چیه؟
داغ‌ترین مطالب روز
تبلیغات

نظرات