Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Unsupported virtual resolution

This thread is locked; no one can reply to it. rss feed Print
Unsupported virtual resolution
Danikaze
Member #8,889
August 2007
avatar

Hello everybody!

I'm coding in Linux, and testing my progress in Windows too.

When I set up graphic modes, I use this:

set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, w*2, h)

It works perfectly on Linux, but I get an error on Windows:
"Unsupported virtual resolution".

Is there any restriction on sizes for virtual resolution?

I used w*2, h to make a double buffering (flipping with show_video_bitmap) and it works on Linux.

If I try with set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, 0, 0) on Windows, it goes ok, but slow.
It seems not to do double buffering right...

Any suggestion? :-/

Jonatan Hedborg
Member #4,886
July 2004
avatar

You pretty much don't use the virtual screen nowadays.
Just create a video bitmap if you want to do some form of double buffering (though i would recommend using a regular bitmap, as drawing/reading to/from the screen is slow).

Damian Yerrick
Member #186
April 2000

Are system bitmaps significantly slower than ordinary bitmaps?

Danikaze
Member #8,889
August 2007
avatar

Jonathan
That's what I was doing, but to create video bitmaps in Linux, I need to have enough memory :S

That's how I made double buffering:

Initializing:

if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, w*2, h)==0) {;
  pantalla_buffer[0] = create_video_bitmap(SCREEN_W, SCREEN_H);
  pantalla_buffer[1] = create_video_bitmap(SCREEN_W, SCREEN_H);
  pantalla_actual = 0;
  pantalla = pantalla_buffer[pantalla_actual];
  fps_frame_time = (fps == 0)? 0 : 1000/fps;
} else {
  allegro_message("Error: %s\n", allegro_error);
}

Flipping function:

void flip() {
  show_video_bitmap(pantalla);
  pantalla_actual = (pantalla_actual+1)%2;
  pantalla = pantalla_buffer[pantalla_actual];
}

Milan Mimica
Member #3,877
September 2003
avatar

Use this:

#ifdef ALLEGRO_VRAM_SINGLE_SURFACE
   set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, w*2, h)
#else
   set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, 0, 0)
#endif

Quote:

f I try with set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, 0, 0) on Windows, it goes ok, but slow.
It seems not to do double buffering right...

Keep in mind that reading from video bitmaps is very slow.
And that's page flipping what you're doing, not double buffering.

Danikaze
Member #8,889
August 2007
avatar

Thanks!

But then... how double buffering is made?

Vanneto
Member #8,643
May 2007

You draw everything onto a sourface, the buffer, that is stored in memory. Then in the end you draw the buffer to the screen.

Drawing:

PlayerSprite --> Buffer
SometinSprite --> Buffer

Buffer --> Screen

Easy!

In capitalist America bank robs you.

Milan Mimica
Member #3,877
September 2003
avatar

In double buffering you draw something onto the buffer (in allegro, that's usually a memory bitmap) and then blit the contents of the buffer to the screen. This can be faster then page flipping if you are using transparency because reading from allegro's video bitmaps is slow.

In page flipping you draw onto one page of video memory and then "flip" the pages to display the page you were previously drawing to. I can be faster then double buffering because no data copying occurs.

Danikaze
Member #8,889
August 2007
avatar

So... If I have understood (I don't think so), double buffering is doing in this way:

// creates buffer
buffer = create_bitmap(SCREEN_W, SCREEN_H);

// draws the frame into the buffer
draw_something_into_buffer(..);
draw_something_into_buffer(..);
draw_something_into_buffer(..);

// blit the buffer into the screen
blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);

That's all? Or is it needed 2 buffers to do it?
Does vsync affects in any way this? (Because the thing is make something while the screen is being rendered... or not?)

Sorry for all those questions ^_^'

Audric
Member #907
January 2001

You got it right.
About vsync():
If you force your blit(on screen) to happen immediately after a vsync(), you're very likely that the complete replacement will happen during the interval, so the user will see the previous image, then the next image, and never a mix of the two : it prevents shearing effects.

However the vsync() function does not have a precise timing, forces a wait, and is based on busy-waiting; so it's not all perfect.

Danikaze
Member #8,889
August 2007
avatar

After watching replies, I made this, to use page_flip or double buffering depending on PAGE_FLIP directive (sorry for variable names, I'm Spanish, just know "pantalla"="screen" :P):

global variables:

#ifdef PAGE_FLIP
  static BITMAP* pantalla_buffer[2];
  static int pantalla_actual;
#endif

function to init graphics:

1int inicializar_graficos(int w, int h, int z, int fps) {
2 int error_init;
3
4 set_color_depth(z);
5
6 #ifdef ALLEGRO_VRAM_SINGLE_SURFACE
7 error_init = set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, w*2, h);
8 #else
9 error_init = set_gfx_mode(GFX_AUTODETECT_WINDOWED, w, h, 0, 0);
10 #endif
11
12 if(!error_init) {
13 #ifdef PAGE_FLIP
14 pantalla_buffer[0] = create_video_bitmap(SCREEN_W, SCREEN_H);
15 pantalla_buffer[1] = create_video_bitmap(SCREEN_W, SCREEN_H);
16 pantalla_actual = 0;
17 pantalla = pantalla_buffer[pantalla_actual];
18 #else
19 pantalla = create_bitmap(SCREEN_W, SCREEN_H);
20 #endif
21 fps_frame_time = (fps == 0)? 0 : 1000/fps;
22 } else {
23 allegro_message("Error: %s\n", allegro_error);
24 }
25 return !error_init;
26}

Function to draw in screen:

void flip() {
#ifdef PAGE_FLIP
  show_video_bitmap(pantalla);
  pantalla_actual = (pantalla_actual+1)%2;
  pantalla = pantalla_buffer[pantalla_actual];
#else
  blit(pantalla, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
#endif
}

Vanneto
Member #8,643
May 2007

I made a class some time ago with Mirans help. You can use it to have more buffers whitout changing a lot of code. For example:

1// Include buffering.hpp
2#include "buffering.hpp"
3 
4// The class is ScreenUpdate
5// The class is extended by double_buffer, triple_buffer and pageflipping
6 
7// Use it like this
8 
9// Everything will be drawn to screen
10 
11// Create a object
12ScreenUpdate *scr = new ScreenUpdate();
13 
14// Then init
15scr->init();
16 
17// Use scr->get_buffer() as the drawing surface
18draw_sprite(scr->get_buffer(), mysprite, x, y);
19 
20// Then when you want to blit the buffer to the screen, use update()
21scr->update();
22 
23// To change the buffering mode at runtime, do it like this
24scr->deinit();
25scr = NULL;
26 
27// Now set the buffering mode to double buffer
28scr = new double_buffer();
29 
30//-------------------------------------------
31// If you want to have a triple buffer or pageflipping, just
32// use the appropriate class on init
33ScreenUpdate *scr = new triple_buffer();
34// or
35ScreenUpdate *scr = new pageflipping();

Class(es) attached.

P.S. The classes dont do error checking. :P

In capitalist America bank robs you.

Danikaze
Member #8,889
August 2007
avatar

Thanks Vanneto!

Even if I am using C (not C++) so I can't use your classes, and I have the code already implemented, it was very useful so I can check my code is ok now and I could see how the triple buffering is used.

^_^

PS: Thanks to everyone who replied here :)

Go to: