147 lines
3.7 KiB
C++
147 lines
3.7 KiB
C++
#define NOMINMAX
|
|
#define _USE_MATH_DEFINES
|
|
#include <cmath>
|
|
|
|
#include <glad/glad.h>
|
|
#define GLFW_INCLUDE_GLU
|
|
#include <GLFW/glfw3.h>
|
|
|
|
#include "icosahedron.h"
|
|
#include "mesh_to_vao.h"
|
|
#include "print_opengl_info.h"
|
|
#include "get_seconds.h"
|
|
#include "report_gl_error.h"
|
|
#include "create_shader_program_from_files.h"
|
|
#include "last_modification_time.h"
|
|
|
|
#include <Eigen/Core>
|
|
#include <Eigen/Geometry>
|
|
|
|
#include <thread>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
// From CMAKE preprocessor
|
|
std::string cmakelists_dir = CMAKELISTS_SOURCE_DIR;
|
|
|
|
// Default width and height
|
|
int width = 640;
|
|
int height = 360;
|
|
GLuint prog_id = 0; // OpenGL index to shader
|
|
|
|
// some user input state
|
|
bool wire_frame = false;
|
|
bool mouse_down = false;
|
|
bool is_animating = true;
|
|
double last_time = 0;
|
|
double animation_seconds = 0;
|
|
Eigen::Affine3f view = Eigen::Affine3f::Identity() * Eigen::Translation3f(Eigen::Vector3f(0, 0, -10));
|
|
Eigen::Matrix4f proj = Eigen::Matrix4f::Identity();
|
|
GLuint VAO;
|
|
// Mesh data: RowMajor is important to directly use in OpenGL
|
|
Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor> V;
|
|
Eigen::Matrix<GLuint, Eigen::Dynamic, 3, Eigen::RowMajor> F;
|
|
|
|
// needs to be included here
|
|
#include "glHelper.h"
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
// Process command line args
|
|
int task = -1;
|
|
if (argc == 2) {
|
|
try {
|
|
task = std::stoi(argv[1]); // char* to int
|
|
std::cout << "Using glsl files for task " << task << std::endl;
|
|
}
|
|
catch (...) {
|
|
std::cout << "Error: failed to parse second argument to an int: " << argv[1] << std::endl;
|
|
}
|
|
}
|
|
if (task < 0 || task > 8) {
|
|
std::cout << "Usage:" << std::endl;
|
|
std::cout << " Unix: ./shaderpipeline <task nr>" << std::endl;
|
|
std::cout << " Windows: shaderpipeline.exe <task nr>" << std::endl;
|
|
std::cout << "where <task nr> is an int in [0, 8]" << std::endl;
|
|
std::cout << "For example: ./shaderpipeline 0" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
GlHelper glHelper(task);
|
|
|
|
GLFWwindow* window = glHelper.createWindow();
|
|
if (!window) {
|
|
return -1;
|
|
}
|
|
print_opengl_info(window);
|
|
igl::opengl::report_gl_error("init");
|
|
|
|
glHelper.setPerspectiveMatrixBasedOnWindowScale();
|
|
|
|
glHelper.createVAO();
|
|
|
|
glHelper.setKeyboardAndMouseCallbacks();
|
|
|
|
// Enable depth testing and delete faces seen from the back
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
// Bind the VAO, which knows where to find the vertex and triangle data
|
|
glBindVertexArray(VAO);
|
|
|
|
// Main display routine
|
|
while (!glfwWindowShouldClose(window))
|
|
{
|
|
double tic = get_seconds();
|
|
|
|
// Compile the glsl files into a shader program
|
|
if (!glHelper.compileShaderIfChanged()) {
|
|
std::cout << "Error: failed to compile shader" << std::endl;
|
|
break;
|
|
}
|
|
|
|
// Clear screen
|
|
glClearColor(0, 0, 0, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
// Set viewport and output framebuffer size
|
|
glfwGetFramebufferSize(window, &::width, &::height);
|
|
glViewport(0, 0, ::width, ::height);
|
|
|
|
// Update the uniforms used in the GLSL shaders
|
|
glHelper.updateShaderUniforms();
|
|
|
|
// Render an icosahedron for the planet and moon
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
// Set the shader uniform "is_moon"
|
|
glUniform1i(glGetUniformLocation(prog_id, "is_moon"), i == 1);
|
|
|
|
// Draw the vertices in the VAO
|
|
glDrawElements(GL_PATCHES, F.size(), GL_UNSIGNED_INT, 0);
|
|
}
|
|
|
|
// Swap the front and back buffers
|
|
glfwSwapBuffers(window);
|
|
|
|
// 60 fps
|
|
{
|
|
glfwPollEvents();
|
|
double duration = 1000000. * (get_seconds() - tic); // In microseconds
|
|
const double min_duration = 1000000. / 60.;
|
|
if (duration < min_duration)
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::microseconds((int)(min_duration - duration)));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Graceful exit
|
|
glfwDestroyWindow(window);
|
|
glfwTerminate();
|
|
return 1;
|
|
}
|