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