opengl的计算着色器的的使用

182 阅读1分钟

通用计算

//被使用计算的数据
float inputData[] = { 0,1,2,3,4,5,6 };
//得到需要计算的元素的个数
int numElements = sizeof(inputData) / sizeof(float);
std::cout << "numElements:" << numElements << std::endl;
// 创建输入缓冲区对象
GLuint inBuffer;
glGenBuffers(1, &inBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, inBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * numElements, inputData, GL_STATIC_DRAW);
// 创建输出缓冲区对象
GLuint outBuffer;
glGenBuffers(1, &outBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, outBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * numElements, NULL, GL_STATIC_DRAW);
//创建着色器和绑定索引点
Glb::ComputeShader* mComputeParticals = new Glb::ComputeShader("ComputeParticals");
std::vector<std::string> computeShaderpaths = {
        std::string("testcomputeShader_01.comp"),
    };
mComputeParticals->BuildFromFiles(computeShaderpaths);
mComputeParticals->Use();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, inBuffer);      //索引点
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, outBuffer);
//准备计算
mComputeParticals->SetFloat("x", 10);
for (int i = 0; i <= 1; i++)
{
    mComputeParticals->SetFloat("pass", i);
    glDispatchCompute(numElements, 1, 1);
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
//读取缓冲区的数据
float* outputData = new float[numElements];
glBindBuffer(GL_SHADER_STORAGE_BUFFER, outBuffer);
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(float) * numElements, outputData);

下面是的着色器代码

#version 430 core
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
// 输入输出缓冲区
layout(std430, binding = 0) buffer InputBuffer {
    float inData[];
};
layout(std430, binding = 1) buffer OutputBuffer {
    float outData[];
};

float a = 1;

uniform float x;

uniform float pass;

void main() {
    // 获取全局索引
    uint index = gl_GlobalInvocationID.x;

    if(pass==0)
    {
         // 检查索引是否在有效范围内
    if (index < inData.length()) 
        {
        // 计算每个元素乘以2
        //outData[index] = inData[index] * x;
        inData[index] = inData[index]*x;
         }
     }

    if(pass==1)
    {
         // 检查索引是否在有效范围内
    if (index < inData.length()) 
        {
        // 计算每个元素乘以2
        outData[index] = inData[index] * x;
         }
    }

}