Grafika_Komputerowa_Interst.../cw 7/src/ex_7_1.hpp

322 lines
11 KiB
C++

#include "glew.h"
#include <GLFW/glfw3.h>
#include "glm.hpp"
#include "ext.hpp"
#include <iostream>
#include <cmath>
#include "Shader_Loader.h"
#include "Render_Utils.h"
#include "Texture.h"
#include "Box.cpp"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <string>
#include "SOIL/SOIL.h"
namespace texture {
GLuint earth;
GLuint clouds;
GLuint moon;
GLuint ship;
GLuint rust;
GLuint grid;
GLuint earthNormal;
GLuint moonNormal;
GLuint shipNormal;
GLuint rustNormal;
}
GLuint program;
GLuint programSun;
GLuint programTex;
GLuint programEarth;
GLuint programProcTex;
GLuint programSkyBox;
Core::Shader_Loader shaderLoader;
Core::RenderContext shipContext;
Core::RenderContext sphereContext;
Core::RenderContext cubeContext;
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
glm::vec3 spaceshipPos = glm::vec3(-4.f, 0, 0);
glm::vec3 spaceshipDir = glm::vec3(1.f, 0.f, 0.f);
GLuint VAO,VBO;
float aspectRatio = 1.f;
unsigned int textureID;
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::mat4 cameraRotrationMatrix = glm::mat4({
cameraSide.x,cameraSide.y,cameraSide.z,0,
cameraUp.x,cameraUp.y,cameraUp.z ,0,
-cameraDir.x,-cameraDir.y,-cameraDir.z,0,
0.,0.,0.,1.,
});
cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix);
glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos);
return cameraMatrix;
}
glm::mat4 createPerspectiveMatrix()
{
glm::mat4 perspectiveMatrix;
float n = 0.05;
float f = 20.;
float a1 = glm::min(aspectRatio, 1.f);
float a2 = glm::min(1 / aspectRatio, 1.f);
perspectiveMatrix = glm::mat4({
1,0.,0.,0.,
0.,aspectRatio,0.,0.,
0.,0.,(f+n) / (n - f),2*f * n / (n - f),
0.,0.,-1.,0.,
});
perspectiveMatrix=glm::transpose(perspectiveMatrix);
return perspectiveMatrix;
}
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
glUseProgram(program);
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
glUniform3f(glGetUniformLocation(program, "color"), color.x, color.y, color.z);
glUniform3f(glGetUniformLocation(program, "lightPos"), 0,0,0);
Core::DrawContext(context);
}
void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint textureID, GLuint normalMapId) {
glUseProgram(programTex);
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(programTex, "transformation"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(programTex, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
glUniform3f(glGetUniformLocation(programTex, "lightPos"), 0, 0, 0);
Core::SetActiveTexture(normalMapId, "normalSampler", programTex, 1);
Core::SetActiveTexture(textureID, "colorTexture", programTex, 0);
Core::DrawContext(context);
}
void drawObjectSkyBox(Core::RenderContext& context, glm::mat4 modelMatrix) {
glDisable(GL_DEPTH_TEST);
glUseProgram(programSkyBox);
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(programSkyBox, "transformation"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(programSkyBox, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
glUniform3f(glGetUniformLocation(programSkyBox, "lightPos"), 0, 0, 0);
//Core::SetActiveTexture(textureID, "colorTexture", programSkyBox, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
Core::DrawContext(context);
glEnable(GL_DEPTH_TEST);
}
void renderScene(GLFWwindow* window)
{
glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 transformation;
float time = glfwGetTime();
drawObjectSkyBox(cubeContext, glm::translate(cameraPos));
drawObjectTexture(sphereContext, glm::mat4(), texture::rust, texture::rustNormal);
drawObjectTexture(sphereContext, glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::scale(glm::vec3(0.3f)), texture::earth, texture::earthNormal);
drawObjectTexture(sphereContext,
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)), texture::moon, texture::moonNormal);
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
glm::mat4 specshipCameraRotrationMatrix = glm::mat4({
spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0,
spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0,
-spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0,
0.,0.,0.,1.,
});
//drawObjectColor(shipContext,
// glm::translate(cameraPos + 1.5 * cameraDir + cameraUp * -0.5f) * inveseCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
// glm::vec3(0.3, 0.3, 0.5)
// );
drawObjectTexture(shipContext,
glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
texture::ship, texture::shipNormal
);
glUseProgram(0);
glfwSwapBuffers(window);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
aspectRatio = width / float(height);
glViewport(0, 0, width, height);
}
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]);
}
void init(GLFWwindow* window)
{
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glEnable(GL_DEPTH_TEST);
program = shaderLoader.CreateProgram("shaders/shader_5_1.vert", "shaders/shader_5_1.frag");
//programTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
//programEarth = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
//programProcTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
programTex = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
programEarth = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
programProcTex = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
programSkyBox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag");
loadModelToContext("./models/sphere.obj", sphereContext);
loadModelToContext("./models/spaceship.obj", shipContext);
loadModelToContext("./models/cube.obj", cubeContext);
texture::earth = Core::LoadTexture("textures/earth.png");
texture::ship = Core::LoadTexture("textures/spaceship.jpg");
texture::moon = Core::LoadTexture("textures/moon.jpg");
texture::rust = Core::LoadTexture("textures/rust.jpg");
texture::earthNormal = Core::LoadTexture("textures/earth_normalmap.png");
texture::shipNormal = Core::LoadTexture("textures/spaceship_normal.jpg");
texture::rustNormal = Core::LoadTexture("textures/rust_normal.jpg");
texture::moonNormal = Core::LoadTexture("textures/moon_normal.jpg");
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
std::vector<std::string> filepaths = {
"textures/skybox/space_rt.png",
"textures/skybox/space_lf.png",
"textures/skybox/space_up.png",
"textures/skybox/space_dn.png",
"textures/skybox/space_bk.png",
"textures/skybox/space_ft.png",
//"textures/skybox/corona_rt.png",
//"textures/skybox/corona_lf.png",
//"textures/skybox/corona_up.png",
//"textures/skybox/corona_dn.png",
//
//"textures/skybox/corona_bk.png",
//"textures/skybox/corona_ft.png",
//"textures/skybox_new/posx.jpg",
//"textures/skybox_new/negx.jpg",
//"textures/skybox_new/posy.jpg",
//"textures/skybox_new/negy.jpg",
//"textures/skybox_new/posz.jpg",
//"textures/skybox_new/negz.jpg"
};
int w, h;
unsigned char* image;
for (unsigned int i = 0; i < 6; i++)
{
image = SOIL_load_image(filepaths[i].c_str(), &w, &h, 0, SOIL_LOAD_RGBA);
glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image
);
}
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_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);
}
void shutdown(GLFWwindow* window)
{
shaderLoader.DeleteProgram(program);
}
//obsluga wejscia
void processInput(GLFWwindow* window)
{
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f);
float angleSpeed = 0.005f;
float moveSpeed = 0.0025f;
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
spaceshipPos += spaceshipDir * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
spaceshipPos -= spaceshipDir * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS)
spaceshipPos += spaceshipSide * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS)
spaceshipPos -= spaceshipSide * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
spaceshipPos += spaceshipUp * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
spaceshipPos -= spaceshipUp * moveSpeed;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0));
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0));
cameraPos = spaceshipPos - 1.5 * spaceshipDir + glm::vec3(0, 1, 0) * 0.5f;
cameraDir = spaceshipDir;
//cameraDir = glm::normalize(-cameraPos);
}
// funkcja jest glowna petla
void renderLoop(GLFWwindow* window) {
while (!glfwWindowShouldClose(window))
{
processInput(window);
renderScene(window);
glfwPollEvents();
}
}
//}