grafix_toolbox/kit/opengl/control/
universion.rs

1#![allow(dead_code, clippy::too_many_arguments, clippy::not_unsafe_ptr_arg_deref)]
2use crate::lib::*;
3
4#[cfg(not(feature = "gl45"))]
5pub const GL_VERSION: (u32, u32, STR) = (3, 3, "#version 330 core\n");
6#[cfg(feature = "gl45")]
7pub const GL_VERSION: (u32, u32, STR) = (4, 5, "#version 450 core\n");
8
9pub const GLSL_VERSION: STR = GL_VERSION.2;
10
11#[cfg(not(debug_assertions))]
12pub const IS_DEBUG: bool = false;
13#[cfg(debug_assertions)]
14pub const IS_DEBUG: bool = true;
15
16#[cfg(not(feature = "gl45"))]
17macro_rules! G {
18	($g33: expr, $g45: expr) => {
19		unsafe { $g33 }
20	};
21}
22#[cfg(feature = "gl45")]
23macro_rules! G {
24	($g33: expr, $g45: expr) => {
25		unsafe { $g45 }
26	};
27}
28
29pub fn glCreateBuffer(obj: &mut u32) {
30	G!(gl::GenBuffers(1, obj), gl::CreateBuffers(1, obj));
31}
32pub fn glCreateVao(obj: &mut u32) {
33	G!(gl::GenVertexArrays(1, obj), gl::CreateVertexArrays(1, obj));
34}
35pub fn glCreateTexture(_typ: GLenum, obj: &mut u32) {
36	G!(gl::GenTextures(1, obj), gl::CreateTextures(_typ, 1, obj));
37}
38pub fn glDeleteTexture(obj: &mut u32) {
39	G!(
40		{
41			if *obj == *bound_tex33() {
42				*bound_tex33() = 0;
43			}
44			gl::DeleteTextures(1, obj);
45		},
46		gl::DeleteTextures(1, obj)
47	);
48}
49pub fn glCreateFramebuff(obj: &mut u32) {
50	G!(gl::GenFramebuffers(1, obj), gl::CreateFramebuffers(1, obj));
51}
52pub fn glCreateRenderbuff(obj: &mut u32) {
53	G!(gl::GenRenderbuffers(1, obj), gl::CreateRenderbuffers(1, obj));
54}
55pub fn glBufferStorage(_typ: GLenum, obj: u32, size: isize, data: *const GLvoid, _usage: GLenum) {
56	G!(
57		{
58			gl::BindBuffer(_typ, obj);
59			gl::BufferData(_typ, size, data, gl::DYNAMIC_DRAW);
60		},
61		gl::NamedBufferStorage(obj, size, data, _usage)
62	);
63}
64pub fn glBufferSubData(_typ: GLenum, obj: u32, offset: isize, size: isize, data: *const GLvoid) {
65	G!(
66		{
67			gl::BindBuffer(_typ, obj);
68			gl::BufferSubData(_typ, offset, size, data);
69		},
70		gl::NamedBufferSubData(obj, offset, size, data)
71	);
72}
73pub fn glMapBufferRange(_typ: GLenum, obj: u32, offset: isize, length: isize, access: GLbitfield) -> *mut GLvoid {
74	G!(
75		{
76			gl::BindBuffer(_typ, obj);
77			gl::MapBufferRange(_typ, offset, length, access)
78		},
79		gl::MapNamedBufferRange(obj, offset, length, access)
80	)
81}
82pub fn glUnmapBuffer(_typ: GLenum, obj: u32) -> GLbool {
83	G!(
84		{
85			gl::BindBuffer(_typ, obj);
86			gl::UnmapBuffer(_typ)
87		},
88		gl::UnmapNamedBuffer(obj)
89	)
90}
91pub fn glVaoElementBuffer(vao: u32, buf: u32) {
92	G!(
93		{
94			gl::BindVertexArray(vao);
95			gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, buf);
96			gl::BindVertexArray(0);
97		},
98		gl::VertexArrayElementBuffer(vao, buf)
99	);
100}
101pub fn glVertexAttribFormat(vao: u32, buf: u32, idx: u32, size: u32, typ: GLenum, normalized: GLbool, stride: u32, offset: u32, t_size: u32) {
102	G!(
103		{
104			gl::BindVertexArray(vao);
105			gl::BindBuffer(gl::ARRAY_BUFFER, buf);
106			gl::EnableVertexAttribArray(idx);
107			gl::VertexAttribPointer(idx, i32(size), typ, normalized, i32(stride), (offset * t_size) as *const GLvoid);
108			gl::BindVertexArray(0);
109		},
110		{
111			gl::EnableVertexArrayAttrib(vao, idx);
112			gl::VertexArrayVertexBuffer(vao, idx, buf, 0, i32((size + stride) * t_size));
113			gl::VertexArrayAttribFormat(vao, idx, i32(size), typ, normalized, offset * t_size);
114			gl::VertexArrayAttribBinding(vao, idx, idx);
115		}
116	);
117}
118pub fn glTextureBuffer(_typ: GLenum, tex: u32, fmt: GLenum, buf: u32) {
119	G!(
120		{
121			gl::BindTexture(_typ, tex);
122			gl::TexBuffer(_typ, fmt, buf);
123			gl::BindTexture(_typ, *bound_tex33());
124		},
125		gl::TextureBuffer(tex, fmt, buf)
126	);
127}
128pub fn glTextureStorage1D(_typ: GLenum, tex: u32, levels: i32, fmt: GLenum, w: i32) {
129	G!(
130		{
131			gl::BindTexture(_typ, tex);
132			let mut w = w;
133			for lvl in 0..levels {
134				gl::TexImage1D(_typ, lvl, formatDepth45to33(fmt), w, 0, gl::RGBA, gl::FLOAT, 0 as *const GLvoid);
135				w = 1.max(w / 2);
136			}
137			gl::BindTexture(_typ, *bound_tex33());
138		},
139		gl::TextureStorage1D(tex, levels, fmt, w)
140	);
141}
142pub fn glTextureStorage2D(_typ: GLenum, tex: u32, levels: i32, fmt: GLenum, w: i32, h: i32) {
143	G!(
144		{
145			gl::BindTexture(_typ, tex);
146			let (mut w, mut h) = (w, h);
147			for lvl in 0..levels {
148				if _typ == gl::TEXTURE_CUBE_MAP {
149					for f in 0..6 {
150						let f = gl::TEXTURE_CUBE_MAP_POSITIVE_X + f;
151						gl::TexImage2D(f, lvl, formatDepth45to33(fmt), w, h, 0, gl::RGBA, gl::FLOAT, 0 as *const GLvoid);
152					}
153				} else {
154					gl::TexImage2D(_typ, lvl, formatDepth45to33(fmt), w, h, 0, gl::RGBA, gl::FLOAT, 0 as *const GLvoid);
155				}
156				w = 1.max(w / 2);
157				h = 1.max(h / 2);
158			}
159			gl::BindTexture(_typ, *bound_tex33());
160		},
161		gl::TextureStorage2D(tex, levels, fmt, w, h)
162	);
163}
164pub fn glTextureStorage3D(_typ: GLenum, tex: u32, levels: i32, fmt: GLenum, w: i32, h: i32, d: i32) {
165	G!(
166		{
167			gl::BindTexture(_typ, tex);
168			let (mut w, mut h, mut d) = (w, h, d);
169			for lvl in 0..levels {
170				gl::TexImage3D(_typ, lvl, formatDepth45to33(fmt), w, h, d, 0, gl::RGBA, gl::FLOAT, 0 as *const GLvoid);
171				w = 1.max(w / 2);
172				h = 1.max(h / 2);
173				d = 1.max(d / 2);
174			}
175			gl::BindTexture(_typ, *bound_tex33());
176		},
177		gl::TextureStorage3D(tex, levels, fmt, w, h, d)
178	);
179}
180pub fn glTextureSubImage1D(_typ: GLenum, tex: u32, lvl: i32, x: i32, w: i32, fmt: GLenum, t: GLenum, data: *const GLvoid) {
181	G!(
182		{
183			gl::BindTexture(_typ, tex);
184			gl::TexSubImage1D(_typ, lvl, x, w, fmt, t, data);
185			gl::BindTexture(_typ, *bound_tex33());
186		},
187		gl::TextureSubImage1D(tex, lvl, x, w, fmt, t, data)
188	);
189}
190pub fn glTextureSubImage2D(_typ: GLenum, tex: u32, lvl: i32, x: i32, y: i32, w: i32, h: i32, fmt: GLenum, t: GLenum, data: *const GLvoid) {
191	G!(
192		{
193			gl::BindTexture(_typ, tex);
194			gl::TexSubImage2D(_typ, lvl, x, y, w, h, fmt, t, data);
195			gl::BindTexture(_typ, *bound_tex33());
196		},
197		gl::TextureSubImage2D(tex, lvl, x, y, w, h, fmt, t, data)
198	);
199}
200pub fn glTextureSubImage3D(_typ: GLenum, tex: u32, lvl: i32, x: i32, y: i32, z: i32, w: i32, h: i32, d: i32, fmt: GLenum, t: GLenum, data: *const GLvoid) {
201	G!(
202		{
203			gl::BindTexture(_typ, tex);
204			if _typ == gl::TEXTURE_CUBE_MAP {
205				gl::TexSubImage2D(gl::TEXTURE_CUBE_MAP_POSITIVE_X + u32(z), lvl, x, y, w, h, fmt, t, data);
206			} else {
207				gl::TexSubImage3D(_typ, lvl, x, y, z, w, h, d, fmt, t, data);
208			}
209			gl::BindTexture(_typ, *bound_tex33());
210		},
211		gl::TextureSubImage3D(tex, lvl, x, y, z, w, h, d, fmt, t, data)
212	);
213}
214pub fn glBindTextureUnit(_typ: GLenum, unit: u32, tex: u32) {
215	G!(
216		{
217			gl::ActiveTexture(gl::TEXTURE0 + unit);
218			gl::BindTexture(_typ, tex);
219			*bound_tex33() = tex;
220		},
221		gl::BindTextureUnit(unit, tex)
222	);
223}
224pub fn glGenMipmaps(_typ: GLenum, tex: u32) {
225	G!(
226		{
227			gl::BindTexture(_typ, tex);
228			gl::GenerateMipmap(_typ);
229			gl::BindTexture(_typ, *bound_tex33());
230		},
231		gl::GenerateTextureMipmap(tex)
232	);
233}
234pub fn glGetTexture(_typ: GLenum, tex: u32, lvl: i32, fmt: GLenum, t: GLenum, _size: i32, data: *mut GLvoid) {
235	G!(
236		{
237			gl::BindTexture(_typ, tex);
238			gl::GetTexImage(_typ, lvl, fmt, t, data);
239			gl::BindTexture(_typ, *bound_tex33());
240		},
241		gl::GetTextureImage(tex, lvl, fmt, t, _size, data)
242	);
243}
244pub fn glClearFramebuff(fb: u32, typ: GLenum, buffidx: i32, val: *const f32) {
245	G!(
246		{
247			gl::BindFramebuffer(gl::FRAMEBUFFER, fb);
248			gl::ClearBufferfv(typ, buffidx, val);
249			gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
250		},
251		gl::ClearNamedFramebufferfv(fb, typ, buffidx, val)
252	);
253}
254pub fn glFramebuffTex(fb: u32, tex: u32, attach: GLenum) {
255	G!(
256		{
257			gl::BindFramebuffer(gl::FRAMEBUFFER, fb);
258			gl::FramebufferTexture(gl::FRAMEBUFFER, attach, tex, 0);
259			gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
260		},
261		gl::NamedFramebufferTexture(fb, attach, tex, 0)
262	);
263}
264pub fn glFramebuffRenderbuff(fb: u32, rb: u32, attach: GLenum) {
265	G!(
266		{
267			gl::BindFramebuffer(gl::FRAMEBUFFER, fb);
268			gl::FramebufferRenderbuffer(gl::FRAMEBUFFER, attach, gl::RENDERBUFFER, rb);
269			gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
270		},
271		gl::NamedFramebufferRenderbuffer(fb, attach, gl::RENDERBUFFER, rb)
272	);
273}
274pub fn glRenderbuffStorage(fb: u32, sampl: i32, fmt: GLenum, w: i32, h: i32) {
275	G!(
276		{
277			gl::BindRenderbuffer(gl::RENDERBUFFER, fb);
278			if sampl == 1 {
279				gl::RenderbufferStorage(gl::RENDERBUFFER, fmt, w, h);
280			} else {
281				gl::RenderbufferStorageMultisample(gl::RENDERBUFFER, sampl, fmt, w, h);
282			}
283			gl::BindRenderbuffer(gl::RENDERBUFFER, 0);
284		},
285		if sampl == 1 {
286			gl::NamedRenderbufferStorage(fb, fmt, w, h);
287		} else {
288			gl::NamedRenderbufferStorageMultisample(fb, sampl, fmt, w, h);
289		}
290	);
291}
292
293fn formatDepth45to33(fmt: GLenum) -> i32 {
294	i32(if fmt == gl::DEPTH_COMPONENT32F || fmt == gl::DEPTH_COMPONENT24 || fmt == gl::DEPTH_COMPONENT16 {
295		WARN!("Using unspecified GL_DEPTH_COMPONENT size");
296		gl::DEPTH_COMPONENT
297	} else {
298		fmt
299	})
300}
301
302fn bound_tex33() -> &'static mut u32 {
303	LocalStatic!(u32, { 0 })
304}