2

そのため、変換フィードバックで見つけた最も単純な例の 1 つ (ここ) に従い、それを Android/Java に変換していますが、AndroidglGetBufferSubDataには OpenGL ES 3.0 で利用できる機能がないようです。

Android ソースを検索して、JNI で別のメソッドを呼び出すときにこのメソッドが使用されているかどうかを確認しようとしましたが、正しい場所を探しているかどうかさえわかりません。

この関数が存在しない場合、変換フィードバックからデータを読み取るにはどうすればよいですか? 私は見ましたがglGetTransformfeedbackVarying、私が望むことをglGetBufferPointervglReadBufferている人はいません。

これが私のコードです:

import com.harmonicprocesses.penelopefree.openGL.MyGLRenderer;
import android.opengl.GLES30;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

/**
* Created by izzy on 6/24/15.
*/
public class TransformFeedback {


// Vertex shader
private final String vertexShaderSrc =

        "in float inValue;\n" +
        "out float outValue;\n" +

        "void main() {\n" +
        "    outValue = sqrt(inValue);\n" +
        "}\n";

private final int mProgram;


public TransformFeedback{

    // Compile shader
    int vertexShader = MyGLRenderer.loadShader(GLES30.GL_VERTEX_SHADER,
            vertexShaderSrc);

    // Create program and specify transform feedback variables
    mProgram = GLES30.glCreateProgram();
    GLES30.glAttachShader(mProgram, vertexShader);

    //const GLchar* feedbackVaryings[] = { "outValue" };
    GLES30.glTransformFeedbackVaryings(mProgram, 1, {"outValue"}, GLES30.GL_INTERLEAVED_ATTRIBS);

    GLES30.glLinkProgram(mProgram);
    GLES30.glUseProgram(mProgram);

    // Create VAO
    int[] vao = new int[1];
    GLES30.glGenVertexArrays(1, vao, 0);
    GLES30.glBindVertexArray(vao[0]);

    // Create input VBO and vertex format
    int bufferLength = 5 * 4; //5 floats 4 bytes each
    ByteBuffer bb = ByteBuffer.allocateDirect(bufferLength);
    FloatBuffer data = bb.asFloatBuffer();
    float[] floatData = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
    data.put(floatData);
    data.position(0);


    int[] vbo = new int[1];
    GLES30.glGenBuffers(1, vbo, 0);
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0]);
    GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, bufferLength, data, GLES30.GL_STATIC_DRAW);

    int inputAttrib = GLES30.glGetAttribLocation(mProgram, "inValue");
    GLES30.glEnableVertexAttribArray(inputAttrib);
    GLES30.glVertexAttribPointer(inputAttrib, 1, GLES30.GL_FLOAT, false, 0, 0);

    // Create transform feedback buffer
    int[] tbo = new int[1];
    GLES30.glGenBuffers(1, tbo, 0);
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, tbo[0]);
    GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, bufferLength, null, GLES30.GL_STATIC_READ);

    // Perform feedback transform
    GLES30.glEnable(GLES30.GL_RASTERIZER_DISCARD);

    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]);

    GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);
    GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 5);
    GLES30.glEndTransformFeedback();

    GLES30.glDisable(GLES30.GL_RASTERIZER_DISCARD);

    GLES30.glFlush();

    // Fetch and print results
    float feedback[] = new float[5];
    GLES30.glGetBufferSubData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, bufferLength, feedback);

    Log.e("TransformFeedback", String.format("%f %f %f %f %f\n", feedback[0], feedback[1], feedback[2], feedback[3], feedback[4]));

}

私の最終的な実装では、必ずしもデータを読み取る必要はありません。次のパス (フィードバック) でシェーダーで使用するだけです。しかし、これは本当に最初のステップです。

4

1 に答える 1

2

glGetBufferSubData()ES 3.0 や ES 3.1 では利用できません。したがって、この場合、Android Java バインディングに欠けているものはありません。

ES 3.0 でバッファ データを読み戻すために使用する関数はglMapBufferRange()です。C/C++ バインディングでは、バッファの内容を含む CPU 可読メモリへのポインタを返します。glUnmapBuffer()読み終わったら、忘れずに電話してください。

Android Java バインディングでは、関数は type のオブジェクトを返しますBuffer。バッファから直接読み取ることはできないため、ByteBuffer最初にキャストする必要があります。これは実際には文書化されていませんが、ここでの私の答えは、この型キャストが安全であると私が信じる理由を説明しています: Android/Java での glMapBufferRange() の安全な使用

于 2015-06-26T03:26:13.343 に答える