我正在尝试在Windows 7上用C语言编写MCVE OpenGL应用程序。我发现OpenGL 4.5的功能是专门的,它是segfaulting(“访问冲突”),我无法确定。
我的电脑是Nvidia Optimus笔记本电脑,带有离散的GeForce 765M卡,according to the Nvidia spec支持OpenGL 4.5。我还在Linux上通过运行primusrun glxgears -info
(使用Bumblebee / Primus允许在离散卡上运行应用程序)观察到这一点。
我的(Windows)GeForce驱动程序是版本372.70(最新的ATOW)。
因此,使用Visual Studio 15,我有以下最小的例子:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <GL\glew.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <GLFW\glfw3.h>
typedef struct
{
GLenum type;
const char* fileName;
} shader_t;
GLuint vao;
GLuint bufferName;
GLint vPosition = 0;
GLuint program;
GLuint vertex, frag;
shader_t shaders[] = {
{GL_VERTEX_SHADER, "vertex.glsl"},
{GL_FRAGMENT_SHADER, "frag.glsl"}
};
GLuint compileShader(shader_t shader)
{
GLuint ret = glCreateShader(shader.type);
FILE* file = fopen(shader.fileName, "r");
fseek(file, 0, SEEK_END);
size_t fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
GLchar* src = malloc(fileSize + 1);
fread(src, 1, fileSize, file);
src[fileSize] = 0;
fclose(file);
glShaderSource(ret, 1, (const GLchar**)&src, NULL);
free(src);
glCompileShader(ret);
GLint compiled;
glGetShaderiv(ret, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLsizei len;
glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &len);
GLchar* log = malloc(len + 1);
glGetShaderInfoLog(ret, len, &len, log);
log[len] = 0;
fprintf(stderr, "Compile failed: %s", log);
free(log);
exit(EXIT_FAILURE);
}
return ret;
}
void init()
{
const GLfloat verts[6][2] =
{
{-0.90, -0.90},
{ 0.85, -0.90},
{-0.90, 0.85},
{ 0.90, -0.85},
{ 0.90, 0.90},
{-0.85, 0.90}
};
glCreateBuffers(1, &bufferName); // XXX <- segfault here!
glNamedBufferStorage(bufferName, sizeof(GLfloat) * 6 * 2, verts, 0);
program = glCreateProgram();
vertex = compileShader(shaders[0]);
frag = compileShader(shaders[1]);
glUseProgram(program);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, bufferName);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glEnableVertexAttribArray(vPosition);
}
void display()
{
const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
glClearBufferfv(GL_COLOR, 0, black);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 1);
}
int main(int argc, char** argv)
{
glfwInit();
GLFWwindow* window = glfwCreateWindow(640, 480, "Triangles", NULL, NULL);
assert(window);
glfwMakeContextCurrent(window);
GLenum glewErr = glewInit();
if (glewErr != GLEW_OK)
{
fprintf(stderr, "glewInit returned %d", glewErr);
return EXIT_FAILURE;
}
if (GLEW_VERSION_4_3)
printf("OpenGL 4.3 is supported!");
if (GLEW_VERSION_4_4)
printf("OpenGL 4.4 is supported!");
if (GLEW_VERSION_4_5)
printf("OpenGL 4.5 is supported!");
init();
while (!glfwWindowShouldClose(window))
{
display();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return EXIT_SUCCESS;
}
我在调用glCreateBuffers()
第84行时发现程序段错误/“访问冲突”。我在调查期间注意到的一件事是这是OpenGL 4.5的新功能。我决定通过添加main()
中的GLEW版本检查来测试兼容性。在segfaulting之前,此应用程序的唯一输出是:
OpenGL 4.3 is supported!
如果我将glCreateBuffers()
替换为glGenBuffers()
,程序会在同一行 段错误;相反,它会在下一次函数调用时死于glNamedBufferStorage()
。从Khronos文档中,我注意到两个segfaulting函数是OpenGL 4.5,而glGenBuffers()
已经存在了一段时间。
图书馆详情:
C:\Program Files (x86)\NVIDIA Corporation\Nsight Visual Studio Edition 5.2\Monitor\glew
)我不知道我(可能)做错了什么;如果我遗失任何东西,请告诉我!
(如果我可以提供任何其他信息来帮助诊断,请发表评论。)