#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <gl/freeglut.h>
// 用于保存传递给GPU的数据的缓冲区对象
GLuint bufferId;
// 用于保存计算结果的缓冲区对象
GLuint resultId;
// 用于保存计算结果的缓冲区对象
float* resultData;
// 用于设置OpenGL和应用程序的初始状态
void init(void)
{
glewInit();
// 创建一个缓冲区对象
glGenBuffers(1, &bufferId);
// 绑定缓冲区对象
glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferId);
// 分配缓冲区大小,并将数据存储在其中
float data[] = { 1.0f, 2.0f, 3.0f, 4.0f };
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
// 解除缓冲区绑定
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// 创建一个缓冲区对象来保存计算结果
glGenBuffers(1, &resultId);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultId);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float), NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// 分配用于保存计算结果的缓冲区的内存
resultData = (float*)malloc(sizeof(float));
}
// 用于绘制场景
void display(void)
{
// 清除缓冲区
glClear(GL_COLOR_BUFFER_BIT);
// 绑定缓冲区对象
glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferId);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bufferId);
// 绑定计算结果缓冲区对象
glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultId);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, resultId);
// 加载计算着色器程序
GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
const GLchar* source =
"#version 430 core\n"
"layout(local_size_x = 1) in;\n"
"layout(std430, binding = 0) buffer InputData {\n"
" float data[4];\n"
"};\n"
"layout(std430, binding = 1) buffer OutputData {\n"
" float result;\n"
"};\n"
"void main() {\n"
" result = data[0] + data[1] + data[2] + data[3];\n"
"}";
glShaderSource(computeShader, 1, &source, NULL);
glCompileShader(computeShader);
// 创建计算着色器程序
GLuint program = glCreateProgram();
glAttachShader(program, computeShader);
glLinkProgram(program);
// 执行计算着色器程序
glUseProgram(program);
glDispatchCompute(1, 1, 1);
// 将计算结果从GPU中读取到主机内存中
glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultId);
float* data = (float*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
*resultData = *data;
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
// 输出计算结果
printf("Result: %f\n", *resultData);
// 删除计算着色器程序
glDeleteShader(computeShader);
glDeleteProgram(program);
// 交换颜色缓冲区
glutSwapBuffers();
}
// 用于清除应用程序使用的资源
void cleanup()
{
// 删除缓冲区对象
glDeleteBuffers(1, &bufferId);
glDeleteBuffers(1, &resultId);
// 释放保存计算结果的缓冲区的内存
free(resultData);
}
// 应用程序入口点
int main(int argc, char** argv)
{
// 初始化GLUT库
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL GPU Compute Example");
// 设置OpenGL状态和回调函数
init();
glutDisplayFunc(display);
glutCloseFunc(cleanup);
// 启动GLUT主循环
glutMainLoop();
return 0;
}
