Remove cmake
[opengl.git] / main.cpp
index 635e182dedd1ab047252afc38640c91dfb30b522..aa78a224281b54efff84c3012daaa587b6add1fb 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -5,7 +5,6 @@
 #include <vector>
 #ifdef __APPLE__
 #include <GL/glew.h>
-#include "cocoa.h"
 #else
 #include <OpenGL/glew.h>
 #endif
@@ -14,6 +13,9 @@
 #include <glm/glm.hpp>
 #include <glm/ext.hpp>
 #include <glm/gtc/type_ptr.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
 #include "model.hpp"
 #include "program.hpp"
 #include "skybox.hpp"
@@ -30,11 +32,11 @@ Program *textureProg, *plainProg, *reflectProg, *pbrProg;
 std::vector<Skybox> skyboxes;
 int activeSkybox = 0;
 
-Model *chest, *mirrorCube, *pbr;
+Assimp::Importer importer; // Need to keep this around, otherwise stuff disappears!
+Model *sceneModel;
 
-glm::vec3 camPos   = glm::vec3(0.0f, 0.0f,  -5.f);
-glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 1.0f);
-glm::vec3 camUp    = glm::vec3(0.0f, 1.0f,  0.0f);
+glm::vec3 camPos = {0, 0, -5}, camFront = {0, 0, 1}, camUp = {0, 1, 0};
+float fov = glm::radians(30.f), znear = 0.01f, zfar = 10000.f;
 float yaw = 1.57, pitch = 0;
 
 struct Light {
@@ -43,14 +45,15 @@ struct Light {
 };
 
 std::vector<Light> lights = {
-       { glm::vec3(0, 0, 3), glm::vec3(1) },
-       { glm::vec3(0, 3, 0), glm::vec3(1) },
-       { glm::vec3(3, 0, 0), glm::vec3(1) },
-       { glm::vec3(3, 0, 0), glm::vec3(1) }
+       { glm::vec3(5, 2, -5), glm::vec3(1) },
+       { glm::vec3(0, 2, -5), glm::vec3(1) },
+       { glm::vec3(-5, 2, -5), glm::vec3(1) },
 };
 
 int activeLight = 0;
 
+bool discoLights = false;
+
 int windowWidth = 800, windowHeight = 600;
 
 float aspect() {
@@ -58,7 +61,7 @@ float aspect() {
 }      
 
 glm::mat4 projMat() {
-       return glm::perspective(glm::radians(45.f), aspect(), 0.01f, 10000.f);
+       return glm::perspective(fov, aspect(), znear, zfar);
 }
 
 glm::mat4 viewMat() {
@@ -115,19 +118,44 @@ void display() {
        glUseProgram(pbrProg->progId);
        setProjectionAndViewUniforms(pbrProg->progId);
 
-       glm::vec3 lightPositions[4], lightColors[4];
-       for (int i = 0; i < 4; i++) {
+       glm::vec3 lightPositions[6], lightColors[6];
+       for (int i = 0; i < 3; i++) {
                lightPositions[i] = lights[i].pos;
                lightColors[i] = lights[i].color;
        }
 
-       glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightPositions"), 4, glm::value_ptr(lightPositions[0]));
-       glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightColors"), 4, glm::value_ptr(lightColors[0]));
+       for (int i = 3; i < 6; i++) {
+               if (discoLights) {
+                       auto m = glm::translate(glm::mat4(1.f), glm::vec3(-2.5, 0, 0));
+                       m = glm::rotate(m, glm::radians(d * 100 + i * 30), glm::vec3(1, 0, 0));
+                       m = glm::rotate(m, glm::radians(d * 100 + i * 30), glm::vec3(0, 1, 0));
+                       m = glm::rotate(m, glm::radians(d * 100 + i * 30), glm::vec3(0, 0, 1));
+                       lightPositions[i] = glm::vec3(m * glm::vec4(5, 0, 0, 1));
+                       lightColors[i] = glm::vec3(0.2);
+                       if (i == 3) lightColors[i].x = sin(d);
+                       if (i == 4) lightColors[i].y = cos(d * 3);
+                       if (i == 5) lightColors[i].z = cos(d);
+               } else {
+                       lightPositions[i] = glm::vec3(0);
+                       lightColors[i] = glm::vec3(0);
+               }
+       }
+       
+       glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightPositions"), 6, glm::value_ptr(lightPositions[0]));
+       glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightColors"), 6, glm::value_ptr(lightColors[0]));
 
-       pbr->draw(skyboxes[activeSkybox], d * 1000);
+       /* pbr->getRoot()->model = glm::rotate(glm::mat4(1.f), glm::radians(d * 10), glm::vec3(0, 1, 0)); */
+        sceneModel->draw(skyboxes[activeSkybox], d * 1000);
 
         for (Light &light: lights) drawLight(light);
 
+       if (discoLights) {
+               for (int i = 3; i < 6; i++) {
+                       Light l { lightPositions[i], lightColors[i] };
+                       drawLight(l);
+               }
+       }
+
        skyboxes[activeSkybox].draw(projMat(), viewMat());
 
        glutSwapBuffers();
@@ -149,19 +177,61 @@ void setupLightBuffers(GLuint progId) {
        glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
 }
 
+int findNodeTrans(struct aiNode *n, const struct aiString name, glm::mat4 *dest) {
+       if (strcmp(n->mName.data, name.data) == 0) {
+               *dest = aiMatrixToMat4(n->mTransformation);
+               return 0;
+       }
+       for (int i = 0; i < n->mNumChildren; i++) {
+               if (findNodeTrans(n->mChildren[i], name, dest) == 0) {
+                       glm::mat4 t = aiMatrixToMat4(n->mTransformation);
+                       *dest = t * *dest;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
 void init() {
        plainProg = new Program("plainvertex.glsl", "plainfrag.glsl");
        glUseProgram(plainProg->progId);
        setupLightBuffers(plainProg->progId);
        plainProg->validate();
 
-       skyboxes.push_back(Skybox(Image("skyboxes/loft/Newport_Loft_Ref.hdr")));
-       skyboxes.push_back(Skybox(Image("skyboxes/monumentValley/Road_to_MonumentValley_Ref.hdr")));
-       skyboxes.push_back(Skybox(Image("skyboxes/factory/Factory_Catwalk_2k.hdr")));
+       skyboxes.push_back(Skybox(Image("skyboxes/wooden_lounge_8k.hdr")));
+       skyboxes.push_back(Skybox(Image("skyboxes/machine_shop_02_8k.hdr")));
+       skyboxes.push_back(Skybox(Image("skyboxes/pink_sunrise_8k.hdr")));
 
        pbrProg = new Program("pbrvert.glsl", "pbrfrag.glsl");
        glUseProgram(pbrProg->progId);
-       pbr = new Model("models/newtonsCradle.gltf", *pbrProg);
+
+       const std::string scenePath = "models/ik.glb";
+       const aiScene *scene = importer.ReadFile(scenePath, aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_FlipUVs);
+       if (!scene) {
+               std::cerr << importer.GetErrorString() << std::endl;
+               exit(1);
+       }
+
+       if (scene->mNumCameras > 0) {
+               struct aiCamera *cam = scene->mCameras[0];
+               glm::mat4 camTrans;
+               if (findNodeTrans(scene->mRootNode, cam->mName, &camTrans) != 0)
+                       abort(); // there must be a node with the same name as camera
+
+               camPos = { camTrans[3][0], camTrans[3][1], camTrans[3][2] };
+
+               glm::vec3 camLookAt = glm::vec3(cam->mLookAt.x, cam->mLookAt.y, cam->mLookAt.z);
+               camFront = camLookAt - camPos;
+
+               camUp = glm::vec3(cam->mUp.x, cam->mUp.y, cam->mUp.z);
+               
+               fov = cam->mHorizontalFOV;
+               // TODO: aspectRatio = cam->mAspect;
+               znear = cam->mClipPlaneNear;
+               zfar = cam->mClipPlaneFar;
+       }
+
+       sceneModel = new Model(scene, *pbrProg);
 
        glEnable(GL_DEPTH_TEST); 
        glEnable(GL_CULL_FACE); 
@@ -171,7 +241,7 @@ void init() {
        glViewport(0, 0, windowWidth, windowHeight);
 }
 
-bool* keyStates = new bool[256];
+bool keyStates[256] = {false};
 
 void keyboard(unsigned char key, int x, int y) {
        keyStates[key] = true;
@@ -179,6 +249,8 @@ void keyboard(unsigned char key, int x, int y) {
                activeSkybox = (activeSkybox + 1) % skyboxes.size();
        if (key == 'x')
                activeLight = (activeLight + 1) % lights.size();
+       if (key == 'c')
+               discoLights = !discoLights;
 }
 
 void keyboardUp(unsigned char key, int x, int y) {
@@ -258,8 +330,7 @@ int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB|GLUT_3_2_CORE_PROFILE);
        glutInitWindowSize(windowWidth, windowHeight);
-       int win = glutCreateWindow("Physically Based Rendering");
-       makeRetina();
+       glutCreateWindow("Physically Based Rendering");
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);