diff --git a/grafika_projekt/src/Render_Utils.h b/grafika_projekt/src/Render_Utils.h index 052008d..2b142df 100644 --- a/grafika_projekt/src/Render_Utils.h +++ b/grafika_projekt/src/Render_Utils.h @@ -10,6 +10,8 @@ namespace Core { + + struct RenderContext { GLuint vertexArray; @@ -22,6 +24,11 @@ namespace Core void initFromAssimpMesh(aiMesh* mesh); }; + struct Node { + std::vector renderContexts; + glm::mat4 matrix; + int parent; + }; // vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...) // numVertices - liczba wierzcholkow do narysowania // elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z)) diff --git a/grafika_projekt/src/main.cpp b/grafika_projekt/src/main.cpp index 602e66f..0378314 100644 --- a/grafika_projekt/src/main.cpp +++ b/grafika_projekt/src/main.cpp @@ -19,6 +19,7 @@ GLuint programColor; GLuint programTexture; GLuint textureSubmarine; GLuint textureBubble; +GLuint textureFish; unsigned int cubemapTexture, skyboxVAO; unsigned int cubeVAO, cubeVBO; @@ -36,8 +37,21 @@ glm::mat4 cameraMatrix, perspectiveMatrix; Core::Shader_Loader shaderLoader; Core::RenderContext submarineContext; +Core::RenderContext fishContext; Core::RenderContext bubbleContext; +std::vector keyPoints({ +glm::vec3(15.0f, 5.0f, 15.0f), +glm::vec3(15.0f, 5.0f, -15.0f), +glm::vec3(-15.0f, 5.0f, -15.0f), +glm::vec3(-15.0f, 5.0f, 15.0f), +glm::vec3(15.0f, 5.0f, 15.0f), + }); + +std::vector keyRotation; + +std::vector fish; + std::string skyboxTextures[6] = { "models/skybox/right.jpg", "models/skybox/left.jpg", @@ -210,6 +224,45 @@ glm::mat4 createCameraMatrix() return Core::createViewMatrixQuat(cameraPos, rotation); } +glm::mat4 animationMatrix(float time) { + float speed = 1.; + time = time * speed; + std::vector distances; + float timeStep = 0; + for (int i = 0; i < keyPoints.size() - 1; i++) { + timeStep += (keyPoints[i] - keyPoints[i + 1]).length(); + distances.push_back((keyPoints[i] - keyPoints[i + 1]).length()); + } + time = fmod(time, timeStep); + + //index of first keyPoint + int index = 0; + + while (distances[index] <= time) { + time = time - distances[index]; + index += 1; + } + + float t = time / distances[index]; + + int size = keyPoints.size(); + int rotationSize = keyRotation.size(); + + + glm::vec3 pos = glm::catmullRom(keyPoints[std::max(0, (index-1)%size)], keyPoints[(index) % size], keyPoints[(index + 1) % size], keyPoints[(index + 2) % size], t); + + glm::quat divideByFour = glm::quat(0.25f, 0.25f, 0.25f, 0.25f); + auto a1 = keyRotation[index % rotationSize] * glm::exp(-(glm::log(glm::inverse(keyRotation[index % rotationSize]) * keyRotation[std::max(0, (index - 1)%rotationSize)]) + glm::log(glm::inverse(keyRotation[index % rotationSize]) * keyRotation[(index + 1) % rotationSize])) * divideByFour); + + auto a2 = keyRotation[(index + 1) % rotationSize] * glm::exp(-(glm::log(glm::inverse(keyRotation[(index + 1) % rotationSize]) * keyRotation[index % rotationSize]) + glm::log(glm::inverse(keyRotation[(index + 1) % rotationSize]) * keyRotation[(index + 2) % rotationSize])) * divideByFour); + + auto animationRotation = glm::squad(keyRotation[index % rotationSize], keyRotation[(index + 1) % rotationSize], a1, a2, t); + + glm::mat4 result = glm::translate(pos) * glm::mat4_cast(animationRotation); + + return result; +} + void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color) { GLuint program = programColor; @@ -252,7 +305,7 @@ void renderScene() perspectiveMatrix = Core::createPerspectiveMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f; glUseProgram(skyboxProgram); glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0); glm::mat4 transformation = perspectiveMatrix * cameraMatrix; @@ -261,22 +314,24 @@ void renderScene() glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); glDrawArrays(GL_TRIANGLES, 0, 36); - glUseProgram(skyboxProgram); - glBindVertexArray(0); - glBindVertexArray(cubeVAO); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); + //glUseProgram(skyboxProgram); + //glBindVertexArray(0); + //glBindVertexArray(cubeVAO); + //glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); + //glDrawArrays(GL_TRIANGLES, 0, 36); + //glBindVertexArray(0); glm::mat4 submarineInitialTransformation = glm::translate(glm::vec3(0, -0.5, -0.4)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f)); glm::mat4 submarineModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * submarineInitialTransformation; - //drawObjectColor(fishContext, fishModelMatrix, glm::vec3(0.6f)); - drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine); - glm::mat4 bubbleInitialTransformation = glm::translate(glm::vec3(1, 0, -0.5)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.005f)); - drawObjectTexture(bubbleContext, bubbleInitialTransformation, textureBubble); + glm::mat4 fishInitialTransformation = glm::translate(glm::vec3(0, 0, 0)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f)); + glm::mat4 bubbleModelMatrix = glm::translate(glm::vec3(0, 0, 0)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.05f)); + + drawObjectTexture(bubbleContext, bubbleModelMatrix, textureBubble); + drawObjectTexture(fishContext, animationMatrix(time + 15), textureFish); + drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine); glutSwapBuffers(); } @@ -343,6 +398,26 @@ void initSkybox() glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); } +void initKeyRotation() { + glm::vec3 oldDirection = glm::vec3(0, 0, 1); + glm::quat oldRotationCamera = glm::quat(1, 0, 0, 0); + glm::vec3 direction; + glm::quat rotation; + for (int i = 0; i < keyPoints.size() - 1; i++) { + //3.1 + direction = glm::normalize(keyPoints[i + 1] - keyPoints[i]); + //3.2 + rotation = glm::normalize(glm::rotationCamera(oldDirection, direction) * oldRotationCamera); + //3.3 + keyRotation.push_back(rotation); + //3.4 + oldDirection = direction; + oldRotationCamera = rotation; + } + keyRotation.push_back(glm::quat(1, 0, 0, 0)); + keyRotation.push_back(glm::quat(1, -1, 1, 1)); +} + void initCube() { glGenVertexArrays(1, &cubeVAO); @@ -364,10 +439,18 @@ void init() skyboxProgram = shaderLoader.CreateProgram((char *) "shaders/skybox.vert", (char *) "shaders/skybox.frag"); cubeProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag"); cubemapTexture = loadCubemap(); + + loadModelToContext("models/submarine.obj", submarineContext); + textureSubmarine = Core::LoadTexture("textures/submarine.png"); + + loadModelToContext("models/fish.obj", fishContext); + textureFish = Core::LoadTexture("textures/fish.png"); + + initKeyRotation(); loadModelToContext("models/submarine.obj", submarineContext); textureSubmarine = Core::LoadTexture("textures/submarine.png"); loadModelToContext("models/sphere.obj", bubbleContext); - textureBubble = Core::LoadTexture("textures/fish.png"); + textureBubble = Core::LoadTexture("textures/bubble.png"); initCube(); initSkybox(); @@ -386,7 +469,6 @@ void idle() } - int main(int argc, char** argv) { glutInit(&argc, argv); diff --git a/grafika_projekt/textures/bubble.png b/grafika_projekt/textures/bubble.png new file mode 100644 index 0000000..16ddc8f Binary files /dev/null and b/grafika_projekt/textures/bubble.png differ diff --git a/grafika_projekt/textures/fish_texture.png b/grafika_projekt/textures/fish.png similarity index 100% rename from grafika_projekt/textures/fish_texture.png rename to grafika_projekt/textures/fish.png