diff --git a/PlanetCreator/cw 6/imgui.ini b/PlanetCreator/cw 6/imgui.ini index f3be94c..98dbfed 100644 --- a/PlanetCreator/cw 6/imgui.ini +++ b/PlanetCreator/cw 6/imgui.ini @@ -11,6 +11,6 @@ Pos=4,3 Size=218,129 [Window][Dodawanie nowej planety] -Pos=1,-20 -Size=282,158 +Pos=109,-18 +Size=282,169 diff --git a/PlanetCreator/cw 6/models/cube.obj b/PlanetCreator/cw 6/models/cube.obj new file mode 100644 index 0000000..e98b40f --- /dev/null +++ b/PlanetCreator/cw 6/models/cube.obj @@ -0,0 +1,40 @@ +# Blender v2.90.0 OBJ File: '' +# www.blender.org +mtllib cube.mtl +o Cube +v -10.000000 -10.000000 10.000000 +v -10.000000 10.000000 10.000000 +v -10.000000 -10.000000 -10.000000 +v -10.000000 10.000000 -10.000000 +v 10.000000 -10.000000 10.000000 +v 10.000000 10.000000 10.000000 +v 10.000000 -10.000000 -10.000000 +v 10.000000 10.000000 -10.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.125000 0.500000 +vt 0.125000 0.750000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl _PBR +s 1 +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/8/4 6/7/4 2/9/4 1/10/4 +f 3/11/5 7/6/5 5/8/5 1/12/5 +f 8/5/6 4/13/6 2/14/6 6/7/6 \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/bloom_final.frag b/PlanetCreator/cw 6/shaders/bloom_final.frag new file mode 100644 index 0000000..c09f11e --- /dev/null +++ b/PlanetCreator/cw 6/shaders/bloom_final.frag @@ -0,0 +1,23 @@ +#version 330 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D scene; +uniform sampler2D bloomBlur; +uniform bool bloom; +uniform float exposure; + +void main() +{ + const float gamma = 2.2; + vec3 hdrColor = texture(scene, TexCoords).rgb; + vec3 bloomColor = texture(bloomBlur, TexCoords).rgb; + if(bloom) + hdrColor += bloomColor; // additive blending + // tone mapping + vec3 result = vec3(1.0) - exp(-hdrColor * exposure); + // also gamma correct while we're at it + result = pow(result, vec3(1.0 / gamma)); + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/bloom_final.vert b/PlanetCreator/cw 6/shaders/bloom_final.vert new file mode 100644 index 0000000..9f93e29 --- /dev/null +++ b/PlanetCreator/cw 6/shaders/bloom_final.vert @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +out vec2 TexCoords; + +void main() +{ + TexCoords = aTexCoords; + gl_Position = vec4(aPos, 1.0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/blur.frag b/PlanetCreator/cw 6/shaders/blur.frag new file mode 100644 index 0000000..7e425ed --- /dev/null +++ b/PlanetCreator/cw 6/shaders/blur.frag @@ -0,0 +1,32 @@ +#version 330 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D image; + +uniform bool horizontal; +uniform float weight[5] = float[] (0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162); + +void main() +{ + vec2 tex_offset = 1.0 / textureSize(image, 0); // gets size of single texel + vec3 result = texture(image, TexCoords).rgb * weight[0]; + if(horizontal) + { + for(int i = 1; i < 8; ++i) + { + result += texture(image, TexCoords + vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; + result += texture(image, TexCoords - vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; + } + } + else + { + for(int i = 1; i < 5; ++i) + { + result += texture(image, TexCoords + vec2(0.0, tex_offset.y * i)).rgb * weight[i]; + result += texture(image, TexCoords - vec2(0.0, tex_offset.y * i)).rgb * weight[i]; + } + } + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/blur.vert b/PlanetCreator/cw 6/shaders/blur.vert new file mode 100644 index 0000000..9f93e29 --- /dev/null +++ b/PlanetCreator/cw 6/shaders/blur.vert @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +out vec2 TexCoords; + +void main() +{ + TexCoords = aTexCoords; + gl_Position = vec4(aPos, 1.0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag index 9f2a55b..a945e74 100644 --- a/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag +++ b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag @@ -1,6 +1,7 @@ #version 430 core #define PI 3.14159265359 - +layout (location = 0) out vec4 outColor; +layout (location = 1) out vec4 BrightColor; float AMBIENT = 0.1; uniform vec3 albedo; @@ -16,7 +17,7 @@ in vec3 fragNormal; in vec3 fragPosition; in vec2 texCoords; -out vec4 outColor; +//out vec4 outColor; float specularD(float NdotH, float roughness) { @@ -68,5 +69,10 @@ void main() vec3 finalColor = ambient + (diffuse + specular) * NdotL; + float brightness = dot(finalColor, vec3(0.2126, 0.7152, 0.0722)); + if(brightness > 1.0) + BrightColor = vec4(finalColor, 1.0); + else + BrightColor = vec4(0.0, 0.0, 0.0, 1.0); outColor = vec4(finalColor, 1.0); } diff --git a/PlanetCreator/cw 6/shaders/shader_sky.frag b/PlanetCreator/cw 6/shaders/shader_sky.frag new file mode 100644 index 0000000..6f4b26b --- /dev/null +++ b/PlanetCreator/cw 6/shaders/shader_sky.frag @@ -0,0 +1,19 @@ +#version 430 core +layout (location = 0) out vec4 out_color; +layout (location = 1) out vec4 BrightColor; +uniform samplerCube skybox; + +in vec3 texCoord; + +//out vec4 out_color; + +void main() +{ +vec4 finalColor =texture(skybox,texCoord); + float brightness = dot(vec3(finalColor.x,finalColor.y, finalColor.z ), vec3(0.2126, 0.7152, 0.0722)); + if(brightness > 1.0) + BrightColor = vec4(vec3(finalColor.x,finalColor.y, finalColor.z ), 1.0); + else + BrightColor = vec4(0.0, 0.0, 0.0, 1.0); + out_color = texture(skybox,texCoord); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/shaders/shader_sky.vert b/PlanetCreator/cw 6/shaders/shader_sky.vert new file mode 100644 index 0000000..9fee19a --- /dev/null +++ b/PlanetCreator/cw 6/shaders/shader_sky.vert @@ -0,0 +1,13 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; + +uniform mat4 transformation; + +out vec3 texCoord; + +void main() +{ + texCoord = vertexPosition; + gl_Position = transformation * vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/src/Texture.cpp b/PlanetCreator/cw 6/src/Texture.cpp index 18bab57..253ca9b 100644 --- a/PlanetCreator/cw 6/src/Texture.cpp +++ b/PlanetCreator/cw 6/src/Texture.cpp @@ -28,6 +28,27 @@ GLuint Core::LoadTexture( const char * filepath ) return id; } +GLuint Core::LoadCubeMap(const char * filepath ) { + GLuint id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_CUBE_MAP, id); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT); + + int w, h; + unsigned char* image = SOIL_load_image(filepath, &w, &h, 0, SOIL_LOAD_RGBA); + for (int i = 0; i < 6; i++) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); + } + + + return id; + +} @@ -37,3 +58,9 @@ void Core::SetActiveTexture(GLuint textureID, const char * shaderVariableName, G glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(GL_TEXTURE_2D, textureID); } +void Core::SetActiveBackground(GLuint textureID, const char* shaderVariableName, GLuint programID, int textureUnit) +{ + glUniform1i(glGetUniformLocation(programID, shaderVariableName), textureUnit); + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); +} diff --git a/PlanetCreator/cw 6/src/Texture.h b/PlanetCreator/cw 6/src/Texture.h index 910228e..85c3ea3 100644 --- a/PlanetCreator/cw 6/src/Texture.h +++ b/PlanetCreator/cw 6/src/Texture.h @@ -6,10 +6,11 @@ namespace Core { GLuint LoadTexture(const char * filepath); - + GLuint LoadCubeMap(const char* filepath); // textureID - identyfikator tekstury otrzymany z funkcji LoadTexture // shaderVariableName - nazwa zmiennej typu 'sampler2D' w shaderze, z ktora ma zostac powiazana tekstura // programID - identyfikator aktualnego programu karty graficznej // textureUnit - indeks jednostki teksturujacej - liczba od 0 do 7. Jezeli uzywa sie wielu tekstur w jednym shaderze, to kazda z nich nalezy powiazac z inna jednostka. void SetActiveTexture(GLuint textureID, const char * shaderVariableName, GLuint programID, int textureUnit); + void SetActiveBackground(GLuint textureID, const char* shaderVariableName, GLuint programID, int textureUnit); } \ No newline at end of file diff --git a/PlanetCreator/cw 6/src/ex_6_1.hpp b/PlanetCreator/cw 6/src/ex_6_1.hpp index 1918f2d..cc125d2 100644 --- a/PlanetCreator/cw 6/src/ex_6_1.hpp +++ b/PlanetCreator/cw 6/src/ex_6_1.hpp @@ -39,7 +39,7 @@ void loadMTLAndGetTextureID(const std::string& filePath, Material& material) { std::ifstream file(filePath); if (!file.is_open()) { std::cerr << "Failed to open MTL file: " << filePath << std::endl; - return; + return; } std::string line; @@ -49,10 +49,10 @@ void loadMTLAndGetTextureID(const std::string& filePath, Material& material) { iss >> token; if (token == "newmtl") { - iss >> token; + iss >> token; } else if (token == "map_Kd") { - iss >> token; + iss >> token; material.textureID = Core::LoadTexture(token.c_str()); file.close(); return; @@ -81,7 +81,7 @@ void loadMTLAndGetTextureID(const std::string& filePath, Material& material) { } file.close(); - return ; + return; } @@ -121,7 +121,7 @@ namespace Plant public: float humMean; float humSD; float tempMean; float tempSD; std::string name; std::string fileName; Core::RenderContext modelContext; glm::vec3 pos; Material material; - Plant(float humMean, float humSD, float tempMean, float tempSD, std::string name, std::string fileName,Material material) { + Plant(float humMean, float humSD, float tempMean, float tempSD, std::string name, std::string fileName, Material material) { this->humMean = humMean; this->humSD = humSD; this->tempMean = tempMean; @@ -129,8 +129,8 @@ namespace Plant this->name = name; this->fileName = fileName; loadModelToContext(fileName, modelContext); - - this->pos = glm::vec3(1,0,0); + + this->pos = glm::vec3(1, 0, 0); this->material = material; //this->pos = glm::vec3((rand() % 100) / 100, (rand() % 100) / 100, (rand() % 100) / 100); } @@ -181,9 +181,9 @@ GLuint defaultTexture; bool sortFunction(std::tuple objA, std::tuple objB) { - float valA=std::get<1>(objA); + float valA = std::get<1>(objA); float valB = std::get<1>(objB); - return (valA objA, std::tuple objB) { @@ -193,15 +193,15 @@ bool sortFunctionPlantInfo(std::tuple objA, std::tuple plants) { - float probability=0.5f; + float probability = 0.5f; int HOW_MANY_PLANTS = 10000; int PRECISION = 10000; - float NOTHING_SPAWNS_CUTOFF = 0.2; + float NOTHING_SPAWNS_CUTOFF = 0.02; int sum = 0; int chosen_number = 0; std::vector> probabilities; int plant_count = 0; - for (int i = 0; i < plant_specimens.size(); i++) + for (int i = 0; i < plant_specimens.size(); i++) { planet.Plant_type_count.push_back(0); } @@ -209,12 +209,12 @@ PlanetParams populatePlanet(PlanetParams planet, std::vector plant int j = 0; std::cout << "Plant Probabilities:" << std::endl; for (auto& plant : plants) { - + //TODO: add humidity calculations - probability = plant.calcProbability2(planet.humidity, plant.humMean, plant.humSD)* plant.calcProbability2(planet.temperature, plant.tempMean, plant.tempSD); - std::cout << probability << std::endl; + probability = plant.calcProbability2(planet.humidity, plant.humMean, plant.humSD) * plant.calcProbability2(planet.temperature, plant.tempMean, plant.tempSD); + std::cout << probability << std::endl; probability = int(probability * PRECISION); - std::tupleprobIdPair = std::make_tuple(j ,probability); + std::tupleprobIdPair = std::make_tuple(j, probability); probabilities.push_back(probIdPair); j++; } @@ -224,11 +224,11 @@ PlanetParams populatePlanet(PlanetParams planet, std::vector plant } std::sort(probabilities.begin(), probabilities.end(), sortFunction); - + for (int i = 0; i < HOW_MANY_PLANTS; i++) { - chosen_number = int(sum * (rand() / (RAND_MAX + 1.0))) ; - int counter=0; + chosen_number = int(sum * (rand() / (RAND_MAX + 1.0))); + int counter = 0; int winnerId = -1; for (auto& probability : probabilities) { @@ -244,16 +244,16 @@ PlanetParams populatePlanet(PlanetParams planet, std::vector plant Plant::Plant plant = plants[winnerId]; plant_count += 1; planet.Plant_type_count[winnerId] += 1; - plant.pos = glm::vec3((2.0 * (rand() / (RAND_MAX + 1.0))-1), (2.0 * (rand() / (RAND_MAX + 1.0))-1), (2.0 * (rand() / (RAND_MAX + 1.0)))-1); - planet.Plant_info.push_back(std::make_tuple(winnerId,plant.pos)); + plant.pos = glm::vec3((2.0 * (rand() / (RAND_MAX + 1.0)) - 1), (2.0 * (rand() / (RAND_MAX + 1.0)) - 1), (2.0 * (rand() / (RAND_MAX + 1.0))) - 1); + planet.Plant_info.push_back(std::make_tuple(winnerId, plant.pos)); } } - std::cout <<"plant_count:" << plant_count << std::endl; + std::cout << "plant_count:" << plant_count << std::endl; for (int i = 0; i < planet.Plant_type_count.size(); i++) { - std::cout << " " < plant planet.humidity >= climate.precipMin && planet.humidity <= climate.precipMax) { planet.texture = climate.textureID; } - } - - return planet; - - -} + } + return planet; + + +} +PlanetParams populatePlanet2(PlanetParams planet, std::vector plants) +{ + + int HOW_MANY_PLANTS = 1000; + int eachSpecie = int(HOW_MANY_PLANTS / plant_specimens.size()); + + for (int i = 0; i < plant_specimens.size(); i++) + { + planet.Plant_type_count.push_back(eachSpecie); + for (int j = 0; j < eachSpecie; j++) + { + Plant::Plant plant = plants[i]; + plant.pos = glm::vec3((2.0 * (rand() / (RAND_MAX + 1.0)) - 1), (2.0 * (rand() / (RAND_MAX + 1.0)) - 1), (2.0 * (rand() / (RAND_MAX + 1.0))) - 1); + planet.Plant_info.push_back(std::make_tuple(i, plant.pos)); + } + + } + planet.texture = defaultTexture; + + for (const auto& climate : climates) { + if (planet.temperature >= climate.tempMin && planet.temperature <= climate.tempMax && + planet.humidity >= climate.precipMin && planet.humidity <= climate.precipMax) { + planet.texture = climate.textureID; + } + } + + return planet; + + +} namespace texture { @@ -285,6 +314,8 @@ namespace texture { GLuint sun; GLuint earthNormal; GLuint asteroidNormal; + GLuint background; + } GLuint program; @@ -293,7 +324,11 @@ GLuint programTex; GLuint program_pbr; GLuint plantProgram; GLuint program_pbr_instanced; +GLuint program_sky; +GLuint program_blur; +GLuint program_bloom_final; Core::Shader_Loader shaderLoader; +Core::RenderContext cubeContext; GLuint programBiomes; @@ -318,15 +353,16 @@ Core::RenderContext plant2_1Context; glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0); glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f); -glm::vec3 sunPosition = glm::vec3(0.0f, 0.0f, 0.0f); // Позиция солнца +glm::vec3 sunPosition = glm::vec3(0.0f, 10.0f, 10.0f); // Позиция солнца glm::vec3 sunColor = glm::vec3(1.0f, 1.0f, 1.0f); // Цвет солнца +glm::vec3 skyPos = glm::vec3(0.f, 0.f, 0.f); +float skySize = 4.f; - -GLuint VAO,VBO; +GLuint VAO, VBO; glm::mat4 planetMatrix = glm::mat4(); -void DrawContextInstanced(Core::RenderContext& context, std::vector transformations, std::vector Modelmatrices, int numberOfInstances,Material material, GLuint program) +void DrawContextInstanced(Core::RenderContext& context, std::vector transformations, std::vector Modelmatrices, int numberOfInstances, Material material, GLuint program) { @@ -352,7 +388,7 @@ void DrawContextInstanced(Core::RenderContext& context, std::vector t glVertexAttribDivisor(10 + i, 1); } - glUniform3f(glGetUniformLocation(program, "lightPos"), 0, 0, 0); + glUniform3f(glGetUniformLocation(program, "lightPos"), sunPosition.x, sunPosition.y, sunPosition.z); //Material glUniform1f(glGetUniformLocation(program, "shininess"), material.Ns); glUniform3f(glGetUniformLocation(program, "ambientColor"), material.Ka.r, material.Ka.g, material.Ka.b); @@ -409,8 +445,8 @@ bool DoTheImportThing(const std::string& pFile) { } glm::mat4 createCameraMatrix() { - glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir,glm::vec3(0.f,1.f,0.f))); - glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide,cameraDir)); + glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f))); + glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir)); glm::mat4 cameraRotrationMatrix = glm::mat4({ cameraSide.x,cameraSide.y,cameraSide.z,0, cameraUp.x,cameraUp.y,cameraUp.z ,0, @@ -429,7 +465,7 @@ void renderImGui() { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ImGui::Begin("Dodawanie nowej planety"); + ImGui::Begin("Dodawanie nowej planety"); static PlanetParams newPlanetParams; ImGui::InputFloat3("Pozycja", &newPlanetParams.position[0]); @@ -438,7 +474,15 @@ void renderImGui() { ImGui::SliderFloat("Temperatura", &newPlanetParams.temperature, 0.0f, 100.0f); // Слайдер для осадков if (ImGui::Button("Dodac")) { - newPlanetParams =populatePlanet(newPlanetParams, plant_specimens); + planets.clear(); + newPlanetParams = populatePlanet(newPlanetParams, plant_specimens); + planets.push_back(newPlanetParams); + newPlanetParams.Plant_info.clear(); + newPlanetParams.Plant_type_count.clear(); + } + if (ImGui::Button("Instancing")) { + planets.clear(); + newPlanetParams = populatePlanet2(newPlanetParams, plant_specimens); planets.push_back(newPlanetParams); newPlanetParams.Plant_info.clear(); newPlanetParams.Plant_type_count.clear(); @@ -448,10 +492,123 @@ void renderImGui() { ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } +unsigned int hdrFBO; +unsigned int colorBuffers[2]; +unsigned int rboDepth; +unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; +unsigned int pingpongFBO[2]; +unsigned int pingpongColorbuffers[2]; +int SCR_WIDTH = 1024, SCR_HEIGHT = 1024; +void bloomConfig(GLFWwindow* window) { + glfwGetWindowSize(window, &SCR_WIDTH, &SCR_HEIGHT); + glGenFramebuffers(1, &hdrFBO); + glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); + glGenTextures(2, colorBuffers); + for (unsigned int i = 0; i < 2; i++) + { + glBindTexture(GL_TEXTURE_2D, colorBuffers[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // we clamp to the edge as the blur filter would otherwise sample repeated texture values! + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // attach texture to framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorBuffers[i], 0); + glGenRenderbuffers(1, &rboDepth); + glBindRenderbuffer(GL_RENDERBUFFER, rboDepth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, SCR_WIDTH, SCR_HEIGHT); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth); + glDrawBuffers(2, attachments); + // finally check if framebuffer is complete + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cout << "Framebuffer not complete!" << std::endl; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glGenFramebuffers(2, pingpongFBO); + glGenTextures(2, pingpongColorbuffers); + for (unsigned int i = 0; i < 2; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, pingpongFBO[i]); + glBindTexture(GL_TEXTURE_2D, pingpongColorbuffers[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // we clamp to the edge as the blur filter would otherwise sample repeated texture values! + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pingpongColorbuffers[i], 0); + // also check if framebuffers are complete (no need for depth buffer) + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cout << "Framebuffer not complete!" << std::endl; + } + } + glUseProgram(program_blur); + glUniform1i(glGetUniformLocation(program_blur, "image"), 0); + glUseProgram(program_bloom_final); + glUniform1i(glGetUniformLocation(program_bloom_final, "scene"), 0); + glUniform1i(glGetUniformLocation(program_bloom_final, "bloomBlur"), 1); +} + +unsigned int quadVAO = 0; +unsigned int quadVBO; +void renderQuad() +{ + if (quadVAO == 0) + { + float quadVertices[] = { + // positions // texture Coords + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + }; + // setup plane VAO + glGenVertexArrays(1, &quadVAO); + glGenBuffers(1, &quadVBO); + glBindVertexArray(quadVAO); + glBindBuffer(GL_ARRAY_BUFFER, quadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + } + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); +} + +float exposure = 0.5f; +bool bloom = true; +void applyBloom() { + bool horizontal = true, first_iteration = true; + unsigned int amount = 10; + glUseProgram(program_blur); + for (unsigned int i = 0; i < amount; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, pingpongFBO[horizontal]); + glUniform1i(glGetUniformLocation(program_blur, "horizontal"), horizontal); + glBindTexture(GL_TEXTURE_2D, first_iteration ? colorBuffers[1] : pingpongColorbuffers[!horizontal]); // bind texture of other framebuffer (or scene if first iteration) + renderQuad(); + horizontal = !horizontal; + if (first_iteration) + first_iteration = false; + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(program_bloom_final); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, colorBuffers[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, pingpongColorbuffers[!horizontal]); + glUniform1i(glGetUniformLocation(program_bloom_final, "bloom"), bloom); + glUniform1f(glGetUniformLocation(program_bloom_final, "exposure"), exposure); + renderQuad(); +} glm::mat4 createPerspectiveMatrix() { - + glm::mat4 perspectiveMatrix; float n = 0.05; float f = 500.; @@ -460,15 +617,25 @@ glm::mat4 createPerspectiveMatrix() perspectiveMatrix = glm::mat4({ 1,0.,0.,0., 0.,aspectRatio,0.,0., - 0.,0.,(f+n) / (n - f),2*f * n / (n - f), + 0.,0.,(f + n) / (n - f),2 * f * n / (n - f), 0.,0.,-1.,0., }); - - perspectiveMatrix=glm::transpose(perspectiveMatrix); + + perspectiveMatrix = glm::transpose(perspectiveMatrix); return perspectiveMatrix; } +void drawSky(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture) { + glUseProgram(program_sky); + Core::SetActiveBackground(texture, "skybox", program_sky, 0); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program_sky, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(program_sky, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); + Core::DrawContext(context); + glUseProgram(0); +} void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color, GLuint program) { GLuint prog = program; @@ -487,14 +654,14 @@ void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::v GLuint colorEndLocation = glGetUniformLocation(prog, "colorEnd"); glm::vec3 colorStartValue(1.0f, 1.0f, 0.0f); - glm::vec3 colorEndValue(0.0f, 0.0f, 0.0f); - + glm::vec3 colorEndValue(0.0f, 0.0f, 0.0f); + glUniform3fv(colorStartLocation, 1, glm::value_ptr(colorStartValue)); glUniform3fv(colorEndLocation, 1, glm::value_ptr(colorEndValue)); Core::DrawContext(context); glUseProgram(0); - + } void renderSun() { @@ -552,8 +719,8 @@ void drawObjectTexture_plant(Core::RenderContext& context, glm::mat4 modelMatrix //Material glUniform1f(glGetUniformLocation(program, "shininess"), material.Ns); glUniform3f(glGetUniformLocation(program, "ambientColor"), material.Ka.r, material.Ka.g, material.Ka.b); - glUniform3f(glGetUniformLocation(program, "specularColor"), material.Ks.r, material.Ks.g, material.Ks.b); - glUniform3f(glGetUniformLocation(program, "emissiveColor"), material.Ke.r, material.Ke.g, material.Ke.b); + glUniform3f(glGetUniformLocation(program, "specularColor"), material.Ks.r, material.Ks.g, material.Ks.b); + glUniform3f(glGetUniformLocation(program, "emissiveColor"), material.Ke.r, material.Ke.g, material.Ke.b); glUniform1f(glGetUniformLocation(program, "opticalDensity"), material.Ni); //glUniform1f(glGetUniformLocation(program, "dissolve"), material.d); glUniform1i(glGetUniformLocation(program, "illuminationModel"), material.illum); @@ -562,14 +729,14 @@ void drawObjectTexture_plant(Core::RenderContext& context, glm::mat4 modelMatrix Core::DrawContext(context); glUseProgram(0); } -void drawObjectTexture_plantInstanced(Core::RenderContext& context, std::vector modelMatrices, Material& material, GLuint program,int count) { +void drawObjectTexture_plantInstanced(Core::RenderContext& context, std::vector modelMatrices, Material& material, GLuint program, int count) { glUseProgram(program); Core::SetActiveTexture(material.textureID, "colorTexture", program, 0); glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); std::vector transformations; for (const auto& matrix : modelMatrices) { - glm::mat4 transformation = viewProjectionMatrix* matrix; + glm::mat4 transformation = viewProjectionMatrix * matrix; transformations.push_back(transformation); } //glUniform3f(glGetUniformLocation(program, "lightPos"), 0, 0, 0); @@ -584,10 +751,10 @@ void drawObjectTexture_plantInstanced(Core::RenderContext& context, std::vector< //glUniform1f(glGetUniformLocation(program, "metallic"), 0.05); //glUniform1f(glGetUniformLocation(program, "roughness"), 0.2); - DrawContextInstanced(context, transformations,modelMatrices,count,material,program); + DrawContextInstanced(context, transformations, modelMatrices, count, material, program); glUseProgram(0); } -void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMatrix,float scale,std::vectorplacePoints, PlanetParams planetParams,int count,Material material) { +void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMatrix, float scale, std::vectorplacePoints, PlanetParams planetParams, int count, Material material) { float planetScale = planetParams.size; glm::mat4 savedobjectMatrix; @@ -610,11 +777,11 @@ void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMat objectMatrix = objectMatrix * glm::translate(planetParams.position * (1 / scale)); matrices.push_back(objectMatrix); } - - - drawObjectTexture_plantInstanced(objectContext, matrices, material, program_pbr_instanced,count); - + + + drawObjectTexture_plantInstanced(objectContext, matrices, material, program_pbr_instanced, count); + @@ -622,7 +789,7 @@ void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMat } -PlanetParams TestPlanet = PlanetParams(); +PlanetParams TestPlanet = PlanetParams(); struct TexturePlantData { Core::RenderContext thirdTreeContext; glm::mat4 plantModelMatrix; @@ -632,15 +799,15 @@ struct TexturePlantData { std::vector texturePlantDataList; #include float thirdTreeStartScale = 0.0f; -void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDuration, float secondTreeDuration, float thirdTreeDuration, +void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDuration, float secondTreeDuration, float thirdTreeDuration, glm::vec3 plantPosition, float scaleFactor, Core::RenderContext& plant_1_1_small_Context, Core::RenderContext& plant_1_1Context, Core::RenderContext& thirdTreeContext, glm::mat4& plantModelMatrix, Material& plant3Material, GLuint program_pbr) { - -// static float thirdTreeStartScale = 0.0f; - //pierwsze drzewo + + // static float thirdTreeStartScale = 0.0f; + //pierwsze drzewo if (elapsedTime < firstTreeDuration) { - + plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(scaleFactor + (elapsedTime / firstTreeDuration) * scaleFactor)); drawObjectTexture_plant(plant_1_1_small_Context, plantModelMatrix, plant3Material, program_pbr); elapsedTime += deltaTime; @@ -653,7 +820,7 @@ void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDura drawObjectTexture_plant(plant_1_1Context, plantModelMatrix, plant3Material, program_pbr); //std::cout << "delta " << deltaTime << std::endl; //rozmiar - if (elapsedTime >= firstTreeDuration && elapsedTime < firstTreeDuration + 4*deltaTime) { + if (elapsedTime >= firstTreeDuration && elapsedTime < firstTreeDuration + 4 * deltaTime) { thirdTreeStartScale = scaleFactor + growthStage2 * scaleFactor; //std::cout << "thirdTreeStartScale: " << thirdTreeStartScale << std::endl; } @@ -661,32 +828,32 @@ void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDura } //trzecie drzewo else if (elapsedTime < firstTreeDuration + secondTreeDuration + thirdTreeDuration) { - + float growthStage3 = ((elapsedTime - firstTreeDuration - secondTreeDuration) / thirdTreeDuration); - plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(thirdTreeStartScale*2 + growthStage3 * scaleFactor)); + plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(thirdTreeStartScale * 2 + growthStage3 * scaleFactor)); drawObjectTexture_plant(thirdTreeContext, plantModelMatrix, plant3Material, program_pbr); elapsedTime += deltaTime; } else { - + //plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(scaleFactor + scaleFactor)); - plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(thirdTreeStartScale*2 + scaleFactor)); + plantModelMatrix = glm::translate(plantPosition) * glm::scale(glm::vec3(thirdTreeStartScale * 2 + scaleFactor)); TexturePlantData newData; newData.thirdTreeContext = thirdTreeContext; newData.plantModelMatrix = plantModelMatrix; newData.plant3Material = plant3Material; newData.program_pbr = program_pbr; texturePlantDataList.push_back(newData); - // drawObjectTexture_plant(thirdTreeContext, plantModelMatrix, plant3Material, program_pbr); + // drawObjectTexture_plant(thirdTreeContext, plantModelMatrix, plant3Material, program_pbr); elapsedTime = 0; } for (const auto& newData : texturePlantDataList) { drawObjectTexture_plant(const_cast(newData.thirdTreeContext), newData.plantModelMatrix, newData.plant3Material, newData.program_pbr); } - - - + + + } @@ -698,6 +865,8 @@ void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDura void renderScene(GLFWwindow* window) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO); glClearColor(0.0f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 transformation; @@ -735,7 +904,7 @@ void renderScene(GLFWwindow* window) glm::mat4 modelMatrix = glm::translate(planet.position) * glm::scale(glm::vec3(planet.size)); drawObjectTexture(sphereContext, modelMatrix, planet.texture, programTex); - std::vector>plants = planet.Plant_info; + std::vector>plants = planet.Plant_info; int plant_type_count = plants.size(); int types_count = 1; std::vector current_type_plant_positions; @@ -761,22 +930,26 @@ void renderScene(GLFWwindow* window) } for (int i = 0; i < types_count; i++) { - + //placeObjectOnPlanet(plant_specimens[std::get<0>(plant)].modelContext, glm::mat4(), 0.2, std::get<1>(plant), planet, plant_type_count); } //for (const auto& plant : plants) //TODO: REMOVE PLACEHOLDER - + //animateGrowingTree(elapsedTime, deltaTime, firstTreeDuration, secondTreeDuration, thirdTreeDuration, plant.pos, scaleFactor, plant_2_1_small_Context, plant_2_1_med_Context, plant_2_1Context, plantModelMatrix, plant2_1Material, program_pbr); } - + skyPos = cameraPos; + glm::mat4 skyMatrix = glm::scale(glm::vec3(skySize)); + glm::mat4 skyTranslate = glm::translate(skyPos); + drawSky(cubeContext, skyTranslate * skyMatrix, texture::background); //placeObjectOnPlanet(plant2Context, glm::scale(glm::mat4(), glm::vec3(0.2)), normalize(glm::vec3(1.0, 0.0, 1.0)), sphereContext, planetMatrix); - + glBindFramebuffer(GL_FRAMEBUFFER, 0); + applyBloom(); renderSun(); - + //drawObjectColor(plant2Context, plantModelMatrix, glm::vec3(1,1,1), program); // drawObjectColor(plant3Context,glm::translate(glm::vec3(1.0f, 0.5f, 3.0f)) *glm::scale(glm::vec3(0.03f)) *glm::rotate(glm::mat4(1.0f), glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)),glm::vec3(1, 1, 1), program); @@ -784,7 +957,7 @@ void renderScene(GLFWwindow* window) //drawObjectTexture_plant(plant_2_1_small_Context, plantModelMatrix, plant2_1Material, program_pbr); //drawObjectColor(plant2Context, plantModelMatrix, glm::vec3(1, 1, 1), program); - + //animateGrowingTree(elapsedTime, deltaTime, firstTreeDuration, secondTreeDuration, thirdTreeDuration, plantPosition, scaleFactor, plant_1_1_small_Context, plant_1_1_med_Context, plant_1_1Context, plantModelMatrix, plant3Material, program_pbr); @@ -792,11 +965,14 @@ void renderScene(GLFWwindow* window) //animateGrowingTree(elapsedTime, deltaTime, firstTreeDuration, secondTreeDuration, thirdTreeDuration, plantPosition2, scaleFactor, plant_2_1_small_Context, plant_2_1_med_Context, plant_2_1Context, plantModelMatrix, plant2_1Material, program_pbr); - //glfwSwapBuffers(window); + renderImGui(); + glfwSwapBuffers(window); } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { aspectRatio = width / float(height); + bloomConfig(window); + glViewport(0, 0, width, height); } @@ -813,6 +989,7 @@ void init(GLFWwindow* window) { glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + bloomConfig(window); glm::vec3 lightPosition = glm::vec3(0.0f, 10.0f, 0.0f); glm::vec3 lightColor = glm::vec3(1.0f, 1.0f, 1.0f); @@ -824,22 +1001,25 @@ void init(GLFWwindow* window) programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag"); programBiomes = shaderLoader.CreateProgram("shaders/shader_biomes.vert", "shaders/shader_biomes.frag"); program_pbr = shaderLoader.CreateProgram("shaders/shader_pbr.vert", "shaders/shader_pbr.frag"); - program_pbr_instanced= shaderLoader.CreateProgram("shaders/shader_pbr_instanced.vert", "shaders/shader_pbr_instanced.frag"); + program_pbr_instanced = shaderLoader.CreateProgram("shaders/shader_pbr_instanced.vert", "shaders/shader_pbr_instanced.frag"); + program_sky = shaderLoader.CreateProgram("shaders/shader_sky.vert", "shaders/shader_sky.frag"); + program_blur = shaderLoader.CreateProgram("shaders/blur.vert", "shaders/blur.frag"); + program_bloom_final = shaderLoader.CreateProgram("shaders/bloom_final.vert", "shaders/bloom_final.frag"); loadModelToContext2("./models/plants/polygon.obj", plantContext); loadModelToContext("./models/sphere.obj", sphereContext); //plant 1-1 - loadModelToContext("./models/plant_1_1_zmn.obj", plant_1_1Context); - loadModelToContext("./models/plant_1_1_med_zmn.obj", plant_1_1_med_Context); - loadModelToContext("./models/plant_1_1_small_zmn.obj", plant_1_1_small_Context); - //plant 2-2 - loadModelToContext("./models/plant_2_1_small.obj", plant_2_1_small_Context); - loadModelToContext("./models/plant_2_1_med.obj", plant_2_1_med_Context); - loadModelToContext("./models/plant_2_1.obj", plant_2_1Context); - loadModelToContext2("./models/plant_4.ply", plant3Context); + loadModelToContext("./models/plant_1_1_zmn.obj", plant_1_1Context); + loadModelToContext("./models/plant_1_1_med_zmn.obj", plant_1_1_med_Context); + loadModelToContext("./models/plant_1_1_small_zmn.obj", plant_1_1_small_Context); + //plant 2-2 + loadModelToContext("./models/plant_2_1_small.obj", plant_2_1_small_Context); + loadModelToContext("./models/plant_2_1_med.obj", plant_2_1_med_Context); + loadModelToContext("./models/plant_2_1.obj", plant_2_1Context); + loadModelToContext2("./models/plant_4.ply", plant3Context); - // setupBuffers(plantContex_test); - texture::earth=Core::LoadTexture("textures/earth2.png"); + // setupBuffers(plantContex_test); + texture::earth = Core::LoadTexture("textures/earth2.png"); texture::clouds = Core::LoadTexture("textures/clouds.jpg"); texture::moon = Core::LoadTexture("textures/moon_normals.png"); texture::grid = Core::LoadTexture("textures/grid.png"); @@ -849,7 +1029,8 @@ void init(GLFWwindow* window) loadMTLAndGetTextureID("./models/plant_1_1.mtl", plant3Material); loadMTLAndGetTextureID("./models/plant_2_1_small.mtl", plant2_1Material); loadMTLAndGetTextureID("./models/plant_2_1_small.mtl", plant2_1Material); - + loadModelToContext("./models/cube.obj", cubeContext); + texture::background = Core::LoadCubeMap("./textures/skyCut.jpg"); plant_specimens.push_back(Plant::Plant(7, 5, 7, 5, "plant1_s", "./models/plant_1_1.obj", plant3Material)); plant_specimens.push_back(Plant::Plant(5, 5, 5, 5, "plant1_m", "./models/plant_2_1.obj", plant2_1Material)); @@ -901,7 +1082,7 @@ void processInput(GLFWwindow* window) if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) cameraPos -= glm::vec3(0.0f, cameraSpeed, 0.0f); } - + //// funkcja jest glowna petla //void renderLoop(GLFWwindow* window) { @@ -929,11 +1110,8 @@ void renderLoop(GLFWwindow* window) { renderScene(window); // Рендеринг ImGui - renderImGui(); - glEnable(GL_DEPTH_TEST); - glfwSwapBuffers(window); } } diff --git a/PlanetCreator/cw 6/textures/skyCut.jpg b/PlanetCreator/cw 6/textures/skyCut.jpg new file mode 100644 index 0000000..176ffc3 Binary files /dev/null and b/PlanetCreator/cw 6/textures/skyCut.jpg differ