#include "glew.h" #include "freeglut.h" #include "glm.hpp" #include "ext.hpp" #include #include #include #include "Shader_Loader.h" #include "Render_Utils.h" #include "Camera.h" #include "Texture.h" #include "Physics.h" #include "Skybox.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" Core::Shader_Loader shaderLoader; GLuint programColor; GLuint programTexture; GLuint programSkybox; GLuint cubemapTexture; GLuint skyboxVAO, skyboxVBO; obj::Model planeModel; obj::Model boxModel; obj::Model shipModel; obj::Model boosterModel; obj::Model platformModel; obj::Model craneModel; obj::Model lampModel; glm::mat4 boxModelMatrix; GLuint boxTexture, groundTexture, shipTexture, stoneTexture, redTex; Core::RenderContext planeContext, boxContext, shipContext, boosterContext, platformContext, craneContext, lampContext; glm::vec3 cameraPos = glm::vec3(0, 10, 25); glm::vec3 cameraDir; glm::vec3 cameraSide; float cameraAngle = 0; glm::mat4 cameraMatrix, perspectiveMatrix; glm::vec3 lightDir = glm::normalize(glm::vec3(0.5, -1, -0.5)); glm::vec3 lightPos = glm::vec3(-15.75, 2, 0); // Initalization of physical scene (PhysX) Physics pxScene(9.8f /* gravity (m/s^2) */); // fixed timestep for stable and deterministic simulation const double physicsStepTime = 1.f / 60.f; double physicsTimeToProcess = 0; // physical objects PxRigidStatic *planeBody = nullptr; PxMaterial *planeMaterial = nullptr; PxRigidDynamic *boxBody = nullptr; PxMaterial *boxMaterial = nullptr; std::vector faces { "textures/skybox/stars.jpeg", "textures/skybox/stars.jpeg", "textures/skybox/stars.jpeg", "textures/skybox/stars.jpeg", "textures/skybox/stars.jpeg", "textures/skybox/stars.jpeg", }; void initRenderables() { // load models planeModel = obj::loadModelFromFile("models/plane.obj"); boxModel = obj::loadModelFromFile("models/box.obj"); shipModel = obj::loadModelFromFile("models/ship.obj"); boosterModel = obj::loadModelFromFile("models/booster.obj"); platformModel = obj::loadModelFromFile("models/platform4.obj"); craneModel = obj::loadModelFromFile("models/crane.obj"); lampModel = obj::loadModelFromFile("models/lamp2.obj"); // load textures groundTexture = Core::LoadTexture("textures/sand.jpg"); boxTexture = Core::LoadTexture("textures/a.jpg"); shipTexture = Core::LoadTexture("textures/ship.png"); stoneTexture = Core::LoadTexture("textures/stone.png"); redTex = Core::LoadTexture("textures/redTex.png"); planeContext.initFromOBJ(planeModel); boxContext.initFromOBJ(boxModel); shipContext.initFromOBJ(shipModel); boosterContext.initFromOBJ(boosterModel); platformContext.initFromOBJ(platformModel); craneContext.initFromOBJ(craneModel); lampContext.initFromOBJ(lampModel); } void initPhysicsScene() { } void updateTransforms() { // Here we retrieve the current transforms of the objects from the physical simulation. auto actorFlags = PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC; PxU32 nbActors = pxScene.scene->getNbActors(actorFlags); if (nbActors) { std::vector actors(nbActors); pxScene.scene->getActors(actorFlags, (PxActor**)&actors[0], nbActors); for (auto actor : actors) { // We use the userData of the objects to set up the proper model matrices. if (!actor->userData) continue; glm::mat4 *modelMatrix = (glm::mat4*)actor->userData; // get world matrix of the object (actor) PxMat44 transform = actor->getGlobalPose(); auto &c0 = transform.column0; auto &c1 = transform.column1; auto &c2 = transform.column2; auto &c3 = transform.column3; // set up the model matrix used for the rendering *modelMatrix = glm::mat4( c0.x, c0.y, c0.z, c0.w, c1.x, c1.y, c1.z, c1.w, c2.x, c2.y, c2.z, c2.w, c3.x, c3.y, c3.z, c3.w); } } } void keyboard(unsigned char key, int x, int y) { float angleSpeed = 0.1f; float moveSpeed = 0.5f; switch (key) { case 'z': cameraAngle -= angleSpeed; break; case 'x': cameraAngle += angleSpeed; break; case 'w': cameraPos += cameraDir * moveSpeed; break; case 's': cameraPos -= cameraDir * moveSpeed; break; case 'd': cameraPos += cameraSide * moveSpeed; break; case 'a': cameraPos -= cameraSide * moveSpeed; break; case 'e': cameraPos += glm::cross(cameraDir, glm::vec3(1, 0, 0)) * moveSpeed; break; case 'q': cameraPos -= glm::cross(cameraDir, glm::vec3(1, 0, 0)) * moveSpeed; break; } } void mouse(int x, int y) { } glm::mat4 createCameraMatrix() { cameraDir = glm::normalize(glm::vec3(cosf(cameraAngle - glm::radians(90.0f)), 0, sinf(cameraAngle - glm::radians(90.0f)))); glm::vec3 up = glm::vec3(0, 1, 0); cameraSide = glm::cross(cameraDir, up); return Core::createViewMatrix(cameraPos, cameraDir, up); } void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color) { GLuint program = programColor; glUseProgram(program); glUniform3f(glGetUniformLocation(program, "objectColor"), color.x, color.y, color.z); glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z); glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation); glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); Core::DrawContext(context); glUseProgram(0); } void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuint textureId) { GLuint program = programTexture; glUseProgram(program); glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z); glUniform3f(glGetUniformLocation(program, "lightPos"), lightPos.x, lightPos.y, lightPos.z); Core::SetActiveTexture(textureId, "textureSampler", program, 0); glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation); glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); Core::DrawContext(context); glUseProgram(0); } void renderScene() { double time = glutGet(GLUT_ELAPSED_TIME) / 1000.0; static double prevTime = time; double dtime = time - prevTime; prevTime = time; // Update physics if (dtime < 1.f) { physicsTimeToProcess += dtime; while (physicsTimeToProcess > 0) { // here we perform the physics simulation step pxScene.step(physicsStepTime); physicsTimeToProcess -= physicsStepTime; } } // Update of camera and perspective matrices cameraMatrix = createCameraMatrix(); perspectiveMatrix = Core::createPerspectiveMatrix(0.1f, 1000.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0f, 0.1f, 0.3f, 1.0f); glUseProgram(programTexture); // Drawing skybox Skybox::drawSkybox(programSkybox, cameraMatrix, perspectiveMatrix, cubemapTexture); glUniform3f(glGetUniformLocation(programTexture, "lightPos"), 0, 0, 0); // update transforms from physics simulation updateTransforms(); // render models drawObjectTexture(planeContext, glm::translate(glm::vec3(0, 0, 0)), groundTexture); drawObjectTexture(shipContext, glm::translate(glm::vec3(0,3,0)), shipTexture); // boxModelMatrix was updated in updateTransforms() drawObjectTexture(boosterContext, glm::translate(glm::vec3(0, 3, 0)), shipTexture); drawObjectTexture(platformContext, glm::rotate(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f)), stoneTexture); drawObjectTexture(craneContext, glm::rotate(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f)), redTex); drawObjectColor(lampContext, glm::translate(glm::vec3(lightPos)) * glm::rotate(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f)), glm::vec3(1, 1, 1)); glutSwapBuffers(); } void init() { srand((unsigned int)time(0)); glEnable(GL_DEPTH_TEST); programColor = shaderLoader.CreateProgram("shaders/shader_color.vert", "shaders/shader_color.frag"); programTexture = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag"); programSkybox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag"); cubemapTexture = Skybox::loadCubemap(faces); initRenderables(); initPhysicsScene(); } void shutdown() { shaderLoader.DeleteProgram(programColor); shaderLoader.DeleteProgram(programTexture); planeContext.initFromOBJ(planeModel); boxContext.initFromOBJ(boxModel); shipContext.initFromOBJ(shipModel); boosterContext.initFromOBJ(boosterModel); platformContext.initFromOBJ(platformModel); craneContext.initFromOBJ(craneModel); lampContext.initFromOBJ(lampModel); } void idle() { glutPostRedisplay(); } int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200, 200); glutInitWindowSize(600, 600); glutCreateWindow("Projekt"); glewInit(); init(); glutKeyboardFunc(keyboard); glutPassiveMotionFunc(mouse); glutDisplayFunc(renderScene); glutIdleFunc(idle); glutMainLoop(); shutdown(); return 0; }