[Chunk] Working on it.

This commit is contained in:
Quentin Bazin 2014-12-18 07:02:48 +01:00
parent fad91e840f
commit 0b806a93c6
17 changed files with 941 additions and 68 deletions

View File

@ -29,6 +29,8 @@ class Application {
Application();
~Application();
void initGL();
void handleEvents();
void run();

59
include/gl/Camera.hpp Normal file
View File

@ -0,0 +1,59 @@
/*
* =====================================================================================
*
* Filename: Camera.hpp
*
* Description:
*
* Version: 1.0
* Created: 16/12/2014 12:21:03
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef CAMERA_HPP_
#define CAMERA_HPP_
#include <cmath>
#include <glm/glm.hpp>
#define RADIANS_PER_DEGREES 0.0174532925199
#define M_PI 3.14159265358979323846
class Camera {
public:
Camera();
~Camera();
void turnH(float angle);
void turnV(float angle);
void move(float direction);
glm::mat4 processInputs();
glm::mat4 update();
float pointTargetedX() { return m_x + cos(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES); }
float pointTargetedY() { return m_y + sin(m_angleV * RADIANS_PER_DEGREES); }
float pointTargetedZ() { return m_z + sin(m_angleH * RADIANS_PER_DEGREES) * cos(m_angleV * RADIANS_PER_DEGREES) - 0.00001; }
private:
glm::mat4 m_viewMatrix;
float m_x;
float m_y;
float m_z;
float m_angleH;
float m_angleV;
float m_vx;
float m_vz;
};
#endif // CAMERA_HPP_

View File

@ -18,6 +18,10 @@
#ifndef SHADER_HPP_
#define SHADER_HPP_
#include <string>
#include <glm/glm.hpp>
#include "OpenGL.hpp"
class Shader {
@ -30,11 +34,14 @@ class Shader {
void compileShader(GLenum type, GLuint &shader, const char *filename);
GLint attrib(const char *attribName);
GLint uniform(const char *uniformName);
GLint attrib(std::string name);
GLint uniform(std::string name);
void enableVertexAttribArray(const char *attribName);
void disableVertexAttribArray(const char *attribName);
void enableVertexAttribArray(std::string name);
void disableVertexAttribArray(std::string name);
void setUniform(std::string name, int n);
void setUniform(std::string name, const glm::mat4 &matrix);
static void bind(const Shader *shader);

View File

@ -0,0 +1,39 @@
/*
* =====================================================================================
*
* Filename: VertexBuffer.hpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 17:09:58
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef VERTEXBUFFER_HPP_
#define VERTEXBUFFER_HPP_
#include "OpenGL.hpp"
class VertexBuffer {
public:
VertexBuffer();
~VertexBuffer();
void setData(GLsizeiptr size, const GLvoid *data, GLenum usage);
void updateData(GLintptr offset, GLsizeiptr size, const GLvoid *data);
static void bind(const VertexBuffer *vertexBuffer);
private:
GLuint m_id;
static VertexBuffer *activeBuffer;
};
#endif // VERTEXBUFFER_HPP_

View File

@ -18,9 +18,11 @@
#ifndef GAMESTATE_HPP_
#define GAMESTATE_HPP_
#include <glm/glm.hpp>
#include "ApplicationState.hpp"
#include "OpenGL.hpp"
#include "Shader.hpp"
#include "Camera.hpp"
#include "World.hpp"
class GameState : public ApplicationState {
public:
@ -32,9 +34,14 @@ class GameState : public ApplicationState {
void draw();
private:
GLuint m_vbo;
glm::mat4 m_projectionMatrix;
glm::mat4 m_viewMatrix;
Camera m_camera;
Shader m_shader;
World m_world;
};
#endif // GAMESTATE_HPP_

View File

@ -26,7 +26,7 @@
#define EXCEPTION(args...) (Exception(__LINE__, _FILE, args))
class Exception : public std::exception {
class Exception {
public:
template<typename... Args>
Exception(u16 line, std::string filename, Args... args) throw() {
@ -40,8 +40,8 @@ class Exception : public std::exception {
~Exception() throw() {
}
virtual const char *what() const throw() {
return (Debug::textColor(Debug::TextColor::Red, true) + "at " + m_filename + ":" + std::to_string(m_line) + ": " + Debug::textColor(0, true) + m_errorMsg.c_str() + Debug::textColor()).c_str();
virtual std::string what() const throw() {
return Debug::textColor(Debug::TextColor::Red, true) + "at " + m_filename + ":" + std::to_string(m_line) + ": " + Debug::textColor(0, true) + m_errorMsg.c_str() + Debug::textColor();
}
private:

86
include/world/Chunk.hpp Normal file
View File

@ -0,0 +1,86 @@
/*
* =====================================================================================
*
* Filename: Chunk.hpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 17:31:17
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef CHUNK_HPP_
#define CHUNK_HPP_
#include <vector>
#include <SFML/Graphics/Texture.hpp>
#include "Shader.hpp"
#include "Types.hpp"
#include "VertexBuffer.hpp"
class Chunk {
public:
Chunk(s32 x, s32 y, s32 z);
~Chunk();
void generate();
void update();
void draw(Shader &shader);
u8 getBlock(s8 x, s8 y, s8 z);
static float noise2d(float x, float y, int seed, int octaves, float persistence);
static float noise3d_abs(float x, float y, float z, int seed, int octaves, float persistence);
s32 x() const { return m_x; }
s32 y() const { return m_y; }
s32 z() const { return m_z; }
bool initialized() const { return m_initialized; }
void setInitialized(bool initialized) { m_initialized = initialized; }
Chunk *left() const { return m_surroundingChunks[0]; }
Chunk *right() const { return m_surroundingChunks[1]; }
Chunk *front() const { return m_surroundingChunks[2]; }
Chunk *back() const { return m_surroundingChunks[3]; }
static const u8 width = 16;
static const u8 height = 32;
static const u8 depth = 16;
void setLeft(Chunk *left) { m_surroundingChunks[0] = left; }
void setRight(Chunk *right) { m_surroundingChunks[1] = right; }
void setFront(Chunk *front) { m_surroundingChunks[2] = front; }
void setBack(Chunk *back) { m_surroundingChunks[3] = back; }
private:
s32 m_x;
s32 m_y;
s32 m_z;
sf::Texture m_texture;
std::vector<u8> m_data;
std::vector<float> m_vertices;
std::vector<float> m_normals;
std::vector<float> m_texCoords;
VertexBuffer m_vbo;
Chunk *m_surroundingChunks[4];
bool m_changed;
bool m_initialized;
};
#endif // CHUNK_HPP_

41
include/world/World.hpp Normal file
View File

@ -0,0 +1,41 @@
/*
* =====================================================================================
*
* Filename: World.hpp
*
* Description:
*
* Version: 1.0
* Created: 16/12/2014 15:28:02
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#ifndef WORLD_HPP_
#define WORLD_HPP_
#include <memory>
#include "Chunk.hpp"
class World {
public:
World();
~World();
void draw(Shader &shader, const glm::mat4 &pv);
Chunk *getChunk(s16 x, s16 z) { return m_chunks[x + z * m_width].get(); }
private:
s32 m_width;
s32 m_depth;
std::vector<std::unique_ptr<Chunk>> m_chunks;
};
#endif // WORLD_HPP_

View File

@ -1,6 +1,43 @@
#version 120
varying vec4 v_coord3d;
varying vec4 v_normal;
varying vec2 v_texCoord;
uniform sampler2D u_tex;
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
//vec4 lightSource = vec4(0.0, 48.0, 0.0, 0.0);
//float lightIntensity = 1.0;
//vec4 surfaceToLight = normalize(lightSource - v_coord3d);
//float brightness = dot(v_normal, surfaceToLight) / (length(surfaceToLight) * length(v_normal));
//brightness = clamp(brightness, 0, 1) / 2 + 0.25;
//gl_FragColor = vec4(brightness * lightIntensity * vec3(1.0, 1.0, 1.0), 1.0);
vec4 lightPosition = vec4(0.0, 48.0, 0.0, 1.0);
vec3 lightColor = vec3(1.0, 1.0, 1.0);
vec4 lightDirection = normalize(lightPosition - v_coord3d);
float ambientIntensity = 0.5;
vec4 ambientColor = vec4(lightColor * ambientIntensity, 1.0);
float diffuseIntensity = 0.5;
float diffuseFactor = dot(v_normal, lightDirection);
vec4 diffuseColor;
if(diffuseFactor > 0) {
//diffuseColor = vec4(lightColor, 1.0) * diffuseIntensity * diffuseFactor;
diffuseColor = vec4(lightColor * diffuseIntensity * diffuseFactor, 1.0);
//diffuseColor = vec4(0.0, 0.0, 0.0, 1.0);
} else {
diffuseColor = vec4(0.0, 0.0, 0.0, 1.0);
}
vec4 surfaceColor = texture2D(u_tex, v_texCoord);
gl_FragColor = surfaceColor * (ambientColor + diffuseColor);
}

View File

@ -1,13 +1,22 @@
#version 120
attribute vec2 coord2d;
attribute vec3 coord3d;
attribute vec3 normal;
attribute vec2 texCoord;
uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;
varying vec4 v_coord3d;
varying vec4 v_normal;
varying vec2 v_texCoord;
uniform mat4 u_modelMatrix;
uniform mat4 u_viewProjectionMatrix;
void main() {
mat4 MVP = u_projectionMatrix * u_viewMatrix;
v_coord3d = u_modelMatrix * vec4(coord3d, 1.0);
gl_Position = MVP * vec4(coord2d, 0.0, 1.0);
gl_Position = u_viewProjectionMatrix * v_coord3d;
v_normal = vec4(normal, 1.0);
v_texCoord = texCoord;
}

View File

@ -15,6 +15,9 @@
*
* =====================================================================================
*/
#include <cstdlib>
#include <ctime>
#include <SFML/Window/Event.hpp>
#include "Application.hpp"
@ -23,13 +26,14 @@
#include "OpenGL.hpp"
Application::Application() {
if(glewInit() != GLEW_OK) {
EXCEPTION("glew init failed");
}
srand(time(NULL));
m_window.create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), APP_NAME, sf::Style::Close, sf::ContextSettings(24, 8, 2));
m_window.setVerticalSyncEnabled(true);
m_defaultView.reset(sf::FloatRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
initGL();
//ResourceHandler::getInstance().loadResources();
m_applicationStateStack = &ApplicationStateStack::getInstance();
}
@ -37,6 +41,22 @@ Application::Application() {
Application::~Application() {
}
void Application::initGL() {
if(glewInit() != GLEW_OK) {
throw EXCEPTION("glew init failed");
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glClearColor(0.196078, 0.6, 0.8, 1.0); // Skyblue
}
void Application::handleEvents() {
sf::Event event;
while(m_window.pollEvent(event)) {
@ -62,9 +82,11 @@ void Application::run() {
});
m_clock.drawGame([&]{
m_window.clear();
//m_window.clear();
m_window.setView(m_defaultView);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_applicationStateStack->top().draw();
m_window.display();

125
source/gl/Camera.cpp Normal file
View File

@ -0,0 +1,125 @@
/*
* =====================================================================================
*
* Filename: Camera.cpp
*
* Description:
*
* Version: 1.0
* Created: 16/12/2014 12:21:19
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include <SFML/Window/Keyboard.hpp>
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp>
#include "Camera.hpp"
Camera::Camera() {
m_x = 0;
m_y = 32;
m_z = 0;
m_angleH = 45.0;
m_angleV = -20.0;
m_vx = 0;
m_vz = 0;
m_viewMatrix = update();
}
Camera::~Camera() {
}
void Camera::turnH(float angle) {
m_angleH += angle;
while(m_angleH >= 180.0) {
m_angleH -= 360.0;
}
while(m_angleH < -180.0) {
m_angleH += 360.0;
}
}
void Camera::turnV(float angle) {
m_angleV += angle;
if(89.9 < m_angleV) {
m_angleV = 89.9;
}
else if(-89.9 > m_angleV) {
m_angleV = -89.9;
}
}
void Camera::move(float direction) {
direction += m_angleH;
m_vx = 0.04f * cos(direction * M_PI / 180.0);
m_vz = 0.04f * sin(direction * M_PI / 180.0);
m_x += m_vx;
m_z += m_vz;
m_vx = 0;
m_vz = 0;
}
glm::mat4 Camera::processInputs() {
if(sf::Keyboard::isKeyPressed(sf::Keyboard::X)) {
turnV(1);
m_viewMatrix = update();
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
turnV(-1);
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
turnH(-0.8);
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
turnH(0.8);
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::BackSpace)) {
m_y -= 0.1;
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Return)) {
m_y += 0.1;
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
move(0.0f);
m_viewMatrix = update();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
move(180.0f);
m_viewMatrix = update();
}
return m_viewMatrix;
}
glm::mat4 Camera::update() {
return glm::lookAt(glm::vec3(m_x, m_y, m_z),
glm::vec3(pointTargetedX(), pointTargetedY(), pointTargetedZ()),
glm::vec3(0, 1, 0));
}

View File

@ -18,6 +18,9 @@
#include <iostream>
#include <fstream>
#define GLM_FORCE_RADIANS
#include <glm/gtc/type_ptr.hpp>
#include "Exception.hpp"
#include "Shader.hpp"
@ -107,32 +110,40 @@ void Shader::compileShader(GLenum type, GLuint &shader, const char *filename) {
}
}
GLint Shader::attrib(const char *attribName) {
GLint attrib = glGetAttribLocation(m_program, attribName);
GLint Shader::attrib(std::string name) {
GLint attrib = glGetAttribLocation(m_program, name.c_str());
if(attrib == -1) {
throw EXCEPTION("Could not bind attribute:", attribName);
throw EXCEPTION("Could not bind attribute:", name);
}
return attrib;
}
GLint Shader::uniform(const char *uniformName) {
GLint uniform = glGetUniformLocation(m_program, uniformName);
GLint Shader::uniform(std::string name) {
GLint uniform = glGetUniformLocation(m_program, name.c_str());
if(uniform == -1) {
throw EXCEPTION("Could not bind uniform:", uniformName);
throw EXCEPTION("Could not bind uniform:", name);
}
return uniform;
}
void Shader::enableVertexAttribArray(const char *attribName) {
glEnableVertexAttribArray(attrib(attribName));
void Shader::enableVertexAttribArray(std::string name) {
glEnableVertexAttribArray(attrib(name));
}
void Shader::disableVertexAttribArray(const char *attribName) {
glDisableVertexAttribArray(attrib(attribName));
void Shader::disableVertexAttribArray(std::string name) {
glDisableVertexAttribArray(attrib(name));
}
void Shader::setUniform(std::string name, int n) {
glUniform1i(uniform(name), n);
}
void Shader::setUniform(std::string name, const glm::mat4 &matrix) {
glUniformMatrix4fv(uniform(name), 1, GL_FALSE, glm::value_ptr(matrix));
}
void Shader::bind(const Shader *shader) {

View File

@ -0,0 +1,54 @@
/*
* =====================================================================================
*
* Filename: VertexBuffer.cpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 17:10:16
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include "VertexBuffer.hpp"
VertexBuffer *VertexBuffer::activeBuffer = nullptr;
VertexBuffer::VertexBuffer() {
glGenBuffers(1, &m_id);
}
VertexBuffer::~VertexBuffer() {
}
void VertexBuffer::setData(GLsizeiptr size, const GLvoid *data, GLenum usage) {
if(activeBuffer != this) bind(this);
glBufferData(GL_ARRAY_BUFFER, size, data, usage);
if(activeBuffer != this) bind(nullptr);
}
void VertexBuffer::updateData(GLintptr offset, GLsizeiptr size, const GLvoid *data) {
if(activeBuffer != this) bind(this);
glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
if(activeBuffer != this) bind(nullptr);
}
void VertexBuffer::bind(const VertexBuffer *vertexBuffer) {
activeBuffer = const_cast<VertexBuffer*>(vertexBuffer);
if(vertexBuffer) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->m_id);
} else {
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}

View File

@ -17,67 +17,56 @@
*/
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "GameState.hpp"
GameState::GameState() {
m_shader.loadFromFile("shaders/game.v.glsl", "shaders/game.f.glsl");
glGenBuffers(1, &m_vbo);
GLfloat vertices[2 * 4] = {
0.0, 1.0,
1.0, 0.0,
0.0, -1.0,
-1.0, 0.0
};
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Shader::bind(&m_shader);
glm::mat4 projectionMatrix = glm::perspective(80.0f, 1.0f, 0.1f, 1000.0f);
glUniformMatrix4fv(m_shader.uniform("u_projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
m_projectionMatrix = glm::perspective(45.0f, 640.0f / 480.0f, 0.1f, 3000.0f);
/*glm::mat4 modelviewMatrix = glm::lookAt(glm::vec3(-20.0f, 40.0f, -20.0f),
glm::vec3(16.0f, 16.0f, 16.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
*/
m_viewMatrix = m_camera.update();
glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.0f, 1.0f, 1.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(m_shader.uniform("u_viewMatrix"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
//glActiveTexture(GL_TEXTURE0);
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
m_shader.setUniform("u_tex", 0);
Shader::bind(nullptr);
}
GameState::~GameState() {
glDeleteBuffers(1, &m_vbo);
}
void GameState::update() {
m_viewMatrix = m_camera.processInputs();
//Shader::bind(&m_shader);
//m_shader.setUniform("u_MVP", m_projectionMatrix * m_modelviewMatrix);
//Shader::bind(nullptr);
}
void GameState::draw() {
Shader::bind(&m_shader);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
m_world.draw(m_shader, m_projectionMatrix * m_viewMatrix);
glVertexAttribPointer(m_shader.attrib("coord2d"), 2, GL_FLOAT, GL_FALSE, 0, 0);
m_shader.enableVertexAttribArray("coord2d");
GLubyte indices[6] = {
0, 1, 2,
2, 3, 0
};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
m_shader.disableVertexAttribArray("coord2d");
glBindBuffer(GL_ARRAY_BUFFER, 0);
/*glBegin(GL_LINES);
glColor3f(1, 1, 1); glVertex3f(0, 0, 0);
glColor3f(1, 1, 1); glVertex3f(0, 5, 0);
glColor3f(1, 0, 1); glVertex3f(0, 0, 0);
glColor3f(1, 0, 1); glVertex3f(5, 0, 0);
glColor3f(1, 1, 0); glVertex3f(0, 0, 0);
glColor3f(1, 1, 0); glVertex3f(0, 0, 5);
glEnd();*/
Shader::bind(nullptr);
}

286
source/world/Chunk.cpp Normal file
View File

@ -0,0 +1,286 @@
/*
* =====================================================================================
*
* Filename: Chunk.cpp
*
* Description:
*
* Version: 1.0
* Created: 15/12/2014 17:31:32
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <glm/gtc/noise.hpp>
#include "Chunk.hpp"
Chunk::Chunk(s32 x, s32 y, s32 z) {
m_x = x;
m_y = y;
m_z = z;
m_texture.loadFromFile("textures/cobblestone.bmp");
sf::Texture::bind(&m_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D);
sf::Texture::bind(nullptr);
m_changed = false;
m_initialized = false;
m_surroundingChunks[0] = nullptr;
m_surroundingChunks[1] = nullptr;
m_surroundingChunks[2] = nullptr;
m_surroundingChunks[3] = nullptr;
}
Chunk::~Chunk() {
}
void Chunk::generate() {
time_t seed = time(NULL);
for(u8 z = 0 ; z < depth ; z++) {
for(u8 y = 0 ; y < height ; y++) {
for(u8 x = 0 ; x < width ; x++) {
float n = noise2d((x + m_x * width) / 256.0, (z + m_z * depth) / 256.0, seed, 5, 0.5) * 4;
float h = 10 + n * 2;
/*float n = noise3d_abs((x + m_x * 32) * 0.015, (y + m_y * 32) * 0.015, (z + m_z * 32) * 0.015, seed, 3, 4) / 2;
if(3 < n && n < 8) {
m_data.push_back(1);
} else {
m_data.push_back(0);
}*/
if(y + m_y * height < h) {
//if(y < abs(h)) {
m_data.push_back(1);
} else {
m_data.push_back(0);
}
// Random value used to determine land type
/*float r = noise3d_abs((x + m_x * 32) / 16.0, (y + m_y * 32) / 16.0, (z + m_z * CZ) / 16.0, -seed, 2, 1);
// Sand layer
if(n + r * 5 < 4) {
//m_blocks[x][y][z] = 7;
m_data.push_back(1);
}
// Dirt layer, but use grass blocks for the top
else if(n + r * 5 < 8) {
//m_blocks[x][y][z] = (h < 4 || y + m_y * 32 < h - 1) ? 1 : 3;
m_data.push_back(1);
}
// Rock layer
else if(r < 1.25) {
//m_blocks[x][y][z] = 6;
m_data.push_back(1);
// Sometimes, ores!
} else {
//m_blocks[x][y][z] = 11;
m_data.push_back(1);
}*/
}
}
}
m_changed = true;
}
#include "Debug.hpp"
#include "GameClock.hpp"
void Chunk::update() {
m_changed = false;
float cubeCoords[6 * 4 * 3] = {
0, 1, 1,
0, 1, 0,
0, 0, 0,
0, 0, 1,
1, 0, 1,
1, 0, 0,
1, 1, 0,
1, 1, 1,
0, 0, 1,
0, 0, 0,
1, 0, 0,
1, 0, 1,
1, 1, 1,
1, 1, 0,
0, 1, 0,
0, 1, 1,
0, 1, 1,
0, 0, 1,
1, 0, 1,
1, 1, 1,
1, 1, 0,
1, 0, 0,
0, 0, 0,
0, 1, 0
};
float texCoords[2 * 4 * 6] = {
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f
};
for(int i = 1 ; i < 6 ; i++) {
memcpy(&texCoords[2 * 4 * i], &texCoords[0], 2 * 4 * sizeof(float));
}
m_vertices.clear();
m_normals.clear();
m_texCoords.clear();
//int truc = GameClock::getTicks(true);
for(u8 z = 0 ; z < depth ; z++) {
for(u8 y = 0 ; y < height ; y++) {
for(u8 x = 0 ; x < width ; x++) {
if(getBlock(x, y, z)) {
for(u8 i = 0 ; i < 6 ; i++) {
if((x > 0 && getBlock(x - 1, y, z) && i == 0)
|| (x < width - 1 && getBlock(x + 1, y, z) && i == 1)
|| (y > 0 && getBlock(x, y - 1, z) && i == 2)
|| (y < height - 1 && getBlock(x, y + 1, z) && i == 3)
|| (z > 0 && getBlock(x, y, z - 1) && i == 5)
|| (z < depth - 1 && getBlock(x, y, z + 1) && i == 4)
|| (x == 0 && m_surroundingChunks[0] && m_surroundingChunks[0]->getBlock(width - 1, y, z) && i == 0)
|| (x == width - 1 && m_surroundingChunks[1] && m_surroundingChunks[1]->getBlock(0, y, z) && i == 1)
|| (z == 0 && m_surroundingChunks[2] && m_surroundingChunks[2]->getBlock(x, y, depth - 1) && i == 5)
|| (z == depth - 1 && m_surroundingChunks[3] && m_surroundingChunks[3]->getBlock(x, y, 0) && i == 4)
) {
continue;
}
glm::vec3 u(cubeCoords[i * 12 + 0], cubeCoords[i * 12 + 1], cubeCoords[i * 12 + 2]);
glm::vec3 v(cubeCoords[i * 12 + 3], cubeCoords[i * 12 + 4], cubeCoords[i * 12 + 5]);
glm::vec3 normal = glm::normalize(glm::cross(u, v));
for(u8 j = 0 ; j < 4 ; j++) {
m_vertices.push_back(x + cubeCoords[i * 12 + j * 3]);
m_vertices.push_back(y + cubeCoords[i * 12 + j * 3 + 1]);
m_vertices.push_back(z + cubeCoords[i * 12 + j * 3 + 2]);
m_normals.push_back(normal.x);
m_normals.push_back(normal.y);
m_normals.push_back(normal.z);
m_texCoords.push_back(texCoords[i * 8 + j * 2]);
m_texCoords.push_back(texCoords[i * 8 + j * 2 + 1]);
}
}
}
}
}
}
//DEBUG("Sending vertices:", GameClock::getTicks(true) - truc, "ms");
VertexBuffer::bind(&m_vbo);
m_vbo.setData((m_vertices.size() + m_normals.size() + m_texCoords.size()) * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
m_vbo.updateData(0, m_vertices.size() * sizeof(float), m_vertices.data());
m_vbo.updateData(m_vertices.size() * sizeof(float), m_normals.size() * sizeof(float), m_normals.data());
m_vbo.updateData((m_vertices.size() + m_normals.size()) * sizeof(float), m_texCoords.size() * sizeof(float), m_texCoords.data());
VertexBuffer::bind(nullptr);
}
void Chunk::draw(Shader &shader) {
if(m_changed) {
int truc = GameClock::getTicks(true);
//if(m_changed) update();
update();
DEBUG("Chunk", m_x, m_y, m_z, "| Vertices:", m_vertices.size(), "| Update time:", GameClock::getTicks(true) - truc, "ms");
}
if(m_vertices.size() == 0) return;
VertexBuffer::bind(&m_vbo);
shader.enableVertexAttribArray("coord3d");
shader.enableVertexAttribArray("normal");
shader.enableVertexAttribArray("texCoord");
glVertexAttribPointer(shader.attrib("coord3d"), 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(shader.attrib("normal"), 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(m_vertices.size() * sizeof(float)));
glVertexAttribPointer(shader.attrib("texCoord"), 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)((m_vertices.size() + m_normals.size()) * sizeof(float)));
sf::Texture::bind(&m_texture);
glDrawArrays(GL_QUADS, 0, m_vertices.size());
sf::Texture::bind(nullptr);
shader.disableVertexAttribArray("texCoord");
shader.disableVertexAttribArray("normal");
shader.disableVertexAttribArray("coord3d");
VertexBuffer::bind(nullptr);
}
u8 Chunk::getBlock(s8 x, s8 y, s8 z) {
u16 i = x + y * width + z * width * height;
if(i < m_data.size()) {
return m_data[i];
} else {
return 0;
}
}
float Chunk::noise2d(float x, float y, int seed, int octaves, float persistence) {
float sum = 0;
float strength = 1.0;
float scale = 1.0;
for(int i = 0 ; i < octaves ; i++) {
sum += strength * glm::simplex(glm::vec2(x, y) * scale);
scale *= 2.0;
strength *= persistence;
}
return sum;
}
float Chunk::noise3d_abs(float x, float y, float z, int seed, int octaves, float persistence) {
float sum = 0;
float strength = 1.0;
float scale = 1.0;
for(int i = 0 ; i < octaves ; i++) {
sum += strength * fabs(glm::simplex(glm::vec3(x, y, z) * scale));
scale *= 2.0;
strength *= persistence;
}
return sum;
}

99
source/world/World.cpp Normal file
View File

@ -0,0 +1,99 @@
/*
* =====================================================================================
*
* Filename: World.cpp
*
* Description:
*
* Version: 1.0
* Created: 16/12/2014 15:28:19
* Revision: none
* Compiler: gcc
*
* Author: Quentin BAZIN, <quent42340@gmail.com>
* Company:
*
* =====================================================================================
*/
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp>
#include "World.hpp"
World::World() {
m_width = 4;
m_depth = 4;
//for(s32 z = -m_depth / 2 ; z < m_depth / 2 ; z++) {
// for(s32 x = -m_width / 2 ; x < m_width / 2 ; x++) {
for(s32 z = 0 ; z < m_depth ; z++) {
for(s32 x = 0 ; x < m_width ; x++) {
m_chunks.push_back(std::unique_ptr<Chunk>(new Chunk(x, 0, z)));
}
}
for(s32 z = 0 ; z < m_depth ; z++) {
for(s32 x = 0 ; x < m_width ; x++) {
if(x > 0) getChunk(x, z)->setLeft(getChunk(x - 1, z));
if(x < m_width - 1) getChunk(x, z)->setRight(getChunk(x + 1, z));
if(z > 0) getChunk(x, z)->setFront(getChunk(x, z - 1));
if(z < m_depth - 1) getChunk(x, z)->setBack(getChunk(x, z + 1));
}
}
}
World::~World() {
}
#include "Debug.hpp"
void World::draw(Shader &shader, const glm::mat4 &pv) {
float ud = 0.0;
s32 ux = -1;
s32 uz = -1;
for(auto &it : m_chunks) {
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(it->x() * Chunk::width, it->y() * Chunk::height, it->z() * Chunk::depth));
glm::mat4 mvp = pv * model;
// Is this chunk on the screen?
glm::vec4 center = mvp * glm::vec4(Chunk::width / 2, Chunk::height / 2, Chunk::depth / 2, 1);
float d = glm::length(center);
center.x /= center.w;
center.y /= center.w;
// If it is behind the camera, don't bother drawing it
if(center.z < -Chunk::height / 2)
continue;
// It it is outside the screen, don't bother drawing it
if(fabsf(center.x) > 1 + fabsf(Chunk::height * 2 / center.w) || fabsf(center.y) > 1 + fabsf(Chunk::height * 2 / center.w))
continue;
if(!it->initialized()) {
if(ux < 0 || d < ud) {
ud = d;
ux = it->x();
uz = it->z();
}
continue;
}
shader.setUniform("u_modelMatrix", model);
shader.setUniform("u_viewProjectionMatrix", pv);
it->draw(shader);
}
if(ux >= 0) {
getChunk(ux, uz)->generate();
if(getChunk(ux, uz)->left()) getChunk(ux, uz)->left()->generate();
if(getChunk(ux, uz)->right()) getChunk(ux, uz)->right()->generate();
if(getChunk(ux, uz)->front()) getChunk(ux, uz)->front()->generate();
if(getChunk(ux, uz)->back()) getChunk(ux, uz)->back()->generate();
getChunk(ux, uz)->setInitialized(true);
}
}