1、向量加法

// main.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <iostream>
#include <fstream>

// 着色器源码加载函数
std::string loadShaderSource(const char* filePath) {
	std::ifstream shaderFile(filePath);
	if (!shaderFile) {
		std::cerr << "无法打开着色器文件:" << filePath << std::endl;
		exit(EXIT_FAILURE);
	}
	return std::string(std::istreambuf_iterator<char>(shaderFile), std::istreambuf_iterator<char>());
}

int main() {
	// 初始化 GLFW
	if (!glfwInit()) {
		std::cerr << "无法初始化 GLFW" << std::endl;
		exit(EXIT_FAILURE);
	}

	// 创建隐藏窗口
	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
	GLFWwindow* window = glfwCreateWindow(640, 480, "Compute", NULL, NULL);
	if (!window) {
		std::cerr << "无法创建 GLFW 窗口" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}
	glfwMakeContextCurrent(window);

	// 初始化 GLEW
	glewExperimental = GL_TRUE;
	if (glewInit() != GLEW_OK) {
		std::cerr << "无法初始化 GLEW" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	// 准备数据
	const int dataSize = 1024;
	std::vector<float> vecA(dataSize, 1.0f); // 初始化为 1.0
	std::vector<float> vecB(dataSize, 2.0f); // 初始化为 2.0

	// 创建并绑定缓冲对象
	GLuint bufferA, bufferB, bufferResult;
	glGenBuffers(1, &bufferA);
	glBindBuffer(GL_ARRAY_BUFFER, bufferA);
	glBufferData(GL_ARRAY_BUFFER, vecA.size() * sizeof(float), vecA.data(), GL_STATIC_DRAW);

	glGenBuffers(1, &bufferB);
	glBindBuffer(GL_ARRAY_BUFFER, bufferB);
	glBufferData(GL_ARRAY_BUFFER, vecB.size() * sizeof(float), vecB.data(), GL_STATIC_DRAW);

	// 用于存储结果的缓冲区
	glGenBuffers(1, &bufferResult);
	glBindBuffer(GL_ARRAY_BUFFER, bufferResult);
	glBufferData(GL_ARRAY_BUFFER, vecA.size() * sizeof(float), nullptr, GL_STATIC_READ);

	// 编写并编译顶点着色器
	std::string vertexShaderSource = loadShaderSource("vertex_shader.glsl");
	const char* vertexShaderCode = vertexShaderSource.c_str();

	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
	glCompileShader(vertexShader);

	// 检查编译错误
	GLint success;
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cerr << "顶点着色器编译失败:" << infoLog << std::endl;
	}

	// 创建程序并链接
	GLuint program = glCreateProgram();
	glAttachShader(program, vertexShader);

	const GLchar* feedbackVaryings[] = { "outValue" };
	glTransformFeedbackVaryings(program, 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(program);

	// 检查链接错误
	glGetProgramiv(program, GL_LINK_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetProgramInfoLog(program, 512, NULL, infoLog);
		std::cerr << "程序链接失败:" << infoLog << std::endl;
	}

	//设置 顶点数组对象
	GLuint vao;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, bufferA);
	glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, nullptr);

	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER, bufferB);
	glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, nullptr);

	//执行Transform Feedback
	glUseProgram(program);
	glBindVertexArray(vao);

	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bufferResult);

	glEnable(GL_RASTERIZER_DISCARD);//禁用光栅化 

	glBeginTransformFeedback(GL_POINTS);
	glDrawArrays(GL_POINTS, 0, dataSize);
	glEndTransformFeedback();

	glDisable(GL_RASTERIZER_DISCARD);

	//读取结果
	std::vector<float> result(dataSize);
	glBindBuffer(GL_ARRAY_BUFFER, bufferResult);
	glGetBufferSubData(GL_ARRAY_BUFFER, 0, result.size() * sizeof(float), result.data());

	//打印部分结果
	for (int i = 0; i < result.size(); i++) {
		std::cout << "result:" << result[i] << std::endl;
	}

	//清理资源
	glDeleteBuffers(1, &bufferA);
	glDeleteBuffers(1, &bufferB);
	glDeleteBuffers(1, &bufferResult);
	glDeleteVertexArrays(1, &vao);
	glDeleteProgram(program);
	glDeleteShader(vertexShader);

	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;


}
// vertex_shader.glsl
#version 330 core
layout(location = 0) in float inValueA;
layout(location = 1) in float inValueB;
out float outValue;

void main() {
    outValue = inValueA + inValueB;
}

2、 矩阵乘法

#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include <vector>
#include <iostream>
#include <fstream>

//着色器编码加载函数
std::string loadShaderSource(const char* filePath) {
	std::ifstream shaderFile(filePath);
	if (!shaderFile) {
		std::cerr << "无法打开着色器文件:" << filePath << std::endl;
		exit(EXIT_FAILURE);
	}

	return std::string(std::istreambuf_iterator<char>(shaderFile), std::istreambuf_iterator<char>());
}

int main() {
	//初始化glfw
	if (!glfwInit()) {
		std::cerr << "无法初始化glfw" << std::endl;
		exit(EXIT_FAILURE);
	}

	//创建隐藏窗口
	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
	GLFWwindow* window = glfwCreateWindow(611, 111, "Matrix Multiply", NULL, NULL);

	if (!window) {
		std::cerr << "无法创建GLFW 窗口" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}
	glfwMakeContextCurrent(window);

	//初始化glew
	glewExperimental = GL_TRUE;
	if (glewInit() != GLEW_OK) {
		std::cerr << "无法初始化 GLEW" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//准备数据
	const int N = 4;//4*4
	std::vector<float> matA(N * N, 1.0f);
	std::vector<float> matB(N * N, 2.0f);

	//创建并绑定缓冲对象
	GLuint bufferA, bufferB, bufferResult;
	glGenBuffers(1, &bufferA);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferA);
	glBufferData(GL_SHADER_STORAGE_BUFFER, matA.size() * sizeof(float), matA.data(), GL_STATIC_DRAW);

	glGenBuffers(1, &bufferB);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferB);
	glBufferData(GL_SHADER_STORAGE_BUFFER, matB.size() * sizeof(float), matB.data(), GL_STATIC_DRAW);


	//用于存储结果的缓冲区
	glGenBuffers(1, &bufferResult);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferResult);
	glBufferData(GL_SHADER_STORAGE_BUFFER, matA.size() * sizeof(float), nullptr, GL_STATIC_DRAW);

	//编写着色器 计算
	std::string computeShaderSource = loadShaderSource("compute_shader.glsl");
	const char* computeShaderCode = computeShaderSource.c_str();

	GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
	glShaderSource(computeShader, 1, &computeShaderCode, NULL);
	glCompileShader(computeShader);

	// 检查编译错误
	GLint success;
	glGetShaderiv(computeShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetShaderInfoLog(computeShader, 512, NULL, infoLog);
		std::cerr << "计算着色器编译失败:" << infoLog << std::endl;
	}

	//创建程序并链接
	GLuint program = glCreateProgram();
	glAttachShader(program, computeShader);
	glLinkProgram(program);

	// 检查链接错误
	glGetProgramiv(program, GL_LINK_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetProgramInfoLog(program, 512, NULL, infoLog);
		std::cerr << "程序链接失败:" << infoLog << std::endl;
	}

	//绑定缓冲区
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bufferA);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bufferB);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bufferResult);

	//执行计算
	glUseProgram(program);
	glDispatchCompute((GLuint)N, (GLuint)N, 1);
	glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

	//读取结果
	std::vector<float> result(N * N);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferResult);
	glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, result.size() * sizeof(float), result.data());

	std::cout << "结果矩阵:" << std::endl;
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			std::cout << result[i * N + j] << " ";
		}
		std::cout << std::endl;
	}

	// 清理资源
	glDeleteBuffers(1, &bufferA);
	glDeleteBuffers(1, &bufferB);
	glDeleteBuffers(1, &bufferResult);
	glDeleteProgram(program);
	glDeleteShader(computeShader);

	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;

}
// compute_shader.glsl
#version 430 core
layout(local_size_x = 1, local_size_y = 1) in;

const uint N = 4;

layout(std430, binding = 0) readonly buffer MatA {
    float elements[];
} matA;

layout(std430, binding = 1) readonly buffer MatB {
    float elements[];
} matB;

layout(std430, binding = 2) writeonly buffer MatResult {
    float elements[];
} result;

void main() {
    uint row = gl_GlobalInvocationID.x;
    uint col = gl_GlobalInvocationID.y;

    if (row < N && col < N) {
        float sum = 0.0;
        for (uint k = 0; k < N; ++k) {
            sum += matA.elements[row * N + k] * matB.elements[k * N + col];
        }
        result.elements[row * N + col] = sum;
    }
}

3、图像处理(高斯模糊)

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define _CRT_SECURE_NO_WARNINGS
#include "stb_image.h"
#include "stb_image_write.h"

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <iostream>
#include <fstream>

// 着色器源码加载函数
std::string loadShaderSource(const char* filePath) {
	std::ifstream shaderFile(filePath);
	if (!shaderFile) {
		std::cerr << "无法打开着色器文件:" << filePath << std::endl;
		exit(EXIT_FAILURE);
	}
	return std::string(std::istreambuf_iterator<char>(shaderFile), std::istreambuf_iterator<char>());
}


int main() {
	//初始化GLFW
	if (!glfwInit()) {
		std::cerr << "无法初始化 GLFW" << std::endl;
		exit(EXIT_FAILURE);
	}

	//创建隐藏窗口
	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
	GLFWwindow* window = glfwCreateWindow(232, 12, "gaussian blur", NULL, NULL);
	if (!window) {
		std::cerr << "无法创建GLFW窗口" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}
	glfwMakeContextCurrent(window);

	//初始化GLEW 
	glewExperimental = GL_TRUE;
	if (glewInit() != GLEW_OK) {
		std::cerr << "无法初始化 GLEW" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//加载图像
	int width, height, channels;
	unsigned char* imageData = stbi_load("input.jpg", &width, &height, &channels, 4);
	if (!imageData) {
		std::cerr << "无法加载图像" << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//创建输入纹理
	GLuint inputImage;
	glGenTextures(1, &inputImage);
	glBindTexture(GL_TEXTURE_2D, inputImage);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

	//创建输出纹理
	GLuint outputImage;
	glGenTextures(1, &outputImage);
	glBindTexture(GL_TEXTURE_2D, outputImage);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);

	stbi_image_free(imageData);

	//编写并编译计算着色器
	std::string computeShaderSource = loadShaderSource("gaussian_blur.glsl");
	const char* computeShaderCode = computeShaderSource.c_str();

	GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
	glShaderSource(computeShader, 1, &computeShaderCode, NULL);
	glCompileShader(computeShader);

	// 检查编译错误
	GLint success;
	glGetShaderiv(computeShader, GL_COMPILE_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetShaderInfoLog(computeShader, 512, NULL, infoLog);
		std::cerr << "计算着色器编译失败:" << infoLog << std::endl;
	}


	//创建程序并链接
	GLuint program = glCreateProgram();
	glAttachShader(program, computeShader);
	glLinkProgram(program);


	// 检查链接错误
	glGetProgramiv(program, GL_LINK_STATUS, &success);
	if (!success) {
		char infoLog[512];
		glGetProgramInfoLog(program, 512, NULL, infoLog);
		std::cerr << "程序链接失败:" << infoLog << std::endl;
	}


	//绑定图像单元
	glUseProgram(program);
	glBindImageTexture(0, inputImage, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
	glBindImageTexture(1, outputImage, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

	//执行计算
	glDispatchCompute((GLuint)ceil(width / 16.0), (GLuint)ceil(height / 16.0), 1);
	glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

	//读取结果并保存图像
	unsigned char* resultData = new unsigned char[width * height * 4];
	glBindTexture(GL_TEXTURE_2D, outputImage);
	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, resultData);

	if (!stbi_write_png("output.png", width, height, 4, resultData, width * 4)) {
		std::cerr << "无法保存图像" << std::endl;
	}
	else {
		std::cout << "图像已保存为 output.png" << std::endl;
	}

	delete[] resultData;

	// 清理资源
	glDeleteTextures(1, &inputImage);
	glDeleteTextures(1, &outputImage);
	glDeleteProgram(program);
	glDeleteShader(computeShader);

	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;

}
// gaussian_blur.glsl
#version 430 core
layout(local_size_x = 16, local_size_y = 16) in;

layout(binding = 0, rgba8) uniform readonly image2D inputImage;
layout(binding = 1, rgba8) uniform writeonly image2D outputImage;

const float kernel[9] = float[](
    1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0,
    2.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0,
    1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0
);

void main() {
    ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
    ivec2 size = imageSize(inputImage);
    vec4 color = vec4(0.0);

    for (int i = -1; i <= 1; ++i) {
        for (int j = -1; j <= 1; ++j) {
            ivec2 coord = pos + ivec2(i, j);
            // 边界检测
            coord = clamp(coord, ivec2(0), size - ivec2(1));
            vec4 pixel = imageLoad(inputImage, coord);
            float weight = kernel[(i + 1) * 3 + (j + 1)];
            color += pixel * weight;
        }
    }

    imageStore(outputImage, pos, color);
}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐