更新:现在正在gist开始工作!谢谢Reto
我正在研究this example之后的转换反馈的Android实现。在没有任何错误的情况下运行得很好,但是在使用glMapBufferRange()
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 {
private final String TAG = "TransformFeedback";
// Vertex shader
private final String vertexShaderSrc =
"#version 300 es \n" +
"in float inValue;\n" +
"out float outValue;\n" +
"void main() {\n" +
" outValue = sqrt(inValue);\n" +
"}";
private final String fragmentShaderCode =
"#version 300 es \n" +
"precision mediump float;\n" +
"in float outValue;\n" +
"out vec4 fragColor;\n" +
"void main() {\n" +
" fragColor = vec4(outValue,outValue,outValue,1.0);\n" +
"}";
private final int mProgram;
public TransformFeedback(){
// Compile shader
int vertexShader = MyGLRenderer.loadShader(GLES30.GL_VERTEX_SHADER,
vertexShaderSrc);
int fragmentShader = MyGLRenderer.loadShader(GLES30.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// Create program and specify transform feedback variables
mProgram = GLES30.glCreateProgram();
GLES30.glAttachShader(mProgram, vertexShader);
GLES30.glAttachShader(mProgram, fragmentShader);
final String[] feedbackVaryings = { "outValue" };
GLES30.glTransformFeedbackVaryings(mProgram, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
MyGLRenderer.checkGlError("glTransformFeedbackVaryings");
GLES30.glLinkProgram(mProgram);
int[] linkSuccessful = new int[1];
GLES30.glGetProgramiv(mProgram, GLES30.GL_LINK_STATUS, linkSuccessful, 0);
if (linkSuccessful[0] != 1){
Log.d(TAG, "glLinkProgram failed");
}
MyGLRenderer.checkGlError(TAG + "glLinkProgram");
GLES30.glUseProgram(mProgram);
MyGLRenderer.checkGlError(TAG + "glUseProgram");
// Create VAO
int[] vao = new int[1];
GLES30.glGenVertexArrays(1, vao, 0);
GLES30.glBindVertexArray(vao[0]);
MyGLRenderer.checkGlError(TAG + "glBindVertexArray");
// 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);
MyGLRenderer.checkGlError(TAG + "glBufferDatar");
int inputAttrib = GLES30.glGetAttribLocation(mProgram, "inValue");
GLES30.glEnableVertexAttribArray(inputAttrib);
GLES30.glVertexAttribPointer(inputAttrib, 1, GLES30.GL_FLOAT, false, 0, 0);
MyGLRenderer.checkGlError(TAG + "glVertexAttribPointer");
// 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]);
MyGLRenderer.checkGlError(TAG + "glBindBufferBase");
GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);
GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 5);
GLES30.glEndTransformFeedback();
GLES30.glDisable(GLES30.GL_RASTERIZER_DISCARD);
GLES30.glFlush();
MyGLRenderer.checkGlError(TAG + "pre glMapBufferRange ");
// Fetch and print results
FloatBuffer transformedBuffer = ((ByteBuffer) GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER,
0, bufferLength, GLES30.GL_MAP_READ_BIT)).asFloatBuffer();
MyGLRenderer.checkGlError(TAG + "glMapBufferRange");
transformedBuffer.position(0);
Log.d(TAG, String.format("%f %f %f %f %f\n", transformedBuffer.get(),
transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get(), transformedBuffer.get()));
transformedBuffer.position(0);
}
}
logcat输出如下所示:
D/TransformFeedback﹕ 0.000000 0.000000 0.000000 0.000000 0.000000
根据this question你可以将返回的缓冲区转换为bytebuffer,所以我不相信转换是个问题。即使数据向后出现,如果着色器代码正确地计算变换反馈变量,它也不应该全为零,并且我正确地链接变换反馈。
答案 0 :(得分:2)
通过此Reto上的question计算出来。输出实际上不是零。它们是反向字节顺序的浮点数,即4.6006E-41。只需将映射缓冲区设置为本机顺序和whallah!
ByteBuffer bb = ((ByteBuffer) mappedBuffer);
bb.order(ByteOrder.nativeOrder());
FloatBuffer transformedData = bb.asFloatBuffer();
Log.d(TAG, String.format("output values = %f %f %f %f %f\n", transformedData.get(),
transformedData.get(), transformedData.get(),
transformedData.get(), transformedData.get()));
上有完整的工作代码