#include "common.h"
#include "model.h"
+#include "shaders/blit.h"
+#include "shaders/standard.h"
+#include "shaders/vblend.h"
+#include "shaders/unlit.h"
+
static void render_water_texture( m4x3f camera );
static void render_water_surface( m4x4f pv, m4x3f camera );
static void render_world( m4x4f projection, m4x3f camera );
#ifndef RENDER_H
#define RENDER_H
+struct framebuffer
+{
+ GLuint fb, colour, rb;
+ int div;
+ GLuint format;
+
+ int allocated;
+};
+
static struct pipeline
{
float fov;
GLuint fb_depthmap, rgb_depthmap;
GLuint ubo_world_lighting,
ubo_world;
+
+ int ready;
}
gpipeline =
{
&gpipeline.ub_world_lighting );
}
-static void render_alloc_ub(void)
-{
- glGenBuffers( 1, &gpipeline.ubo_world_lighting );
- glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting );
- glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting),
- NULL, GL_DYNAMIC_DRAW );
-
- render_update_lighting_ub();
- glBindBufferBase( GL_UNIFORM_BUFFER, 0, gpipeline.ubo_world_lighting );
-}
-
/*
* Framebuffers
*/
-struct framebuffer
-{
- GLuint fb, colour, rb;
- int div;
- GLuint format;
-};
static void fb_use( struct framebuffer *fb )
{
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, fb->rb );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+ VG_CHECK_GL_ERR();
+ fb->allocated = 1;
+}
+
+static void fb_free( struct framebuffer *fb )
+{
+ glDeleteTextures( 1, &fb->colour );
+ glDeleteFramebuffers( 1, &fb->fb );
}
static void fb_bindtex( struct framebuffer *fb, int texture )
static void fb_resize( struct framebuffer *fb )
{
+ if( !fb->allocated )
+ return;
+
i32 ix = vg_window_x / fb->div,
iy = vg_window_y / fb->div;
static void render_fb_resize(void)
{
- glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 0,
- GL_RGB, GL_UNSIGNED_BYTE, NULL );
+ if( gpipeline.ready )
+ {
+ glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, NULL );
+ }
}
-/*
- * Vg
- */
-static void render_init(void)
+/* used for drawing player onto */
+static void render_init_temp_buffer(void)
{
+ vg_info( "[render] Allocate temporary framebuffer\n" );
+
glGenFramebuffers( 1, &gpipeline.fb_background );
glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
GL_TEXTURE_2D,
gpipeline.rgb_background, 0);
- /*
- * World depth map, maybe this should be moved to world.h
- * TODO: review
- */
+ VG_CHECK_GL_ERR();
+}
+
+/* used for drawing world depth from the top view, used in our water and
+ * lighting calculations */
+static void render_init_depthmap_buffer(void)
+{
+ vg_info( "[render] Allocate depth map buffer\n" );
+
glGenFramebuffers( 1, &gpipeline.fb_depthmap );
glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_depthmap );
GL_TEXTURE_2D,
gpipeline.rgb_depthmap, 0);
+ VG_CHECK_GL_ERR();
+}
+
+static void render_init_fs_quad(void)
+{
+ vg_info( "[render] Allocate quad\n" );
+
float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE,
sizeof(float)*2, (void*)0 );
glEnableVertexAttribArray( 0 );
- VG_CHECK_GL();
- render_alloc_ub();
+ VG_CHECK_GL_ERR();
}
-static void render_free(void)
+static void render_init_uniform_buffers(void)
{
- /* TODO: ... */
+ vg_info( "[render] Allocate uniform buffer\n" );
+
+ glGenBuffers( 1, &gpipeline.ubo_world_lighting );
+ glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting );
+ glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting),
+ NULL, GL_DYNAMIC_DRAW );
+
+ render_update_lighting_ub();
+ glBindBufferBase( GL_UNIFORM_BUFFER, 0, gpipeline.ubo_world_lighting );
+
+ VG_CHECK_GL_ERR();
+}
+
+static void render_init(void)
+{
+ shader_blit_register();
+ shader_standard_register();
+ shader_vblend_register();
+ shader_unlit_register();
+
+ vg_acquire_thread_sync();
+ {
+ render_init_temp_buffer();
+ render_init_depthmap_buffer();
+ render_init_fs_quad();
+ render_init_uniform_buffers();
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ gpipeline.ready = 1;
+ }
+
+ vg_release_thread_sync();
+}
+
+static void render_free(void *_)
+{
+ glDeleteBuffers( 1, &gpipeline.ubo_world_lighting );
+
+ glDeleteVertexArrays( 1, &gpipeline.fsquad.vao );
+ glDeleteBuffers( 1, &gpipeline.fsquad.vbo );
+
+ glDeleteFramebuffers( 1, &gpipeline.fb_depthmap );
+ glDeleteTextures( 1, &gpipeline.rgb_depthmap );
+
+ glDeleteFramebuffers( 1, &gpipeline.fb_background );
+ glDeleteTextures( 1, &gpipeline.rgb_background );
}
/*