News:

PlayBASIC2DLL V0.99 Revision I Commercial Edition released! - Convert PlayBASIC programs to super fast Machine Code. 

Main Menu

Graphics Questions

Started by kevin, November 27, 2008, 12:01:56 PM

Previous topic - Next topic

kevin




Graphics Questions:

Document Revision: V0.04

This FAQ might be out of date, always check the home page versions for the most up to date editions





Q. Does PlayBasic Use Hardware Accelerated Graphics ?


    A.  Yes.   All versions of PlayBasic have hardware acceleration wherever possible.  However, it's not always possible.  




Q. What Graphics API does  PlayBasic Use ? - OpenGL or DirectX ?


    A.   All current editions of PlayBasic & PlayBasicFX use some form of the DirectX graphics API.   PlayBasic uses DirectDraw interface, and PlayBasicFX uses the Direct3D interface.  





Q. Can I use shaders in PlayBasic ?


     A.  No.   The graphics API it uses doesn't support them.  However, even if it did, you'd still have to learn to write shaders.   Which is not for the faint hearted!  





Q. Image Stretching with (low resolution) in Full Screen exclusive Modes (LCD monitors)


    A.   Unfortunately this is just how LCD monitors work.    LCD monitors are manufactured such that they contain an array of dots, this array makes up the screen we look at.  The array is a fixed width and height, it never changes.  For example my LCD I'm looking at right now, is 1440 across * 900 high.    This is also the size my windows desktop is set to, which gives the clearest picture.   As each dot coming from the video card, is visualized as one dot on the monitor.  

      However,  if i change my desktop size to say half the monitors resolution (720*450 in my case, if my video card allowed it).  Then the monitor has resize the signal coming from the video card to  make it  fit on monitor pixel array.  Otherwise they'd just fill the top left rectangular area of the monitor,  some older LCD monitors do this, although they do center it.     Anyway,  In this case each pixel from the video card becomes a 2*2 block on the monitor.  

       As programmers this is important to understand,  in particular retro game programming.  Since the majority of  oldschool games use very low resolutions by modern standards, such as 320*200 & 320*240 for example.    Old 8bit machines we're even lower again.  So if you try and display such a screen resolution on your LCD in PlayBasic for example, your monitor with stretch the image any way it sees fit.   The smaller you try and blow up, the worse this will be.

       The solution is, we could all switch back to those beefy CRT monitors (which don't suffer from such problems) or we could simply use a higher resolution and pre-scale our media up proportionately.   For example,  years ago I wrote a 2d shooter on the Amiga.  The game runs in 320*208 screen mode,  If I wanted to recreate this game in PlayBASIC for example on the PC, then rather than use the original artwork as is,  it'd be better to double the size of the everything to suit a 640*400 or 640*480 screen size.  So if the image is scaled by the players monitor, the affect of the monitors filters will be slightly less visible.  They'd still be there though.   Isn't technology wonderful  :)
   




Q. Do modern video cards support full screen 320*200, 320*240 Display resolutions ?


    A.   Some still do, but many don't.  It's not too hard to imagine a time in the not too distance future where it's completely unsupported by Hardware Vendors.    

                 So if your developing a game that requires a 320*240, or 320*200 full screen display mode, you'll need an alternative approach when running the game on systems that don't support this mode in hardware.    Some options might be,

                 * Run the game in Windowed Mode and stretch the screen to the players desktop size.
                 * If the target computer doesn't support 320*240 say, but it supports 640*480, Then you could double the size of your graphics and run the game in 640*480 mode.  Which will give you a simulation of 320*240 modes.   The same goes for 320*200 modes also.




Q. Can I check what display modes the computer video hardware can display ?


    A.   Yep,  use the function ScreenModeExist to query the video card about what mode(s) it supports.

PlayBASIC Code: [Select]
 if  ScreenModeExist(320,240,32)=false
print "screen mode doesn't exist"
else
print "display mode 320*240*32bit is available"
endif


if ScreenModeExist(640,480,32)=false
print "screen mode doesn't exist"
else
print "display mode 640*480*32bit is available"
endif

Sync
waitkey



 


Q. What is a Pixel ?


    A.  We can think of a pixel  as a single dot of graphics.  These Pixel can be any colour (displayable by the computer).    Images are therefore  comprised of generally rectangular or square regions of the pixels.  


    Learn more
    http://en.wikipedia.org/wiki/Pixel
    http://www.economicexpert.com/a/Pixels.htm





Q. What are the RGB components that Pixels use ?


    A.  Pixel colours in PlayBasic (and virtually all languages) are presented using the RGB colour model.  They use this, because this is what the video card (display hardware) uses.

    So to create a pixel colour, we're balancing the three RED, GREEN and BLUE components together.   Each component (R,G,,B) has an 8bit intensity level.  These intensities values will range from the 0 to 255.   0 Being none present,  255 being brightest.    Therefore 127 would give be the half the max brightness.

    To form a colour, we merge the R,G,B intensities together using the RGB() function (Colour = Rgb(R,G,B)) in PlayBasic.

    Given the each component has an 8bit range (0->255), the max number of unique colours you can display is 2^(8+8+8) =  16.8 million colours
 
   
PlayBASIC Code: [Select]
   r=255
g=0
b=0

// Use the RGB function to pack the three intensities into one an RGB COLOUR
ink RGB(R,G,B)
print "This bright RED COLOUR"



r=0
g=255
b=0

// Use the RGB function to pack the three intensities into one an RGB COLOUR
ink RGB(R,G,B)
print "This bright GREEN COLOUR"


r=0
g=0
b=255

// Use the RGB function to pack the three intensities into one an RGB COLOUR
ink RGB(R,G,B)
print "This bright BLUE COLOUR"



r=255
g=0
b=255

// Use the RGB function to pack the three intensities into one an RGB COLOUR
ink RGB(R,G,B)
print "This bright PURPLE COLOUR"

Sync
WaitKey




    Learn more
   http://en.wikipedia.org/wiki/RGB




Q. Does PlayBasic support double buffering ?


    A.   Yes.




Q. What is Double Buffering ?


    A.   Double Buffering is a method computers use to help reduce flicker when drawing graphics.       What it means, is that the screen is really two buffers,  a Visible and hidden (or front and back if you like).   We see the front buffer, while a programs rendering takes place on the back buffer.  During a sync the buffers are swapped.  How they are swapped is up to your video card !    Some video card drivers copy the buffers, most redirect (flip) the hardware to the front->back, and then back ->front surface. (ie. a pointer swap).  So the front and back and constantly being swapped.  


    Learn More:
    http://en.wikipedia.org/wiki/Double_buffering





Q. What is VSync (Vertical beam synchronization) / Video Tearing ?


     A. This is a fairly complicated hardware issue to come to terms with. In a nut shell, Vsync refers to how (and when) the computers video hardware sends the current screen image to the monitor so that we can see it.

     When the monitor displays the screen image, it doesn't actually show the entire image all in one go, rather it lights the rows of dots (also know as scan lines) individually.   This illumination process starts at the top row and sweeps down the display, displaying each row in a left to right fashion. The illumination isn't actually super fast, it's just fast enough to give the illusion to the viewer (the person looking at the screen) that we're seeing a solid picture being displayed. Each time the monitor completes a sweep of the display, is commonly referred to a frame or a refresh.

     The speed (or frequency) in which monitor can refresh the entire picture is generally given in the number of complete frames / refreshes per second that it can drawn. Today this is routinely 60 to 75 hertz and even higher. Some monitors/TV's can display the image at over 200 times per second. The faster the refresh, the more solid the image will appear to generally be. However something that's worth considering, is that this is different for every human. Some people see flicker in 60, 75 , 100 hertz images, where others don't.

     Now this is all well and good, but what does this all mean to you and your game ?, well what we're getting here is that in order for a computer to display the best quality screen image, the computer and monitor need to be synchronized together in some way.    Why ? - Well if there's no synchronization between the computer and monitor, then we can get visual artifacts such as tearing.

     Tearing occurs when the computer and monitor are either not synchronized together, or have fallen out of sync with one another (highly unlikely, but it is possible).    What is it ? -  Well it happens when a computer is drawing a moving or animating  image into the video cards screen buffer (the screen buffer is representation of the screen image stored in computers memory),  then just blindly outputting the image to the monitor without taking where monitor is in it's refresh process into consideration.  

     Why is this an issue ? - Well,  imagine the we have two images currently in computers video cards screen memory.   The first image is a picture of an APPLE,  this image is the one we're sending to be shown to the user on the monitor.  So it's the Front Buffer. (See Double Buffering),   now while this is occurring (the monitor is display the APPLE picture),   we're off drawing a picture of  a ORANGE to the back buffer (The hidden screen).   Now if upon completing drawing of our orange  picture to the back buffer,  we then tell the video card hardware to Swap the front and back buffers immediately, without checking if the monitor has even finished drawing the apple frame,  then we'll potentially get a tearing artifacts, Where the user briefly see the partly drawn Apple frame, mixed with bottom of Orange frame and vice versa.  

     To overcome this we can use VSYNC   (Vertical beam synchronization) to force the video hardwares swapping mechanism (the process it uses to swap the fron & back bu8ffer) to wait until the monitors current Beam position (the row it's currently displaying) is outside of the visual display area (Vertical Blanking gap).   So in other words, rather than just swap the back the front buffers whenever we like, our program will often need to wait for the monitors beam position to reach a certain safe point..  This point is generally the when the beam position is reset to it's starting position at the top of the new frame.     Interestingly, the  monitors first beam position (first row) starts well above the first visible screen rows.  

    While waiting for Vsync  will give a better image quality to the end viewer, it also means that our program is now bound to the speed of the monitor refresh rate.  So if the monitors refresh rate in a particular screen mode was set to 60 hertz say, then our program needs to consistently complete it's work inside the time it takes for the monitor to complete one refresh cycle.   So in millisecond terms, for a 60 hertz screen mode our program has approximately 16.67 milliseconds (1000/60) to complete all of work to maintain the 60 hertz refresh rate (60fps).

     However,  If our program exceeds the time in which the monitor refresh takes, in other words our programs update takes longer than our expected 16.67 milliseconds, and we call sync to swap the front & back buffers when Vsync is enabled,  then if the monitor has started display a new frame, then the video card will be forced to wait until the monitors refresh pass has ended and beam position has reached it's start point again.    When this occurs,  your programs frame  rate will halve.   If your program is alter busy and misses then next sync point, then it'll be forced to wait again,  which will effective slow the program down to a 1/3 of the display refresh rate.    

     So in summary, VSYNC potentially gives our games better visual quality of motion,  but this comes at the expensive of locking our game to the users monitors refresh rate.    Generally it's best to make these things optional to the player.


   Example of Exceeding the Vsync Time period
PlayBASIC Code: [Select]
      // open a full screen exclusive display mode
OpenScreen 800,600,32,2

// request Vsync during SYNC's (if available)
ScreenVsync On

Size=64
size2=size/2
c1=rgb(10,30,70)
c2=rgb(155,255,155)
shadebox 0,0,Size,Size,c1,c2,c1,c2
getimage 1,0,0,size,size

Do
// Display the scrolling backdrop
tileimage 1,Xpos,0,false
xpos=(xpos+1) and (size-1)


// check for a key press
if LeftKey() then dec Delay
if rightKey() then inc Delay



// force the program to just waiting, to simulate it doing some work.
EndTimer=Timer()+Delay
repeat
until Timer()>=EndTimer


Setcursor 0,0
print "Use the LEFT/RIGHT Arrow keys to change the delay time"
print "Delay Time:"+Str$(Delay)

; display the programs current refresh rate (the number of refresh per second)
print "Fps:"+STR$(Fps())

Sync
loop



     Need more information, try this wiki on the subject.http://en.wikipedia.org/wiki/Screen_tearing





Q. Are there issues with VSync (Vertical beam synchronization) ?


       A. Unfortunately, YES.    The most common gotchas are assumptions game programmers make about the end game players machine.    Such as,  programmers shouldn't assume the end user (gamer) has Vsync capable hardware (not all Video Cards/Drivers supports it), the user has vsync enabled in their drivers (they may have turned it off, which overrides your game!) or that the users refresh rate will be the same as yours in the gamers chosen screen mode.  

       So there's a couple of key points that you'll need to keep in mind.   Therefore, If you write a game and use the Vsync as the only way to limited the speed of your application, assuming this will be the same for everyone who plays your game, then you're in for a horrible shock !  -   This goes way beyond language here, the PC is a dynamic platform, it's this diversity of the hardware / software that can make writing PC games potentially tricky  for not only  new programmers, but experienced programmers alike.    As such,  the availability of Vsync/Refresh rates  is not something that can be 'fixed', it's more an issue we develop strategies that help our programs counter.

      The most common strategy resolves around the idea of decoupling our games 'logic' from the rendering loop via the use of some timer based system (See articles bellow)..    These can be quite elaborate though, so if your just starting out on your game programmer journey.   Then simply giving the player an option to enable /disable Vsync and using set  FPS control will do in most cases.  


Related Articles

   Timer Based Movement with Vsync Tweening
   Timer Based Movement  (Tutorial)
    Vsync / Frame Rate Scaling
   Handling Multiple Animations using Timer()
   Consistent Game Timing