feat: swap canvas for opengl context
This commit is contained in:
12
flake.nix
12
flake.nix
@@ -3,13 +3,16 @@
|
|||||||
|
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
outputs = {
|
outputs =
|
||||||
|
{
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
}: let
|
}:
|
||||||
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
pkgs = import nixpkgs {inherit system;};
|
pkgs = import nixpkgs { inherit system; };
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
devShells.${system}.default = pkgs.mkShell {
|
devShells.${system}.default = pkgs.mkShell {
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
gcc
|
gcc
|
||||||
@@ -21,6 +24,7 @@
|
|||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
gtk4
|
gtk4
|
||||||
|
libepoxy
|
||||||
|
|
||||||
gdb
|
gdb
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
gtk = dependency('gtk4', required: true)
|
gtk = dependency('gtk4', required: true)
|
||||||
|
epoxy = dependency('epoxy')
|
||||||
|
|
||||||
src = files(
|
src = files(
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
@@ -25,7 +26,7 @@ src = files(
|
|||||||
executable(
|
executable(
|
||||||
'vektor',
|
'vektor',
|
||||||
src,
|
src,
|
||||||
dependencies: [gtk],
|
dependencies: [gtk,epoxy],
|
||||||
link_args: ['-lm'],
|
link_args: ['-lm'],
|
||||||
install: true,
|
install: true,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) {
|
|||||||
stateOut->workspacePaned =
|
stateOut->workspacePaned =
|
||||||
GTK_PANED(gtk_builder_get_object(builder, "workspace_paned"));
|
GTK_PANED(gtk_builder_get_object(builder, "workspace_paned"));
|
||||||
stateOut->workspaceCanvas =
|
stateOut->workspaceCanvas =
|
||||||
GTK_PICTURE(gtk_builder_get_object(builder, "workspace"));
|
GTK_GL_AREA(gtk_builder_get_object(builder, "workspace"));
|
||||||
stateOut->workspaceButtonLinetool =
|
stateOut->workspaceButtonLinetool =
|
||||||
GTK_BUTTON(gtk_builder_get_object(builder, "button_linetool"));
|
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 {
|
typedef struct VektorWidgetState {
|
||||||
GtkWindow* window;
|
GtkWindow* window;
|
||||||
GtkPaned* workspacePaned;
|
GtkPaned* workspacePaned;
|
||||||
GtkPicture* workspaceCanvas;
|
GtkGLArea* workspaceCanvas;
|
||||||
|
|
||||||
GtkButton* workspaceButtonLinetool;
|
GtkButton* workspaceButtonLinetool;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "epoxy/gl.h"
|
||||||
#include "gtk/gtk.h"
|
#include "gtk/gtk.h"
|
||||||
|
|
||||||
#include "../core/raster.h"
|
#include "../core/raster.h"
|
||||||
@@ -8,6 +9,114 @@
|
|||||||
#define VKTR_CANVAS_HEIGHT 400
|
#define VKTR_CANVAS_HEIGHT 400
|
||||||
#define VKTR_CANVAS_SIZE (VKTR_CANVAS_WIDTH * VKTR_CANVAS_HEIGHT * 4)
|
#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) {
|
void vektor_canvas_init(VektorWidgetState* state, VektorCanvas* canvasOut) {
|
||||||
canvasOut->canvasWidget = state->workspaceCanvas;
|
canvasOut->canvasWidget = state->workspaceCanvas;
|
||||||
canvasOut->width = VKTR_CANVAS_WIDTH;
|
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,
|
VKTR_CANVAS_WIDTH, VKTR_CANVAS_HEIGHT, GDK_MEMORY_R8G8B8A8,
|
||||||
canvasOut->canvasPixelBytes, VKTR_CANVAS_WIDTH * 4);
|
canvasOut->canvasPixelBytes, VKTR_CANVAS_WIDTH * 4);
|
||||||
|
|
||||||
gtk_picture_set_paintable(canvasOut->canvasWidget,
|
g_signal_connect(canvasOut->canvasWidget, "realize", G_CALLBACK(realize),
|
||||||
GDK_PAINTABLE(canvasOut->canvasTexture));
|
NULL);
|
||||||
gtk_picture_set_content_fit(GTK_PICTURE(canvasOut->canvasWidget),
|
g_signal_connect(canvasOut->canvasWidget, "render", G_CALLBACK(render),
|
||||||
GTK_CONTENT_FIT_CONTAIN);
|
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);
|
// g_object_unref(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +151,8 @@ void vektor_canvas_update(VektorCanvas* canvas) {
|
|||||||
canvas->width, canvas->height, GDK_MEMORY_R8G8B8A8,
|
canvas->width, canvas->height, GDK_MEMORY_R8G8B8A8,
|
||||||
canvas->canvasPixelBytes, canvas->width * 4);
|
canvas->canvasPixelBytes, canvas->width * 4);
|
||||||
|
|
||||||
gtk_picture_set_paintable(canvas->canvasWidget,
|
// gtk_picture_set_paintable(canvas->canvasWidget,
|
||||||
GDK_PAINTABLE(canvas->canvasTexture));
|
// GDK_PAINTABLE(canvas->canvasTexture));
|
||||||
}
|
}
|
||||||
|
|
||||||
void vektor_canvas_fill(VektorCanvas* canvas, VektorColor color) {
|
void vektor_canvas_fill(VektorCanvas* canvas, VektorColor color) {
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
#include "../core/raster.h"
|
#include "../core/raster.h"
|
||||||
#include "../util/color.h"
|
#include "../util/color.h"
|
||||||
|
#include "gtk/gtk.h"
|
||||||
#include "uicontroller.h"
|
#include "uicontroller.h"
|
||||||
|
|
||||||
typedef struct VektorCanvas {
|
typedef struct VektorCanvas {
|
||||||
GtkPicture* canvasWidget;
|
GtkGLArea* canvasWidget;
|
||||||
|
|
||||||
// texture related stuff
|
// texture related stuff
|
||||||
guchar* canvasPixels;
|
guchar* canvasPixels;
|
||||||
|
|||||||
@@ -45,11 +45,16 @@
|
|||||||
|
|
||||||
<!--Main canvas-->
|
<!--Main canvas-->
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkPicture" id="workspace">
|
<!-- <object class="GtkPicture" id="workspace">
|
||||||
<property name="content-fit">contain</property>
|
<property name="content-fit">contain</property>
|
||||||
<property name="hexpand">true</property>
|
<property name="hexpand">true</property>
|
||||||
<property name="vexpand">true</property>
|
<property name="vexpand">true</property>
|
||||||
|
|
||||||
|
</object> -->
|
||||||
|
|
||||||
|
<object class="GtkGLArea" id="workspace">
|
||||||
|
<property name="hexpand">true</property>
|
||||||
|
<property name="vexpand">true</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user