- GLContext::EnableDepthTest();
- GLContext::EnableBackfaceCulling();
- program.LoadShader(
- GL_VERTEX_SHADER,
- "#version 330 core\n"
- "layout(location = 0) in vec3 vtx_position;\n"
- "layout(location = 1) in vec3 vtx_color;\n"
- "layout(location = 2) in vec3 vtx_normal;\n"
- "uniform mat4 M;\n"
- "uniform mat4 V;\n"
- "uniform mat4 MVP;\n"
- "uniform vec3 light_position;\n"
- "out vec3 frag_color;\n"
- "out vec3 vtx_world;\n"
- "out vec3 normal;\n"
- "out vec3 eye;\n"
- "out vec3 light_direction;\n"
- "void main() {\n"
- "vec4 v = vec4(vtx_position, 1);\n"
- "gl_Position = MVP * v;\n"
- "vtx_world = (M * v).xyz;\n"
- "vec3 vtx_camera = (V * M * v).xyz;\n"
- "eye = vec3(0, 0, 0) - vtx_camera;\n"
- "vec3 light_camera = (V * v).xyz;\n"
- "light_direction = light_position + eye;\n"
- "normal = (V * M * vec4(vtx_normal, 0)).xyz;\n"
- "frag_color = vtx_color;\n"
- "}\n"
- );
- program.LoadShader(
- GL_FRAGMENT_SHADER,
- "#version 330 core\n"
- "in vec3 frag_color;\n"
- "in vec3 vtx_world;\n"
- "in vec3 normal;\n"
- "in vec3 eye;\n"
- "in vec3 light_direction;\n"
- "uniform mat4 MV;\n"
- "uniform vec3 light_position;\n"
- "uniform vec3 light_color;\n"
- "uniform float light_power;\n"
- "out vec3 color;\n"
- "void main() {\n"
- "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n"
- "vec3 specular = vec3(0.3, 0.3, 0.3);\n"
- "float distance = length(light_position - vtx_world);\n"
- "vec3 n = normalize(normal);\n"
- "vec3 l = normalize(light_direction);\n"
- "float cos_theta = clamp(dot(n, l), 0, 1);\n"
- "vec3 E = normalize(eye);\n"
- "vec3 R = reflect(-l, n);\n"
- "float cos_alpha = clamp(dot(E, R), 0, 1);\n"
- "color = ambient"
- " + frag_color * light_color * light_power * cos_theta / (distance * distance)"
- " + specular * light_color * light_power * pow(cos_alpha, 5) / (distance * distance);\n"
- "}\n"
- );
- program.Link();
- if (!program.Linked()) {
- program.Log(std::cerr);
- throw std::runtime_error("link program");
- }
-
- GLuint VertexArrayID;
- glGenVertexArrays(1, &VertexArrayID);
- glBindVertexArray(VertexArrayID);
-
- cam.Position(glm::vec3(0, 4, 4));