2016-03-16 14:25:35 -04:00
|
|
|
// Copyright 2016 Matthew Collins
|
2015-09-17 11:21:56 -04:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2015-09-17 11:04:25 -04:00
|
|
|
|
2018-11-04 14:48:03 -05:00
|
|
|
use crate::gl;
|
2020-06-21 15:17:24 -04:00
|
|
|
use crate::render::glsl;
|
2019-05-22 19:01:14 -04:00
|
|
|
use log::error;
|
2015-09-17 11:04:25 -04:00
|
|
|
|
|
|
|
pub fn add_shaders(reg: &mut glsl::Registry) {
|
2020-06-21 15:17:24 -04:00
|
|
|
reg.register(
|
|
|
|
"lookup_texture",
|
|
|
|
include_str!("shaders/lookup_texture.glsl"),
|
|
|
|
);
|
2015-10-07 14:36:59 -04:00
|
|
|
reg.register("get_light", include_str!("shaders/get_light.glsl"));
|
2015-09-17 11:04:25 -04:00
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl"));
|
|
|
|
reg.register("ui_frag", include_str!("shaders/ui_frag.glsl"));
|
2016-03-16 13:33:06 -04:00
|
|
|
|
|
|
|
reg.register("chunk_vertex", include_str!("shaders/chunk_vertex.glsl"));
|
|
|
|
reg.register("chunk_frag", include_str!("shaders/chunk_frag.glsl"));
|
|
|
|
|
|
|
|
reg.register("trans_vertex", include_str!("shaders/trans_vertex.glsl"));
|
|
|
|
reg.register("trans_frag", include_str!("shaders/trans_frag.glsl"));
|
2016-03-27 18:31:57 -04:00
|
|
|
|
|
|
|
reg.register("model_vertex", include_str!("shaders/model_vertex.glsl"));
|
|
|
|
reg.register("model_frag", include_str!("shaders/model_frag.glsl"));
|
|
|
|
|
|
|
|
reg.register("sun_vertex", include_str!("shaders/sun_vertex.glsl"));
|
|
|
|
reg.register("sun_frag", include_str!("shaders/sun_frag.glsl"));
|
2016-04-01 15:00:13 -04:00
|
|
|
|
|
|
|
reg.register("clouds_vertex", include_str!("shaders/clouds_vertex.glsl"));
|
|
|
|
reg.register("clouds_geo", include_str!("shaders/clouds_geo.glsl"));
|
|
|
|
reg.register("clouds_frag", include_str!("shaders/clouds_frag.glsl"));
|
2016-03-16 13:33:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! get_shader {
|
2020-06-21 15:17:24 -04:00
|
|
|
($reg:ident, $name:expr) => {
|
2016-03-16 13:33:06 -04:00
|
|
|
$reg.get($name)
|
2020-06-21 15:17:24 -04:00
|
|
|
};
|
|
|
|
($reg:ident, $name:expr, $def:expr) => {
|
2016-03-16 13:33:06 -04:00
|
|
|
$reg.get_define($name, $def)
|
2020-06-21 15:17:24 -04:00
|
|
|
};
|
2015-10-06 18:49:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! init_shader {
|
2016-03-20 16:17:21 -04:00
|
|
|
(
|
|
|
|
Program $name:ident {
|
|
|
|
vert = $vert:expr, $(#$vdef:ident)*
|
|
|
|
frag = $frag:expr, $(#$fdef:ident)*
|
|
|
|
attribute = {
|
|
|
|
$(
|
2016-04-09 06:08:17 -04:00
|
|
|
required $field:ident => $glname:expr,
|
|
|
|
)*
|
|
|
|
$(
|
|
|
|
optional $ofield:ident => $oglname:expr,
|
2016-03-20 16:17:21 -04:00
|
|
|
)*
|
|
|
|
},
|
|
|
|
uniform = {
|
|
|
|
$(
|
2016-04-09 06:08:17 -04:00
|
|
|
required $ufield:ident => $uglname:expr,
|
|
|
|
)*
|
|
|
|
$(
|
|
|
|
optional $oufield:ident => $ouglname:expr,
|
2016-03-20 16:17:21 -04:00
|
|
|
)*
|
|
|
|
},
|
|
|
|
}
|
|
|
|
) => (
|
2016-03-16 13:33:06 -04:00
|
|
|
#[allow(dead_code)]
|
2016-03-20 16:17:21 -04:00
|
|
|
struct $name {
|
|
|
|
program: gl::Program,
|
|
|
|
$(
|
|
|
|
$field: gl::Attribute,
|
2016-04-09 06:08:17 -04:00
|
|
|
)*
|
|
|
|
$(
|
|
|
|
$ofield: Option<gl::Attribute>,
|
|
|
|
)*
|
2016-03-20 16:17:21 -04:00
|
|
|
$(
|
|
|
|
$ufield: gl::Uniform,
|
2016-04-09 06:08:17 -04:00
|
|
|
)*
|
|
|
|
$(
|
|
|
|
$oufield: Option<gl::Uniform>,
|
|
|
|
)*
|
2016-03-20 16:17:21 -04:00
|
|
|
}
|
2015-10-06 18:49:52 -04:00
|
|
|
|
2016-03-20 16:17:21 -04:00
|
|
|
impl $name {
|
2016-03-27 18:31:57 -04:00
|
|
|
#[allow(dead_code)]
|
2016-03-20 16:17:21 -04:00
|
|
|
pub fn new(reg: &glsl::Registry) -> $name {
|
|
|
|
let v = get_shader!(reg, $vert $(,stringify!($vdef))*);
|
|
|
|
let f = get_shader!(reg, $frag $(,stringify!($fdef))*);
|
2016-03-27 18:31:57 -04:00
|
|
|
$name::new_manual(&v, &f)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn new_manual(v: &str, f: &str) -> $name {
|
2016-03-20 16:17:21 -04:00
|
|
|
let shader = shaders::create_program(&v, &f);
|
|
|
|
$name {
|
|
|
|
$(
|
2016-04-09 06:08:17 -04:00
|
|
|
$field: shader.attribute_location($glname).unwrap(),
|
|
|
|
)*
|
|
|
|
$(
|
|
|
|
$ofield: shader.attribute_location($oglname),
|
|
|
|
)*
|
|
|
|
$(
|
|
|
|
$ufield: shader.uniform_location($uglname).unwrap(),
|
|
|
|
)*
|
2016-03-20 16:17:21 -04:00
|
|
|
$(
|
2016-04-09 06:08:17 -04:00
|
|
|
$oufield: shader.uniform_location($ouglname),
|
|
|
|
)*
|
2016-03-20 16:17:21 -04:00
|
|
|
program: shader,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2015-10-06 18:49:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn create_program(vertex: &str, fragment: &str) -> gl::Program {
|
2015-10-07 14:36:59 -04:00
|
|
|
let program = gl::Program::new();
|
2015-10-06 18:49:52 -04:00
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
let v = gl::Shader::new(gl::VERTEX_SHADER);
|
|
|
|
v.set_source(vertex);
|
|
|
|
v.compile();
|
2015-10-06 18:49:52 -04:00
|
|
|
|
Use glow, GL on Whatever (#262)
Replaces the use of gl_generator with the glow wrapper:
* Add glow dependency, based on glow 0.6.1
* Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer
* Remove gl module, steven_gl
Porting details:
* Initialize glow in src/gl/mod.rs
* Call gl methods on glow context
* glow uses camelcase
* Import glow::HasContext trait, finds draw_elements etc.
* Fix mismatched types, glow uses Option and &str instead of raw pointers
* Fix uniform_location, glow already returns Some(u32)
* uniform_location: convert i32 to u32 for Uniform
* Fix attribute_location
* Fix shader creation Result u32 type
* Fix passing GLvoid and 2d/3d
* Fix missing Options type mismatches
* Offsets are i32 in glow, not GLvoid
* Fix clear_buffer using _f32_slice
* Delete methods are singular not plural
* glBufferData -> buffer_data_u8_slice
* buffer_sub_data_u8_slice
* Update more glow method wrapper names found by reviewing glow native platform
* Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent
* glow implements glMapBufferRange
* Remove unused read_buffer
* glow's deletes automatically pass 1 and take no reference
* shader_source() accepts &str directly; removes last of std::ptr
* Pass uniform Option<u32>
* Fix bool passing normalized parameter
* Fix draw_buffers parameter
* Stop unnecessarily returning context from gl::init
* Getting shader info is unsafe
* Unwrapping static mut is unsafe
* Use unsafe raw pointers for global mutable context
* Fix initializing GL objects wrappers from glow wrappers
* Unbinding framebuffers uses None
* Uppercase global to fix warning
* Shaders return Some instead of None
* Unbox the context to a raw pointer
* Use tex_image_2d_multisample added in glow fork
* Implement uniform_location, fixing unwrap None failed
* Add tex_sub_image_3d, using PixelUnpackData::Slice
* set_matrix4: transmute the Matrix4 since it is repr(C)
* get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice
* Wrap sub_image_2d (glTexSubImage2D) and fix warnings
* Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts
2020-12-25 13:00:22 -05:00
|
|
|
if !v.get_shader_compile_status() {
|
2019-05-22 19:01:14 -04:00
|
|
|
error!("Src: {}", vertex);
|
2015-10-07 14:36:59 -04:00
|
|
|
panic!("Shader error: {}", v.get_info_log());
|
|
|
|
} else {
|
|
|
|
let log = v.get_info_log();
|
2016-03-20 20:18:26 -04:00
|
|
|
let log = log.trim().trim_matches('\u{0}');
|
2015-10-07 14:36:59 -04:00
|
|
|
if !log.is_empty() {
|
2019-05-22 19:01:14 -04:00
|
|
|
error!("{}", log);
|
2015-10-07 14:36:59 -04:00
|
|
|
}
|
|
|
|
}
|
2015-10-06 18:49:52 -04:00
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
let f = gl::Shader::new(gl::FRAGMENT_SHADER);
|
|
|
|
f.set_source(fragment);
|
|
|
|
f.compile();
|
2015-10-06 18:49:52 -04:00
|
|
|
|
Use glow, GL on Whatever (#262)
Replaces the use of gl_generator with the glow wrapper:
* Add glow dependency, based on glow 0.6.1
* Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer
* Remove gl module, steven_gl
Porting details:
* Initialize glow in src/gl/mod.rs
* Call gl methods on glow context
* glow uses camelcase
* Import glow::HasContext trait, finds draw_elements etc.
* Fix mismatched types, glow uses Option and &str instead of raw pointers
* Fix uniform_location, glow already returns Some(u32)
* uniform_location: convert i32 to u32 for Uniform
* Fix attribute_location
* Fix shader creation Result u32 type
* Fix passing GLvoid and 2d/3d
* Fix missing Options type mismatches
* Offsets are i32 in glow, not GLvoid
* Fix clear_buffer using _f32_slice
* Delete methods are singular not plural
* glBufferData -> buffer_data_u8_slice
* buffer_sub_data_u8_slice
* Update more glow method wrapper names found by reviewing glow native platform
* Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent
* glow implements glMapBufferRange
* Remove unused read_buffer
* glow's deletes automatically pass 1 and take no reference
* shader_source() accepts &str directly; removes last of std::ptr
* Pass uniform Option<u32>
* Fix bool passing normalized parameter
* Fix draw_buffers parameter
* Stop unnecessarily returning context from gl::init
* Getting shader info is unsafe
* Unwrapping static mut is unsafe
* Use unsafe raw pointers for global mutable context
* Fix initializing GL objects wrappers from glow wrappers
* Unbinding framebuffers uses None
* Uppercase global to fix warning
* Shaders return Some instead of None
* Unbox the context to a raw pointer
* Use tex_image_2d_multisample added in glow fork
* Implement uniform_location, fixing unwrap None failed
* Add tex_sub_image_3d, using PixelUnpackData::Slice
* set_matrix4: transmute the Matrix4 since it is repr(C)
* get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice
* Wrap sub_image_2d (glTexSubImage2D) and fix warnings
* Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts
2020-12-25 13:00:22 -05:00
|
|
|
if !f.get_shader_compile_status() {
|
2019-05-22 19:01:14 -04:00
|
|
|
error!("Src: {}", fragment);
|
2015-10-07 14:36:59 -04:00
|
|
|
panic!("Shader error: {}", f.get_info_log());
|
|
|
|
} else {
|
|
|
|
let log = f.get_info_log();
|
2016-03-20 20:18:26 -04:00
|
|
|
let log = log.trim().trim_matches('\u{0}');
|
2015-10-07 14:36:59 -04:00
|
|
|
if !log.is_empty() {
|
2019-05-22 19:01:14 -04:00
|
|
|
error!("{}", log);
|
2015-10-07 14:36:59 -04:00
|
|
|
}
|
|
|
|
}
|
2015-10-06 18:49:52 -04:00
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
program.attach_shader(v);
|
|
|
|
program.attach_shader(f);
|
|
|
|
program.link();
|
|
|
|
program.use_program();
|
|
|
|
program
|
|
|
|
}
|