commit eefb282c5d136f8638984151591800290f547d42
parent 90c4b692bc865eeb92e8f2d92010ed80419d0b2b
Author: William Casarin <jb55@jb55.com>
Date: Sat, 27 Oct 2018 21:17:32 -0700
fbos working
Diffstat:
23 files changed, 202 insertions(+), 57 deletions(-)
diff --git a/etc/shaders/ui.f.glsl b/etc/shaders/ui.f.glsl
@@ -3,9 +3,13 @@
precision mediump float;
in vec3 v_color;
+in vec2 v_tex_coords;
+
out vec4 fragmentColor;
+uniform sampler2D screen_texture;
+
void main() {
// fragmentColor = vec4(color + diffuse, 1.0);
- fragmentColor = vec4(v_color, 1.0);
+ fragmentColor = texture(screen_texture, v_tex_coords) + vec4(v_color, 1.0) * 0.00001;
}
diff --git a/etc/shaders/ui.v.glsl b/etc/shaders/ui.v.glsl
@@ -2,21 +2,21 @@
in vec3 position;
in vec3 color;
+in vec2 tex_coords;
out vec3 v_color;
+out vec2 v_tex_coords;
uniform mat4 mvp;
uniform vec2 uipos;
uniform vec2 uisize;
-uniform sampler2D texture1;
-
void main()
{
- vec2 v2_pos = uipos + uisize * (position.xy - vec2(0.5, 0.5)) - (1.0 - uisize);
+ vec2 v2_pos = uipos + uisize * (position.xy - vec2(0.5, 0.5));
vec4 v4_pos = vec4(v2_pos, 0.0, 1.0) ;
gl_Position = mvp * v4_pos;
-
- v_color = color + position;
+ v_tex_coords = tex_coords;
+ v_color = color + v4_pos.xyz;
}
diff --git a/src/buffer.c b/src/buffer.c
@@ -43,14 +43,22 @@ void bind_ibo(struct vbo *vbo) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle);
}
-void bind_vbo(struct vbo *vbo, gpu_addr slot) {
+static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot, int size) {
glEnableVertexAttribArray(slot);
glBindBuffer(vbo->type, vbo->handle);
glVertexAttribPointer(slot, // attribute
- 3, // size
+ size, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
}
+
+void bind_uv_vbo(struct vbo *vbo, gpu_addr slot) {
+ bind_vbo_internal(vbo, slot, 2);
+}
+
+void bind_vbo(struct vbo *vbo, gpu_addr slot) {
+ bind_vbo_internal(vbo, slot, 3);
+}
diff --git a/src/buffer.h b/src/buffer.h
@@ -10,6 +10,7 @@ struct attributes {
gpu_addr position;
gpu_addr normal;
gpu_addr color;
+ gpu_addr tex_coord;
};
struct vbo {
@@ -31,6 +32,7 @@ struct vbo *
make_index_buffer(GLenum target, const void *buffer_data,
GLsizei buffer_size, struct vbo *vbo);
+void bind_uv_vbo(struct vbo *vbo, gpu_addr slot);
void bind_vbo(struct vbo *vbo, gpu_addr slot);
void bind_ibo(struct vbo *vbo);
diff --git a/src/event.c b/src/event.c
@@ -4,20 +4,19 @@
#include "input.h"
#include "game.h"
-void process_events(struct ui *ui, float *camera, struct input *input) {
+void process_events(struct game *game, float *camera) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
case SDL_KEYUP:
- handle_key(input, event.key);
+ handle_key(&game->input, event.key);
break;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
- handle_resize(camera, event.window.data1, event.window.data2);
- resize_ui(ui, event.window.data1, event.window.data2);
+ handle_resize(game, event.window.data1, event.window.data2);
break;
}
break;
diff --git a/src/event.h b/src/event.h
@@ -4,8 +4,8 @@
#include "gl.h"
#include "input.h"
-#include "ui.h"
+#include "game.h"
-void process_events(struct ui *ui, float *camera, struct input *input);
+void process_events(struct game *game, float *camera);
#endif /* PA_EVENT_H */
diff --git a/src/fbo.c b/src/fbo.c
@@ -8,6 +8,7 @@ void create_fbo(struct fbo *fbo, int width, int height) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle);
check_gl();
+ fbo->n_attachments = 0;
fbo->width = width;
fbo->height = height;
}
@@ -35,6 +36,13 @@ int fbo_attach_renderbuffer(struct fbo *fbo,
return *rbo;
}
+void init_fbo(struct fbo *fbo) {
+ fbo->n_attachments = 0;
+ fbo->handle = 0;
+ fbo->width = 0;
+ fbo->height = 0;
+}
+
int fbo_attach_texture(struct fbo *fbo, GLenum attachment) {
assert(fbo->n_attachments < MAX_FBO_ATTACHMENTS);
GLuint *texture = &fbo->attachments[fbo->n_attachments++];
@@ -71,6 +79,8 @@ void fbo_check(struct fbo *fbo) {
}
void delete_fbo(struct fbo *fbo) {
+ // TODO: delete attachments
+
glDeleteFramebuffers(1, &fbo->handle);
check_gl();
}
diff --git a/src/fbo.h b/src/fbo.h
@@ -13,6 +13,7 @@ struct fbo {
int width, height;
};
+void init_fbo(struct fbo *fbo);
void bind_fbo(struct fbo *fbo);
void create_fbo(struct fbo *fbo, int width, int height);
int fbo_attach_texture(struct fbo *, GLenum attachment);
diff --git a/src/game.c b/src/game.c
@@ -6,6 +6,7 @@
#include "terrain.h"
#include "render.h"
#include "util.h"
+#include "update.h"
#include <assert.h>
mat4 *cam_init = (float[16]){
@@ -31,6 +32,7 @@ void game_init(struct game *game, int width, int height) {
mat4 *mvp = res->test_mvp;
struct node *root = &res->root;
struct node *camera = &res->camera;
+ struct node *alt_camera = &res->alt_camera;
struct entity *player = &res->player;
struct terrain *terrain = &game->terrain;
mat4 *light_dir = res->light_dir;
@@ -51,6 +53,16 @@ void game_init(struct game *game, int width, int height) {
.scale = 1.0
};
+ // default ortho screenspace projection
+ mat4_ortho(0.0, // left
+ width, // right
+ 0.0, // bottom
+ height, // top
+ 0.0, // near
+ 100000.0, // far
+ res->proj_ortho
+ );
+
create_ui(&game->ui, width, height);
check_gl();
@@ -68,12 +80,21 @@ void game_init(struct game *game, int width, int height) {
light_dir[1] = 0.8;
light_dir[2] = 0.8;
+ // BRB: shadow mapping next!
+
+ // FBO STUFF
+ init_fbo(&res->shadow_buffer);
+ resize_fbos(game, width, height);
+
+ // FBO STUFF END
+
game->test_resources.fog_on = 1;
game->test_resources.diffuse_on = 0;
node_init(root);
node_init(&player->node);
node_init(camera);
+ node_init(alt_camera);
node_init(&terrain->entity.node);
// player init
@@ -88,18 +109,17 @@ void game_init(struct game *game, int width, int height) {
node_attach(&player->node, root);
node_attach(camera, &player->node);
+ node_attach(alt_camera, camera);
quat_axis_angle(V3(1,0,0), -45, camera->orientation);
-
- /* camera->custom_update = camera_update; */
- /* camera->custom_update_data = (void*)game->test_resources.camera_persp; */
-
- /* vec3_all(camera->scale, -1); */
- /* camera->mirrored = 1; */
+ /* quat_axis_angle(V3(1,0,0), -45, alt_camera->orientation); */
node_translate(&player->node, V3(terrain->size/2.,terrain->size/2.,0.0));
/* vec3_scale(player->node.scale, 10.0, player->node.scale); */
+ node_rotate(alt_camera, V3(0, 0, 0));
+ /* node_translate(alt_camera, V3(0,60,-100)); */
+
node_rotate(camera, V3(100, 0, 0));
node_translate(camera, V3(0,-40,20));
/* node_recalc(camera); */
diff --git a/src/game.h b/src/game.h
@@ -10,6 +10,7 @@
#include "entity.h"
#include "terrain.h"
#include "ui.h"
+#include "fbo.h"
#define PLAYER_HEIGHT 1.73
@@ -19,6 +20,7 @@
*/
struct resources {
struct vbo vertex_buffer, element_buffer, normal_buffer;
+ struct fbo shadow_buffer;
struct gpu_program program;
struct gpu_program smooth_program;
@@ -43,13 +45,15 @@ struct resources {
struct node root;
struct entity player;
struct node camera;
+ struct node alt_camera;
bool fog_on, diffuse_on;
float test_mvp[MAT4_ELEMS];
float light_dir[3];
float light_intensity[3];
- float camera_persp[MAT4_ELEMS];
+ float proj_persp[MAT4_ELEMS];
+ float proj_ortho[MAT4_ELEMS];
};
struct game {
diff --git a/src/geometry.c b/src/geometry.c
@@ -9,7 +9,8 @@ destroy_buffer_geometry(struct geometry *geom) {
geom->vbos.vertex.handle,
geom->vbos.normal.handle,
geom->vbos.color.handle,
- geom->vbos.index.handle
+ geom->vbos.index.handle,
+ geom->vbos.tex_coord.handle
};
/* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */
/* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */
@@ -35,6 +36,10 @@ void render_geometry(struct geometry *geom, struct attributes *attrs)
bind_vbo(&geom->vbos.color, attrs->color);
check_gl();
}
+ if (geom->vbos.tex_coord.handle) {
+ bind_uv_vbo(&geom->vbos.tex_coord, attrs->tex_coord);
+ check_gl();
+ }
bind_ibo(&geom->vbos.index);
check_gl();
@@ -51,7 +56,9 @@ void init_geometry(struct geometry *geom) {
geom->colors = NULL;
geom->vbos.color.handle = 0;
geom->normals = NULL;
+ geom->tex_coords = NULL;
geom->vbos.normal.handle = 0;
+ geom->vbos.tex_coord.handle = 0;
}
void
@@ -90,6 +97,20 @@ make_buffer_geometry(struct geometry *geom) {
&geom->vbos.color
);
+ if (geom->tex_coords != NULL) {
+ printf("%f %f %f %f\n",
+ geom->tex_coords[0],
+ geom->tex_coords[1],
+ geom->tex_coords[2],
+ geom->tex_coords[3]
+ );
+
+ make_vertex_buffer(GL_ARRAY_BUFFER,
+ geom->tex_coords,
+ geom->num_verts * 2 * (int)sizeof(*geom->tex_coords),
+ &geom->vbos.tex_coord);
+ }
+
/* printf("making index buffer\n"); */
// cube indices
make_index_buffer(
diff --git a/src/geometry.h b/src/geometry.h
@@ -10,6 +10,7 @@ struct buffer_geometry {
struct vbo index;
struct vbo normal;
struct vbo color;
+ struct vbo tex_coord;
};
struct geometry {
@@ -20,6 +21,7 @@ struct geometry {
float *normals;
u32 *indices;
float *colors;
+ float *tex_coords;
};
void render_geometry(struct geometry *geom, struct attributes *);
diff --git a/src/gl.h b/src/gl.h
@@ -88,7 +88,7 @@ void glFramebufferRenderbuffer( GLenum target,
GLuint renderbuffer);
-
-
+void glDeleteRenderbuffers( GLsizei n,
+ GLuint *renderbuffers);
#endif /* POLYADVENT_GL_H */
diff --git a/src/main.c b/src/main.c
@@ -17,6 +17,7 @@
#include "poisson.h"
#include "uniform.h"
#include "ply.h"
+#include "fbo.h"
int main(void)
@@ -43,13 +44,34 @@ int main(void)
check_gl();
u32 last = SDL_GetTicks();
+ struct render_config fbo_render_config = {
+ .draw_ui = 0,
+ .camera = game.test_resources.camera.mat,
+ .projection = game.test_resources.proj_persp
+ };
+
+ struct render_config default_config = {
+ .draw_ui = 1,
+ .camera = game.test_resources.camera.mat,
+ .projection = game.test_resources.proj_persp
+ };
+
while (1) {
- process_events(&game.ui, game.test_resources.camera_persp, &game.input);
+ process_events(&game, game.test_resources.proj_persp);
u32 ticks = SDL_GetTicks();
update(&game, ticks-last);
last = ticks;
- render(&game);
+
+ GLuint texture = game.test_resources.shadow_buffer.attachments[0];
+ struct fbo *fbo = &game.test_resources.shadow_buffer;
+ bind_fbo(fbo);
+
+ /* glViewport( 0, 0, width, height ); */
+
+ render(&game, &fbo_render_config);
+ unbind_fbo(&game.test_resources.shadow_buffer);
+ render(&game, &default_config);
/* Swap front and back buffers */
SDL_GL_SwapWindow(window);
diff --git a/src/model.c b/src/model.c
@@ -8,6 +8,8 @@ int load_model(struct model *model, const char *name) {
int ok = 0;
+ init_geometry(&model->geom);
+
// Load mesh
snprintf(path, 128, "data/models/%s.ply", name);
ok = parse_ply(path, &model->geom);
diff --git a/src/render.c b/src/render.c
@@ -78,7 +78,7 @@ init_gl(struct resources *resources, int width, int height) {
(float)width / height,
1,
5000,
- resources->camera_persp);
+ resources->proj_persp);
// Shader program
ok = make_program(&terrain_vertex, &fragment, &resources->terrain_program);
@@ -152,7 +152,7 @@ recalc_normals(GLint nm_uniform, mat4 *model_view, mat4 *normal) {
-void render (struct game *game) {
+void render (struct game *game, struct render_config *config) {
float adjust = game->test_resources.light_intensity[0];
glEnable(GL_DEPTH_TEST);
glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black
@@ -169,11 +169,11 @@ void render (struct game *game) {
struct resources *res = &game->test_resources;
mat4 *mvp = res->test_mvp;
- mat4 *persp = res->camera_persp;
+ mat4 *projection = config->projection;
mat4 *light = res->light_dir;
mat4 *light_intensity = res->light_intensity;
- struct node *camera = &res->camera;
+ float *camera = config->camera;
struct entity *entities[] =
{ &game->terrain.entity
@@ -189,13 +189,13 @@ void render (struct game *game) {
glUseProgram(game->test_resources.program.handle);
check_gl();
- mat4_inverse(camera->mat, view);
- mat4_multiply(persp, view, view_proj);
+ mat4_inverse(camera, view);
+ mat4_multiply(projection, view, view_proj);
glUniform3f(res->uniforms.camera_position,
- camera->mat[M_X],
- camera->mat[M_Y],
- camera->mat[M_Z]);
+ camera[M_X],
+ camera[M_Y],
+ camera[M_Z]);
glUniform1i(res->uniforms.fog_on, res->fog_on);
glUniform1i(res->uniforms.diffuse_on, res->diffuse_on);
@@ -217,7 +217,8 @@ void render (struct game *game) {
check_gl();
}
- render_ui(&game->ui, view);
+ if (config->draw_ui)
+ render_ui(&game->ui, view);
//player
// y tho
diff --git a/src/render.h b/src/render.h
@@ -5,8 +5,14 @@
struct game;
+struct render_config {
+ int draw_ui;
+ float *camera;
+ float *projection;
+};
+
void init_gl(struct resources *resources, int width, int height);
-void render (struct game *game);
+void render (struct game *game, struct render_config *config);
void wireframe_mode_on();
void wireframe_mode_off();
diff --git a/src/ui.c b/src/ui.c
@@ -25,12 +25,22 @@ static GLfloat quad_normals[] = {
static GLuint quad_indices[] = {0, 1, 2, 0, 2, 3};
+static GLfloat quad_uvs[] =
+{
+ 1.0, 1.0, // v0
+ 0.0, 1.0, // v1
+ 0.0, 0.0, // v2
+ 1.0, 0.0, // v3
+};
+
+
static void create_quad(struct geometry *geom)
{
init_geometry(geom);
geom->indices = quad_indices;
geom->vertices = quad_vertices;
geom->colors = quad_normals;
+ geom->tex_coords = quad_uvs;
geom->num_indices = ARRAY_SIZE(quad_indices);
geom->num_verts = ARRAY_SIZE(quad_vertices);
make_buffer_geometry(geom);
@@ -44,16 +54,17 @@ void render_ui(struct ui *ui, float *view) {
check_gl();
float uipos[2] = {0.01, 0.01};
- float uisize[2] = {0.2, 0.2};
+ float uisize[2] = {0.4, 0.4};
mat4_multiply(ui->ortho, view, mvp);
// setup camera for shader
/* glUniform2f(ui->uipos_uniform, uipos[0] * uisize[0], uipos[1] * uisize[1]); */
- glUniform2f(ui->uipos_uniform, uipos[0], uipos[1]);
- glUniform2f(ui->uisize_uniform, uisize[0], uisize[1]);
+ glUniform2f(ui->uniforms.uipos, uipos[0], uipos[1]);
+ glUniform2f(ui->uniforms.uisize, uisize[0], uisize[1]);
+ glUniform1i(ui->uniforms.texture, 0);
- glUniformMatrix4fv(ui->mvp_uniform, 1, 0, ui->ortho);
+ glUniformMatrix4fv(ui->uniforms.mvp, 1, 0, ui->ortho);
check_gl();
// render quad
@@ -63,12 +74,12 @@ void render_ui(struct ui *ui, float *view) {
void resize_ui(struct ui *ui, int width, int height) {
- float left = 0;
+ float left = 0.0;
float right = 1.0;
- float bottom = 1.0;
- float top = 0;
- float near = 0.0;
- float far = 1.0;
+ float bottom = 0.0;
+ float top = 1.0;
+ float near = -1.0;
+ float far = 2.0;
mat4_ortho(left, right, bottom, top, near, far, ui->ortho);
}
@@ -93,13 +104,17 @@ void create_ui(struct ui *ui, int width, int height) {
GLuint program = ui->shader.handle;
- ui->mvp_uniform = glGetUniformLocation(program, "mvp");
- ui->uipos_uniform = glGetUniformLocation(program, "uipos");
- ui->uisize_uniform = glGetUniformLocation(program, "uisize");
+ ui->uniforms.mvp = glGetUniformLocation(program, "mvp");
+ ui->uniforms.uipos = glGetUniformLocation(program, "uipos");
+ ui->uniforms.uisize = glGetUniformLocation(program, "uisize");
+
+ ui->uniforms.texture =
+ glGetUniformLocation(program, "screen_texture");
/* ui->attrs.normal = (gpu_addr)glGetAttribLocation(program, "normal"); */
- ui->attrs.position = (gpu_addr)glGetAttribLocation(program, "position");
- ui->attrs.color = (gpu_addr)glGetAttribLocation(program, "color");
+ ui->attrs.position = (gpu_addr)glGetAttribLocation(program, "position");
+ ui->attrs.color = (gpu_addr)glGetAttribLocation(program, "color");
+ ui->attrs.tex_coord = (gpu_addr)glGetAttribLocation(program, "tex_coords");
check_gl();
resize_ui(ui, width, height);
diff --git a/src/ui.h b/src/ui.h
@@ -10,9 +10,14 @@ struct ui {
struct gpu_program shader;
struct geometry quad;
struct attributes attrs;
- GLint mvp_uniform;
- GLint uipos_uniform;
- GLint uisize_uniform;
+
+ struct ui_uniforms {
+ GLint mvp;
+ GLint uipos;
+ GLint uisize;
+ GLint texture;
+ } uniforms;
+
float ortho[MAT4_ELEMS];
};
diff --git a/src/update.c b/src/update.c
@@ -200,6 +200,22 @@ static int try_reload_shaders(struct resources *res) {
}
#endif
+void resize_fbos(struct game *game, int width, int height) {
+ struct resources *res = &game->test_resources;
+
+ if (res->shadow_buffer.handle) {
+ // TODO: remove once delete_fbo deletes attachments
+ glDeleteTextures(1, &res->shadow_buffer.attachments[1]);
+ glDeleteRenderbuffers(1, &res->shadow_buffer.attachments[0]);
+ delete_fbo(&res->shadow_buffer);
+ }
+
+ create_fbo(&res->shadow_buffer, width, height);
+ fbo_attach_renderbuffer(&res->shadow_buffer, GL_DEPTH24_STENCIL8,
+ GL_DEPTH_STENCIL_ATTACHMENT);
+ fbo_attach_texture(&res->shadow_buffer, GL_COLOR_ATTACHMENT0);
+}
+
// TODO: match based on some real concept of time
static void day_night_cycle(float n, struct resources *res) {
float darkest = 0.25;
diff --git a/src/update.h b/src/update.h
@@ -5,5 +5,6 @@
#include "game.h"
void update(struct game * game, u32 dt);
+void resize_fbos(struct game * game, int width, int height);
#endif /* PA_UPDATE_H */
diff --git a/src/window.c b/src/window.c
@@ -3,13 +3,18 @@
#include "gl.h"
#include "mat4.h"
#include "window.h"
+#include "game.h"
+#include "update.h"
void
-handle_resize(float *camera, int width, int height) {
+handle_resize(struct game *game, int width, int height) {
/* printf("resizing %d %d\n", width, height); */
glViewport( 0, 0, width, height );
- mat4_perspective(75 /* fov */, (float)width / height, 1, 20000, camera);
+ mat4_perspective(75 /* fov */, (float)width / height, 1, 20000,
+ game->test_resources.proj_persp);
+
+ resize_fbos(game, width, height);
/* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */
/* Set the camera perspective */
diff --git a/src/window.h b/src/window.h
@@ -3,9 +3,10 @@
#define POLYADVENT_WINDOW_H
#include "gl.h"
+#include "game.h"
void
-handle_resize(float *camera, int width, int height);
+handle_resize(struct game *game, int width, int height);
#endif /* POLYADVENT_WINDOW_H */