OpenGL 4.5函数segfaulting

时间:2016-09-14 20:22:15

标签: c windows opengl windows-7

我正在尝试在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()已经存在了一段时间。

图书馆详情:

  • 来自网站的GLFW v3.2.1(最新)二进制文件
  • GLEW来自最近下载的Nsight工具(C:\Program Files (x86)\NVIDIA Corporation\Nsight Visual Studio Edition 5.2\Monitor\glew

我不知道我(可能)做错了什么;如果我遗失任何东西,请告诉我!

(如果我可以提供任何其他信息来帮助诊断,请发表评论。)

0 个答案:

没有答案