我正在学习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)。