Created
June 30, 2014 15:12
-
-
Save fkaa/bef91d05a0e4e97dd3d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "game.h" | |
Chunk::Chunk(int x, int y, int z) { | |
memset(contents, 0, sizeof(contents)); | |
count = 0; | |
dirty = true; | |
left = 0; | |
right = 0; | |
top = 0; | |
bottom = 0; | |
front = 0; | |
back = 0; | |
cx = x; | |
cy = y; | |
cz = z; | |
// TEST | |
for (int x = 0; x < CX; x++) { | |
for (int y = 0; y < CY; y++) { | |
for (int z = 0; z < CZ; z++) { | |
contents[x][y][z] = rand() % 2;//sqrt((float) (x-CX/2)*(x-CX/2) + (y-CY/2)*(y-CY/2) + (z-CY/2)*(z-CZ/2)) <= CX/2 ? 1 : 0; | |
} | |
} | |
} | |
// TEST | |
glGenBuffers(1, &vbo); | |
} | |
Chunk::~Chunk() { | |
glDeleteBuffers(1, &vbo); | |
} | |
uint8_t Chunk::get(int x, int y, int z) { | |
if (x < 0) return left ? left->contents [x + CX][y ][z ] : 0; | |
if (x >= CX) return right ? right->contents [x - CX][y ][z ] : 0; | |
if (y < 0) return bottom ? bottom->contents[x ][y + CY][z ] : 0; | |
if (y >= CY) return top ? top->contents [x ][y - CY][z ] : 0; | |
if (z < 0) return front ? front->contents [x ][y ][z + CZ] : 0; | |
if (z >= CZ) return back ? back->contents [x ][y ][z - CZ] : 0; | |
return contents[x][y][z]; | |
} | |
void Chunk::set(int x, int y, int z, uint8_t type) { | |
if (x < 0) if (left) left->set( x + CX, y, z, type); | |
if (x >= CX) if (right) right->set( x - CX, y, z, type); | |
if (y < 0) if (bottom) bottom->set(x, y + CY, z, type); | |
if (y >= CY) if (top) top->set( x, y - CY, z, type); | |
if (z < 0) if (front) front->set( x, y, z + CZ, type); | |
if (z >= CZ) if (back) back->set( x, y, z - CZ, type); | |
contents[x][y][z] = type; | |
dirty = true; | |
if(x == 0 && left) left->dirty = true; | |
if(x == CX - 1 && right) right->dirty = true; | |
if(y == 0 && bottom) bottom->dirty = true; | |
if(y == CY - 1 && top) top->dirty = true; | |
if(z == 0 && front) front->dirty = true; | |
if(z == CZ - 1 && back) back->dirty = true; | |
} | |
void Chunk::reshape() { | |
dirty = false; | |
vec3b vertices[CX * CY * CZ * 12 * 6]; | |
int i = 0; | |
for (int x = 0; x < CX; x++) { | |
for (int y = 0; y < CY; y++) { | |
for (int z = 0; z < CZ; z++) { | |
if (!contents[x][y][z]) continue; | |
uint8_t type = contents[x][y][z]; | |
// -x | |
if (!get(x - 1, y, z)) { | |
vertices[i++] = vec3b(x, y, z ); vertices[i++] = vec3b(-1, 0, 0); | |
vertices[i++] = vec3b(x, y, z + 1); vertices[i++] = vec3b(-1, 0, 0); | |
vertices[i++] = vec3b(x, y + 1, z ); vertices[i++] = vec3b(-1, 0, 0); | |
vertices[i++] = vec3b(x, y + 1, z ); vertices[i++] = vec3b(-1, 0, 0); | |
vertices[i++] = vec3b(x, y, z + 1); vertices[i++] = vec3b(-1, 0, 0); | |
vertices[i++] = vec3b(x, y + 1, z + 1); vertices[i++] = vec3b(-1, 0, 0); | |
} | |
// +x | |
if (!get(x + 1, y, z)) { | |
vertices[i++] = vec3b(x + 1, y, z ); vertices[i++] = vec3b(1, 0, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z ); vertices[i++] = vec3b(1, 0, 0); | |
vertices[i++] = vec3b(x + 1, y, z + 1); vertices[i++] = vec3b(1, 0, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z ); vertices[i++] = vec3b(1, 0, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z + 1); vertices[i++] = vec3b(1, 0, 0); | |
vertices[i++] = vec3b(x + 1, y , z + 1); vertices[i++] = vec3b(1, 0, 0); | |
} | |
// -y | |
if (!get(x, y - 1, z)) { | |
vertices[i++] = vec3b(x, y, z ); vertices[i++] = vec3b(0, -1, 0); | |
vertices[i++] = vec3b(x + 1, y, z ); vertices[i++] = vec3b(0, -1, 0); | |
vertices[i++] = vec3b(x, y, z + 1); vertices[i++] = vec3b(0, -1, 0); | |
vertices[i++] = vec3b(x + 1, y, z ); vertices[i++] = vec3b(0, -1, 0); | |
vertices[i++] = vec3b(x + 1, y, z + 1); vertices[i++] = vec3b(0, -1, 0); | |
vertices[i++] = vec3b(x, y, z + 1); vertices[i++] = vec3b(0, -1, 0); | |
} | |
// +y | |
if (!get(x, y + 1, z)) { | |
vertices[i++] = vec3b(x, y + 1, z ); vertices[i++] = vec3b(0, 1, 0); | |
vertices[i++] = vec3b(x, y + 1, z + 1); vertices[i++] = vec3b(0, 1, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z ); vertices[i++] = vec3b(0, 1, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z ); vertices[i++] = vec3b(0, 1, 0); | |
vertices[i++] = vec3b(x, y + 1, z + 1); vertices[i++] = vec3b(0, 1, 0); | |
vertices[i++] = vec3b(x + 1, y + 1, z + 1); vertices[i++] = vec3b(0, 1, 0); | |
} | |
// -z | |
if (!get(x, y, z - 1)) { | |
vertices[i++] = vec3b(x, y, z ); vertices[i++] = vec3b(0, 0, -1); | |
vertices[i++] = vec3b(x, y + 1, z ); vertices[i++] = vec3b(0, 0, -1); | |
vertices[i++] = vec3b(x + 1, y, z ); vertices[i++] = vec3b(0, 0, -1); | |
vertices[i++] = vec3b(x, y + 1, z ); vertices[i++] = vec3b(0, 0, -1); | |
vertices[i++] = vec3b(x + 1, y + 1, z ); vertices[i++] = vec3b(0, 0, -1); | |
vertices[i++] = vec3b(x + 1, y, z ); vertices[i++] = vec3b(0, 0, -1); | |
} | |
// +z | |
if (!get(x, y, z + 1)) { | |
vertices[i++] = vec3b(x, y, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
vertices[i++] = vec3b(x + 1, y, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
vertices[i++] = vec3b(x, y + 1, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
vertices[i++] = vec3b(x, y + 1, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
vertices[i++] = vec3b(x + 1, y, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
vertices[i++] = vec3b(x + 1, y + 1, z + 1); vertices[i++] = vec3b(0, 0, 1); | |
} | |
} | |
} | |
} | |
count = i; | |
printf("%i/%i\n", count, CX * CY * CZ * 12 * 6); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glBufferData(GL_ARRAY_BUFFER, count * sizeof(*vertices), vertices, GL_STREAM_DRAW); | |
} | |
void Chunk::render(GLuint coord, GLuint normal) { | |
if (dirty) reshape(); | |
if (!count) return; | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glVertexAttribPointer(coord, 3, GL_BYTE, GL_FALSE, 6 * sizeof(GLbyte), (void*)0); | |
glVertexAttribPointer(normal, 3, GL_BYTE, GL_FALSE, 6 * sizeof(GLbyte), (void*)(3 * sizeof(GLbyte))); | |
glDrawArrays(GL_TRIANGLES, 0, count); | |
} | |
#pragma mark - | |
#pragma mark World Shader | |
/*** | |
* ____ _ _ | |
* / ___|| |__ __ _ __| | ___ _ __ | |
* \___ \| '_ \ / _` |/ _` |/ _ \ '__| | |
* ___) | | | | (_| | (_| | __/ | | |
* |____/|_| |_|\__,_|\__,_|\___|_| | |
* | |
*/ | |
const char* SuperChunk::vs = glsl(120, | |
attribute vec3 a_coord; | |
attribute vec3 a_normal; | |
uniform mat4 u_mvp; | |
uniform mat4 u_model; | |
uniform mat4 u_view; | |
varying vec3 v_coord; | |
varying vec3 v_normal; | |
void main() { | |
v_coord = a_coord; | |
v_normal = (a_normal + .5) * .5; | |
gl_Position = u_mvp * vec4(a_coord, 1.); | |
} | |
); | |
const char* SuperChunk::fs = glsl(120, | |
varying vec3 v_coord; | |
varying vec3 v_normal; | |
void main() { | |
gl_FragData[0] = vec4(vec3(1.), 0.); | |
gl_FragData[1] = vec4(v_normal, 1.); | |
} | |
); | |
#pragma mark - | |
SuperChunk::SuperChunk() { | |
memset(chunks, 0, sizeof(chunks)); | |
shader = glutil::make_shader_source(vs, fs); | |
glUseProgram(shader); | |
a_coord = glGetAttribLocation(shader, "a_coord"); | |
a_normal = glGetAttribLocation(shader, "a_normal"); | |
u_mvp = glGetUniformLocation(shader, "u_mvp"); | |
u_model = glGetUniformLocation(shader, "u_model"); | |
u_view = glGetUniformLocation(shader, "u_view"); | |
for(int x = 0; x < SCX; x++) { | |
for(int y = 0; y < SCY; y++) { | |
for(int z = 0; z < SCZ; z++) { | |
chunks[x][y][z] = new Chunk(x, y, z);// = new Chunk(); | |
} | |
} | |
} | |
for(int x = 0; x < SCX; x++) { | |
for(int y = 0; y < SCY; y++) { | |
for(int z = 0; z < SCZ; z++) { | |
if(x > 0) chunks[x][y][z]->left = chunks[x - 1][y][z]; | |
if(x < SCX - 1) chunks[x][y][z]->right = chunks[x + 1][y][z]; | |
if(y > 0) chunks[x][y][z]->bottom = chunks[x][y - 1][z]; | |
if(y < SCY - 1) chunks[x][y][z]->top = chunks[x][y + 1][z]; | |
if(z > 0) chunks[x][y][z]->front = chunks[x][y][z - 1]; | |
if(z < SCZ - 1) chunks[x][y][z]->back = chunks[x][y][z + 1]; | |
} | |
} | |
} | |
glUseProgram(0); | |
} | |
SuperChunk::~SuperChunk() { | |
glDeleteProgram(shader); | |
} | |
uint8_t SuperChunk::get(int x, int y, int z) { | |
int cx = x / CX; | |
int cy = y / CY; | |
int cz = z / CZ; | |
x %= CX; | |
y %= CY; | |
z %= CZ; | |
if (!chunks[cx][cy][cz]) { | |
return 0; | |
} else { | |
return chunks[cx][cy][cz]->get(x, y, z); | |
} | |
} | |
void SuperChunk::set(int x, int y, int z, uint8_t type) { | |
int cx = x / CX; | |
int cy = y / CY; | |
int cz = z / CZ; | |
x %= CX; | |
y %= CY; | |
z %= CZ; | |
if (!chunks[cx][cy][cz]) { | |
chunks[cx][cy][cz] = new Chunk(cx, cy, cz); | |
} | |
chunks[cx][cy][cz]->set(x, y, z, type); | |
} | |
void SuperChunk::render(const glm::mat4 &proj, const glm::mat4 &view) { | |
glEnable(GL_DEPTH_TEST); | |
glEnable(GL_CULL_FACE); | |
glEnableVertexAttribArray(a_coord); | |
glEnableVertexAttribArray(a_normal); | |
glUseProgram(shader); | |
for(int x = 0; x < SCX; x++) { | |
for(int y = 0; y < SCY; y++) { | |
for(int z = 0; z < SCZ; z++) { | |
if(chunks[x][y][z]) { | |
glm::mat4 model = glm::translate(glm::mat4(1), glm::vec3(x * CX, y * CY, z * CZ)); | |
glm::mat4 mvp = proj * view * model; | |
glm::vec4 center = mvp * glm::vec4(CX / 2, CY / 2, CZ / 2, 1); | |
center.x /= center.w; | |
center.y /= center.w; | |
if(center.z < -CY / 2) | |
continue; | |
if(fabsf(center.x) > 1 + fabsf(CY * 2 / center.w) || fabsf(center.y) > 1 + fabsf(CY * 2 / center.w)) continue; | |
glm::mat4 nmat = glm::inverse(view * model); | |
glUniformMatrix4fv(u_mvp, 1, GL_FALSE, glm::value_ptr(mvp)); | |
glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model)); | |
glUniformMatrix4fv(u_view, 1, GL_FALSE, glm::value_ptr(view)); | |
chunks[x][y][z]->render(a_coord, a_normal); | |
} | |
} | |
} | |
} | |
glDisableVertexAttribArray(a_coord); | |
glDisableVertexAttribArray(a_normal); | |
} | |
#pragma mark - | |
#pragma mark Default shader | |
/*** | |
* ____ _ _ | |
* / ___|| |__ __ _ __| | ___ _ __ | |
* \___ \| '_ \ / _` |/ _` |/ _ \ '__| | |
* ___) | | | | (_| | (_| | __/ | | |
* |____/|_| |_|\__,_|\__,_|\___|_| | |
* | |
*/ | |
const char* Game::vs_default = glsl(120, | |
attribute vec4 a_coord; | |
varying vec2 v_uv; | |
void main() { | |
v_uv = a_coord.zw; | |
gl_Position = vec4(a_coord.x, a_coord.y, 0., 1.); | |
} | |
); | |
const char* Game::fs_default = glsl(120, | |
uniform sampler2D u_texture; | |
varying vec2 v_uv; | |
void main() { | |
gl_FragColor = texture2D(u_texture, v_uv); | |
} | |
); | |
#pragma mark SSAO Shader | |
const char* Game::vs_ssao = glsl(120, | |
attribute vec4 a_coord; | |
varying vec2 v_uv; | |
void main() { | |
v_uv = a_coord.zw; | |
gl_Position = vec4(a_coord.x, a_coord.y, 0., 1.); | |
} | |
); | |
const char* Game::fs_ssao = glsl(120, | |
uniform sampler2D u_diffuse; | |
uniform sampler2D u_normal; | |
uniform sampler2D u_depth; | |
uniform mat4 inv_mat; | |
uniform float total_strength = 20.; | |
uniform float falloff = 0.005; | |
uniform float radius = 0.2; | |
uniform float base = 0.; | |
uniform float area = 0.0000075; | |
varying vec2 v_uv; | |
const vec2 rvalues[16] = vec2[]( | |
vec2( -0.94201624, -0.39906216 ), | |
vec2( 0.94558609, -0.76890725 ), | |
vec2( -0.094184101, -0.92938870 ), | |
vec2( 0.34495938, 0.29387760 ), | |
vec2( -0.91588581, 0.45771432 ), | |
vec2( -0.81544232, -0.87912464 ), | |
vec2( -0.38277543, 0.27676845 ), | |
vec2( 0.97484398, 0.75648379 ), | |
vec2( 0.44323325, -0.97511554 ), | |
vec2( 0.53742981, -0.47373420 ), | |
vec2( -0.26496911, -0.41893023 ), | |
vec2( 0.79197514, 0.19090188 ), | |
vec2( -0.24188840, 0.99706507 ), | |
vec2( -0.81409955, 0.91437590 ), | |
vec2( 0.19984126, 0.78641367 ), | |
vec2( 0.14383161, -0.14100790 ) | |
); | |
const int SAMPLES = 10; | |
float linear(sampler2D sampler, vec2 uv) { | |
float n = 1.0; | |
float f = 1000.0; | |
float z = texture2D(sampler, uv).x; | |
return (2.0 * n) / (f + n - z * (f - n)); | |
} | |
float rand(vec2 co){ | |
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); | |
} | |
void main() { | |
vec4 diffuse = texture2D(u_diffuse, v_uv); | |
vec4 normal = texture2D(u_normal, v_uv); | |
float depth = linear(u_depth, v_uv); | |
vec3 rand = vec3(rand(v_uv), rand(1. - v_uv), rand(.5 * v_uv)) * .6; | |
vec3 pos = vec3(v_uv.xy, depth); | |
vec3 norm = normal.xyz; | |
vec3 tangent = normalize(rand - norm * dot(rand, norm)); | |
vec3 bitangent = cross(norm, tangent); | |
mat3 tbn = mat3(tangent, bitangent, norm); | |
float ambientOcclusion = 0; | |
// perform AO | |
for (int i = 0; i < 10; ++i) { | |
vec2 sampleTexCoord = v_uv + (rvalues[i] * (radius)) ; | |
float sampleDepth = linear(u_depth, sampleTexCoord); | |
vec3 samplePos = vec3(v_uv.xy, sampleDepth); | |
vec3 sampleDir = normalize(samplePos - pos); | |
float NdotS = max(dot(norm, sampleDir), 0); | |
float VPdistSP = distance(pos, samplePos); | |
float a = 1.0 - smoothstep(total_strength, total_strength * 2, VPdistSP); | |
float b = NdotS; | |
ambientOcclusion += (a * b); | |
} | |
vec3 ao =vec3((ambientOcclusion / 10)); | |
gl_FragColor = vec4(ao, 1.) * diffuse; | |
/*float occlusion = 0.; | |
float radius_depth = radius / depth; | |
for (int i = 0; i < SAMPLES; i++) { | |
vec3 ray = radius_depth * reflect(rvalues[i], rand); | |
vec3 hemi_ray = pos + sign(dot(ray, norm)) * ray; | |
float occluder_depth = linear(u_depth, clamp(hemi_ray.xy, 0., 1.)); | |
float difference = depth - occluder_depth; | |
occlusion += step(falloff, difference) * (1. - smoothstep(falloff, area, difference)); | |
} | |
float ao = 1. - total_strength * occlusion * (1. / SAMPLES); | |
gl_FragColor = vec4(vec3(clamp(ao, 0., 1.)), 1.) * diffuse;*/ | |
} | |
); | |
#pragma mark - | |
Game::Game(int width, int height) { | |
controller = 0; | |
glGenFramebuffers(1, &fbo); | |
glGenBuffers(1, &quad_vbo); | |
glGenTextures(1, &t_col); | |
glGenTextures(1, &t_depth); | |
glGenTextures(1, &t_norm); | |
shader_default = glutil::make_shader_source(vs_default, fs_default); | |
glUseProgram(shader_default); | |
a_default_coord = glGetAttribLocation(shader_default, "a_coord"); | |
u_default_texture = glGetUniformLocation(shader_default, "u_texture"); | |
shader_ssao = glutil::make_shader_source(vs_ssao, fs_ssao); | |
glUseProgram(shader_ssao); | |
a_ssao_coord = glGetAttribLocation(shader_ssao, "a_coord"); | |
u_ssao_diffuse = glGetUniformLocation(shader_ssao, "u_diffuse"); | |
u_ssao_normal = glGetUniformLocation(shader_ssao, "u_normal"); | |
u_ssao_depth = glGetUniformLocation(shader_ssao, "u_depth"); | |
u_ssao_inv = glGetUniformLocation(shader_ssao, "u_inv_mat"); | |
reshape(width, height); | |
proj = glm::perspective(45.0f, 1.0f * w / h, 0.01f, 1000.0f); | |
position = glm::vec3(0, CY + 1, 0); | |
angle = glm::vec3(0, -0.5, 0); | |
update_camera(); | |
world = new SuperChunk(); | |
} | |
Game::~Game() { | |
glDeleteFramebuffers(1, &fbo); | |
glDeleteBuffers(1, &quad_vbo); | |
glDeleteShader(shader_default); | |
glDeleteShader(shader_ssao); | |
delete world; | |
} | |
void Game::reshape(int width, int height) { | |
w = width; | |
h = height; | |
glViewport(0, 0, w, h); | |
GLfloat data[4][4] = { | |
{-1., 1., 0., 1.}, | |
{-1., -1., 0., 0.}, | |
{1., -1., 1., 0.}, | |
{1., 1., 1., 1.} | |
}; | |
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); | |
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), data, GL_STREAM_DRAW); | |
glBindTexture(GL_TEXTURE_2D, t_col); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
glBindTexture(GL_TEXTURE_2D, t_norm); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
glBindTexture(GL_TEXTURE_2D, t_depth); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); | |
} | |
void Game::update() { | |
glm::vec2 left_axis(0.f); | |
glm::vec2 right_axis(0.f); | |
if (glfwJoystickPresent(controller)) { | |
//const char* name = glfwGetJoystickName(controller); | |
//printf("Controller: %s\n", name); | |
int axis_count; | |
const float* axis = glfwGetJoystickAxes(controller, &axis_count); | |
if (axis_count) { | |
left_axis.x = axis[0]; | |
if (fabs(left_axis.x) < 0.05) left_axis.x = 0; | |
left_axis.y = axis[1]; | |
if (fabs(left_axis.y) < 0.05) left_axis.y = 0; | |
right_axis.x = axis[2]; | |
if (fabs(right_axis.x) < 0.05) right_axis.x = 0; | |
right_axis.y = axis[3]; | |
if (fabs(right_axis.y) < 0.05) right_axis.y = 0; | |
/*for (int i = 0; i < axis_count; i++) { | |
printf("Axis %i: %f\n", i, axis[i]); | |
}*/ | |
} | |
int button_count; | |
const unsigned char* buttons = glfwGetJoystickButtons(controller, &button_count); | |
/*if (button_count) { | |
for (int i = 0; i < button_count; i++) { | |
if (buttons[i]) printf("[#%i: %i] ", i, buttons[i]); | |
} | |
printf("\n"); | |
}*/ | |
} | |
float lookspeed = 0.025f; | |
angle.x -= right_axis.x * lookspeed; | |
angle.y -= right_axis.y * lookspeed; | |
float movespeed = 0.25f; | |
glm::vec3 forward_dir = glm::vec3(sinf(angle.x), sinf(angle.y), cosf(angle.x)); | |
glm::vec3 right_dir = glm::vec3(-forward_dir.z, 0, forward_dir.x); | |
position += left_axis.x * right_dir * movespeed; | |
position -= left_axis.y * forward_dir * movespeed; | |
update_camera(); | |
} | |
void Game::update_camera() { | |
forward.x = sinf(angle.x); | |
forward.y = 0; | |
forward.z = cosf(angle.x); | |
right.x = -cosf(angle.x); | |
right.y = 0; | |
right.z = sinf(angle.x); | |
lookat.x = sinf(angle.x) * cosf(angle.y); | |
lookat.y = sinf(angle.y); | |
lookat.z = cosf(angle.x) * cosf(angle.y); | |
up = glm::cross(right, lookat); | |
view = glm::lookAt(position, position + lookat, up); | |
} | |
void Game::render() { | |
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; | |
glViewport(0, 0, w, h); | |
glBindFramebuffer(GL_FRAMEBUFFER, fbo); | |
glDrawBuffers(2, buffers); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_col, 0); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, t_norm, 0); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, t_depth, 0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
world->render(proj, view); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glUseProgram(shader_ssao); | |
glEnableVertexAttribArray(a_ssao_coord); | |
glUniform1i(u_ssao_diffuse, 2); | |
glUniform1i(u_ssao_normal, 1); | |
glUniform1i(u_ssao_depth, 0); | |
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, t_col); | |
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, t_norm); | |
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, t_depth); | |
glEnable(GL_TEXTURE_2D); | |
glDisable(GL_DEPTH_TEST); | |
glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); | |
glVertexAttribPointer(a_default_coord, 4, GL_FLOAT, GL_FALSE, 0, (void*)0); | |
glDrawArrays(GL_QUADS, 0, 4); | |
glDisableVertexAttribArray(a_ssao_coord); | |
} | |
void Game::mouse(int button, int state, int x, int y) { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __GAME_H__ | |
#define __GAME_H__ | |
#include <iostream> | |
#include <vector> | |
#include "glutil.h" | |
#define SCX 8 | |
#define SCY 1 | |
#define SCZ 8 | |
#define CX 16 | |
#define CY 16 | |
#define CZ 16 | |
typedef glm::detail::tvec4<GLbyte> vec4b; | |
typedef glm::detail::tvec3<GLbyte> vec3b; | |
class Chunk { | |
public: | |
Chunk(int x, int y, int z); | |
~Chunk(); | |
uint8_t get(int x, int y, int z); | |
void set(int x, int y, int z, uint8_t type); | |
void reshape(); | |
void render(GLuint coord, GLuint normal); | |
Chunk *left, *right, *top, *bottom, *front, *back; | |
private: | |
uint8_t contents[CX][CY][CZ]; | |
GLuint vbo; | |
int count, cx, cy, cz; | |
bool dirty; | |
}; | |
class SuperChunk { | |
public: | |
SuperChunk(); | |
~SuperChunk(); | |
uint8_t get(int x, int y, int z); | |
void set(int x, int y, int z, uint8_t type); | |
void render(const glm::mat4 &proj, const glm::mat4 &view); | |
private: | |
Chunk* chunks[SCX][SCY][SCZ]; | |
GLuint shader; | |
GLuint a_coord, a_normal, u_mvp, u_model, u_view; | |
const static char* fs; | |
const static char* vs; | |
}; | |
class Game { | |
public: | |
Game(int width, int height); | |
~Game(); | |
void reshape(int width, int height); | |
void update(); | |
void update_camera(); | |
void render(); | |
void mouse(int button, int state, int x, int y); | |
int w, h; | |
int move; | |
int controller; | |
private: | |
SuperChunk* world; | |
GLuint shader_ssao, shader_default, quad_vbo, fbo, t_depth, t_col, t_norm; | |
GLuint u_default_texture, u_ssao_normal, u_ssao_depth, u_ssao_diffuse, u_ssao_inv; | |
GLuint a_default_coord, a_ssao_coord, a_ssao_uv; | |
glm::mat4 proj; | |
glm::mat4 view; | |
glm::vec3 position; | |
glm::vec3 forward; | |
glm::vec3 right; | |
glm::vec3 up; | |
glm::vec3 lookat; | |
glm::vec3 angle; | |
const static char* fs_ssao; | |
const static char* vs_ssao; | |
const static char* fs_default; | |
const static char* vs_default; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment