2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
8 #include "shaders/blit.h"
9 #include "shaders/blitblur.h"
10 #include "shaders/standard.h"
11 #include "shaders/vblend.h"
13 VG_STATIC
void render_water_texture( m4x3f camera
);
14 VG_STATIC
void render_water_surface( m4x4f pv
, m4x3f camera
);
15 VG_STATIC
void render_world( m4x4f projection
, m4x3f camera
);
16 VG_STATIC
void shader_link_standard_ub( GLuint shader
, int texture_id
);
17 VG_STATIC
void render_world_depth( m4x4f projection
, m4x3f camera
);
24 GLuint fb
, colour
, rb
;
31 VG_STATIC
struct pipeline
40 struct ub_world_lighting
43 v4f g_light_colours
[3],
44 g_light_directions
[3],
65 float shadow_spread
, shadow_length
;
67 GLuint fb_depthmap
, rgb_depthmap
;
68 GLuint ubo_world_lighting
,
79 .colour
= { 1.36f
, 1.35f
, 1.01f
},
80 .dir
= { 0.63f
, -0.08f
}
84 .colour
= { 0.33f
, 0.56f
, 0.64f
},
85 .dir
= { -2.60f
, -0.13f
}
89 .colour
= { 0.05f
, 0.05f
, 0.23f
},
90 .dir
= { 2.60f
, -0.84f
}
93 .shadow_spread
= 0.65f
,
94 .shadow_length
= 9.50f
,
98 .g_ambient_colour
= { 0.09f
, 0.03f
, 0.07f
}
106 * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
108 VG_STATIC
void plane_clip_projection( m4x4f mat
, v4f plane
)
112 (vg_signf(plane
[0]) + mat
[2][0]) / mat
[0][0],
113 (vg_signf(plane
[1]) + mat
[2][1]) / mat
[1][1],
115 (1.0f
+ mat
[2][2]) / mat
[3][2]
118 v4_muls( plane
, 2.0f
/ v4_dot(plane
,c
), c
);
122 mat
[2][2] = c
[2] + 1.0f
;
126 VG_STATIC
void pipeline_projection( m4x4f mat
, float nearz
, float farz
)
128 m4x4_projection( mat
,
130 (float)vg
.window_x
/ (float)vg
.window_y
,
137 VG_STATIC
void shader_link_standard_ub( GLuint shader
, int texture_id
)
139 GLuint idx
= glGetUniformBlockIndex( shader
, "ub_world_lighting" );
140 glUniformBlockBinding( shader
, idx
, 0 );
142 glActiveTexture( GL_TEXTURE0
+ texture_id
);
143 glBindTexture( GL_TEXTURE_2D
, gpipeline
.rgb_depthmap
);
144 glUniform1i( glGetUniformLocation( shader
, "g_world_depth" ), texture_id
);
147 VG_STATIC
void render_update_lighting_ub(void)
149 struct ub_world_lighting
*winf
= &gpipeline
.ub_world_lighting
;
152 for( int i
=0; i
<3; i
++ )
154 struct light_widget
*lw
= &gpipeline
.widgets
[i
];
158 float pitch
= lw
->dir
[0],
162 v3_copy( (v3f
){ xz
*cosf(yaw
), sinf(pitch
), xz
*sinf(yaw
) },
163 winf
->g_light_directions
[c
] );
164 v3_copy( lw
->colour
, winf
->g_light_colours
[c
] );
170 winf
->g_light_count
= c
;
171 winf
->g_light_directions
[0][3] = gpipeline
.shadow_length
;
172 winf
->g_light_colours
[0][3] = gpipeline
.shadow_spread
;
174 if( vg
.quality_profile
== k_quality_profile_low
)
175 winf
->g_shadow_samples
= 0;
177 winf
->g_shadow_samples
= 8;
179 glBindBuffer( GL_UNIFORM_BUFFER
, gpipeline
.ubo_world_lighting
);
180 glBufferSubData( GL_UNIFORM_BUFFER
, 0, sizeof(struct ub_world_lighting
),
181 &gpipeline
.ub_world_lighting
);
188 VG_STATIC
void fb_use( struct framebuffer
*fb
)
192 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
193 glViewport( 0, 0, vg
.window_x
, vg
.window_y
);
197 glBindFramebuffer( GL_FRAMEBUFFER
, fb
->fb
);
198 glViewport( 0, 0, vg
.window_x
/ fb
->div
, vg
.window_y
/ fb
->div
);
202 VG_STATIC
void fb_init( struct framebuffer
*fb
)
204 i32 ix
= vg
.window_x
/ fb
->div
,
205 iy
= vg
.window_y
/ fb
->div
;
207 glGenFramebuffers( 1, &fb
->fb
);
208 glBindFramebuffer( GL_FRAMEBUFFER
, fb
->fb
);
210 glGenTextures( 1, &fb
->colour
);
211 glBindTexture( GL_TEXTURE_2D
, fb
->colour
);
212 glTexImage2D( GL_TEXTURE_2D
, 0, fb
->format
, ix
, iy
,
213 0, fb
->format
, GL_UNSIGNED_BYTE
, NULL
);
215 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
216 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
217 glFramebufferTexture2D( GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
218 GL_TEXTURE_2D
, fb
->colour
, 0);
220 glGenRenderbuffers( 1, &fb
->rb
);
221 glBindRenderbuffer( GL_RENDERBUFFER
, fb
->rb
);
222 glRenderbufferStorage( GL_RENDERBUFFER
, GL_DEPTH24_STENCIL8
, ix
, iy
);
224 glFramebufferRenderbuffer( GL_FRAMEBUFFER
, GL_DEPTH_STENCIL_ATTACHMENT
,
225 GL_RENDERBUFFER
, fb
->rb
);
226 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
232 VG_STATIC
void fb_free( struct framebuffer
*fb
)
234 glDeleteTextures( 1, &fb
->colour
);
235 glDeleteFramebuffers( 1, &fb
->fb
);
238 VG_STATIC
void fb_bindtex( struct framebuffer
*fb
, int texture
)
240 glActiveTexture( GL_TEXTURE0
+ texture
);
241 glBindTexture( GL_TEXTURE_2D
, fb
->colour
);
244 VG_STATIC
void fb_resize( struct framebuffer
*fb
)
249 i32 ix
= vg
.window_x
/ fb
->div
,
250 iy
= vg
.window_y
/ fb
->div
;
252 glBindTexture( GL_TEXTURE_2D
, fb
->colour
);
253 glTexImage2D( GL_TEXTURE_2D
, 0, fb
->format
, ix
, iy
, 0,
254 fb
->format
, GL_UNSIGNED_BYTE
, NULL
);
256 glBindRenderbuffer( GL_RENDERBUFFER
, fb
->rb
);
257 glRenderbufferStorage( GL_RENDERBUFFER
, GL_DEPTH24_STENCIL8
, ix
, iy
);
260 VG_STATIC
void render_fb_resize(void)
262 if( gpipeline
.ready
)
264 glBindTexture( GL_TEXTURE_2D
, gpipeline
.rgb_background
);
265 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGB
, vg
.window_x
, vg
.window_y
, 0,
266 GL_RGB
, GL_UNSIGNED_BYTE
, NULL
);
270 /* used for drawing player onto */
271 VG_STATIC
void render_init_temp_buffer(void)
273 vg_info( "[render] Allocate temporary framebuffer\n" );
275 glGenFramebuffers( 1, &gpipeline
.fb_background
);
276 glBindFramebuffer( GL_FRAMEBUFFER
, gpipeline
.fb_background
);
278 glGenTextures( 1, &gpipeline
.rgb_background
);
279 glBindTexture( GL_TEXTURE_2D
, gpipeline
.rgb_background
);
280 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGB
, vg
.window_x
, vg
.window_y
,
281 0, GL_RGB
, GL_UNSIGNED_BYTE
, NULL
);
283 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
284 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
285 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
286 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
287 glFramebufferTexture2D( GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
289 gpipeline
.rgb_background
, 0);
294 /* used for drawing world depth from the top view, used in our water and
295 * lighting calculations */
296 VG_STATIC
void render_init_depthmap_buffer(void)
298 vg_info( "[render] Allocate depth map buffer\n" );
300 glGenFramebuffers( 1, &gpipeline
.fb_depthmap
);
301 glBindFramebuffer( GL_FRAMEBUFFER
, gpipeline
.fb_depthmap
);
303 glGenTextures( 1, &gpipeline
.rgb_depthmap
);
304 glBindTexture( GL_TEXTURE_2D
, gpipeline
.rgb_depthmap
);
305 glTexImage2D( GL_TEXTURE_2D
, 0, GL_R32F
, 1024, 1024, 0,
306 GL_RED
, GL_FLOAT
, NULL
);
307 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
308 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
311 glFramebufferTexture2D( GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
313 gpipeline
.rgb_depthmap
, 0);
318 VG_STATIC
void render_init_fs_quad(void)
320 vg_info( "[render] Allocate quad\n" );
322 float quad
[] = { 0.0f
, 0.0f
, 1.0f
, 1.0f
, 0.0f
, 1.0f
,
323 0.0f
, 0.0f
, 1.0f
, 0.0f
, 1.0f
, 1.0f
,
325 0.2f
, 0.0f
, 0.8f
, 1.0f
, 0.2f
, 1.0f
,
326 0.2f
, 0.0f
, 0.8f
, 0.0f
, 0.8f
, 1.0f
};
328 glGenVertexArrays( 1, &gpipeline
.fsquad
.vao
);
329 glGenBuffers( 1, &gpipeline
.fsquad
.vbo
);
330 glBindVertexArray( gpipeline
.fsquad
.vao
);
331 glBindBuffer( GL_ARRAY_BUFFER
, gpipeline
.fsquad
.vbo
);
332 glBufferData( GL_ARRAY_BUFFER
, sizeof(quad
), quad
, GL_STATIC_DRAW
);
333 glBindVertexArray( gpipeline
.fsquad
.vao
);
334 glVertexAttribPointer( 0, 2, GL_FLOAT
, GL_FALSE
,
335 sizeof(float)*2, (void*)0 );
336 glEnableVertexAttribArray( 0 );
341 VG_STATIC
void render_init_uniform_buffers(void)
343 vg_info( "[render] Allocate uniform buffer\n" );
345 glGenBuffers( 1, &gpipeline
.ubo_world_lighting
);
346 glBindBuffer( GL_UNIFORM_BUFFER
, gpipeline
.ubo_world_lighting
);
347 glBufferData( GL_UNIFORM_BUFFER
, sizeof(struct ub_world_lighting
),
348 NULL
, GL_DYNAMIC_DRAW
);
350 render_update_lighting_ub();
351 glBindBufferBase( GL_UNIFORM_BUFFER
, 0, gpipeline
.ubo_world_lighting
);
356 VG_STATIC
void render_init(void)
358 shader_blit_register();
359 shader_blitblur_register();
360 shader_standard_register();
361 shader_vblend_register();
363 vg_acquire_thread_sync();
365 render_init_temp_buffer();
366 render_init_depthmap_buffer();
367 render_init_fs_quad();
368 render_init_uniform_buffers();
370 glBindFramebuffer( GL_FRAMEBUFFER
, 0 );
374 vg_release_thread_sync();
380 VG_STATIC
void render_fsquad(void)
382 glBindVertexArray( gpipeline
.fsquad
.vao
);
383 glDrawArrays( GL_TRIANGLES
, 0, 6 );
386 VG_STATIC
void render_fsquad1(void)
388 glBindVertexArray( gpipeline
.fsquad
.vao
);
389 glDrawArrays( GL_TRIANGLES
, 6, 6 );
392 #endif /* RENDER_H */