Run ui as thread, add world simulator, currently has one trunk.
This commit is contained in:
parent
fc4e9fd723
commit
4d7dfc763d
|
@ -13,7 +13,7 @@ add_subdirectory(./deps/glm)
|
||||||
|
|
||||||
|
|
||||||
##test target##
|
##test target##
|
||||||
add_executable(jungle ./src/main.cpp ./deps/glad/src/glad.c)
|
add_executable(jungle ./src/main.cpp ./src/ui.cpp ./src/world.cpp ./deps/glad/src/glad.c)
|
||||||
target_include_directories(jungle PRIVATE ./inc/)
|
target_include_directories(jungle PRIVATE ./inc/)
|
||||||
#glfw dep
|
#glfw dep
|
||||||
add_dependencies(jungle glfw)
|
add_dependencies(jungle glfw)
|
||||||
|
@ -26,4 +26,4 @@ target_link_libraries(jungle Bullet3Common)
|
||||||
#glm dep
|
#glm dep
|
||||||
add_dependencies(jungle glm)
|
add_dependencies(jungle glm)
|
||||||
target_include_directories(jungle PRIVATE ./deps/glm/)
|
target_include_directories(jungle PRIVATE ./deps/glm/)
|
||||||
target_link_libraries(jungle glm)
|
target_link_libraries(jungle glm)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef UI_H
|
||||||
|
#define UI_H
|
||||||
|
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
|
int player_ui(
|
||||||
|
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
|
||||||
|
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock);
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,7 +21,7 @@ const float YAW = -90.0f;
|
||||||
const float PITCH = 0.0f;
|
const float PITCH = 0.0f;
|
||||||
const float SPEED = 4.5f;
|
const float SPEED = 4.5f;
|
||||||
const float SENSITIVITY = 0.1f;
|
const float SENSITIVITY = 0.1f;
|
||||||
const float ZOOM = 45.0f;
|
const float ZOOM = 95.0f;
|
||||||
|
|
||||||
// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
|
// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
|
||||||
class Camera
|
class Camera
|
||||||
|
@ -71,9 +71,15 @@ public:
|
||||||
{
|
{
|
||||||
float velocity = MovementSpeed * deltaTime;
|
float velocity = MovementSpeed * deltaTime;
|
||||||
if (direction == FORWARD)
|
if (direction == FORWARD)
|
||||||
Position += Front * velocity;
|
{
|
||||||
|
Position.x += Front.x * velocity;
|
||||||
|
Position.z += Front.z * velocity;
|
||||||
|
}
|
||||||
if (direction == BACKWARD)
|
if (direction == BACKWARD)
|
||||||
Position -= Front * velocity;
|
{
|
||||||
|
Position.x -= Front.x * velocity;
|
||||||
|
Position.z -= Front.z * velocity;
|
||||||
|
}
|
||||||
if (direction == LEFT)
|
if (direction == LEFT)
|
||||||
Position -= Right * velocity;
|
Position -= Right * velocity;
|
||||||
if (direction == RIGHT)
|
if (direction == RIGHT)
|
||||||
|
@ -111,10 +117,10 @@ public:
|
||||||
void ProcessMouseScroll(float yoffset)
|
void ProcessMouseScroll(float yoffset)
|
||||||
{
|
{
|
||||||
Zoom -= (float)yoffset;
|
Zoom -= (float)yoffset;
|
||||||
if (Zoom < 1.0f)
|
if (Zoom < 45.0f)
|
||||||
Zoom = 1.0f;
|
|
||||||
if (Zoom > 45.0f)
|
|
||||||
Zoom = 45.0f;
|
Zoom = 45.0f;
|
||||||
|
if (Zoom > ZOOM)
|
||||||
|
Zoom = ZOOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
|
@ -56,25 +56,26 @@ float vertices[] = {
|
||||||
// world space positions of our cubes
|
// world space positions of our cubes
|
||||||
glm::ivec3 cubePositions[] = {
|
glm::ivec3 cubePositions[] = {
|
||||||
glm::ivec3(0, 0, 0),
|
glm::ivec3(0, 0, 0),
|
||||||
glm::ivec3(2, 5, -15),
|
glm::ivec3(0, 0, 1),
|
||||||
glm::ivec3(-1, -2, -2),
|
glm::ivec3(0, 0, 2),
|
||||||
glm::ivec3(-3, -2, -12),
|
glm::ivec3(0, 0, 3),
|
||||||
glm::ivec3(2, -0, -3),
|
glm::ivec3(0, 0, 4),
|
||||||
glm::ivec3(-1, 3, -7),
|
|
||||||
glm::ivec3(1, -2, -2),
|
glm::ivec3(0, 0, 5),
|
||||||
glm::ivec3(1, 2, -2),
|
glm::ivec3(0, 0, 6),
|
||||||
glm::ivec3(1, 0, -1),
|
glm::ivec3(0, 0, 7),
|
||||||
glm::ivec3(-1, 1, -1)};
|
glm::ivec3(0, 0, 8),
|
||||||
|
glm::ivec3(0, 0, 9)};
|
||||||
|
|
||||||
glm::ivec2 cubeTextures[] = {
|
glm::ivec2 cubeTextures[] = {
|
||||||
glm::ivec2(1, 14),
|
|
||||||
glm::ivec2(8, 3),
|
|
||||||
glm::ivec2(0, 4),
|
|
||||||
glm::ivec2(1, 12),
|
glm::ivec2(1, 12),
|
||||||
glm::ivec2(1, 6),
|
glm::ivec2(1, 11),
|
||||||
|
glm::ivec2(1, 10),
|
||||||
|
glm::ivec2(1, 9),
|
||||||
|
glm::ivec2(1, 8),
|
||||||
|
|
||||||
glm::ivec2(0, 6),
|
glm::ivec2(1, 7),
|
||||||
glm::ivec2(1, 2),
|
glm::ivec2(1, 6),
|
||||||
glm::ivec2(0, 14),
|
glm::ivec2(1, 5),
|
||||||
glm::ivec2(3, 12),
|
glm::ivec2(1, 4),
|
||||||
glm::ivec2(1, 12)};
|
glm::ivec2(1, 0)};
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef WORLD_H
|
||||||
|
#define WORLD_H
|
||||||
|
|
||||||
|
#include "world/trunk.h"
|
||||||
|
#include "world/block.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
enum WorldRequire
|
||||||
|
{
|
||||||
|
NoneReq,
|
||||||
|
BlockReq,
|
||||||
|
ExitReq,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void world_simulator(std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
|
||||||
|
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef BLOCK_H
|
||||||
|
#define BLOCK_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
enum BlockType
|
||||||
|
{
|
||||||
|
Air,
|
||||||
|
Soil,
|
||||||
|
Grass,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BlockFacing
|
||||||
|
{
|
||||||
|
FacingNone,
|
||||||
|
Xpos,
|
||||||
|
Xneg,
|
||||||
|
Ypos,
|
||||||
|
Yneg,
|
||||||
|
Zpos,
|
||||||
|
Zneg,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Block(BlockType type = BlockType::Air, BlockFacing facing = BlockFacing::FacingNone) : type(type), facing(facing) {}
|
||||||
|
|
||||||
|
void set_type(BlockType type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockType get_type()
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BlockType type;
|
||||||
|
BlockFacing facing;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef WORLD
|
||||||
|
extern std::map<BlockType, glm::ivec2> block_type_texture_table;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef TRUNK_H
|
||||||
|
#define TRUNK_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "world/block.h"
|
||||||
|
|
||||||
|
const int TrunkSizeX = 32;
|
||||||
|
const int TrunkSizeY = 512;
|
||||||
|
const int TrunkSizeZ = 32;
|
||||||
|
|
||||||
|
class Trunk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Trunk()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < TrunkSizeX; i++)
|
||||||
|
for (int j = 0; j < 61; j++)
|
||||||
|
for (int k = 0; k < TrunkSizeZ; k++)
|
||||||
|
if (j < 60)
|
||||||
|
blocks[i][j][k].set_type(BlockType::Soil);
|
||||||
|
else
|
||||||
|
blocks[i][j][k].set_type(BlockType::Grass);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::tuple<glm::ivec3, Block &>> &getBlockList()
|
||||||
|
{
|
||||||
|
static std::vector<std::tuple<glm::ivec3, Block &>> res;
|
||||||
|
res.clear();
|
||||||
|
for (int i = 0; i < TrunkSizeX; i++)
|
||||||
|
for (int j = 0; j < TrunkSizeY; j++)
|
||||||
|
for (int k = 0; k < TrunkSizeZ; k++)
|
||||||
|
if (blocks[i][j][k].get_type() != BlockType::Air)
|
||||||
|
res.push_back(std::tuple<glm::ivec3, Block &>({i, j, k}, blocks[i][j][k]));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Block blocks[TrunkSizeX][TrunkSizeY][TrunkSizeZ];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
451
src/main.cpp
451
src/main.cpp
|
@ -1,437 +1,34 @@
|
||||||
#include <glad/glad.h>
|
#include <thread>
|
||||||
#include <GLFW/glfw3.h>
|
#include <future>
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
#include "stb_image.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
|
||||||
|
|
||||||
#include "shader_m.h"
|
|
||||||
#include "camera.h"
|
|
||||||
#include "cube_model.h"
|
|
||||||
#include "native.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <vector>
|
||||||
|
#include "ui.h"
|
||||||
#ifdef __GNUC__
|
#include "world.h"
|
||||||
// #include <pthread.h>
|
|
||||||
// #include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
|
|
||||||
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
|
|
||||||
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
|
|
||||||
void focus_callback(GLFWwindow *window, int focused);
|
|
||||||
void processInput(GLFWwindow *window);
|
|
||||||
|
|
||||||
void glfwDump(GLFWwindow *window);
|
|
||||||
|
|
||||||
bool running = true;
|
|
||||||
bool pausing = false;
|
|
||||||
bool just_dispaused = false;
|
|
||||||
|
|
||||||
// settings
|
|
||||||
const unsigned int SCR_WIDTH = 854;
|
|
||||||
const unsigned int SCR_HEIGHT = 480;
|
|
||||||
|
|
||||||
// camera
|
|
||||||
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
|
|
||||||
float lastX = SCR_WIDTH / 2.0f;
|
|
||||||
float lastY = SCR_HEIGHT / 2.0f;
|
|
||||||
bool firstMouse = true;
|
|
||||||
|
|
||||||
// timing
|
|
||||||
volatile double deltaTime = 0; // time between current frame and last frame
|
|
||||||
volatile double lastFrame = 0;
|
|
||||||
volatile double timer = 0;
|
|
||||||
volatile double currentFrame = 0;
|
|
||||||
|
|
||||||
// focuse controlling
|
|
||||||
bool window_focused = false;
|
|
||||||
|
|
||||||
// window managing
|
|
||||||
int curr_width;
|
|
||||||
int curr_height;
|
|
||||||
int curr_x;
|
|
||||||
int curr_y;
|
|
||||||
|
|
||||||
// monitors controlling
|
|
||||||
// int monitor_count;
|
|
||||||
// GLFWmonitor **monitors;
|
|
||||||
|
|
||||||
GLFWimage icon;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
std::vector<WorldRequire> require_pipe;
|
||||||
nativeSetIcon();
|
std::mutex require_pipe_lock;
|
||||||
#endif
|
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> blocks_pipe;
|
||||||
|
std::mutex blocks_pipe_lock;
|
||||||
|
|
||||||
// std::cout << "debug";
|
// 启动ui渲染线程
|
||||||
// glfw: initialize and configure
|
std::promise<int> ui_prom;
|
||||||
// ------------------------------
|
std::future<int> ui_future = ui_prom.get_future();
|
||||||
glfwInit();
|
std::thread ui(
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
[&ui_prom, &require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock]()
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
|
|
||||||
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// glfw window creation
|
|
||||||
// --------------------
|
|
||||||
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Jungle", NULL, NULL);
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
std::cout << "Failed to create GLFW window" << std::endl;
|
|
||||||
glfwTerminate();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// monitors = glfwGetMonitors(&monitor_count);
|
|
||||||
|
|
||||||
// pthread_t thr_getting_fps;
|
|
||||||
// pthread_create(&thr_getting_fps, nullptr, getting_fps, window);
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
|
||||||
glfwSetCursorPosCallback(window, mouse_callback);
|
|
||||||
glfwSetScrollCallback(window, scroll_callback);
|
|
||||||
glfwSetWindowFocusCallback(window, focus_callback);
|
|
||||||
|
|
||||||
// tell GLFW to capture our mouse
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
||||||
|
|
||||||
// glad: load all OpenGL function pointers
|
|
||||||
// ---------------------------------------
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
|
||||||
{
|
|
||||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
icon.pixels = stbi_load("./icon.png", &icon.width, &icon.height, 0, STBI_rgb_alpha);
|
|
||||||
glfwSetWindowIcon(window, 1, &icon);
|
|
||||||
|
|
||||||
// configure global opengl state
|
|
||||||
// -----------------------------
|
|
||||||
// glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// build and compile our shader zprogram
|
|
||||||
// ------------------------------------
|
|
||||||
Shader ourShader("demo.vs", "demo.fs");
|
|
||||||
|
|
||||||
unsigned int VBO, VAO;
|
|
||||||
glGenVertexArrays(1, &VAO);
|
|
||||||
glGenBuffers(1, &VBO);
|
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// position attribute
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
// texture coord attribute
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// load and create a texture
|
|
||||||
// -------------------------
|
|
||||||
unsigned int texture1; //, texture2;
|
|
||||||
// texture 1
|
|
||||||
// ---------
|
|
||||||
glGenTextures(1, &texture1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture1);
|
|
||||||
// set the texture wrapping parameters
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
// set texture filtering parameters
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
// load image, create texture and generate mipmaps
|
|
||||||
int width, height, nrChannels;
|
|
||||||
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
|
|
||||||
unsigned char *data = stbi_load("./terrain.png", &width, &height, &nrChannels, STBI_rgb_alpha);
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
// glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Failed to load texture" << std::endl;
|
|
||||||
}
|
|
||||||
stbi_image_free(data);
|
|
||||||
|
|
||||||
// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
|
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
ourShader.use();
|
|
||||||
ourShader.setInt("texture1", 0);
|
|
||||||
// ourShader.setInt("texture2", 1);
|
|
||||||
|
|
||||||
// bind textures on corresponding texture units
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture1);
|
|
||||||
// glActiveTexture(GL_TEXTURE1);
|
|
||||||
// glBindTexture(GL_TEXTURE_2D, texture2);
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
|
|
||||||
glfwDump(window);
|
|
||||||
|
|
||||||
// glfwSetCursorPos(window, curr_x + curr_width / 2, curr_y + curr_height / 2);
|
|
||||||
// render loop
|
|
||||||
// -----------
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
// per-frame time logic
|
|
||||||
// --------------------
|
|
||||||
currentFrame = glfwGetTime();
|
|
||||||
deltaTime = currentFrame - lastFrame;
|
|
||||||
lastFrame = currentFrame;
|
|
||||||
|
|
||||||
// input
|
|
||||||
// -----
|
|
||||||
processInput(window);
|
|
||||||
|
|
||||||
// render
|
|
||||||
// ------
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// activate shader
|
|
||||||
ourShader.use();
|
|
||||||
|
|
||||||
// pass projection matrix to shader (note that in this case it could change every frame)
|
|
||||||
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
|
||||||
ourShader.setMat4("projection", projection);
|
|
||||||
|
|
||||||
// camera/view transformation
|
|
||||||
glm::mat4 view = camera.GetViewMatrix();
|
|
||||||
ourShader.setMat4("view", view);
|
|
||||||
|
|
||||||
// glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// glDepthMask(GL_TRUE);
|
|
||||||
// render opaque objects first
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 10; i++)
|
|
||||||
{
|
{
|
||||||
ourShader.setIVec2("index", cubeTextures[i]);
|
int res = player_ui(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock);
|
||||||
|
ui_prom.set_value(res); });
|
||||||
|
|
||||||
// calculate the model matrix for each object and pass it to shader before drawing
|
// 启动世界模拟器线程
|
||||||
glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
|
std::thread world_sim(
|
||||||
model = glm::translate(model, glm::vec3(cubePositions[i]));
|
[&require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock]()
|
||||||
ourShader.setMat4("model", model);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
|
||||||
}
|
|
||||||
// glDepthMask(GL_FALSE);
|
|
||||||
|
|
||||||
// render transparent objects with blending enabled
|
|
||||||
|
|
||||||
// glDisable(GL_DEPTH_TEST);
|
|
||||||
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
|
||||||
// -------------------------------------------------------------------------------
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
timer += deltaTime;
|
|
||||||
if (timer > 0.3f)
|
|
||||||
{
|
{
|
||||||
glfwSetWindowTitle(window, ("fps:" + std::to_string(int(1.0f / deltaTime)) + " X:" + std::to_string(camera.Position.x) + " Y:" + std::to_string(camera.Position.y) + " Z:" + std::to_string(camera.Position.z)).c_str());
|
world_simulator(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock);
|
||||||
timer -= 0.3f;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// double renderTime = glfwGetTime() - lastFrame;
|
ui.join();
|
||||||
// delay_fps(fps, (int)(renderTime * 1000 * 1000));
|
world_sim.join();
|
||||||
}
|
return ui_future.get();
|
||||||
|
|
||||||
running = false;
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// optional: de-allocate all resources once they've outlived their purpose:
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
glDeleteVertexArrays(1, &VAO);
|
|
||||||
glDeleteBuffers(1, &VBO);
|
|
||||||
|
|
||||||
// glfw: terminate, clearing all previously allocated GLFW resources.
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
glfwTerminate();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
|
|
||||||
// ---------------------------------------------------------------------------------------------------------
|
|
||||||
bool ESC_KEY_PRESSED = false;
|
|
||||||
void processInput(GLFWwindow *window)
|
|
||||||
{
|
|
||||||
int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE);
|
|
||||||
if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS)
|
|
||||||
{
|
|
||||||
ESC_KEY_PRESSED = true;
|
|
||||||
pausing = !pausing;
|
|
||||||
if (!pausing)
|
|
||||||
just_dispaused = true;
|
|
||||||
if (!pausing)
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
||||||
else
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
}
|
|
||||||
else if (esc_key_evetype == GLFW_RELEASE)
|
|
||||||
{
|
|
||||||
ESC_KEY_PRESSED = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pausing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(FORWARD, deltaTime);
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(LEFT, deltaTime);
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(RIGHT, deltaTime);
|
|
||||||
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(UP, deltaTime);
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
|
||||||
camera.ProcessKeyboard(DOWN, deltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
|
||||||
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
|
|
||||||
{
|
|
||||||
// make sure the viewport matches the new window dimensions; note that width and
|
|
||||||
// height will be significantly larger than specified on retina displays.
|
|
||||||
curr_width = width;
|
|
||||||
curr_height = height;
|
|
||||||
if ((double)width / height > (double)SCR_WIDTH / SCR_HEIGHT)
|
|
||||||
{ // When profiled screen size rate less than new size
|
|
||||||
int vpwidth = width;
|
|
||||||
int vpheight = width * SCR_HEIGHT / SCR_WIDTH;
|
|
||||||
glViewport(0, -(vpheight - height) / 2, vpwidth, vpheight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // or more than
|
|
||||||
int vpheight = height;
|
|
||||||
int vpwidth = height * SCR_WIDTH / SCR_HEIGHT;
|
|
||||||
glViewport(-(vpwidth - width) / 2, 0, vpwidth, vpheight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// glfw: whenever the mouse moves, this callback is called
|
|
||||||
// -------------------------------------------------------
|
|
||||||
void mouse_callback(GLFWwindow *window, double xposIn, double yposIn)
|
|
||||||
{
|
|
||||||
if (pausing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float xpos = static_cast<float>(xposIn);
|
|
||||||
float ypos = static_cast<float>(yposIn);
|
|
||||||
|
|
||||||
if (just_dispaused)
|
|
||||||
{
|
|
||||||
lastX = xpos;
|
|
||||||
lastY = ypos;
|
|
||||||
just_dispaused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstMouse)
|
|
||||||
{
|
|
||||||
lastX = xpos;
|
|
||||||
lastY = ypos;
|
|
||||||
firstMouse = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float xoffset = xpos - lastX;
|
|
||||||
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
|
||||||
|
|
||||||
lastX = xpos;
|
|
||||||
lastY = ypos;
|
|
||||||
|
|
||||||
camera.ProcessMouseMovement(xoffset, yoffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
|
|
||||||
{
|
|
||||||
camera.ProcessMouseScroll(static_cast<float>(yoffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void focus_callback(GLFWwindow *window, int focused)
|
|
||||||
{
|
|
||||||
if (focused)
|
|
||||||
{
|
|
||||||
window_focused = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window_focused = false;
|
|
||||||
pausing = true;
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void glfwDump(GLFWwindow *window)
|
|
||||||
{
|
|
||||||
int clientAPI = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
|
||||||
int contextAPI = glfwGetWindowAttrib(window, GLFW_CONTEXT_CREATION_API);
|
|
||||||
int contextVersionMajor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
|
||||||
int contextVersionMinor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
|
||||||
int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
|
||||||
int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS);
|
|
||||||
int releaseBehavior = glfwGetWindowAttrib(window, GLFW_CONTEXT_RELEASE_BEHAVIOR);
|
|
||||||
int forwardCompat = glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT);
|
|
||||||
int debugContext = glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT);
|
|
||||||
|
|
||||||
int windowSizeWidth, windowSizeHeight;
|
|
||||||
glfwGetWindowSize(window, &windowSizeWidth, &windowSizeHeight);
|
|
||||||
int bufferSizeWidth, bufferSizeHeight;
|
|
||||||
glfwGetFramebufferSize(window, &bufferSizeWidth, &bufferSizeHeight);
|
|
||||||
float windowScaleX, windowScaleY;
|
|
||||||
glfwGetWindowContentScale(window, &windowScaleX, &windowScaleY);
|
|
||||||
|
|
||||||
std::cout << "Client API: " << clientAPI << std::endl;
|
|
||||||
std::cout << "Context API: " << contextAPI << std::endl;
|
|
||||||
std::cout << "OpenGL version: " << contextVersionMajor << "." << contextVersionMinor << std::endl;
|
|
||||||
std::cout << "OpenGL profile: " << profile << std::endl;
|
|
||||||
std::cout << "Robustness: " << robustness << std::endl;
|
|
||||||
std::cout << "Release behavior: " << releaseBehavior << std::endl;
|
|
||||||
std::cout << "Forward compatibility: " << forwardCompat << std::endl;
|
|
||||||
std::cout << "Debug context: " << debugContext << std::endl;
|
|
||||||
|
|
||||||
std::cout << "Window size: "
|
|
||||||
<< " width-" << windowSizeWidth << " height-" << windowSizeHeight << std::endl;
|
|
||||||
std::cout << "FrameBuffer size: "
|
|
||||||
<< " width-" << bufferSizeWidth << " height-" << bufferSizeHeight << std::endl;
|
|
||||||
std::cout << "Window Scale: "
|
|
||||||
<< " X-" << bufferSizeWidth << " Y-" << bufferSizeHeight << std::endl;
|
|
||||||
}
|
|
|
@ -0,0 +1,422 @@
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "ui/stb_image.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "ui/shader_m.h"
|
||||||
|
#include "ui/camera.h"
|
||||||
|
#include "ui/cube_model.h"
|
||||||
|
#include "ui/native.h"
|
||||||
|
|
||||||
|
#define UI
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
|
||||||
|
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
|
||||||
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
|
||||||
|
void focus_callback(GLFWwindow *window, int focused);
|
||||||
|
void processInput(GLFWwindow *window);
|
||||||
|
|
||||||
|
void glfwDump(GLFWwindow *window);
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
bool pausing = true;
|
||||||
|
bool just_dispaused = false;
|
||||||
|
|
||||||
|
// settings
|
||||||
|
const unsigned int SCR_WIDTH = 1920;
|
||||||
|
const unsigned int SCR_HEIGHT = 1080;
|
||||||
|
|
||||||
|
// camera
|
||||||
|
Camera camera(glm::vec3(0.0f, 63.0f, 0.0f));
|
||||||
|
float lastX = SCR_WIDTH / 2.0f;
|
||||||
|
float lastY = SCR_HEIGHT / 2.0f;
|
||||||
|
bool firstMouse = true;
|
||||||
|
|
||||||
|
// timing
|
||||||
|
volatile double deltaTime = 0; // time between current frame and last frame
|
||||||
|
volatile double lastFrame = 0;
|
||||||
|
volatile double timer = 0;
|
||||||
|
volatile double currentFrame = 0;
|
||||||
|
|
||||||
|
// focuse controlling
|
||||||
|
bool window_focused = false;
|
||||||
|
|
||||||
|
// window managing
|
||||||
|
int curr_width;
|
||||||
|
int curr_height;
|
||||||
|
int curr_x;
|
||||||
|
int curr_y;
|
||||||
|
|
||||||
|
GLFWimage icon;
|
||||||
|
|
||||||
|
int player_ui(
|
||||||
|
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
|
||||||
|
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
nativeSetIcon();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// std::cout << "debug";
|
||||||
|
// glfw: initialize and configure
|
||||||
|
// ------------------------------
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// glfw window creation
|
||||||
|
// --------------------
|
||||||
|
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Jungle", NULL, NULL);
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to create GLFW window" << std::endl;
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
glfwSetWindowFocusCallback(window, focus_callback);
|
||||||
|
|
||||||
|
// glad: load all OpenGL function pointers
|
||||||
|
// ---------------------------------------
|
||||||
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon.pixels = stbi_load("./icon.png", &icon.width, &icon.height, 0, STBI_rgb_alpha);
|
||||||
|
glfwSetWindowIcon(window, 1, &icon);
|
||||||
|
|
||||||
|
// configure global opengl state
|
||||||
|
// -----------------------------
|
||||||
|
// glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// build and compile our shader zprogram
|
||||||
|
// ------------------------------------
|
||||||
|
Shader ourShader("demo.vs", "demo.fs");
|
||||||
|
|
||||||
|
unsigned int VBO, VAO;
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// position attribute
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
// texture coord attribute
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// load and create a texture
|
||||||
|
// -------------------------
|
||||||
|
unsigned int texture1; //, texture2;
|
||||||
|
// texture 1
|
||||||
|
// ---------
|
||||||
|
glGenTextures(1, &texture1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
// set the texture wrapping parameters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
// set texture filtering parameters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// load image, create texture and generate mipmaps
|
||||||
|
int width, height, nrChannels;
|
||||||
|
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
|
||||||
|
unsigned char *data = stbi_load("./terrain.png", &width, &height, &nrChannels, STBI_rgb_alpha);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
// glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Failed to load texture" << std::endl;
|
||||||
|
}
|
||||||
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
ourShader.use();
|
||||||
|
ourShader.setInt("texture1", 0);
|
||||||
|
|
||||||
|
// bind textures on corresponding texture units
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
|
glfwDump(window);
|
||||||
|
|
||||||
|
framebuffer_size_callback(window, SCR_WIDTH, SCR_HEIGHT);
|
||||||
|
|
||||||
|
// glfwSetCursorPos(window, curr_x + curr_width / 2, curr_y + curr_height / 2);
|
||||||
|
// render loop
|
||||||
|
// -----------
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
// per-frame time logic
|
||||||
|
// --------------------
|
||||||
|
currentFrame = glfwGetTime();
|
||||||
|
deltaTime = currentFrame - lastFrame;
|
||||||
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
|
// input
|
||||||
|
// -----
|
||||||
|
processInput(window);
|
||||||
|
|
||||||
|
// render
|
||||||
|
// ------
|
||||||
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// activate shader
|
||||||
|
ourShader.use();
|
||||||
|
|
||||||
|
// pass projection matrix to shader (note that in this case it could change every frame)
|
||||||
|
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), 1.0f, 0.1f, 100.0f);
|
||||||
|
ourShader.setMat4("projection", projection);
|
||||||
|
|
||||||
|
// camera/view transformation
|
||||||
|
glm::mat4 view = camera.GetViewMatrix();
|
||||||
|
ourShader.setMat4("view", view);
|
||||||
|
|
||||||
|
// render opaque objects first
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
/*for (unsigned int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
ourShader.setIVec2("index", cubeTextures[i]);
|
||||||
|
|
||||||
|
// calculate the model matrix for each object and pass it to shader before drawing
|
||||||
|
glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
|
||||||
|
model = glm::translate(model, glm::vec3(cubePositions[i]));
|
||||||
|
ourShader.setMat4("model", model);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
require_pipe_lock.lock();
|
||||||
|
require_pipe.push_back(WorldRequire::BlockReq);
|
||||||
|
require_pipe_lock.unlock();
|
||||||
|
std::vector<std::tuple<glm::ivec3, Block &>> blks;
|
||||||
|
blocks_pipe_lock.lock();
|
||||||
|
if (!blocks_pipe.empty())
|
||||||
|
{
|
||||||
|
blks = blocks_pipe.back();
|
||||||
|
blocks_pipe.pop_back();
|
||||||
|
}
|
||||||
|
blocks_pipe_lock.unlock();
|
||||||
|
for (auto block : blks)
|
||||||
|
{
|
||||||
|
auto loc = std::get<0>(block);
|
||||||
|
ourShader.setIVec2("index", block_type_texture_table[std::get<1>(block).get_type()]);
|
||||||
|
glm::mat4 model(1.0f);
|
||||||
|
model = glm::translate(model, glm::vec3(loc));
|
||||||
|
ourShader.setMat4("model", model);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
timer += deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
require_pipe_lock.lock();
|
||||||
|
require_pipe.push_back(WorldRequire::ExitReq);
|
||||||
|
require_pipe_lock.unlock();
|
||||||
|
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
// optional: de-allocate all resources once they've outlived their purpose:
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
glDeleteBuffers(1, &VBO);
|
||||||
|
|
||||||
|
// glfw: terminate, clearing all previously allocated GLFW resources.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
|
||||||
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
|
bool ESC_KEY_PRESSED = false;
|
||||||
|
void processInput(GLFWwindow *window)
|
||||||
|
{
|
||||||
|
int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE);
|
||||||
|
if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS)
|
||||||
|
{
|
||||||
|
ESC_KEY_PRESSED = true;
|
||||||
|
pausing = !pausing;
|
||||||
|
if (!pausing)
|
||||||
|
just_dispaused = true;
|
||||||
|
if (!pausing)
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
else
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
}
|
||||||
|
else if (esc_key_evetype == GLFW_RELEASE)
|
||||||
|
{
|
||||||
|
ESC_KEY_PRESSED = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pausing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(LEFT, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(RIGHT, deltaTime);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(UP, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||||
|
camera.ProcessKeyboard(DOWN, deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
||||||
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
|
||||||
|
{
|
||||||
|
// make sure the viewport matches the new window dimensions; note that width and
|
||||||
|
// height will be significantly larger than specified on retina displays.
|
||||||
|
curr_width = width;
|
||||||
|
curr_height = height;
|
||||||
|
if (width > height)
|
||||||
|
{ // When profiled screen size rate less than new size
|
||||||
|
int vpwidth = width;
|
||||||
|
int vpheight = width;
|
||||||
|
glViewport(0, -(vpheight - height) / 2, vpwidth, vpheight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // or more than
|
||||||
|
int vpheight = height;
|
||||||
|
int vpwidth = height;
|
||||||
|
glViewport(-(vpwidth - width) / 2, 0, vpwidth, vpheight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the mouse moves, this callback is called
|
||||||
|
// -------------------------------------------------------
|
||||||
|
void mouse_callback(GLFWwindow *window, double xposIn, double yposIn)
|
||||||
|
{
|
||||||
|
if (pausing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float xpos = static_cast<float>(xposIn);
|
||||||
|
float ypos = static_cast<float>(yposIn);
|
||||||
|
|
||||||
|
if (just_dispaused)
|
||||||
|
{
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
just_dispaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstMouse)
|
||||||
|
{
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
firstMouse = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float xoffset = xpos - lastX;
|
||||||
|
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
||||||
|
|
||||||
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
|
|
||||||
|
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
|
||||||
|
{
|
||||||
|
camera.ProcessMouseScroll(static_cast<float>(yoffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
void focus_callback(GLFWwindow *window, int focused)
|
||||||
|
{
|
||||||
|
if (focused)
|
||||||
|
{
|
||||||
|
window_focused = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window_focused = false;
|
||||||
|
pausing = true;
|
||||||
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glfwDump(GLFWwindow *window)
|
||||||
|
{
|
||||||
|
int clientAPI = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
||||||
|
int contextAPI = glfwGetWindowAttrib(window, GLFW_CONTEXT_CREATION_API);
|
||||||
|
int contextVersionMajor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||||
|
int contextVersionMinor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
||||||
|
int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
||||||
|
int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS);
|
||||||
|
int releaseBehavior = glfwGetWindowAttrib(window, GLFW_CONTEXT_RELEASE_BEHAVIOR);
|
||||||
|
int forwardCompat = glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT);
|
||||||
|
int debugContext = glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT);
|
||||||
|
|
||||||
|
int windowSizeWidth, windowSizeHeight;
|
||||||
|
glfwGetWindowSize(window, &windowSizeWidth, &windowSizeHeight);
|
||||||
|
int bufferSizeWidth, bufferSizeHeight;
|
||||||
|
glfwGetFramebufferSize(window, &bufferSizeWidth, &bufferSizeHeight);
|
||||||
|
float windowScaleX, windowScaleY;
|
||||||
|
glfwGetWindowContentScale(window, &windowScaleX, &windowScaleY);
|
||||||
|
|
||||||
|
std::cout << "Client API: " << clientAPI << std::endl;
|
||||||
|
std::cout << "Context API: " << contextAPI << std::endl;
|
||||||
|
std::cout << "OpenGL version: " << contextVersionMajor << "." << contextVersionMinor << std::endl;
|
||||||
|
std::cout << "OpenGL profile: " << profile << std::endl;
|
||||||
|
std::cout << "Robustness: " << robustness << std::endl;
|
||||||
|
std::cout << "Release behavior: " << releaseBehavior << std::endl;
|
||||||
|
std::cout << "Forward compatibility: " << forwardCompat << std::endl;
|
||||||
|
std::cout << "Debug context: " << debugContext << std::endl;
|
||||||
|
|
||||||
|
std::cout << "Window size: "
|
||||||
|
<< " width-" << windowSizeWidth << " height-" << windowSizeHeight << std::endl;
|
||||||
|
std::cout << "FrameBuffer size: "
|
||||||
|
<< " width-" << bufferSizeWidth << " height-" << bufferSizeHeight << std::endl;
|
||||||
|
std::cout << "Window Scale: "
|
||||||
|
<< " X-" << bufferSizeWidth << " Y-" << bufferSizeHeight << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#define WORLD
|
||||||
|
#include "world.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
std::map<BlockType, glm::ivec2> block_type_texture_table{
|
||||||
|
std::make_pair(BlockType::Soil, glm::ivec2(2, 15)),
|
||||||
|
std::make_pair(BlockType::Grass, glm::ivec2(3, 15)),
|
||||||
|
};
|
||||||
|
|
||||||
|
void world_simulator(
|
||||||
|
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
|
||||||
|
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock)
|
||||||
|
{
|
||||||
|
Trunk trunk000;
|
||||||
|
bool ends = false;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
WorldRequire wreq = WorldRequire::NoneReq;
|
||||||
|
require_pipe_lock.lock();
|
||||||
|
if (!require_pipe.empty())
|
||||||
|
{
|
||||||
|
wreq = require_pipe.back();
|
||||||
|
require_pipe.pop_back();
|
||||||
|
}
|
||||||
|
require_pipe_lock.unlock();
|
||||||
|
if (wreq == WorldRequire::NoneReq)
|
||||||
|
continue;
|
||||||
|
std::vector<std::tuple<glm::ivec3, Block &>> *list;
|
||||||
|
switch (wreq)
|
||||||
|
{
|
||||||
|
case BlockReq:
|
||||||
|
list = &trunk000.getBlockList();
|
||||||
|
blocks_pipe_lock.lock();
|
||||||
|
blocks_pipe.push_back(*list);
|
||||||
|
blocks_pipe_lock.unlock();
|
||||||
|
break;
|
||||||
|
case ExitReq:
|
||||||
|
ends = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ends)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue