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