Anyone have (or know of) a complete ChangeScreenBuffer() example?

21 posts / 0 new
Last post
Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Anyone have (or know of) a complete ChangeScreenBuffer() example?

The subject says it all. I'm looking for a complete ChangeScreenBuffer() example. The AutoDocs say to look at the graphics library documentation, and the graphics library's documentation has an incomplete example of double-buffering a viewport. I could definitely figure it out eventually, but a complete example specific to ChangeScreenBuffer() would be so much easier.

Hans

kas1e
kas1e's picture
Offline
Last seen: 2 months 3 weeks ago
Joined: 2010-11-30 15:30
I spend tons of time to

I spend tons of time to understand how all of this works to make it works together with Warp3D in my diskmag (thevague), and finally found out how to do all of this. The full source codes of diskmag are here , but necessary file are "other_funcs.h", in which:

  1. struct ScreenBuffer* buffer[2];
  2. int drawBuffer;
  3.  
  4. void SwitchDisplay(W3D_Context *context,struct Screen *screen)
  5. {
  6.  
  7.  
  8. if(window_mode==TRUE)
  9. {
  10. WaitTOF();
  11. W3D_FlushFrame(context);
  12. W3D_WaitIdle(context);
  13. BltBitMapRastPort(bufferrastport.BitMap,0,0,window->RPort,0,0,640,480,0xC0);
  14. W3D_SetScissor(context, &SwiDisp);
  15. W3D_SetDrawRegion(context, bufferrastport.BitMap, 0,&SwiDisp);
  16. }
  17.  
  18. if(fullscreen_mode==TRUE)
  19. {
  20. buffer[drawBuffer]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=0;
  21. while (!ChangeScreenBuffer(screen, buffer[drawBuffer]));
  22. drawBuffer ^=1;
  23. W3D_SetDrawRegion(context, buffer[drawBuffer]->sb_BitMap,0, &SwiDisp);
  24. WaitTOF();
  25. }
  26.  
  27. }

So i use ChangeScreenBuffer for double-buffering when i use full-screen mode (for window mode i use plain BltBitMapRastPort for making dbl-buffering).

Then, from my main code (mag.c) , i do:

  1. buffer[0] = AllocScreenBuffer(screen,NULL, SB_SCREEN_BITMAP);
  2. buffer[1] = AllocScreenBuffer(screen,NULL, 0);
  3. // bitmap
  4.  
  5. bm = screen->RastPort.BitMap;
  6.  
  7. context = W3D_CreateContextTags(&CError,
  8. W3D_CC_MODEID, ModeID, // Mandatory for non-pubscreen
  9. W3D_CC_BITMAP, bm, // The bitmap we'll use
  10. W3D_CC_YOFFSET, 0, // We don't do dbuffering
  11. W3D_CC_DRIVERTYPE, W3D_DRIVER_BEST, // Let Warp3D decide
  12. // W3D_CC_DOUBLEHEIGHT,TRUE, // Double height screen
  13. W3D_CC_FAST, TRUE, // Fast drawing
  14. // W3D_CC_INDIRECT, TRUE, // NEVER USE IT !
  15. TAG_DONE);

And then, when time is come , i just do:

  1. SwitchDisplay(context,screen);
  2. draw something
  3. SwitchDisplay(context,screen);

Hope that helps.

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@kas1e

It helps a little. However, you're not using the notification message ports, which is the bit that I'm most unsure about.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

TSK
TSK's picture
Offline
Last seen: 1 year 1 month ago
Joined: 2011-06-28 02:06
@Hans There's more example

@Hans
There's more example code in Autodocs for graphics.library/AllocDBufInfo.

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@TSK

@Hans
There's more example code in Autodocs for graphics.library/AllocDBufInfo.

That example is the graphics library example that I was talking about. Notice how it doesn't include any of the object allocation and initialisation stuff?

It turns out that there really is nothing to it. Just use AllocSysObject() to allocate the message ports, and assign them to dbi_SafeMessage and dbi_DispMessage. That's it. AllocSysObject() takes care of initialisation (incl. allocating a signal). What was confusing me is that you don't normally use GetMsg() without a PutMsg() or a ReplyMsg(). A full example would have eliminated the uncertainty.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

Menthos
Menthos's picture
Offline
Last seen: 12 years 11 months ago
Joined: 2011-04-18 10:38
Hello Hans! If you now have

Hello Hans!

If you now have figured it out could you please create a Blog here with a complete example that explains what it does?

/M.Andersson, Viking Technology

salass00
salass00's picture
Offline
Last seen: 6 months 3 days ago
Joined: 2011-02-03 11:27
There's a complete intuition

There's a complete intuition double-buffer example in the OS3.1 NDK.

http://dl.dropbox.com/u/26599983/doublebuffer.c

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

There's a complete intuition double-buffer example in the OS3.1 NDK.

http://dl.dropbox.com/u/26599983/doublebuffer.c

Thanks. I have the Amiga Dev CD too, but I didn't find this one.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@Menthos

If I can find the time, I'll try to create a minimal example.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 4 days ago
Joined: 2011-05-26 03:58
I am working on a project

I am working on a project that requires me to learn more about graphics.
This double-buffer example given _MAY_ be the right way for me to start looking, or it may not.

My needs are something like this. I'll have one or more windows open, each something smaller than the entire screen, but sizeable, so the dimensions remain flexible.

For each of these windows I want to allocate a bitmap/RastPort that is one window high and three windows wide (all variable to the current window size), then use Draw() and PrintIText() to add graphics, and finally scroll the visible part of that past the window.

At some point after the first 1/3 has completely passed by I'll be swapping the view to another, so I'll get the appearance of a much longer scroll, possibly hundreds of windows wide before it is finished.

This scrolling is horizonital only, and always in one direction, scrolling from left to right across the screen. scroll speed will need to be under program control as well.

So, in my search I read about BitMap, then RastPort, and finally ViewPort, which led me to read this thread. I grabbed the code example offered, and it does fine with an object that is smaller than the container.. though it seems to have a lot of flashing and a bit of graphics corruption.
This thread is also a good few years old. :)

Is this "double-buffering" the right path to follow, or would I be better off with some other approach?

Thanks for any advice offered!

LyleHaze

Massi
Massi's picture
Offline
Last seen: 4 years 6 months ago
Joined: 2012-03-28 17:16
@LyleHaze http://wiki.amigao

@LyleHaze

http://wiki.amigaos.net/wiki/Intuition_Screens

Double-buffering is certainly the way to go in order to implement a smooth scrolling.

However keep in mind that double (or multiple) buffering is supported by Intuition inside a screen, so your application should basically render its graphics into a screen.
If this system wide solution doesn' t meet your requirements then you need to implement your own thing.

Smooth (hardware accelerated) scrolling can also be achieved using Warp3D.

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 4 days ago
Joined: 2011-05-26 03:58
@Massi: Thank You.

@Massi:

Thank You. Double-buffering the entire screen looks good for full-screen gaming, but I don't think it's a good match for scrolling the contents of a just few windows.

From the page you linked:
"Windows with borders are not supportable on double-buffered screens. Double-buffered screens are expected to consist nearly entirely of custom rendering."

I'll have to keep looking.

LyleHaze

Massi
Massi's picture
Offline
Last seen: 4 years 6 months ago
Joined: 2012-03-28 17:16
@LyleHaze In general

@LyleHaze

In general speaking double-buffering lets you to avoid the so called "flickering" whether you scroll a screen or window content.

Intuition double-buffering is a cool thing but has a bit of restrictions.
I would implement my own custom routines.

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@LyleHaze

So, in my search I read about BitMap, then RastPort, and finally ViewPort, which led me to read this thread. I grabbed the code example offered, and it does fine with an object that is smaller than the container.. though it seems to have a lot of flashing and a bit of graphics corruption.
This thread is also a good few years old. :)

A gotcha that trips up a lot of people, is that you need to make sure that the GPU is done rendering before swapping the buffers. Currently the only way to do that is to lock the bitmap and unlock it again (see the Composite3DDemo's C3DContext code).

Since you have multiple windows open, using full-screen double-buffering won't work. The best option is indeed to allocate an off-screen bitmap, render to that, and then blit that onto the window.

There are a few things to bear in mind:
- Use WaitBOVP() before blitting to avoid tearing artifacts (not needed on screens with compositing effects, but definitely needed on screens without those effects)
- Scroll by blitting from the off-screen bitmap onto the window. Do NOT use IIntuition->ScrollWindowRaster(), because you'll still need to blit in the new areas, and overlapped blits are slower on Radeon HD cards than a blit from a separate bitmap

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 4 days ago
Joined: 2011-05-26 03:58
Hans, Thank you. I'll start

Hans,

Thank you.
I'll start down that path today.

Somehow I missed the "ScrollWindowRaster", but since I am copying from a larger bitmap to a smaller one, I can see how that would make things harder than they have to be.

My next step is to create my own RastPort and BitMap of the larger size (3x window width) so my existing Text() and Draw() calls can be moved to there. Hopefully it is as easy as it looks. ;)

Thanks again for the advice.

LyleHaze

LyleHaze

Massi
Massi's picture
Offline
Last seen: 4 years 6 months ago
Joined: 2012-03-28 17:16
@LyleHaze I hope I wasn' t

@LyleHaze

I hope I wasn' t misunderstood, I just wanted to advice what Intuition double-buffering is good for, according to the forum topic.
In your case a different solution is needed, as I suggested and Hans then detailed.
Anyway, your are on a safe path now :)

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 4 days ago
Joined: 2011-05-26 03:58
@Massi, Nothing to worry

@Massi,
Nothing to worry about. I have never played with any graphics before, except a bit of Intuition, so it's all new to me. I don't yet even know what I need to know.
Now if you want to make music, then I have some experience. :)

Based on the suggestions made, I just allocated my own offscreen rastport and bitmap at 3X window width. I then used some Text and Draw to mark it up a bit, and tried a loop of IGraphics->BltBitMapTags() with a steadily increasing X offset.. this looks like it's gonna work fine.

I have not yet added the WaitBOVP(), but that will be in the next rewrite.

Anyway, my "test case" is working very well. Now to go rewrite the graphics of the main program to use this technique. I'm really quite happy so far, I have wanted to add "Smooth Scrolling" for quite a while now. With the help I found here, I am well on my way. :)

Thanks again to you both.
:)

LyleHaze

LyleHaze
LyleHaze's picture
Offline
Last seen: 2 years 4 days ago
Joined: 2011-05-26 03:58
Follow up: Thank you Hans,

Follow up:

Thank you Hans, it's working very well.
I have horizonital scrolling, and the CPU load is very low.
I have an off-screen bitmap and RastPort that I render into, then I use IGraphics->BltBitMapTags() with a gradually increasing BLITA_SrcX to create the effect.

The speed of scrolling is tied directly to the music tempo, and it's a good bit faster than I expected. I'll need to raise the redraw rate if it's going to appear smooth.

But it looks great otherwise, many thanks for your help.

I will ask one question: Is there a limit to the width of the (non-displayed) raster that I render into? Everything was working great until I resized the window to near full-screen. The resuting crash may have been due to something else, but I was wondering if a 1680 X 3 rastport might be a problem.

Thanks,
LyleHaze

LyleHaze

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@LyleHaze

The bitmap size limit depends on the graphics card. Radeon 7xxx/9xxx cards can handle up to 2048x2048 in compositing, and larger bitmaps for blitting (at least 4096x4096, IIRC). Radeon HD 2xxx-4xxx series can handle up to 4096x4096, while newer Radeon HD cards can handle larger and larger dimensions.

It shouldn't crash, though. It should just drop down to software rendering when the graphics card is too big for the graphics card to handle.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

Massi
Massi's picture
Offline
Last seen: 4 years 6 months ago
Joined: 2012-03-28 17:16
@Hans What is the bitmap

@Hans

What is the bitmap size limit for a Radeon R200 9250 graphics card?

Just curious because I am developing a graphics application and currently have this card installed in my system.

Thanks.

Hans
Hans's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2010-12-09 22:04
Re: Anyone have (or know of) a complete ChangeScreenBuffer()...

@Massi

That depends on whether you want to use compositing or not. Like I said above, Radeon 7xxx/9xxx (R100/R200) have a max of 2048x2048 for compositing (the GPU's limit). I'm not 100% sure what the limits are for standard blitting, but it's definitely larger than 2048x2048.

Hans

Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work

Log in or register to post comments