feat: swap canvas for opengl context
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user