数日後、計算シェーダとバッファに苦労しました。私は、 "The OpenGL redbook 8th edition"やスレッド "OpenGL vertices in shader storage buffer"、 "OpenGL Compute Shader SSBO"のような使い方の例をいくつか見てきましたが、これはうまくいかないようです。OpenGL:SSBOに保存されている計算シェーダで生成された頂点を描画できません
私は、計算シェーダを呼び出すことによって頂点を生成し、生成した頂点をSSBOに保存し、これらの頂点を頂点シェーダに渡し、残りの部分を通過させることによって、パイプラインは単一の固定画像を作成します。この場合、これは単なるラインです。ただし、プログラムをコンパイルした後は、(0,0)のドットだけが表示されます。
コンピュートシェーダ:
#version 430 core
layout(std430, binding = 0) buffer data
{
float coordinate_array[200][3];
};
layout(local_size_x=20, local_size_y=1, local_size_z=1) in;
void main(void)
{
uint x = gl_GlobalInvocationID.x;
if(x%2 == 0)
{
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = -.5;
coordinate_array[x][0] = 0;
}
else
{
coordinate_array[x][0] = .5;
coordinate_array[x][0] = .5;
coordinate_array[x][0] = 0;
}
}
プログラム:
char *source;
GLuint vertexShader, fragmentShader, computeShader;
GLuint program, computeShaderProgram;
GLuint computeShaderBuffer;
numVertices = 200;
dimension = 3;
size = sizeof(float**)*numVertices*dimension;
//Create the buffer the compute shader will write to
glGenBuffers(1, &computeShaderBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, computeShaderBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, computeShaderBuffer);
//Create the compute shader
computeShader = glCreateShader(GL_COMPUTE_SHADER);
source = getSource(computeShaderSrc);
glShaderSource(computeShader, 1, &source, NULL);
glCompileShader(computeShader);
//Create and dispatch the compute shader program
computeShaderProgram = glCreateProgram();
glAttachShader(computeShaderProgram, computeShader);
glLinkProgram(computeShaderProgram);
glUseProgram(computeShaderProgram);
glDispatchCompute(numVertices/20, 1, 1);
//Generate the vertex array object
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Use buffer as a set of vertices
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, computeShaderBuffer);
//Create the vertex shader
vertexShader = glCreateShader(GL_VERTEX_SHADER);
source = getSource(vertexShaderSource);
glShaderSource(vertexShader, 1, &source, NULL);
//Create the fragment shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
source = getSource(fragmentShaderSource);
glShaderSource(fragmentShader, 1, &source, NULL);
glCompileShader(fragmentShader);
//Create the program to draw
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program);
//Enable the vertex array
glVertexAttribPointer(0, dimension, GL_FLOAT, 0, 0, (void*)0);
glEnableVertexAttribArray(0);
//Draw it
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_POINTS, 0, numVertices);
glFlush();
バーテックスシェーダ:
#version 430 core
layout(location = 0) in vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
このサンプルでは、私が保持するSSBOを使用しよう線の2つの端点セグメント(-.5、-.5)(.5、.5)。シェーダストレージバッファは、このセグメントを1回ではなく100回保持します。私は会議出席していない最低の派遣があると思った。
glGetError(program)またはglGetError(computeShaderProgram)を呼び出すと、GL_NO_ERRORが返されます。また、シェーダは正常にコンパイルされ、両方のプログラムがエラーなくリンクされます。ただし、何らかの理由で計算シェーダに拡張子420packが必要であると私に警告しています。 #extension ARB_420pack(正確な文章ではない)を使用したとき、警告を取り除いていませんでした。私のドライバは最新のもので、私はRadeon R9 270x(OpenGL 4.4)を持っています。 MinGWとCを使ってこのプログラムを作成していますが、C++をいくつか知っています。
誰かが私が間違っていることに関するアイデアはありますか?
うん、そうだった。どうもありがとうございます。 – user3739358