11 "attribute vec2 position;\n"
12 "attribute vec2 in_texcoord;\n"
13 "uniform vec2 offset;\n"
14 "uniform vec2 scale;\n"
15 "varying vec2 texcoord;\n"
18 " gl_Position = vec4(offset + position * scale, 0, 1);\n"
19 " texcoord = in_texcoord;\n"
25 "precision mediump float;\n"
28 "uniform sampler2D texture;\n"
29 "varying vec2 texcoord;\n"
32 " gl_FragColor = texture2D(texture, texcoord);\n"
55 fl_compositor_opengl_shader,
59 static gchar* get_shader_log(GLuint shader) {
63 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
65 log =
static_cast<gchar*
>(g_malloc(log_length + 1));
66 glGetShaderInfoLog(shader, log_length,
nullptr, log);
76 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
78 log =
static_cast<gchar*
>(g_malloc(log_length + 1));
79 glGetProgramInfoLog(program, log_length,
nullptr, log);
87 "Failed to setup compositor shaders, unable to make OpenGL context "
92 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
94 glCompileShader(vertex_shader);
95 GLint vertex_compile_status;
96 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
97 if (vertex_compile_status == GL_FALSE) {
98 g_autofree gchar* shader_log = get_shader_log(vertex_shader);
99 g_warning(
"Failed to compile vertex shader: %s", shader_log);
102 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
104 glCompileShader(fragment_shader);
105 GLint fragment_compile_status;
106 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
107 if (fragment_compile_status == GL_FALSE) {
108 g_autofree gchar* shader_log = get_shader_log(fragment_shader);
109 g_warning(
"Failed to compile fragment shader: %s", shader_log);
112 self->program = glCreateProgram();
113 glAttachShader(self->program, vertex_shader);
114 glAttachShader(self->program, fragment_shader);
115 glLinkProgram(self->program);
118 glGetProgramiv(self->program, GL_LINK_STATUS, &link_status);
119 if (link_status == GL_FALSE) {
121 g_warning(
"Failed to link program: %s", program_log);
124 self->offset_location = glGetUniformLocation(self->program,
"offset");
125 self->scale_location = glGetUniformLocation(self->program,
"scale");
127 glDeleteShader(vertex_shader);
128 glDeleteShader(fragment_shader);
134 GLfloat
const vertex_data[] = {-1, -1, 0, 0, 1, 1, 1, 1, -1, 1, 0, 1,
135 -1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1};
137 glGenBuffers(1, &self->vertex_buffer);
138 glBindBuffer(GL_ARRAY_BUFFER, self->vertex_buffer);
139 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_data), vertex_data,
144 FlCompositorOpenGLShader*
self = FL_COMPOSITOR_OPENGL_SHADER(
object);
146 if (self->opengl_manager !=
nullptr) {
148 if (self->program != 0) {
149 glDeleteProgram(self->program);
151 if (self->vertex_buffer != 0) {
152 glDeleteBuffers(1, &self->vertex_buffer);
156 "Failed to cleanup compositor shaders, unable to make OpenGL context "
161 self->vertex_buffer = 0;
163 g_clear_object(&self->opengl_manager);
165 G_OBJECT_CLASS(fl_compositor_opengl_shader_parent_class)->dispose(
object);
169 FlCompositorOpenGLShaderClass* klass) {
177 g_return_val_if_fail(FL_IS_OPENGL_MANAGER(
opengl_manager),
nullptr);
179 FlCompositorOpenGLShader*
self = FL_COMPOSITOR_OPENGL_SHADER(
180 g_object_new(fl_compositor_opengl_shader_get_type(),
nullptr));
182 self->opengl_manager = FL_OPENGL_MANAGER(g_object_ref(
opengl_manager));
190 g_return_if_fail(FL_IS_COMPOSITOR_OPENGL_SHADER(
self));
192 glBindBuffer(GL_ARRAY_BUFFER, self->vertex_buffer);
193 GLint position_location = glGetAttribLocation(self->program,
"position");
194 glEnableVertexAttribArray(position_location);
195 glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE,
196 sizeof(GLfloat) * 4, 0);
197 GLint texcoord_location = glGetAttribLocation(self->program,
"in_texcoord");
198 glEnableVertexAttribArray(texcoord_location);
199 glVertexAttribPointer(texcoord_location, 2, GL_FLOAT, GL_FALSE,
201 reinterpret_cast<void*
>(
sizeof(GLfloat) * 2));
203 glUseProgram(self->program);
209 g_return_if_fail(FL_IS_COMPOSITOR_OPENGL_SHADER(
self));
210 glUniform2f(self->offset_location,
x,
y);
216 g_return_if_fail(FL_IS_COMPOSITOR_OPENGL_SHADER(
self));
217 glUniform2f(self->scale_location,
x,
y);
FlFramebuffer double double y
G_BEGIN_DECLS FlOpenGLManager * opengl_manager
static void setup_shader(FlCompositorOpenGLShader *self)
static const char * fragment_shader_src
static gchar * get_program_log(GLuint program)
static void fl_compositor_opengl_shader_dispose(GObject *object)
static void fl_compositor_opengl_shader_init(FlCompositorOpenGLShader *self)
void fl_compositor_opengl_shader_set_offset(FlCompositorOpenGLShader *self, double x, double y)
FlCompositorOpenGLShader * fl_compositor_opengl_shader_new(FlOpenGLManager *opengl_manager)
void fl_compositor_opengl_shader_set_scale(FlCompositorOpenGLShader *self, double x, double y)
static void fl_compositor_opengl_shader_class_init(FlCompositorOpenGLShaderClass *klass)
void fl_compositor_opengl_shader_use(FlCompositorOpenGLShader *self)
static const char * vertex_shader_src
G_DEFINE_TYPE(FlCompositorOpenGLShader, fl_compositor_opengl_shader, G_TYPE_OBJECT) static gchar *get_shader_log(GLuint shader)
gboolean fl_opengl_manager_make_platform_current(FlOpenGLManager *self)
FlOpenGLManager * opengl_manager