نمایش نتایج 1 تا 13 از 13

نام تاپیک: کد نویسی به روش Double Buffering

  1. #1
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    Post کد نویسی به روش Double Buffering

    مهمترین اصل در ساخت گرافیک بازی های رایانه ای با #C

    دابل بافرینگ _Double Buffering



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





    Double Buffered Graphics


    NET Framework 4.5
    Flicker is a common problem when programming graphics. Graphics operations that require multiple complex painting operations can cause the rendered images to appear to flicker or have an otherwise unacceptable appearance. To address these problems, the .NET Framework provides access to double buffering.
    Double buffering uses a memory buffer to address the flicker problems associated with multiple paint operations. When double buffering is enabled, all paint operations are first rendered to a memory buffer instead of the drawing surface on the screen. After all paint operations are completed, the memory buffer is copied directly to the drawing surface associated with it. Because only one graphics operation is performed on the screen, the image flickering associated with complex painting operations is eliminated.


    Default Double Buffering


    The easiest way to use double buffering in your applications is to use the default double buffering for forms and controls that is provided by the .NET Framework. You can enable default double buffering for your Windows Forms and authored Windows controls by setting the DoubleBuffered property to true or by using the SetStyle method. For more information, see How to: Reduce Graphics Flicker with Double Buffering for Forms and Controls.


    Manually Managing Buffered Graphics


    For more advanced double buffering scenarios, such as animation or advanced memory management, you can use the .NET Framework classes to implement your own double-buffering logic. The class responsible for allocating and managing individual graphics buffers is the BufferedGraphicsContext class. Every application domain has its own default BufferedGraphicsContext instance that manages all of the default double buffering for that application. In most cases there will be only one application domain per application, so there is generally one default BufferedGraphicsContext per application. Default BufferedGraphicsContext instances are managed by the BufferedGraphicsManager class. You can retrieve a reference to the default BufferedGraphicsContext instance by calling the BufferedGraphicsManager.Current Property. You can also create a dedicated BufferedGraphicsContext instance, which can improve performance for graphically intensive applications. For information on how to create a BufferedGraphicsContext instance, see How to: Manually Manage Buffered Graphics.


    Manually Displaying Buffered Graphics


    You can use an instance of the BufferedGraphicsContext class to create graphics buffers by calling the BufferedGraphicsContext.Allocate Method, which returns an instance of the BufferedGraphics class. A BufferedGraphics object manages a memory buffer that is associated with a rendering surface, such as a form or control.
    After it is instantiated, the BufferedGraphics class manages rendering to an in-memory graphics buffer. You can render graphics to the memory buffer through the BufferedGraphics.Graphics Property, which exposes a Graphics object that directly represents the memory buffer. You can paint to this Graphics object just as you would to a Graphics object that represents a drawing surface. After all the graphics have been drawn to the buffer, you can use the BufferedGraphics.Render Method to copy the contents of the buffer to the drawing surface on the screen.
    For more information on using the BufferedGraphics class, see Manually Rendering Buffered Graphics. For more information on rendering graphics, see Graphics and Drawing in Windows Forms
    آخرین ویرایش به وسیله habibb : جمعه 07 تیر 1392 در 08:16 صبح دلیل: درج نکات و ویرایش متن

  2. #2
    VIP آواتار gwbasic
    تاریخ عضویت
    فروردین 1403
    محل زندگی
    تهران
    سن
    42
    پست
    982

    نقل قول: کد نویسی به روش Double Buffering

    در هر فرم خاصیتی به نام DoubleBuffered وجود داره که با true کردن آن کمی چشمک زدن فرم کمتر می شه. اما راه بهتر اینه که شما تصویری که قرار نمایش بدین رو اول در یک Bitmap ایجاد کنید و سپس اون رو روی فرم Draw کنید. پستهای قدیمی من رو جستجو کنید در این موردا توضیح دادم

  3. #3

    نقل قول: کد نویسی به روش Double Buffering

    در هر فرم خاصیتی به نام DoubleBuffered وجود داره که با true کردن آن کمی چشمک زدن فرم کمتر می شه. اما راه بهتر اینه که شما تصویری که قرار نمایش بدین رو اول در یک Bitmap ایجاد کنید و سپس اون رو روی فرم Draw کنید. پستهای قدیمی من رو جستجو کنید در این موردا توضیح دادم
    سلام ممکنه لینک پست ها رو بذارید
    ممنون

  4. #4
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    نقل قول نوشته شده توسط gwbasic مشاهده تاپیک
    راه بهتر اینه که شما تصویری که قرار نمایش بدین رو اول در یک Bitmap ایجاد کنید

    // Double Buffering بافر کردن تصویر کنترل در حال حرکت برای اجرای تکنیک
    Bitmap buffer = new Bitmap(pictureBox1.DisplayRectangle.Width
    ,pictureBox1.DisplayRectangle.Height);

    نقل قول نوشته شده توسط gwbasic مشاهده تاپیک
    و سپس اون رو روی فرم Draw کنید.


    using (Graphics context = Graphics.FromImage(buffer))
    {
    // کیفیت ترسیم
    context.SmoothingMode = SmoothingMode.HighQuality;

    // ترسیم پس زمینه درون بافر
    context.DrawImage(this.background, 0, 0);


    // PictureBoxترسیم بافر بر روی کنترل
    pictureBox1.CreateGraphics().DrawImage(buffer, 0, 0);
    }

    نقل قول نوشته شده توسط gwbasic مشاهده تاپیک
    پستهای قدیمی من رو جستجو کنید در این موردا توضیح دادم
    کد HTML:
    https://barnamenevis.org/showthread.php?202784-%D8%A7%D9%81%D8%B2%D8%A7%DB%8C%D8%B4-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%AA%D8%B1%D8%B3%DB%8C%D9%85&highlight=Double+Buffer
    ================================================== =======
    ولی یک روش بهتر و سخت تر دیگه هم هست که این روش کاربردی تره!
    کد هاش رو که از سایت MSDN با موضوع BufferedGraphics Class گرفتم اینجا میگذارم لطفا مفهومش رو توضیح بدین و یک مثال کاربردی ازش بزنید و هر کی هر چی می دونه بگه چون این موضوع خیلی کم راجبش بحث شده .
    جزء 1

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    namespace BufferingExample
    {


    جزء 2

    public class BufferingExample : Form
    {
    private BufferedGraphicsContext context;
    private BufferedGraphics grafx;

    private byte bufferingMode;
    private string[] bufferingModeStrings =
    { "Draw to Form without OptimizedDoubleBufferring control style",
    "Draw to Form using OptimizedDoubleBuffering control style",
    "Draw to HDC for form" };

    private System.Windows.Forms.Timer timer1;
    private byte count;


    جزء 3

    public BufferingExample() : base()
    {


    جزء 4
    // Configure the Form for this example.

    this.Text = "User double buffering";
    this.MouseDown += new MouseEventHandler(this.MouseDownHandler);
    this.Resize += new EventHandler(this.OnResize);
    this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true );

    جزء 5
    // Configure a timer to draw graphics updates.

    timer1 = new System.Windows.Forms.Timer();
    timer1.Interval = 200;
    timer1.Tick += new EventHandler(this.OnTimer);
    bufferingMode = 2;
    count = 0;

    جزء 6
    // Retrieves the BufferedGraphicsContext for the
    // current application domain.

    context = BufferedGraphicsManager.Current;

    جزء 7
    // Sets the maximum size for the primary graphics buffer
    // of the buffered graphics context for the application
    // domain. Any allocation requests for a buffer larger
    // than this will create a temporary buffered graphics
    // context to host the graphics buffer.

    context.MaximumBuffer = new Size(this.Width+1, this.Height+1);

    جزء 8
    // Allocates a graphics buffer the size of this form
    // using the pixel format of the Graphics created by
    // the Form.CreateGraphics() method, which returns a
    // Graphics object that matches the pixel format of the form.

    grafx = context.Allocate(this.CreateGraphics(),
    new Rectangle( 0, 0, this.Width, this.Height ));

    جزء 9
    // Draw the first frame to the buffer.

    DrawToBuffer(grafx.Graphics);
    }

    جزء 10

    private void MouseDownHandler(object sender, MouseEventArgs e)
    {
    if( e.Button == MouseButtons.Right )
    {

    جزء 11
    // Cycle the buffering mode.

    if( ++bufferingMode > 2 )
    bufferingMode = 0;

    جزء 12
    // If the previous buffering mode used
    // the OptimizedDoubleBuffering ControlStyle,
    // disable the control style.

    if( bufferingMode == 1 )
    this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );

    جزء 13
    // If the current buffering mode uses
    // the OptimizedDoubleBuffering ControlStyle,
    // enabke the control style.

    if( bufferingMode == 2 )
    this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false );

    جزء 14
    // Cause the background to be cleared and redraw.

    count = 6;
    DrawToBuffer(grafx.Graphics);
    this.Refresh();
    }
    else
    {

    جزء 15
    // Toggle whether the redraw timer is active.

    if( timer1.Enabled )
    timer1.Stop();
    else
    timer1.Start();
    }
    }

    جزء 16

    private void OnTimer(object sender, EventArgs e)
    {

    جزء 17
    // Draw randomly positioned ellipses to the buffer.

    DrawToBuffer(grafx.Graphics);

    جزء 18
    // If in bufferingMode 2, draw to the form's HDC.

    if( bufferingMode == 2 )

    جزء 19
    // Render the graphics buffer to the form's HDC.

    grafx.Render(Graphics.FromHwnd(this.Handle));

    جزء 20
    // If in bufferingMode 0 or 1, draw in the paint method.

    else
    this.Refresh();
    }

    جزء 21

    private void OnResize(object sender, EventArgs e)
    {

    جزء 22
    // Re-create the graphics buffer for a new window size.

    context.MaximumBuffer = new Size(this.Width+1, this.Height+1);
    if( grafx != null )
    {
    grafx.Dispose();
    grafx = null;
    }
    grafx = context.Allocate(this.CreateGraphics(),
    new Rectangle( 0, 0, this.Width, this.Height ));

    جزء 23
    // Cause the background to be cleared and redraw.

    count = 6;
    DrawToBuffer(grafx.Graphics);
    this.Refresh();
    }

    جزء 24

    private void DrawToBuffer(Graphics g)
    {

    جزء 25
    // Clear the graphics buffer every five updates.

    if( ++count > 5 )
    {
    count = 0;
    grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);
    }

    جزء 26
    // Draw randomly positioned and colored ellipses.

    Random rnd = new Random();
    for( int i=0; i<20; i++ )
    {
    int px = rnd.Next(20,this.Width-40);
    int py = rnd.Next(20,this.Height-40);
    g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0,255), rnd.Next(0,255)), 1),
    px, py, px+rnd.Next(0, this.Width-px-20), py+rnd.Next(0, this.Height-py-20));
    }

    جزء 27
    // Draw information strings.

    g.DrawString("Buffering Mode: "+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10);
    g.DrawString("Right-click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22);
    g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34);
    }

    جزء 28

    protected override void OnPaint(PaintEventArgs e)
    {
    grafx.Render(e.Graphics);
    }

    جزء 29

    [STAThread]
    public static void Main(string[] args)
    {
    Application.Run(new BufferingExample());
    }
    }
    }
    آخرین ویرایش به وسیله habibb : جمعه 07 تیر 1392 در 22:48 عصر

  5. #5
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    سلام من کلاس BufferedGraphics رو جزء به جزء جدا کردم .
    هر کی هر چی می دونه راجب هر جزئیش که هست یک کمی توضیح بده
    من خودم هم دنبالش می گردم و اینجا نتیجه ی کارم رو می گذارم .
    در ضمن لینک برنامه های دابل بافرینگ هم که کلاس BufferedGraphics توش به کار رفته رو هم بگذارید .

  6. #6
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    جزء 2 خط 10
    "Draw to HDC for form" };

    HDC آدرس داده گرافيکي
    که درContex Device ذخيره شده ، می باشد

    پس یعنی داده ی گرافیکی رو روی فرم رسم کن.


    *
    آخرین ویرایش به وسیله habibb : جمعه 07 تیر 1392 در 18:51 عصر

  7. #7
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    حال بايد تابعي بسازيم که تصاوير گرافيکي را درون حافظه load کند .
    نکته مهمي که بايد به آن توجه کنيد اينست که يک device context خودش به تنهايي هيچ داده گرافيکي ندارد
    و بايستي يک bitmap موجود باشد تا درون آن load شود
    براي مثال يک فايل bmp يا يک bitmap خالي که از آن بعنوان back buffer استفاده مي کنيد .
    تابعي که خواهيم نوشت يک device context منطبق با صفحه مي سازد سپس فايلهاي گرافيکي مورد نظر را درون device context قرار مي دهد .
    کدوم خط؟
    ورودی تصاویر گرافیکیه که يک bitmap هست که تصاویر در درونش load میشه ؟در واقع کدومش back buffer هست؟
    آخرین ویرایش به وسیله habibb : جمعه 07 تیر 1392 در 13:04 عصر

  8. #8
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    تابعي که يک انتقال از داده هاي مرتبط به يک مستطيل از پيکسلها همون (sprite)به يک device context مقصد انجام مي دهد .
    به عبارت ديگر داده هاي گرافيکي را از محيط گرافيکي ( يک bitmap ) به محيط گرافيکي ديگري ( screen و form ) کپي مي کند .
    sprite چیست ؟ به اشیاء متحرکی گفته میشه که در بازی ها وجود دارن .
    حالا اون تابعی که این وظیفه رو انجام بده . کدومه ؟

  9. #9
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    بررسی کل جزء29

    [STAThread]
    public static void Main(string[] args)
    {
    Application.Run(new BufferingExample());
    }
    }
    }

    پروسه ی ورودی و اصلی برنامه که در Program.cs قرار دارد در داخل کلاس BufferedGraphics قرار گرفته شاید به این خاطر این کار صورت گرفته تا سرعت لود برنامه بالا تر رود ولی بهتر است پروسه ی Main برنامه در ابتدای کلاس قرار گیرد تا تابع Main در اولین بررسی توسط کامپایلر شناخته شود جهت اجرای اولیه ، هر چند که از نظر سرعت خیلی به چشم نمی آید. در ضمن حالا که تابع Main رو داخل کلاس BufferedGraphics آوردیم پس دیگه احتیاجی به فایل Program.cs نداریم .
    بنابراین من فایل Program.cs رو از Solution Explorer پروژم Delete می کنم .

  10. #10
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering


    بررسی کل جزء 3


    public BufferingExample() : base()
    {

    سازنده ی کلاس BufferingExample می باشد که هم نام با نام کلاس و بدون نوع خروجی می باشد که سازنده از کلاس base ارث می برد .
    در اینجا چون هیج جایی از کلاس base استفاده نشده پس ارث بری سازنده از کلاس base رو من از پروژم Delete می کنم .
    ولی اگر در پروژه کلاس پایه هم داشتیم پس باید سازنده ی BufferingExample از سازنده ی کلاس base ارث ببرد .
    آخرین ویرایش به وسیله habibb : چهارشنبه 26 آذر 1393 در 22:32 عصر

  11. #11
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    بررسی کل جزء1

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    namespace BufferingExample
    {

    در این روش نیازی به اضافه کردن using ها نداریم و به جای BufferingExample می تونید نام دلخواهی برای پروژتون انتخاب کنید .
    کسی نیست بیات کمک ما کنه این کد ها خیلی سخته

  12. #12
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    جزء 4 خط 1

    this.Text = "User double buffering";

    این قطعه کد عنوان فرم را مشخص می کند. که یکی از Property های فرم می باشد .

  13. #13
    کاربر دائمی آواتار habibb
    تاریخ عضویت
    خرداد 1388
    محل زندگی
    قُلْ هُوَ اللَّهُ أَحَدٌ
    پست
    423

    نقل قول: کد نویسی به روش Double Buffering

    بررسی کل جزء 28

    protected override void OnPaint(PaintEventArgs e)
    {
    grafx.Render(e.Graphics);
    }
    در متود OnPaint هیچگونه پردازش و رسم و ... ای وجود نخواهد داشت
    و تنها وظیفه OnPaint نمایش بافر از قبل آماده روی صفحه هست.

    آخرین ویرایش به وسیله habibb : پنج شنبه 14 خرداد 1394 در 01:04 صبح

تاپیک های مشابه

  1. سوال: متد نیتیو، کاربرد استاتیک و Double Buffering
    نوشته شده توسط ehsangerrard در بخش برنامه‌نویسی جاوا
    پاسخ: 4
    آخرین پست: دوشنبه 13 تیر 1390, 20:50 عصر
  2. کد نویسی یا روش های دیگر ؟ (برای کار با database)
    نوشته شده توسط jas1387 در بخش C#‎‎
    پاسخ: 19
    آخرین پست: دوشنبه 09 فروردین 1389, 14:52 عصر
  3. مشکل با double buffered
    نوشته شده توسط Delphi-Man در بخش مباحث عمومی دلفی و پاسکال
    پاسخ: 19
    آخرین پست: پنج شنبه 16 مهر 1388, 22:51 عصر
  4. کسی میدونه Double Buffering در دلفی چطور کار می کنه
    نوشته شده توسط interrupt21 در بخش برنامه نویسی در Delphi
    پاسخ: 1
    آخرین پست: چهارشنبه 06 اردیبهشت 1385, 12:09 عصر
  5. Double Buffer
    نوشته شده توسط BAHMAN_SH در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 3
    آخرین پست: جمعه 06 شهریور 1383, 04:20 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •