9

2つの画像間で「クロスオーバー」効果を実行するためにglReadPixelsでスクリーンショットを撮っています。

Marmalade SDKシミュレーターでは、スクリーンショットは問題なく撮影され、「クロスオーバー」効果はうまく機能します。 ここに画像の説明を入力してください

ただし、これはiOSおよびAndroidデバイスでの外観です-破損しています:( ソース:eikona.infoここに画像の説明を入力してください

ドキュメントには常に受け入れられると書かれているので、私は常に画面をRGBA1バイト/チャネルとして読み取ります。

スクリーンショットを撮るために使用されるコードは次のとおりです。

uint8* Gfx::ScreenshotBuffer(int& deviceWidth, int& deviceHeight, int& dataLength) {

    /// width/height
    deviceWidth = IwGxGetDeviceWidth();
    deviceHeight = IwGxGetDeviceHeight();
    int rowLength = deviceWidth * 4; /// data always returned by GL as RGBA, 1 byte/each

    dataLength = rowLength * deviceHeight;

    // set the target framebuffer to read
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    uint8* buffer = new uint8[dataLength];
    glReadPixels(0, 0, deviceWidth, deviceHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    return buffer;
}

void Gfx::ScreenshotImage(CIwImage* img, uint8*& pbuffer) {

    int deviceWidth, deviceHeight, dataLength;

    pbuffer = ScreenshotBuffer(deviceWidth, deviceHeight, dataLength);
    img->SetFormat(CIwImage::ABGR_8888);
    img->SetWidth(deviceWidth);
    img->SetHeight(deviceHeight);
    img->SetBuffers(pbuffer, dataLength, 0, 0);
}
4

6 に答える 6

5

これはドライバーのバグです。そのような単純な。

ドライバーがビデオメモリの表面のピッチを間違えました。これは上の行ではっきりとわかります。また、画像の下部に表示されるゴミは、ドライバーが画像が保存されていると考えるメモリですが、そこには異なるデータがあります。テクスチャ/頂点データかもしれません。

申し訳ありませんが、それを修正する方法がわかりません。別のサーフェス形式を使用するか、マルチサンプリングを有効/無効にすることで、運が良くなる可能性があります。

于 2011-11-27T19:24:30.503 に答える
5

結局、それは記憶の欠如でした。「新しいuint8[dataLength];」既存のポインタを返すことはなかったため、プロセス全体が破損しました。

TomA、バッファをクリアするというあなたのアイデアは、実際に私が問題を解決するのに役立ちました。ありがとう。

于 2011-11-30T11:57:47.657 に答える
3

使用しているAndroidまたはSDKについてはわかりませんが、IOSでスクリーンショットを撮るときは、バッファーを次のPOTテクスチャのサイズにする必要があります。

int x = NextPot((int)screenSize.x*retina);
int y = NextPot((int)screenSize.y*retina);

void *buffer = malloc( x * y * 4 );

glReadPixels(0,0,x,y,GL_RGBA,GL_UNSIGNED_BYTE,buffer);

関数NextPotは、次のPOTサイズを提供するだけなので、画面サイズが320x480の場合、x、yは512x512になります。

おそらく、より大きなバッファサイズを期待しているため、バッファのラップアラウンドが表示されますか?

また、これがデバイスではなくシミュレータで機能する理由である可能性があります。私のグラフィックカードにはPOTサイズの制限がなく、同様の(奇妙な外観の)結果が得られます。

于 2011-11-28T10:34:40.217 に答える
3

私が起こっていると思うのは、あなたがglReadPixels覆われている窓で使用しようとしているということです。ビューエリアがカバーされている場合、の結果glReadPixelsは未定義です。

glDrawPixels()およびglReadPixels()の使用方法を参照してください。およびピクセル所有権の問題

ここで言ったように:

解決策は、オフスクリーンバッファ(FBO)を作成し、FBOにレンダリングすることです。

もう1つのオプションは、を使用するときにウィンドウが覆われていないことを確認することですglReadPixels

于 2011-11-30T10:31:10.733 に答える
1

glReadPixelsを修正するための解決策がありません。画面からデータを読み戻す必要がないように、アルゴリズムを変更することをお勧めします。

このページをご覧ください。これらの人はすべてFlashでページめくり効果を実行しました。それはすべて2Dであり、錯覚は影のグラデーションだけで実現されます。

同様のアプローチを使用できると思いますが、3Dでは少し優れています。基本的に、エフェクトを3つの部分に分割する必要があります。前面のトップページ(雲)、下部のページ(女の子)、およびフロントページの背面です。各パーツを個別に描画する必要があります。前面のトップページとボトムページを同じ画面で簡単に一緒に描画できます。トップページが曲がる分割線に合わせて事前設定されたクリッピング領域を使用して、それぞれの描画コードを呼び出す必要があります。トップページとバックページのセクションを描画する必要がある場合は、分割線に合わせて、グレーの背面部分を上部に描画できます。

このアプローチで失うのは、雲の画像が曲がり始めるわずかな変形だけです。もちろん、私の方法では変形は発生しません。それが効果を減らさないことを願っていますが、深さの効果を与えるには影がはるかに重要であり、この小さな矛盾を隠すことができると思います。

于 2011-11-30T07:11:43.913 に答える
1

glReadPixelsを使用しているAndroidデバイスで問題なくAndroidゲームのスクリーンショットを取得しています。

あなたの場合の問題はまだわかりません。詳細情報が必要です。それでは始めましょう:

  1. PixelStore形式は指定しないことをお勧めします。1バイトでの配置が心配ですが、本当に「使用」/「何をするのか知っていますか」?完全にパックされた画像の代わりに、指定したものを正確に取得しているようです。つまり、1バイト余分に(画像を見てください。常に1ピクセル余分にあります!)。だからこれを削除してみてください:

    glPixelStorei(GL_UNPACK_ALIGNMENT、1); glPixelStorei(GL_PACK_ALIGNMENT、1);

  2. 私はJavaでしか作業していなかったので、Cコードではわかりませんが、これは可能な点のように見えます。

    //幅/高さdeviceWidth=IwGxGetDeviceWidth(); deviceHeight = IwGxGetDeviceHeight();

デバイスサイズを取得していますか?次のように、OpenGLのサーフェスサイズを使用する必要があります。

public void onSurfaceChanged(GL10 gl, int width, int height) {
int surfaceWidth = width;
int surfaceHeight = height;
}
  1. キャプチャした画像で次に何をしますか?openglから取得したメモリブロックがRGBAであることを知っていますが、opengl以外のすべての画像操作はARGBを想定していますか?たとえば、ここのコードでは、アルファが最後ではなく最初のビットであると想定しています。

    img-> SetFormat(CIwImage :: ABGR_8888);

  2. 1、2、3が役に立たなかった場合は、キャプチャした画面を電話のsdcardに保存して、後で調べることができます。PCで調べるためにopenglRGBAブロックを通常のビットマップに変換するプログラムがあります。私はあなたとそれを共有するかもしれません。

于 2011-11-30T11:15:27.853 に答える