Heya,

A couple of weeks ago, I posted:

>> Hi Folks,
>>
>> As it says in the subject line, I would like to create an DirectFB 
>> application with the following capabilities:
>>
>> 1. The ability to use the Draw functions in an area outside the viewable 
>> area (ie invisible to the user).
>> 2. Pan the data in the area outside the viewable area into (and out of) 
>> the viewable area.
>> 3. Copy data from one part of the surface to another, to provide 
>> temporary saving (I realize that I could use the "Dump" API for this, 
>> create a png and when I want to restore it, load it back in but this 
>> seems somewhat inefficient) as well as a provide a very fast (or fade in) 
>> transition between images.
>>
>> Can anybody point me to any references or example code explaining how 
>> this could be done? I'm using the basic DirectFB package (ie no 
>> QT/Qtopia) to try and keep the code footprint as small as possible.
>>
>> Thanx - I really appreciate any suggestions that people would have for 
>> me.
>>
>> myke


I wanted to follow up and say that I believe that I have solved all my 
problems.

What I was missing was an understanding of how “surfaces” work in DirectFB; 
they provide the ability of drawing off screen, bring data into the viewable 
area and provide the ability to temporarily save data off screen.

To demonstrate this operation, I created the application below so hopefully 
somebody else new to working with DirectFB and wanting similar capabilities 
will have a place to start. I would also appreciate any of the old hands at 
DirectFB reviewing the code below and commenting/suggesting on where I have 
done things wrong/could be done better or more efficiently.

My application runs on a Freescale i.MX233, which is an ARM without video 
hardware acceleration running Linux 2.6.31. The display is 480x272 and for 
the “bckgnd#.png” images, I clipped some basic pictures to this size. 
Similarly, the font used is an open-source Open Text font which should be 
easy to find.

This is a resend because the original seemed to lose formatting (hopefully this 
one won’t).  


Please reply back with any questions or comments,

myke



/*
* dfb_image6.c
*
*
* Save and Later Redisplay Surface on the display
*
* Written for fsl i.MX233 EVK running Linux 2.6.31
*
*
* Created on: 29-Dec-2011
* Author: myke
*/

#include <stdio.h>
#include <unistd.h>
#include <directfb.h>



static IDirectFB*         dfb = NULL;
static IDirectFBSurface*  primary = NULL;
DFBSurfaceDescription     primary_dsc;
static IDirectFBSurface*  image1;
DFBSurfaceDescription     image1_dsc;
static IDirectFBSurface*  image2;
DFBSurfaceDescription     image2_dsc;
static IDirectFBSurface*  image3;
DFBSurfaceDescription     image3_dsc;

IDirectFBFont*            font = NULL;
DFBFontDescription        font_dsc;

static int                screen_width = 0;
static int                screen_height = 0;


#define DFBCHECK(x...)                                          \
{                                                               \
DFBResult err = x;                                              \
                                                                \
    if (err != DFB_OK)                                          \
    {                                                           \
        fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ );  \
        DirectFBErrorFatal( #x, err );                          \
    }                                                           \
}  

int main (int argc, char **argv)
{
int                       i;
IDirectFBImageProvider*   provider;


// Create Super Interface
    DFBCHECK(DirectFBInit (&argc, &argv));
    DFBCHECK(DirectFBCreate (&dfb));

// Create Primary Surface
    DFBCHECK(dfb->SetCooperativeLevel(dfb, DFSCL_FULLSCREEN));
    primary_dsc.flags = DSDESC_CAPS;
    primary_dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE;
    DFBCHECK(dfb->CreateSurface(dfb, &primary_dsc, &primary));

// Get the size of the primary Display
    DFBCHECK(primary->GetSize(primary, &screen_width, &screen_height));
//    printf("\r#### - \"primary\" screen_width = %i, screen_height = %i\r\n", 
screen_width, screen_height);

// Create (1) - JUST a background image
    DFBCHECK(dfb->CreateImageProvider(dfb, "/home/images/bckgnd1.png", 
&provider)); // Gears Background
    DFBCHECK(provider->GetSurfaceDescription(provider, &image1_dsc));
    DFBCHECK(dfb->CreateSurface(dfb, &image1_dsc, &image1));
    DFBCHECK(provider->RenderTo(provider, image1, NULL));
    DFBCHECK(provider->Release(provider));

// Create (2) - NO background image
    image2_dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT;
    image2_dsc.width = screen_width; image2_dsc.height = screen_height;
    DFBCHECK(dfb->CreateSurface(dfb, &image2_dsc, &image2));
    font_dsc.flags = DFDESC_HEIGHT | DFDESC_ROTATION;
    font_dsc.height = 24;
    font_dsc.rotation = DFB_DEGREES(0);
    DFBCHECK(dfb->CreateFont(dfb, "/home/fonts/NotCourierSans-Bold.otf", 
&font_dsc, &font));
    DFBCHECK(image2->SetFont(image2, font));
    DFBCHECK(image2->SetColor(image2, 0x00, 0x00, 0xff, 0xff));
    DFBCHECK(image2->FillRectangle(image2, 0, 0, screen_width, screen_height));
    DFBCHECK(image2->SetColor(image2, 0xff, 0xff, 0xff, 0xff));
    DFBCHECK(image2->DrawString(image2, "Image (2)", -1, 25, screen_height / 2, 
DSTF_LEFT | DSTF_TOP));

// Create (3) - Background image & Box
    DFBCHECK(dfb->CreateImageProvider(dfb, "/home/images/bckgnd2.png", 
&provider)); // Gears Background
    DFBCHECK(provider->GetSurfaceDescription(provider, &image3_dsc));
    DFBCHECK(dfb->CreateSurface(dfb, &image3_dsc, &image3));
    DFBCHECK(provider->RenderTo(provider, image3, NULL));
    DFBCHECK(provider->Release(provider));
    DFBCHECK(image3->SetColor(image3, 0xff, 0xff, 0xff, 0xff));
    DFBCHECK(image3->FillRectangle(image3, screen_width / 4, screen_height / 4, 
screen_width / 2, screen_height / 2));

// Display the First Image
    DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
    DFBCHECK(primary->Blit(primary, image1, NULL, 0, 0));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));

    sleep(1);


// Display the Second Image
    DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
    DFBCHECK(primary->Blit(primary, image2, NULL, 0, 0));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));

    sleep(1);


// Display the Third Image - From Right
    for (i = screen_width; 0 <= i; i -= 4) {
//        printf("\ri = %i\r\n", i);
        DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
        DFBCHECK(primary->Blit(primary, image3, NULL, i, 0));
        DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));
    }

    sleep(1);


// Redisplay the Second Image - From Bottom
    for (i = screen_height; 0 <= i; i -= 4) {
//        printf("\ri = %i\r\n", i);
        DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
        DFBCHECK(primary->Blit(primary, image2, NULL, 0, i));
        DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));
    }

    sleep(1);


// Redisplay the First Image - From Left
    for (i = -screen_width; 0 >= i; i += 4) {
//        printf("\ri = %i\r\n", i);
        DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
        DFBCHECK(primary->Blit(primary, image1, NULL, i, 0));
        DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));
    }

    sleep(1);


// Before redisplaying Third Image, make white rectangle outlined black box
    DFBCHECK(image3->SetColor(image3, 0x00, 0x00, 0x00, 0xff));
    DFBCHECK(image3->FillRectangle(image3, (screen_width / 4) + 3, 
(screen_height / 4) + 3, (screen_width / 2) - 6, screen_height / 2) - 6));

// Redisplay the Third Image - From Top
    for (i = -screen_height; 0 >= i; i += 4) {
//        printf("\ri = %i\r\n", i);
        DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
        DFBCHECK(primary->Blit(primary, image3, NULL, 0, i));
        DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));
    }

    sleep(1);


// Update the currently shown image
    DFBCHECK(primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff));
    DFBCHECK(primary->DrawLine(primary, screen_width / 8, screen_height / 8, 
(screen_width * 7 ) / 8, screen_height / 8));
    DFBCHECK(primary->DrawLine(primary, screen_width / 8, (screen_height * 7) / 
8, (screen_width * 7 ) / 8, (screen_height * 7) / 8));
    DFBCHECK(primary->SetFont(primary, font));
    DFBCHECK(primary->DrawString(primary, "That's all!", -1, (screen_width / 4) 
+ 6, (screen_height / 4) + 6, DSTF_LEFT | DSTF_TOP));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));

    sleep(1);


// Copy primary into image2
    DFBCHECK(image2->SetBlittingFlags(image2, DSBLIT_NOFX));
    DFBCHECK(image2->Blit(image2, primary, NULL, 0, i));

// Clear the "That's all!" message on displayed image
    DFBCHECK(primary->SetColor(primary, 0x00, 0x00, 0x00, 0xff));
    DFBCHECK(primary->FillRectangle(primary, (screen_width / 4) + 3, 
(screen_height / 4) + 3, (screen_width / 2) - 6, (screen_height / 2) - 6));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC)); // Remember the Flip 
after updating the display

    sleep(1);


// Display the First Image
    DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
    DFBCHECK(primary->Blit(primary, image1, NULL, 0, 0));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));

    sleep(1);


// Display the saved Image
    DFBCHECK(primary->SetBlittingFlags(primary, DSBLIT_NOFX));
    DFBCHECK(primary->Blit(primary, image2, NULL, 0, 0));
    DFBCHECK(primary->Flip(primary, NULL, DSFLIP_ONSYNC));

    sleep(5);


// Release the DirectFB components
    DFBCHECK(font->Release(font));
    DFBCHECK(image1->Release(image1));
    DFBCHECK(image2->Release(image2));
    DFBCHECK(image3->Release(image3));
    DFBCHECK(primary->Release(primary));
    DFBCHECK(dfb->Release(dfb));

    return 6;

} 

_______________________________________________
directfb-users mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-users

Reply via email to