2

OpenGL ES 2.0(Android 4.0.4、Galaxy Nexus)で、頂点とフラグメントシェーダーを使用して、フルスクリーンの背景として単純なテクスチャを表示しようとしています。最終的にはそこにカメラ画像を表示する必要がありますが、最初はファイルからの単純なテクスチャで十分です。私は多くのことをテストし、OpenGL ES 1.xを使用してしばらくの間は機能しましたが、YUV-> RGB変換にシェーダーを使用する予定なので、2.0を使用する必要があります。

私は次の頂点シェーダーを持っています:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main() {
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy
}

そしてこのフラグメントシェーダー:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

void main() {
    gl_FragColor = texture2D(videoFrame, textureCoordinate);
}

シェーダーの作成自体は問題ないはずです。なぜなら、私が書くとき、gl_FragColor=vec4(1,0,0,0)それは完全にうまく機能し、赤い背景を見せてくれるからです。

OnSurfaceCreated私は次のことをします:

 a = makeFloatBuffer(squareVertices);
 b = makeFloatBuffer(textureVertices);

次のようsquareVerticestextureVertices

static float squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
        1.0f, 1.0f, };

static float textureVertices[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, };

OnSurfaceChanged私は次のことをします:

GLES20.glViewport(0, 0, width, height);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.raw.htc);
GLES20.glGenTextures(1, textures, 0);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

R.raw.htcは128x128ピクセルのpngです。

そしてOnDrawFrame

    GLES20.glUseProgram(program);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

    GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame"),0);

    GLES20.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
    GLES20.glClearDepthf(1.0f);
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    int x = GLES20.glGetAttribLocation(program, "position");
    int y = GLES20.glGetAttribLocation(program, "inputTextureCoordinate");

    GLES20.glEnableVertexAttribArray(x);        
    GLES20.glVertexAttribPointer(x, 2, GLES20.GL_FLOAT, false, 0, a);
    GLES20.glEnableVertexAttribArray(y);
    GLES20.glVertexAttribPointer(y, 4, GLES20.GL_FLOAT, false, 0, b);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

私が見るのは完全に黒い画面だけで、その理由はわかりません。私はここで同様の問題を抱えた他のいくつかの投稿を見ましたが、提案された解決策のどれも私を助けなかったか、解決策がまったく与えられませんでした。

4

3 に答える 3

2

上記のように、問題の解決策を見つけることができましたが、現在は機能しており、以前は機能していなかった理由は正確にはわかりません (いくつか変更したところ、突然機能しました)。それにもかかわらず、私は作業バージョンを共有したいと思います:

YUV->RGB 変換も行うシェーダーが完成しました: 頂点シェーダー:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

 void main() {
      gl_Position = position;
      textureCoordinate = inputTextureCoordinate.xy;
 };

フラグメント シェーダー:

varying highp vec2 textureCoordinate;
uniform sampler2D videoFrame;
uniform sampler2D videoFrame2;

void main(void) {
    highp float nx,ny,r,g,b,y,u,v;
    highp vec2 uv;
    highp vec4 txl,ux,vx;"
    nx=(textureCoordinate.x)/1024.0*720.0;
    ny=(textureCoordinate.y)/1024.0*480.0;
    y=texture2D(videoFrame,vec2(nx,ny)).r;
    uv=texture2D(videoFrame2,vec2(nx,ny)).ag;
    y=1.1643*(y-0.0625);
    u=uv[0]-0.5;
    v=uv[1]-0.5;
    r=y+1.5958*v;
    g=y-0.39173*u-0.81290*v;
    b=y+2.017*u;

    gl_FragColor=vec4(r,g,b,1);
};

OnSurfaceCreatedは同じですが、頂点の定義が少し変更されました。

static float squareVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
        1.0f, 1.0f, };

private float textureVertices[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, };

OnSurfaceChanged:

    buffer = new int[2];
    GLES20.glGenTextures(2, buffer, 0);
    for (int i = 0; i < 2; i++) {
        int texture = buffer[i];
        Log.v("Texture", "Texture is at " + texture);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
        GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, GLES20.GL_TRUE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    }

    buf = new byte[1024 * 1024];
    for (int i = 0; i < 1024 * 1024; i++) {
        buf[i] = 0;
    }
    buf2 = new byte[1024 * 1024];
    for (int i = 0; i < 1024 * 1024; i++) {
        buf2[i] = -128;
    }

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[0]);

    GLES20.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_LUMINANCE, 1024,
            1024, 0, GL10.GL_LUMINANCE, GL10.GL_UNSIGNED_BYTE,
            ByteBuffer.wrap(buf));

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[1]);

    GLES20.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_LUMINANCE_ALPHA,
            512, 512, 0, GL10.GL_LUMINANCE_ALPHA, GL10.GL_UNSIGNED_BYTE,
            ByteBuffer.wrap(buf2));

OnDrawFrame:

    GLES20.glViewport(0, 0, mWidth, mHeight);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[0]);

    GLES20.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, Util.CAMWIDTH,
            Util.CAMHEIGHT, GL10.GL_LUMINANCE, GL10.GL_UNSIGNED_BYTE,
            ByteBuffer.wrap(mBuffer, 0, Util.CAMWIDTH * Util.CAMHEIGHT));

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, buffer[1]);

    GLES20.glTexSubImage2D(
            GL10.GL_TEXTURE_2D,
            0,
            0,
            0,
            Util.CAMWIDTH / 2,
            Util.CAMHEIGHT / 2,
            GL10.GL_LUMINANCE_ALPHA,
            GL10.GL_UNSIGNED_BYTE,
            ByteBuffer.wrap(mBuffer, Util.CAMWIDTH * Util.CAMHEIGHT,
                    Util.CAMWIDTH / 2 * Util.CAMHEIGHT).slice());

    GLES20.glClearColor(1.0f, .0f, .0f, .0f);

    GLES20.glUseProgram(program);

    GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame"),
            0);
    GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "videoFrame2"),
            1);

    GLES20.glClearDepthf(1.0f);
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    int x = GLES20.glGetAttribLocation(program, "position");
    int y = GLES20.glGetAttribLocation(program, "inputTextureCoordinate");

    GLES20.glEnableVertexAttribArray(x);
    GLES20.glVertexAttribPointer(x, 2, GLES20.GL_FLOAT, false, 0, a);
    GLES20.glEnableVertexAttribArray(y);
    GLES20.glVertexAttribPointer(y, 2, GLES20.GL_FLOAT, false, 0, b);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
于 2012-07-22T23:54:02.070 に答える
0
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

これらの2行のコードは私のためにトリックをしました

GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

PNGファイルを表示するには、これら2つも必要でした

于 2016-01-19T20:28:28.047 に答える
0

テクスチャ座標を 2 のように見えるのではなく、4 つのコンポーネントとして宣言しています。それ以外の場合、コードは正常に見えます。

于 2012-07-16T16:02:11.077 に答える