2017-12-11 7 views
-1

PyGObjectでGLAreaウィジェットを使用しようとすると、以前の質問(Use of the Gtk.GLArea in Pygobject GTK3)がありました。私はコマンドを描くためにPythonのバージョンを取得したことはありませんでしたので、私はそれをよりよく理解しようとするCバージョンを与えるだろうと思った。 Gtk3がすべて含まれているのでUbuntu 16を使って、私はそれを撃った。次のコードは、エラーまたは警告なしでコンパイルおよび実行されますが、含まれているGL_LINES命令は描画されません。本当に奇妙なことは、glClearColorが背景を変更し、GL_LINESが同じ関数に変更されていることです。ご覧のとおり、私はUbuntuに含まれているエポキシ/ glライブラリーを使用しています。これはGL/glに相当すると思います。何か案は?CでのGtk GLAreaウィジェットに、glコマンドが表示されない

/*to compile -> 
gcc `pkg-config --cflags gtk+-3.0` -o gl_area gl_area.c `pkg-config --libs gtk+-3.0 epoxy`*/ 
#include <math.h> 
#include <gtk/gtk.h> 
#include <epoxy/gl.h> 
#include <stdio.h> 


gint init(GtkWidget *widget) 
{ 
    /* Setup the viewport*/ 
     glViewport(0, 0, gtk_widget_get_allocated_width (widget), 
         gtk_widget_get_allocated_height(widget)); 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     glOrtho(0,100, 100,0, -1,1); 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 

     printf("ran init method\n"); 
     return TRUE; 
} 



/* When widget is exposed it's contents are redrawn. */ 
static gboolean 
render (GtkGLArea *area, GdkGLContext *context) 
{ 
    /* OpenGL functions can be called only if make_current returns true */ 

     /* Draw simple triangle */ 
     glClearColor(.3,.3,.3,1); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glColor4f(1,1,1,1); 
     glBegin(GL_LINES); 
{ 
     glVertex2f(0,0); 
     glVertex2f(10000,10000); 
     glVertex2f(0,0); 
     glVertex2f(-10000,-10000); 
     glVertex2f(0,0); 
     glVertex2f(10000,-10000); 
     glVertex2f(0,0); 
     glVertex2f(-10000,10000); 
} 
     glEnd(); 
     printf("ran render method\n"); 
    return TRUE; 
} 

/* When glarea widget size changes, viewport size is set to match the new size */ 
gint reshape(GtkWidget *widget, GdkEventConfigure *event) 
{ 
    /* OpenGL functions can be called if context is current */ 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     printf("ran rehsape method\n"); 
    glViewport(0, 0, gtk_widget_get_allocated_width (widget), 
         gtk_widget_get_allocated_height(widget)); 
    return TRUE; 
} 


int main(int argc, char **argv) 
{ 
/* initialize gtk */ 
gtk_init(&argc, &argv); 

/* Create new top level window. */ 
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
gtk_window_set_title(GTK_WINDOW(window), "GL Area Test"); 
gtk_window_set_default_size (GTK_WINDOW(window), 
          640, 
          480); 
    gtk_container_set_border_width(GTK_CONTAINER(window), 10); 

    /* Quit main if got delete event */ 
    g_signal_connect(G_OBJECT(window), 
        "delete-event", 
        G_CALLBACK(gtk_main_quit), 
        NULL); 

    /* Create new OpenGL widget. */ 
GtkWidget *glarea = gtk_gl_area_new(); 

    /* Do initialization when widget has been realized. */ 
g_signal_connect(glarea, "realize", G_CALLBACK(init), NULL); 
    /* When window is resized viewport needs to be resized also. */ 
g_signal_connect(glarea, "configure-event", G_CALLBACK(reshape), NULL); 

    /* Render signal should be sent once the context is set to current. */ 
g_signal_connect (glarea, "render", G_CALLBACK (render), NULL); 


    /* set minimum size */ 
gtk_widget_set_size_request(glarea, 100,100); 

    /* put glarea into window and show it all */ 
gtk_container_add(GTK_CONTAINER(window), glarea); 
gtk_widget_show_all (window); 
gtk_main(); 
return 0; 
} 
+1

IMHO、:; ''あなたはglMatrixMode(GL_PROJECTION)を呼び出し、再びと '' glLoadIdentity(); 'glOrtho(0100、100,0、-1,1)が後に'。これは 'glOrtho()'の前の呼び出しを無効にします。 (これは 'glOrtho(-1、-1、-1、-1、1);')のようなものだと思いますが、 'glMatrixMode(GL_MODELVIEW);'代わりに 'glMatrixMode()')を使用してください。 – Scheff

+0

Completeleyは関係ありませんが、あなたは 'destroy_event'ではなく' destroy'に接続して 'gtk_main_quit'を呼び出すことになっています。 – liberforce

+0

'gtk-demo'を実行して、glのサンプルを見てください。間違っていることが分かりますか?この例もここにあります:https://git.gnome.org/browse/gtk+/tree/demos/gtk-demo/glarea.c – liberforce

答えて

0

enter image description here [OK]を、私はOpenGLとシェーダの使用について多くの詳細を理解しています。基本的に、GLAreaが持っていた問題は、コマンドが現在のコンテキストのアクティブなバッファに "束縛されていた"配列にないことでした。このチュートリアルは多くの助けになりました:https://www.youtube.com/watch?v=Q_kFcRlLTk0シンプルにするためにデモコードをハックし、シェーダのソースコードをCコードに文字列として持ってきました。それはデモアプリケーションから開き、マトリックスで三角形を回転させるスライダーを持っていました。私は最も基本的なウィンドウにそれを蒸留しようとしました。これはコンパイルしてエラーなしで実行します。今度はPyGObjectで試してみましょう。おそらくないエラーが、

/* OpenGL Area 
* 
* GtkGLArea is a widget that allows custom drawing using OpenGL calls. 
*/ 
#include <string.h> 
#include <stdio.h> 
#include <math.h> 
#include <gtk/gtk.h> 
#include <epoxy/gl.h> 

const GLchar *FRAGMENT_SOURCE = 
"#version 330\n" 
"in vec4 inputColor;\n" 
"out vec4 outputColor;\n" 
"void main() {\n" 
"outputColor = vec4(1.0f, 0.0f, 0.0f, 0.0f);\n" //constant red. I know it's a poor shader 
"}"; 
const GLchar *VERTEX_SOURCE = 
"#version 330\n" 
"in vec4 position;\n" 
"void main()\n{gl_Position = position;\n" 
"}"; 


/* the GtkGLArea widget */ 
static GtkWidget *gl_area = NULL; 

/* The object we are drawing */ 
static const GLfloat vertex_data[] = { 
    0.f, 0.5f, 0.f, 1.f, 
    0.5f, -0.366f, 0.f, 1.f, 
-0.5f, -0.366f, 0.f, 1.f, 
}; 

/* Initialize the GL buffers */ 
static void 
init_buffers (GLuint *vao_out, 
       GLuint *buffer_out) 
{ 
    GLuint vao, buffer; 

    /* We only use one VAO, so we always keep it bound */ 
    glGenVertexArrays (1, &vao); 
    glBindVertexArray (vao); 

    /* This is the buffer that holds the vertices */ 
    glGenBuffers (1, &buffer); 
    glBindBuffer (GL_ARRAY_BUFFER, buffer); 
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertex_data), vertex_data, GL_STATIC_DRAW); 
    glBindBuffer (GL_ARRAY_BUFFER, 0); 

    if (vao_out != NULL) 
    *vao_out = vao; 

    if (buffer_out != NULL) 
    *buffer_out = buffer; 
} 

/* Create and compile a shader */ 
static GLuint 
create_shader (int type) 
{ 
    GLuint shader; 
    int status; 
    shader = glCreateShader (type); 
if (type== GL_FRAGMENT_SHADER){ 
    glShaderSource (shader, 1, &FRAGMENT_SOURCE, NULL);} 
if (type== GL_VERTEX_SHADER){ 
    glShaderSource (shader, 1, &VERTEX_SOURCE, NULL);} 
    glCompileShader (shader); 

    glGetShaderiv (shader, GL_COMPILE_STATUS, &status); 
    if (status == GL_FALSE) 
    { 
     int log_len; 
     char *buffer; 
     glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len); 
     buffer = g_malloc (log_len + 1); 
     glGetShaderInfoLog (shader, log_len, NULL, buffer); 
     g_warning ("Compile failure in %s shader:\n%s", 
       type == GL_VERTEX_SHADER ? "vertex" : "fragment", 
       buffer); 
     g_free (buffer); 
     glDeleteShader (shader); 
     return 0; 
    } 

    return shader; 
} 

/* Initialize the shaders and link them into a program */ 
static void 
init_shaders (GLuint *program_out) 
{ 
    GLuint vertex, fragment; 
    GLuint program = 0; 
    int status; 
    vertex = create_shader (GL_VERTEX_SHADER); 

    if (vertex == 0) 
    { 
     *program_out = 0; 
     return; 
    } 

    fragment = create_shader (GL_FRAGMENT_SHADER); 

    if (fragment == 0) 
    { 
     glDeleteShader (vertex); 
     *program_out = 0; 
     return; 
    } 

    program = glCreateProgram(); 
    glAttachShader (program, vertex); 
    glAttachShader (program, fragment); 

    glLinkProgram (program); 

    glGetProgramiv (program, GL_LINK_STATUS, &status); 
    if (status == GL_FALSE) 
    { 
     int log_len; 
     char *buffer; 

     glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len); 

     buffer = g_malloc (log_len + 1); 
     glGetProgramInfoLog (program, log_len, NULL, buffer); 

     g_warning ("Linking failure:\n%s", buffer); 

     g_free (buffer); 

     glDeleteProgram (program); 
     program = 0; 

     goto out; 
    } 


    glDetachShader (program, vertex); 
    glDetachShader (program, fragment); 

out: 
    glDeleteShader (vertex); 
    glDeleteShader (fragment); 

    if (program_out != NULL) 
    *program_out = program; 

} 


static GLuint position_buffer; 
static GLuint program; 

/* We need to set up our state when we realize the GtkGLArea widget */ 
static void 
realize (GtkWidget *widget) 
{ 
    GdkGLContext *context; 
    gtk_gl_area_make_current (GTK_GL_AREA (widget)); 
    if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL) 
    return; 
    context = gtk_gl_area_get_context (GTK_GL_AREA (widget)); 
    init_buffers (&position_buffer, NULL); 
    init_shaders (&program); 
} 

/* We should tear down the state when unrealizing */ 
static void 
unrealize (GtkWidget *widget) 
{ 
    gtk_gl_area_make_current (GTK_GL_AREA (widget)); 

    if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL) 
    return; 

    glDeleteBuffers (1, &position_buffer); 
    glDeleteProgram (program); 
} 

static void 
draw_triangle (void) 
{ 

    /* Use our shaders */ 
    glUseProgram (program); 


    /* Use the vertices in our buffer */ 
    glBindBuffer (GL_ARRAY_BUFFER, position_buffer); 
    glEnableVertexAttribArray (0); 
    glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, 0); 
    /* Draw the three vertices as a triangle */ 
    glDrawArrays (GL_TRIANGLES, 0, 3); 

    /* We finished using the buffers and program */ 
    glDisableVertexAttribArray (0); 
    glBindBuffer (GL_ARRAY_BUFFER, 0); 
    glUseProgram (0); 
} 

static gboolean 
render (GtkGLArea *area, 
     GdkGLContext *context) 
{ 
    if (gtk_gl_area_get_error (area) != NULL) 
    return FALSE; 

    /* Clear the viewport */ 
    glClearColor (0.0, 0.0, 0.0, 1.0); 
    glClear (GL_COLOR_BUFFER_BIT); 

    /* Draw our object */ 
    draw_triangle(); 

    /* Flush the contents of the pipeline */ 
    glFlush(); 

    return TRUE; 
} 

static void 
on_axis_value_change (void) 
{ 
    gtk_widget_queue_draw (gl_area); 
} 



int main(int argc, char **argv) 
{ 
GtkWidget *window, *box; 
/* initialize gtk */ 
gtk_init(&argc, &argv); 
/* Create new top level window. */ 
window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_default_size (GTK_WINDOW(window),1000,1000); 
    gtk_window_set_title(GTK_WINDOW(window), "GL Area"); 
    gtk_container_set_border_width(GTK_CONTAINER(window), 10); 
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE); 
    g_object_set (box, "margin", 12, NULL); 
    gtk_box_set_spacing (GTK_BOX (box), 6); 
    gtk_container_add (GTK_CONTAINER (window), box); 
gl_area = gtk_gl_area_new(); 
    gtk_box_pack_start (GTK_BOX(box), gl_area,1,1, 0); 
    /* We need to initialize and free GL resources, so we use 
    * the realize and unrealize signals on the widget 
    */ 
    g_signal_connect (gl_area, "realize", G_CALLBACK (realize), NULL); 
    g_signal_connect (gl_area, "unrealize", G_CALLBACK (unrealize), NULL); 

    /* The main "draw" call for GtkGLArea */ 
    g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL); 
    /* Quit form main if got delete event */ 
    g_signal_connect(G_OBJECT(window), "delete-event", 
        G_CALLBACK(gtk_main_quit), NULL); 
gtk_widget_show_all(GTK_WIDGET(window)); 
gtk_main(); 

    return 0; 
} 
関連する問題