and we have the linux wayland backend usable (sorta)
parent
89f0a15ade
commit
fb60bd5f32
2
justfile
2
justfile
|
@ -4,7 +4,7 @@ alias r := run
|
||||||
c_flags := if os() == "macos" {
|
c_flags := if os() == "macos" {
|
||||||
"$(curl-config --libs) -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC"
|
"$(curl-config --libs) -framework Cocoa -framework QuartzCore -framework CoreImage -framework Metal -framework MetalKit -ObjC"
|
||||||
} else if os_family() == "unix" {
|
} else if os_family() == "unix" {
|
||||||
"$(curl-config --libs) -lEGL -lGLESv2 -lGL -lm -lwayland-client -lwayland-egl -lX11 -lXi -lXcursor"
|
"$(curl-config --libs) -lEGL -lGLESv2 -lGL -lm -lwayland-client -lwayland-egl -lX11 -lXi -lXcursor -Wno-implicit-function-declaration"
|
||||||
} else { "" }
|
} else { "" }
|
||||||
|
|
||||||
[macos]
|
[macos]
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#version 440 core
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
vec4 position;
|
||||||
|
vec2 tex_coord;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in VertexOutput out_vertex;
|
||||||
|
layout(location = 1) uniform highp sampler2D atlas_texture;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float text_color = texture(atlas_texture, out_vertex.tex_coord).r;
|
||||||
|
|
||||||
|
color = vec4(text_color * vec3(1,1,1), text_color);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#version 440 core
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
vec2 position;
|
||||||
|
vec2 tex_coord;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
vec4 position;
|
||||||
|
vec2 tex_coord;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Glyph {
|
||||||
|
vec2 atlas_position;
|
||||||
|
vec2 size;
|
||||||
|
vec2 target_position;
|
||||||
|
float y_offset;
|
||||||
|
float _haha_alignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 0) readonly buffer VertexBlock {
|
||||||
|
Vertex vertices[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 1) readonly buffer GlyphBlock {
|
||||||
|
Glyph glyphs[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 2) readonly buffer ParamsBlock {
|
||||||
|
vec2 screen_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
vec4 to_device_position(vec2 position, vec2 size) {
|
||||||
|
return vec4(((position / size) * 2.0) - vec2(1.0), 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location = 0) out VertexOutput out_vertex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Glyph glyph = glyphs[gl_InstanceID];
|
||||||
|
|
||||||
|
vec2 scaled_size = ((vertices[gl_VertexID].position + 1.0) / 2.0) * (glyph.size/2.0);
|
||||||
|
vec2 scaled_size_2 = ((vertices[gl_VertexID].position + 1.0) / 2.0) * (glyph.size);
|
||||||
|
vec2 glyph_pos = scaled_size + glyph.target_position + vec2(0, glyph.y_offset/2.0+24);
|
||||||
|
|
||||||
|
vec4 device_position = to_device_position(glyph_pos, screen_size);
|
||||||
|
vec2 atlas_position = (scaled_size_2 + glyph.atlas_position) / 512.0;
|
||||||
|
|
||||||
|
device_position.y = -device_position.y;
|
||||||
|
|
||||||
|
out_vertex.position = device_position;
|
||||||
|
out_vertex.tex_coord = atlas_position;
|
||||||
|
|
||||||
|
gl_Position = device_position;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#version 320 es
|
#version 440 core
|
||||||
|
|
||||||
struct UiRectFragment {
|
struct UiRectFragment {
|
||||||
highp vec4 device_position;
|
highp vec4 device_position;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#version 320 es
|
#version 440 core
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
vec2 position;
|
vec2 position;
|
||||||
|
@ -23,7 +23,7 @@ struct UiRectFragment {
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std430, binding = 0) readonly buffer VertexBlock {
|
layout(std430, binding = 0) readonly buffer VertexBlock {
|
||||||
Vertex verticies[];
|
Vertex vertices[];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std430, binding = 1) readonly buffer RectBlock {
|
layout(std430, binding = 1) readonly buffer RectBlock {
|
||||||
|
@ -38,13 +38,13 @@ out UiRectFragment out_rect;
|
||||||
void main() {
|
void main() {
|
||||||
UiRect rect = rects[gl_InstanceID];
|
UiRect rect = rects[gl_InstanceID];
|
||||||
|
|
||||||
out_rect.device_position = vec4(verticies[gl_VertexID].position, 1, 1);
|
out_rect.device_position = vec4(vertices[gl_VertexID].position, 1, 1);
|
||||||
out_rect.position = rect.position.xy;
|
out_rect.position = rect.position.xy;
|
||||||
out_rect.size = rect.size.xy;
|
out_rect.size = rect.size.xy;
|
||||||
out_rect.border_size = rect.border_size.xy;
|
out_rect.border_size = rect.border_size.xy;
|
||||||
out_rect.screen_size = screen_size;
|
out_rect.screen_size = screen_size;
|
||||||
out_rect.tex_coord = verticies[gl_VertexID].tex_coord;
|
out_rect.tex_coord = vertices[gl_VertexID].tex_coord;
|
||||||
out_rect.color = rect.color;
|
out_rect.color = rect.color;
|
||||||
|
|
||||||
gl_Position = vec4(verticies[gl_VertexID].position, 1, 1);
|
gl_Position = vec4(vertices[gl_VertexID].position, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
69
src/gfx.h
69
src/gfx.h
|
@ -113,13 +113,15 @@ typedef struct {
|
||||||
int mouse_x, mouse_y;
|
int mouse_x, mouse_y;
|
||||||
int mouse_left_down, mouse_right_down;
|
int mouse_left_down, mouse_right_down;
|
||||||
|
|
||||||
GLuint vao;
|
|
||||||
GLuint ui_rect_vertex_shader;
|
GLuint ui_rect_vertex_shader;
|
||||||
GLuint ui_rect_fragment_shader;
|
GLuint ui_rect_fragment_shader;
|
||||||
GLuint text_atlas_vertex_shader;
|
GLuint text_atlas_vertex_shader;
|
||||||
GLuint text_atlas_fragment_shader;
|
GLuint text_atlas_fragment_shader;
|
||||||
GLuint ui_rect_shader_program;
|
GLuint ui_rect_shader_program;
|
||||||
|
GLuint text_atlas_shader_program;
|
||||||
|
|
||||||
array(GLuint) buffers;
|
array(GLuint) buffers;
|
||||||
|
array(GLuint) textures;
|
||||||
} _opengl_gfx_context_wayland;
|
} _opengl_gfx_context_wayland;
|
||||||
|
|
||||||
static void _opengl_gfx_present_wayland(_opengl_gfx_context_wayland *cx);
|
static void _opengl_gfx_present_wayland(_opengl_gfx_context_wayland *cx);
|
||||||
|
@ -942,6 +944,10 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) {
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
glDebugMessageCallback(_opengl_gfx_message_callback, NULL);
|
glDebugMessageCallback(_opengl_gfx_message_callback, NULL);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
cx.ui_rect_vertex_shader = _opengl_gfx_compile_shader(
|
cx.ui_rect_vertex_shader = _opengl_gfx_compile_shader(
|
||||||
_String("shaders/ui_rect_vertex.glsl"), GL_VERTEX_SHADER);
|
_String("shaders/ui_rect_vertex.glsl"), GL_VERTEX_SHADER);
|
||||||
cx.ui_rect_fragment_shader = _opengl_gfx_compile_shader(
|
cx.ui_rect_fragment_shader = _opengl_gfx_compile_shader(
|
||||||
|
@ -951,10 +957,23 @@ _opengl_gfx_init_context_wayland(uint32_t width, uint32_t height) {
|
||||||
glAttachShader(cx.ui_rect_shader_program, cx.ui_rect_fragment_shader);
|
glAttachShader(cx.ui_rect_shader_program, cx.ui_rect_fragment_shader);
|
||||||
glLinkProgram(cx.ui_rect_shader_program);
|
glLinkProgram(cx.ui_rect_shader_program);
|
||||||
_opengl_gfx_check_shader_program_error(
|
_opengl_gfx_check_shader_program_error(
|
||||||
_String("failed to link shader program"), cx.ui_rect_shader_program,
|
_String("failed to link ui_rect shader program"),
|
||||||
GL_LINK_STATUS);
|
cx.ui_rect_shader_program, GL_LINK_STATUS);
|
||||||
|
|
||||||
|
cx.text_atlas_vertex_shader = _opengl_gfx_compile_shader(
|
||||||
|
_String("shaders/text_atlas_vertex.glsl"), GL_VERTEX_SHADER);
|
||||||
|
cx.text_atlas_fragment_shader = _opengl_gfx_compile_shader(
|
||||||
|
_String("shaders/text_atlas_fragment.glsl"), GL_FRAGMENT_SHADER);
|
||||||
|
cx.text_atlas_shader_program = glCreateProgram();
|
||||||
|
glAttachShader(cx.text_atlas_shader_program, cx.text_atlas_vertex_shader);
|
||||||
|
glAttachShader(cx.text_atlas_shader_program, cx.text_atlas_fragment_shader);
|
||||||
|
glLinkProgram(cx.text_atlas_shader_program);
|
||||||
|
_opengl_gfx_check_shader_program_error(
|
||||||
|
_String("failed to link text_atlas shader program"),
|
||||||
|
cx.text_atlas_shader_program, GL_LINK_STATUS);
|
||||||
|
|
||||||
cx.buffers = newArray(GLuint, 8);
|
cx.buffers = newArray(GLuint, 8);
|
||||||
|
cx.textures = newArray(GLuint, 8);
|
||||||
/* ******** */
|
/* ******** */
|
||||||
|
|
||||||
return cx;
|
return cx;
|
||||||
|
@ -1031,6 +1050,9 @@ static void _opengl_gfx_present_wayland(_opengl_gfx_context_wayland *cx) {
|
||||||
|
|
||||||
gfx_update_buffer(&_gfx_context, 3, &gpu_uniform_params,
|
gfx_update_buffer(&_gfx_context, 3, &gpu_uniform_params,
|
||||||
sizeof(GpuUniformParams));
|
sizeof(GpuUniformParams));
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glViewport(0, 0, _gfx_context.frame_width, _gfx_context.frame_height);
|
||||||
|
|
||||||
if (_gfx_context.gpu_ui_rects.size > 0) {
|
if (_gfx_context.gpu_ui_rects.size > 0) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cx->buffers.data[0]);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cx->buffers.data[0]);
|
||||||
|
@ -1038,19 +1060,26 @@ static void _opengl_gfx_present_wayland(_opengl_gfx_context_wayland *cx) {
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, cx->buffers.data[3]);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, cx->buffers.data[3]);
|
||||||
glUseProgram(cx->ui_rect_shader_program);
|
glUseProgram(cx->ui_rect_shader_program);
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glViewport(0, 0, _gfx_context.frame_width, _gfx_context.frame_height);
|
|
||||||
|
|
||||||
const uint16_t indices[] = {0, 1, 2, 0, 2, 3};
|
const uint16_t indices[] = {0, 1, 2, 0, 2, 3};
|
||||||
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices,
|
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices,
|
||||||
_gfx_context.gpu_ui_rects.size);
|
_gfx_context.gpu_ui_rects.size);
|
||||||
|
}
|
||||||
|
|
||||||
glFlush();
|
if (_gfx_context.gpu_glyphs.size > 0) {
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cx->buffers.data[0]);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, cx->buffers.data[2]);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, cx->buffers.data[3]);
|
||||||
|
glUseProgram(cx->text_atlas_shader_program);
|
||||||
|
|
||||||
if (eglSwapBuffers(cx->egl_display, cx->egl_surface) != EGL_TRUE) {
|
const uint16_t indices[] = {0, 1, 2, 0, 2, 3};
|
||||||
fprintf(stderr, "eglSwapBuffers() failed\n");
|
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices,
|
||||||
}
|
_gfx_context.gpu_glyphs.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
|
||||||
|
if (eglSwapBuffers(cx->egl_display, cx->egl_surface) != EGL_TRUE) {
|
||||||
|
fprintf(stderr, "eglSwapBuffers() failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,8 +1087,21 @@ static size_t
|
||||||
_opengl_gfx_push_texture_buffer_wayland(_opengl_gfx_context_wayland *cx,
|
_opengl_gfx_push_texture_buffer_wayland(_opengl_gfx_context_wayland *cx,
|
||||||
uint32_t width, uint32_t height,
|
uint32_t width, uint32_t height,
|
||||||
const void *data, size_t len) {
|
const void *data, size_t len) {
|
||||||
// TODO
|
pushArray(GLuint, &cx->textures, 0);
|
||||||
return 0;
|
glCreateTextures(GL_TEXTURE_2D, 1,
|
||||||
|
&cx->textures.data[cx->textures.size - 1]);
|
||||||
|
glTextureParameteri(cx->textures.data[cx->textures.size - 1],
|
||||||
|
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTextureParameteri(cx->textures.data[cx->textures.size - 1],
|
||||||
|
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTextureStorage2D(cx->textures.data[cx->textures.size - 1], 1, GL_RGBA8,
|
||||||
|
width, height);
|
||||||
|
glTextureSubImage2D(cx->textures.data[cx->textures.size - 1], 0, 0, 0,
|
||||||
|
width, height, GL_RED, GL_UNSIGNED_BYTE, data);
|
||||||
|
glBindTextureUnit(cx->textures.size - 1,
|
||||||
|
cx->textures.data[cx->textures.size - 1]);
|
||||||
|
|
||||||
|
return cx->textures.size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1067,6 +1109,7 @@ _opengl_gfx_resize_texture_buffer_wayland(_opengl_gfx_context_wayland *cx,
|
||||||
uint32_t width, size_t texture_index,
|
uint32_t width, size_t texture_index,
|
||||||
uint32_t height) {
|
uint32_t height) {
|
||||||
// TODO
|
// TODO
|
||||||
|
assert(false && "_opengl_gfx_resize_texture_buffer_wayland unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _opengl_gfx_push_vertex_buffer_wayland(_opengl_gfx_context_wayland *cx,
|
size_t _opengl_gfx_push_vertex_buffer_wayland(_opengl_gfx_context_wayland *cx,
|
||||||
|
|
Loading…
Reference in New Issue