diff --git a/bind/v4k.lua b/bind/v4k.lua index f8ba368..ce12785 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1102,6 +1102,7 @@ typedef struct colormap_t { texture_t *texture; } colormap_t; bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ); + unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size); void fullscreen_quad_rgb( texture_t texture_rgb ); void fullscreen_quad_rgb_flipped( texture_t texture ); void fullscreen_quad_ycbcr( texture_t texture_YCbCr[3] ); diff --git a/engine/art/shaders/query_point_fs.glsl b/engine/art/shaders/query_point_fs.glsl new file mode 100644 index 0000000..775faf7 --- /dev/null +++ b/engine/art/shaders/query_point_fs.glsl @@ -0,0 +1,5 @@ +out vec4 fragcolor; + +void main() { + fragcolor = vec4(1.0); +} diff --git a/engine/art/shaders/query_point_vs.glsl b/engine/art/shaders/query_point_vs.glsl new file mode 100644 index 0000000..3b4b7a7 --- /dev/null +++ b/engine/art/shaders/query_point_vs.glsl @@ -0,0 +1,5 @@ +uniform mat4 u_mvp; + +void main() { + gl_Position = u_mvp * vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 3b52c93..31d8d0b 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -17190,6 +17190,11 @@ typedef struct colormap_t { API bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ); +// ----------------------------------------------------------------------------- +// Occlusion queries + +API unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size); + // ----------------------------------------------------------------------------- // fullscreen quads @@ -383214,6 +383219,61 @@ void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float bottom, f ortho44(shm_proj, left, right, bottom, top, znear, zfar); } +// ----------------------------------------------------------------------------- +// Occlusion queries + +static renderstate_t query_test_rs; + +static inline +void query_test_rs_init() { + do_once { + query_test_rs = renderstate(); + query_test_rs.depth_test_enabled = true; + query_test_rs.depth_write_enabled = false; + query_test_rs.depth_func = GL_LESS; + query_test_rs.point_size_enabled = 1; + query_test_rs.point_size = 1.0f; + memset(query_test_rs.color_mask, 0, sizeof(query_test_rs.color_mask)); + } +} + +unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size) { + static int program = -1, vao = -1, u_mvp = -1, query = -1; + if( program < 0 ) { + const char* vs = vfs_read("shaders/query_point_vs.glsl"); + const char* fs = vfs_read("shaders/query_point_fs.glsl"); + + program = shader(vs, fs, "", "fragcolor" , NULL); + u_mvp = glGetUniformLocation(program, "u_mvp"); + glGenVertexArrays( 1, (GLuint*)&vao ); + glGenQueries(1, (GLuint*)&query); + query_test_rs_init(); + } + + query_test_rs.point_size = size; + renderstate_apply(&query_test_rs); + + int oldprog = last_shader; + glUseProgram( program ); + + mat44 M; translation44(M, pos.x, pos.y, pos.z); + mat44 MVP; multiply44x3(MVP, proj, view, M); + glUniformMatrix4fv(u_mvp, 1, GL_FALSE, MVP); + + glBindVertexArray( vao ); + + glBeginQuery(GL_SAMPLES_PASSED, query); + glDrawArrays( GL_POINTS, 0, 1 ); + glEndQuery(GL_SAMPLES_PASSED); + + GLuint samples_passed = 0; + glGetQueryObjectuiv(query, GL_QUERY_RESULT, &samples_passed); + + glBindVertexArray( 0 ); + glUseProgram( oldprog ); + return samples_passed; +} + // ----------------------------------------------------------------------------- // fullscreen quads diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index cce4aea..e90f83f 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -1547,6 +1547,61 @@ void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float bottom, f ortho44(shm_proj, left, right, bottom, top, znear, zfar); } +// ----------------------------------------------------------------------------- +// Occlusion queries + +static renderstate_t query_test_rs; + +static inline +void query_test_rs_init() { + do_once { + query_test_rs = renderstate(); + query_test_rs.depth_test_enabled = true; + query_test_rs.depth_write_enabled = false; + query_test_rs.depth_func = GL_LESS; + query_test_rs.point_size_enabled = 1; + query_test_rs.point_size = 1.0f; + memset(query_test_rs.color_mask, 0, sizeof(query_test_rs.color_mask)); + } +} + +unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size) { + static int program = -1, vao = -1, u_mvp = -1, query = -1; + if( program < 0 ) { + const char* vs = vfs_read("shaders/query_point_vs.glsl"); + const char* fs = vfs_read("shaders/query_point_fs.glsl"); + + program = shader(vs, fs, "", "fragcolor" , NULL); + u_mvp = glGetUniformLocation(program, "u_mvp"); + glGenVertexArrays( 1, (GLuint*)&vao ); + glGenQueries(1, (GLuint*)&query); + query_test_rs_init(); + } + + query_test_rs.point_size = size; + renderstate_apply(&query_test_rs); + + int oldprog = last_shader; + glUseProgram( program ); + + mat44 M; translation44(M, pos.x, pos.y, pos.z); + mat44 MVP; multiply44x3(MVP, proj, view, M); + glUniformMatrix4fv(u_mvp, 1, GL_FALSE, MVP); + + glBindVertexArray( vao ); + + glBeginQuery(GL_SAMPLES_PASSED, query); + glDrawArrays( GL_POINTS, 0, 1 ); + glEndQuery(GL_SAMPLES_PASSED); + + GLuint samples_passed = 0; + glGetQueryObjectuiv(query, GL_QUERY_RESULT, &samples_passed); + + glBindVertexArray( 0 ); + glUseProgram( oldprog ); + return samples_passed; +} + // ----------------------------------------------------------------------------- // fullscreen quads diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index 5911ab7..93359b5 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -222,6 +222,11 @@ typedef struct colormap_t { API bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ); +// ----------------------------------------------------------------------------- +// Occlusion queries + +API unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size); + // ----------------------------------------------------------------------------- // fullscreen quads diff --git a/engine/v4k.c b/engine/v4k.c index e4aa163..e5d8628 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -18346,6 +18346,61 @@ void shadowmatrix_ortho(mat44 shm_proj, float left, float right, float bottom, f ortho44(shm_proj, left, right, bottom, top, znear, zfar); } +// ----------------------------------------------------------------------------- +// Occlusion queries + +static renderstate_t query_test_rs; + +static inline +void query_test_rs_init() { + do_once { + query_test_rs = renderstate(); + query_test_rs.depth_test_enabled = true; + query_test_rs.depth_write_enabled = false; + query_test_rs.depth_func = GL_LESS; + query_test_rs.point_size_enabled = 1; + query_test_rs.point_size = 1.0f; + memset(query_test_rs.color_mask, 0, sizeof(query_test_rs.color_mask)); + } +} + +unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size) { + static int program = -1, vao = -1, u_mvp = -1, query = -1; + if( program < 0 ) { + const char* vs = vfs_read("shaders/query_point_vs.glsl"); + const char* fs = vfs_read("shaders/query_point_fs.glsl"); + + program = shader(vs, fs, "", "fragcolor" , NULL); + u_mvp = glGetUniformLocation(program, "u_mvp"); + glGenVertexArrays( 1, (GLuint*)&vao ); + glGenQueries(1, (GLuint*)&query); + query_test_rs_init(); + } + + query_test_rs.point_size = size; + renderstate_apply(&query_test_rs); + + int oldprog = last_shader; + glUseProgram( program ); + + mat44 M; translation44(M, pos.x, pos.y, pos.z); + mat44 MVP; multiply44x3(MVP, proj, view, M); + glUniformMatrix4fv(u_mvp, 1, GL_FALSE, MVP); + + glBindVertexArray( vao ); + + glBeginQuery(GL_SAMPLES_PASSED, query); + glDrawArrays( GL_POINTS, 0, 1 ); + glEndQuery(GL_SAMPLES_PASSED); + + GLuint samples_passed = 0; + glGetQueryObjectuiv(query, GL_QUERY_RESULT, &samples_passed); + + glBindVertexArray( 0 ); + glUseProgram( oldprog ); + return samples_passed; +} + // ----------------------------------------------------------------------------- // fullscreen quads diff --git a/engine/v4k.h b/engine/v4k.h index e5418a7..11533c9 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -3257,6 +3257,11 @@ typedef struct colormap_t { API bool colormap( colormap_t *cm, const char *texture_name, bool load_as_srgb ); +// ----------------------------------------------------------------------------- +// Occlusion queries + +API unsigned query_test_point(mat44 proj, mat44 view, vec3 pos, float size); + // ----------------------------------------------------------------------------- // fullscreen quads