问题
UPDATE: This is working and up on gist now! Thanks Reto
I am working on an Android implementation of transform feedback following this example. runs pretty well without any errors, but I am getting all zeros out when reading the TransformFeedback buffer with 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);
}
}
The logcat output looks like this:
D/TransformFeedback﹕ 0.000000 0.000000 0.000000 0.000000 0.000000
according to this question you may cast the returned buffer to a bytebuffer, so I do not believe the casting is the problem. Even if the data is coming out backwards it shouldn't be all zeros if the shader code is computing the transform feedback variable correctly, and I am linking the transform feedback correctly.
回答1:
Figured it out, thanks to Reto on this question. The outputs are actually not zeros. They are floats in reversed byte order, i.e. 4.6006E-41. Simply set the mapped buffer to native order and 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()));
Complete working code is up on gist
来源:https://stackoverflow.com/questions/31095601/glmapbufferrange-returns-all-zeros-in-android-opengles-3-0-using-trasnformfeed