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

GLFW窗口无内容显示求助:无法绘制点与线条

问题修复方案

问题根源分析

  • 核心模式禁用立即模式:你创建的是OpenGL 3.3核心上下文,glBegin()/glEnd()这类旧版立即模式API在核心模式中已被废弃,无法正常工作,必须使用VAO/VBO配合着色器的现代渲染流程。
  • 图形完全透明:glColor4f的最后一个参数是alpha通道,你设为0.0,导致绘制的图形完全透明,看不到任何内容。
  • 清屏颜色值错误:glClearColor的RGB参数需要是0.0到1.0之间的浮点数,你写的255.0会被自动截断为1.0,虽然结果是白色,但属于错误用法。
  • 绘制坐标太小:你设置的投影范围是窗口全尺寸(0-1024, 0-768),但绘制的顶点坐标只有(0,0,0)和(1,1,1),在窗口里只占极小的区域,即使显示也很难发现。

修正后的完整代码

#define GL_SILENCE_DEPRECATION

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <cstdio>
#include <vector>

GLFWwindow* window;

// 着色器编译辅助函数
GLuint compileShader(GLenum type, const char* source) {
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &source, nullptr);
    glCompileShader(shader);

    GLint success;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(shader, 512, nullptr, infoLog);
        fprintf(stderr, "Shader compilation failed: %s\n", infoLog);
    }
    return shader;
}

int main(int argc, char *argv[]) {
    if (!glfwInit()) {
        fprintf( stderr, "Failed to initialize GLFW\n" );
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    window = glfwCreateWindow(1024, 768, "Test", NULL, NULL);
    if (window == NULL) {
        fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible.\n" );
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW\n");
        glfwTerminate();
        return -1;
    }

    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    // 修正清屏颜色值到0-1范围
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // 顶点着色器代码
    const char* vertexShaderSource = R"(
        #version 330 core
        layout (location = 0) in vec3 aPos;
        layout (location = 1) in vec4 aColor;

        uniform mat4 projection;
        uniform mat4 modelview;

        out vec4 vertexColor;

        void main() {
            gl_Position = projection * modelview * vec4(aPos, 1.0);
            vertexColor = aColor;
            // 设置点大小
            gl_PointSize = 20.0;
        }
    )";

    // 片段着色器代码
    const char* fragmentShaderSource = R"(
        #version 330 core
        in vec4 vertexColor;
        out vec4 FragColor;

        void main() {
            FragColor = vertexColor;
        }
    )";

    // 编译链接着色器程序
    GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
    GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    GLint success;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        fprintf(stderr, "Shader program linking failed: %s\n", infoLog);
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 准备顶点数据:位置 + 颜色
    std::vector<float> vertices = {
        // 点的顶点
        512.0f, 384.0f, 0.0f,   0.0f, 0.0f, 0.4f, 1.0f,
        600.0f, 450.0f, 0.0f,   0.0f, 0.0f, 0.4f, 1.0f,
        // 线的顶点
        200.0f, 200.0f, 0.0f,   0.0f, 0.0f, 0.4f, 1.0f,
        300.0f, 300.0f, 0.0f,   0.0f, 0.0f, 0.4f, 1.0f
    };

    // 创建VAO和VBO
    GLuint VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);

    // 设置顶点位置属性
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // 设置顶点颜色属性
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    // 设置投影和模型视图矩阵
    glm::mat4 projection = glm::ortho(0.0f, 1024.0f, 0.0f, 768.0f, -1.0f, 1.0f);
    glm::mat4 modelview = glm::mat4(1.0f);

    do {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);
        // 传递矩阵 uniforms
        GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
        GLint modelViewLoc = glGetUniformLocation(shaderProgram, "modelview");
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, &projection[0][0]);
        glUniformMatrix4fv(modelViewLoc, 1, GL_FALSE, &modelview[0][0]);

        glBindVertexArray(VAO);
        // 绘制点(前2个顶点)
        glDrawArrays(GL_POINTS, 0, 2);
        // 设置线宽并绘制线(后2个顶点)
        glLineWidth(5.0f);
        glDrawArrays(GL_LINES, 2, 2);

        glfwSwapBuffers(window);
        glfwPollEvents();
    } while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);

    // 清理资源
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);

    glfwTerminate();

    return 0;
}

代码改进说明

  • 采用OpenGL 3.3核心模式支持的现代渲染流程:用VAO/VBO存储顶点数据,配合顶点/片段着色器完成绘制。
  • 修正alpha通道值为1.0,确保图形不透明可见。
  • 调整顶点坐标到窗口中间区域,让绘制的点和线清晰可见。
  • 修正glClearColor参数到0-1的合法范围。
  • 保留了glLineWidth设置,核心模式下该API仍可正常使用(需硬件支持)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:50:24