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}