OpenGL细分着色器中缺少线条

时间:2015-02-28 17:21:36

标签: opengl glsl shader tesselation

我正在学习tesselation着色器,并遵循从OpenGL wiki

的链接

http://voxels.blogspot.de/2011/09/tesselation-shader-tutorial-with-source.html

我将四个tesselation示例移植到Mac OS X,但它只在外层渲染了一半的线。如果我在tesselation评估着色器中将ccw更改为cw,则会渲染另一半,但不能同时渲染两者。

预期(简化):

---------
|\|\|/|/|
---------
|/|/|\|\|
---------

实际(ccw):

     ----
|\|\|/|/
---------
 /|/|\|\|
-----

实际(cw):

-----
 \|\|/|/|
---------
|/|/|\|\
    -----

这是源代码(如果它没有编译,请告诉我):

#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>

#include <iostream>
#include <string>

static GLuint program;
static GLuint vbo;
static GLuint vao;

GLuint compileShader (const std::string& source, GLenum type)
{
  const GLchar*const src = source.c_str ();

  const GLuint shader = glCreateShader (type);
  glShaderSource (shader, 1, &src, NULL);
  glCompileShader (shader);

  return shader;
}

void initializeShaders ()
{
  const std::string vert_source =
      "#version 410 core\n"

      "layout(location = 0) in vec4 vertex;"

      "void main(void)"
      "{"
      "  gl_Position = vertex;"
      "}";

  const std::string tesc_source =
      "#version 410 core\n"

      "layout(vertices = 4) out;"

      "void main(void)"
      "{"
      "  gl_TessLevelOuter[0] = 2.0;"
      "  gl_TessLevelOuter[1] = 4.0;"
      "  gl_TessLevelOuter[2] = 6.0;"
      "  gl_TessLevelOuter[3] = 8.0;"

      "  gl_TessLevelInner[0] = 8.0;"
      "  gl_TessLevelInner[1] = 8.0;"

      "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;"
      "}";

  const std::string tese_source =
      "#version 410 core\n"

      "layout(quads, equal_spacing, ccw) in;"

      "vec4 interpolate(in vec4 v0, in vec4 v1, in vec4 v2, in vec4 v3)"
      "{"
      "  vec4 a = mix(v0, v1, gl_TessCoord.x);"
      "  vec4 b = mix(v3, v2, gl_TessCoord.x);"
      "  return mix(a, b, gl_TessCoord.y);"
      "}"

      "void main()"
      "{"
      "  gl_Position = interpolate("
      "    gl_in[0].gl_Position,"
      "    gl_in[1].gl_Position,"
      "    gl_in[2].gl_Position,"
      "    gl_in[3].gl_Position);"
      "}";

  const std::string geom_source =
      "#version 410 core\n"

      "layout(triangles, invocations = 1) in;"
      "layout(line_strip, max_vertices = 3) out;"

      "void main(void)"
      "{"
      "  gl_Position = gl_in[0].gl_Position;"
      "  EmitVertex();"
      "  gl_Position = gl_in[1].gl_Position;"
      "  EmitVertex();"
      "  gl_Position = gl_in[2].gl_Position;"
      "  EmitVertex();"

      "  EndPrimitive();"
      "}";

  const std::string frag_source =
      "#version 410 core\n"

      "layout(location = 0, index = 0) out vec4 fragColor;"

      "void main(void)"
      "{"
      "  fragColor = vec4(1.0,0.0,0.0,1.0);"
      "}";

  const GLuint vert = compileShader (vert_source, GL_VERTEX_SHADER);
  const GLuint tesc = compileShader (tesc_source, GL_TESS_CONTROL_SHADER);
  const GLuint tese = compileShader (tese_source, GL_TESS_EVALUATION_SHADER);
  const GLuint geom = compileShader (geom_source, GL_GEOMETRY_SHADER);
  const GLuint frag = compileShader (frag_source, GL_FRAGMENT_SHADER);

  program = glCreateProgram ();

  glAttachShader (program, vert);
  glAttachShader (program, tesc);
  glAttachShader (program, tese);
  glAttachShader (program, geom);
  glAttachShader (program, frag);

  glLinkProgram (program);

  glDetachShader (program, vert);
  glDetachShader (program, tesc);
  glDetachShader (program, tese);
  glDetachShader (program, geom);
  glDetachShader (program, frag);

  glDeleteShader (vert);
  glDeleteShader (tesc);
  glDeleteShader (tese);
  glDeleteShader (geom);
  glDeleteShader (frag);
}

void deinitializeShaders ()
{
  glDeleteProgram (program);
}

void initializeVBOandVAO ()
{
  glGenBuffers (1, &vbo);
  glGenVertexArrays (1, &vao);

  glBindVertexArray (vao);
  glBindBuffer (GL_ARRAY_BUFFER, vbo);
  glEnableVertexAttribArray (0);
  glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
  glBindVertexArray (0);
}

void deinitializeVBOandVAO ()
{
  glDeleteVertexArrays (1, &vao);
  glDeleteBuffers (1, &vbo);
}

void uploadVertices ()
{
  const int n_vert = 16;
  const float vert [n_vert] =
  {
    -0.9f , -0.9f , 0.0f , 1.0f,
     0.9f , -0.9f , 0.0f , 1.0f,
     0.9f ,  0.9f , 0.0f , 1.0f,
    -0.9f ,  0.9f , 0.0f , 1.0f
  };

  glBindBuffer (GL_ARRAY_BUFFER, vbo);
  glBufferData (GL_ARRAY_BUFFER, n_vert * sizeof (float), vert, GL_STATIC_DRAW);
  glBindBuffer (GL_ARRAY_BUFFER, 0);
}

void draw (GLFWwindow* window)
{
  glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glUseProgram (program);
  glBindVertexArray (vao);

  glPatchParameteri (GL_PATCH_VERTICES, 4);
  glDrawArrays (GL_PATCHES, 0, 4);

  glBindVertexArray (0);
  glUseProgram (0);

  glfwSwapBuffers (window);
}

void error_callback (int error, const char* description)
{
  std::cerr << "Error " << error << ": " << description << std::endl;
}

int main ()
{
  glfwSetErrorCallback (error_callback);
  if (!glfwInit ())
  {
    return 1;
  }

  glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 1);
  glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  GLFWwindow* window = glfwCreateWindow (480, 360, "Tesselation", NULL, NULL);
  if (!window)
  {
    glfwTerminate ();
    return 1;
  }

  glfwMakeContextCurrent (window);

  initializeShaders ();
  initializeVBOandVAO ();
  uploadVertices ();

  int width = -1, height = -1;
  glfwGetFramebufferSize (window, &width, &height);
  glViewport (0, 0, width, height);

  while (!glfwWindowShouldClose (window))
  {
    draw (window);
    glfwWaitEvents ();
  }

  deinitializeShaders ();
  deinitializeVBOandVAO ();

  glfwDestroyWindow (window);
  glfwTerminate ();

  return 0;
}

我正在使用macports的GLFW 3.1(glfw @ 20150106)。

0 个答案:

没有答案