gl46: implement DSA version of gl runtime
This commit is contained in:
parent
7b2721aa19
commit
5078015605
|
@ -13,6 +13,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/librashader-compiler/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-common/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d11/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-gl46/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
|
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -418,6 +418,7 @@ dependencies = [
|
|||
"librashader-reflect",
|
||||
"librashader-runtime-d3d11",
|
||||
"librashader-runtime-gl",
|
||||
"librashader-runtime-gl46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -496,6 +497,22 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librashader-runtime-gl46"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"gl",
|
||||
"glfw",
|
||||
"librashader-common",
|
||||
"librashader-preprocess",
|
||||
"librashader-presets",
|
||||
"librashader-reflect",
|
||||
"rustc-hash",
|
||||
"spirv_cross",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
|
|
@ -7,4 +7,5 @@ members = [
|
|||
"librashader-reflect",
|
||||
"librashader-runtime-d3d11",
|
||||
"librashader-runtime-gl",
|
||||
"librashader-runtime-gl46",
|
||||
]
|
11
README.md
11
README.md
|
@ -9,12 +9,13 @@ librashader (*/ˈli:brəʃeɪdɚ/*) is a preprocessor, compiler, and runtime for
|
|||
Heavily WIP.
|
||||
|
||||
## Supported Render APIs
|
||||
librashader supports OpenGL 3, Vulkan, DirectX 11, and DirectX 12. Support is WIP for all runtimes except OpenGL 3. Older versions
|
||||
librashader supports OpenGL 3, OpenGL 4.6, Vulkan, DirectX 11, and DirectX 12. Support is WIP for all runtimes except OpenGL 3. Older versions
|
||||
of DirectX and OpenGL, as well as Metal, are not supported (but pull-requests are welcome).
|
||||
|
||||
| **API** | **Status** | **`librashader` feature** |
|
||||
|-------------|------------|---------------------------|
|
||||
| OpenGL 3.3+ | ✔ | `gl` |
|
||||
| OpenGL 4.6 | ✔ | `gl46` |
|
||||
| Vulkan | 🚧 | `vk` |
|
||||
| Direct3D11 | 🚧 | `d3d11` |
|
||||
| Direct3D12 | 🚧 | `d3d12` |
|
||||
|
@ -54,11 +55,17 @@ Please report an issue if you run into a shader that works in RetroArch, but not
|
|||
* Sampler objects are used rather than `glTexParameter`.
|
||||
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
|
||||
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
|
||||
*
|
||||
* OpenGL 4.6+
|
||||
* All caveats from the OpenGL 3.3+ section should be considered.
|
||||
* Should work on OpenGL 4.5 but this is not guaranteed. The OpenGL 4.6 runtime may eventually switch to using `ARB_spirv_extensions` for loading shaders, and this will not be marked as a breaking change.
|
||||
* The OpenGL 4.6 runtime uses Direct State Access to minimize changes to the OpenGL state. For recent GPUs, this may improve performance.
|
||||
* Direct3D 11
|
||||
* The staging buffer is not kept around when loading static textures (LUTs).
|
||||
* HDR10 support is not part of the shader runtime and is not supported.
|
||||
|
||||
Most, if not all shader presets should work fine on librashader. The runtime specific differences should not affect the output,
|
||||
and are more a heads-up for integrating librashader into your project.
|
||||
|
||||
## License
|
||||
The core parts of librashader such as the preprocessor, the preset parser,
|
||||
the reflection library, and the runtimes, are all licensed under the Mozilla Public License version 2.0.
|
||||
|
|
|
@ -183,6 +183,7 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
// can't use framebuffer.clear because it will unbind.
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::texture::Texture;
|
|||
pub struct FilterChain {
|
||||
passes: Box<[FilterPass]>,
|
||||
common: FilterCommon,
|
||||
filter_vao: GLuint,
|
||||
pub(crate) draw_quad: DrawQuad,
|
||||
output_framebuffers: Box<[Framebuffer]>,
|
||||
feedback_framebuffers: Box<[Framebuffer]>,
|
||||
history_framebuffers: VecDeque<Framebuffer>,
|
||||
|
@ -43,7 +43,6 @@ pub struct FilterCommon {
|
|||
pub output_textures: Box<[Texture]>,
|
||||
pub feedback_textures: Box<[Texture]>,
|
||||
pub history_textures: Box<[Texture]>,
|
||||
pub(crate) draw_quad: DrawQuad,
|
||||
}
|
||||
|
||||
pub struct FilterMutable {
|
||||
|
@ -177,17 +176,12 @@ impl FilterChain {
|
|||
// create VBO objects
|
||||
let draw_quad = DrawQuad::new();
|
||||
|
||||
let mut filter_vao = 0;
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut filter_vao);
|
||||
}
|
||||
|
||||
Ok(FilterChain {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
filter_vao,
|
||||
draw_quad,
|
||||
common: FilterCommon {
|
||||
config: FilterMutable {
|
||||
passes_enabled: preset.shader_count as usize,
|
||||
|
@ -199,7 +193,6 @@ impl FilterChain {
|
|||
output_textures: output_textures.into_boxed_slice(),
|
||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
history_textures,
|
||||
draw_quad,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -279,6 +272,15 @@ impl FilterChain {
|
|||
|
||||
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
|
||||
let mut luts = FxHashMap::default();
|
||||
let pixel_unpack = unsafe {
|
||||
let mut binding = 0;
|
||||
gl::GetIntegerv(gl::PIXEL_UNPACK_BUFFER_BINDING, &mut binding);
|
||||
binding
|
||||
};
|
||||
|
||||
unsafe {
|
||||
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
for (index, texture) in textures.iter().enumerate() {
|
||||
let image = Image::load(&texture.path)?;
|
||||
|
@ -290,10 +292,10 @@ impl FilterChain {
|
|||
|
||||
let mut handle = 0;
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut handle);
|
||||
gl::BindTexture(gl::TEXTURE_2D, handle);
|
||||
gl::TexStorage2D(
|
||||
gl::TEXTURE_2D,
|
||||
gl::CreateTextures(gl::TEXTURE_2D,1, &mut handle);
|
||||
|
||||
gl::TextureStorage2D(
|
||||
handle,
|
||||
levels as GLsizei,
|
||||
gl::RGBA8,
|
||||
image.size.width as GLsizei,
|
||||
|
@ -302,12 +304,10 @@ impl FilterChain {
|
|||
|
||||
gl::PixelStorei(gl::UNPACK_ROW_LENGTH, 0);
|
||||
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
|
||||
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
|
||||
gl::TexSubImage2D(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
gl::TextureSubImage2D(
|
||||
handle,
|
||||
0, 0, 0,
|
||||
image.size.width as GLsizei,
|
||||
image.size.height as GLsizei,
|
||||
gl::RGBA,
|
||||
|
@ -317,10 +317,8 @@ impl FilterChain {
|
|||
|
||||
let mipmap = levels > 1;
|
||||
if mipmap {
|
||||
gl::GenerateMipmap(gl::TEXTURE_2D);
|
||||
gl::GenerateTextureMipmap(handle);
|
||||
}
|
||||
|
||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
luts.insert(
|
||||
|
@ -338,6 +336,10 @@ impl FilterChain {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, pixel_unpack as GLuint);
|
||||
};
|
||||
Ok(luts)
|
||||
}
|
||||
|
||||
|
@ -416,17 +418,15 @@ impl FilterChain {
|
|||
let size = ubo.size;
|
||||
let mut ring: InlineRingBuffer<GLuint, 16> = InlineRingBuffer::new();
|
||||
unsafe {
|
||||
gl::GenBuffers(16, ring.items_mut().as_mut_ptr());
|
||||
gl::CreateBuffers(16, ring.items_mut().as_mut_ptr());
|
||||
for buffer in ring.items() {
|
||||
gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer);
|
||||
gl::BufferData(
|
||||
gl::UNIFORM_BUFFER,
|
||||
gl::NamedBufferData(
|
||||
*buffer,
|
||||
size as GLsizeiptr,
|
||||
std::ptr::null(),
|
||||
gl::STREAM_DRAW,
|
||||
);
|
||||
}
|
||||
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
||||
}
|
||||
Some(ring)
|
||||
} else {
|
||||
|
@ -593,11 +593,9 @@ impl FilterChain {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// do not need to rebind FBO 0 here since first `draw` will
|
||||
// bind automatically.
|
||||
gl::BindVertexArray(self.filter_vao);
|
||||
}
|
||||
// do not need to rebind FBO 0 here since first `draw` will
|
||||
// bind automatically.
|
||||
self.draw_quad.bind_vao();
|
||||
|
||||
let filter = passes[0].config.filter;
|
||||
let wrap_mode = passes[0].config.wrap_mode;
|
||||
|
@ -710,10 +708,9 @@ impl FilterChain {
|
|||
|
||||
self.push_history(input)?;
|
||||
|
||||
// pass.draw should return framebuffer bound to 0.
|
||||
unsafe {
|
||||
gl::BindVertexArray(0);
|
||||
}
|
||||
// do not need to rebind FBO 0 here since first `draw` will
|
||||
// bind automatically.
|
||||
self.draw_quad.unbind_vao();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -104,9 +104,7 @@ impl FilterPass {
|
|||
fn bind_texture(samplers: &SamplerSet, binding: &TextureBinding, texture: &Texture) {
|
||||
unsafe {
|
||||
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
||||
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
||||
|
||||
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
|
||||
gl::BindTextureUnit(binding.binding, texture.image.handle);
|
||||
gl::BindSampler(binding.binding,
|
||||
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
|
||||
}
|
||||
|
@ -137,7 +135,7 @@ impl FilterPass {
|
|||
let framebuffer = output.framebuffer;
|
||||
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
||||
// gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
||||
gl::UseProgram(self.program);
|
||||
}
|
||||
|
||||
|
@ -162,14 +160,12 @@ impl FilterPass {
|
|||
let buffer = ring.current();
|
||||
|
||||
unsafe {
|
||||
gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer);
|
||||
gl::BufferSubData(
|
||||
gl::UNIFORM_BUFFER,
|
||||
gl::NamedBufferSubData(
|
||||
*buffer,
|
||||
0,
|
||||
size as GLsizeiptr,
|
||||
self.uniform_buffer.as_ptr().cast(),
|
||||
);
|
||||
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
||||
|
||||
if self.ubo_location.vertex != gl::INVALID_INDEX {
|
||||
gl::BindBufferBase(gl::UNIFORM_BUFFER, self.ubo_location.vertex, *buffer);
|
||||
|
@ -183,10 +179,9 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
//
|
||||
// can use because DSA
|
||||
framebuffer.clear();
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
||||
gl::Viewport(
|
||||
output.x,
|
||||
output.y,
|
||||
|
@ -204,36 +199,7 @@ impl FilterPass {
|
|||
gl::Disable(gl::BLEND);
|
||||
gl::Disable(gl::DEPTH_TEST);
|
||||
|
||||
gl::EnableVertexAttribArray(0);
|
||||
gl::EnableVertexAttribArray(1);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, parent.draw_quad.vbo);
|
||||
|
||||
// the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo,
|
||||
// and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers.
|
||||
// that are inexpressible in Rust
|
||||
gl::VertexAttribPointer(
|
||||
0,
|
||||
2,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
(4 * std::mem::size_of::<f32>()) as GLsizei,
|
||||
std::ptr::invalid(0),
|
||||
);
|
||||
gl::VertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
gl::FLOAT,
|
||||
gl::FALSE,
|
||||
(4 * std::mem::size_of::<f32>()) as GLsizei,
|
||||
std::ptr::invalid(2 * std::mem::size_of::<f32>()),
|
||||
);
|
||||
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
||||
gl::DisableVertexAttribArray(0);
|
||||
gl::DisableVertexAttribArray(1);
|
||||
|
||||
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
}
|
||||
|
@ -483,12 +449,12 @@ impl FilterPass {
|
|||
|
||||
// bind float parameters
|
||||
for (id, (location, offset)) in
|
||||
self.uniform_bindings
|
||||
.iter()
|
||||
.filter_map(|(binding, value)| match binding {
|
||||
UniformBinding::Parameter(id) => Some((id, value)),
|
||||
_ => None,
|
||||
})
|
||||
self.uniform_bindings
|
||||
.iter()
|
||||
.filter_map(|(binding, value)| match binding {
|
||||
UniformBinding::Parameter(id) => Some((id, value)),
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
let id = id.as_str();
|
||||
let (buffer, offset) = match offset {
|
||||
|
|
|
@ -21,9 +21,7 @@ impl Framebuffer {
|
|||
pub fn new(max_levels: u32) -> Framebuffer {
|
||||
let mut framebuffer = 0;
|
||||
unsafe {
|
||||
gl::GenFramebuffers(1, &mut framebuffer);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::CreateFramebuffers(1, &mut framebuffer);
|
||||
}
|
||||
|
||||
Framebuffer {
|
||||
|
@ -139,11 +137,9 @@ impl Framebuffer {
|
|||
|
||||
pub(crate) fn clear(&self) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||
gl::ClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::ClearNamedFramebufferfv(self.handle,
|
||||
gl::COLOR, 0,
|
||||
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,64 +150,15 @@ impl Framebuffer {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
||||
// gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
||||
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
||||
gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
||||
|
||||
gl::FramebufferTexture2D(
|
||||
gl::READ_FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
image.handle,
|
||||
0,
|
||||
);
|
||||
gl::BlitNamedFramebuffer(image.handle, self.handle,
|
||||
0, 0, image.size.width as GLint, image.size.height as GLint,
|
||||
0, 0, self.size.width as GLint, self.size.height as GLint,
|
||||
gl::COLOR_BUFFER_BIT, gl::NEAREST);
|
||||
|
||||
gl::FramebufferTexture2D(
|
||||
gl::DRAW_FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT1,
|
||||
gl::TEXTURE_2D,
|
||||
self.image,
|
||||
0,
|
||||
);
|
||||
gl::DrawBuffer(gl::COLOR_ATTACHMENT1);
|
||||
gl::BlitFramebuffer(
|
||||
0,
|
||||
0,
|
||||
self.size.width as GLint,
|
||||
self.size.height as GLint,
|
||||
0,
|
||||
0,
|
||||
self.size.width as GLint,
|
||||
self.size.height as GLint,
|
||||
gl::COLOR_BUFFER_BIT,
|
||||
gl::NEAREST,
|
||||
);
|
||||
|
||||
// cleanup after ourselves.
|
||||
gl::FramebufferTexture2D(
|
||||
gl::READ_FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
gl::FramebufferTexture2D(
|
||||
gl::DRAW_FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT1,
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
// set this back to color_attachment 0
|
||||
gl::FramebufferTexture2D(
|
||||
gl::FRAMEBUFFER,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
self.image,
|
||||
0,
|
||||
);
|
||||
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -225,22 +172,18 @@ impl Framebuffer {
|
|||
self.size = size;
|
||||
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
||||
|
||||
// reset the framebuffer image
|
||||
if self.image != 0 {
|
||||
gl::FramebufferTexture2D(
|
||||
gl::FRAMEBUFFER,
|
||||
gl::NamedFramebufferTexture(
|
||||
self.handle,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
gl::DeleteTextures(1, &self.image);
|
||||
}
|
||||
|
||||
gl::GenTextures(1, &mut self.image);
|
||||
gl::BindTexture(gl::TEXTURE_2D, self.image);
|
||||
gl::CreateTextures(gl::TEXTURE_2D,1, &mut self.image);
|
||||
|
||||
if size.width == 0 {
|
||||
size.width = 1;
|
||||
|
@ -257,18 +200,17 @@ impl Framebuffer {
|
|||
self.levels = 1;
|
||||
}
|
||||
|
||||
gl::TexStorage2D(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TextureStorage2D(
|
||||
self.image,
|
||||
self.levels as GLsizei,
|
||||
self.format,
|
||||
size.width as GLsizei,
|
||||
size.height as GLsizei,
|
||||
);
|
||||
|
||||
gl::FramebufferTexture2D(
|
||||
gl::FRAMEBUFFER,
|
||||
gl::NamedFramebufferTexture(
|
||||
self.handle,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
self.image,
|
||||
0,
|
||||
);
|
||||
|
@ -279,16 +221,14 @@ impl Framebuffer {
|
|||
gl::FRAMEBUFFER_UNSUPPORTED => {
|
||||
eprintln!("unsupported fbo");
|
||||
|
||||
gl::FramebufferTexture2D(
|
||||
gl::FRAMEBUFFER,
|
||||
gl::NamedFramebufferTexture(
|
||||
self.handle,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
gl::DeleteTextures(1, &self.image);
|
||||
gl::GenTextures(1, &mut self.image);
|
||||
gl::BindTexture(1, self.image);
|
||||
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
|
||||
|
||||
self.levels = util::calc_miplevel(size);
|
||||
if self.levels > self.max_levels {
|
||||
|
@ -298,17 +238,16 @@ impl Framebuffer {
|
|||
self.levels = 1;
|
||||
}
|
||||
|
||||
gl::TexStorage2D(
|
||||
gl::TEXTURE_2D,
|
||||
gl::TextureStorage2D(
|
||||
self.image,
|
||||
self.levels as GLsizei,
|
||||
ShaderFormat::R8G8B8A8Unorm.into(),
|
||||
size.width as GLsizei,
|
||||
size.height as GLsizei,
|
||||
);
|
||||
gl::FramebufferTexture2D(
|
||||
gl::FRAMEBUFFER,
|
||||
gl::NamedFramebufferTexture(
|
||||
self.handle,
|
||||
gl::COLOR_ATTACHMENT0,
|
||||
gl::TEXTURE_2D,
|
||||
self.image,
|
||||
0,
|
||||
);
|
||||
|
@ -318,9 +257,6 @@ impl Framebuffer {
|
|||
_ => return Err(FilterChainError::FramebufferInit(status))
|
||||
}
|
||||
}
|
||||
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::framebuffer::{Framebuffer, GlImage, Viewport};
|
|||
|
||||
const WIDTH: u32 = 900;
|
||||
const HEIGHT: u32 = 700;
|
||||
const TITLE: &str = "librashader OpenGL";
|
||||
const TITLE: &str = "librashader OpenGL 4.6";
|
||||
|
||||
pub fn compile_program(vertex: &str, fragment: &str) -> GLuint {
|
||||
let vertex_shader = unsafe { gl::CreateShader(gl::VERTEX_SHADER) };
|
||||
|
@ -215,7 +215,7 @@ void main()
|
|||
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
||||
|
||||
gl::VertexArrayVertexBuffer(vao, 0,
|
||||
vbo, 0, (6 * std::mem::size_of::<f32>()) as GLint
|
||||
vbo, 0, 6 * std::mem::size_of::<f32>() as GLint
|
||||
);
|
||||
|
||||
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
|
||||
|
@ -226,7 +226,7 @@ void main()
|
|||
|
||||
gl::EnableVertexArrayAttrib(vao, 1);
|
||||
gl::VertexArrayAttribFormat(vao, 1, 3,
|
||||
gl::FLOAT, gl::FALSE, (3 * std::mem::size_of::<f32>() as GLuint));
|
||||
gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::<f32>() as GLuint);
|
||||
|
||||
|
||||
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||
|
@ -461,13 +461,11 @@ void main()
|
|||
|
||||
unsafe {
|
||||
// render to fb
|
||||
|
||||
gl::ClearNamedFramebufferfv(rendered_framebuffer, gl::COLOR, 0, [0.3f32, 0.4, 0.6, 1.0].as_ptr().cast());
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
||||
gl::Viewport(0, 0, vp_width, vp_height);
|
||||
|
||||
// clear color
|
||||
clear_color(Color(0.3, 0.4, 0.6, 1.0));
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
// do the drawing
|
||||
gl::UseProgram(triangle_program);
|
||||
// select vertices
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use gl::types::{GLsizeiptr, GLuint};
|
||||
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
||||
|
||||
#[rustfmt::skip]
|
||||
static QUAD_VBO_DATA: &[f32; 16] = &[
|
||||
|
@ -9,24 +9,55 @@ static QUAD_VBO_DATA: &[f32; 16] = &[
|
|||
];
|
||||
|
||||
pub struct DrawQuad {
|
||||
pub vbo: GLuint,
|
||||
vbo: GLuint,
|
||||
vao: GLuint,
|
||||
}
|
||||
|
||||
impl DrawQuad {
|
||||
pub fn new() -> DrawQuad {
|
||||
let mut vbo = 0;
|
||||
let mut vao = 0;
|
||||
|
||||
unsafe {
|
||||
gl::GenBuffers(1, &mut vbo);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
|
||||
gl::BufferData(
|
||||
gl::ARRAY_BUFFER,
|
||||
gl::CreateBuffers(1, &mut vbo);
|
||||
gl::NamedBufferData(
|
||||
vbo,
|
||||
std::mem::size_of_val(QUAD_VBO_DATA) as GLsizeiptr,
|
||||
QUAD_VBO_DATA.as_ptr().cast(),
|
||||
gl::STATIC_DRAW,
|
||||
);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
||||
gl::CreateVertexArrays(1, &mut vao);
|
||||
|
||||
gl::EnableVertexArrayAttrib(vao, 0);
|
||||
gl::EnableVertexArrayAttrib(vao, 1);
|
||||
|
||||
gl::VertexArrayVertexBuffer(vao, 0,
|
||||
vbo, 0, 4 * std::mem::size_of::<f32>() as GLint
|
||||
);
|
||||
|
||||
gl::VertexArrayAttribFormat(vao, 0, 2,
|
||||
gl::FLOAT, gl::FALSE, 0);
|
||||
gl::VertexArrayAttribFormat(vao, 1, 2,
|
||||
gl::FLOAT, gl::FALSE,
|
||||
2 * std::mem::size_of::<f32>() as GLuint);
|
||||
|
||||
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||
gl::VertexArrayAttribBinding(vao, 1, 0);
|
||||
|
||||
}
|
||||
|
||||
DrawQuad { vbo }
|
||||
DrawQuad { vbo, vao }
|
||||
}
|
||||
|
||||
pub fn bind_vao(&self) {
|
||||
unsafe {
|
||||
gl::BindVertexArray(self.vao);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unbind_vao(&self) {
|
||||
unsafe {
|
||||
gl::BindVertexArray(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ librashader-preprocess = { path = "../librashader-preprocess" }
|
|||
librashader-reflect = { path = "../librashader-reflect" }
|
||||
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
||||
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
||||
librashader-runtime-gl46 = { path = "../librashader-runtime-gl46" }
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -27,7 +27,7 @@ pub mod reflect {
|
|||
}
|
||||
|
||||
pub mod targets {
|
||||
/// Shader compiler targets and runtime for OpenGL.
|
||||
/// Shader compiler targets and runtime for OpenGL 3.3+.
|
||||
pub mod gl {
|
||||
/// Shader compiler target for GLSL.
|
||||
pub use librashader_reflect::back::targets::GLSL;
|
||||
|
@ -38,6 +38,17 @@ pub mod targets {
|
|||
}
|
||||
}
|
||||
|
||||
/// Shader compiler targets and runtime for OpenGL 4.6.
|
||||
pub mod gl46 {
|
||||
/// Shader compiler target for GLSL.
|
||||
pub use librashader_reflect::back::targets::GLSL;
|
||||
|
||||
/// Shader runtime for OpenGL.
|
||||
pub mod runtime {
|
||||
pub use librashader_runtime_gl46::*;
|
||||
}
|
||||
}
|
||||
|
||||
/// Shader compiler targets and runtime for DirectX.
|
||||
pub mod dx {
|
||||
/// Shader compiler target for HLSL.
|
||||
|
|
Loading…
Reference in a new issue