5 #include <glm/glm.hpp>
\r
6 #include <glm/gtc/matrix_transform.hpp>
\r
7 #include <glm/gtc/type_ptr.hpp>
\r
9 #include <SFML/OpenGL.hpp>
\r
10 #include <SFML/Window.hpp>
\r
12 #include <assimp/Importer.hpp>
\r
13 #include <assimp/postprocess.h>
\r
14 #include <assimp/scene.h>
\r
16 const char *vertexShaderSource = R"(
\r
19 layout (location = 0) in vec3 pos;
\r
20 layout (location = 0) in vec3 normal;
\r
27 uniform mat4 projection;
\r
31 gl_Position = projection * view * model * vec4(pos, 1.0);
\r
32 FragPos = vec3(model * vec4(pos, 1));
\r
37 const char *fragmentShaderSource = R"(
\r
45 uniform vec3 objectColor;
\r
46 uniform vec3 lightColor;
\r
47 uniform vec3 lightPos;
\r
51 vec3 norm = normalize(Normal);
\r
52 vec3 lightDir = normalize(lightPos - FragPos);
\r
54 float diff = max(dot(norm, lightDir), 0.0);
\r
55 vec3 diffuse = diff * lightColor;
\r
57 float ambientStrength = 0.1;
\r
58 vec3 ambient = ambientStrength * lightColor;
\r
60 vec3 result = (ambient + diffuse) * objectColor;
\r
61 FragColor = vec4(result, 1.0f);
\r
65 std::vector<float> vertices;
\r
66 std::vector<GLuint> indices;
\r
68 glm::vec3 lightPos(1.2f, 0.5f, 2.0f);
\r
70 void load(const std::string &filename, std::vector<float> &vertices,
\r
71 std::vector<GLuint> &indices) {
\r
72 Assimp::Importer importer;
\r
74 const aiScene *scene = importer.ReadFile(
\r
75 filename, aiProcess_CalcTangentSpace | aiProcess_Triangulate |
\r
76 aiProcess_SortByPType | aiProcess_GenNormals);
\r
78 for (int i = 0; i < scene->mMeshes[0]->mNumVertices; i++) {
\r
79 aiVector3D v = scene->mMeshes[0]->mVertices[i];
\r
80 aiVector3D n = scene->mMeshes[0]->mNormals[i];
\r
81 vertices.push_back(v.x);
\r
82 vertices.push_back(v.y);
\r
83 vertices.push_back(v.z);
\r
84 vertices.push_back(n.x);
\r
85 vertices.push_back(n.y);
\r
86 vertices.push_back(n.z);
\r
89 for (int i = 0; i < scene->mMeshes[0]->mNumFaces; i++) {
\r
90 aiFace f = scene->mMeshes[0]->mFaces[i];
\r
91 for (int j = 0; j < f.mNumIndices; j++) {
\r
92 indices.push_back(f.mIndices[j]);
\r
100 sf::ContextSettings settings;
\r
101 settings.depthBits = 24;
\r
102 settings.antialiasingLevel = 0;
\r
103 settings.majorVersion = 4;
\r
104 settings.minorVersion = 6;
\r
106 sf::Window window(sf::VideoMode(800, 600), "Subsurface Scattering",
\r
107 sf::Style::Default, settings);
\r
108 window.setVerticalSyncEnabled(true);
\r
110 window.setActive(true);
\r
114 if (glewInit() != GLEW_OK) {
\r
117 load("models/Isotrop-upperjaw.ply", vertices, indices);
\r
121 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
\r
122 glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
\r
123 glCompileShader(vertexShader);
\r
127 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
\r
129 glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
\r
130 printf("Error compiling vertex shader: %s\n", infoLog);
\r
133 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
\r
134 glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
\r
135 glCompileShader(fragmentShader);
\r
137 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
\r
139 glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
\r
140 printf("Error compiling fragment shader: %s\n", infoLog);
\r
143 // Link Shader Program
\r
145 GLuint shaderProgram = glCreateProgram();
\r
146 glAttachShader(shaderProgram, vertexShader);
\r
147 glAttachShader(shaderProgram, fragmentShader);
\r
148 glLinkProgram(shaderProgram);
\r
150 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
\r
152 glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
\r
153 printf("Error linking shader program: %s\n", infoLog);
\r
156 glDeleteShader(vertexShader);
\r
157 glDeleteShader(fragmentShader);
\r
162 glGenBuffers(1, &VBO);
\r
167 glGenBuffers(1, &EBO);
\r
172 glGenVertexArrays(1, &VAO);
\r
174 glBindVertexArray(VAO);
\r
176 glBindBuffer(GL_ARRAY_BUFFER, VBO);
\r
177 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(),
\r
178 vertices.data(), GL_STATIC_DRAW);
\r
180 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
\r
181 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(),
\r
182 indices.data(), GL_STATIC_DRAW);
\r
184 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)0);
\r
185 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)3);
\r
186 glEnableVertexAttribArray(0);
\r
188 glBindVertexArray(0);
\r
192 glm::mat4 model = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));
\r
195 glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -3.0f));
\r
198 glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 1000.0f);
\r
200 bool wireframe = false;
\r
202 bool running = true;
\r
205 while (window.pollEvent(event)) {
\r
206 if (event.type == sf::Event::Closed) {
\r
208 } else if (event.type == sf::Event::Resized) {
\r
209 glViewport(0, 0, event.size.width, event.size.height);
\r
210 } else if (event.type == sf::Event::KeyReleased) {
\r
211 using keys = sf::Keyboard;
\r
212 switch (event.key.code) {
\r
214 wireframe = !wireframe;
\r
223 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
225 glEnable(GL_DEPTH_TEST);
\r
228 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
\r
230 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
\r
232 glUseProgram(shaderProgram);
\r
234 model = glm::rotate(model, glm::radians(0.2f), glm::vec3(0.0f, 1.0f, 0.0f));
\r
236 glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1,
\r
237 GL_FALSE, glm::value_ptr(model));
\r
238 glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE,
\r
239 glm::value_ptr(view));
\r
240 glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1,
\r
241 GL_FALSE, glm::value_ptr(proj));
\r
243 glUniform3f(glGetUniformLocation(shaderProgram, "objectColor"), 1.0f, 0.5f,
\r
245 glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"), 1.0f, 1.0f,
\r
247 glUniform3fv(glGetUniformLocation(shaderProgram, "lightPos"), 1, glm::value_ptr(lightPos));
\r
249 glBindVertexArray(VAO);
\r
250 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
\r
251 glBindVertexArray(0);
\r