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