6

画面にデータバッファを表示する非常に高速な方法が必要です。私は最初にLinuxフレームバッファにアクセスしようとしましたが、それは非常に優れていることがわかりました。次に、directFBについて学び、directFBが提供する追加機能(高速memcpy、オンザフライでの画像のサイズ変更、追加のコードの必要なしなど)が気に入りました。しかし、それから私は障害にぶつかりました-すべての例はファイルからロードされる画像のためのものです。私が知る限り、その「DataBuffer」タイプの例/チュートリアルはありません。ドキュメントとソースコードを調べた後、私は次のようなものをコンパイルすることができました。

DFBSurfaceDescription sdsc;
DFBDataBufferDescription ddsc;
DFBDataBufferDescriptionFlags ddscf = (DFBDataBufferDescriptionFlags)DBDESC_MEMORY;
IDirectFBDataBuffer *dbuffer;
IDirectFBImageProvider *provider;

ddsc.flags = ddscf;
ddsc.file = NULL;
ddsc.memory.data = m_z;
ddsc.memory.length = 640*480;

DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
sdsc.flags = DSDESC_CAPS;
sdsc.caps  = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_FLIPPING);
DFBCHECK (dfb->CreateSurface( dfb, &sdsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));

DFBCHECK (dfb->CreateDataBuffer(dfb, &ddsc, &dbuffer));
DFBCHECK (dbuffer->CreateImageProvider(dbuffer, &provider));
DFBCHECK (provider->GetSurfaceDescription (provider, &sdsc));

DFBCHECK (dfb->CreateSurface( dfb, &sdsc, &fbwindow ));
DFBCHECK (provider->RenderTo (provider, fbwindow, NULL));
provider->Release (provider);

つまり、基本的には、DFBからDataBufferを作成し、次にDataBufferからImageProviderを作成して、サーフェス上にレンダリングするように設定しています。ただし、実行するとエラーが発生します。

(#) DirectFBError [dbuffer->CreateImageProvider(dbuffer, &provider)]: No (suitable) implementation found!

メソッドは本当に実装されていませんか?私は現在DirectFB1.4を使用していますが、APIドキュメントから関数がそこにあるはずです。そうは言っても、DirectFBを使用してメモリからバッファ(char * 640 * 480 * 4 RGBA)を取得してフレームバッファにレンダリングする方法を知っている人はいますか?

ありがとう。

4

2 に答える 2

8

多分あなたを助けるために少し遅れます、しかしこれを試みている他の誰かの利益のために、ここに答えがあります。

それは実際にはあなたが思っているよりも単純です(1つの落とし穴があります)-私はDirectFb 1.4.11を使用して、あなたが望むことを正確に実行しています。

プライマリサーフェスを作成したら、DataBufferを気にしないでください。DSDESC_PREALLOCATED flasgとバッファーを事前に割り当てられたデータとして使用して、別のサーフェスを作成します。次に、新しいサーフェスからプライマリサーフェスにデータをBlit()し、プライマリサーフェスを画面にFlip()します。1つの落とし穴は、データがDirectFBが理解できる形式である必要があるということです。32ビットRGBAはその1つではありませんが、32ビットARGBは-バイトを入れ替えるためにバッファーを解析する必要がありました。

コード例:

  dsc.width = screen_width;
  dsc.height = screen_height;
  dsc.flags = DSDESC_HEIGHT | DSDESC_WIDTH | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT;
  dsc.caps = DSCAPS_NONE;
  dsc.pixelformat = DSPF_ARGB;
  dsc.preallocated[0].data = buffer;      // Buffer is your data
  dsc.preallocated[0].pitch = dsc.width*4;
  dsc.preallocated[1].data = NULL;
  dsc.preallocated[1].pitch = 0;

  DFBCHECK (dfb->CreateSurface( dfb, &dsc, &imageSurface ));
  DFBCHECK (primary->Blit(primary, imageSurface, NULL, 0, 0));
  DFBCHECK (primary->Flip(primary, NULL, DSFLIP_ONSYNC));

バッファが画面と同じサイズ/形状でない場合は、代わりにStretchBlit()を使用してサイズを変更できます。

これがお役に立てば幸いです。

于 2012-03-16T08:59:05.580 に答える
3

上記のMartinPの回答は適切ですが、画像が圧縮されていない場合にのみ機能します。png / jpeg画像をメモリから直接ロードおよびデコード/解凍したかったので、このトピックを見つけました。

これに関する有用な情報はほとんどなく、私自身も苦労していますが、その方法を見つけました。これは古い質問ですが、同じことを達成しようとする他の人に役立つ可能性があります。

// Variables
DFBDataBufferDescription ddsc;
DFBSurfaceDescription sdsc;
IDirectFBDataBuffer *buffer;
IDirectFBImageProvider *image_provider;

// The surface that will contain the rendered image
IDirectFBSurface *surface;                      

// create a data buffer for memory
ddsc.flags = DBDESC_MEMORY;
ddsc.memory.data = data;
ddsc.memory.length = dataLength;
DFBCHECK(directFB->CreateDataBuffer(directFB, &ddsc, &buffer));

// Create the image provider, surface description and surface itself
DFBCHECK(buffer->CreateImageProvider(buffer, &image_provider));
DFBCHECK(image_provider->GetSurfaceDescription(image_provider, &sdsc));
DFBCHECK(directFB->CreateSurface(directFB, &sdsc, &surface ));

// Now render the image onto the surface
DFBCHECK(image_provider->RenderTo(image_provider, surface, NULL));

// Release 
image_provider->Release(image_provider);
buffer->Release(buffer);

データ変数は、画像を含むunsigned charの配列へのポインタです(ヒント:このような配列は'xxd -i image.jpg> image.h'で作成できます)。datalengthは、配列のサイズを持つunsignedintです。作成されたサーフェスを画面にブリットすることも、ディスプレイサーフェスを一度に「レンダリング」することもできます。

于 2014-03-31T17:13:51.480 に答える