I'm experimenting with using the GtkGLArea
widget at the moment. None of the answers to similar questions seem to pertain to this situation.
glClear()
can set the background colour just fine but actually drawing arrays of triangles isn't.
According to this tutorial, the code below should work.
EDIT: 21/5/2015: Added shaders, still getting same results. New code below
Here's the main.c
and the SConstruct
so you can build with scons:
SOLVED: Working code under the heading SOLUTION: main.c the same SConstruct file can be used to build example
main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#include <gtk/gtkglarea.h>
#define IGNORE_VAR(type, identifier)
{
type IGNORED_VARIABLE_abcd = identifier;
identifier = IGNORED_VARIABLE_abcd;
}
const GLchar *vert_src ="
"
"#version 330
"
"
"
"layout(location = 0) in vec2 in_position;
"
"
"
"void main()
"
"{
"
" gl_Position = in_position;
"
"}
";
const GLchar *frag_src ="
"
"void main (void)
"
"{
"
" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
"
"}
";
GLuint gl_buffer, gl_program;
static gboolean realise(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
gtk_gl_area_make_current(GTK_GL_AREA(area));
if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL)
{
printf("Failed to initialiize buffers
");
return FALSE;
}
GLfloat verts[] =
{
+0.0f, +1.0f,
-1.0f, -1.0f,
+1.0f, -1.0f,
};
GLuint frag_shader, vert_shader;
frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
vert_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(frag_shader, 1, &frag_src, NULL);
glShaderSource(vert_shader, 1, &vert_src, NULL);
glCompileShader(frag_shader);
glCompileShader(vert_shader);
gl_program = glCreateProgram();
glAttachShader(gl_program, frag_shader);
glAttachShader(gl_program, vert_shader);
glLinkProgram(gl_program);
glGenBuffers(1, &gl_buffer);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
return TRUE;
}
static gboolean render(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
IGNORE_VAR(GtkGLArea*, area);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
//glUseProgram(gl_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
return TRUE;
}
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL),
*gl_area = gtk_gl_area_new();
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL);
gtk_container_add(GTK_CONTAINER(window), gl_area);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Sconstruct
import os
env = Environment(CC='gcc', CCFLAGS='--std=c11', ENV={'PATH':os.environ['PATH']})
env.Append(LIBS = ['GL', 'epoxy'])
env.ParseConfig('pkg-config --cflags --libs gtk+-3.0')
#env.ParseConfig('pkg-config --cflags gdkglext-1.0')
env.Program(target='gl', source=['main.c'])
# vim: set filetype=python:
SOLUTION: main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#define IGNORE_VAR(type, identifier)
{
type IGNORED_VARIABLE_abcd = identifier;
identifier = IGNORED_VARIABLE_abcd;
}
const GLchar *vert_src ="
"
"#version 330
"
"#extension GL_ARB_explicit_attrib_location: enable
"
"
"
"layout(location = 0) in vec2 in_position;
"
"
"
"void main()
"
"{
"
" gl_Position = vec4(in_position, 0.0, 1.0);
"
"}
";
const GLchar *frag_src ="
"
"void main (void)
"
"{
"
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
"
"}
";
GLuint gl_vao, gl_buffer, gl_program;
static gboolean realise(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
gtk_gl_area_make_current(GTK_GL_AREA(area));
if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL)
{
printf("Failed to initialiize buffers
");
return FALSE;
}
GLfloat verts[] =
{
+0.0f, +1.0f,
-1.0f, -1.0f,
+1.0f, -1.0f,
};
GLuint frag_shader, vert_shader;
frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
vert_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(frag_shader, 1, &frag_src, NULL);
glShaderSource(vert_shader, 1, &vert_src, NULL);
glCompileShader(frag_shader);
glCompileShader(vert_shader);
gl_program = glCreateProgram();
glAttachShader(gl_program, frag_shader);
glAttachShader(gl_program, vert_shader);
glLinkProgram(gl_program);
glGenVertexArrays(1, &gl_vao);
glBindVertexArray(gl_vao);
glGenBuffers(1, &gl_buffer);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindVertexArray(0);
glDeleteBuffers(1, &gl_buffer);
return TRUE;
}
static gboolean render(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
IGNORE_VAR(GtkGLArea*, area);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glUseProgram(gl_program);
glBindVertexArray(gl_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray (0);
glUseProgram (0);
glFlush();
return TRUE;
}
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL),
*gl_area = gtk_gl_area_new();
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL);
gtk_container_add(GTK_CONTAINER(window), gl_area);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
See Question&Answers more detail:
os