无法为 GPGPU 执行 OpenGL 计算

问题描述 投票:0回答:0

我尝试基于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
c++ opengl glsl glfw gpgpu
© www.soinside.com 2019 - 2024. All rights reserved.