Using OpenGL shader programs on the M1mac

96 views Asked by At

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
0

There are 0 answers