我编写了非常简单的程序来从计算着色器中获取值并将其直接渲染到屏幕上。
我怀疑在调用所有必要的计算着色器方法后着色器存储缓冲区没有绑定到我的 vbo。
我正在分享代码,请查看是否有错误。我没有得到任何编译错误,而且我使用的设备也支持我检查过的 gl 3.1。
除了所有这些,我们还必须在清单中提及任何内容吗?
这是我的渲染器代码
public class MyRenderer implements Renderer{
Context context;
int ProgramId;
int ComputeShaderProgramId;
int aPositionLocation;
int aColorLocation;
int radiusLocation;
int gIndexBufferBinding;
float rad=0;
int[] vbo = new int[1];
int NUM_VERTS_H = 16;
int NUM_VERTS_V = 16;
int GROUP_SIZE_WIDTH = 8;
int GROUP_SIZE_HEIGHT = 8;
MyRenderer(Context context)
{
this.context = context;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES31.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
String VetrexShaderSource = ShaderHelper.readFile(context, R.raw.vertexshader);
String FragmentShaderSource = ShaderHelper.readFile(context, R.raw.fragmentshader);
String ComputeShaderSource = ShaderHelper.readFile(context, R.raw.hellocompute);
int vertexShader = ShaderHelper.compileShader(VetrexShaderSource,GLES31.GL_VERTEX_SHADER);
int fragmentShader = ShaderHelper.compileShader(FragmentShaderSource,GLES31.GL_FRAGMENT_SHADER);
int computeShader = ShaderHelper.compileShader(ComputeShaderSource,GLES31.GL_COMPUTE_SHADER);
ProgramId = ShaderHelper.createShaderProgram(vertexShader, fragmentShader);
GLES31.glUseProgram(ProgramId);
aPositionLocation = GLES31.glGetAttribLocation(ProgramId, "a_Position");
aColorLocation = GLES31.glGetAttribLocation(ProgramId, "aColorCoordinate");
ComputeShaderProgramId = ShaderHelper.createComputeShaderProgram(computeShader);
GLES31.glUseProgram(ComputeShaderProgramId);
gIndexBufferBinding = 1;
GLES31.glGenBuffers(1, vbo,0);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT);
GLES31.glUseProgram(ComputeShaderProgramId);
GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, gIndexBufferBinding, vbo[0]);
// GLES31.glDispatchCompute(
// (NUM_VERTS_H % GROUP_SIZE_WIDTH + NUM_VERTS_H) / GROUP_SIZE_WIDTH,
// (NUM_VERTS_V % GROUP_SIZE_HEIGHT + NUM_VERTS_V) / GROUP_SIZE_HEIGHT,
// 1);
GLES31.glDispatchCompute(2,1,1);
GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, gIndexBufferBinding, 0);
GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT);
System.out.println("error "+GLES31.glGetError());
// Bind VBO
GLES31.glBindBuffer( GLES31.GL_ARRAY_BUFFER, vbo[0] );
// Bind Vertex and Fragment rendering shaders
GLES31.glUseProgram(ProgramId);
GLES31.glEnableVertexAttribArray(aPositionLocation);
// Draw points from VBO
GLES31.glDrawArrays(GLES31.GL_POINTS, 0, 6);
}
}
这是我的计算着色器(hellocompute)
#version 310 es
layout (local_size_x = 3) in;
layout (std430, binding = 1) buffer Output
{
float data[];
} outBuffer;
void main()
{
uint ident = gl_GlobalInvocationID.x;
outBuffer.data[ident] = float(ident)*0.2;
memoryBarrierShared();
barrier();
}
这是我的顶点着色器
attribute float a_Position;
void main()
{
gl_PointSize = 15.0;
gl_Position = vec4(a_Position,0.0,0.0,1.0);
}
这是我的片段着色器
precision mediump float;
void main()
{
//gl_FragColor = vColorCoordinate;
gl_FragColor = vec4(1.0,1.0,0.0,1.0);
}
我应该在 x = 0.2、0.4、0.6、0.8、1.0 处看到一些黄点
但是在 x=0 处只看到一个点,因为它采用了属性 a_Position 的默认零值。
新值应在调度调用后绑定到 vbo 时反映出来。