Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GL/glew.h>
- #include <GLFW/glfw3.h>
- #include <iostream>
- #include <string>
- #include <malloc.h>
- #include <fstream>
- #include <glm/glm.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <vector>
- #include <cmath>
- #include "cube.hh"
- #include "stb_image.h"
- #include <map>
- #include <unordered_map>
- #include <algorithm>
- #define UNIF(shader_name, uniform_name) glGetUniformLocation(shader_name, uniform_name)
- #define GL_N GL_NEAREST
- #define GL_L GL_LINEAR
- #define TINYOBJLOADER_IMPLEMENTATION
- #include "tiny_obj_loader.h"
- //Units in the world are in decimeters.
- // ---------------------------------------------------------------------------------------------------------------------- NAMESPACES ETC.
- using namespace glm;
- using std::string;
- using std::cout;
- using std::cin;
- using std::endl;
- typedef unsigned int uint;
- // ---------------------------------------------------------------------------------------------------------------------- GLOBAL VARIABLES
- float dt = 0;
- float mouseWheel = 0;
- int windowHeight = 900, windowWidth = 1500;
- float aspectRatio = windowWidth / windowHeight;
- float fov = 60.0f * 180.0f / 3.14159265f;
- float g = 98.1;
- bool isNight = true, drawWall = true;
- static uint createShader(const string& vertexShader, const string& fragmentShader);
- string readFile(string filename);
- string toString(uint number);
- // ---------------------------------------------------------------------------------------------------------------------- CAMERA
- struct Camera
- {
- vec3 pos;
- vec3 up;
- vec3 front;
- vec3 flat;
- float speed;
- };
- // ---------------------------------------------------------------------------------------------------------------------- MOUSE
- struct Mouse
- {
- float x;
- float y;
- float xPrev;
- float yPrev;
- float yaw;
- float pitch;
- bool firstMove;
- };
- // ---------------------------------------------------------------------------------------------------------------------- VERTEX
- struct Vertex
- {
- vec3 position;
- vec3 color;
- vec2 texcoord;
- vec3 normal;
- Vertex(vec3 position, vec3 color, vec2 texcoord, vec3 normal)
- : position(position), color(color), texcoord(texcoord), normal(normal) {}
- };
- // ---------------------------------------------------------------------------------------------------------------------- COLLIDER
- struct RectCollider //p1 and p3 are supposed to bo on the opposite sides!
- {
- float width, height;
- vec3 center;
- vec3 normal;
- RectCollider(float width, float height, vec3 p1, vec3 p2, vec3 p3)
- : width(width), height(height)
- {
- center = (p1 + p3);
- center.x /= 2;
- center.y /= 2;
- center.z /= 2;
- vec3 u = p2 - p1;
- vec3 v = p3 - p1;
- normal.x = u.y*v.z - u.z*v.y;
- normal.y = u.z*v.x - u.x*v.z;
- normal.z = u.x*v.y - u.y*v.x;
- }
- };
- struct Collision
- {
- vec3 position, normal;
- float penetration;
- };
- // ---------------------------------------------------------------------------------------------------------------------- GLOBAL STRUCTS
- RectCollider colliderRampTop(20.0f, sqrt(15.0f*15.0f + 30.0f*30.0f), vec3(10.0f, 0.0f, 40.0f), vec3(-10.0f, 0.0f, 40.0f), vec3(-10.0f, 15.0f, 70.0f));
- Camera camera;
- Mouse mouse;
- // ---------------------------------------------------------------------------------------------------------------------- SHADER CLASS AND GLOBAL DECLARATION
- class Shader
- {
- private:
- uint shaderProgram;
- public:
- Shader()
- {
- }
- void LoadShader(string vertexShaderPath, string fragmentShaderPath)
- {
- //shader = createShader(readFile("model_vertex_shader.vert"), readFile("model_fragment_shader.vert"));
- shaderProgram = createShader(readFile(vertexShaderPath), readFile(fragmentShaderPath));
- }
- void UseShader()
- {
- glUseProgram(shaderProgram);
- }
- uint& GetShader()
- {
- return shaderProgram;
- }
- };
- Shader modelShader;
- Shader simpleShader;
- Shader lightShader;
- Shader daylightShader;
- // ---------------------------------------------------------------------------------------------------------------------- MODEL
- class Model
- {
- private:
- std::vector<Vertex> vertices;
- std::vector<uint32_t> indices;
- uint vao;
- uint* vbo;
- //uint shader;
- uint texture;
- int width, height, nrChannels;
- unsigned char* data;
- float modelScale;
- public:
- Model()
- {
- vbo = new uint[5];
- }
- Model(string modelPath, float modelScale = 1.0f, float texScale = 1.0f)
- {
- vbo = new uint[5];
- LoadModel(modelPath, modelScale, texScale);
- }
- ~Model()
- {
- delete [] vbo;
- }
- void LoadModel(string modelPath, float modelScale = 1.0f, float texScale = 1.0f)
- {
- this->modelScale = modelScale;
- tinyobj::attrib_t attributes;
- std::vector<tinyobj::shape_t> shapes;
- std::vector<tinyobj::material_t> materials;
- string warning, error;
- //string modelPath = "basketball/NBA BASKETBALL.obj";
- if (!tinyobj::LoadObj(&attributes, &shapes, &materials, &warning, &error, modelPath.c_str()))
- {
- throw std::runtime_error(warning + error);
- }
- for (const tinyobj::shape_t& shape : shapes)
- {
- for (const tinyobj::index_t& index : shape.mesh.indices)
- {
- const vec3 position{
- attributes.vertices[3 * index.vertex_index + 0], // x
- attributes.vertices[3 * index.vertex_index + 1], // y
- attributes.vertices[3 * index.vertex_index + 2], // z
- };
- const vec3 color{ 1.f, 1.f, 1.f };
- const vec2 texcoord{
- attributes.texcoords[2 * index.texcoord_index + 0],
- attributes.texcoords[2 * index.texcoord_index + 1],
- };
- const vec3 normal{
- attributes.normals[3 * index.normal_index + 0], // x
- attributes.normals[3 * index.normal_index + 1], // y
- attributes.normals[3 * index.normal_index + 2], // z
- };
- this->vertices.push_back(Vertex(position, color, texcoord, normal));
- this->indices.push_back(vertices.size() - 1);
- }
- }
- if (modelScale != 1.0f && modelScale > 0.0f)
- {
- uint vertSize = vertices.size();
- for (uint i = 0; i < vertSize; i++)
- {
- vertices[i].position.x *= modelScale;
- vertices[i].position.y *= modelScale;
- vertices[i].position.z *= modelScale;
- }
- }
- if (texScale != 1.0f && texScale > 0.0f)
- {
- uint vertSize = vertices.size();
- for (uint i = 0; i < vertSize; i++)
- {
- vertices[i].texcoord.x *= texScale;
- vertices[i].texcoord.y *= texScale;
- }
- }
- /*
- float minY = 0.0f, maxY = 0.0f;
- float minX = 0.0f, maxX = 0.0f;
- float minZ = 0.0f, maxZ = 0.0f;
- for (int i = 0; i < vertices.size(); i++)
- {
- if (vertices[i].position.y > maxY) maxY = vertices[i].position.y;
- if (vertices[i].position.y < minY) minY = vertices[i].position.y;
- if (vertices[i].position.x > maxX) maxX = vertices[i].position.x;
- if (vertices[i].position.x < minX) minX = vertices[i].position.x;
- if (vertices[i].position.z > maxZ) maxZ = vertices[i].position.z;
- if (vertices[i].position.z < minZ) minZ = vertices[i].position.z;
- }
- cout << "\nMAX Y: " << maxY << ", MIN Y: " << minY << "\n";
- cout << "\nMAX X: " << maxX << ", MIN X: " << minX << "\n";
- cout << "\nMAX Z: " << maxZ << ", MIN Z: " << minZ << "\n";
- */
- /*
- cout << "vertices size: " << this->vertices.size() << "\n";
- cout << "first index:\n position: " << this->vertices[0].position.x << ", " <<
- this->vertices[0].position.y << ", " <<
- this->vertices[0].position.z << "\n";
- cout << "first index:\n color: " << this->vertices[0].color.x << ", " <<
- this->vertices[0].color.y << ", " <<
- this->vertices[0].color.z << "\n";
- cout << "first index:\n texcoord: " << this->vertices[0].texcoord.x << ", " <<
- this->vertices[0].texcoord.y << "\n";
- */
- }
- void InitModel(string texturePath)
- {
- //SHADER:
- //shader = createShader(readFile("model_vertex_shader.vert"), readFile("model_fragment_shader.vert"));
- //BUFORY:
- glGenVertexArrays(1, &vao);
- glGenBuffers(5, vbo);
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), this->vertices.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(0, 3, GL_FLOAT, false, 11 * sizeof(float), 0);
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), this->vertices.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(1, 3, GL_FLOAT, false, 11 * sizeof(float), (void*) (3 * sizeof(float)));
- glEnableVertexAttribArray(1);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
- glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), this->vertices.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(2, 2, GL_FLOAT, false, 11 * sizeof(float), (void*) (6 * sizeof(float)));
- glEnableVertexAttribArray(2);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
- glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), this->vertices.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(3, 3, GL_FLOAT, false, 11 * sizeof(float), (void*) (8 * sizeof(float)));
- glEnableVertexAttribArray(3);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(indices[0]), indices.data(), GL_STATIC_DRAW);
- glBindVertexArray(0);
- //TEKSTURA:
- stbi_set_flip_vertically_on_load(1);
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
- // set the texture wrapping/filtering options (on the currently bound texture object)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_L);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_L);
- // load and generate the texture
- //data = stbi_load("basketball/maps/NBA BASKETBALL DIFFUSE.tga", &width, &height, &nrChannels, 0); //"basketball/maps/ballTex.jpg"
- data = stbi_load(texturePath.c_str(), &width, &height, &nrChannels, 0);
- if (data)
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
- //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, width, height, GL_TRUE);
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- else
- {
- cout << "Failed to load texture" << endl;
- }
- glBindTexture(GL_TEXTURE_2D, 0);
- stbi_image_free(data);
- }
- void Bind()
- {
- glBindTexture(GL_TEXTURE_2D, texture);
- glBindVertexArray(vao);
- //glUseProgram(shader);
- }
- void Unbind()
- {
- glBindVertexArray(0);
- }
- void Draw(GLFWwindow* window, Shader& shader, const mat4& P, const mat4& V, const mat4& M)
- {
- Bind();
- shader.UseShader();
- const uint& shaderName = shader.GetShader();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //FILL OR WIREFRAME?
- glUniformMatrix4fv(UNIF(shaderName, "M"), 1, false, value_ptr(M));
- glUniformMatrix4fv(UNIF(shaderName, "P"), 1, false, value_ptr(P));
- glUniformMatrix4fv(UNIF(shaderName, "V"), 1, false, value_ptr(V));
- //glUniform3fv(UNIF(shader, "lightColor"), 1, value_ptr(lightColor));
- glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
- //glDrawArrays(GL_TRIANGLES, 0, this->vertices.size());
- Unbind();
- }
- void Draw(GLFWwindow* window, Shader& shader, const mat4& P, const mat4& V)
- {
- Bind();
- shader.UseShader();
- const uint& shaderName = shader.GetShader();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //FILL OR WIREFRAME?
- mat4 M(1.0f);
- glUniformMatrix4fv(UNIF(shaderName, "M"), 1, false, value_ptr(M));
- glUniformMatrix4fv(UNIF(shaderName, "P"), 1, false, value_ptr(P));
- glUniformMatrix4fv(UNIF(shaderName, "V"), 1, false, value_ptr(V));
- //glUniform3fv(UNIF(shader, "lightColor"), 1, value_ptr(lightColor));
- glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
- //glDrawArrays(GL_TRIANGLES, 0, this->vertices.size());
- Unbind();
- }
- float GetScale()
- {
- return modelScale;
- }
- };
- // ---------------------------------------------------------------------------------------------------------------------- SKYBOX
- class Skybox
- {
- private:
- uint vao;
- uint* vbo;
- std::vector<float> positions;
- std::vector<float> texs;
- //uint shader;;
- uint texture;
- int width, height, nrChannels;
- unsigned char* data;
- public:
- Skybox()
- {
- positions = {
- -0.5f, -0.5f, -0.5f, //back
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f, //front
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f, //left
- -0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f, //right
- 0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f, //bottom
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f, //top
- 0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f };
- for (int i = 0; i < positions.size(); i++) positions[i] *= 3000;
- texs = {
- 0.0f, 0.25f,
- 0.25f, 0.25f,
- 0.25f, 0.5f,
- 0.25f, 0.5f,
- 0.0f, 0.5f,
- 0.0f, 0.25f,
- 0.75f, 0.25f,
- 0.5f, 0.25f,
- 0.5f, 0.5f,
- 0.5f, 0.5f,
- 0.75f, 0.5f,
- 0.75f, 0.25f,
- 0.75f, 0.5f,
- 1.0f, 0.5f,
- 1.0f, 0.25f,
- 1.0f, 0.25f,
- 0.75f, 0.25f,
- 0.75f, 0.5f,
- 0.5f, 0.5f,
- 0.25f, 0.5f,
- 0.25f, 0.25f,
- 0.25f, 0.25f,
- 0.5f, 0.25f,
- 0.5f, 0.5f,
- 1.0f, 0.25f,
- 1.0f, 0.0f,
- 0.75f, 0.0f,
- 0.75f, 0.0f,
- 0.75f, 0.25f,
- 1.0f, 0.25f,
- 1.0f, 0.5f,
- 1.0f, 0.75f,
- 0.75f, 0.75f,
- 0.75f, 0.75f,
- 0.75f, 0.5f,
- 1.0f, 0.5f, };
- vbo = new uint[2];
- }
- ~Skybox()
- {
- delete [] vbo;
- }
- void InitSkybox(string texPath)
- {
- //SHADER:
- //shader = createShader(readFile("sky_vertex_shader.vert"), readFile("sky_fragment_shader.vert"));
- //BUFORY:
- glGenVertexArrays(1, &vao);
- glGenBuffers(2, vbo);
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(positions[0]), positions.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, texs.size() * sizeof(texs[0]), texs.data(), GL_STATIC_DRAW);
- glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
- glEnableVertexAttribArray(1);
- glBindVertexArray(0);
- //TEKSTURA:
- stbi_set_flip_vertically_on_load(1);
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
- // set the texture wrapping/filtering options (on the currently bound texture object)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_L);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_L);
- // load and generate the texture
- data = stbi_load(texPath.c_str(), &width, &height, &nrChannels, 0);
- if (data)
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, width, height, GL_TRUE);
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- else
- {
- cout << "Failed to load texture" << endl;
- }
- glBindTexture(GL_TEXTURE_2D, 0);
- stbi_image_free(data);
- }
- void Bind()
- {
- glBindTexture(GL_TEXTURE_2D, texture);
- glBindVertexArray(vao);
- //glUseProgram(shader);
- }
- void Unbind()
- {
- glBindVertexArray(0);
- }
- void Draw(GLFWwindow* window, const mat4& P, const mat4& V, const vec3& camPos)
- {
- Bind();
- simpleShader.UseShader();
- const uint& shaderName = simpleShader.GetShader();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //FILL OR WIREFRAME?
- mat4 M(1.0f);
- M = glm::translate(M, camPos);
- glUniformMatrix4fv(UNIF(shaderName, "M"), 1, false, value_ptr(M));
- glUniformMatrix4fv(UNIF(shaderName, "P"), 1, false, value_ptr(P));
- glUniformMatrix4fv(UNIF(shaderName, "V"), 1, false, value_ptr(V));
- glDrawArrays(GL_TRIANGLES, 0, 36);
- Unbind();
- }
- };
- // ---------------------------------------------------------------------------------------------------------------------- LIGHT
- class Light
- {
- public:
- static Model model;
- private:
- vec3 lightPos;
- vec3 lightColor;
- mat4 M;
- static uint nr;
- string lightPosStr, lightColorStr;
- public:
- Light(vec3 lightPos = vec3(0.0f, 0.0f, 0.0f), vec3 lightColor = vec3(1.0f, 1.0f, 1.0f))
- : lightPos(lightPos), lightColor(lightColor), M(1.0f)
- {
- nr++;
- M = glm::translate(M, lightPos);
- string nrStr = toString(nr);
- lightPosStr = "lightPos" + nrStr;
- lightColorStr = "lightColor" + nrStr;
- }
- ~Light()
- {
- nr--;
- }
- void Draw(GLFWwindow* window, const mat4& P, const mat4& V)
- {
- if (isNight)
- {
- modelShader.UseShader();
- const uint& shaderName = modelShader.GetShader();
- glUniform3fv(UNIF(shaderName, lightPosStr.c_str()), 1, value_ptr(lightPos));
- glUniform3fv(UNIF(shaderName, lightColorStr.c_str()), 1, value_ptr(lightColor));
- //glUniform3fv(UNIF(shaderName, "lightPos1"), 1, value_ptr(lightPos));
- //glUniform3fv(UNIF(shaderName, "lightColor1"), 1, value_ptr(lightColor));
- glUniform3fv(UNIF(shaderName, "cameraPos"), 1, value_ptr(camera.pos));
- }
- else
- {
- daylightShader.UseShader();
- const uint& shaderName = daylightShader.GetShader();
- glUniform3fv(UNIF(shaderName, lightPosStr.c_str()), 1, value_ptr(lightPos));
- glUniform3fv(UNIF(shaderName, lightColorStr.c_str()), 1, value_ptr(lightColor));
- //glUniform3fv(UNIF(shaderName, "lightPos1"), 1, value_ptr(lightPos));
- //glUniform3fv(UNIF(shaderName, "lightColor1"), 1, value_ptr(lightColor));
- glUniform3fv(UNIF(shaderName, "cameraPos"), 1, value_ptr(camera.pos));
- }
- model.Draw(window, lightShader, P, V, M);
- }
- void Move(vec3 ds)
- {
- lightPos += ds;
- M = glm::translate(M, ds);
- }
- };
- Model Light::model;
- uint Light::nr = 0;
- // ---------------------------------------------------------------------------------------------------------------------- BALL
- class Ball
- {
- public:
- static Model model;
- private:
- float r;
- float scale;
- mat4 M;
- vec3 center;
- vec3 v;
- vec3 ds;
- float angle;
- int id;
- vec3 pivot;
- float weaker;
- public:
- Ball(float startV = 0, float centerOffset = 3.0f, int id = -1)
- : v(camera.front * startV), r(18.9 * model.GetScale()), scale(/*0.0635f*/1.0f), M(1.0f), center(camera.pos + centerOffset * camera.front), id(id), pivot(vec3(0.0f, 1.0f, 0.0f)), weaker(6.0f)
- {
- M = glm::translate(M, center);
- M = glm::scale(M, vec3(scale, scale, scale));
- r *= scale;
- }
- Draw(GLFWwindow* window, const mat4& P, const mat4& V)
- {
- if (isNight) model.Draw(window, modelShader, P, V, M);
- else model.Draw(window, daylightShader, P, V, M);
- }
- vec3 GetCenter()
- {
- return center;
- }
- void MoveBall(std::vector<Ball>& balls)
- {
- //flight:
- ds.x = v.x * dt;
- ds.z = v.z * dt;
- v.y = v.y - g * dt * 1.0f;
- if (v.y < -1000.0f) v.y = -1000.0f;
- ds.y = v.y * dt;
- center += ds;
- //Bouncing:
- if (center.y - r < 0.0f && (center.x - r < 100.0f && center.x + r > -100.0f) && (center.z - r < 100.0f && center.z + r > -100.0f))
- {
- //vec3 t = camera.pos + 2.0f * camera.front;
- //cout << center.y << " ... " << center.y - r << " ... " << camera.pos.y << " ... " << t.y << '\n';
- float temp = (center.y - r) * (-1.0f);
- center.y += temp;
- ds.y += temp;
- v.y = v.y * (-1.0f) * 0.7f;
- if (abs(ds.y) > 0.1f)
- {
- v.x = v.x * 0.7f;
- v.z = v.z * 0.7f;
- if (weaker > 1.0f) weaker--;
- }
- else
- {
- //v.x = v.x * 0.999f;
- //v.z = v.z * 0.999f;
- v.x = v.x * 0.999f;
- v.z = v.z * 0.999f;
- weaker = 1.0f;
- }
- if (abs(v.x) < 0.1f && abs(v.z) < 0.1f)
- {
- v.x = 0.0f;
- v.z = 0.0f;
- }
- }
- //Wall bouncing:
- if (center.x - r < -100.0f)
- {
- float temp = (center.x - r + 100.0f) * (-1.0f);
- center.x += temp;
- ds.x += temp;
- v.x *= (-0.8f);
- }
- if (center.z - r < -100.0f)
- {
- float temp = (center.z - r + 100.0f) * (-1.0f);
- center.z += temp;
- ds.z += temp;
- v.z *= (-0.8f);
- }
- if (center.x + r > 100.0f)
- {
- float temp = (center.x + r - 100.0f) * (-1.0f);
- center.x += temp;
- ds.x += temp;
- v.x *= (-0.8f);
- }
- if (center.z + r > 100.0f)
- {
- float temp = (center.z + r - 100.0f) * (-1.0f);
- center.z += temp;
- ds.z += temp;
- v.z *= (-0.8f);
- }
- //Collide with other balls:
- for (int i = 0; i < balls.size(); i++)
- {
- if (balls[i].GetID() == id) continue;
- if (glm::distance(balls[i].GetCenter(), center) < r*2)
- {
- }
- }
- //Rotate:
- vec3 dsFlat = glm::normalize(vec3(ds.x, 0.0f, ds.z));
- vec3 up = vec3(0.0f, 1.0f, 0.0f);
- if (ds.x != 0.0f || ds.z != 0.0f) pivot = glm::cross(dsFlat, up);
- angle -= sqrt((ds.x*ds.x) + (ds.z*ds.z)) / weaker;
- //Update M matrix:
- M = mat4(1.0f);
- M = glm::translate(M, center);
- M = glm::rotate(M, angle, pivot);
- }
- int GetID()
- {
- return id;
- }
- };
- Model Ball::model;
- // ---------------------------------------------------------------------------------------------------------------------- BALLS SET
- class BallsSet
- {
- private:
- uint ballsCount = 0;
- std::vector<Ball> balls;
- public:
- BallsSet()
- {
- }
- ~BallsSet()
- {
- }
- void CreateBall()
- {
- ballsCount++;
- Ball newBall(70.0f, 3.0f, ballsCount);
- balls.push_back(newBall);
- }
- void CreateStaticBall()
- {
- ballsCount++;
- Ball newBall(0.0f, 10.0f, ballsCount);
- balls.push_back(newBall);
- }
- void RemoveLastBall()
- {
- if (!ballsCount) return;
- balls.pop_back();
- ballsCount--;
- }
- void UpdateBalls()
- {
- for (int i = 0; i < ballsCount; i++)
- {
- balls[i].MoveBall(balls);
- }
- }
- void DrawBalls(GLFWwindow* window, const mat4& P, const mat4& V)
- {
- for (int i = 0; i < ballsCount; i++)
- {
- balls[i].Draw(window, P, V);
- }
- }
- };
- // ---------------------------------------------------------------------------------------------------------------------- WALL
- class SquareWall
- {
- public:
- static Model model;
- private:
- mat4 M;
- float distanceFromOrigin;
- float dip;
- public:
- SquareWall(float distanceFromOrigin = 109.0f, float dip = -50.0f)
- : M(1.0f), distanceFromOrigin(distanceFromOrigin), dip(dip) {}
- void Draw(GLFWwindow* window, const mat4& P, const mat4& V)
- {
- M = mat4(1.0f);
- M = glm::translate(M, vec3(0.0f, dip, distanceFromOrigin));
- if (isNight) model.Draw(window, modelShader, P, V, M);
- else model.Draw(window, daylightShader, P, V, M);
- M = mat4(1.0f);
- M = glm::translate(M, vec3(0.0f, dip, -distanceFromOrigin));
- M = glm::rotate(M, glm::radians(180.0f), vec3(0.0f, 1.0f, 0.0f));
- if (isNight) model.Draw(window, modelShader, P, V, M);
- else model.Draw(window, daylightShader, P, V, M);
- M = mat4(1.0f);
- M = glm::translate(M, vec3(distanceFromOrigin, dip, 0.0f));
- M = glm::rotate(M, glm::radians(90.0f), vec3(0.0f, 1.0f, 0.0f));
- if (isNight) model.Draw(window, modelShader, P, V, M);
- else model.Draw(window, daylightShader, P, V, M);
- M = mat4(1.0f);
- M = glm::translate(M, vec3(-distanceFromOrigin, dip, 0.0f));
- M = glm::rotate(M, glm::radians(270.0f), vec3(0.0f, 1.0f, 0.0f));
- if (isNight) model.Draw(window, modelShader, P, V, M);
- else model.Draw(window, daylightShader, P, V, M);
- }
- };
- Model SquareWall::model;
- // ---------------------------------------------------------------------------------------------------------------------- GLOBAL MODELS DECLARATION
- Model basketballPost("basketball/Basketball_Post_No_Ball.obj");
- Model ground("surface/ground.obj", 100.0f, 10.0f);
- Model house1("houses/house1/House01_OBJ.obj", 10.0f);
- Model ramp1("surface/ramp1.obj");
- Model ramp2("surface/ramp2.obj");
- BallsSet ballsSet;
- Skybox skyboxNight;
- Skybox skyboxDay;
- Light light1(vec3(150.0f, 100.0f, 50.0f), vec3(0.8f, 0.8f, 0.8f));
- Light light2(vec3(-100.0f, 100.0f, -50.0f), vec3(0.5f, 0.5f, 0.5f));
- Light light3(vec3(1000000.0f, 1000000.0f, 0.0f), vec3(0.8f, 0.7f, 0.6f));
- //Light light3(vec3(1000000.0f, 1000000.0f, 0.0f), vec3(1.0f, 0.6f, 0.25f));
- SquareWall wall;
- // ---------------------------------------------------------------------------------------------------------------------- SHADERS BUILDING
- static uint compileShader(uint type, const string& source)
- {
- uint id = glCreateShader(type);
- const char* src = source.c_str();
- glShaderSource(id, 1, &src, nullptr);
- glCompileShader(id);
- int result;
- glGetShaderiv(id, GL_COMPILE_STATUS, &result);
- if (result == GL_FALSE) // !result
- {
- int length;
- glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
- char* message = (char*) alloca(length * sizeof(char));
- glGetShaderInfoLog(id, length, &length, message);
- cout << "Failed to compile " <<
- (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader:\n";
- cout << message << endl;
- glDeleteShader(id);
- return 0;
- }
- return id;
- }
- static uint createShader(const string& vertexShader, const string& fragmentShader)
- {
- uint program = glCreateProgram();
- uint vs = compileShader(GL_VERTEX_SHADER, vertexShader);
- uint fs = compileShader(GL_FRAGMENT_SHADER, fragmentShader);
- glAttachShader(program, vs);
- glAttachShader(program, fs);
- glLinkProgram(program);
- glValidateProgram(program);
- glDeleteShader(vs); //glDetachShader(vs);
- glDeleteShader(fs); //glDetachShader(fs);
- return program;
- }
- // ---------------------------------------------------------------------------------------------------------------------- READ FILE
- string readFile(string filename)
- {
- std::ifstream file(filename);
- std::string content((std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>()));
- return content;
- }
- // ---------------------------------------------------------------------------------------------------------------------- TO STRING
- string toString(uint number)
- {
- string result = "";
- while (number)
- {
- uint digit = number % 10;
- number = number / 10;
- char chDigit = digit + 48;
- result += chDigit;
- }
- reverse(result.begin(), result.end());
- return result;
- }
- // ---------------------------------------------------------------------------------------------------------------------- EVENTS
- void onMouseScroll(GLFWwindow *window, double xOffset, double yOffset)
- {
- mouseWheel += (float) yOffset;
- }
- void onMouseClick(GLFWwindow *window, int button, int action, int mods)
- {
- if (action == GLFW_PRESS)
- {
- double x, y;
- glfwGetCursorPos(window, &x, &y);
- if (button == GLFW_MOUSE_BUTTON_LEFT)
- {
- ballsSet.CreateBall();
- }
- if (button == GLFW_MOUSE_BUTTON_RIGHT)
- {
- ballsSet.RemoveLastBall();
- }
- if (button == GLFW_MOUSE_BUTTON_MIDDLE)
- {
- ballsSet.CreateStaticBall();
- }
- }
- }
- void handleCamera(GLFWwindow* window)
- {
- if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
- camera.pos += dt * camera.speed * camera.flat;
- if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
- camera.pos -= dt * camera.speed * camera.flat;
- if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
- camera.pos += dt * glm::normalize(glm::cross(camera.front, camera.up)) * camera.speed;
- if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
- camera.pos -= dt * glm::normalize(glm::cross(camera.front, camera.up)) * camera.speed;
- if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
- camera.pos.y += dt * camera.speed;
- if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) camera.pos.y -= dt * camera.speed;
- if (camera.pos.y < 3.0f) camera.pos.y = 3.0f;
- if (camera.pos.y > 47.0f) camera.pos.y = 47.0f;
- if (camera.pos.x < -98.0f) camera.pos.x = -98.0f;
- if (camera.pos.x > 98.0f) camera.pos.x = 98.0f;
- if (camera.pos.z < -98.0f) camera.pos.z = -98.0f;
- if (camera.pos.z > 98.0f) camera.pos.z = 98.0f;
- }
- void onKeyboard(GLFWwindow *window, int key, int code, int action, int mods)
- {
- static int turn = 0;
- if (action == GLFW_PRESS)
- {
- if (key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, true);
- if (key == GLFW_KEY_Z)
- {
- if ((turn++ % 2)) glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- else glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- }
- if (key == GLFW_KEY_X)
- {
- if (isNight) isNight = 0;
- else isNight = 1;
- }
- if (key == GLFW_KEY_C)
- {
- if (drawWall) drawWall = 0;
- else drawWall = 1;
- }
- }
- }
- void onResize(GLFWwindow *window, int width, int height)
- {
- windowWidth = width, windowHeight = height;
- if (height == 0) return;
- glViewport(0, 0, width, height);
- aspectRatio = (float) width / (float) height;
- cout << windowHeight << ", " << windowWidth << "\n";
- }
- void mouse_callback(GLFWwindow* window, double x, double y) //MOUSE CALLBACK
- {
- mouse.x = x;
- mouse.y = y;
- if(mouse.firstMove) // this bool variable is initially set to true
- {
- mouse.xPrev = mouse.x;
- mouse.yPrev = mouse.y;
- mouse.firstMove = false;
- }
- float xOffset = mouse.x - mouse.xPrev;
- float yOffset = mouse.yPrev - mouse.y; // reversed since y-coordinates range from bottom to top
- mouse.xPrev = mouse.x;
- mouse.yPrev = mouse.y;
- float sensitivity = 0.1f;
- xOffset *= sensitivity;
- yOffset *= sensitivity;
- mouse.yaw += xOffset;
- mouse.pitch += yOffset;
- if(mouse.pitch > 89.0f) mouse.pitch = 89.0f;
- if(mouse.pitch < -89.0f) mouse.pitch = -89.0f;
- camera.front.x = cos(glm::radians(mouse.pitch)) * cos(glm::radians(mouse.yaw));
- camera.front.y = sin(glm::radians(mouse.pitch));
- camera.front.z = cos(glm::radians(mouse.pitch)) * sin(glm::radians(mouse.yaw));
- camera.front = glm::normalize(camera.front);
- camera.flat.x = cos(glm::radians(mouse.yaw));
- camera.flat.z = sin(glm::radians(mouse.yaw));
- camera.flat = glm::normalize(camera.flat);
- }
- // ---------------------------------------------------------------------------------------------------------------------- INITIALIZATIONS OF MOUSE AND CAMERA
- void initMouse()
- {
- mouse.yaw = 0.0f;Camera camera;
- Mouse mouse;
- mouse.pitch = 0.0f;
- mouse.firstMove = true;
- }
- void initCamera()
- {
- camera.pos = vec3(0.0f, 0.0f, 10.0f);
- camera.up = vec3(0.0f, 1.0f, 0.0f);
- camera.front = vec3(0.0f, 0.0f, -1.0f);
- camera.flat = vec3(0.0f, 0.0f, -1.0f);
- camera.speed = 30.0f;
- }
- // ---------------------------------------------------------------------------------------------------------------------- INITIALIZATION OF SCENE, MODELS AND OTHER OBJECTS
- void initScene()
- {
- glClearColor(0.08f, 0.08f, 0.12f, 0.0f);
- glEnable(GL_DEPTH_TEST);
- modelShader.LoadShader("model_vertex_shader.vert", "model_fragment_shader.vert");
- simpleShader.LoadShader("sky_vertex_shader.vert", "sky_fragment_shader.vert");
- lightShader.LoadShader("light_vertex_shader.vert", "light_fragment_shader.vert");
- daylightShader.LoadShader("daylight_vertex_shader.vert", "daylight_fragment_shader.vert");
- Light::model.LoadModel("light/lantern/Gamelantern_updated.obj", 20.0f);
- Light::model.InitModel("light/lantern/Old_lantern_UV_Diffuse.png");
- //Light::model.LoadModel("light/modernLamp/export.obj", 0.2f);
- //Light::model.InitModel("light/modernLamp/texture/vasa otlivom biruzy.jpg");
- Ball::model.LoadModel("basketball/NBA BASKETBALL.obj", 0.0635f);
- Ball::model.InitModel("basketball/maps/ballTex.png");
- SquareWall::model.LoadModel("wall/stone wall/stonewall.obj", 17.0f);
- SquareWall::model.InitModel("wall/stone wall/Textures/red4.jpg");
- initMouse();
- initCamera();
- skyboxNight.InitSkybox("skybox/nightSkybox.png");
- //skyboxDay.InitSkybox("skybox/skyboxSunset.png");
- skyboxDay.InitSkybox("skybox/skybox4.png");
- basketballPost.InitModel("basketball/maps/Basketball_Post.jpg");
- house1.InitModel("houses/house1/Building.Texture2.jpg");
- //house1.InitModel("basketball/maps/Basketball_Post.jpg");
- ground.InitModel("surface/tiles2.jpg");
- //ground.InitModel("brick.png");
- ramp1.InitModel("surface/concrete.jpg");
- ramp2.InitModel("surface/concrete.jpg");
- }
- // ---------------------------------------------------------------------------------------------------------------------- DRAWING SCENE
- void drawScene(GLFWwindow* window)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- handleCamera(window);
- mat4 P = glm::perspective(fov, aspectRatio, 0.5f, 3000.0f); //500.0f
- mat4 V = glm::lookAt(camera.pos, camera.pos + camera.front, camera.up);
- mat4 M_basketballPost(1.0f);
- M_basketballPost = glm::translate(M_basketballPost, vec3(0.0f, 0.0f, -70.0f));
- M_basketballPost = glm::scale(M_basketballPost, vec3(0.2f, 0.2f, 0.2f));
- float dist = 250.0f;
- vec3 Trans[12] = {
- vec3(dist, 15.0f, dist),
- vec3(dist/2, 15.0f, dist),
- vec3(0.0f, 15.0f, dist),
- vec3(-dist/2, 15.0f, dist),
- vec3(-dist, 15.0f, dist),
- vec3(dist, 15.0f, 0.0f),
- vec3(-dist, 15.0f, 0.0f),
- vec3(dist, 15.0f, -dist),
- vec3(dist/2, 15.0f, -dist),
- vec3(0.0f, 15.0f, -dist),
- vec3(-dist/2, 15.0f, -dist),
- vec3(-dist, 15.0f, -dist),
- };
- if (isNight)
- {
- light1.Draw(window, P, V);
- light2.Draw(window, P, V);
- skyboxNight.Draw(window, glm::perspective(fov, aspectRatio, 0.001f, 5000.0f), V, camera.pos); ////////////////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- basketballPost.Draw(window, modelShader, P, V, M_basketballPost);
- ground.Draw(window, modelShader, P, V);
- ramp1.Draw(window, modelShader, P, V);
- ramp2.Draw(window, modelShader, P, V);
- for (int i = 0; i < 12; i++)
- {
- mat4 M(1.0f);
- M = glm::translate(M, Trans[i]);
- house1.Draw(window, modelShader, P, V, M);
- }
- }
- else
- {
- light3.Draw(window, P, V);
- skyboxDay.Draw(window, glm::perspective(fov, aspectRatio, 0.001f, 5000.0f), V, camera.pos);
- basketballPost.Draw(window, daylightShader, P, V, M_basketballPost);
- ground.Draw(window, daylightShader, P, V);
- ramp1.Draw(window, daylightShader, P, V);
- ramp2.Draw(window, daylightShader, P, V);
- for (int i = 0; i < 12; i++)
- {
- mat4 M(1.0f);
- M = glm::translate(M, Trans[i]);
- house1.Draw(window, daylightShader, P, V, M);
- }
- }
- if (drawWall) wall.Draw(window, P, V);
- ballsSet.UpdateBalls();
- ballsSet.DrawBalls(window, P, V);
- glfwSwapBuffers(window);
- }
- // ---------------------------------------------------------------------------------------------------------------------- MAIN()
- int main()
- {
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- glfwWindowHint(GLFW_SAMPLES, 8);
- glEnable(GL_MULTISAMPLE);
- GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "My Balls", NULL, NULL);
- if (!window)
- {
- cout << "Failed to create GLFW window\n";
- glfwTerminate();
- return -1;
- }
- glfwMakeContextCurrent(window); //PRZYPISANIE KONTEKSTU DO OKNA window
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- if (GLEW_OK != glewInit()) cout << "Failed to initialize GLEW\n";
- cout << glGetString(GL_VERSION) << endl;
- glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); //REAGOWNIE NA INPUTY
- glfwSetKeyCallback(window, onKeyboard);
- glfwSetScrollCallback(window, onMouseScroll);
- glfwSetMouseButtonCallback(window, onMouseClick);
- glfwSetWindowSizeCallback(window, onResize);
- glfwSetCursorPosCallback(window, mouse_callback);
- glfwPollEvents();
- //glEnable(GL_CULL_FACE);
- //glCullFace(GL_BACK);
- //glFrontFace(GL_CCW);
- initScene();
- glfwSetTime(0);
- onResize(window, windowWidth, windowHeight);
- while(!glfwWindowShouldClose(window))
- {
- dt = glfwGetTime();
- glfwSetTime(0);
- drawScene(window);
- glfwPollEvents();
- }
- glfwTerminate();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement