diff --git a/grafika_projekt/grafika_projekt.vcxproj b/grafika_projekt/grafika_projekt.vcxproj index 68ed12b..caf784f 100644 --- a/grafika_projekt/grafika_projekt.vcxproj +++ b/grafika_projekt/grafika_projekt.vcxproj @@ -142,6 +142,7 @@ + @@ -155,6 +156,7 @@ + diff --git a/grafika_projekt/grafika_projekt.vcxproj.filters b/grafika_projekt/grafika_projekt.vcxproj.filters index 9fa44ef..4abfd2a 100644 --- a/grafika_projekt/grafika_projekt.vcxproj.filters +++ b/grafika_projekt/grafika_projekt.vcxproj.filters @@ -48,6 +48,9 @@ Source Files + + Source Files + @@ -95,6 +98,9 @@ Header Files + + Header Files + diff --git a/grafika_projekt/src/Engine.cpp b/grafika_projekt/src/Engine.cpp new file mode 100644 index 0000000..461c890 --- /dev/null +++ b/grafika_projekt/src/Engine.cpp @@ -0,0 +1,180 @@ +#include "Engine.h" + + +void Core::Engine::initShaderPrograms() { + this->textureShader = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.frag"); + this->skyboxShader = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag"); + this->bubbleShader = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag"); +} + +void Core::Engine::shutdownShaderPrograms() { + shaderLoader.DeleteProgram(this->textureShader); + shaderLoader.DeleteProgram(this->skyboxShader); + shaderLoader.DeleteProgram(this->bubbleShader); +} + +void Core::Engine::initRenderContexts() { + loadModelToContext("models/fish.obj", this->fishContext); + loadModelToContext("models/submarine.obj", this->submarineContext); + loadModelToContext("models/sphere.obj", this->bubbleContext); + + this->terrain = Terrain(this->heightGenerator); + obj::Model model = this->terrain.generateTerrain(); + this->terrainContext.initFromOBJ(model); +} + +void Core::Engine::loadTextures() { + this->fishTexture = LoadTexture("textures/fish.png"); + this->submarineTexture = LoadTexture("textures/submarine.png"); + this->bubbleTexture = LoadTexture("textures/bubble.png"); + this->terrainTexture = LoadTexture("textures/terrain.jpg"); + this->skyboxTexture = loadCubemap(); +} + +void Core::Engine::initCube() { + GLuint cubeVAO, cubeVBO; + glGenVertexArrays(1, &cubeVAO); + glGenBuffers(1, &cubeVBO); + glBindVertexArray(cubeVAO); + glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(this->cubeVertices), &this->cubeVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); +} + +void Core::Engine::initSkybox() { + this->initCube(); + glGenVertexArrays(1, &this->skyboxVAO); + glBindVertexArray(this->skyboxVAO); + + glGenBuffers(1, &this->skyboxVBO); + glBindBuffer(GL_ARRAY_BUFFER, this->skyboxVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(this->skyboxVertices), &this->skyboxVertices, GL_STATIC_DRAW); + + GLuint vPosition = glGetAttribLocation(this->skyboxShader, "aPos"); + glEnableVertexAttribArray(vPosition); + + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(this->skyboxVertices), this->skyboxVertices); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); +} + +void Core::Engine::initRandomGenerator(std::default_random_engine gen, std::uniform_int_distribution<> distr) { + this->gen = gen; + this->distr = distr; +} + + +std::vector Core::Engine::genBubbleKeyPoints() { + float random1 = this->distr(this->gen); + float random2 = this->distr(this->gen); + std::vector bubbleKeyPoints({ + glm::vec3(random1 , -this->skyboxVerticeParameter, random2), + glm::vec3(random1 , this->skyboxVerticeParameter, random2) + } + ); + return bubbleKeyPoints; +}; + +void Core::Engine::generateBubbleArray() { + for (int i = 0; i < 300; i++) { + this->bubbleArray[i] = this->genBubbleKeyPoints(); + } +} + +void Core::Engine::initBubbles() { + this->generateBubbleArray(); +} + +const float Core::Engine::cubeVertices[216] = { + // positions // normals + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f +}; + +const float Core::Engine::skyboxVerticeParameter = 50.0f; + +const float Core::Engine::skyboxVertices[108] = { + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, + -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, + + -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, + -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, + skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter +}; \ No newline at end of file diff --git a/grafika_projekt/src/Engine.h b/grafika_projekt/src/Engine.h new file mode 100644 index 0000000..b555dcf --- /dev/null +++ b/grafika_projekt/src/Engine.h @@ -0,0 +1,43 @@ +#pragma once +#include "glm.hpp" +#include "glew.h" +#include +#include +#include "Shader_Loader.h" +#include "Texture.h" +#include "Render_Utils.h" +#include "Terrain.h" +#include "HeightGenerator.h" +#include + + +namespace Core { + class Engine { + public: + GLuint textureShader, skyboxShader, bubbleShader; + GLuint submarineTexture, bubbleTexture, fishTexture, terrainTexture, skyboxTexture; + GLuint skyboxVAO; + Core::RenderContext submarineContext, fishContext, bubbleContext, terrainContext; + std::vector bubbleArray[300]; + void initShaderPrograms(); + void shutdownShaderPrograms(); + void initRenderContexts(); + void loadTextures(); + void initSkybox(); + void initBubbles(); + void initRandomGenerator(std::default_random_engine gen, std::uniform_int_distribution<> distr); + static const float skyboxVerticeParameter; + private: + HeightGenerator heightGenerator; + GLuint skyboxVBO; + Terrain terrain; + Shader_Loader shaderLoader; + static const float cubeVertices[216], skyboxVertices[108]; + std::uniform_int_distribution<> distr; + std::default_random_engine gen; + void initCube(); + void generateBubbleArray(); + std::vector genBubbleKeyPoints(); + }; + +} \ No newline at end of file diff --git a/grafika_projekt/src/Render_Utils.cpp b/grafika_projekt/src/Render_Utils.cpp index 39869d3..bcfe787 100644 --- a/grafika_projekt/src/Render_Utils.cpp +++ b/grafika_projekt/src/Render_Utils.cpp @@ -8,7 +8,6 @@ #include #include - void Core::RenderContext::initFromOBJ(obj::Model& model) { vertexArray = 0; @@ -167,3 +166,80 @@ void Core::DrawContext(Core::RenderContext& context) ); glBindVertexArray(0); } + +void Core::loadModelToContext(std::string path, Core::RenderContext& context) +{ + Assimp::Importer import; + const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace); + + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl; + return; + } + context.initFromAssimpMesh(scene->mMeshes[0]); +} + +GLuint Core::loadCubemap() +{ + std::string skyboxTextures[6] = { + "models/skybox/right.jpg", + "models/skybox/left.jpg", + "models/skybox/top.jpg", + "models/skybox/bottom.jpg", + "models/skybox/front.jpg", + "models/skybox/back.jpg" + }; + GLuint textureID; + glGenTextures(1, &textureID); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + int width, height, nrChannels; + for (unsigned int i = 0; i < 6; i++) + { + unsigned char* data = stbi_load(skyboxTextures[i].c_str(), &width, &height, &nrChannels, STBI_rgb_alpha); + if (data) + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data + ); + stbi_image_free(data); + } + else + { + std::cout << stbi_failure_reason() << std::endl; + std::cout << "Cubemap tex failed to load at path: " << skyboxTextures[i] << std::endl; + stbi_image_free(data); + } + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + return textureID; +} + +void Core::drawObjectTexture( + Core::RenderContext context, + glm::mat4 modelMatrix, + GLuint textureId, + GLuint program, + glm::vec3 lightDir, + glm::mat4 cameraMatrix, + glm::mat4 perspectiveMatrix +) { + glUseProgram(program); + + glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.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); +} diff --git a/grafika_projekt/src/Render_Utils.h b/grafika_projekt/src/Render_Utils.h index 2b142df..04bf927 100644 --- a/grafika_projekt/src/Render_Utils.h +++ b/grafika_projekt/src/Render_Utils.h @@ -5,12 +5,15 @@ #include #include #include +#include "SOIL/stb_image_aug.h" +#include "Texture.h" +#define STB_IMAGE_IMPLEMENTATION + #define BUFFER_OFFSET(i) ((char *)NULL + (i)) namespace Core { - struct RenderContext { @@ -76,4 +79,18 @@ namespace Core void DrawVertexArray(const VertexData & data); void DrawContext(RenderContext& context); + + void loadModelToContext(std::string path, Core::RenderContext& context); + + void drawObjectTexture( + Core::RenderContext context, + glm::mat4 modelMatrix, + GLuint textureId, + GLuint program, + glm::vec3 lightDir, + glm::mat4 cameraMatrix, + glm::mat4 perspectiveMatrix + ); + + GLuint loadCubemap(); } \ No newline at end of file diff --git a/grafika_projekt/src/main.cpp b/grafika_projekt/src/main.cpp index c3b48a2..968175f 100644 --- a/grafika_projekt/src/main.cpp +++ b/grafika_projekt/src/main.cpp @@ -1,4 +1,3 @@ -#define STB_IMAGE_IMPLEMENTATION #include "glew.h" #include "freeglut.h" #include "glm.hpp" @@ -14,27 +13,15 @@ #include "SOIL/stb_image_aug.h" #include "HeightGenerator.h" #include "Terrain.h" +#include "Engine.h" -GLuint skyboxProgram, skyboxBuffer; -GLuint bubbleProgram; -GLuint programTexture; +Core::Engine engine; -GLuint terrainProgram; -Terrain terrain; -GLuint textureSubmarine; -GLuint textureBubble; -GLuint textureFish; - -unsigned int cubemapTexture, skyboxVAO; -unsigned int cubeVAO, cubeVBO; - -float skyboxVerticeParameter = 50.0f; float skyboxBoundary = 48.0f; -std::vector bubbleArray[300]; float old_x, old_y = -1; glm::vec3 cursorDiff; -glm::vec3 lightDir = glm::normalize(glm::vec3(0.0f, skyboxVerticeParameter, 0.0f)); +glm::vec3 lightDir = glm::normalize(glm::vec3(0.0f, engine.skyboxVerticeParameter, 0.0f)); glm::vec3 cameraPos = glm::vec3(0, 0, 0); glm::vec3 oldCameraPos = glm::vec3(0, 0, 5); @@ -46,164 +33,31 @@ glm::quat rotation = glm::quat(1, 0, 0, 0); glm::mat4 cameraMatrix, perspectiveMatrix; -Core::Shader_Loader shaderLoader; -Core::RenderContext submarineContext; -Core::RenderContext fishContext; -Core::RenderContext bubbleContext; -Core::RenderContext terrainContext; - -GLuint textureTerrain; -HeightGenerator heightGenerator; - std::vector fishKeyPoints({ -glm::vec3(-18.0f, -10.0f, -10.0f), -glm::vec3(-10.0f, -5.0f, -12.0f), -glm::vec3(8.0f, -3.0f, -3.0f), -glm::vec3(5.0f, 0.0f, 3.0f), -glm::vec3(3.0f, 2.0f, 4.0f), -glm::vec3(8.0f, 5.0f, 9.0f), -glm::vec3(14.0f, 6.0f, 15.0f), -glm::vec3(15.0f, 12.0f, 12.0f), -glm::vec3(10.0f, 17.0f, 15.0f), -glm::vec3(5.0f, 10.0f, 7.0f), -glm::vec3(-1.0f, 4.0f, 8.0f), -glm::vec3(-8.0f, 0.0f, 3.0f), -glm::vec3(-12.0f, -6.0f, -3.0f), -glm::vec3(-15.0f, -8.0f, -6.0f), -glm::vec3(-18.0f, -10.0f, -10.0f), - }); + glm::vec3(-18.0f, -10.0f, -10.0f), + glm::vec3(-10.0f, -5.0f, -12.0f), + glm::vec3(8.0f, -3.0f, -3.0f), + glm::vec3(5.0f, 0.0f, 3.0f), + glm::vec3(3.0f, 2.0f, 4.0f), + glm::vec3(8.0f, 5.0f, 9.0f), + glm::vec3(14.0f, 6.0f, 15.0f), + glm::vec3(15.0f, 12.0f, 12.0f), + glm::vec3(10.0f, 17.0f, 15.0f), + glm::vec3(5.0f, 10.0f, 7.0f), + glm::vec3(-1.0f, 4.0f, 8.0f), + glm::vec3(-8.0f, 0.0f, 3.0f), + glm::vec3(-12.0f, -6.0f, -3.0f), + glm::vec3(-15.0f, -8.0f, -6.0f), + glm::vec3(-18.0f, -10.0f, -10.0f) +}); std::vector keyRotation; -std::vector fish; - -std::string skyboxTextures[6] = { - "models/skybox/right.jpg", - "models/skybox/left.jpg", - "models/skybox/top.jpg", - "models/skybox/bottom.jpg", - "models/skybox/front.jpg", - "models/skybox/back.jpg" -}; - - - -float cubeVertices[] = { - // positions // normals - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f -}; - -float skyboxVertices[] = { - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter, - -skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter, - - -skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter, - -skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter, - skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter -}; - - bool isInBoundaries(glm::vec3 nextPosition) { return nextPosition.z > -skyboxBoundary && nextPosition.z < skyboxBoundary&& nextPosition.y > -skyboxBoundary && nextPosition.y < skyboxBoundary&& nextPosition.x < skyboxBoundary&& nextPosition.x > -skyboxBoundary; } -std::default_random_engine gen(HeightGenerator::SEED); // seed the generator -std::uniform_int_distribution<> distr(-skyboxVerticeParameter, skyboxVerticeParameter); // define the range - -std::vector genBubbleKeyPoints() { - float random1 = distr(gen); - float random2 = distr(gen); - std::vector bubbleKeyPoints({ - glm::vec3(random1 , -skyboxVerticeParameter, random2), - glm::vec3(random1 , skyboxVerticeParameter, random2) - } - ); - return bubbleKeyPoints; -}; - -void generateBubbleArray() { - - for (int i = 0; i < 300; i++) { - bubbleArray[i] = genBubbleKeyPoints(); - } -} - void keyboard(unsigned char key, int x, int y) { float angleSpeed = 10.f; @@ -333,23 +187,6 @@ glm::mat4 animationMatrix(float time, glm::vec3 change, std::vector k return result; } -void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuint textureId, GLuint program) -{ - glUseProgram(program); - - glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.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() { cameraMatrix = createCameraMatrix(); @@ -359,14 +196,14 @@ void renderScene() glClearColor(0.219f, 0.407f, 0.658f, 1.0f); float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f; - glUseProgram(skyboxProgram); - glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0); + glUseProgram(engine.skyboxShader); + glUniform1i(glGetUniformLocation(engine.skyboxShader, "skybox"), 0); glm::mat4 transformation = perspectiveMatrix * cameraMatrix; - glUniformMatrix4fv(glGetUniformLocation(skyboxProgram, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation); - glBindVertexArray(skyboxVAO); + glUniformMatrix4fv(glGetUniformLocation(engine.skyboxShader, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation); + glBindVertexArray(engine.skyboxVAO); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); + glBindTexture(GL_TEXTURE_CUBE_MAP, engine.skyboxTexture); glDrawArrays(GL_TRIANGLES, 0, 36); glEnable(GL_BLEND); @@ -386,92 +223,29 @@ void renderScene() glm::vec3 change0 = glm::vec3(0, 0, 0); for (int j = 0; j < 100; j++) { - drawObjectTexture(bubbleContext, animationMatrix(time + j, change0, bubbleArray[j], glm::vec3(0.04f), 0.2f), textureBubble, bubbleProgram); + Core::drawObjectTexture(engine.bubbleContext, animationMatrix(time + j, change0, engine.bubbleArray[j], glm::vec3(0.04f), 0.2f), engine.bubbleTexture, engine.bubbleShader, lightDir, cameraMatrix, perspectiveMatrix); } for (int i = 0; i < 5; i++) { if (time > -10) { - drawObjectTexture(fishContext, animationMatrix(time + 15, change1, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture); - drawObjectTexture(fishContext, animationMatrix(time + 15, change2, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture); - drawObjectTexture(fishContext, animationMatrix(time + 15, change3, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture); - drawObjectTexture(fishContext, animationMatrix(time + 15, change4, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture); + Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change1, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); + Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change2, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); + Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change3, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); + Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change4, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); time -= 6; } } - drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine, programTexture); + Core::drawObjectTexture(engine.submarineContext, submarineModelMatrix, engine.submarineTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - glm::mat4 terrainTransformation = glm::translate(glm::vec3(50, -49, 50)) * glm::rotate(glm::radians(180.f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(2.f)); + glm::mat4 terrainTransformation = glm::translate(glm::vec3(50, -45, 50)) * glm::rotate(glm::radians(180.f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(2.f)); - drawObjectTexture(terrainContext, terrainTransformation, textureTerrain, programTexture); + Core::drawObjectTexture(engine.terrainContext, terrainTransformation, engine.terrainTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix); glutSwapBuffers(); } -void loadModelToContext(std::string path, Core::RenderContext& context) -{ - Assimp::Importer import; - const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace); - - if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) - { - std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl; - return; - } - context.initFromAssimpMesh(scene->mMeshes[0]); -} - -unsigned int loadCubemap() -{ - unsigned int textureID; - glGenTextures(1, &textureID); - glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); - - int width, height, nrChannels; - for (unsigned int i = 0; i < 6; i++) - { - unsigned char* data = stbi_load(skyboxTextures[i].c_str(), &width, &height, &nrChannels, STBI_rgb_alpha); - if (data) - { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, - 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data - ); - stbi_image_free(data); - } - else - { - std::cout << stbi_failure_reason() << std::endl; - std::cout << "Cubemap tex failed to load at path: " << skyboxTextures[i] << std::endl; - stbi_image_free(data); - } - } - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - return textureID; -} - -void initSkybox() -{ - glGenVertexArrays(1, &skyboxVAO); - glBindVertexArray(skyboxVAO); - - glGenBuffers(1, &skyboxBuffer); - glBindBuffer(GL_ARRAY_BUFFER, skyboxBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); - - GLuint vPosition = glGetAttribLocation(skyboxProgram, "aPos"); - glEnableVertexAttribArray(vPosition); - - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(skyboxVertices), skyboxVertices); - glEnableVertexAttribArray(0); - 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); @@ -491,77 +265,18 @@ void initKeyRotation() { keyRotation.push_back(glm::quat(1, 0, 0, 0)); } -void initCube() -{ - cubemapTexture = loadCubemap(); - glGenVertexArrays(1, &cubeVAO); - glGenBuffers(1, &cubeVBO); - glBindVertexArray(cubeVAO); - glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); -} - -void initTerrainContext() -{ - textureTerrain = Core::LoadTexture("textures/terrain.jpg"); - terrain = Terrain(heightGenerator); - obj::Model model = terrain.generateTerrain(); - terrainContext.initFromOBJ(model); -} - -void initFishContext() -{ - loadModelToContext("models/fish.obj", fishContext); - textureFish = Core::LoadTexture("textures/fish.png"); -} - -void initSubmarineContext() -{ - loadModelToContext("models/submarine.obj", submarineContext); - textureSubmarine = Core::LoadTexture("textures/submarine.png"); -} - -void initBubblesContext() -{ - loadModelToContext("models/sphere.obj", bubbleContext); - textureBubble = Core::LoadTexture("textures/bubble.png"); - generateBubbleArray(); -} - -void initContexts() -{ - initTerrainContext(); - initFishContext(); - initSubmarineContext(); - initBubblesContext(); -} - -void initShaderPrograms() -{ - programTexture = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.frag"); - skyboxProgram = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag"); - bubbleProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag"); -} - void init() { + std::default_random_engine gen(HeightGenerator::SEED); + std::uniform_int_distribution<> distr(-engine.skyboxVerticeParameter, engine.skyboxVerticeParameter); + engine.initRandomGenerator(gen, distr); glEnable(GL_DEPTH_TEST); - initShaderPrograms(); - initContexts(); + engine.initShaderPrograms(); + engine.initRenderContexts(); + engine.loadTextures(); + engine.initSkybox(); + engine.initBubbles(); initKeyRotation(); - initCube(); - initSkybox(); -} - -void shutdown() -{ - shaderLoader.DeleteProgram(programTexture); - shaderLoader.DeleteProgram(skyboxProgram); - shaderLoader.DeleteProgram(bubbleProgram); } void idle() @@ -587,6 +302,6 @@ int main(int argc, char** argv) glutSetCursor(GLUT_CURSOR_NONE); glutMainLoop(); - shutdown(); + engine.shutdownShaderPrograms(); return 0; } \ No newline at end of file