使用 Xcode 和 Eclipse 在 Mac Mojave 上的着色器编译问题
Shader compilation issue on Mac Mojave using Xcode and Eclipse
以下代码在使用 Visual Studio 的 Windows PC 上运行良好,但在 Mac 上使用 运行 时无法为三角形提供颜色。似乎片段着色器编译没有问题,但是 MacOS 是 compiling/using 着色器不工作的方式。
我最初是从 Xcode 开始的。在发现代码在 Windows PC 上运行后,我切换到 Mac 上的 Eclipse。同样的问题。毫无疑问,我有依赖问题,但我正在努力寻找它。
使用 MacBook Air 和 Mojave 10.14.1。 Xcode 是 10.1(10861)。 Eclipse 是 2018-09 (4.9.0)。
GLFW 是 3.2.1 版。 GLEW 是 2.1.0。
#include <iostream>
#include <string>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
// Draw primative(s)
void draw() {
GLenum mode = GL_TRIANGLES;
GLint first = 0;
GLsizei count = 6;
glDrawArrays(mode, first, count);
}
// Create and compile shaders
static GLuint CompileShader(const std::string& source, GLuint shaderType) {
// Create shader object
GLuint shaderID = glCreateShader(shaderType);
const char* src = source.c_str();
// Attach source code to shader object
glShaderSource(shaderID, 1, &src, nullptr);
// Compile shader
std::cout << "Compiling shader..." << std::endl;
glCompileShader(shaderID);
// Return ID of compiled shader
return shaderID;
}
// Create program object
static GLuint CreateShaderProgram(const std::string& vertexShader, const std::string& fragmentShader) {
// Compile vertex shader
std::cout << "***** Compiling Vertex Shader *****" << std::endl;
GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);
// Compile fragment shader
std::cout << "***** Compiling Fragment Shader *****" << std::endl;
GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// Create program object
std::cout << "***** Create program object *****" << std::endl;
GLuint shaderProgram = glCreateProgram();
// Attach vertex and fragment shaders to program object
glAttachShader(shaderProgram, vertexShaderComp);
glAttachShader(shaderProgram, fragmentShaderComp);
std::cout << "***** Attached both Shaders *****" << std::endl;
// Link shaders to create executable
glLinkProgram(shaderProgram);
// Delete compiled shaders
glDeleteShader(vertexShaderComp);
glDeleteShader(fragmentShaderComp);
// Return shaderProgram
return shaderProgram;
}
int main() {
glfwInit(); // Initialize the glfw library
// Setup properties for the window
// THESE OPTIONS CAUSED THE TRIANGLE TO FAIL RENDERING; NOT SURE WHY
/*glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint( GLFW_RESIZABLE, GL_FALSE);*/
// Create instance of the window
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Kevin Tooley", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
// Handle the case that the window was not initialized
if ( nullptr == window ) {
std::cout << "Failed to create OpenGL Window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent( window ); // Make the window active
glewExperimental = GL_TRUE;
// Handle the case where glew failed to init
if ( GLEW_OK != glewInit() ) {
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Parameters used to display the window in relation to my screen
glViewport( 0, 0, screenWidth, screenHeight );
GLfloat vertices[] = {
// Triangle 1
0.0, 0.0, 0.0, // vert 0
1.0, 0.0, 0.0, // Red
-0.5, 0.0, 0.0, // vert 1
0.0, 1.0, 0.0, // Green
-0.5, 0.5, 0.0, // vert2
0.0, 0.0, 1.0, // Blue
// Triangle 2
0.0, 0.0, 0.0, // vert 0
1.0, 1.0, 0.0, // Red
0.5, 0.0, 0.0, // vert 1
0.0, 1.0, 1.0, // Green
0.5, -0.5, 0.0, // vert2
1.0, 0.0, 1.0 // Blue
};
GLuint VBO;
glGenBuffers(1, &VBO); // Create VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select buffer ( VBO )
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
// Specify location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// Vertex Shader source code
std::string vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec4 aPosition;\n"
"layout(location = 1) in vec4 aColor;\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
"gl_Position = aPosition;\n"
"oColor = aColor;\n"
"}\n";
// Fragment shader source code
std::string fragmentShaderSource =
"#version 330 core\n"
"in vec4 oColor;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
"fragColor = oColor;\n"
"}\n";
// Create shader program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
// Use shader program
glUseProgram(shaderProgram);
// Loop to process while window is open
while ( !glfwWindowShouldClose( window ) ) {
glfwPollEvents();
// Resize window and drawing simultaneously
//glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
//glViewport( 0, 0, screenWidth, screenHeight );
//glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT );
// Draw primative
draw();
//glEnable(GL_DEPTH_TEST);
glfwSwapBuffers( window );
//glfwPollEvents();
}
// The window has been closed, so terminate glfw
glfwTerminate();
return 0;
}
控制台输出如下。注意开头的错误。根据这一点它是已知的错误?
2018-11-19 22:04:14.669523-0500 GLFW OpenGL[30749:3605032] [General] ERROR: Setting <GLFWContentView: 0x1005d0e60> as the first responder for window <GLFWWindow: 0x1005aa770>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff48427a8b -[NSWindow _validateFirstResponder:] + 530
1 AppKit 0x00007fff48427835 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff484fa114 -[NSWindow _realMakeFirstResponder:] + 448
3 libglfw.3.dylib 0x00000001003619f7 _glfwPlatformCreateWindow + 644
4 libglfw.3.dylib 0x000000010035d71e glfwCreateWindow + 443
5 GLFW OpenGL 0x00000001000015bd main + 77
6 libdyld.dylib 0x00007fff7803508d start + 1
)
***** Compiling Vertex Shader *****
Compiling shader...
***** Compiling Fragment Shader *****
Compiling shader...
***** Create program object *****
***** Attached both Shaders *****
Program ended with exit code: 0
最后,这是 Mac 上输出的屏幕截图:
我没有 PC 的屏幕截图,但它可以正常工作。
如果我不得不猜测,我会认为你的 OpenGL-version
在你的 Mac 上已经过时了。这会导致某些功能无法按预期运行。可以通过 glGetString(GL_VERSION)
.
获得 OpenGL 版本
您的着色器设置为使用 OpenGL 3.3 核心配置文件,但您没有在 GLFW 初始化中指定版本。这可能导致着色器与正在初始化的 OpenGL 版本不匹配。 Check out this link 并为主要版本和次要版本指定 3。
此外,您可能还想检查一下您的着色器程序是否编译有误。 Here is an example from the OpenGL wiki 关于如何做到这一点。
如果问题仍然存在,请在每次 OpenGL 调用后添加 glGetError() 以确定发生错误的位置。
以下代码在使用 Visual Studio 的 Windows PC 上运行良好,但在 Mac 上使用 运行 时无法为三角形提供颜色。似乎片段着色器编译没有问题,但是 MacOS 是 compiling/using 着色器不工作的方式。
我最初是从 Xcode 开始的。在发现代码在 Windows PC 上运行后,我切换到 Mac 上的 Eclipse。同样的问题。毫无疑问,我有依赖问题,但我正在努力寻找它。
使用 MacBook Air 和 Mojave 10.14.1。 Xcode 是 10.1(10861)。 Eclipse 是 2018-09 (4.9.0)。
GLFW 是 3.2.1 版。 GLEW 是 2.1.0。
#include <iostream>
#include <string>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
// Draw primative(s)
void draw() {
GLenum mode = GL_TRIANGLES;
GLint first = 0;
GLsizei count = 6;
glDrawArrays(mode, first, count);
}
// Create and compile shaders
static GLuint CompileShader(const std::string& source, GLuint shaderType) {
// Create shader object
GLuint shaderID = glCreateShader(shaderType);
const char* src = source.c_str();
// Attach source code to shader object
glShaderSource(shaderID, 1, &src, nullptr);
// Compile shader
std::cout << "Compiling shader..." << std::endl;
glCompileShader(shaderID);
// Return ID of compiled shader
return shaderID;
}
// Create program object
static GLuint CreateShaderProgram(const std::string& vertexShader, const std::string& fragmentShader) {
// Compile vertex shader
std::cout << "***** Compiling Vertex Shader *****" << std::endl;
GLuint vertexShaderComp = CompileShader(vertexShader, GL_VERTEX_SHADER);
// Compile fragment shader
std::cout << "***** Compiling Fragment Shader *****" << std::endl;
GLuint fragmentShaderComp = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// Create program object
std::cout << "***** Create program object *****" << std::endl;
GLuint shaderProgram = glCreateProgram();
// Attach vertex and fragment shaders to program object
glAttachShader(shaderProgram, vertexShaderComp);
glAttachShader(shaderProgram, fragmentShaderComp);
std::cout << "***** Attached both Shaders *****" << std::endl;
// Link shaders to create executable
glLinkProgram(shaderProgram);
// Delete compiled shaders
glDeleteShader(vertexShaderComp);
glDeleteShader(fragmentShaderComp);
// Return shaderProgram
return shaderProgram;
}
int main() {
glfwInit(); // Initialize the glfw library
// Setup properties for the window
// THESE OPTIONS CAUSED THE TRIANGLE TO FAIL RENDERING; NOT SURE WHY
/*glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint( GLFW_RESIZABLE, GL_FALSE);*/
// Create instance of the window
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Kevin Tooley", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
// Handle the case that the window was not initialized
if ( nullptr == window ) {
std::cout << "Failed to create OpenGL Window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent( window ); // Make the window active
glewExperimental = GL_TRUE;
// Handle the case where glew failed to init
if ( GLEW_OK != glewInit() ) {
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
// Parameters used to display the window in relation to my screen
glViewport( 0, 0, screenWidth, screenHeight );
GLfloat vertices[] = {
// Triangle 1
0.0, 0.0, 0.0, // vert 0
1.0, 0.0, 0.0, // Red
-0.5, 0.0, 0.0, // vert 1
0.0, 1.0, 0.0, // Green
-0.5, 0.5, 0.0, // vert2
0.0, 0.0, 1.0, // Blue
// Triangle 2
0.0, 0.0, 0.0, // vert 0
1.0, 1.0, 0.0, // Red
0.5, 0.0, 0.0, // vert 1
0.0, 1.0, 1.0, // Green
0.5, -0.5, 0.0, // vert2
1.0, 0.0, 1.0 // Blue
};
GLuint VBO;
glGenBuffers(1, &VBO); // Create VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // Select buffer ( VBO )
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Load vertex attributes
// Specify location and layout to GPU
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// Vertex Shader source code
std::string vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec4 aPosition;\n"
"layout(location = 1) in vec4 aColor;\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
"gl_Position = aPosition;\n"
"oColor = aColor;\n"
"}\n";
// Fragment shader source code
std::string fragmentShaderSource =
"#version 330 core\n"
"in vec4 oColor;\n"
"out vec4 fragColor;\n"
"void main()\n"
"{\n"
"fragColor = oColor;\n"
"}\n";
// Create shader program
GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
// Use shader program
glUseProgram(shaderProgram);
// Loop to process while window is open
while ( !glfwWindowShouldClose( window ) ) {
glfwPollEvents();
// Resize window and drawing simultaneously
//glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
//glViewport( 0, 0, screenWidth, screenHeight );
//glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT );
// Draw primative
draw();
//glEnable(GL_DEPTH_TEST);
glfwSwapBuffers( window );
//glfwPollEvents();
}
// The window has been closed, so terminate glfw
glfwTerminate();
return 0;
}
控制台输出如下。注意开头的错误。根据这一点它是已知的错误?
2018-11-19 22:04:14.669523-0500 GLFW OpenGL[30749:3605032] [General] ERROR: Setting <GLFWContentView: 0x1005d0e60> as the first responder for window <GLFWWindow: 0x1005aa770>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff48427a8b -[NSWindow _validateFirstResponder:] + 530
1 AppKit 0x00007fff48427835 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff484fa114 -[NSWindow _realMakeFirstResponder:] + 448
3 libglfw.3.dylib 0x00000001003619f7 _glfwPlatformCreateWindow + 644
4 libglfw.3.dylib 0x000000010035d71e glfwCreateWindow + 443
5 GLFW OpenGL 0x00000001000015bd main + 77
6 libdyld.dylib 0x00007fff7803508d start + 1
)
***** Compiling Vertex Shader *****
Compiling shader...
***** Compiling Fragment Shader *****
Compiling shader...
***** Create program object *****
***** Attached both Shaders *****
Program ended with exit code: 0
最后,这是 Mac 上输出的屏幕截图:
我没有 PC 的屏幕截图,但它可以正常工作。
如果我不得不猜测,我会认为你的 OpenGL-version
在你的 Mac 上已经过时了。这会导致某些功能无法按预期运行。可以通过 glGetString(GL_VERSION)
.
您的着色器设置为使用 OpenGL 3.3 核心配置文件,但您没有在 GLFW 初始化中指定版本。这可能导致着色器与正在初始化的 OpenGL 版本不匹配。 Check out this link 并为主要版本和次要版本指定 3。
此外,您可能还想检查一下您的着色器程序是否编译有误。 Here is an example from the OpenGL wiki 关于如何做到这一点。
如果问题仍然存在,请在每次 OpenGL 调用后添加 glGetError() 以确定发生错误的位置。