2

I am currently learning the Book "Computer Graphics Programming - Using OpenGL and C++". When I test the chapter 2-3, I found the error:

shader program failed to link:
Program Info Log: Vertex info
-----------
(0) : error C5145: must write to gl_Position

It is so wired, since my test glsl code is very simple:

    // 顶点着色器
    const char* vertexShaderSource = "#version 430 \n"
        "void main(void) \n"
        "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
    // 光栅化着色器
    const char* fragmentShaderSource = "#version 430 \n"
        "out vec4 color; \n"
        "void main(void){ \n"
        "if (gl_FragCoord.x < 300) \n"
        "{ color = vec4(0.0, 0.1, 0.9, 1.0); }\n"
        "else { color = vec4(0.0, 0.9, 0.1, 1.0); }}";

following is my full test code:

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

#define numVAOs 1

GLuint renderingProgram;
GLuint vao[numVAOs];

void printShaderLog(GLuint shader) {
    int len = 0;
    int chWrittn = 0;
    char * log;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetShaderInfoLog(shader, len, &chWrittn, log);
        std::cout << "Shader Info Log: " << log << std::endl;
        free(log);
    }
}

void printProgramLog(GLuint program) {
    int len = 0;
    int chWrittn = 0;
    char * log;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetProgramInfoLog(program, len, &chWrittn, log);
        std::cout << "Program Info Log: " << log << std::endl;
        free(log);
    }
}

bool checkOpenGLError() {
    bool foundError = false;
    int glErr = glGetError();
    while (glErr!= GL_NO_ERROR) {
        std::cout << "OpenGL Error: " << glErr << std::endl;
        foundError = true;
        glErr = glGetError();
    }

    return foundError;
}

GLuint createShaderProgram() {
    // 顶点着色器
    const char* vertexShaderSource = "#version 430 \n"
        "void main(void) \n"
        "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
    // 光栅化着色器
    const char* fragmentShaderSource = "#version 430 \n"
        "out vec4 color; \n"
        "void main(void){ \n"
        "if (gl_FragCoord.x < 300) \n"
        "{ color = vec4(0.0, 0.1, 0.9, 1.0); }\n"
        "else { color = vec4(0.0, 0.9, 0.1, 1.0); }}";

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    // 载入着色器的代码
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    // 编译着色器
    glCompileShader(vertexShader);
    // 判断着色器是否编译成功
    checkOpenGLError();
    GLint vertexShaderCompiled;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexShaderCompiled);
    if(vertexShaderCompiled != GL_TRUE) {
        std::cerr << "vertex shader failed to compile" << std::endl;
        printShaderLog(vertexShader);
        exit(EXIT_FAILURE);
    }
    glCompileShader(fragmentShader);
    // 判断着色器是否编译成功
    checkOpenGLError();
    GLint fragmentShaderCompiled;
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled);
    if(fragmentShaderCompiled != GL_TRUE) {
        std::cerr << "fragment shader failed to compile" << std::endl;
        printShaderLog(fragmentShader);
        exit(EXIT_FAILURE);
    }

    GLuint shaderProgram = glCreateProgram();
    // 将着色器加入到程序中
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    // 请求 GLSL 编译器链接着色器
    glLinkProgram(shaderProgram);
    checkOpenGLError();
    GLint programLinked;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked);
    if (programLinked!= GL_TRUE) {
        std::cerr << "shader program failed to link:" << std::endl;
        printProgramLog(shaderProgram);
        exit(EXIT_FAILURE);
    }

    return shaderProgram;
}

void init(GLFWwindow* window) {
    renderingProgram = createShaderProgram();
    // 创建着色器所需要的缓存区
    glGenVertexArrays(numVAOs, vao);
    glBindVertexArray(vao[0]);
}

void display(GLFWwindow* window, double currentTime) {
    glClear(GL_COLOR_BUFFER_BIT);
    // 载入到 OpenGL 管线(GPU 上), 加载到硬件上
    glUseProgram(renderingProgram);
    // 设置点的大小
    glPointSize(60.0f);
    glDrawArrays(GL_POINTS, 0, 1);
}

int main(){
    if(!glfwInit()) {
        exit(EXIT_FAILURE);
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    GLFWwindow* window =  glfwCreateWindow(600, 600, "Chatpter02-Program2", nullptr, nullptr);

    // 判断窗口是否创建成功
    if(!window) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwMakeContextCurrent(window);
    // 判断上下文有没有正确设置
    if(!glfwGetCurrentContext()) {
        std::cerr << "Failed to set GLFW context" << std::endl;
        glfwTerminate();
        return EXIT_FAILURE;
    }

    if(glewInit()!= GLEW_OK) {
        exit(EXIT_FAILURE);
    }
    glfwSwapInterval(1);

    init(window);

    while(!glfwWindowShouldClose(window)) {
        display(window, glfwGetTime());
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

My question is, what's wrong of my simple code? Is it my platform (Windows 11) have some problem to support the code? I have test the opengl version of my laptop, which shows it support OpenGL 4.6.

  1. I have test on Ubuntu, it works
  2. I have test on Windows 11, it fails.
NerdNiels
  • 21
  • 1

0 Answers0