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.
- I have test on Ubuntu, it works
- I have test on Windows 11, it fails.