What we want to achieve
I would like to use GLSL shader programs on my M1mac.
Assumption
I want to use OlenGL shader program in C++ to display a red screen. However, the shader program is not reflected and the screen remains white.
Problem/error message being encountered
The shader program is not reflected. Both compile and run successfully. There are no errors or warnings.
What we researched and tried
compile command
g++ -o main main.cpp -lglfw -lglew -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -std=c++11
When executed, the shader program is not reflected and a white screen is displayed.
Source code in question
#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#endif
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
// Display the compiled result of a shader object
// shader: Shader Object Name
// str: String indicating where the compilation error occurred
GLboolean printShaderInfoLog(GLuint shader, const char *str) {
// Obtain compilation results
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) std::cerr << "Compile Error in " << str << std::endl;
// Get the length of the shader's compile-time log
GLsizei bufSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize);
if (bufSize > 1) {
// Get the contents of the shader's compile-time log
std::vector<GLchar> infoLog(bufSize);
GLsizei length;
glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]);
std::cerr << &infoLog[0] << std::endl;
}
return static_cast<GLboolean>(status);
}
// Display the results of linking program objects
// program: Program Object Name
GLboolean printProgramInfoLog(GLuint program) {
// Get link results
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) std::cerr << "Link Error." << std::endl;
// Get the length of the shader's log at the time of linking
GLsizei bufSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize);
if (bufSize > 1) {
// Get the contents of the log when linking shaders
std::vector<GLchar> infoLog(bufSize);
GLsizei length;
glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]);
std::cerr << &infoLog[0] << std::endl;
}
return static_cast<GLboolean>(status);
}
// Create a program object
// vsrc: Vertex shader source program string
// fsrc: Fragment shader source program string
GLuint createProgram(const char *vsrc, const char *fsrc) {
// Create an empty program object
const GLuint program(glCreateProgram());
if (vsrc != NULL) {
// Create a shader object for a vertex shader
const GLuint vobj(glCreateShader(GL_VERTEX_SHADER));
glShaderSource(vobj, 1, &vsrc, NULL);
glCompileShader(vobj);
// Incorporate vertex shader objects into program objects
if (printShaderInfoLog(vobj, "vertex shader"))
glAttachShader(program, vobj);
glDeleteShader(vobj);
}
if (fsrc != NULL) {
// Create a shader object for a fragment shader
const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER));
glShaderSource(fobj, 1, &fsrc, NULL);
glCompileShader(fobj);
// Incorporate shader objects of fragment shaders into program
// objects
if (printShaderInfoLog(fobj, "fragment shader"))
glAttachShader(program, fobj);
glDeleteShader(fobj);
}
// Linking Program Objects
glBindAttribLocation(program, 0, "position");
glBindFragDataLocation(program, 0, "fragment");
glLinkProgram(program);
// Returns the created program object
if (printProgramInfoLog(program)) return program;
// Returns 0 if program object cannot be created
glDeleteProgram(program);
return 0;
}
int main() {
// Initialize GLFW
if (glfwInit() == GL_FALSE) {
// Initialization failed.
std::cerr << "Can't initialize GLFW" << std::endl;
return 1;
}
// Register processing at the end of the program
atexit(glfwTerminate);
// Select OpenGL Version 3.2 Core Profile
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a window
GLFWwindow *const window(glfwCreateWindow(640, 480, "Hello!", NULL, NULL));
if (window == NULL) {
// Window could not be created.
std::cerr << "Can't create GLFW window." << std::endl;
return 1;
}
// Make the created window an OpenGL target
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
// GLEW initialization failed.
std::cerr << "Can't initialize GLEW" << std::endl;
return 1;
}
// Wait for vertical synchronous timing
glfwSwapInterval(1);
// Specify background color
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
// Source program for vertex shader
static constexpr GLchar vsrc[] =
"#version 150 core\n"
"in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\n";
// Fragment shader source program
static constexpr GLchar fsrc[] =
"#version 150 core\n"
"out vec4 fragment;\n"
"void main()\n"
"{\n"
" fragment = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
// Create a program object
const GLuint program(createProgram(vsrc, fsrc));
// Repeat while window is open
while (glfwWindowShouldClose(window) == GL_FALSE) {
// Clear Window
glClear(GL_COLOR_BUFFER_BIT);
// Start using shader program
glUseProgram(program);
// replace the color buffer
glfwSwapBuffers(window);
// retrieve an event
glfwWaitEvents();
}
}
Supplementary information (tool version)
PC Environment OS: macOS Monterey version 12.3.1 MacBook Air (M1, 2020) Chip: Apple M1 Memory: 16GB
g++ version Apple clang version 13.1.6 (clang-1316.0.21.2.3)
compile command
g++ -o main main.cpp -lglfw -lglew -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -std=c++11