使用glCreateVertexArrays时获取黑屏

时间:2016-07-24 17:24:23

标签: c++ opengl

我正在学习opengl。我买了一本名为OpenGL Superbible的书。但我无法幸免于正确配置环境。我使用GLFW 3.2作为窗口工具包(如果这就是所谓的)和GLEW 2.0。

我正在尝试编译并使用着色器在屏幕上绘制。根据这本书,这应该在屏幕上绘制一个三角形。但事实并非如此。相反,它显示由glClearColor设置的清晰背景颜色。

这是Code

#include <iostream>

#include <GLFW\glfw3.h>
#include <GL\glew.h>

GLuint CompileShaders();

int main(void) {
  // Initialise GLFW
  if (!glfwInit()) {
    fprintf(stderr, "Failed to initialize GLFW\n");
    getchar();
    return -1;
  }

  // Open a window and create its OpenGL context
  GLFWwindow *window;
  window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
  if (window == NULL) {
    fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, "
                    "they are not 3.3 compatible. Try the 2.1 version of the "
                    "tutorials.\n");
    getchar();
    glfwTerminate();
    return -1;
  }
  glfwMakeContextCurrent(window);

  // Initialize GLEW
  if (glewInit() != GLEW_OK) {
    fprintf(stderr, "Failed to initialize GLEW\n");
    getchar();
    glfwTerminate();
    return -1;
  }

  // Ensure we can capture the escape key being pressed below
  glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

  GLuint RederingProgram = CompileShaders();
  GLuint VertexArrayObject;
  glCreateVertexArrays(1, &VertexArrayObject);
  glBindVertexArray(VertexArrayObject);

  int LoopCounter = 0;

  do {
    // Clear the screen. It's not mentioned before Tutorial 02, but it can cause
    // flickering, so it's there nonetheless.
    /*const GLfloat red[] = {
            (float)sin(LoopCounter++ / 100.0f)*0.5f + 0.5f,
            (float)cos(LoopCounter++ / 100.0f)*0.5f + 0.5f,
            0.0f, 1.0f
    };*/
    // glClearBufferfv(GL_COLOR, 0, red);

    // Draw nothing, see you in tutorial 2 !
    glUseProgram(RederingProgram);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // Swap buffers
    glfwSwapBuffers(window);
    glfwPollEvents();

  } // Check if the ESC key was pressed or the window was closed
  while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
         glfwWindowShouldClose(window) == 0);

  // Close OpenGL window and terminate GLFW
  glfwTerminate();

  return 0;
}

GLuint CompileShaders() {
  GLuint VertexShader;
  GLuint FragmentShader;
  GLuint Program;

  static const GLchar *VertexShaderSource[] = {
      "#version 450 core                        "
      " "
      "\n",
      "                                 "
      "     \n",
      "void main(void)                          "
      " "
      "\n",
      "{                                "
      " "
      "     \n",
      "const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),\n",
      "                                 "
      "vec4(-0.25, -0.25, 0.5, 1.0),\n",
      "                                 "
      "vec4(0.25, 0.25, 0.5, 1.0)); \n",
      " gl_Position = vertices[gl_VertexID];    \n",
      "}                                "
      " "
      "     \n"};

  static const GLchar *FragmentShaderSource[] = {
      "#version 450 core                        "
      " "
      "\n",
      "                                 "
      "     \n",
      "out vec4 color;                          \n",
      "                                 "
      "     \n",
      "void main(void)                          "
      " "
      "\n",
      "{                                "
      " "
      "     \n",
      " color = vec4(0.0, 0.8, 1.0, 1.0);       \n",
      "}                                "
      " "
      "     \n"};

  // Create and compile vertex shader.
  VertexShader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(VertexShader, 1, VertexShaderSource, NULL);
  glCompileShader(VertexShader);

  // Create and compile fragment shader.
  FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(FragmentShader, 1, FragmentShaderSource, NULL);
  glCompileShader(FragmentShader);

  // Create program, attach shaders to it, and link it
  Program = glCreateProgram();
  glAttachShader(Program, VertexShader);
  glAttachShader(Program, FragmentShader);
  glLinkProgram(Program);

  // Delete the shaders as the program has them now.
  glDeleteShader(FragmentShader);
  glDeleteShader(VertexShader);

  return Program;
}

我在视觉工作室2015工作。我有所有的库来开发一些opengl(我想),但是有些错误。请帮我。顺便说一句,glCreateVertexArrays()函数仅在Opengl 4.5及更高版本中,我知道,因为本书在opengl 4.5中有解释。

我很快就会发疯,因为没有适合初学者的教程。了解这一点的人是非常雄心勃勃的人。我向那些人鞠躬。

1 个答案:

答案 0 :(得分:2)

你的着色器不应该编译:

glShaderSource(VertexShader, 1, VertexShaderSource, NULL);

这告诉GL它应该期望一个 1 GLchar指针的数组。但是,您的GLSL代码实际上被分成几个单独的字符串(请注意逗号);

static const GLchar *VertexShaderSource[] = {
    "...GLSL-code..."
    "...GLSL-code..."
    "...GLSL-code...",  //  <- this comma ends the first string vertexShaderSource[0]
    "...GLSL-code..."   //  vertexShaderSource[1] starts here
    [...]

有两种可能的解决方案:

  1. 只需删除这些逗号,以便您的数组只包含一个指向整个GLSL源的元素作为一个字符串。
  2. 告诉GL你的数据真相:

    glShaderSoure(..., sizeof(vertexShaderSource)/sizeof(vertexShaderSource[0]), vertexShaderSource, ,,,)
    
  3. 除此之外,您应始终查询着色器和程序对象的编译和链接状态。还查询着色器编译和程序链接信息日志。它们将包含人为readbale消息,告诉您编译/链接失败的原因。