OpenGL不在C++中绘制三角形

Posted

技术标签:

【中文标题】OpenGL不在C++中绘制三角形【英文标题】:OpenGL not drawing triangle in C++ 【发布时间】:2021-01-06 05:22:54 【问题描述】:

我正在学习 C++ 中的 openGL,并且已经到了可以绘制三角形的地步。 我决定将三角形的创建放到一个类中,这样所有的代码就不仅仅在一个文件中,现在当我执行绘图函数时,什么也没有发生。我已经查看了这段代码一段时间了,现在我无法弄清楚为什么会发生这种情况。

程序不会崩溃,它只是绘制黑色背景。 OpenGL 也不会返回任何错误。

这是我的主要功能:

int main(int argc, char* args[])
    GLrenderer renderer;
    setRendererSettings(&renderer);
    renderer.init();

    //triangle tri = createTriangle();
    //compileShaders();

    glslShader triangle("VertexShader.glsl", "FragShader.glsl");
    std::vector<GLfloat> vertices = 
        -1.0f, -1.0f, 0.0f,
        -1.0f, 1.0f, 0.0f,
        1.0f, -1.0f, 0.0f
    ;
    triangle.createShape(vertices);
    triangle.compileShaders();

    while(renderer.shouldRun())
        input(&renderer);

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

        triangle.draw();

        renderer.swapBuffers();
    
    renderer.destroy();
    return 0;

这是我的 GLrenderer 标题

class GLrenderer 
private:
    SDL_Window* window;
    SDL_GLContext GLcontext;
    bool isRunning = false;
    bool initSDL();
    bool initGL();
public:
    GLrenderer();
    int width = 1, height = 1;
    int winX = 0, winY = 0;
    int versionMajor = 3, versionMinor = 3;
    const char* title = "OpenGL window";
    Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN;
    bool init();
    bool shouldRun();
    void setShouldRun(bool value);
    void destroy();
    void swapBuffers();
    SDL_Window* getWindow();
;

GLrenderer 的来源

GLrenderer::GLrenderer() 

bool GLrenderer::init()
    if(!initSDL()) return false;
    if(!initGL()) return false;
    isRunning = true;
    return true;


bool GLrenderer::initSDL()
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0)
        printf("Failed to init SDL.\n");
        return false;
    
    window = SDL_CreateWindow(
        title,
        winX, winY,
        width, height,
        flags
    );

    if(window == NULL)
        printf("Failed to create SDL_Window.\n");
        return false;
    

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, versionMajor);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, versionMinor);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    GLcontext = SDL_GL_CreateContext(window);

    if(!GLcontext)
        printf("Failed to create OpenGl context.\n");
        return false;
    

    SDL_GL_MakeCurrent(window, GLcontext);

    return true;


bool GLrenderer::initGL()
    glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK)
        printf("Failed to init glew.\n");
        return false;
    
    return true;


bool GLrenderer::shouldRun()
    return isRunning;


void GLrenderer::setShouldRun(bool value)
    isRunning = value;


void GLrenderer::destroy()
    SDL_DestroyWindow(window);
    SDL_GL_DeleteContext(GLcontext);
    SDL_Quit();


SDL_Window* GLrenderer::getWindow()
    return window;


void GLrenderer::swapBuffers()
    SDL_GL_SwapWindow(window);

我用来创建三角形的班级的标题

class glslShader;
std::string readShader(std::string file);

class glslShader 
private:
    GLuint ShaderProgram, VAO, VBO;
    std::string vertexFile, fragFile;
public:
    glslShader(std::string _vertexFile, std::string _fragFile);
    void createShape(std::vector<GLfloat> vertices);
    bool compileShaders();
    void draw();
;

最后是该标题的来源

bool fileExsists(std::string file)
    std::fstream test(file);
    return test.good();


std::string readShader(std::string file)
    if(!fileExsists(file))
        printf("Not able to locate shader\n");
        return "";
    
    const int maxLine = 130;
    std::string shader = "";
    std::fstream shaderFile(file);
    while(!shaderFile.eof())
        char line[maxLine];
        shaderFile.getline(line, 130);
        shader += line;
        shader += "\n";
    

    return shader;


glslShader::glslShader(std::string _vertexFile, std::string _fragFile) : vertexFile_vertexFile, fragFile_fragFile 

void glslShader::createShape(std::vector<GLfloat> vertices)
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices.data()), vertices.data(), GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);


bool addShader(GLuint program, const char* shaderSRC, GLenum type)
    GLuint shader = glCreateShader(type);

    const GLchar* src[1];
    src[0] = shaderSRC;
    GLint size[1];
    size[0] = strlen(shaderSRC);

    glShaderSource(shader, 1, src, size);

    GLint result = 0;
    GLchar log[1024];

    glCompileShader(shader);

    glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
    if(!result)
        glGetShaderInfoLog(shader, 1024, NULL, log);
        printf("ERROR: Failed to compile shader: &s\n", log);
        return false;
    

    glAttachShader(program, shader);
    return true;


bool glslShader::compileShaders()
    ShaderProgram = glCreateProgram();
    if (!ShaderProgram)
        printf("ERROR: Failed to create shader program.\n");
        return false;
    

    if (!addShader(ShaderProgram, readShader("VertexShader.glsl").c_str(), GL_VERTEX_SHADER))
        printf("ERROR: failed to create vertex shader.\n");
        return false;
    
    if (!addShader(ShaderProgram, readShader("FragShader.glsl").c_str(), GL_FRAGMENT_SHADER))
        printf("ERROR: failed to create fragment shader.\n");
        return false;
    

    GLint result = 0;
    GLchar log[1024];

    glLinkProgram(ShaderProgram);
    glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &result);
    if(!result)
        glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
        printf("ERROR: Failed to link program: %s", log);
        return false;
    

    glValidateProgram(ShaderProgram);
    glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &result);
    if (!result)
        glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
        printf("ERROR: Failed to validate program: %s\n", log);
        return false;
    

    return true;


void glslShader::draw()
    glUseProgram(ShaderProgram);
    glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
    glUseProgram(0);

我确定它不是我的着色器代码,因为我使用的着色器与我在使用类之前用来渲染最后一个三角形的着色器相同。

【问题讨论】:

【参考方案1】:
glBufferData(GL_ARRAY_BUFFER, sizeof(_verticies.data()), _verticies.data(), GL_STATIC_DRAW);

应该是:

glBufferData(GL_ARRAY_BUFFER, _verticies.size() * sizeof(Glfloat), _verticies.data(), GL_STATIC_DRAW);

【讨论】:

应该是_verticies.size() * sizeof(GLfloat)

以上是关于OpenGL不在C++中绘制三角形的主要内容,如果未能解决你的问题,请参考以下文章

无法获得简单的 2D 着色器以在 C++ openGL 中绘制红色三角形(无编译器错误)

使用 PyQt5 和 OpenGL 绘制三角形(重写 Qt C++ 示例)

OpenGL c++ - 出现不需要的黑色三角形

C++ OpenGL/Glut 无法绘制

如何纹理 Opengl glut 对象(C++)

OpenGL:使用退化三角形绘制线