rust/lib-hedgewars-engine/src/render/gl.rs
changeset 15783 e7eb0cd5b0e4
parent 15782 ff1432e873bd
child 15784 84c07aa94b61
equal deleted inserted replaced
15782:ff1432e873bd 15783:e7eb0cd5b0e4
   129         data: &[u8],
   129         data: &[u8],
   130         data_stride: Option<NonZeroU32>,
   130         data_stride: Option<NonZeroU32>,
   131         size: Size,
   131         size: Size,
   132         internal_format: TextureInternalFormat,
   132         internal_format: TextureInternalFormat,
   133         format: TextureFormat,
   133         format: TextureFormat,
   134         ty: TextureDataType,
   134         data_type: TextureDataType,
   135         filter: TextureFilter,
   135         filter: TextureFilter,
   136     ) -> Self {
   136     ) -> Self {
   137         if is_out_of_bounds(data, data_stride, size) {
   137         if is_out_of_bounds(data, data_stride, size) {
   138             return Self { handle: None, size };
   138             return Self { handle: None, size };
   139         }
   139         }
   148                     internal_format as i32,
   148                     internal_format as i32,
   149                     size.width as i32,
   149                     size.width as i32,
   150                     size.height as i32,
   150                     size.height as i32,
   151                     0,
   151                     0,
   152                     format as u32,
   152                     format as u32,
   153                     ty as u32,
   153                     data_type as u32,
   154                     data.as_ptr() as *const _,
   154                     data.as_ptr() as *const _,
   155                 )
   155                 )
   156             }
   156             }
   157 
   157 
   158             tex_params(filter);
   158             tex_params(filter);
   169         &self,
   169         &self,
   170         region: Rect,
   170         region: Rect,
   171         data: &[u8],
   171         data: &[u8],
   172         data_stride: Option<NonZeroU32>,
   172         data_stride: Option<NonZeroU32>,
   173         format: TextureFormat,
   173         format: TextureFormat,
   174         ty: TextureDataType,
   174         data_type: TextureDataType,
   175     ) {
   175     ) {
   176         if is_out_of_bounds(data, data_stride, self.size) {
   176         if is_out_of_bounds(data, data_stride, self.size) {
   177             return;
   177             return;
   178         }
   178         }
   179 
   179 
   187                     region.left(),
   187                     region.left(),
   188                     region.top(),
   188                     region.top(),
   189                     region.width() as i32,
   189                     region.width() as i32,
   190                     region.height() as i32,
   190                     region.height() as i32,
   191                     format as u32,
   191                     format as u32,
   192                     ty as u32,
   192                     data_type as u32,
   193                     data.as_ptr() as *const _,
   193                     data.as_ptr() as *const _,
   194                 );
   194                 );
   195             }
   195             }
   196         }
   196         }
   197     }
   197     }
   214             }
   214             }
   215         }
   215         }
   216     }
   216     }
   217 }
   217 }
   218 
   218 
       
   219 #[derive(Clone, Copy, Debug)]
       
   220 #[repr(u32)]
       
   221 pub enum BufferType {
       
   222     Array = gl::ARRAY_BUFFER,
       
   223     ElementArray = gl::ELEMENT_ARRAY_BUFFER,
       
   224 }
       
   225 
       
   226 #[derive(Clone, Copy, Debug)]
       
   227 #[repr(u32)]
       
   228 pub enum BufferUsage {
       
   229     DynamicDraw = gl::DYNAMIC_DRAW,
       
   230 }
       
   231 
   219 #[derive(Debug)]
   232 #[derive(Debug)]
   220 pub struct Buffer {
   233 pub struct Buffer {
   221     pub handle: u32,
   234     pub handle: Option<NonZeroU32>,
   222     pub ty: u32,
   235     pub buffer_type: BufferType,
   223     pub usage: u32,
   236     pub usage: BufferUsage,
   224 }
   237 }
   225 
   238 
   226 impl Buffer {
   239 impl Buffer {
   227     pub fn empty(
   240     pub fn empty(buffer_type: BufferType, usage: BufferUsage) -> Buffer {
   228         ty: u32,
       
   229         usage: u32,
       
   230         //size: isize
       
   231     ) -> Buffer {
       
   232         let mut buffer = 0;
   241         let mut buffer = 0;
   233 
   242 
   234         unsafe {
   243         unsafe {
   235             gl::GenBuffers(1, &mut buffer);
   244             gl::GenBuffers(1, &mut buffer);
   236             gl::BindBuffer(ty, buffer);
       
   237             //gl::BufferData(ty, size, ptr::null_mut(), usage);
       
   238         }
   245         }
   239 
   246 
   240         Buffer {
   247         Buffer {
   241             handle: buffer,
   248             handle: NonZeroU32::new(buffer),
   242             ty,
   249             buffer_type: buffer_type,
   243             usage,
   250             usage,
   244         }
   251         }
   245     }
   252     }
   246 
   253 
   247     fn with_data(ty: u32, usage: u32, data: &[u8]) -> Buffer {
   254     fn with_data(buffer_type: BufferType, usage: BufferUsage, data: &[u8]) -> Buffer {
   248         let mut buffer = 0;
   255         let mut buffer = 0;
   249 
   256 
   250         unsafe {
   257         unsafe {
   251             gl::GenBuffers(1, &mut buffer);
   258             gl::GenBuffers(1, &mut buffer);
   252             gl::BindBuffer(ty, buffer);
   259             if buffer != 0 {
   253             gl::BufferData(ty, data.len() as isize, data.as_ptr() as _, usage);
   260                 gl::BindBuffer(buffer_type as u32, buffer);
       
   261                 gl::BufferData(
       
   262                     buffer_type as u32,
       
   263                     data.len() as isize,
       
   264                     data.as_ptr() as _,
       
   265                     usage as u32,
       
   266                 );
       
   267             }
   254         }
   268         }
   255 
   269 
   256         Buffer {
   270         Buffer {
   257             handle: buffer,
   271             handle: NonZeroU32::new(buffer),
   258             ty,
   272             buffer_type,
   259             usage,
   273             usage,
   260         }
   274         }
   261     }
   275     }
   262 
   276 
   263     pub fn ty(&self) -> u32 {
   277     pub fn ty(&self) -> BufferType {
   264         self.ty
   278         self.buffer_type
   265     }
   279     }
   266 
   280 
   267     pub fn handle(&self) -> u32 {
   281     pub fn handle(&self) -> Option<NonZeroU32> {
   268         self.handle
   282         self.handle
   269     }
   283     }
   270 
   284 
   271     pub fn write_typed<T>(&self, data: &[T]) {
   285     pub fn write_typed<T>(&self, data: &[T]) {
   272         unsafe {
   286         if let Some(handle) = self.handle {
   273             let data =
   287             unsafe {
   274                 slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * mem::size_of::<T>());
   288                 gl::BindBuffer(self.buffer_type as u32, handle.get());
   275 
   289                 gl::BufferData(
   276             gl::BindBuffer(self.ty, self.handle);
   290                     self.buffer_type as u32,
   277             gl::BufferData(
   291                     (data.len() * mem::size_of::<T>()) as isize,
   278                 self.ty,
   292                     data.as_ptr() as *const _,
   279                 data.len() as isize,
   293                     self.usage as u32,
   280                 data.as_ptr() as *const _ as *const _,
   294                 );
   281                 self.usage,
   295             }
   282             );
       
   283         }
   296         }
   284     }
   297     }
   285 
   298 
   286     pub fn write(&self, data: &[u8]) {
   299     pub fn write(&self, data: &[u8]) {
   287         unsafe {
   300         if let Some(handle) = self.handle {
   288             gl::BindBuffer(self.ty, self.handle);
   301             unsafe {
   289             gl::BufferData(
   302                 gl::BindBuffer(self.buffer_type as u32, handle.get());
   290                 self.ty,
   303                 gl::BufferData(
   291                 data.len() as isize,
   304                     self.buffer_type as u32,
   292                 data.as_ptr() as *const _ as *const _,
   305                     data.len() as isize,
   293                 self.usage,
   306                     data.as_ptr() as *const _,
   294             );
   307                     self.usage as u32,
       
   308                 );
       
   309             }
   295         }
   310         }
   296     }
   311     }
   297 }
   312 }
   298 
   313 
   299 impl Drop for Buffer {
   314 impl Drop for Buffer {
   300     fn drop(&mut self) {
   315     fn drop(&mut self) {
   301         unsafe {
   316         if let Some(handle) = self.handle {
   302             gl::DeleteBuffers(1, &self.handle);
   317             let handle = handle.get();
       
   318             unsafe {
       
   319                 gl::DeleteBuffers(1, &handle);
       
   320             }
   303         }
   321         }
   304     }
   322     }
   305 }
   323 }
   306 
   324 
   307 #[derive(Debug)]
   325 #[derive(Debug)]
   329     pub fn new<'a>(
   347     pub fn new<'a>(
   330         vs: &str,
   348         vs: &str,
   331         ps: Option<&str>,
   349         ps: Option<&str>,
   332         bindings: &[VariableBinding<'a>],
   350         bindings: &[VariableBinding<'a>],
   333     ) -> Result<Self, String> {
   351     ) -> Result<Self, String> {
   334         unsafe fn compile_shader(ty: u32, shdr: &str) -> Result<u32, String> {
   352         unsafe fn compile_shader(shader_type: u32, shader_code: &str) -> Result<u32, String> {
   335             let shader = gl::CreateShader(ty);
   353             let shader = gl::CreateShader(shader_type);
   336             let len = shdr.len() as i32;
   354             let len = shader_code.len() as i32;
   337             let shdr = shdr.as_ptr() as *const i8;
   355             let code_strings = shader_code.as_ptr() as *const i8;
   338             gl::ShaderSource(shader, 1, &shdr, &len);
   356             gl::ShaderSource(shader, 1, &code_strings, &len);
   339             gl::CompileShader(shader);
   357             gl::CompileShader(shader);
   340 
   358 
   341             let mut success = 0i32;
   359             let mut success = 0i32;
   342             gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success as _);
   360             gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success as _);
   343 
   361 
   522             gl::GenVertexArrays(1, &mut vao);
   540             gl::GenVertexArrays(1, &mut vao);
   523             gl::BindVertexArray(vao);
   541             gl::BindVertexArray(vao);
   524         }
   542         }
   525 
   543 
   526         for &(slot, ref buffer) in buffers {
   544         for &(slot, ref buffer) in buffers {
   527             unsafe {
   545             if let Some(handle) = buffer.handle() {
   528                 gl::BindBuffer(buffer.ty(), buffer.handle());
   546                 unsafe {
       
   547                     gl::BindBuffer(buffer.ty() as u32, handle.get());
       
   548                 }
   529             }
   549             }
   530 
   550 
   531             for attr in self.elements.iter().filter(|a| a.buffer_slot == slot) {
   551             for attr in self.elements.iter().filter(|a| a.buffer_slot == slot) {
   532                 unsafe {
   552                 unsafe {
   533                     gl::EnableVertexAttribArray(attr.shader_slot);
   553                     gl::EnableVertexAttribArray(attr.shader_slot);
   555                 }
   575                 }
   556             }
   576             }
   557         }
   577         }
   558 
   578 
   559         if let Some(buf) = index_buffer {
   579         if let Some(buf) = index_buffer {
   560             unsafe {
   580             if let Some(handle) = buf.handle() {
   561                 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, buf.handle());
   581                 unsafe {
       
   582                     gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, handle.get());
       
   583                 }
   562             }
   584             }
   563         }
   585         }
   564 
   586 
   565         LayoutGuard { vao }
   587         LayoutGuard { vao }
   566     }
   588     }