[英]OpenGL+GLFW glGenVertexArrays returns GL_INVALID_OPERATION
In trying to move into using "modern" OpenGL (basically 3.2+), I've run into some troubles running basic code (derived from both here and here ) using GLFW, GLEW, and OpenGL. 在尝试使用“现代”OpenGL(基本上是3.2+)时,我遇到了使用GLFW,GLEW和OpenGL运行基本代码(从这里和这里派生)的一些麻烦。
My first problem is that with the below code: 我的第一个问题是使用以下代码:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"void main()"
"{"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"out vec4 outColor;"
"void main()"
"{"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
void checkErr(const char* msg) {
GLenum err = glGetError();
if (err != 0) {
printf("@ \"%s\": %d\n", msg, err);
exit(EXIT_FAILURE);
} else {
printf("@ \"%s\": successful\n", msg);
}
}
int main(int argc, char* argv[]) {
GLFWwindow* window;
// Initialize GLFW
if (!glfwInit())
return -1;
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 windowed mode window and its OpenGL context
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
printf ("Renderer: %s\n", renderer);
printf ("OpenGL version: %s\n", version);
printf ("GLSL version: %s\n", glslVersion);
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
checkErr("Gen VAO");
glBindVertexArray(vao);
checkErr("Bind VAO");
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
checkErr("Gen VBO");
GLfloat vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
checkErr("Bind VBO");
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
checkErr("VBO data");
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
checkErr("Compile vert shader");
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
checkErr("Compile frag shader");
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
checkErr("Link program");
glUseProgram(shaderProgram);
checkErr("Use program");
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
checkErr("Enable vertex attrib");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
checkErr("Describe vert data");
// Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
exit(EXIT_SUCCESS);
}
I'm immediately running into GL_INVALID_OPERATION
errors on the very first step of setting up the vertex array object. 我在设置顶点数组对象的第一步中立即
GL_INVALID_OPERATION
错误。
I've done a fair bit of research regarding OS X's flimsy OpenGL support, but so far most of the things I've modified in this code has done nothing more but produce a completely black screen (that is, when I removed the crashing behavior of the checkError
helper function). 我已经对OS X的脆弱的OpenGL支持进行了一些研究,但到目前为止,我在这段代码中修改过的大部分内容都没有做更多的事情,只产生一个完全黑屏(也就是说,当我删除崩溃的行为时)
checkError
辅助函数)。
For reference, I'm running on an early 2015 MacBook Pro w/Retina, OS X v10.11.3, and the output of the version info from my above program lists as follows: 作为参考,我使用的是2015年初的MacBook Pro w / Retina,OS X v10.11.3,以及我上面程序列出的版本信息输出如下:
Renderer: Intel(R) Iris(TM) Graphics 6100
OpenGL version: 4.1 INTEL-10.12.13
GLSL version: 4.10
Any help is greatly appreciated! 任何帮助是极大的赞赏!
You just assumed that your error was generated by glGenVertexArrays
. 您只是假设您的错误是由
glGenVertexArrays
生成的。 But that is not the case. 但事实并非如此。 It is generated by
glewInit
. 它由
glewInit
生成。 And this is because GLEW is just broken on core profile opengl: it uses glGetString(GL_EXTENSIONS)
to query the extension string, which is not available in core prodiles and generates a GL_INVALID_ENUM
error (1280). 这是因为GLEW刚刚在核心配置文件opengl上被打破:它使用
glGetString(GL_EXTENSIONS)
来查询扩展字符串,这在核心产品中不可用并生成GL_INVALID_ENUM
错误(1280)。
Normally, glewInit
will then abort with return code GL_FALSE
. 通常,
glewInit
将以返回码GL_FALSE
中止。 However, the "workaround" of setting glewExperimental=GL_TRUE
will make it going on, ignoring the error, and querying all the extension pointers anyway. 但是,设置
glewExperimental=GL_TRUE
的“解决方法”将使其继续,忽略错误,并且无论如何都要查询所有扩展指针。 This is now broken in at least 3 different regards: 现在至少在3个不同方面打破了这个问题:
NULL
, but calling these would be undefined behavior. NULL
,但调用这些指针将是未定义的行为。 Together with 1, this means you have no way of checking the availibility of any extension, except by manually doing the stuff glew is actually there for to do for you. As a quick & dirty hack, you can just add a glGetError()
right after glewInit
, to read the error away. 作为一个快速和肮脏的黑客,你可以再补充一个
glGetError()
之后glewInit
,读取错误了。 After I did that, your code produced the expected white triangle on my implementation (NVIDIA/Linux). 在我这样做之后,你的代码在我的实现(NVIDIA / Linux)上产生了预期的白色三角形。
A better fix is probably to switch over to another GL loader which does properly work with core profiles, for example glad . 一个更好的修复可能是切换到另一个GL加载器,它正确地与核心配置文件一起工作,例如很高兴 。 Switching over will not be really hard, as only that init function has to be replaced.
切换不会很难,因为只需要替换init函数。 Note that glad is not a loader library, but a python script which generates a loader source file for your needs, so you don't need to link another library, but just have to add another source file to your project.
请注意,很高兴不是一个加载器库,而是一个python脚本,它根据您的需要生成一个加载器源文件,因此您不需要链接另一个库,只需要将另一个源文件添加到您的项目中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.