简单的OpenGL三角函数不会在屏幕上绘制任何内容

yks3o0rb  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(165)

我刚刚开始使用OpenGL,已经遇到了一个相当令人沮丧的错误。我遵循了learnopengl教程,将大多数内容封装到一个渲染器类中,该类包含缓冲区等元素。下面是执行所有操作的主要代码:


# include <gfx/gfx.h>

# include <gfx/gl.h>

# include <gfx/shaders.h>

# include <iostream>

void Renderer::init() {

    vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader_id, 1, &vertex_shader, nullptr);
    glCompileShader(vertex_shader_id);

    GLint vertex_shader_status;
    glGetShaderiv(vertex_shader_id, GL_COMPILE_STATUS, &vertex_shader_status);

    if (vertex_shader_status == false) {
        std::cout << "vsh compilation failed due to";
        char vertex_fail_info_log[1024];
        glGetShaderInfoLog(vertex_shader_id, 1024, nullptr, vertex_fail_info_log);
        std::cout << vertex_fail_info_log << std::endl;
        abort();
    }

    fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader_id, 1, &fragment_shader, nullptr);
    glCompileShader(fragment_shader_id);

    GLint fragment_shader_status;
    glGetShaderiv(fragment_shader_id, GL_COMPILE_STATUS, &fragment_shader_status);

    if (fragment_shader_status == false) {
        std::cout << "fsh compilation failed due to";
        char fragment_fail_info_log[1024];
        glGetShaderInfoLog(fragment_shader_id, 1024, nullptr, fragment_fail_info_log);
        std::cout << fragment_fail_info_log << std::endl;
        abort();
    }

    shader_program = glCreateProgram();
    glAttachShader(shader_program, vertex_shader_id);
    glAttachShader(shader_program, fragment_shader_id);
    glLinkProgram(shader_program);

    GLint shader_program_status;
    glGetProgramiv(shader_program, GL_LINK_STATUS, &shader_program_status);

    if (shader_program_status == false) {
        std::cout << "shprogram compilation failed due to";
        char shader_program_fail_info_log[1024];
        glGetShaderInfoLog(shader_program, 1024, nullptr, shader_program_fail_info_log);
        std::cout << shader_program_fail_info_log << std::endl;
        abort();
    }

    glUseProgram(shader_program);

    glDeleteShader(vertex_shader_id);
    glDeleteShader(fragment_shader_id);

}

void Renderer::draw(f32 verts[]) {

    glUseProgram(shader_program);

    glClearColor(1, 0, 0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glCreateVertexArrays(1, &vertex_array);
    glBindVertexArray(vertex_array);

    glCreateBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(f32), (void*)0);
    glEnableVertexAttribArray(0);

    glBindVertexArray(vertex_array);
    glUseProgram(shader_program);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

以下是shaders.h:


# ifndef SHADERS_H

# define SHADERS_H

const char* vertex_shader =
"#version 460 coren"
"layout (location = 0) in vec3 aPos;n"

"void main() {n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);n"
"}n0";

const char* fragment_shader =
"#version 460 coren"
"out vec4 FragColor;n"

"void main() {n"
"FragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);n"
"}n0";

# endif

我一辈子也搞不清楚自己到底出了什么问题。红色清晰的颜色出现了,但没有其他颜色。

jqjz2hbq

jqjz2hbq1#

看起来你的绘制方法有问题。签名是void Renderer::draw(f32 verts[]) {,然后调用glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);。问题是,当您将一个数组传递给一个函数时,它会衰减为一个指针(尽管声明可能会让它看起来像没有发生,这非常令人困惑)。因此,在函数参数中,draw(f32 verts[])等同于draw(f32* verts)This question对那里正在发生的事情有一些解释。

无论如何,当您调用sizeof(verts)时,您只获得浮点指针的字节数,而不是verts拥有的字节数。因此,当您调用glBufferData()来创建要创建的三角形时,您将没有指定足够的字节。简单的解决方法是将一个长度传递到您的DRAW函数中,然后您将得到类似于

void Renderer::draw(f32* verts, int length) {
        //...
        glBufferData(GL_ARRAY_BUFFER, sizeof(float) * length, verts, GL_STATIC_DRAW);
        //...
    }

Here是关于此特定函数的一些文档。可能还有其他错误,但由于您没有进行黑屏,并且代码通常看起来是正确的,所以不太可能有一堆无效操作或任何东西。

要在此之后继续调试,请将以下代码添加到代码中


# define GL_ERROR_CHECK() (log_error(__FILE__, __LINE__))

void log_error(const* file, int line) {
    GLenum err;
    while((err = glGetError()) != GL_NO_ERROR) {
        std::cout << "GL error " << err << " in " << file << "at line " << line << std::endl;
    }
}

并将GL_ERROR_CHECK()撒得到处都是,以查看是否有任何OpenGL调用无效。

相关问题