You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL GLFW无法渲染图形:GL_QUADS绘制正方形无显示问题排查

问题原因与解决方案

你的代码黑屏的核心原因是:你初始化的是OpenGL 3.3核心上下文,但代码里用的是早已被核心模式废弃的固定管线API,具体问题点如下:

  • OpenGL 3.2+核心配置移除了glBegin/glEnd这种立即渲染模式,也不再支持glLoadIdentity、glOrtho这类固定管线矩阵操作,这些调用在核心上下文里会被忽略。
  • GL_QUADS图元类型在核心模式中已被移除,即使是兼容模式,新版本OpenGL也推荐用三角形图元(如GL_TRIANGLE_FAN或GL_TRIANGLES)替代。

快速修复方案(兼容模式)

如果只是想验证代码逻辑,把GLFW的上下文配置改成兼容模式即可:
修改这一行:

glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

为:

glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

这样旧的立即模式代码就能正常运行,屏幕上会显示灰色正方形。


推荐方案(现代OpenGL流程)

长期学习建议使用现代OpenGL的VAO/VBO+着色器流程,以下是适配你的需求的完整代码:

#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

const GLint WIDTH = 800, HEIGHT = 600;

// 顶点着色器源码
const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec2 aPos;
    void main() {
        gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
    }
)";

// 片段着色器源码
const char* fragmentShaderSource = R"(
    #version 330 core
    out vec4 FragColor;
    void main() {
        FragColor = vec4(0.5f, 0.5f, 0.5f, 1.0f);
    }
)";

int main() {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Isosurface Stuffing", nullptr, nullptr);
    int screenWidth, screenHeight;
    glfwGetFramebufferSize(window, &screenWidth, &screenHeight);

    if (window == nullptr) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
    if (GLEW_OK != glewInit()) {
        std::cout << "Failed to initialize GLEW" << std::endl;
        return -1;
    }

    // 编译顶点着色器
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);
    // 检查编译错误
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        std::cout << "Vertex shader compile error:\n" << infoLog << std::endl;
    }

    // 编译片段着色器
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
        std::cout << "Fragment shader compile error:\n" << infoLog << std::endl;
    }

    // 链接着色器程序
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cout << "Shader program link error:\n" << infoLog << std::endl;
    }
    // 删除临时着色器对象
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 正方形顶点数据(用两个三角形组成)
    float vertices[] = {
        100.0f/screenWidth*2 -1,  100.0f/screenHeight*2 -1, // 左下角
        200.0f/screenWidth*2 -1,  100.0f/screenHeight*2 -1, // 右下角
        200.0f/screenWidth*2 -1,  200.0f/screenHeight*2 -1, // 右上角
        100.0f/screenWidth*2 -1,  200.0f/screenHeight*2 -1  // 左上角
    };
    // 索引数据(三角列表)
    unsigned int indices[] = {
        0, 1, 2, // 第一个三角形
        0, 2, 3  // 第二个三角形
    };

    GLuint VAO, VBO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // 设置顶点属性指针
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // 解绑(VAO绑定状态下解绑VBO不影响,EBO会存在VAO里)
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        // 用索引绘制6个顶点(两个三角形)
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwPollEvents();
        glfwSwapBuffers(window);
    }

    // 释放资源
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteProgram(shaderProgram);

    glfwTerminate();
    return 0;
}

代码说明:

  • 使用了#version 330 core的着色器,符合核心上下文要求
  • 把窗口坐标转换为OpenGL的标准化设备坐标(NDC),替代了旧的glOrtho矩阵
  • 用GL_TRIANGLES图元配合索引缓冲(EBO)绘制正方形,这是现代OpenGL的标准方式

内容的提问来源于stack exchange,提问作者ronalama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:25:24