我尝试基于this教程实现OpenGL GPGPU计算。
我现在重新实现代码以使用 VAO、VBO 而不是 glVertex。我创建的代码是计算数组 X 和数组 Y 之间的总和。我将数组 X 和数组 Y 作为纹理传递,并将总和的结果绑定到帧缓冲区以将其读回。然而,结果是错误的,不知道为什么?
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
// https://github.com/JoeyDeVries/LearnOpenGL/blob/master/includes/learnopengl/shader_c.h
#include "shader.h"
const int SCR_WIDTH = 600;
const int SCR_HEIGHT = 600;
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
int texSize = 2;
const int Size = texSize*texSize*4;
float *x = new float[Size];
float *y = new float [Size];
float *result = new float[Size];
float alpha = 1.0/9.0;
for(int i=0;i<Size;i++){
x[i] = i + 1.0;
y[i] = i * 2.0;
}
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
Shader my("com.vs","com.fs");
my.use();
float vertices[] ={
// positions // texture coords
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
};
GLuint vao,vbo;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
(void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),
(void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
glEnable(GL_TEXTURE_2D);
GLuint fbo;
glGenFramebuffers(1,&fbo);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
GLuint textX, textY, res;
glGenTextures(1,&textX);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,textX);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA32F, texSize, texSize, 0,GL_RGBA,GL_FLOAT,x);
glGenTextures(1,&textY);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,textY);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA32F, texSize, texSize, 0,GL_RGBA,GL_FLOAT,y);
glGenTextures(1,&res);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,res);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D,0, GL_RGBA32F, texSize, texSize, 0,GL_RGBA,GL_FLOAT,0);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,res,0);
my.setInt("TexX",0);
my.setInt("TexY",1);
my.setFloat("a",alpha);
glDrawArrays(GL_TRIANGLES,0,6);
glFlush();
glFinish();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels(0, 0, texSize, texSize,GL_RGBA,GL_FLOAT,result);
std::cout<<"Data X Y \n";
for(int i =0; i<Size;i++){
std::cout<<x[i]<<" "<<y[i]<<"\n";
}
std::cout<<"\nRes:\n";
for(int i =0; i<Size; i++){
std::cout<<result[i]<<"\n";
}
glDeleteFramebuffers (1,&fbo);
glDeleteTextures (1,&textX);
glfwTerminate();
return 0;
}
这里是com.vs文件中的顶点代码:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 TexCo;
out vec2 TexCoo;
void main()
{
gl_Position = vec4(aPos, 1.0);
TexCoo = TexCo;
}
这里是com.fs文件中的片段代码:
#version 330 core
uniform sampler2D TexX;
uniform sampler2D TexY;
uniform float a;
out vec4 FragColor;
in vec2 TexCoo;
void main()
{
vec4 x = texture(TexX, TexCoo);
vec4 y = texture(TexY, TexCoo);
FragColor = y + x;
}
这是我收到的结果:
Data X Y
1 0
2 2
3 4
4 6
5 8
6 10
7 12
8 14
9 16
10 18
11 20
12 22
13 24
14 26
15 28
16 30
Res:
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0