2

編集:それを理解しました、以下の答えを参照してください。

Samsung GalaxySのAndroid(NDK)上のOpenGLES2.0でテクスチャにレンダリングしようとして問題が発生しました

より具体的には、フレームバッファーを使用してテクスチャにレンダリングし、そのテクスチャからバックバッファーに描画します-エミュレーター(4.2.2を実行)およびGalaxy S2では完全にレンダリングされ、同じことが複数の実行にも当てはまります同じコードのiOSデバイスの。

Galaxy Sは2.3.3を実行しています(2.3.3でこれを行うようにエミュレーターを説得することはできません)。

テクスチャサイズを1024x1024に設定すると、512x512テクスチャに保存されているように見えます。または、重い圧縮が行われているように見えます。これは、S2、エミュレータ、iOSデバイスの両方のGalaxySでのみ発生します。完璧に。

テクスチャを512x512に設定すると、Galaxy Sでほとんど問題なくレンダリングされるように見えますが、ギラギラすることは何も悪いことではありませんが、同じブレが発生する程度ははるかに少ないことに気付くでしょう。

1024x1024のスクリーンショット

1024x1024のスクリーンショット

スクリーンショットog512x512

スクリーンショットog512x512

両方の画像で、上の4つのアイテムが最初にテクスチャに描画され、次にそこからバックバッファに描画されます(黒いものの欠陥もGalaxy Sのみの問題ですが、関連しているとは考えていません)

1024x1024のテクスチャをロードして、そこから問題なくレンダリングできます。テクスチャのレンダリングバッファでglReadPixelsを使用すると、見た目も問題ありません(残念ながら、GL ESは、基になるテクスチャからピクセルを直接読み取ることをサポートしていません)。

1024x1024で保存されたフレームバッファ

お気づきかもしれませんが、512x512バージョンの軽い種類でもぼやけることはありません。

さらに不思議なことに、同じGalaxySデバイスで問題なく1024x1024テクスチャにレンダリングするOpenGLES 1.1を実行しているJavaの古いプロジェクトがありますが、Javaで完全なES 2.0レンダリングを記述して、それが違いがあり、フレームバッファのOES拡張メソッドがリンカーエラーを作成するため、NDKでES 1.1を試していません(リンクできるlibがある可能性があります。より良いアイデアがない場合は、そこに行く可能性があります)

ただし、Javaでフレームバッファとテクスチャを作成し、ハンドルをネイティブコードに渡してみましたが、違いはありません。

グーグルのためのどんなポインタ、推測、ハンチ、魔法のキーワード、何でも私はこれを理解しようとして今日12時間まっすぐに費やしました、そして私はこれまで何も進歩していません、私は必死に近づいています。

以下は、関連する可能性のあるコードの抜粋です。さらに質問することを躊躇しないでください(この時点で、プロジェクト全体が3つのプラットフォームにまたがる数千行であるため、最も関連性の高い部分を選択してみました)。

フレームバッファを作成するためのコード:

glGenFramebuffers(1, &FFrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, FFrameBufferID);
glGenRenderbuffers(1, &FDepthBufferID);
glBindRenderbuffer(GL_RENDERBUFFER, FDepthBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, FDepthBufferID);

glGenTextures(1, &FTextureID);
glBindTexture(GL_TEXTURE_2D, FTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Tried both with and without:
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FTextureID, 0);

GLenum OStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (OStatus != GL_FRAMEBUFFER_COMPLETE) {
    Dev::Log(SGString("framebuffer creation failed: ") + (int) OStatus);
}

バーテックスシェーダー:

void main(void) {
    gl_Position = Projection * vec4(Position, 1.0);
    TextureCoordsOut = TextureCoords;
    ParamOut = Param;
    ColorOut = Color;
}

射影行列:

matrix[0]  = 2.0 / (right - left);
matrix[1]  = 0.0;
matrix[2]  = 0.0;
matrix[3] = 0.0;

matrix[4]  = 0.0;
matrix[5]  = 2.0 / (top - bottom);
matrix[6]  = 0.0;
matrix[7] = 0.0;

matrix[8]  = 0.0;
matrix[9]  = 0.0;
matrix[10]  = -2.0 / (far - near);
matrix[11] = 0.0;

matrix[12]  = -(right + left) / (right - left);
matrix[13]  = -(top + bottom) / (top - bottom);
matrix[14] = -(far + near) / (far - near);
matrix[15] = 1.0;

レンダリング:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);

glVertexAttribPointer(FPositionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(SGVertex), OVertextBuffer->Buffer());
glVertexAttribPointer(FTextureCoordsSlot, 2, GL_FLOAT, GL_FALSE, sizeof(SGVertex), OVertextBuffer->Buffer() + (sizeof(float) * 3));
glVertexAttribPointer(FParamSlot, 1, GL_FLOAT, GL_FALSE, sizeof(SGVertex), OVertextBuffer->Buffer()+ (sizeof(float) * 5));
glVertexAttribPointer(FColorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(SGVertex), OVertextBuffer->Buffer()+ (sizeof(float) * 6));

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OTexture->TextureID());
glUniform1i(FTextureUniform, 0);

glDrawArrays(GL_TRIANGLES, 0, count);
4

1 に答える 1

1

答えにつながる小さなヒントに出くわしました。問題は、サンプルからコピーしたテクスチャ座標の精度でした。

varying lowp vec2 TextureCoordsOut;

lowpが何を意味するのかわからないので、無視しました-大きな間違い-に変更しました

varying highp vec2 TextureCoordsOut;

そして今では完璧に動作しますが、他のすべてのデバイスで動作する理由lowpは私を超えています

それも可能ですが、私はそれをテストするmediumpためだけに行くと思いました。highp

于 2013-03-23T00:48:14.373 に答える