为什么我的C++程序在使用构造函数时会崩溃

Why does my C++ program crash when using a constructor?

本文关键字:构造函数 崩溃 我的 C++ 程序 为什么      更新时间:2023-10-16

我正在按照"learnopengl.com"教程制作一个简单的OpenGL程序。现在代码应该只显示一个橙色三角形。

我的代码:

屏幕管理器.h

#ifndef SCREEN_MANAGER_H
#define SCREEN_MANAGER_H
#define GLEW_STATIC
#include <GLglew.h>
#include <GLFWglfw3.h>
#include <iostream>
#include "Input.h"
#include "Renderer.h"
class ScreenManager
{
    public:
        ScreenManager(void);
        bool isCloseRequested();
        void render();
        void update();
        void dispose();
        private:
        GLFWwindow* window;
        Renderer renderer;
};
#endif

屏幕管理器.cpp

#include "ScreenManager.h"
ScreenManager::ScreenManager(void)
{
    // Initialize GLFW library
    glfwInit();
    // Specify the opengl version to 3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    // Specify opengl profile to core profile
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    // Disable resizing
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    // Create the window object
    window = glfwCreateWindow(800, 600, "test", nullptr, nullptr);
    // Make the GL context the active context in the thread
    glfwMakeContextCurrent(window);
    // Error check
    if(window==NULL){
        std::cout << "failed to create GLFW window :( " << std::endl;
        dispose();
    }
    // Make sure that GLEW use modern techniques to manage opengl functionality
    glewExperimental = GL_TRUE;
    // Initialize GLEW and check for errors
    if(glewInit() != GLEW_OK){
        std::cout << "failed to initialize glew :( " << std::endl;
    }
    // Specify opengl viewport => bottom left coordinates and window size
    glViewport(0, 0, 800, 600);
    // Register the events for GLFW => currently :keyboard
    Input input(window);
    renderer.init();
}
// Check if window is closed
bool ScreenManager::isCloseRequested(){
    if(glfwWindowShouldClose(window))
        return true;
    return false;
}
// Clear screen and swap buffers
void ScreenManager::render(){
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    renderer.render();
    glfwSwapBuffers(window);
}
// Check for events (registered events)
void ScreenManager::update(){
    glfwPollEvents();
}
void ScreenManager::dispose(){
    glfwTerminate();
}

渲染器.h

#ifndef RENDERER_H
#define RENDERER_H
#define GLEW_STATIC
#include <GLglew.h>
#include <iostream>
class Renderer
{
    public:
        Renderer(void);
        void init();
        void render();
    private:
        void testShape();
        GLuint createVertexShader(GLuint &shader);
        GLuint createFragmentShader(GLuint &shader);
        void createShaderProgram(GLuint &program);
};
#endif

渲染器.cpp

#include "Renderer.h"
GLuint program;
GLuint vertexShader;
GLuint fragmentShader;
GLuint VAO;
Renderer::Renderer(){
    //init();
}
void Renderer::init(){
    testShape();
    createShaderProgram(program);
}
void Renderer::render(){
    glUseProgram(program);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
}
void Renderer::testShape(){
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3* sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(VBO, 0);
    glBindVertexArray(0);
}
GLuint Renderer::createVertexShader(GLuint &shader){
    const GLchar* vertexShaderSource =
        "#version 330 coren"
        "layout (location = 0) in vec3 position;n"
        "void main(){n"
        "    gl_Position = vec4(position.x, position.y, position.z, 1.0);n"
        "}";
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    GLint success;
    GLchar info[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if(!success){
        glGetShaderInfoLog(vertexShader, 512, NULL, info);
        std::cout << "couldn't compile shader :(/n" << info << std::endl;
    }
    return vertexShader;
}
GLuint Renderer::createFragmentShader(GLuint &shader){
    const GLchar* fragmentShaderSource =
        "#version 330 coren"
        "out vec4 color;n"
        "void main(){n"
        "    color = vec4(1.0, 0.5, 0.2, 0);n"
        "}";
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    GLint success;
    GLchar info[512];
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if(!success){
        glGetShaderInfoLog(fragmentShader, 512, NULL, info);
        std::cout << "couldn't compile shader :(n" << info << "n" << std::endl;
    }
    return fragmentShader;
}
void Renderer::createShaderProgram(GLuint &program){
    program = glCreateProgram();
    glAttachShader(program, createVertexShader(vertexShader));
    glAttachShader(program, createFragmentShader(fragmentShader));
    glLinkProgram(program);
    GLint success;
    GLchar info[512];
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if(!success){
        glGetProgramInfoLog(program, 512, NULL, info);
        std::cout << "couldn't link program :(n" << info << "n" << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

好吧,如果我不使用Renderer类构造函数,只使用init()函数,如果我使用构造函数(在取消对init()的注释并对Renderer.init()进行注释之后),程序崩溃,那么代码运行得非常好。

主函数在一个单独的类中,它所做的只是在循环中调用ScreenManager渲染函数。

当您在构造函数中调用init时,它是在构造ScreenManager的成员期间调用的,这发生在执行ScreenManager的构造函数主体之前。

在这一点上,OpenGL还没有初始化,这就是你崩溃的原因。