【问题标题】:OpenGL Not Drawing To SDL2 WindowOpenGL 不绘制到 SDL2 窗口
【发布时间】:2024-01-05 15:12:01
【问题描述】:

所以我正在用 C++ 制作游戏,我正在使用 SDL2 和 OpenGL/GLEW。我试图只在我的窗口上绘制基本形状,但是,当它应该绘制一个三角形时,它只是创建了一个黑屏。这是代码。

游戏循环:

int main(int argc, char** argv) {

    Window window("Test", 600, 400);
    RenderingEngine e(window);

    e.Init();

    while (!window.IsCloseRequested()) {
        window.SwapBuffers();
        e.Render();
    }

    return 0;
}

窗口类:

Window::Window(const std::string& title, unsigned int width, unsigned int height) :
    m_title(title), m_width(width), m_height(height), m_isCloseRequested(false) {

    SDL_Init(SDL_INIT_VIDEO);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
        width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    m_glContext = SDL_GL_CreateContext(m_window);
    SDL_GL_MakeCurrent(m_window, m_glContext);

    SDL_GL_SetSwapInterval(1);
    glewExperimental = GL_TRUE;

    GLenum res = glewInit();

    if (res != GLEW_OK) {
        std::cerr << "Error initializting OpenGL." << std::endl;
        exit(1);
    }
}

void Window::SwapBuffers() {
    SDL_GL_SwapWindow(m_window);
}

渲染引擎类:

RenderingEngine::RenderingEngine(const Window& window) : m_window(&window) {

}

RenderingEngine::~RenderingEngine() {
    if (m_window) delete m_window;
}

void RenderingEngine::Init() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    glFrontFace(GL_CW);
    glCullFace(GL_BACK);

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    glDepthFunc(GL_LESS);

    glEnable(GL_FRAMEBUFFER_SRGB);
}

void RenderingEngine::Render() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glColor3f(1.0f, 1.0f, 1.0f);

    glBegin(GL_TRIANGLES);
        glVertex3f(-1.0f, -1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, 0.0f);
        glVertex3f(0.0f, 1.0f, 0.0f);
    glEnd();
}

我无法弄清楚为什么它没有绘制到屏幕上,因此非常感谢任何帮助。谢谢!

【问题讨论】:

    标签: c++ opengl rendering sdl


    【解决方案1】:

    您正在设置背面剔除,指定您的正面三角形具有顺时针缠绕顺序,并且您想要剔除所有不是正面的东西:

    glFrontFace(GL_CW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    

    但是你指定的三角形有逆时针缠绕顺序:

    glVertex3f(-1.0f, -1.0f, 0.0f);
    glVertex3f(1.0f, -1.0f, 0.0f);
    glVertex3f(0.0f, 1.0f, 0.0f);
    

    您可以通过在一张纸上绘制点来验证这一点,x 轴向右,y 轴向上。您会看到点的顺序是围绕原点逆时针排列的。

    基于此,您的三角形被背面剔除消除。由于 OpenGL 更常使用逆时针缠绕顺序,因此我建议通过将 glFrontFace() 调用更改为:

    glFrontFace(GL_CCW);
    

    或者根本不拨打电话,因为这是默认设置。

    【讨论】:

    • 我将剔除更改为逆时针顺序并正确排列了我的顶点,但是绘制时它仍然只是一个黑屏。
    • 不需要改变顶点,它们已经是逆时针的了。
    • 顶点是正确的,逆时针顺序,但屏幕仍然只是黑色。
    【解决方案2】:

    您没有加载视图/投影/模型矩阵...我想这将是一个问题...如果您想以 3.2 样式制作,您应该使用着色器

    【讨论】: