feat: swap canvas for opengl context
This commit is contained in:
44
flake.nix
44
flake.nix
@@ -3,29 +3,33 @@
|
||||
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
}: let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {inherit system;};
|
||||
in {
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
gcc
|
||||
clang-tools
|
||||
lldb
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
}:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
gcc
|
||||
clang-tools
|
||||
lldb
|
||||
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
|
||||
gtk4
|
||||
gtk4
|
||||
libepoxy
|
||||
|
||||
gdb
|
||||
];
|
||||
gdb
|
||||
];
|
||||
|
||||
shellHook = "";
|
||||
shellHook = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ project(
|
||||
)
|
||||
|
||||
gtk = dependency('gtk4', required: true)
|
||||
epoxy = dependency('epoxy')
|
||||
|
||||
src = files(
|
||||
'src/main.c',
|
||||
@@ -25,7 +26,7 @@ src = files(
|
||||
executable(
|
||||
'vektor',
|
||||
src,
|
||||
dependencies: [gtk],
|
||||
dependencies: [gtk,epoxy],
|
||||
link_args: ['-lm'],
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) {
|
||||
stateOut->workspacePaned =
|
||||
GTK_PANED(gtk_builder_get_object(builder, "workspace_paned"));
|
||||
stateOut->workspaceCanvas =
|
||||
GTK_PICTURE(gtk_builder_get_object(builder, "workspace"));
|
||||
GTK_GL_AREA(gtk_builder_get_object(builder, "workspace"));
|
||||
stateOut->workspaceButtonLinetool =
|
||||
GTK_BUTTON(gtk_builder_get_object(builder, "button_linetool"));
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ all the widgets used in internal logic of the program
|
||||
typedef struct VektorWidgetState {
|
||||
GtkWindow* window;
|
||||
GtkPaned* workspacePaned;
|
||||
GtkPicture* workspaceCanvas;
|
||||
GtkGLArea* workspaceCanvas;
|
||||
|
||||
GtkButton* workspaceButtonLinetool;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "epoxy/gl.h"
|
||||
#include "gtk/gtk.h"
|
||||
|
||||
#include "../core/raster.h"
|
||||
@@ -8,6 +9,114 @@
|
||||
#define VKTR_CANVAS_HEIGHT 400
|
||||
#define VKTR_CANVAS_SIZE (VKTR_CANVAS_WIDTH * VKTR_CANVAS_HEIGHT * 4)
|
||||
|
||||
static GLuint shader_program;
|
||||
static GLuint vao;
|
||||
|
||||
static const char* vertex_shader_src =
|
||||
"#version 300 es\n" // <- ES version
|
||||
"layout(location = 0) in vec2 aPos;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = vec4(aPos, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* fragment_shader_src =
|
||||
"#version 300 es\n" // <- ES version
|
||||
"precision mediump float;\n" // required in ES for fragment color
|
||||
"out vec4 FragColor;\n"
|
||||
"void main() {\n"
|
||||
" FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static GLuint compile_shader(GLenum type, const char* src) {
|
||||
GLuint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint success;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char info[512];
|
||||
glGetShaderInfoLog(shader, 512, NULL, info);
|
||||
g_error("Shader compile failed: %s", info);
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
static void init_shader(void) {
|
||||
GLuint vertex = compile_shader(GL_VERTEX_SHADER, vertex_shader_src);
|
||||
GLuint fragment = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_src);
|
||||
|
||||
shader_program = glCreateProgram();
|
||||
glAttachShader(shader_program, vertex);
|
||||
glAttachShader(shader_program, fragment);
|
||||
glLinkProgram(shader_program);
|
||||
|
||||
GLint success;
|
||||
glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char info[512];
|
||||
glGetProgramInfoLog(shader_program, 512, NULL, info);
|
||||
g_error("Shader link failed: %s", info);
|
||||
}
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
}
|
||||
|
||||
static void init_geometry(void) {
|
||||
// Vertices for a rectangle in NDC coordinates
|
||||
float vertices[] = {
|
||||
-0.5f, -0.5f, // bottom-left
|
||||
0.5f, -0.5f, // bottom-right
|
||||
0.5f, 0.5f, // top-right
|
||||
-0.5f, 0.5f // top-left
|
||||
};
|
||||
unsigned int indices[] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
GLuint vbo, ebo;
|
||||
glGenVertexArrays(1, &vao);
|
||||
glGenBuffers(1, &vbo);
|
||||
glGenBuffers(1, &ebo);
|
||||
|
||||
glBindVertexArray(vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),
|
||||
(void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
static gboolean render(GtkGLArea* area, GdkGLContext* context) {
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(shader_program);
|
||||
glBindVertexArray(vao);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void realize(GtkGLArea* area, gpointer user_data) {
|
||||
gtk_gl_area_make_current(area);
|
||||
|
||||
if (gtk_gl_area_get_error(area) != NULL)
|
||||
return; // context creation failed
|
||||
|
||||
init_shader();
|
||||
init_geometry();
|
||||
}
|
||||
|
||||
void vektor_canvas_init(VektorWidgetState* state, VektorCanvas* canvasOut) {
|
||||
canvasOut->canvasWidget = state->workspaceCanvas;
|
||||
canvasOut->width = VKTR_CANVAS_WIDTH;
|
||||
@@ -20,10 +129,14 @@ void vektor_canvas_init(VektorWidgetState* state, VektorCanvas* canvasOut) {
|
||||
VKTR_CANVAS_WIDTH, VKTR_CANVAS_HEIGHT, GDK_MEMORY_R8G8B8A8,
|
||||
canvasOut->canvasPixelBytes, VKTR_CANVAS_WIDTH * 4);
|
||||
|
||||
gtk_picture_set_paintable(canvasOut->canvasWidget,
|
||||
GDK_PAINTABLE(canvasOut->canvasTexture));
|
||||
gtk_picture_set_content_fit(GTK_PICTURE(canvasOut->canvasWidget),
|
||||
GTK_CONTENT_FIT_CONTAIN);
|
||||
g_signal_connect(canvasOut->canvasWidget, "realize", G_CALLBACK(realize),
|
||||
NULL);
|
||||
g_signal_connect(canvasOut->canvasWidget, "render", G_CALLBACK(render),
|
||||
NULL);
|
||||
// gtk_picture_set_paintable(canvasOut->canvasWidget,
|
||||
// GDK_PAINTABLE(canvasOut->canvasTexture));
|
||||
// gtk_picture_set_content_fit(GTK_PICTURE(canvasOut->canvasWidget),
|
||||
// GTK_CONTENT_FIT_CONTAIN);
|
||||
// g_object_unref(bytes);
|
||||
}
|
||||
|
||||
@@ -38,8 +151,8 @@ void vektor_canvas_update(VektorCanvas* canvas) {
|
||||
canvas->width, canvas->height, GDK_MEMORY_R8G8B8A8,
|
||||
canvas->canvasPixelBytes, canvas->width * 4);
|
||||
|
||||
gtk_picture_set_paintable(canvas->canvasWidget,
|
||||
GDK_PAINTABLE(canvas->canvasTexture));
|
||||
// gtk_picture_set_paintable(canvas->canvasWidget,
|
||||
// GDK_PAINTABLE(canvas->canvasTexture));
|
||||
}
|
||||
|
||||
void vektor_canvas_fill(VektorCanvas* canvas, VektorColor color) {
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include "../core/raster.h"
|
||||
#include "../util/color.h"
|
||||
#include "gtk/gtk.h"
|
||||
#include "uicontroller.h"
|
||||
|
||||
typedef struct VektorCanvas {
|
||||
GtkPicture* canvasWidget;
|
||||
GtkGLArea* canvasWidget;
|
||||
|
||||
// texture related stuff
|
||||
guchar* canvasPixels;
|
||||
|
||||
@@ -45,11 +45,16 @@
|
||||
|
||||
<!--Main canvas-->
|
||||
<child>
|
||||
<object class="GtkPicture" id="workspace">
|
||||
<!-- <object class="GtkPicture" id="workspace">
|
||||
<property name="content-fit">contain</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
|
||||
</object> -->
|
||||
|
||||
<object class="GtkGLArea" id="workspace">
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user