Created
March 21, 2014 16:40
-
-
Save bananu7/9690357 to your computer and use it in GitHub Desktop.
My Little Tesselation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <glload/gl_4_0.hpp> | |
#include <glload/gl_load.hpp> | |
#include <GLFW/glfw3.h> | |
#include <string> | |
#include <vector> | |
#include <iostream> | |
#define NL "\n" | |
bool compileSuccessful(unsigned obj) { | |
int status; | |
gl::GetShaderiv(obj, gl::COMPILE_STATUS, &status); | |
return status == gl::TRUE_; | |
} | |
bool linkSuccessful(unsigned program) { | |
int status; | |
gl::GetProgramiv(program, gl::LINK_STATUS, &status); | |
return status == gl::TRUE_; | |
} | |
std::string getShaderLog(unsigned shader) | |
{ | |
GLsizei len; | |
char log[2048]; | |
gl::GetShaderInfoLog(shader, sizeof(log), &len, log); | |
return log; | |
} | |
unsigned loadProgram () { | |
using std::string; | |
const string vss = | |
"#version 400 core"NL | |
"layout(location = 0) in vec2 position;"NL | |
"out vec2 vPosition;"NL | |
"void main() {"NL | |
" vPosition = position;"NL | |
" gl_Position = vec4(position, 0.0, 1.0);"NL | |
"}"NL | |
NL; | |
const string tcss = | |
"#version 400 core"NL | |
"layout(vertices = 4) out;"NL | |
"in vec2 vPosition[];"NL | |
"out vec2 tcPosition[];"NL | |
//"uniform float TessLevelInner;"NL | |
//"uniform float TessLevelOuter;"NL | |
"const float TessLevelInner = 16.0;"NL | |
"const float TessLevelOuter = 16.0;"NL | |
"#define ID gl_InvocationID"NL | |
"void main()"NL | |
"{"NL | |
" tcPosition[ID] = vPosition[ID];"NL | |
" if (ID == 0) {"NL | |
" gl_TessLevelInner[0] = TessLevelInner;"NL | |
" gl_TessLevelInner[1] = TessLevelInner;"NL | |
" gl_TessLevelOuter[0] = TessLevelOuter;"NL | |
" gl_TessLevelOuter[1] = TessLevelOuter;"NL | |
" gl_TessLevelOuter[2] = TessLevelOuter;"NL | |
" gl_TessLevelOuter[3] = TessLevelOuter;"NL | |
" }"NL | |
"}"NL | |
NL; | |
const string tess = | |
"#version 400 core"NL | |
"layout(quads) in;"NL | |
"in vec2 tcPosition[];"NL | |
"out vec2 tePosition;"NL | |
"#define ID gl_PrimitiveID"NL | |
"void main() {"NL | |
//"vec2 p0 = gl_TessCoord.x * tcPosition[0];"NL | |
//"vec2 p1 = gl_TessCoord.y * tcPosition[1];"NL | |
//"vec3 p2 = gl_TessCoord.z * tcPosition[2];"NL | |
//"vec2 tePosition = p0 + p1;"NL | |
"float u = gl_TessCoord.x, v = gl_TessCoord.y;"NL | |
"vec2 a = mix(tcPosition[0], tcPosition[1], u);"NL | |
"vec2 b = mix(tcPosition[2], tcPosition[3], u);"NL | |
//"vec2 a = mix(gl_in[0].gl_Position.xy, gl_in[1].gl_Position.xy, u);"NL | |
//"vec2 b = mix(gl_in[2].gl_Position.xy, gl_in[3].gl_Position.xy, u);"NL | |
"tePosition = mix(a, b, v);"NL | |
"tePosition.y += sin(u * 3.1416 * 2) * 0.1;" | |
//"vec2 tePosition = tcPosition[ID];"NL | |
" gl_Position = vec4(tePosition, 0.0, 1.0);"NL | |
"}"NL | |
NL; | |
const string fss = | |
"#version 400 core"NL | |
"out vec4 color;"NL | |
"in vec2 tePosition;"NL | |
"void main() {"NL | |
" color = vec4((tePosition + 1.0) * 0.5, 0.0, 1.0);"NL | |
"}"NL | |
NL; | |
auto vs = gl::CreateShader(gl::VERTEX_SHADER); | |
auto fs = gl::CreateShader(gl::FRAGMENT_SHADER); | |
auto tcs = gl::CreateShader(gl::TESS_CONTROL_SHADER); | |
auto tes = gl::CreateShader(gl::TESS_EVALUATION_SHADER); | |
auto shaderSource = [](unsigned shader, string const& source) { | |
auto const ptr = source.data(); | |
int size = source.size(); | |
gl::ShaderSource(shader, 1, &ptr, &size); | |
}; | |
shaderSource(vs, vss); | |
shaderSource(fs, fss); | |
shaderSource(tcs, tcss); | |
shaderSource(tes, tess); | |
gl::CompileShader(vs); | |
gl::CompileShader(fs); | |
gl::CompileShader(tcs); | |
gl::CompileShader(tes); | |
std::cerr << "TCS: " << getShaderLog(tcs); | |
std::cerr << "TES: " << getShaderLog(tes); | |
unsigned program = gl::CreateProgram(); | |
gl::AttachShader(program, vs); | |
gl::AttachShader(program, fs); | |
gl::AttachShader(program, tcs); | |
gl::AttachShader(program, tes); | |
gl::LinkProgram(program); | |
if (!linkSuccessful(program)) | |
std::cerr << "LINK FAILED!\n"; | |
gl::DeleteShader(vs); | |
gl::DeleteShader(fs); | |
gl::DeleteShader(tcs); | |
gl::DeleteShader(tes); | |
return program; | |
} | |
struct Mesh { unsigned vbo, vao; }; | |
Mesh loadMesh() { | |
Mesh m; | |
gl::GenVertexArrays(1, &m.vao); | |
gl::GenBuffers(1, &m.vbo); | |
gl::BindVertexArray(m.vao); | |
float verts[] = { | |
-0.5f, -0.5f, | |
0.5f, -0.5f, | |
-0.5f, 0.5f, | |
0.5f, 0.5f | |
}; | |
gl::BindBuffer(gl::ARRAY_BUFFER, m.vbo); | |
gl::BufferData(gl::ARRAY_BUFFER, sizeof(verts), verts, gl::STATIC_DRAW); | |
gl::EnableVertexAttribArray (0); | |
gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE_, 0, 0); | |
return m; | |
} | |
int main(void) { | |
GLFWwindow* window; | |
/* Initialize the library */ | |
if (!glfwInit()) | |
return -1; | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); | |
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, gl::TRUE_); | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, gl::TRUE_); | |
glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
/* Create a windowed mode window and its OpenGL context */ | |
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); | |
if (!window) { | |
glfwTerminate(); | |
return -1; | |
} | |
/* Make the window's context current */ | |
glfwMakeContextCurrent(window); | |
glload::LoadFunctions(); | |
auto program = loadProgram(); | |
auto mesh = loadMesh(); | |
gl::BindVertexArray(mesh.vao); | |
/* Loop until the user closes the window */ | |
while (!glfwWindowShouldClose(window)) { | |
/* Render here */ | |
gl::UseProgram(program); | |
gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE); | |
gl::PatchParameteri(gl::PATCH_VERTICES, 4); // tell OpenGL that every patch has 16 verts | |
gl::DrawArrays(gl::PATCHES, 0, 4); | |
//gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4); | |
/* Swap front and back buffers */ | |
glfwSwapBuffers(window); | |
/* Poll for and process events */ | |
glfwPollEvents(); | |
} | |
glfwTerminate(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment