Skip to content

Commit d19671d

Browse files
Implement SDL_Vertex and SDL_RenderGeometry
1 parent 02e5ec8 commit d19671d

File tree

1 file changed

+166
-1
lines changed

1 file changed

+166
-1
lines changed

src/sdl2/render.rs

+166-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::common::{validate_int, IntegerOrSdlError};
3232
use crate::get_error;
3333
use crate::pixels;
3434
use crate::pixels::PixelFormatEnum;
35+
use crate::rect::FPoint;
3536
use crate::rect::Point;
3637
use crate::rect::Rect;
3738
use crate::surface;
@@ -47,7 +48,7 @@ use std::fmt;
4748
use std::marker::PhantomData;
4849
use std::mem;
4950
use std::mem::{transmute, MaybeUninit};
50-
use std::ops::Deref;
51+
use std::ops::{Deref, DerefMut};
5152
use std::ptr;
5253
use std::rc::Rc;
5354

@@ -100,6 +101,106 @@ impl Error for TargetRenderError {
100101
}
101102
}
102103

104+
#[derive(Copy, Clone)]
105+
pub struct Vertex {
106+
raw: sys::SDL_Vertex,
107+
}
108+
109+
pub trait VertexIndex {}
110+
111+
impl VertexIndex for u8 {}
112+
impl VertexIndex for u16 {}
113+
impl VertexIndex for u32 {}
114+
115+
impl ::std::fmt::Debug for Vertex {
116+
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
117+
return write!(
118+
fmt,
119+
"Vertex {{ position: {:?}, color: {:?}, tex_coord: {:?} }}",
120+
self.position(),
121+
self.color(),
122+
self.tex_coord(),
123+
);
124+
}
125+
}
126+
127+
impl Deref for Vertex {
128+
type Target = sys::SDL_Vertex;
129+
130+
fn deref(&self) -> &sys::SDL_Vertex {
131+
&self.raw
132+
}
133+
}
134+
135+
impl DerefMut for Vertex {
136+
fn deref_mut(&mut self) -> &mut sys::SDL_Vertex {
137+
&mut self.raw
138+
}
139+
}
140+
141+
impl AsRef<sys::SDL_Vertex> for Vertex {
142+
fn as_ref(&self) -> &sys::SDL_Vertex {
143+
&self.raw
144+
}
145+
}
146+
147+
impl AsMut<sys::SDL_Vertex> for Vertex {
148+
fn as_mut(&mut self) -> &mut sys::SDL_Vertex {
149+
&mut self.raw
150+
}
151+
}
152+
153+
impl From<sys::SDL_Vertex> for Vertex {
154+
fn from(prim: sys::SDL_Vertex) -> Vertex {
155+
Vertex { raw: prim }
156+
}
157+
}
158+
159+
impl Into<sys::SDL_Vertex> for Vertex {
160+
fn into(self) -> sys::SDL_Vertex {
161+
self.raw
162+
}
163+
}
164+
165+
impl Vertex {
166+
pub fn new(position: FPoint, color: pixels::Color, tex_coord: FPoint) -> Vertex {
167+
Vertex {
168+
raw: sys::SDL_Vertex {
169+
position: position.into(),
170+
color: color.into(),
171+
tex_coord: tex_coord.into(),
172+
},
173+
}
174+
}
175+
176+
pub fn from_ll(raw: sys::SDL_Vertex) -> Vertex {
177+
Vertex::new(raw.position.into(), raw.color.into(), raw.tex_coord.into())
178+
}
179+
180+
#[doc(alias = "SDL_Vertex")]
181+
pub fn raw_slice(slice: &[Vertex]) -> *const sys::SDL_Vertex {
182+
slice.as_ptr() as *const sys::SDL_Vertex
183+
}
184+
// this can prevent introducing UB until
185+
// https://github.com/rust-lang/rust-clippy/issues/5953 is fixed
186+
#[allow(clippy::trivially_copy_pass_by_ref)]
187+
pub fn raw(&self) -> *const sys::SDL_Vertex {
188+
&self.raw
189+
}
190+
191+
pub fn position(self) -> FPoint {
192+
self.raw.position.into()
193+
}
194+
195+
pub fn color(self) -> pixels::Color {
196+
self.raw.color.into()
197+
}
198+
199+
pub fn tex_coord(self) -> FPoint {
200+
self.raw.tex_coord.into()
201+
}
202+
}
203+
103204
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
104205
#[repr(i32)]
105206
pub enum TextureAccess {
@@ -1468,6 +1569,70 @@ impl<T: RenderTarget> Canvas<T> {
14681569
}
14691570
}
14701571

1572+
/// Render a list of triangles, optionally using a texture and indices into the vertex array.
1573+
#[doc(alias = "SDL_RenderGeometry")]
1574+
pub fn geometry(
1575+
&mut self,
1576+
texture: &Texture,
1577+
vertices: &[Vertex],
1578+
indices: &[u32],
1579+
) -> Result<(), String> {
1580+
let result = unsafe {
1581+
sys::SDL_RenderGeometry(
1582+
self.context.raw,
1583+
texture.raw,
1584+
Vertex::raw_slice(vertices),
1585+
vertices.len() as c_int,
1586+
indices.as_ptr() as *const i32,
1587+
indices.len() as c_int,
1588+
)
1589+
};
1590+
1591+
if result != 0 {
1592+
Err(get_error())
1593+
} else {
1594+
Ok(())
1595+
}
1596+
}
1597+
1598+
/// Render a list of triangles, optionally using a texture and indices into the vertex arrays.
1599+
#[doc(alias = "SDL_RenderGeometryRaw")]
1600+
pub fn geometry_raw<I: VertexIndex>(
1601+
&mut self,
1602+
texture: &Texture,
1603+
xy: &[f32],
1604+
xy_stride: i32,
1605+
color: &[sys::SDL_Color],
1606+
color_stride: i32,
1607+
uv: &[f32],
1608+
uv_stride: i32,
1609+
num_vertices: i32,
1610+
indices: &[I],
1611+
) -> Result<(), String> {
1612+
let result = unsafe {
1613+
sys::SDL_RenderGeometryRaw(
1614+
self.context.raw,
1615+
texture.raw,
1616+
xy.as_ptr(),
1617+
xy_stride as c_int,
1618+
color.as_ptr(),
1619+
color_stride as c_int,
1620+
uv.as_ptr(),
1621+
uv_stride as c_int,
1622+
num_vertices as c_int,
1623+
indices.as_ptr() as *const c_void,
1624+
indices.len() as c_int,
1625+
std::mem::size_of::<I>() as i32,
1626+
)
1627+
};
1628+
1629+
if result != 0 {
1630+
Err(get_error())
1631+
} else {
1632+
Ok(())
1633+
}
1634+
}
1635+
14711636
/// Reads pixels from the current rendering target.
14721637
/// # Remarks
14731638
/// WARNING: This is a very slow operation, and should not be used frequently.

0 commit comments

Comments
 (0)