Commit ea9a7174 authored by Adam S's avatar Adam S
Browse files

upload

parent cb86d657
# CMakeList.txt : Top-level CMake project file, do global configuration
# and include sub-projects here.
#
cmake_minimum_required (VERSION 3.8)
project ("GameEngine")
find_package( OpenGL REQUIRED )
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
# Include sub-projects.
add_subdirectory ("GameEngine")
add_subdirectory ("include/glfw-3.3.3")
add_subdirectory ("include/glad")
#include "BreakOut3D.h"
// Init of static variables so the callbacks work!
// ---------------------------------------------------------------------------------------------------
unsigned int BreakOut3D::SCR_WIDTH = 1280;
unsigned int BreakOut3D::SCR_HEIGHT = 720;
float BreakOut3D::camera_radius = 15.0f;
vec3 BreakOut3D::camera_position = vec3(1.0f * camera_radius, 0.0f * camera_radius, 20.0f);
bool BreakOut3D::ball_launched = false;
bool BreakOut3D::top_camera = false;
bool BreakOut3D::game_over = false;
// ---------------------------------------------------------------------------------------------------
BreakOut3D::BreakOut3D(int brick_rows, int brick_cols) {
brick_row_count = brick_rows;
brick_in_row_count = brick_cols;
}
void BreakOut3D::framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
SCR_HEIGHT = height;
SCR_WIDTH = width;
glViewport(0, 0, width, height);
}
void BreakOut3D::processInput(GLFWwindow* window, std::vector<Paddle>& paddles)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera_position.z += camera_speed * deltaTime;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera_position.z -= camera_speed * deltaTime;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera_position = (MatrixGenerator::rotateAround(MatrixGenerator::radians(camera_angle_speed) * deltaTime, vec3(0.0f, 0.0f, 1.0f)) * vec4(camera_position, 1.0f)).xyz;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera_position = (MatrixGenerator::rotateAround(MatrixGenerator::radians(-camera_angle_speed) * deltaTime, vec3(0.0f, 0.0f, 1.0f)) * vec4(camera_position, 1.0f)).xyz;
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
for (Paddle& p : paddles) {
p.update(Movement::left, deltaTime);
}
}
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
for (Paddle& p : paddles) {
p.update(Movement::right, deltaTime);
}
}
}
void BreakOut3D::scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
camera_position = (MatrixGenerator::translate(-camera_position.normalized() * yoffset) * vec4(camera_position, 1.0f)).xyz;
}
void BreakOut3D::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
{
if (ball_launched) {
return;
}
game_over = false;
ball_launched = true;
}
if (key == GLFW_KEY_1 && action == GLFW_PRESS)
{
top_camera = false;
}
if (key == GLFW_KEY_2 && action == GLFW_PRESS)
{
top_camera = true;
}
}
void BreakOut3D::ui_init(GLFWwindow* window) {
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();
io.Fonts->AddFontDefault();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 450");
}
void BreakOut3D::ui_frame_data(bool game_over, bool won) {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f)); //top left corner
ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f)); //no border
ImGui::Begin("BreakOut");
ImGui::Text("Controls:");
ImGui::Text("1 - Perspective Camera");
ImGui::Text("2 - Top Camera");
ImGui::Text("A - Move Perspective Camera LEFT");
ImGui::Text("D - Move Perspective Camera RIGHT");
ImGui::Text("");
ImGui::Text("Arrow LEFT - Paddle LEFT");
ImGui::Text("Arrow RIGHT - Paddle RIGHT");
ImGui::Text("SPACE - Launch Ball");
if (game_over && won) {
ImGui::Text("");
ImGui::Text("----------------");
ImGui::Text("| YOU WON! :) |");
ImGui::Text("----------------");
ImGui::Text("");
ImGui::Text("Press SPACE to start again...");
}
if (game_over && !won) {
ImGui::Text("");
ImGui::Text("-----------------");
ImGui::Text("| YOU LOST! :( |");
ImGui::Text("-----------------");
ImGui::Text("");
ImGui::Text("Press SPACE to start again...");
}
ImGui::End();
}
void BreakOut3D::ui_render() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void BreakOut3D::ui_cleanUp() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
bool BreakOut3D::check_victory(const std::vector<std::vector<Paddle>>& bricks) {
int count = 0;
for (auto& brick_col : bricks) {
count += brick_col.size();
}
return count == 0;
}
void BreakOut3D::generateBricks() {
bricks.clear();
float angle_step = 360.0f / brick_in_row_count;
float angle = 0.0f;
for (int i = 0; i < brick_in_row_count; i++) {
std::vector<Paddle> brick_col;
float brick_z = 0.0f;
for (int j = 0; j < brick_row_count; j++) {
if ((i + j) % 2 == 0)
{
brick_col.push_back(Paddle(angle, angle + angle_step, 6, brick_width, brick_height, brick_radius, Colors::orange, true, brick_z));
}
else
{
brick_col.push_back(Paddle(angle, angle + angle_step, 6, brick_width, brick_height, brick_radius, Colors::blue, true, brick_z));
}
brick_z += brick_height;
}
bricks.push_back(brick_col);
angle += angle_step;
}
for (auto& brick_cols : bricks) {
for (auto& brick : brick_cols) {
brick.sendLightingData(light_color, light_position, camera_position);
}
}
}
void BreakOut3D::run() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "BreakOut3D", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetKeyCallback(window, key_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return;
}
glEnable(GL_DEPTH_TEST);
Ground g = Ground(ground_radius, 36);
g.sendLightingData(light_color, light_position, camera_position);
const vec3 init_ball_position(6.5f, -1.0f, 0.5f);
const vec3 init_ball_direction(-1.0f, 0.0f, 0.0f);
Ball b = Ball(ball_r, 18, 36, init_ball_position);
b.sendLightingData(light_color, light_position, camera_position);
std::vector<Paddle> paddles{
Paddle(0.0f, 36.0f, 6, paddle_width, paddle_height, paddle_radius, Colors::gray),
Paddle(120.0f, 156.0f, 6, paddle_width, paddle_height, paddle_radius, Colors::gray),
Paddle(240.0f, 276.0f, 6, paddle_width, paddle_height, paddle_radius, Colors::gray)
};
for (Paddle& p : paddles) {
p.sendLightingData(light_color, light_position, camera_position);
}
generateBricks();
ui_init(window);
bool lost = false;
bool won = false;
while (!glfwWindowShouldClose(window))
{
if ((!game_over && won) || (game_over && lost)) {
generateBricks();
}
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// input
// -----
processInput(window, paddles);
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mat4 view;
if (top_camera) {
view = MatrixGenerator::lookAt(vec3(0.0f, 0.0f, 25.0f), vec3(0.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f));
}
else {
view = MatrixGenerator::lookAt(camera_position, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f));
}
g.render(view, 45.0f, SCR_WIDTH, SCR_HEIGHT);
b.render(view, 45.0f, SCR_WIDTH, SCR_HEIGHT);
for (Paddle& p : paddles) {
p.render(view, 45.0f, SCR_WIDTH, SCR_HEIGHT);
}
for (auto& brick_cols : bricks) {
for (auto& brick : brick_cols) {
brick.render(view, 45.0f, SCR_WIDTH, SCR_HEIGHT);
}
}
lost = b.update((float)glfwGetTime(), deltaTime, paddles, paddle_radius, paddle_width, bricks, brick_radius, brick_width, brick_in_row_count, ground_radius, ball_launched);
won = check_victory(bricks);
if (won || lost) {
game_over = true;
ball_launched = false;
b.setPosition(init_ball_position);
b.setDirection(init_ball_direction);
}
ui_frame_data(game_over, won);
ui_render();
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
g.cleanUp();
b.cleanUp();
for (Paddle& p : paddles) {
p.cleanUp();
}
for (auto& brick_cols : bricks) {
for (auto& brick : brick_cols) {
brick.cleanUp();
}
}
ui_cleanUp();
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
}
// --------------------------------------------------------------------------------------------------------
// MAIN
// --------------------------------------------------------------------------------------------------------
// Simple driver program
// 1st parameter ... number of rows
// 2nd parameter ... number of columns
int main() {
auto g = BreakOut3D(4, 12);
g.run();
return 0;
}
// --------------------------------------------------------------------------------------------------------
\ No newline at end of file
#pragma once
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "utils/Shader.h"
#include "utils/MatrixGenerator.h"
#include "objects/Ground.h"
#include "objects/Ball.h"
#include "objects/Paddle.h"
#define STB_IMAGE_IMPLEMENTATION
#include "utils/std_image.h"
#include "utils/imgui/imgui.h"
#include "utils/imgui/imgui_impl_glfw.h"
#include "utils/imgui/imgui_impl_opengl3.h"
#include <iostream>
#include <string>
namespace Colors {
const vec3 gray(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f);
const vec3 blue(17.0f / 255.0f, 103.0f / 255.0f, 177.0f / 255.0f);
const vec3 orange(255.0f / 255.0f, 173.0f / 255.0f, 0.0f / 255.0f);
}
class BreakOut3D
{
private:
static unsigned int SCR_WIDTH;
static unsigned int SCR_HEIGHT;
static float camera_radius;
static vec3 camera_position;
float camera_angle_speed = 40.0f;
float camera_speed = 5.0f;
vec3 light_color = vec3(1.0f, 1.0f, 1.0f);
vec3 light_position = vec3(5.0f, 0.0f, 6.0f);
// game config
float paddle_width = 0.5f;
float paddle_height = 1.0f;
float paddle_radius = 8.0f;
float ball_r = 0.5f;
float ground_radius = 10.0f;
float brick_width = 0.5f;
float brick_height = 1.0f;
float brick_radius = 2.5f;
int brick_in_row_count;
int brick_row_count;
// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f;
// game loop variables
static bool ball_launched;
static bool top_camera;
static bool game_over;
std::vector<std::vector<Paddle>> bricks;
// -----------------------------------------------------------------------------------------------
// METHODS
// -----------------------------------------------------------------------------------------------
// window
void static framebuffer_size_callback(GLFWwindow* window, int width, int height);
void static scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void static key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void processInput(GLFWwindow* window, std::vector<Paddle>& paddles);
// UI
void ui_init(GLFWwindow* window);
void ui_frame_data(bool game_over, bool won);
void ui_render();
void ui_cleanUp();
// game
bool check_victory(const std::vector<std::vector<Paddle>>& bricks);
void generateBricks();
public:
BreakOut3D(int brick_rows, int brick_cols);
void run();
};
\ No newline at end of file
# CMakeList.txt : CMake project for GameEngine, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
include_directories( ${OPENGL_INCLUDE_DIRS} )
# Add source to this project's executable.
add_executable (BreakOut3D "BreakOut3D.h" "math/vec3.h" "math/vec3.cpp" "math/vec4.h" "math/vec4.cpp" "math/mat3.h" "math/mat3.cpp" "math/mat4.h" "math/mat4.cpp" "math/ray.h" "math/ray.cpp" "objects/GameObject.h" "utils/CoordsConverter.h" "utils/odeSolver.h" "utils/Shader.h" "utils/MatrixGenerator.h" "utils/std_image.h" "objects/Ground.h" "objects/Ground.cpp" "objects/Ball.h" "objects/Ball.cpp" "objects/Paddle.h" "objects/Paddle.cpp"
"utils/imgui/imconfig.h" "utils/imgui/imgui.h" "utils/imgui/imgui.cpp" "utils/imgui/imgui_internal.h" "utils/imgui/imstb_rectpack.h" "utils/imgui/imstb_textedit.h" "utils/imgui/imstb_truetype.h"
"utils/imgui/imgui_demo.cpp" "utils/imgui/imgui_draw.cpp" "utils/imgui/imgui_tables.cpp" "utils/imgui/imgui_widgets.cpp"
"utils/imgui/imgui_impl_glfw.h" "utils/imgui/imgui_impl_glfw.cpp" "utils/imgui/imgui_impl_opengl3.h" "utils/imgui/imgui_impl_opengl3.cpp" "BreakOut3D.cpp" "collisions/CollisionDetector.h")
target_link_libraries( BreakOut3D ${OPENGL_LIBRARIES} glfw )
target_link_libraries( BreakOut3D glad )
# TODO: Add tests and install targets if needed.
#pragma once
#include "../math/vec3.h"
#include <algorithm>
using namespace MyMath;
class CollisionDetector
{
static bool sphere_sphere_collision(Sphere s1, Sphere s2) {
float distance = (s1.mid - s2.mid).magnitude();
return distance <= (s1.radius + s2.radius);
}
static bool sphere_aabb_collision(Sphere s, Aabb bb) {
//box closest point to sphere center
vec3 p = vec3(
std::max(bb.min.x, std::min(s.mid.x, bb.max.x)),
std::max(bb.min.y, std::min(s.mid.y, bb.max.y)),
std::max(bb.min.z, std::min(s.mid.z, bb.max.z))
);
float distance = (p - s.mid).magnitude();
return distance <= s.radius;
}
};
// Example classes since I did NOT use this in my Game
class Sphere
{
public:
vec3 mid;
float radius;
};
class Aabb
{
public:
vec3 min;
vec3 max;
};
\ No newline at end of file
#include "mat3.h"
using namespace MyMath;
mat3::mat3() {
mat = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
int idx = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rawData[idx] = mat[j][i];
idx++;
}
}
}
mat3::mat3(float m11, float m12, float m13,
float m21, float m22, float m23,
float m31, float m32, float m33) {
mat = {
{m11, m12, m13},
{m21, m22, m23},
{m31, m32, m33}
};
int idx = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rawData[idx] = mat[j][i];
idx++;
}
}
}
mat3::mat3(const std::vector<std::vector<float>>& mat) {
this->mat = mat;
int idx = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rawData[idx] = mat[j][i];
idx++;
}
}
}
std::vector<float>& mat3::operator[] (int index) {
return mat[index];
}
mat3 mat3::operator+ (const mat3& b) const {
return mat3(mat[0][0] + b.mat[0][0], mat[0][1] + b.mat[0][1], mat[0][2] + b.mat[0][2],
mat[1][0] + b.mat[1][0], mat[1][1] + b.mat[1][1], mat[1][2] + b.mat[1][2],
mat[2][0] + b.mat[2][0], mat[2][1] + b.mat[2][1], mat[2][2] + b.mat[2][2]);
}
mat3 mat3::operator- (const mat3& b) const {
return mat3(mat[0][0] - b.mat[0][0], mat[0][1] - b.mat[0][1], mat[0][2] - b.mat[0][2],
mat[1][0] - b.mat[1][0], mat[1][1] - b.mat[1][1], mat[1][2] - b.mat[1][2],
mat[2][0] - b.mat[2][0], mat[2][1] - b.mat[2][1], mat[2][2] - b.mat[2][2]);
}
vec3 mat3::operator* (const vec3& b) const {
return vec3(mat[0][0] * b.x + mat[0][1] * b.y + mat[0][2] * b.z,
mat[1][0] * b.x + mat[1][1] * b.y + mat[1][2] * b.z,
mat[2][0] * b.x + mat[2][1] * b.y + mat[2][2] * b.z);
}
mat3 mat3::operator* (const mat3& b) const {