1 // Copyright 2014 The Servo Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution. 3 // 4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 7 // option. This file may not be copied, modified, or distributed 8 // except according to those terms. 9 10 pub struct GlesFns { 11 ffi_gl_: GlesFfi, 12 } 13 14 impl GlesFns { load_with<'a, F>(loadfn: F) -> Rc<Gl> where F: FnMut(&str) -> *const c_void,15 pub unsafe fn load_with<'a, F>(loadfn: F) -> Rc<Gl> 16 where 17 F: FnMut(&str) -> *const c_void, 18 { 19 let ffi_gl_ = GlesFfi::load_with(loadfn); 20 Rc::new(GlesFns { ffi_gl_: ffi_gl_ }) as Rc<Gl> 21 } 22 } 23 24 impl Gl for GlesFns { get_type(&self) -> GlType25 fn get_type(&self) -> GlType { 26 GlType::Gles 27 } 28 buffer_data_untyped( &self, target: GLenum, size: GLsizeiptr, data: *const GLvoid, usage: GLenum, )29 fn buffer_data_untyped( 30 &self, 31 target: GLenum, 32 size: GLsizeiptr, 33 data: *const GLvoid, 34 usage: GLenum, 35 ) { 36 unsafe { 37 self.ffi_gl_.BufferData(target, size, data, usage); 38 } 39 } 40 tex_buffer(&self, _target: GLenum, _internal_format: GLenum, _buffer: GLuint)41 fn tex_buffer(&self, _target: GLenum, _internal_format: GLenum, _buffer: GLuint) { 42 panic!("not supported") 43 } 44 buffer_sub_data_untyped( &self, target: GLenum, offset: isize, size: GLsizeiptr, data: *const GLvoid, )45 fn buffer_sub_data_untyped( 46 &self, 47 target: GLenum, 48 offset: isize, 49 size: GLsizeiptr, 50 data: *const GLvoid, 51 ) { 52 unsafe { 53 self.ffi_gl_.BufferSubData(target, offset, size, data); 54 } 55 } 56 map_buffer(&self, _target: GLenum, _access: GLbitfield) -> *mut c_void57 fn map_buffer(&self, 58 _target: GLenum, 59 _access: GLbitfield) -> *mut c_void { 60 panic!("not supported") 61 } 62 map_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr, access: GLbitfield) -> *mut c_void63 fn map_buffer_range(&self, 64 target: GLenum, 65 offset: GLintptr, 66 length: GLsizeiptr, 67 access: GLbitfield) -> *mut c_void { 68 unsafe { 69 return self.ffi_gl_.MapBufferRange(target, offset, length, access); 70 } 71 } 72 unmap_buffer(&self, target: GLenum) -> GLboolean73 fn unmap_buffer(&self, target: GLenum) -> GLboolean { 74 unsafe { 75 return self.ffi_gl_.UnmapBuffer(target); 76 } 77 } 78 shader_source(&self, shader: GLuint, strings: &[&[u8]])79 fn shader_source(&self, shader: GLuint, strings: &[&[u8]]) { 80 let pointers: Vec<*const u8> = strings.iter().map(|string| (*string).as_ptr()).collect(); 81 let lengths: Vec<GLint> = strings.iter().map(|string| string.len() as GLint).collect(); 82 unsafe { 83 self.ffi_gl_.ShaderSource( 84 shader, 85 pointers.len() as GLsizei, 86 pointers.as_ptr() as *const *const GLchar, 87 lengths.as_ptr(), 88 ); 89 } 90 drop(lengths); 91 drop(pointers); 92 } 93 94 #[allow(unused_variables)] read_buffer(&self, mode: GLenum)95 fn read_buffer(&self, mode: GLenum) { 96 panic!("not supported") 97 } 98 read_pixels_into_buffer( &self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum, dst_buffer: &mut [u8], )99 fn read_pixels_into_buffer( 100 &self, 101 x: GLint, 102 y: GLint, 103 width: GLsizei, 104 height: GLsizei, 105 format: GLenum, 106 pixel_type: GLenum, 107 dst_buffer: &mut [u8], 108 ) { 109 // Assumes that the user properly allocated the size for dst_buffer. 110 assert!(calculate_length(width, height, format, pixel_type) == dst_buffer.len()); 111 112 unsafe { 113 // We don't want any alignment padding on pixel rows. 114 self.ffi_gl_.PixelStorei(ffi::PACK_ALIGNMENT, 1); 115 self.ffi_gl_.ReadPixels( 116 x, 117 y, 118 width, 119 height, 120 format, 121 pixel_type, 122 dst_buffer.as_mut_ptr() as *mut c_void, 123 ); 124 } 125 } 126 read_pixels( &self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum, ) -> Vec<u8>127 fn read_pixels( 128 &self, 129 x: GLint, 130 y: GLint, 131 width: GLsizei, 132 height: GLsizei, 133 format: GLenum, 134 pixel_type: GLenum, 135 ) -> Vec<u8> { 136 let len = calculate_length(width, height, format, pixel_type); 137 let mut pixels: Vec<u8> = Vec::new(); 138 pixels.reserve(len); 139 unsafe { 140 pixels.set_len(len); 141 } 142 143 self.read_pixels_into_buffer( 144 x, 145 y, 146 width, 147 height, 148 format, 149 pixel_type, 150 pixels.as_mut_slice(), 151 ); 152 153 pixels 154 } 155 read_pixels_into_pbo(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum)156 unsafe fn read_pixels_into_pbo(&self, 157 x: GLint, 158 y: GLint, 159 width: GLsizei, 160 height: GLsizei, 161 format: GLenum, 162 pixel_type: GLenum) { 163 self.ffi_gl_.ReadPixels(x, y, width, height, format, pixel_type, ptr::null_mut()); 164 } 165 sample_coverage(&self, value: GLclampf, invert: bool)166 fn sample_coverage(&self, value: GLclampf, invert: bool) { 167 unsafe { 168 self.ffi_gl_.SampleCoverage(value, invert as GLboolean); 169 } 170 } 171 polygon_offset(&self, factor: GLfloat, units: GLfloat)172 fn polygon_offset(&self, factor: GLfloat, units: GLfloat) { 173 unsafe { 174 self.ffi_gl_.PolygonOffset(factor, units); 175 } 176 } 177 pixel_store_i(&self, name: GLenum, param: GLint)178 fn pixel_store_i(&self, name: GLenum, param: GLint) { 179 unsafe { 180 self.ffi_gl_.PixelStorei(name, param); 181 } 182 } 183 gen_buffers(&self, n: GLsizei) -> Vec<GLuint>184 fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint> { 185 let mut result = vec![0 as GLuint; n as usize]; 186 unsafe { 187 self.ffi_gl_.GenBuffers(n, result.as_mut_ptr()); 188 } 189 result 190 } 191 gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint>192 fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint> { 193 let mut result = vec![0 as GLuint; n as usize]; 194 unsafe { 195 self.ffi_gl_.GenRenderbuffers(n, result.as_mut_ptr()); 196 } 197 result 198 } 199 gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint>200 fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint> { 201 let mut result = vec![0 as GLuint; n as usize]; 202 unsafe { 203 self.ffi_gl_.GenFramebuffers(n, result.as_mut_ptr()); 204 } 205 result 206 } 207 gen_textures(&self, n: GLsizei) -> Vec<GLuint>208 fn gen_textures(&self, n: GLsizei) -> Vec<GLuint> { 209 let mut result = vec![0 as GLuint; n as usize]; 210 unsafe { 211 self.ffi_gl_.GenTextures(n, result.as_mut_ptr()); 212 } 213 result 214 } 215 gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint>216 fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint> { 217 let mut result = vec![0 as GLuint; n as usize]; 218 unsafe { 219 self.ffi_gl_.GenVertexArrays(n, result.as_mut_ptr()); 220 } 221 result 222 } 223 gen_queries(&self, n: GLsizei) -> Vec<GLuint>224 fn gen_queries(&self, n: GLsizei) -> Vec<GLuint> { 225 if !self.ffi_gl_.GenQueriesEXT.is_loaded() { 226 return Vec::new(); 227 } 228 let mut result = vec![0 as GLuint; n as usize]; 229 unsafe { 230 self.ffi_gl_.GenQueriesEXT(n, result.as_mut_ptr()); 231 } 232 result 233 } 234 begin_query(&self, target: GLenum, id: GLuint)235 fn begin_query(&self, target: GLenum, id: GLuint) { 236 if !self.ffi_gl_.BeginQueryEXT.is_loaded() { 237 return; 238 } 239 unsafe { 240 self.ffi_gl_.BeginQueryEXT(target, id); 241 } 242 } 243 end_query(&self, target: GLenum)244 fn end_query(&self, target: GLenum) { 245 if !self.ffi_gl_.EndQueryEXT.is_loaded() { 246 return; 247 } 248 unsafe { 249 self.ffi_gl_.EndQueryEXT(target); 250 } 251 } 252 query_counter(&self, id: GLuint, target: GLenum)253 fn query_counter(&self, id: GLuint, target: GLenum) { 254 if !self.ffi_gl_.QueryCounterEXT.is_loaded() { 255 return; 256 } 257 unsafe { 258 self.ffi_gl_.QueryCounterEXT(id, target); 259 } 260 } 261 get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32262 fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 { 263 if !self.ffi_gl_.GetQueryObjectivEXT.is_loaded() { 264 return 0; 265 } 266 let mut result = 0; 267 unsafe { 268 self.ffi_gl_.GetQueryObjectivEXT(id, pname, &mut result); 269 } 270 result 271 } 272 get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32273 fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 { 274 if !self.ffi_gl_.GetQueryObjectuivEXT.is_loaded() { 275 return 0; 276 } 277 let mut result = 0; 278 unsafe { 279 self.ffi_gl_.GetQueryObjectuivEXT(id, pname, &mut result); 280 } 281 result 282 } 283 get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64284 fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 { 285 if !self.ffi_gl_.GetQueryObjecti64vEXT.is_loaded() { 286 return 0; 287 } 288 let mut result = 0; 289 unsafe { 290 self.ffi_gl_.GetQueryObjecti64vEXT(id, pname, &mut result); 291 } 292 result 293 } 294 get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64295 fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 { 296 if !self.ffi_gl_.GetQueryObjectui64vEXT.is_loaded() { 297 return 0; 298 } 299 let mut result = 0; 300 unsafe { 301 self.ffi_gl_.GetQueryObjectui64vEXT(id, pname, &mut result); 302 } 303 result 304 } 305 delete_queries(&self, queries: &[GLuint])306 fn delete_queries(&self, queries: &[GLuint]) { 307 if !self.ffi_gl_.DeleteQueriesEXT.is_loaded() { 308 return; 309 } 310 unsafe { 311 self.ffi_gl_ 312 .DeleteQueriesEXT(queries.len() as GLsizei, queries.as_ptr()); 313 } 314 } 315 delete_vertex_arrays(&self, vertex_arrays: &[GLuint])316 fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]) { 317 unsafe { 318 self.ffi_gl_ 319 .DeleteVertexArrays(vertex_arrays.len() as GLsizei, vertex_arrays.as_ptr()); 320 } 321 } 322 delete_buffers(&self, buffers: &[GLuint])323 fn delete_buffers(&self, buffers: &[GLuint]) { 324 unsafe { 325 self.ffi_gl_ 326 .DeleteBuffers(buffers.len() as GLsizei, buffers.as_ptr()); 327 } 328 } 329 delete_renderbuffers(&self, renderbuffers: &[GLuint])330 fn delete_renderbuffers(&self, renderbuffers: &[GLuint]) { 331 unsafe { 332 self.ffi_gl_ 333 .DeleteRenderbuffers(renderbuffers.len() as GLsizei, renderbuffers.as_ptr()); 334 } 335 } 336 delete_framebuffers(&self, framebuffers: &[GLuint])337 fn delete_framebuffers(&self, framebuffers: &[GLuint]) { 338 unsafe { 339 self.ffi_gl_ 340 .DeleteFramebuffers(framebuffers.len() as GLsizei, framebuffers.as_ptr()); 341 } 342 } 343 delete_textures(&self, textures: &[GLuint])344 fn delete_textures(&self, textures: &[GLuint]) { 345 unsafe { 346 self.ffi_gl_ 347 .DeleteTextures(textures.len() as GLsizei, textures.as_ptr()); 348 } 349 } 350 framebuffer_renderbuffer( &self, target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: GLuint, )351 fn framebuffer_renderbuffer( 352 &self, 353 target: GLenum, 354 attachment: GLenum, 355 renderbuffertarget: GLenum, 356 renderbuffer: GLuint, 357 ) { 358 unsafe { 359 self.ffi_gl_.FramebufferRenderbuffer( 360 target, 361 attachment, 362 renderbuffertarget, 363 renderbuffer, 364 ); 365 } 366 } 367 renderbuffer_storage( &self, target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei, )368 fn renderbuffer_storage( 369 &self, 370 target: GLenum, 371 internalformat: GLenum, 372 width: GLsizei, 373 height: GLsizei, 374 ) { 375 unsafe { 376 self.ffi_gl_ 377 .RenderbufferStorage(target, internalformat, width, height); 378 } 379 } 380 depth_func(&self, func: GLenum)381 fn depth_func(&self, func: GLenum) { 382 unsafe { 383 self.ffi_gl_.DepthFunc(func); 384 } 385 } 386 active_texture(&self, texture: GLenum)387 fn active_texture(&self, texture: GLenum) { 388 unsafe { 389 self.ffi_gl_.ActiveTexture(texture); 390 } 391 } 392 attach_shader(&self, program: GLuint, shader: GLuint)393 fn attach_shader(&self, program: GLuint, shader: GLuint) { 394 unsafe { 395 self.ffi_gl_.AttachShader(program, shader); 396 } 397 } 398 bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str)399 fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) { 400 let c_string = CString::new(name).unwrap(); 401 unsafe { 402 self.ffi_gl_ 403 .BindAttribLocation(program, index, c_string.as_ptr()) 404 } 405 } 406 407 // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint])408 unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]) { 409 assert!(!result.is_empty()); 410 self.ffi_gl_ 411 .GetUniformiv(program, location, result.as_mut_ptr()); 412 } 413 414 // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat])415 unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]) { 416 assert!(!result.is_empty()); 417 self.ffi_gl_ 418 .GetUniformfv(program, location, result.as_mut_ptr()); 419 } 420 get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint421 fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint { 422 let c_string = CString::new(name).unwrap(); 423 unsafe { 424 self.ffi_gl_ 425 .GetUniformBlockIndex(program, c_string.as_ptr()) 426 } 427 } 428 get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint>429 fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint> { 430 let c_strings: Vec<CString> = names.iter().map(|n| CString::new(*n).unwrap()).collect(); 431 let pointers: Vec<*const GLchar> = c_strings.iter().map(|string| string.as_ptr()).collect(); 432 let mut result = Vec::with_capacity(c_strings.len()); 433 unsafe { 434 result.set_len(c_strings.len()); 435 self.ffi_gl_.GetUniformIndices( 436 program, 437 pointers.len() as GLsizei, 438 pointers.as_ptr(), 439 result.as_mut_ptr(), 440 ); 441 } 442 result 443 } 444 bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint)445 fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint) { 446 unsafe { 447 self.ffi_gl_.BindBufferBase(target, index, buffer); 448 } 449 } 450 bind_buffer_range( &self, target: GLenum, index: GLuint, buffer: GLuint, offset: GLintptr, size: GLsizeiptr, )451 fn bind_buffer_range( 452 &self, 453 target: GLenum, 454 index: GLuint, 455 buffer: GLuint, 456 offset: GLintptr, 457 size: GLsizeiptr, 458 ) { 459 unsafe { 460 self.ffi_gl_ 461 .BindBufferRange(target, index, buffer, offset, size); 462 } 463 } 464 uniform_block_binding( &self, program: GLuint, uniform_block_index: GLuint, uniform_block_binding: GLuint, )465 fn uniform_block_binding( 466 &self, 467 program: GLuint, 468 uniform_block_index: GLuint, 469 uniform_block_binding: GLuint, 470 ) { 471 unsafe { 472 self.ffi_gl_ 473 .UniformBlockBinding(program, uniform_block_index, uniform_block_binding); 474 } 475 } 476 bind_buffer(&self, target: GLenum, buffer: GLuint)477 fn bind_buffer(&self, target: GLenum, buffer: GLuint) { 478 unsafe { 479 self.ffi_gl_.BindBuffer(target, buffer); 480 } 481 } 482 bind_vertex_array(&self, vao: GLuint)483 fn bind_vertex_array(&self, vao: GLuint) { 484 unsafe { 485 self.ffi_gl_.BindVertexArray(vao); 486 } 487 } 488 bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint)489 fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) { 490 unsafe { 491 self.ffi_gl_.BindRenderbuffer(target, renderbuffer); 492 } 493 } 494 bind_framebuffer(&self, target: GLenum, framebuffer: GLuint)495 fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) { 496 unsafe { 497 self.ffi_gl_.BindFramebuffer(target, framebuffer); 498 } 499 } 500 bind_texture(&self, target: GLenum, texture: GLuint)501 fn bind_texture(&self, target: GLenum, texture: GLuint) { 502 unsafe { 503 self.ffi_gl_.BindTexture(target, texture); 504 } 505 } 506 draw_buffers(&self, bufs: &[GLenum])507 fn draw_buffers(&self, bufs: &[GLenum]) { 508 unsafe { 509 self.ffi_gl_ 510 .DrawBuffers(bufs.len() as GLsizei, bufs.as_ptr()); 511 } 512 } 513 514 // FIXME: Does not verify buffer size -- unsafe! tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, ty: GLenum, opt_data: Option<&[u8]>, )515 fn tex_image_2d( 516 &self, 517 target: GLenum, 518 level: GLint, 519 internal_format: GLint, 520 width: GLsizei, 521 height: GLsizei, 522 border: GLint, 523 format: GLenum, 524 ty: GLenum, 525 opt_data: Option<&[u8]>, 526 ) { 527 match opt_data { 528 Some(data) => unsafe { 529 self.ffi_gl_.TexImage2D( 530 target, 531 level, 532 internal_format, 533 width, 534 height, 535 border, 536 format, 537 ty, 538 data.as_ptr() as *const GLvoid, 539 ); 540 }, 541 None => unsafe { 542 self.ffi_gl_.TexImage2D( 543 target, 544 level, 545 internal_format, 546 width, 547 height, 548 border, 549 format, 550 ty, 551 ptr::null(), 552 ); 553 }, 554 } 555 } 556 compressed_tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: &[u8], )557 fn compressed_tex_image_2d( 558 &self, 559 target: GLenum, 560 level: GLint, 561 internal_format: GLenum, 562 width: GLsizei, 563 height: GLsizei, 564 border: GLint, 565 data: &[u8], 566 ) { 567 unsafe { 568 self.ffi_gl_.CompressedTexImage2D( 569 target, 570 level, 571 internal_format, 572 width, 573 height, 574 border, 575 data.len() as GLsizei, 576 data.as_ptr() as *const GLvoid, 577 ); 578 } 579 } 580 compressed_tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: &[u8], )581 fn compressed_tex_sub_image_2d( 582 &self, 583 target: GLenum, 584 level: GLint, 585 xoffset: GLint, 586 yoffset: GLint, 587 width: GLsizei, 588 height: GLsizei, 589 format: GLenum, 590 data: &[u8], 591 ) { 592 unsafe { 593 self.ffi_gl_.CompressedTexSubImage2D( 594 target, 595 level, 596 xoffset, 597 yoffset, 598 width, 599 height, 600 format, 601 data.len() as GLsizei, 602 data.as_ptr() as *const GLvoid, 603 ); 604 } 605 } 606 607 // FIXME: Does not verify buffer size -- unsafe! tex_image_3d( &self, target: GLenum, level: GLint, internal_format: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, ty: GLenum, opt_data: Option<&[u8]>, )608 fn tex_image_3d( 609 &self, 610 target: GLenum, 611 level: GLint, 612 internal_format: GLint, 613 width: GLsizei, 614 height: GLsizei, 615 depth: GLsizei, 616 border: GLint, 617 format: GLenum, 618 ty: GLenum, 619 opt_data: Option<&[u8]>, 620 ) { 621 unsafe { 622 let pdata = match opt_data { 623 Some(data) => mem::transmute(data.as_ptr()), 624 None => ptr::null(), 625 }; 626 self.ffi_gl_.TexImage3D( 627 target, 628 level, 629 internal_format, 630 width, 631 height, 632 depth, 633 border, 634 format, 635 ty, 636 pdata, 637 ); 638 } 639 } 640 copy_tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLenum, x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint, )641 fn copy_tex_image_2d( 642 &self, 643 target: GLenum, 644 level: GLint, 645 internal_format: GLenum, 646 x: GLint, 647 y: GLint, 648 width: GLsizei, 649 height: GLsizei, 650 border: GLint, 651 ) { 652 unsafe { 653 self.ffi_gl_.CopyTexImage2D( 654 target, 655 level, 656 internal_format, 657 x, 658 y, 659 width, 660 height, 661 border, 662 ); 663 } 664 } 665 copy_tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei, )666 fn copy_tex_sub_image_2d( 667 &self, 668 target: GLenum, 669 level: GLint, 670 xoffset: GLint, 671 yoffset: GLint, 672 x: GLint, 673 y: GLint, 674 width: GLsizei, 675 height: GLsizei, 676 ) { 677 unsafe { 678 self.ffi_gl_ 679 .CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 680 } 681 } 682 copy_tex_sub_image_3d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei, )683 fn copy_tex_sub_image_3d( 684 &self, 685 target: GLenum, 686 level: GLint, 687 xoffset: GLint, 688 yoffset: GLint, 689 zoffset: GLint, 690 x: GLint, 691 y: GLint, 692 width: GLsizei, 693 height: GLsizei, 694 ) { 695 unsafe { 696 self.ffi_gl_.CopyTexSubImage3D( 697 target, level, xoffset, yoffset, zoffset, x, y, width, height, 698 ); 699 } 700 } 701 tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, ty: GLenum, data: &[u8], )702 fn tex_sub_image_2d( 703 &self, 704 target: GLenum, 705 level: GLint, 706 xoffset: GLint, 707 yoffset: GLint, 708 width: GLsizei, 709 height: GLsizei, 710 format: GLenum, 711 ty: GLenum, 712 data: &[u8], 713 ) { 714 unsafe { 715 self.ffi_gl_.TexSubImage2D( 716 target, 717 level, 718 xoffset, 719 yoffset, 720 width, 721 height, 722 format, 723 ty, 724 data.as_ptr() as *const c_void, 725 ); 726 } 727 } 728 tex_sub_image_2d_pbo( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, ty: GLenum, offset: usize, )729 fn tex_sub_image_2d_pbo( 730 &self, 731 target: GLenum, 732 level: GLint, 733 xoffset: GLint, 734 yoffset: GLint, 735 width: GLsizei, 736 height: GLsizei, 737 format: GLenum, 738 ty: GLenum, 739 offset: usize, 740 ) { 741 unsafe { 742 self.ffi_gl_.TexSubImage2D( 743 target, 744 level, 745 xoffset, 746 yoffset, 747 width, 748 height, 749 format, 750 ty, 751 offset as *const c_void, 752 ); 753 } 754 } 755 tex_sub_image_3d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, ty: GLenum, data: &[u8], )756 fn tex_sub_image_3d( 757 &self, 758 target: GLenum, 759 level: GLint, 760 xoffset: GLint, 761 yoffset: GLint, 762 zoffset: GLint, 763 width: GLsizei, 764 height: GLsizei, 765 depth: GLsizei, 766 format: GLenum, 767 ty: GLenum, 768 data: &[u8], 769 ) { 770 unsafe { 771 self.ffi_gl_.TexSubImage3D( 772 target, 773 level, 774 xoffset, 775 yoffset, 776 zoffset, 777 width, 778 height, 779 depth, 780 format, 781 ty, 782 data.as_ptr() as *const c_void, 783 ); 784 } 785 } 786 tex_sub_image_3d_pbo( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, ty: GLenum, offset: usize, )787 fn tex_sub_image_3d_pbo( 788 &self, 789 target: GLenum, 790 level: GLint, 791 xoffset: GLint, 792 yoffset: GLint, 793 zoffset: GLint, 794 width: GLsizei, 795 height: GLsizei, 796 depth: GLsizei, 797 format: GLenum, 798 ty: GLenum, 799 offset: usize, 800 ) { 801 unsafe { 802 self.ffi_gl_.TexSubImage3D( 803 target, 804 level, 805 xoffset, 806 yoffset, 807 zoffset, 808 width, 809 height, 810 depth, 811 format, 812 ty, 813 offset as *const c_void, 814 ); 815 } 816 } 817 tex_storage_2d( &self, target: GLenum, levels: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, )818 fn tex_storage_2d( 819 &self, 820 target: GLenum, 821 levels: GLint, 822 internal_format: GLenum, 823 width: GLsizei, 824 height: GLsizei, 825 ) { 826 unsafe { 827 self.ffi_gl_ 828 .TexStorage2D(target, levels, internal_format, width, height); 829 } 830 } 831 tex_storage_3d( &self, target: GLenum, levels: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, )832 fn tex_storage_3d( 833 &self, 834 target: GLenum, 835 levels: GLint, 836 internal_format: GLenum, 837 width: GLsizei, 838 height: GLsizei, 839 depth: GLsizei, 840 ) { 841 unsafe { 842 self.ffi_gl_ 843 .TexStorage3D(target, levels, internal_format, width, height, depth); 844 } 845 } 846 847 #[allow(unused_variables)] get_tex_image_into_buffer( &self, target: GLenum, level: GLint, format: GLenum, ty: GLenum, output: &mut [u8], )848 fn get_tex_image_into_buffer( 849 &self, 850 target: GLenum, 851 level: GLint, 852 format: GLenum, 853 ty: GLenum, 854 output: &mut [u8], 855 ) { 856 panic!("not supported"); 857 } 858 copy_image_sub_data( &self, src_name: GLuint, src_target: GLenum, src_level: GLint, src_x: GLint, src_y: GLint, src_z: GLint, dst_name: GLuint, dst_target: GLenum, dst_level: GLint, dst_x: GLint, dst_y: GLint, dst_z: GLint, src_width: GLsizei, src_height: GLsizei, src_depth: GLsizei, )859 unsafe fn copy_image_sub_data( 860 &self, 861 src_name: GLuint, 862 src_target: GLenum, 863 src_level: GLint, 864 src_x: GLint, 865 src_y: GLint, 866 src_z: GLint, 867 dst_name: GLuint, 868 dst_target: GLenum, 869 dst_level: GLint, 870 dst_x: GLint, 871 dst_y: GLint, 872 dst_z: GLint, 873 src_width: GLsizei, 874 src_height: GLsizei, 875 src_depth: GLsizei, 876 ) { 877 self.ffi_gl_.CopyImageSubDataEXT( 878 src_name, src_target, src_level, src_x, src_y, src_z, dst_name, dst_target, dst_level, 879 dst_x, dst_y, dst_z, src_width, src_height, src_depth, 880 ); 881 } 882 invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum])883 fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]) { 884 unsafe { 885 self.ffi_gl_.InvalidateFramebuffer( 886 target, 887 attachments.len() as GLsizei, 888 attachments.as_ptr(), 889 ); 890 } 891 } 892 invalidate_sub_framebuffer( &self, target: GLenum, attachments: &[GLenum], xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, )893 fn invalidate_sub_framebuffer( 894 &self, 895 target: GLenum, 896 attachments: &[GLenum], 897 xoffset: GLint, 898 yoffset: GLint, 899 width: GLsizei, 900 height: GLsizei, 901 ) { 902 unsafe { 903 self.ffi_gl_.InvalidateSubFramebuffer( 904 target, 905 attachments.len() as GLsizei, 906 attachments.as_ptr(), 907 xoffset, 908 yoffset, 909 width, 910 height, 911 ); 912 } 913 } 914 915 #[inline] get_integer_v(&self, name: GLenum, result: &mut [GLint])916 unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]) { 917 assert!(!result.is_empty()); 918 self.ffi_gl_.GetIntegerv(name, result.as_mut_ptr()); 919 } 920 921 #[inline] get_integer_64v(&self, name: GLenum, result: &mut [GLint64])922 unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]) { 923 assert!(!result.is_empty()); 924 self.ffi_gl_.GetInteger64v(name, result.as_mut_ptr()); 925 } 926 927 #[inline] get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint])928 unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]) { 929 assert!(!result.is_empty()); 930 self.ffi_gl_.GetIntegeri_v(name, index, result.as_mut_ptr()); 931 } 932 933 #[inline] get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64])934 unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]) { 935 assert!(!result.is_empty()); 936 self.ffi_gl_ 937 .GetInteger64i_v(name, index, result.as_mut_ptr()); 938 } 939 940 #[inline] get_boolean_v(&self, name: GLenum, result: &mut [GLboolean])941 unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]) { 942 assert!(!result.is_empty()); 943 self.ffi_gl_.GetBooleanv(name, result.as_mut_ptr()); 944 } 945 946 #[inline] get_float_v(&self, name: GLenum, result: &mut [GLfloat])947 unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]) { 948 assert!(!result.is_empty()); 949 self.ffi_gl_.GetFloatv(name, result.as_mut_ptr()); 950 } 951 get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint952 fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint { 953 let mut result: GLint = 0; 954 unsafe { 955 self.ffi_gl_ 956 .GetRenderbufferParameteriv(target, pname, &mut result); 957 } 958 result 959 } 960 get_framebuffer_attachment_parameter_iv( &self, target: GLenum, attachment: GLenum, pname: GLenum, ) -> GLint961 fn get_framebuffer_attachment_parameter_iv( 962 &self, 963 target: GLenum, 964 attachment: GLenum, 965 pname: GLenum, 966 ) -> GLint { 967 let mut result: GLint = 0; 968 unsafe { 969 self.ffi_gl_.GetFramebufferAttachmentParameteriv( 970 target, 971 attachment, 972 pname, 973 &mut result, 974 ); 975 } 976 result 977 } 978 get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint979 fn get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint { 980 let mut result: GLint = 0; 981 unsafe { 982 self.ffi_gl_.GetTexParameteriv(target, pname, &mut result); 983 } 984 result 985 } 986 get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat987 fn get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat { 988 let mut result: GLfloat = 0.0; 989 unsafe { 990 self.ffi_gl_.GetTexParameterfv(target, pname, &mut result); 991 } 992 result 993 } 994 tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint)995 fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) { 996 unsafe { 997 self.ffi_gl_.TexParameteri(target, pname, param); 998 } 999 } 1000 tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat)1001 fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) { 1002 unsafe { 1003 self.ffi_gl_.TexParameterf(target, pname, param); 1004 } 1005 } 1006 framebuffer_texture_2d( &self, target: GLenum, attachment: GLenum, textarget: GLenum, texture: GLuint, level: GLint, )1007 fn framebuffer_texture_2d( 1008 &self, 1009 target: GLenum, 1010 attachment: GLenum, 1011 textarget: GLenum, 1012 texture: GLuint, 1013 level: GLint, 1014 ) { 1015 unsafe { 1016 self.ffi_gl_ 1017 .FramebufferTexture2D(target, attachment, textarget, texture, level); 1018 } 1019 } 1020 framebuffer_texture_layer( &self, target: GLenum, attachment: GLenum, texture: GLuint, level: GLint, layer: GLint, )1021 fn framebuffer_texture_layer( 1022 &self, 1023 target: GLenum, 1024 attachment: GLenum, 1025 texture: GLuint, 1026 level: GLint, 1027 layer: GLint, 1028 ) { 1029 unsafe { 1030 self.ffi_gl_ 1031 .FramebufferTextureLayer(target, attachment, texture, level, layer); 1032 } 1033 } 1034 blit_framebuffer( &self, src_x0: GLint, src_y0: GLint, src_x1: GLint, src_y1: GLint, dst_x0: GLint, dst_y0: GLint, dst_x1: GLint, dst_y1: GLint, mask: GLbitfield, filter: GLenum, )1035 fn blit_framebuffer( 1036 &self, 1037 src_x0: GLint, 1038 src_y0: GLint, 1039 src_x1: GLint, 1040 src_y1: GLint, 1041 dst_x0: GLint, 1042 dst_y0: GLint, 1043 dst_x1: GLint, 1044 dst_y1: GLint, 1045 mask: GLbitfield, 1046 filter: GLenum, 1047 ) { 1048 unsafe { 1049 self.ffi_gl_.BlitFramebuffer( 1050 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter, 1051 ); 1052 } 1053 } 1054 vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat)1055 fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) { 1056 unsafe { self.ffi_gl_.VertexAttrib4f(index, x, y, z, w) } 1057 } 1058 vertex_attrib_pointer_f32( &self, index: GLuint, size: GLint, normalized: bool, stride: GLsizei, offset: GLuint, )1059 fn vertex_attrib_pointer_f32( 1060 &self, 1061 index: GLuint, 1062 size: GLint, 1063 normalized: bool, 1064 stride: GLsizei, 1065 offset: GLuint, 1066 ) { 1067 unsafe { 1068 self.ffi_gl_.VertexAttribPointer( 1069 index, 1070 size, 1071 ffi::FLOAT, 1072 normalized as GLboolean, 1073 stride, 1074 offset as *const GLvoid, 1075 ) 1076 } 1077 } 1078 vertex_attrib_pointer( &self, index: GLuint, size: GLint, type_: GLenum, normalized: bool, stride: GLsizei, offset: GLuint, )1079 fn vertex_attrib_pointer( 1080 &self, 1081 index: GLuint, 1082 size: GLint, 1083 type_: GLenum, 1084 normalized: bool, 1085 stride: GLsizei, 1086 offset: GLuint, 1087 ) { 1088 unsafe { 1089 self.ffi_gl_.VertexAttribPointer( 1090 index, 1091 size, 1092 type_, 1093 normalized as GLboolean, 1094 stride, 1095 offset as *const GLvoid, 1096 ) 1097 } 1098 } 1099 vertex_attrib_i_pointer( &self, index: GLuint, size: GLint, type_: GLenum, stride: GLsizei, offset: GLuint, )1100 fn vertex_attrib_i_pointer( 1101 &self, 1102 index: GLuint, 1103 size: GLint, 1104 type_: GLenum, 1105 stride: GLsizei, 1106 offset: GLuint, 1107 ) { 1108 unsafe { 1109 self.ffi_gl_ 1110 .VertexAttribIPointer(index, size, type_, stride, offset as *const GLvoid) 1111 } 1112 } 1113 vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint)1114 fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) { 1115 unsafe { self.ffi_gl_.VertexAttribDivisor(index, divisor) } 1116 } 1117 viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei)1118 fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) { 1119 unsafe { 1120 self.ffi_gl_.Viewport(x, y, width, height); 1121 } 1122 } 1123 scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei)1124 fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) { 1125 unsafe { 1126 self.ffi_gl_.Scissor(x, y, width, height); 1127 } 1128 } 1129 line_width(&self, width: GLfloat)1130 fn line_width(&self, width: GLfloat) { 1131 unsafe { 1132 self.ffi_gl_.LineWidth(width); 1133 } 1134 } 1135 use_program(&self, program: GLuint)1136 fn use_program(&self, program: GLuint) { 1137 unsafe { 1138 self.ffi_gl_.UseProgram(program); 1139 } 1140 } 1141 validate_program(&self, program: GLuint)1142 fn validate_program(&self, program: GLuint) { 1143 unsafe { 1144 self.ffi_gl_.ValidateProgram(program); 1145 } 1146 } 1147 draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei)1148 fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) { 1149 unsafe { 1150 return self.ffi_gl_.DrawArrays(mode, first, count); 1151 } 1152 } 1153 draw_arrays_instanced( &self, mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei, )1154 fn draw_arrays_instanced( 1155 &self, 1156 mode: GLenum, 1157 first: GLint, 1158 count: GLsizei, 1159 primcount: GLsizei, 1160 ) { 1161 unsafe { 1162 return self 1163 .ffi_gl_ 1164 .DrawArraysInstanced(mode, first, count, primcount); 1165 } 1166 } 1167 draw_elements( &self, mode: GLenum, count: GLsizei, element_type: GLenum, indices_offset: GLuint, )1168 fn draw_elements( 1169 &self, 1170 mode: GLenum, 1171 count: GLsizei, 1172 element_type: GLenum, 1173 indices_offset: GLuint, 1174 ) { 1175 unsafe { 1176 return self.ffi_gl_.DrawElements( 1177 mode, 1178 count, 1179 element_type, 1180 indices_offset as *const c_void, 1181 ); 1182 } 1183 } 1184 draw_elements_instanced( &self, mode: GLenum, count: GLsizei, element_type: GLenum, indices_offset: GLuint, primcount: GLsizei, )1185 fn draw_elements_instanced( 1186 &self, 1187 mode: GLenum, 1188 count: GLsizei, 1189 element_type: GLenum, 1190 indices_offset: GLuint, 1191 primcount: GLsizei, 1192 ) { 1193 unsafe { 1194 return self.ffi_gl_.DrawElementsInstanced( 1195 mode, 1196 count, 1197 element_type, 1198 indices_offset as *const c_void, 1199 primcount, 1200 ); 1201 } 1202 } 1203 blend_color(&self, r: f32, g: f32, b: f32, a: f32)1204 fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) { 1205 unsafe { 1206 self.ffi_gl_.BlendColor(r, g, b, a); 1207 } 1208 } 1209 blend_func(&self, sfactor: GLenum, dfactor: GLenum)1210 fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) { 1211 unsafe { 1212 self.ffi_gl_.BlendFunc(sfactor, dfactor); 1213 } 1214 } 1215 blend_func_separate( &self, src_rgb: GLenum, dest_rgb: GLenum, src_alpha: GLenum, dest_alpha: GLenum, )1216 fn blend_func_separate( 1217 &self, 1218 src_rgb: GLenum, 1219 dest_rgb: GLenum, 1220 src_alpha: GLenum, 1221 dest_alpha: GLenum, 1222 ) { 1223 unsafe { 1224 self.ffi_gl_ 1225 .BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha); 1226 } 1227 } 1228 blend_equation(&self, mode: GLenum)1229 fn blend_equation(&self, mode: GLenum) { 1230 unsafe { 1231 self.ffi_gl_.BlendEquation(mode); 1232 } 1233 } 1234 blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum)1235 fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) { 1236 unsafe { 1237 self.ffi_gl_.BlendEquationSeparate(mode_rgb, mode_alpha); 1238 } 1239 } 1240 color_mask(&self, r: bool, g: bool, b: bool, a: bool)1241 fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) { 1242 unsafe { 1243 self.ffi_gl_.ColorMask( 1244 r as GLboolean, 1245 g as GLboolean, 1246 b as GLboolean, 1247 a as GLboolean, 1248 ); 1249 } 1250 } 1251 cull_face(&self, mode: GLenum)1252 fn cull_face(&self, mode: GLenum) { 1253 unsafe { 1254 self.ffi_gl_.CullFace(mode); 1255 } 1256 } 1257 front_face(&self, mode: GLenum)1258 fn front_face(&self, mode: GLenum) { 1259 unsafe { 1260 self.ffi_gl_.FrontFace(mode); 1261 } 1262 } 1263 enable(&self, cap: GLenum)1264 fn enable(&self, cap: GLenum) { 1265 unsafe { 1266 self.ffi_gl_.Enable(cap); 1267 } 1268 } 1269 disable(&self, cap: GLenum)1270 fn disable(&self, cap: GLenum) { 1271 unsafe { 1272 self.ffi_gl_.Disable(cap); 1273 } 1274 } 1275 hint(&self, param_name: GLenum, param_val: GLenum)1276 fn hint(&self, param_name: GLenum, param_val: GLenum) { 1277 unsafe { 1278 self.ffi_gl_.Hint(param_name, param_val); 1279 } 1280 } 1281 is_enabled(&self, cap: GLenum) -> GLboolean1282 fn is_enabled(&self, cap: GLenum) -> GLboolean { 1283 unsafe { self.ffi_gl_.IsEnabled(cap) } 1284 } 1285 is_shader(&self, shader: GLuint) -> GLboolean1286 fn is_shader(&self, shader: GLuint) -> GLboolean { 1287 unsafe { self.ffi_gl_.IsShader(shader) } 1288 } 1289 is_texture(&self, texture: GLenum) -> GLboolean1290 fn is_texture(&self, texture: GLenum) -> GLboolean { 1291 unsafe { self.ffi_gl_.IsTexture(texture) } 1292 } 1293 is_framebuffer(&self, framebuffer: GLenum) -> GLboolean1294 fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean { 1295 unsafe { self.ffi_gl_.IsFramebuffer(framebuffer) } 1296 } 1297 is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean1298 fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean { 1299 unsafe { self.ffi_gl_.IsRenderbuffer(renderbuffer) } 1300 } 1301 check_frame_buffer_status(&self, target: GLenum) -> GLenum1302 fn check_frame_buffer_status(&self, target: GLenum) -> GLenum { 1303 unsafe { self.ffi_gl_.CheckFramebufferStatus(target) } 1304 } 1305 enable_vertex_attrib_array(&self, index: GLuint)1306 fn enable_vertex_attrib_array(&self, index: GLuint) { 1307 unsafe { 1308 self.ffi_gl_.EnableVertexAttribArray(index); 1309 } 1310 } 1311 disable_vertex_attrib_array(&self, index: GLuint)1312 fn disable_vertex_attrib_array(&self, index: GLuint) { 1313 unsafe { 1314 self.ffi_gl_.DisableVertexAttribArray(index); 1315 } 1316 } 1317 uniform_1f(&self, location: GLint, v0: GLfloat)1318 fn uniform_1f(&self, location: GLint, v0: GLfloat) { 1319 unsafe { 1320 self.ffi_gl_.Uniform1f(location, v0); 1321 } 1322 } 1323 uniform_1fv(&self, location: GLint, values: &[f32])1324 fn uniform_1fv(&self, location: GLint, values: &[f32]) { 1325 unsafe { 1326 self.ffi_gl_ 1327 .Uniform1fv(location, values.len() as GLsizei, values.as_ptr()); 1328 } 1329 } 1330 uniform_1i(&self, location: GLint, v0: GLint)1331 fn uniform_1i(&self, location: GLint, v0: GLint) { 1332 unsafe { 1333 self.ffi_gl_.Uniform1i(location, v0); 1334 } 1335 } 1336 uniform_1iv(&self, location: GLint, values: &[i32])1337 fn uniform_1iv(&self, location: GLint, values: &[i32]) { 1338 unsafe { 1339 self.ffi_gl_ 1340 .Uniform1iv(location, values.len() as GLsizei, values.as_ptr()); 1341 } 1342 } 1343 1344 #[allow(unused_variables)] uniform_1ui(&self, location: GLint, v0: GLuint)1345 fn uniform_1ui(&self, location: GLint, v0: GLuint) { 1346 panic!("not supported") 1347 } 1348 uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat)1349 fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) { 1350 unsafe { 1351 self.ffi_gl_.Uniform2f(location, v0, v1); 1352 } 1353 } 1354 uniform_2fv(&self, location: GLint, values: &[f32])1355 fn uniform_2fv(&self, location: GLint, values: &[f32]) { 1356 unsafe { 1357 self.ffi_gl_ 1358 .Uniform2fv(location, (values.len() / 2) as GLsizei, values.as_ptr()); 1359 } 1360 } 1361 uniform_2i(&self, location: GLint, v0: GLint, v1: GLint)1362 fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) { 1363 unsafe { 1364 self.ffi_gl_.Uniform2i(location, v0, v1); 1365 } 1366 } 1367 uniform_2iv(&self, location: GLint, values: &[i32])1368 fn uniform_2iv(&self, location: GLint, values: &[i32]) { 1369 unsafe { 1370 self.ffi_gl_ 1371 .Uniform2iv(location, (values.len() / 2) as GLsizei, values.as_ptr()); 1372 } 1373 } 1374 1375 #[allow(unused_variables)] uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint)1376 fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) { 1377 panic!("not supported") 1378 } 1379 uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat)1380 fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) { 1381 unsafe { 1382 self.ffi_gl_.Uniform3f(location, v0, v1, v2); 1383 } 1384 } 1385 uniform_3fv(&self, location: GLint, values: &[f32])1386 fn uniform_3fv(&self, location: GLint, values: &[f32]) { 1387 unsafe { 1388 self.ffi_gl_ 1389 .Uniform3fv(location, (values.len() / 3) as GLsizei, values.as_ptr()); 1390 } 1391 } 1392 uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint)1393 fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) { 1394 unsafe { 1395 self.ffi_gl_.Uniform3i(location, v0, v1, v2); 1396 } 1397 } 1398 uniform_3iv(&self, location: GLint, values: &[i32])1399 fn uniform_3iv(&self, location: GLint, values: &[i32]) { 1400 unsafe { 1401 self.ffi_gl_ 1402 .Uniform3iv(location, (values.len() / 3) as GLsizei, values.as_ptr()); 1403 } 1404 } 1405 1406 #[allow(unused_variables)] uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint)1407 fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) { 1408 panic!("not supported") 1409 } 1410 uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat)1411 fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) { 1412 unsafe { 1413 self.ffi_gl_.Uniform4f(location, x, y, z, w); 1414 } 1415 } 1416 uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint)1417 fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) { 1418 unsafe { 1419 self.ffi_gl_.Uniform4i(location, x, y, z, w); 1420 } 1421 } 1422 uniform_4iv(&self, location: GLint, values: &[i32])1423 fn uniform_4iv(&self, location: GLint, values: &[i32]) { 1424 unsafe { 1425 self.ffi_gl_ 1426 .Uniform4iv(location, (values.len() / 4) as GLsizei, values.as_ptr()); 1427 } 1428 } 1429 1430 #[allow(unused_variables)] uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint)1431 fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) { 1432 panic!("not supported") 1433 } 1434 uniform_4fv(&self, location: GLint, values: &[f32])1435 fn uniform_4fv(&self, location: GLint, values: &[f32]) { 1436 unsafe { 1437 self.ffi_gl_ 1438 .Uniform4fv(location, (values.len() / 4) as GLsizei, values.as_ptr()); 1439 } 1440 } 1441 uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32])1442 fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]) { 1443 unsafe { 1444 self.ffi_gl_.UniformMatrix2fv( 1445 location, 1446 (value.len() / 4) as GLsizei, 1447 transpose as GLboolean, 1448 value.as_ptr(), 1449 ); 1450 } 1451 } 1452 uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32])1453 fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]) { 1454 unsafe { 1455 self.ffi_gl_.UniformMatrix3fv( 1456 location, 1457 (value.len() / 9) as GLsizei, 1458 transpose as GLboolean, 1459 value.as_ptr(), 1460 ); 1461 } 1462 } 1463 uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32])1464 fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]) { 1465 unsafe { 1466 self.ffi_gl_.UniformMatrix4fv( 1467 location, 1468 (value.len() / 16) as GLsizei, 1469 transpose as GLboolean, 1470 value.as_ptr(), 1471 ); 1472 } 1473 } 1474 depth_mask(&self, flag: bool)1475 fn depth_mask(&self, flag: bool) { 1476 unsafe { 1477 self.ffi_gl_.DepthMask(flag as GLboolean); 1478 } 1479 } 1480 depth_range(&self, near: f64, far: f64)1481 fn depth_range(&self, near: f64, far: f64) { 1482 unsafe { 1483 self.ffi_gl_.DepthRangef(near as GLclampf, far as GLclampf); 1484 } 1485 } 1486 get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String)1487 fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String) { 1488 let mut buf_size = [0]; 1489 unsafe { 1490 self.get_program_iv(program, ffi::ACTIVE_ATTRIBUTE_MAX_LENGTH, &mut buf_size); 1491 } 1492 let mut name = vec![0u8; buf_size[0] as usize]; 1493 let mut length = 0 as GLsizei; 1494 let mut size = 0 as i32; 1495 let mut type_ = 0 as u32; 1496 unsafe { 1497 self.ffi_gl_.GetActiveAttrib( 1498 program, 1499 index, 1500 buf_size[0], 1501 &mut length, 1502 &mut size, 1503 &mut type_, 1504 name.as_mut_ptr() as *mut GLchar, 1505 ); 1506 } 1507 name.truncate(if length > 0 { length as usize } else { 0 }); 1508 (size, type_, String::from_utf8(name).unwrap()) 1509 } 1510 get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String)1511 fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String) { 1512 let mut buf_size = [0]; 1513 unsafe { 1514 self.get_program_iv(program, ffi::ACTIVE_UNIFORM_MAX_LENGTH, &mut buf_size); 1515 } 1516 let mut name = vec![0 as u8; buf_size[0] as usize]; 1517 let mut length: GLsizei = 0; 1518 let mut size: i32 = 0; 1519 let mut type_: u32 = 0; 1520 1521 unsafe { 1522 self.ffi_gl_.GetActiveUniform( 1523 program, 1524 index, 1525 buf_size[0], 1526 &mut length, 1527 &mut size, 1528 &mut type_, 1529 name.as_mut_ptr() as *mut GLchar, 1530 ); 1531 } 1532 1533 name.truncate(if length > 0 { length as usize } else { 0 }); 1534 1535 (size, type_, String::from_utf8(name).unwrap()) 1536 } 1537 get_active_uniforms_iv( &self, program: GLuint, indices: Vec<GLuint>, pname: GLenum, ) -> Vec<GLint>1538 fn get_active_uniforms_iv( 1539 &self, 1540 program: GLuint, 1541 indices: Vec<GLuint>, 1542 pname: GLenum, 1543 ) -> Vec<GLint> { 1544 let mut result = Vec::with_capacity(indices.len()); 1545 unsafe { 1546 result.set_len(indices.len()); 1547 self.ffi_gl_.GetActiveUniformsiv( 1548 program, 1549 indices.len() as GLsizei, 1550 indices.as_ptr(), 1551 pname, 1552 result.as_mut_ptr(), 1553 ); 1554 } 1555 result 1556 } 1557 get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint1558 fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint { 1559 let mut result = 0 as GLint; 1560 unsafe { 1561 self.ffi_gl_ 1562 .GetActiveUniformBlockiv(program, index, pname, &mut result); 1563 } 1564 result 1565 } 1566 get_active_uniform_block_iv( &self, program: GLuint, index: GLuint, pname: GLenum, ) -> Vec<GLint>1567 fn get_active_uniform_block_iv( 1568 &self, 1569 program: GLuint, 1570 index: GLuint, 1571 pname: GLenum, 1572 ) -> Vec<GLint> { 1573 let count = 1574 self.get_active_uniform_block_i(program, index, ffi::UNIFORM_BLOCK_ACTIVE_UNIFORMS); 1575 let mut result = Vec::with_capacity(count as usize); 1576 unsafe { 1577 result.set_len(count as usize); 1578 self.ffi_gl_ 1579 .GetActiveUniformBlockiv(program, index, pname, result.as_mut_ptr()); 1580 } 1581 result 1582 } 1583 get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String1584 fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String { 1585 let buf_size = 1586 self.get_active_uniform_block_i(program, index, ffi::UNIFORM_BLOCK_NAME_LENGTH); 1587 let mut name = vec![0 as u8; buf_size as usize]; 1588 let mut length: GLsizei = 0; 1589 unsafe { 1590 self.ffi_gl_.GetActiveUniformBlockName( 1591 program, 1592 index, 1593 buf_size, 1594 &mut length, 1595 name.as_mut_ptr() as *mut GLchar, 1596 ); 1597 } 1598 name.truncate(if length > 0 { length as usize } else { 0 }); 1599 1600 String::from_utf8(name).unwrap() 1601 } 1602 get_attrib_location(&self, program: GLuint, name: &str) -> c_int1603 fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int { 1604 let name = CString::new(name).unwrap(); 1605 unsafe { self.ffi_gl_.GetAttribLocation(program, name.as_ptr()) } 1606 } 1607 1608 #[allow(unused_variables)] get_frag_data_location(&self, program: GLuint, name: &str) -> c_int1609 fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int { 1610 panic!("not supported") 1611 } 1612 get_uniform_location(&self, program: GLuint, name: &str) -> c_int1613 fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int { 1614 let name = CString::new(name).unwrap(); 1615 unsafe { self.ffi_gl_.GetUniformLocation(program, name.as_ptr()) } 1616 } 1617 get_program_info_log(&self, program: GLuint) -> String1618 fn get_program_info_log(&self, program: GLuint) -> String { 1619 let mut max_len = [0]; 1620 unsafe { 1621 self.get_program_iv(program, ffi::INFO_LOG_LENGTH, &mut max_len); 1622 } 1623 if max_len[0] == 0 { 1624 return String::new(); 1625 } 1626 let mut result = vec![0u8; max_len[0] as usize]; 1627 let mut result_len = 0 as GLsizei; 1628 unsafe { 1629 self.ffi_gl_.GetProgramInfoLog( 1630 program, 1631 max_len[0] as GLsizei, 1632 &mut result_len, 1633 result.as_mut_ptr() as *mut GLchar, 1634 ); 1635 } 1636 result.truncate(if result_len > 0 { 1637 result_len as usize 1638 } else { 1639 0 1640 }); 1641 String::from_utf8(result).unwrap() 1642 } 1643 1644 #[inline] get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint])1645 unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]) { 1646 assert!(!result.is_empty()); 1647 self.ffi_gl_ 1648 .GetProgramiv(program, pname, result.as_mut_ptr()); 1649 } 1650 get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum)1651 fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum) { 1652 let mut len = [0]; 1653 unsafe { 1654 self.get_program_iv(program, ffi::PROGRAM_BINARY_LENGTH, &mut len); 1655 } 1656 if len[0] <= 0 { 1657 return (Vec::new(), NONE); 1658 } 1659 let mut binary: Vec<u8> = Vec::with_capacity(len[0] as usize); 1660 let mut format = NONE; 1661 let mut out_len = 0; 1662 unsafe { 1663 binary.set_len(len[0] as usize); 1664 self.ffi_gl_.GetProgramBinary( 1665 program, 1666 len[0], 1667 &mut out_len as *mut GLsizei, 1668 &mut format, 1669 binary.as_mut_ptr() as *mut c_void, 1670 ); 1671 } 1672 if len[0] != out_len { 1673 return (Vec::new(), NONE); 1674 } 1675 1676 (binary, format) 1677 } 1678 program_binary(&self, program: GLuint, format: GLenum, binary: &[u8])1679 fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]) { 1680 unsafe { 1681 self.ffi_gl_.ProgramBinary( 1682 program, 1683 format, 1684 binary.as_ptr() as *const c_void, 1685 binary.len() as GLsizei, 1686 ); 1687 } 1688 } 1689 program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint)1690 fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint) { 1691 unsafe { 1692 self.ffi_gl_.ProgramParameteri(program, pname, value); 1693 } 1694 } 1695 1696 #[inline] get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint])1697 unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]) { 1698 assert!(!result.is_empty()); 1699 self.ffi_gl_ 1700 .GetVertexAttribiv(index, pname, result.as_mut_ptr()); 1701 } 1702 1703 #[inline] get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat])1704 unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]) { 1705 assert!(!result.is_empty()); 1706 self.ffi_gl_ 1707 .GetVertexAttribfv(index, pname, result.as_mut_ptr()); 1708 } 1709 get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr1710 fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr { 1711 let mut result = 0 as *mut GLvoid; 1712 unsafe { 1713 self.ffi_gl_ 1714 .GetVertexAttribPointerv(index, pname, &mut result) 1715 } 1716 result as GLsizeiptr 1717 } 1718 get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint1719 fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint { 1720 let mut result = 0 as GLint; 1721 unsafe { 1722 self.ffi_gl_ 1723 .GetBufferParameteriv(target, pname, &mut result); 1724 } 1725 result 1726 } 1727 get_shader_info_log(&self, shader: GLuint) -> String1728 fn get_shader_info_log(&self, shader: GLuint) -> String { 1729 let mut max_len = [0]; 1730 unsafe { 1731 self.get_shader_iv(shader, ffi::INFO_LOG_LENGTH, &mut max_len); 1732 } 1733 if max_len[0] == 0 { 1734 return String::new(); 1735 } 1736 let mut result = vec![0u8; max_len[0] as usize]; 1737 let mut result_len = 0 as GLsizei; 1738 unsafe { 1739 self.ffi_gl_.GetShaderInfoLog( 1740 shader, 1741 max_len[0] as GLsizei, 1742 &mut result_len, 1743 result.as_mut_ptr() as *mut GLchar, 1744 ); 1745 } 1746 result.truncate(if result_len > 0 { 1747 result_len as usize 1748 } else { 1749 0 1750 }); 1751 String::from_utf8(result).unwrap() 1752 } 1753 get_string(&self, which: GLenum) -> String1754 fn get_string(&self, which: GLenum) -> String { 1755 unsafe { 1756 let llstr = self.ffi_gl_.GetString(which); 1757 if !llstr.is_null() { 1758 return str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes()) 1759 .to_string(); 1760 } else { 1761 return "".to_string(); 1762 } 1763 } 1764 } 1765 get_string_i(&self, which: GLenum, index: GLuint) -> String1766 fn get_string_i(&self, which: GLenum, index: GLuint) -> String { 1767 unsafe { 1768 let llstr = self.ffi_gl_.GetStringi(which, index); 1769 if !llstr.is_null() { 1770 str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes()) 1771 .to_string() 1772 } else { 1773 "".to_string() 1774 } 1775 } 1776 } 1777 get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint])1778 unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]) { 1779 assert!(!result.is_empty()); 1780 self.ffi_gl_.GetShaderiv(shader, pname, result.as_mut_ptr()); 1781 } 1782 get_shader_precision_format( &self, shader_type: GLuint, precision_type: GLuint, ) -> (GLint, GLint, GLint)1783 fn get_shader_precision_format( 1784 &self, 1785 shader_type: GLuint, 1786 precision_type: GLuint, 1787 ) -> (GLint, GLint, GLint) { 1788 let (mut range, mut precision) = match precision_type { 1789 // These values are for a 32-bit twos-complement integer format. 1790 ffi::LOW_INT | ffi::MEDIUM_INT | ffi::HIGH_INT => ([31, 30], 0), 1791 1792 // These values are for an IEEE single-precision floating-point format. 1793 ffi::LOW_FLOAT | ffi::MEDIUM_FLOAT | ffi::HIGH_FLOAT => ([127, 127], 23), 1794 1795 _ => unreachable!("invalid precision"), 1796 }; 1797 // This function is sometimes defined even though it's really just 1798 // a stub, so we need to set range and precision as if it weren't 1799 // defined before calling it. Suppress any error that might occur. 1800 unsafe { 1801 self.ffi_gl_.GetShaderPrecisionFormat( 1802 shader_type, 1803 precision_type, 1804 range.as_mut_ptr(), 1805 &mut precision, 1806 ); 1807 let _ = self.ffi_gl_.GetError(); 1808 } 1809 1810 (range[0], range[1], precision) 1811 } 1812 compile_shader(&self, shader: GLuint)1813 fn compile_shader(&self, shader: GLuint) { 1814 unsafe { 1815 self.ffi_gl_.CompileShader(shader); 1816 } 1817 } 1818 create_program(&self) -> GLuint1819 fn create_program(&self) -> GLuint { 1820 unsafe { 1821 return self.ffi_gl_.CreateProgram(); 1822 } 1823 } 1824 delete_program(&self, program: GLuint)1825 fn delete_program(&self, program: GLuint) { 1826 unsafe { 1827 self.ffi_gl_.DeleteProgram(program); 1828 } 1829 } 1830 create_shader(&self, shader_type: GLenum) -> GLuint1831 fn create_shader(&self, shader_type: GLenum) -> GLuint { 1832 unsafe { 1833 return self.ffi_gl_.CreateShader(shader_type); 1834 } 1835 } 1836 delete_shader(&self, shader: GLuint)1837 fn delete_shader(&self, shader: GLuint) { 1838 unsafe { 1839 self.ffi_gl_.DeleteShader(shader); 1840 } 1841 } 1842 detach_shader(&self, program: GLuint, shader: GLuint)1843 fn detach_shader(&self, program: GLuint, shader: GLuint) { 1844 unsafe { 1845 self.ffi_gl_.DetachShader(program, shader); 1846 } 1847 } 1848 link_program(&self, program: GLuint)1849 fn link_program(&self, program: GLuint) { 1850 unsafe { 1851 return self.ffi_gl_.LinkProgram(program); 1852 } 1853 } 1854 clear_color(&self, r: f32, g: f32, b: f32, a: f32)1855 fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) { 1856 unsafe { 1857 self.ffi_gl_.ClearColor(r, g, b, a); 1858 } 1859 } 1860 clear(&self, buffer_mask: GLbitfield)1861 fn clear(&self, buffer_mask: GLbitfield) { 1862 unsafe { 1863 self.ffi_gl_.Clear(buffer_mask); 1864 } 1865 } 1866 clear_depth(&self, depth: f64)1867 fn clear_depth(&self, depth: f64) { 1868 unsafe { 1869 self.ffi_gl_.ClearDepthf(depth as GLclampf); 1870 } 1871 } 1872 clear_stencil(&self, s: GLint)1873 fn clear_stencil(&self, s: GLint) { 1874 unsafe { 1875 self.ffi_gl_.ClearStencil(s); 1876 } 1877 } 1878 flush(&self)1879 fn flush(&self) { 1880 unsafe { 1881 self.ffi_gl_.Flush(); 1882 } 1883 } 1884 finish(&self)1885 fn finish(&self) { 1886 unsafe { 1887 self.ffi_gl_.Finish(); 1888 } 1889 } 1890 get_error(&self) -> GLenum1891 fn get_error(&self) -> GLenum { 1892 unsafe { self.ffi_gl_.GetError() } 1893 } 1894 stencil_mask(&self, mask: GLuint)1895 fn stencil_mask(&self, mask: GLuint) { 1896 unsafe { self.ffi_gl_.StencilMask(mask) } 1897 } 1898 stencil_mask_separate(&self, face: GLenum, mask: GLuint)1899 fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) { 1900 unsafe { self.ffi_gl_.StencilMaskSeparate(face, mask) } 1901 } 1902 stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint)1903 fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) { 1904 unsafe { self.ffi_gl_.StencilFunc(func, ref_, mask) } 1905 } 1906 stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint)1907 fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) { 1908 unsafe { self.ffi_gl_.StencilFuncSeparate(face, func, ref_, mask) } 1909 } 1910 stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum)1911 fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) { 1912 unsafe { self.ffi_gl_.StencilOp(sfail, dpfail, dppass) } 1913 } 1914 stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum)1915 fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum) { 1916 unsafe { self.ffi_gl_.StencilOpSeparate(face, sfail, dpfail, dppass) } 1917 } 1918 egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES)1919 fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES) { 1920 unsafe { 1921 self.ffi_gl_.EGLImageTargetTexture2DOES(target, image); 1922 } 1923 } 1924 generate_mipmap(&self, target: GLenum)1925 fn generate_mipmap(&self, target: GLenum) { 1926 unsafe { self.ffi_gl_.GenerateMipmap(target) } 1927 } 1928 insert_event_marker_ext(&self, message: &str)1929 fn insert_event_marker_ext(&self, message: &str) { 1930 if self.ffi_gl_.InsertEventMarkerEXT.is_loaded() { 1931 unsafe { 1932 self.ffi_gl_ 1933 .InsertEventMarkerEXT(message.len() as GLsizei, message.as_ptr() as *const _); 1934 } 1935 } 1936 } 1937 push_group_marker_ext(&self, message: &str)1938 fn push_group_marker_ext(&self, message: &str) { 1939 if self.ffi_gl_.PushGroupMarkerEXT.is_loaded() { 1940 unsafe { 1941 self.ffi_gl_ 1942 .PushGroupMarkerEXT(message.len() as GLsizei, message.as_ptr() as *const _); 1943 } 1944 } 1945 } 1946 pop_group_marker_ext(&self)1947 fn pop_group_marker_ext(&self) { 1948 if self.ffi_gl_.PopGroupMarkerEXT.is_loaded() { 1949 unsafe { 1950 self.ffi_gl_.PopGroupMarkerEXT(); 1951 } 1952 } 1953 } 1954 debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str)1955 fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) { 1956 if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() { 1957 unsafe { 1958 self.ffi_gl_ 1959 .DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _); 1960 } 1961 } 1962 } 1963 push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str)1964 fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) { 1965 if self.ffi_gl_.PushDebugGroupKHR.is_loaded() { 1966 unsafe { 1967 self.ffi_gl_ 1968 .PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _); 1969 } 1970 } 1971 } 1972 pop_debug_group_khr(&self)1973 fn pop_debug_group_khr(&self) { 1974 if self.ffi_gl_.PopDebugGroupKHR.is_loaded() { 1975 unsafe { 1976 self.ffi_gl_.PopDebugGroupKHR(); 1977 } 1978 } 1979 } 1980 fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync1981 fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync { 1982 unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ } 1983 } 1984 client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64)1985 fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) { 1986 unsafe { 1987 self.ffi_gl_ 1988 .ClientWaitSync(sync as *const _, flags, timeout); 1989 } 1990 } 1991 wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64)1992 fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) { 1993 unsafe { 1994 self.ffi_gl_.WaitSync(sync as *const _, flags, timeout); 1995 } 1996 } 1997 delete_sync(&self, sync: GLsync)1998 fn delete_sync(&self, sync: GLsync) { 1999 unsafe { 2000 self.ffi_gl_.DeleteSync(sync as *const _); 2001 } 2002 } 2003 texture_range_apple(&self, _target: GLenum, _data: &[u8])2004 fn texture_range_apple(&self, _target: GLenum, _data: &[u8]) { 2005 panic!("not supported") 2006 } 2007 gen_fences_apple(&self, _n: GLsizei) -> Vec<GLuint>2008 fn gen_fences_apple(&self, _n: GLsizei) -> Vec<GLuint> { 2009 panic!("not supported") 2010 } 2011 delete_fences_apple(&self, _fences: &[GLuint])2012 fn delete_fences_apple(&self, _fences: &[GLuint]) { 2013 panic!("not supported") 2014 } 2015 set_fence_apple(&self, _fence: GLuint)2016 fn set_fence_apple(&self, _fence: GLuint) { 2017 panic!("not supported") 2018 } 2019 finish_fence_apple(&self, _fence: GLuint)2020 fn finish_fence_apple(&self, _fence: GLuint) { 2021 panic!("not supported") 2022 } 2023 test_fence_apple(&self, _fence: GLuint)2024 fn test_fence_apple(&self, _fence: GLuint) { 2025 panic!("not supported") 2026 } 2027 test_object_apple(&self, _object: GLenum, _name: GLuint) -> GLboolean2028 fn test_object_apple(&self, _object: GLenum, _name: GLuint) -> GLboolean { 2029 panic!("not supported") 2030 } 2031 finish_object_apple(&self, _object: GLenum, _name: GLuint)2032 fn finish_object_apple(&self, _object: GLenum, _name: GLuint) { 2033 panic!("not supported") 2034 } 2035 2036 2037 2038 // GL_ARB_blend_func_extended bind_frag_data_location_indexed( &self, _program: GLuint, _color_number: GLuint, _index: GLuint, _name: &str, )2039 fn bind_frag_data_location_indexed( 2040 &self, 2041 _program: GLuint, 2042 _color_number: GLuint, 2043 _index: GLuint, 2044 _name: &str, 2045 ) { 2046 panic!("not supported"); 2047 } 2048 get_frag_data_index(&self, _program: GLuint, _name: &str) -> GLint2049 fn get_frag_data_index(&self, _program: GLuint, _name: &str) -> GLint { 2050 panic!("not supported"); 2051 } 2052 2053 // GL_KHR_debug get_debug_messages(&self) -> Vec<DebugMessage>2054 fn get_debug_messages(&self) -> Vec<DebugMessage> { 2055 if !self.ffi_gl_.GetDebugMessageLog.is_loaded() { 2056 return Vec::new(); 2057 } 2058 2059 let mut max_message_len = 0; 2060 unsafe { 2061 self.ffi_gl_ 2062 .GetIntegerv(ffi::MAX_DEBUG_MESSAGE_LENGTH, &mut max_message_len) 2063 } 2064 2065 let mut output = Vec::new(); 2066 const CAPACITY: usize = 4; 2067 2068 let mut msg_data = vec![0u8; CAPACITY * max_message_len as usize]; 2069 let mut sources = [0 as GLenum; CAPACITY]; 2070 let mut types = [0 as GLenum; CAPACITY]; 2071 let mut severities = [0 as GLenum; CAPACITY]; 2072 let mut ids = [0 as GLuint; CAPACITY]; 2073 let mut lengths = [0 as GLsizei; CAPACITY]; 2074 2075 loop { 2076 let count = unsafe { 2077 self.ffi_gl_.GetDebugMessageLog( 2078 CAPACITY as _, 2079 msg_data.len() as _, 2080 sources.as_mut_ptr(), 2081 types.as_mut_ptr(), 2082 ids.as_mut_ptr(), 2083 severities.as_mut_ptr(), 2084 lengths.as_mut_ptr(), 2085 msg_data.as_mut_ptr() as *mut _, 2086 ) 2087 }; 2088 2089 let mut offset = 0; 2090 output.extend((0..count as usize).map(|i| { 2091 let len = lengths[i] as usize; 2092 let slice = &msg_data[offset..offset + len]; 2093 offset += len; 2094 DebugMessage { 2095 message: String::from_utf8_lossy(slice).to_string(), 2096 source: sources[i], 2097 ty: types[i], 2098 id: ids[i], 2099 severity: severities[i], 2100 } 2101 })); 2102 2103 if (count as usize) < CAPACITY { 2104 return output; 2105 } 2106 } 2107 } 2108 provoking_vertex_angle(&self, mode: GLenum)2109 fn provoking_vertex_angle(&self, mode: GLenum) { 2110 unsafe { 2111 self.ffi_gl_.ProvokingVertexANGLE(mode); 2112 } 2113 } 2114 2115 // GL_KHR_blend_equation_advanced blend_barrier_khr(&self)2116 fn blend_barrier_khr(&self) { 2117 if self.ffi_gl_.BlendBarrierKHR.is_loaded() { 2118 unsafe { 2119 self.ffi_gl_.BlendBarrierKHR(); 2120 } 2121 } 2122 } 2123 } 2124