我的顶点和片段着色器是我在 glfw 中出现黑屏的原因吗? [关闭]

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

我正在用 C++ 编写一个光线行进程序,但我似乎无法让屏幕显示要绘制到屏幕上的结果。我制作了一个正方形并将其作为纹理放在正方形上。我相信这是因为 opengl 方面的问题,而不是我的光线行进的问题。打印距离矢量时,它似乎是正确的。

//graphic_engine.h
struct ray_march_graphics {
public:
    GLuint texture;
    GLuint vao, vbo, ebo;
    std::string fragment_shader;
    std::string vertex_shader;
    unsigned int shader;
    void draw_ray_march(std::vector<float> distances);
    void main();
};
//graphic_engine.cpp
void ray_march_graphics::draw_ray_march(std::vector<float> distances) {
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    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_R32F, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RED, GL_FLOAT, &distances[0]);
    GLfloat vertices[] = {
    -1.0f, -1.0f, 0.0f, 0.0f,
     1.0f, -1.0f, 1.0f, 0.0f,
     1.0f,  1.0f, 1.0f, 1.0f,
    -1.0f,  1.0f, 0.0f, 1.0f
    };
    GLuint indices[] = {
        0, 1, 2,
        2, 3, 0
    };
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(0);

    // draw the quad with the texture mapped onto it
    glBindVertexArray(vao);
    glBindTexture(GL_TEXTURE_2D, texture);

     vertex_shader = R"glsl(
#version 450 core
layout (location = 0) in vec3 position;
layout (location =1) in vec3 texCord;
out vec3 TexCord;
void main(){
gl_Position = vec4(position, 1.0);
TexCord = texCord;
}
)glsl";
    fragment_shader = R"glsl(
#version 450 core
in vec3 TexCord;
out vec4 color;
uniform sampler2D texture;
void main(){

vec4 distance = texture(texture, TexCord.xy);
vec3 color_value = (vec3(1.0f, 1.0f, 1.0f) - distance.rgb);

color = vec4(color_value,1.0f);
}
)glsl";
    shader = create_shader(vertex_shader, fragment_shader);
    glUseProgram(shader);
}
void ray_march_graphics::main() {
    glUseProgram(shader);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    //std::cout << glGetError() << std::endl;
}
static unsigned int create_shader(const std::string& vertex_shader, const std::string& fragment_shader){
    unsigned int program = glCreateProgram();
    unsigned int vs = compile_shader(GL_VERTEX_SHADER, vertex_shader);
    unsigned int fs = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(fs);
    glDeleteShader(vs);
    return program;
    }
static unsigned int compile_shader(unsigned int type, const std::string source) {
    unsigned int id = glCreateShader(GL_VERTEX_SHADER);
    const char* src = source.c_str();//dont let source go out of scope
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);
    if (!result) {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*)malloc(length * sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "failed to compile from the "<<(type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader, try again later" << std::endl;
        std::cout << message << std::endl;
        glDeleteShader(id);
        return 0;
    }
    return id;
}
//main.cpp
class ray_marcher {
public:
    vec3 camera_pos; vec3 camera_dir; float cam_fov; float aspect_ratio;
    ray_marcher(vec3 cam_pos, vec3 cam_dir, float cam_fov) {
        camera_pos = cam_pos;
        camera_dir = cam_dir;
        this->cam_fov = cam_fov;
        aspect_ratio = SCREEN_WIDTH / SCREEN_HEIGHT;
    }
    void march(float min_dist, float max_dist, int max_steps, std::vector<float> dist_storage) {
        float half_height = tan(cam_fov / 2);
        float half_width = aspect_ratio * half_height;
        float pixel_size = (half_height * 2) / SCREEN_HEIGHT;
        vec3 right(0.0f, 1.0f, 0.0f);
        vec3 camera_right = camera_dir.cross(right).normal(); 
        vec3 camera_up = camera_dir.cross(camera_dir).normal();
        for (int x = 0; x < SCREEN_HEIGHT; x++) {
            std::cout << "[*]MARCHING THE RAYS" << std::endl;
            for (int j = 0; j < SCREEN_WIDTH; j++) {
                float y_normal = x/ SCREEN_HEIGHT;
                float x_normal = j / SCREEN_WIDTH;
                //direction of raycast
                vec3 ray_dir = camera_dir + camera_right * (x_normal - 0.5f) * (2.0f * half_width)
                    + camera_up * (y_normal - 0.5f) * (2.0f * half_height);
                float dist = 0;
                int steps = 0;
                while (steps < max_steps && dist < max_dist) {
                    vec3 pos = camera_pos + ray_dir * dist;
                    float sdf = signed_distance_function_tetrahedron_fractal(pos);
                    //float sdf = signed_distance_function_circle(pos, {300,300, 300 }, 200);
                    //std::cout << sdf << std::endl;
                    if (sdf < min_dist) {
                        break;
                    }
                    dist += sdf * 0.5f;
                    steps++;
                    //std::cout << dist << std::endl;
                }
                
                dist_storage[(int)(x * SCREEN_WIDTH + SCREEN_HEIGHT)] = dist;
            }
            system("CLS");
        }
        std::cout << "[*]FINISHED" << std::endl;


    }
    float signed_distance_function_tetrahedron_fractal(vec3 pos) {
        float s = 1.0f;
        for (int i = 0; i < 4; i++) {
            float d = pos.dot_multiply({1.0f, 1.0f, 1.0f}) + s;
            pos = ((pos.mod(s) * 2.0f).minus(s) - vec3(1.0f, 1.0f, 1.0f)).abs();
            s *= 2.0f;
        }
        return pos.magnitude() / powf(2.0f, 4.0f);
    }
    float signed_distance_function_circle(vec3 pos, vec3 center, float radius) {
        return (pos - center).magnitude() - radius;
    }
};
void glfw_init(GLFWwindow* window) {

    glfwMakeContextCurrent(window);
    glEnable(GL_DEPTH_TEST);
    glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT); // specifies the part of the window to which OpenGL will draw (in pixels), convert from normalised to pixels
    glMatrixMode(GL_PROJECTION); // projection matrix defines the properties of the camera that views the objects in the world coordinate frame. Here you typically set the zoom factor, aspect ratio and the near and far clipping planes
    glLoadIdentity(); // replace the current matrix with the identity matrix and starts us a fresh because matrix transforms such as glOrpho and glRotate cumulate, basically puts us at (0, 0, 0)
    glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, -1, 1); // essentially set coordinate system
    glMatrixMode(GL_MODELVIEW); // (default matrix mode) modelview matrix defines how your objects are transformed (meaning translation, rotation and scaling) in your world
    glLoadIdentity(); // same as above comment
}
int main(void)
{
    GLFWwindow* window;
    if (!glfwInit())
    {
        return -1;
    }
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    window = glfwCreateWindow((int)SCREEN_WIDTH, (int)SCREEN_HEIGHT, "Physics Engine", NULL, NULL);
    glfw_init(window);
    glewExperimental = GL_TRUE; // Needed in core profile
    if (!window)
    {
        glfwTerminate();
        return -2;
    }
    if (glewInit() != GLEW_OK) {
        // GLEW initialization failed
        glfwTerminate();
        return -1;
    }
    std::cout << glGetString(GL_VERSION)<<std::endl;

    ray_marcher march({ 0,0,-2 }, { 0,0,1 }, 60.0f);
    std::vector <float> d;
    d.resize(SCREEN_SIZE);
    march.march(0.01f, 100.0f, 50, d);
    std::cout << "test" << std::endl;

    ray_march_graphics graphics;
    graphics.draw_ray_march(d);
    while (!glfwWindowShouldClose(window))
    {
        graphics.main();
        //frame_per_second();
        glfwSetKeyCallback(window, key_callback);
        glfwSwapBuffers(window);
        glfwPollEvents();
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        

    }

    glfwTerminate();
    return 0;
}

我没有从着色器程序中得到任何错误,但是我得到了 1282 opengl 错误,但是我似乎无法诊断它来自哪里。

c++ opengl glfw glew
© www.soinside.com 2019 - 2024. All rights reserved.