Skip to content

Commit 3f9d2f5

Browse files
authored
Merge pull request #993 from gfx-rs/kvark-android
Basic Android / GLES support
2 parents e89f611 + cb91d96 commit 3f9d2f5

File tree

15 files changed

+115
-29
lines changed

15 files changed

+115
-29
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ name = "gfx_app"
1717
env_logger = "0.3"
1818
getopts = "0.2"
1919
time = "0.1"
20-
glutin = "0.5"
20+
glutin = "0.6"
2121
gfx_core = { path = "src/core", version = "0.3" }
2222
gfx_device_gl = { path = "src/backend/gl", version = "0.10" }
2323
gfx_window_glutin = { path = "src/window/glutin", version = "0.11" }

examples/cube/main.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use gfx::Bundle;
2626
// Notice the use of FixedPoint.
2727
gfx_defines!{
2828
vertex Vertex {
29-
pos: [i8; 4] = "a_Pos",
30-
tex_coord: [i8; 2] = "a_TexCoord",
29+
pos: [f32; 4] = "a_Pos",
30+
tex_coord: [f32; 2] = "a_TexCoord",
3131
}
3232

3333
constant Locals {
@@ -49,8 +49,8 @@ gfx_defines!{
4949
impl Vertex {
5050
fn new(p: [i8; 3], t: [i8; 2]) -> Vertex {
5151
Vertex {
52-
pos: [p[0], p[1], p[2], 1],
53-
tex_coord: t,
52+
pos: [p[0] as f32, p[1] as f32, p[2] as f32, 1.0],
53+
tex_coord: [t[0] as f32, t[1] as f32],
5454
}
5555
}
5656
}
@@ -69,12 +69,14 @@ impl<R: gfx::Resources> gfx_app::Application<R> for App<R> {
6969
let vs = gfx_app::shade::Source {
7070
glsl_120: include_bytes!("shader/cube_120.glslv"),
7171
glsl_150: include_bytes!("shader/cube_150.glslv"),
72+
glsl_es_100: include_bytes!("shader/cube_100_es.glslv"),
7273
hlsl_40: include_bytes!("data/vertex.fx"),
7374
.. gfx_app::shade::Source::empty()
7475
};
7576
let ps = gfx_app::shade::Source {
7677
glsl_120: include_bytes!("shader/cube_120.glslf"),
7778
glsl_150: include_bytes!("shader/cube_150.glslf"),
79+
glsl_es_100: include_bytes!("shader/cube_100_es.glslf"),
7880
hlsl_40: include_bytes!("data/pixel.fx"),
7981
.. gfx_app::shade::Source::empty()
8082
};

examples/cube/shader/cube.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cbuffer Locals {
77
float4x4 u_Transform;
88
};
99

10-
VsOutput Vertex(int4 pos: a_Pos, int2 tc: a_TexCoord) {
10+
VsOutput Vertex(float4 pos: a_Pos, float2 tc: a_TexCoord) {
1111
VsOutput output = {
1212
mul(u_Transform, pos),
1313
tc,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 100
2+
3+
precision mediump float;
4+
precision mediump int;
5+
6+
varying vec2 v_TexCoord;
7+
uniform sampler2D t_Color;
8+
9+
void main() {
10+
vec4 tex = texture2D(t_Color, v_TexCoord);
11+
float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
12+
gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#version 100
2+
3+
attribute vec4 a_Pos;
4+
attribute vec2 a_TexCoord;
5+
varying vec2 v_TexCoord;
6+
7+
uniform mat4 u_Transform;
8+
9+
void main() {
10+
v_TexCoord = a_TexCoord;
11+
gl_Position = u_Transform * a_Pos;
12+
}

examples/cube/shader/cube_120.glslv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#version 120
22

3-
attribute ivec4 a_Pos;
4-
attribute ivec2 a_TexCoord;
3+
attribute vec4 a_Pos;
4+
attribute vec2 a_TexCoord;
55
varying vec2 v_TexCoord;
66

77
uniform mat4 u_Transform;

examples/cube/shader/cube_150.glslv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#version 150 core
22

3-
in ivec4 a_Pos;
4-
in ivec2 a_TexCoord;
3+
in vec4 a_Pos;
4+
in vec2 a_TexCoord;
55
out vec2 v_TexCoord;
66

77
uniform mat4 u_Transform;

examples/shadow/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ impl<R, C> gfx_app::ApplicationBase<R, C> for App<R, C> where
604604
// Section-6: main entry point
605605

606606
pub fn main() {
607-
<App<_, _> as gfx_app::ApplicationGL2>::launch(
607+
<App<_, _> as gfx_app::ApplicationGL>::launch(
608608
"Multi-threaded shadow rendering example with gfx-rs",
609609
gfx_app::DEFAULT_CONFIG);
610610
}

src/backend/gl/src/info.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use gfx_core::Capabilities;
2121
/// A version number for a specific component of an OpenGL implementation
2222
#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
2323
pub struct Version {
24+
pub is_embedded: bool,
2425
pub major: u32,
2526
pub minor: u32,
2627
pub revision: Option<u32>,
@@ -32,12 +33,23 @@ impl Version {
3233
pub fn new(major: u32, minor: u32, revision: Option<u32>,
3334
vendor_info: &'static str) -> Version {
3435
Version {
36+
is_embedded: false,
3537
major: major,
3638
minor: minor,
3739
revision: revision,
3840
vendor_info: vendor_info,
3941
}
4042
}
43+
/// Create a new OpenGL ES version number
44+
pub fn new_embedded(major: u32, minor: u32, vendor_info: &'static str) -> Version {
45+
Version {
46+
is_embedded: true,
47+
major: major,
48+
minor: minor,
49+
revision: None,
50+
vendor_info: vendor_info,
51+
}
52+
}
4153

4254
/// According to the OpenGL specification, the version information is
4355
/// expected to follow the following syntax:
@@ -54,9 +66,17 @@ impl Version {
5466
/// Note that this function is intentionally lenient in regards to parsing,
5567
/// and will try to recover at least the first two version numbers without
5668
/// resulting in an `Err`.
57-
pub fn parse(src: &'static str) -> Result<Version, &'static str> {
69+
pub fn parse(mut src: &'static str) -> Result<Version, &'static str> {
70+
let es_sig = " ES ";
71+
let is_es = match src.rfind(es_sig) {
72+
Some(pos) => {
73+
src = &src[pos + es_sig.len() ..];
74+
true
75+
},
76+
None => false,
77+
};
5878
let (version, vendor_info) = match src.find(' ') {
59-
Some(i) => (&src[..i], &src[(i + 1)..]),
79+
Some(i) => (&src[..i], &src[i+1..]),
6080
None => (src, ""),
6181
};
6282

@@ -69,6 +89,7 @@ impl Version {
6989

7090
match (major, minor, revision) {
7191
(Some(major), Some(minor), revision) => Ok(Version {
92+
is_embedded: is_es,
7293
major: major,
7394
minor: minor,
7495
revision: revision,
@@ -185,7 +206,11 @@ impl Info {
185206
}
186207

187208
pub fn is_version_supported(&self, major: u32, minor: u32) -> bool {
188-
self.version >= Version::new(major, minor, None, "")
209+
!self.version.is_embedded && self.version >= Version::new(major, minor, None, "")
210+
}
211+
212+
pub fn is_embedded_version_supported(&self, major: u32, minor: u32) -> bool {
213+
self.version.is_embedded && self.version >= Version::new(major, minor, None, "")
189214
}
190215

191216
/// Returns `true` if the implementation supports the extension
@@ -218,7 +243,8 @@ pub fn get(gl: &gl::Gl) -> (Info, Capabilities, PrivateCaps) {
218243
};
219244
let private = PrivateCaps {
220245
array_buffer_supported: info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
221-
frame_buffer_supported: info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object"),
246+
frame_buffer_supported: info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object") |
247+
info.is_embedded_version_supported(2, 0),
222248
immutable_storage_supported: info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
223249
sampler_objects_supported: info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
224250
program_interface_supported: info.is_version_or_extension_supported(4, 3, "GL_ARB_program_interface_query"),
@@ -243,5 +269,8 @@ mod tests {
243269
assert_eq!(Version::parse("1.2. h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
244270
assert_eq!(Version::parse("1.2.3.h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "W0rld")));
245271
assert_eq!(Version::parse("1.2.3 h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "h3l1o. W0rld")));
272+
assert_eq!(Version::parse("OpenGL ES 3.1"), Ok(Version::new_embedded(3, 1, "")));
273+
assert_eq!(Version::parse("OpenGL ES 2.0 Google Nexus"), Ok(Version::new_embedded(2, 0, "Google Nexus")));
274+
assert_eq!(Version::parse("GLSL ES 1.1"), Ok(Version::new_embedded(1, 1, "")));
246275
}
247276
}

src/backend/gl/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ impl Device {
436436
assert!(d::MAX_SAMPLERS <= d::MAX_RESOURCE_VIEWS);
437437
debug_assert_eq!(sampler.object, 0);
438438
if let Some(bind) = bind_opt {
439-
tex::bind_sampler(gl, bind, &sampler.info);
439+
tex::bind_sampler(gl, bind, &sampler.info, self.info.version.is_embedded);
440440
}else {
441441
error!("Trying to bind a sampler to slot {}, when sampler objects are not supported, and no texture is bound there", slot);
442442
}
@@ -480,7 +480,7 @@ impl Device {
480480
state::bind_draw_color_buffers(&self.share.context, mask);
481481
},
482482
Command::SetRasterizer(rast) => {
483-
state::bind_rasterizer(&self.share.context, &rast);
483+
state::bind_rasterizer(&self.share.context, &rast, self.info.version.is_embedded);
484484
},
485485
Command::SetViewport(rect) => {
486486
state::bind_viewport(&self.share.context, rect);

src/backend/gl/src/state.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub fn bind_raster_method(gl: &gl::Gl, method: s::RasterMethod, offset: Option<s
4444
}
4545
}
4646

47-
pub fn bind_rasterizer(gl: &gl::Gl, r: &s::Rasterizer) {
47+
pub fn bind_rasterizer(gl: &gl::Gl, r: &s::Rasterizer, is_embedded: bool) {
4848
unsafe {
4949
gl.FrontFace(match r.front_face {
5050
FrontFace::Clockwise => gl::CW,
@@ -63,8 +63,10 @@ pub fn bind_rasterizer(gl: &gl::Gl, r: &s::Rasterizer) {
6363
gl.CullFace(gl::BACK);
6464
}}
6565
}
66-
67-
bind_raster_method(gl, r.method, r.offset);
66+
67+
if !is_embedded {
68+
bind_raster_method(gl, r.method, r.offset);
69+
}
6870
match r.samples {
6971
Some(_) => unsafe { gl.Enable(gl::MULTISAMPLE) },
7072
None => unsafe { gl.Disable(gl::MULTISAMPLE) },

src/backend/gl/src/tex.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ pub fn make_with_storage(gl: &gl::Gl, desc: &t::Descriptor, cty: ChannelType) ->
534534

535535
/// Bind a sampler using a given binding anchor.
536536
/// Used for GL compatibility profile only. The core profile has sampler objects
537-
pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo) { unsafe {
537+
pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo, is_embedded: bool) { unsafe {
538538
let (min, mag) = filter_to_gl(info.filter);
539539

540540
match info.filter {
@@ -551,9 +551,11 @@ pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo) { unsafe
551551
gl.TexParameteri(target, gl::TEXTURE_WRAP_T, wrap_to_gl(t) as GLint);
552552
gl.TexParameteri(target, gl::TEXTURE_WRAP_R, wrap_to_gl(r) as GLint);
553553

554-
gl.TexParameterf(target, gl::TEXTURE_LOD_BIAS, info.lod_bias.into());
555-
let border: [f32; 4] = info.border.into();
556-
gl.TexParameterfv(target, gl::TEXTURE_BORDER_COLOR, &border[0]);
554+
if !is_embedded {
555+
let border: [f32; 4] = info.border.into();
556+
gl.TexParameterfv(target, gl::TEXTURE_BORDER_COLOR, &border[0]);
557+
gl.TexParameterf(target, gl::TEXTURE_LOD_BIAS, info.lod_bias.into());
558+
}
557559

558560
let (min, max) = info.lod_range;
559561
gl.TexParameterf(target, gl::TEXTURE_MIN_LOD, min.into());

src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub trait Application<R: gfx::Resources>: Sized {
9696
WrapD3D11::<Self>::launch(name, DEFAULT_CONFIG);
9797
}
9898
#[cfg(not(target_os = "windows"))]
99-
fn launch_default(name: &str) where WrapGL2<Self>: ApplicationGL2 {
99+
fn launch_default(name: &str) where WrapGL2<Self>: ApplicationGL {
100100
WrapGL2::<Self>::launch(name, DEFAULT_CONFIG);
101101
}
102102
}
@@ -137,7 +137,7 @@ impl<R, C, A> ApplicationBase<R, C> for Wrap<R, C, A> where
137137
}
138138

139139

140-
pub trait ApplicationGL2 {
140+
pub trait ApplicationGL {
141141
fn launch(&str, Config);
142142
}
143143

@@ -146,25 +146,35 @@ pub trait ApplicationD3D11 {
146146
fn launch(&str, Config);
147147
}
148148

149-
impl<A> ApplicationGL2 for A where
149+
impl<A> ApplicationGL for A where
150150
A: ApplicationBase<gfx_device_gl::Resources,
151151
gfx_device_gl::CommandBuffer>
152152
{
153153
fn launch(title: &str, config: Config) {
154154
use gfx::traits::Device;
155155

156156
env_logger::init().unwrap();
157+
let gl_version = glutin::GlRequest::GlThenGles {
158+
opengl_version: (3, 2), //TODO: try more versions
159+
opengles_version: (2, 0),
160+
};
157161
let builder = glutin::WindowBuilder::new()
158162
.with_title(title.to_string())
159163
.with_dimensions(config.size.0 as u32, config.size.1 as u32)
164+
.with_gl(gl_version)
160165
.with_vsync();
161166
let (window, mut device, mut factory, main_color, main_depth) =
162167
gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder);
163168
let (width, height) = window.get_inner_size().unwrap();
164169
let combuf = factory.create_command_buffer();
170+
let shade_lang = device.get_info().shading_language;
165171

166172
let mut app = Self::new(factory, combuf.into(), Init {
167-
backend: shade::Backend::Glsl(device.get_info().shading_language),
173+
backend: if shade_lang.is_embedded {
174+
shade::Backend::GlslEs(shade_lang)
175+
} else {
176+
shade::Backend::Glsl(shade_lang)
177+
},
168178
color: main_color,
169179
depth: main_depth,
170180
aspect_ratio: width as f32 / height as f32,

src/shade.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub use gfx_device_dx11::ShaderModel as DxShaderModel;
2121
#[derive(Copy, Clone, PartialEq, Debug)]
2222
pub enum Backend {
2323
Glsl(GlslVersion),
24+
GlslEs(GlslVersion),
2425
#[cfg(target_os = "windows")]
2526
Hlsl(DxShaderModel),
2627
}
@@ -35,6 +36,9 @@ pub struct Source<'a> {
3536
pub glsl_140: &'a [u8],
3637
pub glsl_150: &'a [u8],
3738
pub glsl_430: &'a [u8],
39+
pub glsl_es_100: &'a [u8],
40+
pub glsl_es_200: &'a [u8],
41+
pub glsl_es_300: &'a [u8],
3842
pub hlsl_30 : &'a [u8],
3943
pub hlsl_40 : &'a [u8],
4044
pub hlsl_41 : &'a [u8],
@@ -51,6 +55,9 @@ impl<'a> Source<'a> {
5155
glsl_140: EMPTY,
5256
glsl_150: EMPTY,
5357
glsl_430: EMPTY,
58+
glsl_es_100: EMPTY,
59+
glsl_es_200: EMPTY,
60+
glsl_es_300: EMPTY,
5461
hlsl_30: EMPTY,
5562
hlsl_40: EMPTY,
5663
hlsl_41: EMPTY,
@@ -72,6 +79,15 @@ impl<'a> Source<'a> {
7279
_ => return Err(())
7380
}
7481
},
82+
Backend::GlslEs(version) => {
83+
let v = version.major * 100 + version.minor;
84+
match *self {
85+
Source { glsl_es_100: s, .. } if s != EMPTY && v >= 100 => s,
86+
Source { glsl_es_200: s, .. } if s != EMPTY && v >= 200 => s,
87+
Source { glsl_es_300: s, .. } if s != EMPTY && v >= 300 => s,
88+
_ => return Err(())
89+
}
90+
},
7591
#[cfg(target_os = "windows")]
7692
Backend::Hlsl(model) => match *self {
7793
Source { hlsl_50: s, .. } if s != EMPTY && model >= 50 => s,

src/window/glutin/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ authors = ["The Gfx-rs Developers"]
2626
name = "gfx_window_glutin"
2727

2828
[dependencies]
29-
glutin = "0.5"
29+
glutin = "0.6"
3030
gfx_core = { path = "../../core", version = "0.3" }
3131
gfx_device_gl = { path = "../../backend/gl", version = "0.10" }

0 commit comments

Comments
 (0)