@@ -7,13 +7,17 @@ use std::{
77
88use gl:: {
99 types:: { GLboolean , GLchar , GLenum , GLfloat , GLint , GLsizei , GLsizeiptr , GLuint , GLvoid } ,
10- BGRA , FRAGMENT_SHADER , PIXEL_PACK_BUFFER , POINTS , READ_ONLY , STREAM_READ , UNSIGNED_BYTE ,
11- VERTEX_SHADER ,
10+ BGRA , CLAMP_TO_EDGE , FRAGMENT_SHADER , LINEAR , PIXEL_PACK_BUFFER , POINTS , READ_ONLY , RGBA8 ,
11+ STREAM_READ , TEXTURE0 , TEXTURE_2D , TEXTURE_MAG_FILTER , TEXTURE_MIN_FILTER , TEXTURE_WRAP_S ,
12+ TEXTURE_WRAP_T , TRIANGLE_STRIP , UNSIGNED_BYTE , VERTEX_SHADER ,
1213} ;
1314
1415use windows:: {
1516 core:: PCSTR ,
16- Win32 :: Graphics :: OpenGL :: { glDrawArrays, glPointSize, glReadPixels, wglGetProcAddress} ,
17+ Win32 :: Graphics :: OpenGL :: {
18+ glBindTexture, glDrawArrays, glGenTextures, glPointSize, glReadPixels, glTexParameteri,
19+ glTexSubImage2D, glViewport, wglGetProcAddress,
20+ } ,
1721} ;
1822
1923type GlGenBuffersFn = unsafe extern "system" fn ( n : GLsizei , buffers : * mut GLuint ) ;
@@ -36,13 +40,23 @@ type GlAttachShaderFn = unsafe extern "system" fn(program: GLuint, shader: GLuin
3640type GlLinkProgramFn = unsafe extern "system" fn ( program : GLuint ) ;
3741type GlDeleteShaderFn = unsafe extern "system" fn ( shader : GLuint ) ;
3842type GlBindVertexArrayFn = unsafe extern "system" fn ( array : GLuint ) ;
39-
4043type GlUseProgramFn = unsafe extern "system" fn ( program : GLuint ) ;
41-
42- type GlCreateVertexArrays = unsafe extern "system" fn ( n : GLsizei , arrays : * mut GLuint ) ;
43-
44- type GLUniform2Fv =
44+ type GlCreateVertexArraysFn = unsafe extern "system" fn ( n : GLsizei , arrays : * mut GLuint ) ;
45+ type GlGenVertexArraysFn = unsafe extern "system" fn ( n : GLsizei , arrays : * mut GLuint ) ;
46+ type GLUniform2FvFn =
4547 unsafe extern "system" fn ( location : GLint , count : GLsizei , value : * const GLfloat ) ;
48+ type GLTexStorage2DFn = unsafe extern "system" fn (
49+ target : GLenum ,
50+ levels : GLsizei ,
51+ internalformat : GLenum ,
52+ width : GLsizei ,
53+ height : GLsizei ,
54+ ) ;
55+ type GLActiveTextureFn = unsafe extern "system" fn ( texture : GLenum ) ;
56+ type GLBindTextureFn = unsafe extern "system" fn ( target : GLenum , texture : GLuint ) ;
57+ type GLUniform1iFn = unsafe extern "system" fn ( location : GLint , v0 : GLint ) ;
58+ type GLGetUniformLocationFn =
59+ unsafe extern "system" fn ( program : GLuint , name : * const GLchar ) -> GLint ;
4660
4761static GL_GEN_BUFFERS : OnceLock < GlGenBuffersFn > = OnceLock :: new ( ) ;
4862static GL_DELETE_BUFFERS : OnceLock < GlDeleteBuffersFn > = OnceLock :: new ( ) ;
@@ -59,11 +73,19 @@ static GL_LINK_PROGRAM: OnceLock<GlLinkProgramFn> = OnceLock::new();
5973static GL_DELETE_SHADER : OnceLock < GlDeleteShaderFn > = OnceLock :: new ( ) ;
6074static GL_BIND_VERTEX_ARRAY : OnceLock < GlBindVertexArrayFn > = OnceLock :: new ( ) ;
6175static GL_USE_PROGRAM : OnceLock < GlUseProgramFn > = OnceLock :: new ( ) ;
62- static GL_CREATE_VERTEX_ARRAYS : OnceLock < GlCreateVertexArrays > = OnceLock :: new ( ) ;
63- static GL_UNIFORM_2FV : OnceLock < GLUniform2Fv > = OnceLock :: new ( ) ;
64-
65- static SHADER_PROGRAM : OnceLock < GLuint > = OnceLock :: new ( ) ;
76+ static GL_CREATE_VERTEX_ARRAYS : OnceLock < GlCreateVertexArraysFn > = OnceLock :: new ( ) ;
77+ static GL_GEN_VERTEX_ARRAYS : OnceLock < GlGenVertexArraysFn > = OnceLock :: new ( ) ;
78+ static GL_UNIFORM_2FV : OnceLock < GLUniform2FvFn > = OnceLock :: new ( ) ;
79+ static GL_TEX_STORAGE_2D : OnceLock < GLTexStorage2DFn > = OnceLock :: new ( ) ;
80+ static GL_ACTIVE_TEXTURE : OnceLock < GLActiveTextureFn > = OnceLock :: new ( ) ;
81+ static GL_BIND_TEXTURE : OnceLock < GLBindTextureFn > = OnceLock :: new ( ) ;
82+ static GL_UNIFORM_1I : OnceLock < GLUniform1iFn > = OnceLock :: new ( ) ;
83+ static GL_GET_UNIFORM_LOCATION : OnceLock < GLGetUniformLocationFn > = OnceLock :: new ( ) ;
84+
85+ static POINT_SHADER : OnceLock < GLuint > = OnceLock :: new ( ) ;
6686static VAO : OnceLock < GLuint > = OnceLock :: new ( ) ;
87+ static OVERLAY_SHADER : OnceLock < GLuint > = OnceLock :: new ( ) ;
88+ static TEXTURE : OnceLock < GLuint > = OnceLock :: new ( ) ;
6789
6890pub fn restore_state ( prev_program : i32 , prev_vao : i32 ) {
6991 let use_program = * GL_USE_PROGRAM . get ( ) . unwrap ( ) ;
@@ -122,14 +144,28 @@ pub unsafe fn load_opengl_extensions() -> bool {
122144 && load ! ( GL_USE_PROGRAM , GlUseProgramFn , "glUseProgram" )
123145 && load ! (
124146 GL_CREATE_VERTEX_ARRAYS ,
125- GlCreateVertexArrays ,
147+ GlCreateVertexArraysFn ,
126148 "glCreateVertexArrays"
127149 )
128- && load ! ( GL_UNIFORM_2FV , GLUniform2Fv , "glUniform2fv" )
150+ && load ! (
151+ GL_GEN_VERTEX_ARRAYS ,
152+ GlGenVertexArraysFn ,
153+ "glGenVertexArrays"
154+ )
155+ && load ! ( GL_UNIFORM_2FV , GLUniform2FvFn , "glUniform2fv" )
156+ && load ! ( GL_TEX_STORAGE_2D , GLTexStorage2DFn , "glTexStorage2D" )
157+ && load ! ( GL_ACTIVE_TEXTURE , GLActiveTextureFn , "glActiveTexture" )
158+ && load ! ( GL_BIND_TEXTURE , GLBindTextureFn , "glBindTexture" )
159+ && load ! ( GL_UNIFORM_1I , GLUniform1iFn , "glUniform1i" )
160+ && load ! (
161+ GL_GET_UNIFORM_LOCATION ,
162+ GLGetUniformLocationFn ,
163+ "glGetUniformLocation"
164+ )
129165}
130166
131167lazy_static ! {
132- static ref PBO_DATA : Mutex <( Vec <u32 >, i32 , usize ) > = Mutex :: new( ( vec![ 0 , 0 ] , 0 , 0 ) ) ; // (PBOs, size, index)
168+ static ref PBO_DATA : Mutex <( Vec <u32 >, i32 , usize ) > = Mutex :: new( ( vec![ 0 , 0 ] , 0 , 0 ) ) ; //(PBOs, size, index)
133169}
134170
135171pub fn read_frame ( width : i32 , height : i32 , size : i32 , dest : * mut u8 ) {
@@ -197,17 +233,6 @@ pub fn read_frame(width: i32, height: i32, size: i32, dest: *mut u8) {
197233 }
198234}
199235
200- /* fn print_gl_errors(name: &str) {
201- loop {
202- let error = unsafe { glGetError() };
203- if error == GL_NO_ERROR {
204- break;
205- }
206- println!("{} error: {:x}\r\n", name, error);
207- }
208- }
209- */
210-
211236fn compile_shader ( source : & str , shader_type : GLenum ) -> GLuint {
212237 let gl_create_shader = * GL_CREATE_SHADER . get ( ) . unwrap ( ) ;
213238 let gl_shader_source = * GL_SHADER_SOURCE . get ( ) . unwrap ( ) ;
@@ -223,12 +248,125 @@ fn compile_shader(source: &str, shader_type: GLenum) -> GLuint {
223248 }
224249}
225250
251+ fn init_gl_resources_overlay ( ) {
252+ let create_program = * GL_CREATE_PROGRAM . get ( ) . unwrap ( ) ;
253+ let gen_vertex_arrays = * GL_GEN_VERTEX_ARRAYS . get ( ) . unwrap ( ) ;
254+ let attach_shader = * GL_ATTACH_SHADER . get ( ) . unwrap ( ) ;
255+ let link_program = * GL_LINK_PROGRAM . get ( ) . unwrap ( ) ;
256+ let delete_shader = * GL_DELETE_SHADER . get ( ) . unwrap ( ) ;
257+
258+ const VS_SRC : & str = r#"
259+ #version 460 core
260+ const vec2 verts[4] = vec2[4](
261+ vec2(-1.0, -1.0),
262+ vec2( 1.0, -1.0),
263+ vec2(-1.0, 1.0),
264+ vec2( 1.0, 1.0)
265+ );
266+ out vec2 texCoord;
267+ void main() {
268+ texCoord = (verts[gl_VertexID].xy + 1.0) * 0.5;
269+ gl_Position = vec4(verts[gl_VertexID], 0.0, 1.0);
270+ }"# ;
271+
272+ const FS_SRC : & str = r#"
273+ #version 460 core
274+ in vec2 texCoord;
275+ out vec4 FragColor;
276+ uniform sampler2D screenTex;
277+ void main() {
278+ FragColor = texture(screenTex, vec2(texCoord.x, 1.0 - texCoord.y));
279+ }"# ;
280+
281+ let vs = compile_shader ( VS_SRC , VERTEX_SHADER ) ;
282+ let fs = compile_shader ( FS_SRC , FRAGMENT_SHADER ) ;
283+
284+ unsafe {
285+ let program = create_program ( ) ;
286+ attach_shader ( program, vs) ;
287+ attach_shader ( program, fs) ;
288+ link_program ( program) ;
289+
290+ delete_shader ( vs) ;
291+ delete_shader ( fs) ;
292+ OVERLAY_SHADER . set ( program) . unwrap ( ) ;
293+ } ;
294+
295+ if VAO . get ( ) . is_none ( ) {
296+ let mut vao = 0 ;
297+ unsafe { gen_vertex_arrays ( 1 , & mut vao) } ;
298+ VAO . set ( vao) . unwrap ( ) ;
299+ }
300+ }
301+
302+ fn init_gl_texture ( width : i32 , height : i32 ) {
303+ let gl_tex_storage_2d = * GL_TEX_STORAGE_2D . get ( ) . unwrap ( ) ;
304+ let mut texture: GLuint = 0 ;
305+ unsafe {
306+ glGenTextures ( 1 , & mut texture) ;
307+ glBindTexture ( TEXTURE_2D , texture) ;
308+ glTexParameteri ( TEXTURE_2D , TEXTURE_MIN_FILTER , LINEAR as i32 ) ;
309+ glTexParameteri ( TEXTURE_2D , TEXTURE_MAG_FILTER , LINEAR as i32 ) ;
310+ glTexParameteri ( TEXTURE_2D , TEXTURE_WRAP_S , CLAMP_TO_EDGE as i32 ) ;
311+ glTexParameteri ( TEXTURE_2D , TEXTURE_WRAP_T , CLAMP_TO_EDGE as i32 ) ;
312+ gl_tex_storage_2d ( TEXTURE_2D , 1 , RGBA8 , width, height) ;
313+ } ;
314+ TEXTURE . set ( texture) . unwrap ( ) ;
315+ }
316+
317+ pub fn draw_overlay ( width : i32 , height : i32 , src : * const u8 ) {
318+ if OVERLAY_SHADER . get ( ) . is_none ( ) {
319+ init_gl_resources_overlay ( ) ;
320+ }
321+
322+ if TEXTURE . get ( ) . is_none ( ) {
323+ init_gl_texture ( width, height) ;
324+ }
325+
326+ let use_program = * GL_USE_PROGRAM . get ( ) . unwrap ( ) ;
327+ let active_texture = * GL_ACTIVE_TEXTURE . get ( ) . unwrap ( ) ;
328+ let bind_texture = * GL_BIND_TEXTURE . get ( ) . unwrap ( ) ;
329+ let uniform_1i = * GL_UNIFORM_1I . get ( ) . unwrap ( ) ;
330+ let get_uniform_location = * GL_GET_UNIFORM_LOCATION . get ( ) . unwrap ( ) ;
331+ let bind_vertex_array = * GL_BIND_VERTEX_ARRAY . get ( ) . unwrap ( ) ;
332+
333+ let program = * OVERLAY_SHADER . get ( ) . unwrap ( ) ;
334+ let texture = * TEXTURE . get ( ) . unwrap ( ) ;
335+ let vao = * VAO . get ( ) . unwrap ( ) ;
336+
337+ // Upload new data every frame
338+ unsafe {
339+ glViewport ( 0 , 0 , width, height) ;
340+ glBindTexture ( TEXTURE_2D , texture) ;
341+ glTexSubImage2D (
342+ TEXTURE_2D ,
343+ 0 ,
344+ 0 ,
345+ 0 ,
346+ width,
347+ height,
348+ BGRA ,
349+ UNSIGNED_BYTE ,
350+ src as * const c_void ,
351+ ) ;
352+
353+ use_program ( program) ;
354+ active_texture ( TEXTURE0 ) ;
355+ bind_texture ( TEXTURE_2D , texture) ;
356+ let name = CString :: new ( "screenTex" ) . unwrap ( ) ;
357+ uniform_1i ( get_uniform_location ( program, name. as_ptr ( ) ) , 0 ) ;
358+
359+ bind_vertex_array ( vao) ;
360+ glDrawArrays ( TRIANGLE_STRIP , 0 , 4 ) ;
361+ }
362+ }
363+
226364fn init_gl_resources ( ) {
227- let gl_create_program = * GL_CREATE_PROGRAM . get ( ) . unwrap ( ) ;
228- let gl_attach_shader = * GL_ATTACH_SHADER . get ( ) . unwrap ( ) ;
229- let gl_link_program = * GL_LINK_PROGRAM . get ( ) . unwrap ( ) ;
230- let gl_delete_shader = * GL_DELETE_SHADER . get ( ) . unwrap ( ) ;
231- let gl_create_vertex_arrays = * GL_CREATE_VERTEX_ARRAYS . get ( ) . unwrap ( ) ;
365+ let create_program = * GL_CREATE_PROGRAM . get ( ) . unwrap ( ) ;
366+ let attach_shader = * GL_ATTACH_SHADER . get ( ) . unwrap ( ) ;
367+ let link_program = * GL_LINK_PROGRAM . get ( ) . unwrap ( ) ;
368+ let delete_shader = * GL_DELETE_SHADER . get ( ) . unwrap ( ) ;
369+ let gen_vertex_arrays = * GL_GEN_VERTEX_ARRAYS . get ( ) . unwrap ( ) ;
232370
233371 const VS_SRC : & str = r#"
234372 #version 460 core
@@ -251,32 +389,34 @@ fn init_gl_resources() {
251389 let fs = compile_shader ( FS_SRC , FRAGMENT_SHADER ) ;
252390
253391 unsafe {
254- let program = gl_create_program ( ) ;
255- gl_attach_shader ( program, vs) ;
256- gl_attach_shader ( program, fs) ;
257- gl_link_program ( program) ;
392+ let program = create_program ( ) ;
393+ attach_shader ( program, vs) ;
394+ attach_shader ( program, fs) ;
395+ link_program ( program) ;
258396
259- gl_delete_shader ( vs) ;
260- gl_delete_shader ( fs) ;
397+ delete_shader ( vs) ;
398+ delete_shader ( fs) ;
261399
262- let mut vao = 0 ;
263- gl_create_vertex_arrays ( 1 , & mut vao ) ;
400+ POINT_SHADER . set ( program ) . unwrap ( ) ;
401+ } ;
264402
265- SHADER_PROGRAM . set ( program) . unwrap ( ) ;
403+ if VAO . get ( ) . is_none ( ) {
404+ let mut vao = 0 ;
405+ unsafe { gen_vertex_arrays ( 1 , & mut vao) } ;
266406 VAO . set ( vao) . unwrap ( ) ;
267- } ;
407+ }
268408}
269409
270410pub fn draw_point ( x : i32 , y : i32 , w : i32 , h : i32 ) {
271- if SHADER_PROGRAM . get ( ) . is_none ( ) {
411+ if POINT_SHADER . get ( ) . is_none ( ) {
272412 init_gl_resources ( ) ;
273413 }
274414
275415 let use_program = * GL_USE_PROGRAM . get ( ) . unwrap ( ) ;
276416 let bind_vertex_array = * GL_BIND_VERTEX_ARRAY . get ( ) . unwrap ( ) ;
277417 let uniform_2fv = * GL_UNIFORM_2FV . get ( ) . unwrap ( ) ;
278418
279- let program = * SHADER_PROGRAM . get ( ) . unwrap ( ) ;
419+ let program = * POINT_SHADER . get ( ) . unwrap ( ) ;
280420 let vao = * VAO . get ( ) . unwrap ( ) ;
281421
282422 let x_ndc = ( x as f32 / w as f32 ) * 2.0 - 1.0 ;
0 commit comments