Guest User

drawing with GtkGLExt

a guest
Feb 29th, 2016
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.50 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <strings.h>
  3. #include <stdlib.h>
  4. #include <gtk/gtk.h>
  5. #include <gtk/gtkgl.h>
  6. #include <GL/gl.h>
  7.  
  8. const GLfloat rect[] = {-0.5f, 0.5f,
  9.             0.5f, 0.5f,
  10.             0.5f, -0.5f,
  11.             -0.5f, -0.5f};
  12.  
  13. const GLfloat tri[] = { 0.0f, 1.0f,
  14.             0.5f, 0.5f,
  15.             -0.5f, 0.5f};
  16.  
  17. const GLchar *v_src = "#version 440\n"
  18.               "in vec2 pos;"
  19.               "void main() {"
  20.               " gl_Position = vec4(pos, 0.0, 1.0);"
  21.               "}";
  22.  
  23. const GLchar *f_src = "#version 440\n"
  24.               "out vec4 col;"
  25.               "void main() {"
  26.               " col = vec4(0.5, 0.3, 0.0, 1.0);"
  27.               "}";
  28.  
  29. void print_gl_err(const char *operation) {
  30.     GLenum err = glGetError();
  31.     if(err != GL_NO_ERROR) {
  32.         fprintf(stderr, "%s: ", operation);
  33.         fprintf(stderr, err == GL_INVALID_ENUM ? "invalid enumeration\n" :
  34.                 err == GL_INVALID_VALUE ? "invalid value\n" :
  35.                 err == GL_INVALID_OPERATION ? "invalid operation\n" :
  36.                 err == GL_INVALID_FRAMEBUFFER_OPERATION ? "invalid framebuffer operation\n" :
  37.                 err == GL_OUT_OF_MEMORY ? "out of memory\n" :
  38.                 err == GL_STACK_UNDERFLOW ? "stack underflow\n" :
  39.                 err == GL_STACK_OVERFLOW ? "stack overflow\n" : "unknown error\n");
  40.     }
  41. }
  42.  
  43. gboolean on_destroy(GtkWidget *main_window, gpointer data) {
  44.     gtk_main_quit();
  45.     return TRUE;
  46. }
  47.  
  48. gboolean on_expose(GtkWidget *main_window, GdkEventExpose *event, gpointer data) {
  49.     GdkGLDrawable *gl_window = gtk_widget_get_gl_drawable(main_window);
  50.     GdkGLContext *context = gtk_widget_get_gl_context(main_window);
  51.     gdk_gl_drawable_gl_begin(gl_window, context);
  52.     // gl commands for drawing
  53.     glClearColor(0.2, 0.1, 0.1, 1.0);
  54.     glClear(GL_COLOR_BUFFER_BIT);
  55.    
  56.     GLuint vbo[2];
  57.     glGenBuffers(2, vbo);
  58.     print_gl_err("buffer allocation");
  59.    
  60.     GLuint vshader, fshader, prog;
  61.     vshader = glCreateShader(GL_VERTEX_SHADER);
  62.     glShaderSource(vshader, 1, &v_src, NULL);
  63.     glCompileShader(vshader);
  64.  
  65.     GLint compile_status;
  66.     char compile_log[512];
  67.     glGetShaderiv(vshader, GL_COMPILE_STATUS, &compile_status);
  68.     if(compile_status != GL_TRUE) {
  69.         bzero(compile_log, sizeof(compile_log));
  70.         glGetShaderInfoLog(vshader, 512, NULL, compile_log);
  71.         fprintf(stderr, "%-512s\n", compile_log);
  72.     }
  73.  
  74.     fshader = glCreateShader(GL_FRAGMENT_SHADER);
  75.     glShaderSource(fshader, 1, &f_src, NULL);
  76.     glCompileShader(fshader);
  77.  
  78.     glGetShaderiv(fshader, GL_COMPILE_STATUS, &compile_status);
  79.     if(compile_status != GL_TRUE) {
  80.         bzero(compile_log, sizeof(compile_log));
  81.         glGetShaderInfoLog(vshader, 512, NULL, compile_log);
  82.         fprintf(stderr, "%-512s\n", compile_log);
  83.     }
  84.     print_gl_err("shader compilation");
  85.  
  86.     prog = glCreateProgram();
  87.     glAttachShader(prog, vshader);
  88.     glAttachShader(prog, fshader);
  89.     glLinkProgram(prog);
  90.     print_gl_err("program linking");
  91.     glUseProgram(prog);
  92.     print_gl_err("program usage");
  93.  
  94.     GLuint varr;
  95.     glGenVertexArrays(1, &varr);
  96.     glBindVertexArray(varr);
  97.     // draw triangle
  98.     glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  99.     glBufferStorage(GL_ARRAY_BUFFER, sizeof(tri), tri, 0);
  100.     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
  101.     // alternative way to map attributes with binding points
  102.     /*glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
  103.     glVertexAttribBinding(0, 0);
  104.     glBindVertexBuffer(0, vbo[0], 0, 2 * sizeof(GLfloat));*/
  105.     glEnableVertexAttribArray(0);
  106.     // draw rectangle
  107.     glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
  108.     glBufferStorage(GL_ARRAY_BUFFER, sizeof(rect), rect, 0);
  109.     glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
  110.     // alternative way to map attributes with binding points
  111.     /*glVertexAttribFormat(3, 2, GL_FLOAT, GL_FALSE, 0);
  112.     glVertexAttribBinding(3, 3);
  113.     glBindVertexBuffer(3, vbo[1], 2 * sizeof(GLfloat), 2 * sizeof(GLfloat));*/
  114.     glEnableVertexAttribArray(3);
  115.     print_gl_err("vertex array binding");
  116.  
  117.     glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
  118.     print_gl_err("drawing");
  119.    
  120.     glDeleteProgram(prog);
  121.     glDeleteShader(vshader);
  122.     glDeleteShader(fshader);
  123.     glDeleteVertexArrays(1, &varr);
  124.     glDeleteBuffers(2, vbo);
  125.     print_gl_err("deletion");
  126.  
  127.     if(gdk_gl_drawable_is_double_buffered(gl_window))
  128.         gdk_gl_drawable_swap_buffers(gl_window);
  129.     else
  130.         glFlush();
  131.     gdk_gl_drawable_gl_end(gl_window);
  132.     return TRUE;
  133. }
  134.  
  135. int main(int argc, char *argv[]) {
  136.     const gchar *name = "OpenGL test";
  137.     const gint w = 800, h = 600;
  138.     gtk_init(&argc, &argv);
  139.     if(!gtk_gl_init_check(&argc, &argv)) {
  140.         fprintf(stderr, "Unable to initialize OpenGL system\n");
  141.         return EXIT_FAILURE;
  142.     }
  143.     GtkWidget *main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  144.     gtk_widget_set_size_request(main_window, w, h);
  145.     gtk_window_set_title(GTK_WINDOW(main_window), name);
  146.     g_signal_connect(main_window, "destroy", G_CALLBACK(on_destroy), NULL);
  147.  
  148.     GtkWidget *drawing_area = gtk_drawing_area_new();
  149.         gtk_widget_set_size_request(drawing_area, w, h);
  150.     gtk_widget_set_events(drawing_area, GDK_EXPOSURE_MASK);
  151.         gtk_container_add(GTK_CONTAINER(main_window), drawing_area);
  152.     // make drawing area drawable by realizing(making it visible) the attached window
  153.     // don't attach the draw event handlers yet
  154.     gtk_widget_show(main_window);
  155.  
  156.     // RGBA colour mode and double buffered window
  157.     GdkGLConfig *gl_conf = gdk_gl_config_new_by_mode(
  158.                 GDK_GL_MODE_RGBA
  159.                 |GDK_GL_MODE_DOUBLE
  160.                   );
  161.     if(!gl_conf || !gtk_widget_set_gl_capability(drawing_area, gl_conf, NULL, TRUE, GDK_GL_RGBA_TYPE)) {
  162.         fprintf(stderr, "Unable to configure OpenGL system\n");
  163.         return EXIT_FAILURE;
  164.     }
  165.     // GTK2 version of draw event
  166.     g_signal_connect(drawing_area, "expose-event", G_CALLBACK(on_expose), NULL);
  167.  
  168.     gtk_widget_show_all(main_window);
  169.     gtk_main();
  170.     return EXIT_SUCCESS;
  171. }
Add Comment
Please, Sign In to add comment