Compare commits

...

3 Commits

6 changed files with 451 additions and 130 deletions

29
src/game/engine/chunk.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "chunk.hpp"
namespace polygun::engine {
Chunk::Chunk() {
for (int x = 0; x < CHUNK_SIZE; x++) {
for (int y = 0; y < CHUNK_SIZE; y++) {
for (int z = 0; z < CHUNK_SIZE; z++) {
chunk_data[x][y][z] = 0;
}
}
}
}
Chunk::~Chunk() {
delete chunk_data;
}
void Chunk::add_node(int node_to_add, glm::vec3 pos) {
chunk_data[(int)pos.x][(int)pos.y][(int)pos.z] = node_to_add;
}
bool Chunk::is_air(glm::vec3 pos) {
return chunk_data[(int)pos.x][(int)pos.y][(int)pos.z] == 0;
}
int Chunk::get_node(glm::vec3 pos) {
return chunk_data[(int)pos.x][(int)pos.y][(int)pos.z];
}
}

25
src/game/engine/chunk.hpp Normal file
View File

@ -0,0 +1,25 @@
#ifndef POLYGUN_ENGINE_CHUNK_HPP
#define POLYGUN_ENGINE_CHUNK_HPP
#include "nodes.hpp"
namespace polygun::engine {
class Chunk {
public:
Chunk();
~Chunk();
void add_node(int node_to_add, glm::vec3 pos);
bool is_air(glm::vec3 pos);
int get_node(glm::vec3 pos);
static const int CHUNK_SIZE = 32;
glm::vec3 chunk_pos;
private:
int chunk_data[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
};
}
#endif // POLYGUN_ENGINE_CHUNK_HPP

View File

@ -0,0 +1,354 @@
#include "chunk_renderer.hpp"
namespace polygun::engine {
ChunkRenderer::ChunkRenderer(Chunk *chunk_to_render) {
m_chunk = chunk_to_render;
m_chunk_shader = renderer::Shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl");
generate_mesh();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, GL_DYNAMIC_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_textures();
}
ChunkRenderer::~ChunkRenderer() {
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
}
void ChunkRenderer::load_textures() {/*
for (int i = 0; i < sizeof(nodes); i++) {
glGenTextures(1, &m_textures[i]);
glBindTexture(GL_TEXTURE_2D, m_textures[i]);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load(nodes[i++].texture.c_str(), &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
}
m_chunk_shader.bind();
m_chunk_shader.set_uniform("texture1", 0);*/
glGenTextures(1, &m_texture1);
glBindTexture(GL_TEXTURE_2D, m_texture1);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load(nodes[2].texture.c_str(), &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
m_chunk_shader.bind();
m_chunk_shader.set_uniform("texture1", 0);
}
void ChunkRenderer::generate_mesh() {
int index = 0;
for (int x = 0; x < Chunk::CHUNK_SIZE; x++) {
for (int y = 0; y < Chunk::CHUNK_SIZE; y++) {
for (int z = 0; z < Chunk::CHUNK_SIZE; z++) {
if (!m_chunk->is_air(glm::vec3(x, y, z))) {
// check if the neighbour is air and if so add the face vertices to the array
if (m_chunk->is_air(glm::vec3(x + 1, y, z))) {
// right face
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
}
if (m_chunk->is_air(glm::vec3(x - 1, y, z))) {
// left face
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
}
if (m_chunk->is_air(glm::vec3(x, y + 1, z))) {
// top face
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
}
if (m_chunk->is_air(glm::vec3(x, y - 1, z))) {
// bottom face
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
}
if (m_chunk->is_air(glm::vec3(x, y, z + 1))) {
// front face
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z + 1;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
}
if (m_chunk->is_air(glm::vec3(x, y, z - 1))) {
// back face
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 0.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x + 1;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 1.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y + 1;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 1.0f;
m_vertices[index++] = x;
m_vertices[index++] = y;
m_vertices[index++] = z;
m_vertices[index++] = 0.0f;
m_vertices[index++] = 0.0f;
}
}
}
}
}
}
void ChunkRenderer::render(Camera camera) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture1);
// activate shader
m_chunk_shader.bind();
glm::mat4 projection = glm::perspective(glm::radians(camera.m_zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
m_chunk_shader.set_uniform("projection", projection);
glm::mat4 view = camera.get_view_matrix();
m_chunk_shader.set_uniform("view", view);
glBindVertexArray(m_vao);
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
m_chunk_shader.set_uniform("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
}

View File

@ -0,0 +1,28 @@
#ifndef POLYGUN_ENGINE_CHUNK_RENDERER_HPP
#define POLYGUN_ENGINE_CHUNK_RENDERER_HPP
#include "chunk.hpp"
#include "engine.hpp"
namespace polygun::engine {
class ChunkRenderer {
public:
ChunkRenderer(Chunk *chunk_to_render);
~ChunkRenderer();
void update_chunk(Chunk *chunk_to_render);
void render(Camera camera);
private:
void load_textures();
void generate_mesh();
renderer::Shader m_chunk_shader;
unsigned int m_vbo, m_vao;
unsigned int m_textures[sizeof(nodes)];
unsigned int m_texture1;
float m_vertices[32768];
Chunk *m_chunk;
};
}
#endif //POLYGUN_ENGINE_CHUNK_RENDERER_HPP

View File

@ -1,6 +1,9 @@
#include "engine.hpp"
#include "../audio/audio.hpp"
#include "chunk_renderer.hpp"
#include <GLFW/glfw3.h>
using namespace polygun::renderer;
@ -17,7 +20,7 @@ namespace polygun::engine {
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Blocking3D", NULL, NULL);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Polygun", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
@ -34,101 +37,9 @@ namespace polygun::engine {
}
glEnable(GL_DEPTH_TEST);
Shader chunk_shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl");
float vertices[] = {
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
0.1f, -0.1f, -0.1f, 1.0f, 0.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
-0.1f, 0.1f, 0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, -0.1f, 1.0f, 1.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, 0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f
};
//32x32x32 chunk | ONLY FOR TEST THIS IS'NT EVEN A CHUNK
glm::vec3 cube_positions[1024];
for(int i = 0; i < 1024; i++){
cube_positions[i] = glm::vec3(0.2f * (i % 32), 0.2f * (i / 32), 0.2f * (i / 32));
}
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);
unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load("res/textures/grass.png", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
chunk_shader.bind();
chunk_shader.set_uniform("texture1", 0);
Chunk m_chunk;
m_chunk.add_node(1, glm::vec3(0, 0, 0));
ChunkRenderer m_chunk_renderer(&m_chunk);
m_delta_time = 0;
m_last_frame = 0;
@ -161,39 +72,13 @@ namespace polygun::engine {
m_camera.update();
// render
// ------
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
// activate shader
chunk_shader.bind();
glm::mat4 projection = glm::perspective(glm::radians(m_camera.m_zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
chunk_shader.set_uniform("projection", projection);
glm::mat4 view = m_camera.get_view_matrix();
chunk_shader.set_uniform("view", view);
glBindVertexArray(VAO);
for (unsigned int i = 0; i < (sizeof(cube_positions)/sizeof(*cube_positions)) ; i++)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cube_positions[i]);
float angle = 20.0f * i;
chunk_shader.set_uniform("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
m_chunk_renderer.render(m_camera);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
}

View File

@ -4,18 +4,18 @@
#include "../core.hpp"
namespace polygun::engine {
/*
struct Node {
struct NodeType {
std::string name;
std::string texture;
bool spriteNode = false;
bool sprite_node = false;
bool transparent = false;
};
Node nodes[] = {
{"cobble stone", "res/textures/cobble.png"}
{"iron block", "res/textures/iron.png"}
static NodeType nodes[] = {
{"air", "none"},
{"cobble stone", "res/textures/cobble.png"},
{"iron block", "res/textures/iron.png"},
};
*/
}
#endif // POLYGUN_ENGINE_NODES_HPP